Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/lib/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1826,6 +1826,21 @@ Key::validate_binding(SignatureInfo & sinfo,
sinfo.validity.mark_validated();
return;
}
/* RFC 9980 §7.2: Subkey binding signatures (Signature Type 0x18) over
* PQ(/T) algorithms MUST NOT be made with MD5, SHA-1, or RIPEMD-160.
* A receiving implementation MUST treat such a signature as invalid. */
#if defined(ENABLE_PQC)
if (Key::is_pqc_alg(subkey.alg())) {
auto halg = sinfo.sig->halg();
if (halg == PGP_HASH_MD5 || halg == PGP_HASH_SHA1 || halg == PGP_HASH_RIPEMD) {
RNP_LOG("Weak hash algorithm %d in PQ subkey binding signature (RFC 9980 §7.2)",
(int) halg);
sinfo.validity.add_error(RNP_ERROR_SIG_WEAK_HASH);
sinfo.validity.mark_validated();
return;
}
}
#endif
auto hash = signature_hash_binding(*sinfo.sig, pkt(), subkey.pkt());
validate_sig(sinfo, *hash, ctx);
/* Check whether subkey is capable of signing and return otherwise */
Expand Down
41 changes: 25 additions & 16 deletions src/lib/keygen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,23 +117,23 @@ static const id_str_pair pubkey_alg_map[] = {
{PGP_PKA_X25519, "X25519"},
#endif
#if defined(ENABLE_PQC)
{PGP_PKA_KYBER768_X25519, "ML-KEM-768_X25519"},
{PGP_PKA_KYBER768_X25519, RNP_ALGNAME_KYBER768_X25519},
#endif
#if defined(ENABLE_PQC) && defined(ENABLE_CRYPTO_REFRESH)
{PGP_PKA_KYBER1024_X448, "Kyber-X448"},
{PGP_PKA_KYBER768_P384, "ML-KEM-768_P384"},
{PGP_PKA_KYBER1024_P521, "ML-KEM-1024_P521"},
{PGP_PKA_KYBER768_BP384, "ML-KEM-768_BP384"},
{PGP_PKA_KYBER1024_BP512, "ML-KEM-1024_BP512"},
{PGP_PKA_DILITHIUM3_ED25519, "ML-DSA-65_ED25519"},
{PGP_PKA_DILITHIUM5_ED448, "Dilithium-ED448"},
{PGP_PKA_DILITHIUM3_P384, "ML-DSA-65_P384"},
{PGP_PKA_DILITHIUM5_P521, "ML-DSA-87_P521"},
{PGP_PKA_DILITHIUM3_BP384, "ML-DSA-65_BP384"},
{PGP_PKA_DILITHIUM5_BP512, "ML-DSA-87_BP512"},
{PGP_PKA_SPHINCSPLUS_SHAKE_128f, "SLH-DSA-SHAKE-128f"},
{PGP_PKA_SPHINCSPLUS_SHAKE_128s, "SLH-DSA-SHAKE-128s"},
{PGP_PKA_SPHINCSPLUS_SHAKE_256s, "SLH-DSA-SHAKE-256s"},
{PGP_PKA_KYBER1024_X448, RNP_ALGNAME_KYBER1024_X448},
{PGP_PKA_KYBER768_P384, RNP_ALGNAME_KYBER768_P384},
{PGP_PKA_KYBER1024_P521, RNP_ALGNAME_KYBER1024_P521},
{PGP_PKA_KYBER768_BP384, RNP_ALGNAME_KYBER768_BP384},
{PGP_PKA_KYBER1024_BP512, RNP_ALGNAME_KYBER1024_BP512},
{PGP_PKA_DILITHIUM3_ED25519, RNP_ALGNAME_DILITHIUM3_ED25519},
{PGP_PKA_DILITHIUM5_ED448, RNP_ALGNAME_DILITHIUM5_ED448},
{PGP_PKA_DILITHIUM3_P384, RNP_ALGNAME_DILITHIUM3_P384},
{PGP_PKA_DILITHIUM5_P521, RNP_ALGNAME_DILITHIUM5_P521},
{PGP_PKA_DILITHIUM3_BP384, RNP_ALGNAME_DILITHIUM3_BP384},
{PGP_PKA_DILITHIUM5_BP512, RNP_ALGNAME_DILITHIUM5_BP512},
{PGP_PKA_SPHINCSPLUS_SHAKE_128f, RNP_ALGNAME_SPHINCSPLUS_SHAKE_128f},
{PGP_PKA_SPHINCSPLUS_SHAKE_128s, RNP_ALGNAME_SPHINCSPLUS_SHAKE_128s},
{PGP_PKA_SPHINCSPLUS_SHAKE_256s, RNP_ALGNAME_SPHINCSPLUS_SHAKE_256s},
#endif
{0, NULL}};

Expand Down Expand Up @@ -426,7 +426,16 @@ UserPrefs::check_defaults(pgp_version_t version, pgp_pubkey_alg_t pk_alg)
#endif
}
#if defined(ENABLE_CRYPTO_REFRESH)
if (aead_prefs.empty() && (version == PGP_V6)) {
if (aead_prefs.empty() &&
((version == PGP_V6)
#if defined(ENABLE_PQC)
|| Key::is_pqc_alg(pk_alg)
#endif
)) {
/* Per RFC 9980 §7.1, a certificate that contains a PQ(/T) key SHOULD
* include the pair AES-256 with OCB in the Preferred AEAD Ciphersuites
* subpacket. v6 keys get the full matrix; v4 PQ keys (only
* ML-KEM-768+X25519 is valid for v4) get at minimum AES-256+OCB. */
for (auto sym_alg : symm_algs) {
aead_prefs.push_back(sym_alg);
aead_prefs.push_back(PGP_AEAD_OCB);
Expand Down
Loading