From 2baa4fc6a37106233fb49985d0a3d6951edba482 Mon Sep 17 00:00:00 2001 From: Johannes Roth Date: Fri, 22 Sep 2023 16:41:38 +0200 Subject: [PATCH] fix not signing with mandated hash algorithm when using PQC --- src/lib/crypto/dilithium.cpp | 6 +++++ src/lib/crypto/dilithium.h | 2 ++ src/lib/crypto/sphincsplus.cpp | 41 +++++++++++++++++++++++++++++++++- src/lib/crypto/sphincsplus.h | 3 +++ src/lib/pgp-key.cpp | 22 ++++++++++++++++++ 5 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/lib/crypto/dilithium.cpp b/src/lib/crypto/dilithium.cpp index 2c061518..bd7f112b 100644 --- a/src/lib/crypto/dilithium.cpp +++ b/src/lib/crypto/dilithium.cpp @@ -128,4 +128,10 @@ dilithium_hash_allowed(pgp_hash_alg_t hash_alg) default: return false; } +} + +pgp_hash_alg_t +dilithium_default_hash_alg() +{ + return PGP_HASH_SHA3_256; } \ No newline at end of file diff --git a/src/lib/crypto/dilithium.h b/src/lib/crypto/dilithium.h index 678cf372..18035ce0 100644 --- a/src/lib/crypto/dilithium.h +++ b/src/lib/crypto/dilithium.h @@ -111,4 +111,6 @@ std::pair dilithium_gen bool dilithium_hash_allowed(pgp_hash_alg_t hash_alg); +pgp_hash_alg_t dilithium_default_hash_alg(); + #endif diff --git a/src/lib/crypto/sphincsplus.cpp b/src/lib/crypto/sphincsplus.cpp index 5589212e..d948ddbe 100644 --- a/src/lib/crypto/sphincsplus.cpp +++ b/src/lib/crypto/sphincsplus.cpp @@ -383,4 +383,43 @@ sphincsplus_hash_allowed(pgp_pubkey_alg_t pk_alg, break; } return true; -} \ No newline at end of file +} + +pgp_hash_alg_t +sphincsplus_default_hash_alg(pgp_pubkey_alg_t pk_alg, + sphincsplus_parameter_t sphincsplus_param) +{ + switch (sphincsplus_param) { + case sphincsplus_simple_128s: + FALLTHROUGH_STATEMENT; + case sphincsplus_simple_128f: + switch (pk_alg) { + case PGP_PKA_SPHINCSPLUS_SHA2: + return PGP_HASH_SHA256; + case PGP_PKA_SPHINCSPLUS_SHAKE: + return PGP_HASH_SHA3_256; + default: + RNP_LOG("invalid parameter given"); + throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS); + } + case sphincsplus_simple_192s: + FALLTHROUGH_STATEMENT; + case sphincsplus_simple_192f: + FALLTHROUGH_STATEMENT; + case sphincsplus_simple_256s: + FALLTHROUGH_STATEMENT; + case sphincsplus_simple_256f: + switch (pk_alg) { + case PGP_PKA_SPHINCSPLUS_SHA2: + return PGP_HASH_SHA512; + case PGP_PKA_SPHINCSPLUS_SHAKE: + return PGP_HASH_SHA3_512; + default: + RNP_LOG("invalid parameter given"); + throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS); + } + default: + RNP_LOG("invalid parameter given"); + throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS); + } +} diff --git a/src/lib/crypto/sphincsplus.h b/src/lib/crypto/sphincsplus.h index c709bb89..17d61c8e 100644 --- a/src/lib/crypto/sphincsplus.h +++ b/src/lib/crypto/sphincsplus.h @@ -199,4 +199,7 @@ bool sphincsplus_hash_allowed(pgp_pubkey_alg_t pk_alg, sphincsplus_parameter_t sphincsplus_param, pgp_hash_alg_t hash_alg); +pgp_hash_alg_t sphincsplus_default_hash_alg(pgp_pubkey_alg_t pk_alg, + sphincsplus_parameter_t sphincsplus_param); + #endif \ No newline at end of file diff --git a/src/lib/pgp-key.cpp b/src/lib/pgp-key.cpp index 99f21ab9..aadd1054 100644 --- a/src/lib/pgp-key.cpp +++ b/src/lib/pgp-key.cpp @@ -520,6 +520,28 @@ find_suitable_key(pgp_op_t op, pgp_hash_alg_t pgp_hash_adjust_alg_to_key(pgp_hash_alg_t hash, const pgp_key_pkt_t *pubkey) { +#if defined(ENABLE_PQC) + switch (pubkey->alg) { + case PGP_PKA_SPHINCSPLUS_SHA2: + FALLTHROUGH_STATEMENT; + case PGP_PKA_SPHINCSPLUS_SHAKE: + return sphincsplus_default_hash_alg(pubkey->alg, + pubkey->material.sphincsplus.pub.param()); + case PGP_PKA_DILITHIUM3_ED25519: + FALLTHROUGH_STATEMENT; + case PGP_PKA_DILITHIUM3_P256: + FALLTHROUGH_STATEMENT; + case PGP_PKA_DILITHIUM5_P384: + FALLTHROUGH_STATEMENT; + case PGP_PKA_DILITHIUM3_BP256: + FALLTHROUGH_STATEMENT; + case PGP_PKA_DILITHIUM5_BP384: + return dilithium_default_hash_alg(); + default: + break; + } +#endif + if ((pubkey->alg != PGP_PKA_DSA) && (pubkey->alg != PGP_PKA_ECDSA)) { return hash; }