Skip to content

Commit

Permalink
Initial PQC algorithm support
Browse files Browse the repository at this point in the history
  • Loading branch information
CBonnell committed Jan 9, 2025
1 parent 529c066 commit 3dc9131
Show file tree
Hide file tree
Showing 32 changed files with 1,697 additions and 113 deletions.
1 change: 1 addition & 0 deletions pkilint/bin/lint_pkix_cert.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def main(cli_args=None) -> int:
certificate.create_validity_validator_container(),
certificate.create_subject_validator_container([]),
certificate.create_extensions_validator_container([]),
certificate.create_spki_validator_container([]),
],
)

Expand Down
7 changes: 3 additions & 4 deletions pkilint/cabf/serverauth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,15 @@ def create_spki_validator_container(additional_validators=None):
if additional_validators is None:
additional_validators = []

return validation.ValidatorContainer(
validators=[
return certificate.create_spki_validator_container(
[
serverauth_key.ServerauthAllowedPublicKeyAlgorithmEncodingValidator(
path="certificate.tbsCertificate.subjectPublicKeyInfo.algorithm"
),
cabf_key.RsaKeyValidator(),
cabf_key.EcdsaKeyValidator(),
]
+ additional_validators,
path="certificate.tbsCertificate.subjectPublicKeyInfo",
+ additional_validators
)


Expand Down
7 changes: 3 additions & 4 deletions pkilint/cabf/smime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,16 +146,15 @@ def create_decoding_validators():


def create_spki_validation_container():
return validation.ValidatorContainer(
validators=[
return certificate.create_spki_validator_container(
[
smime_key.SmimeAllowedPublicKeyAlgorithmEncodingValidator(
path="certificate.tbsCertificate.subjectPublicKeyInfo.algorithm"
),
cabf_key.RsaKeyValidator(),
cabf_key.EcdsaKeyValidator(),
smime_key.GmailAllowedModulusLengthValidator(),
],
path="certificate.tbsCertificate.subjectPublicKeyInfo",
]
)


Expand Down
5 changes: 2 additions & 3 deletions pkilint/etsi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,8 @@ def create_validators(
additional_spki_validators=spki_validators,
)
else:
spki_validator_container = validation.ValidatorContainer(
validators=spki_validators,
path="certificate.tbsCertificate.subjectPublicKeyInfo",
spki_validator_container = certificate.create_spki_validator_container(
spki_validators
)

top_level_container = validation.ValidatorContainer(
Expand Down
Empty file added pkilint/nist/__init__.py
Empty file.
Empty file added pkilint/nist/asn1/__init__.py
Empty file.
134 changes: 134 additions & 0 deletions pkilint/nist/asn1/csor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
from pyasn1.type.univ import ObjectIdentifier


# top-level OID arcs

nistAlgorithms = ObjectIdentifier("2.16.840.1.101.3.4")

sigAlgs = nistAlgorithms + (3,)

kems = nistAlgorithms + (4,)

# ML-DSA

id_ml_dsa_44 = sigAlgs + (17,)

id_ml_dsa_65 = sigAlgs + (18,)

id_ml_dsa_87 = sigAlgs + (19,)

MLDSA_OIDS = {
id_ml_dsa_44,
id_ml_dsa_65,
id_ml_dsa_87,
}

# HashML-DSA

id_hash_ml_dsa_44_with_sha512 = sigAlgs + (32,)

id_hash_ml_dsa_65_with_sha512 = sigAlgs + (33,)

id_hash_ml_dsa_87_with_sha512 = sigAlgs + (34,)

HASH_MLDSA_OIDS = {
id_hash_ml_dsa_44_with_sha512,
id_hash_ml_dsa_65_with_sha512,
id_hash_ml_dsa_87_with_sha512,
}

# SLH-DSA

id_slh_dsa_sha2_128s = sigAlgs + (20,)

id_slh_dsa_sha2_128f = sigAlgs + (21,)

id_slh_dsa_sha2_192s = sigAlgs + (22,)

id_slh_dsa_sha2_192f = sigAlgs + (23,)

id_slh_dsa_sha2_256s = sigAlgs + (24,)

id_slh_dsa_sha2_256f = sigAlgs + (25,)

id_slh_dsa_shake_128s = sigAlgs + (26,)

id_slh_dsa_shake_128f = sigAlgs + (27,)

id_slh_dsa_shake_192s = sigAlgs + (28,)

id_slh_dsa_shake_192f = sigAlgs + (29,)

id_slh_dsa_shake_256s = sigAlgs + (30,)

id_slh_dsa_shake_256f = sigAlgs + (31,)

SLHDSA_OIDS = {
id_slh_dsa_sha2_128s,
id_slh_dsa_sha2_128f,
id_slh_dsa_sha2_192s,
id_slh_dsa_sha2_192f,
id_slh_dsa_sha2_256s,
id_slh_dsa_sha2_256f,
id_slh_dsa_shake_128s,
id_slh_dsa_shake_128f,
id_slh_dsa_shake_192s,
id_slh_dsa_shake_192f,
id_slh_dsa_shake_256s,
id_slh_dsa_shake_256f,
}

# HashSLH-DSA

id_hash_slh_dsa_sha2_128s_with_sha256 = sigAlgs + (35,)

id_hash_slh_dsa_sha2_128f_with_sha256 = sigAlgs + (36,)

id_hash_slh_dsa_sha2_192s_with_sha512 = sigAlgs + (37,)

id_hash_slh_dsa_sha2_192f_with_sha512 = sigAlgs + (38,)

id_hash_slh_dsa_sha2_256s_with_sha512 = sigAlgs + (39,)

id_hash_slh_dsa_sha2_256f_with_sha512 = sigAlgs + (40,)

id_hash_slh_dsa_shake_128s_with_shake128 = sigAlgs + (41,)

id_hash_slh_dsa_shake_128f_with_shake128 = sigAlgs + (42,)

id_hash_slh_dsa_shake_192s_with_shake256 = sigAlgs + (43,)

id_hash_slh_dsa_shake_192f_with_shake256 = sigAlgs + (44,)

id_hash_slh_dsa_shake_256s_with_shake256 = sigAlgs + (45,)

id_hash_slh_dsa_shake_256f_with_shake256 = sigAlgs + (46,)

HASH_SLHDSA_OIDS = {
id_hash_slh_dsa_sha2_128s_with_sha256,
id_hash_slh_dsa_sha2_128f_with_sha256,
id_hash_slh_dsa_sha2_192s_with_sha512,
id_hash_slh_dsa_sha2_192f_with_sha512,
id_hash_slh_dsa_sha2_256s_with_sha512,
id_hash_slh_dsa_sha2_256f_with_sha512,
id_hash_slh_dsa_shake_128s_with_shake128,
id_hash_slh_dsa_shake_128f_with_shake128,
id_hash_slh_dsa_shake_192s_with_shake256,
id_hash_slh_dsa_shake_192f_with_shake256,
id_hash_slh_dsa_shake_256s_with_shake256,
id_hash_slh_dsa_shake_256f_with_shake256,
}

# ML-KEM

id_alg_ml_kem_512 = kems + (1,)

id_alg_ml_kem_768 = kems + (2,)

id_alg_ml_kem_1024 = kems + (3,)

MLKEM_OIDS = {
id_alg_ml_kem_512,
id_alg_ml_kem_768,
id_alg_ml_kem_1024,
}
40 changes: 40 additions & 0 deletions pkilint/nist/asn1/fips_203.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from pyasn1.type import univ
from pyasn1.type.constraint import ValueSizeConstraint

from pkilint import document
from pkilint.nist.asn1 import csor


ML_KEM_512_PublicKeySize = 800
ML_KEM_768_PublicKeySize = 1184
ML_KEM_1024_PublicKeySize = 1568


class MlKem512PublicKey(univ.OctetString):
subtypeSpec = ValueSizeConstraint(
ML_KEM_512_PublicKeySize, ML_KEM_512_PublicKeySize
)


class MlKem768PublicKey(univ.OctetString):
subtypeSpec = ValueSizeConstraint(
ML_KEM_768_PublicKeySize, ML_KEM_768_PublicKeySize
)


class MlKem1024PublicKey(univ.OctetString):
subtypeSpec = ValueSizeConstraint(
ML_KEM_1024_PublicKeySize, ML_KEM_1024_PublicKeySize
)


ALGORITHM_OID_TO_KEY_MAPPINGS = {
csor.id_alg_ml_kem_512: MlKem512PublicKey(),
csor.id_alg_ml_kem_768: MlKem768PublicKey(),
csor.id_alg_ml_kem_1024: MlKem1024PublicKey(),
}

ALGORITHM_OID_TO_PARAMETER_MAPPINGS = {
k: document.ValueDecoder.VALUE_NODE_ABSENT
for k in ALGORITHM_OID_TO_KEY_MAPPINGS.keys()
}
39 changes: 39 additions & 0 deletions pkilint/nist/asn1/fips_204.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from pyasn1.type import univ
from pyasn1.type.constraint import ValueSizeConstraint

from pkilint import document
from pkilint.nist.asn1 import csor


ML_DSA_44_PublicKeySize = 1312
ML_DSA_65_PublicKeySize = 1952
ML_DSA_87_PublicKeySize = 2592


class MlDsa44PublicKey(univ.OctetString):
subtypeSpec = ValueSizeConstraint(ML_DSA_44_PublicKeySize, ML_DSA_44_PublicKeySize)


class MlDsa65PublicKey(univ.OctetString):
subtypeSpec = ValueSizeConstraint(ML_DSA_65_PublicKeySize, ML_DSA_65_PublicKeySize)


class MlDsa87PublicKey(univ.OctetString):
subtypeSpec = ValueSizeConstraint(ML_DSA_87_PublicKeySize, ML_DSA_87_PublicKeySize)


ALGORITHM_OID_TO_KEY_MAPPINGS = {
# pure
csor.id_ml_dsa_44: MlDsa44PublicKey(),
csor.id_ml_dsa_65: MlDsa65PublicKey(),
csor.id_ml_dsa_87: MlDsa87PublicKey(),
# pre-hashed
csor.id_hash_ml_dsa_44_with_sha512: MlDsa44PublicKey(),
csor.id_hash_ml_dsa_65_with_sha512: MlDsa65PublicKey(),
csor.id_hash_ml_dsa_87_with_sha512: MlDsa87PublicKey(),
}

ALGORITHM_OID_TO_PARAMETER_MAPPINGS = {
k: document.ValueDecoder.VALUE_NODE_ABSENT
for k in ALGORITHM_OID_TO_KEY_MAPPINGS.keys()
}
Loading

0 comments on commit 3dc9131

Please sign in to comment.