@@ -9,13 +9,14 @@
#if HAVE_CRYPTO
#include <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <openssl/sha.h>
#include <openssl/x509.h>
#elif HAVE_GNUTLS
#include <gnutls/abstract.h>
+#include <gnutls/gnutls.h>
#endif
+#include <libcamera/base/utils.h>
+
/**
* \file pub_key.h
* \brief Public key signature verification
@@ -28,12 +29,17 @@ namespace libcamera {
* \brief Public key wrapper for signature verification
*
* The PubKey class wraps a public key and implements signature verification. It
- * only supports RSA keys and the RSA-SHA256 signature algorithm.
+ * supports RSA keys with the RSA-SHA256 signature algorithm, or ML-DSA-65 keys
+ * as specified in NIST FIPS 204. The signature algorithm is determined at
+ * compile time.
*/
/**
* \brief Construct a PubKey from key data
* \param[in] key Key data encoded in DER format
+ *
+ * Supported key types are RSA (verified with RSA-SHA256) and ML-DSA-65
+ * (verified as ML-DSA-65 according to FIPS 204).
*/
PubKey::PubKey([[maybe_unused]] Span<const uint8_t> key)
: valid_(false)
@@ -83,7 +89,7 @@ PubKey::~PubKey()
* \param[in] sig The signature
*
* Verify that the signature \a sig matches the signed \a data for the public
- * key. The signture algorithm is hardcoded to RSA-SHA256.
+ * key.
*
* \return True if the signature is valid, false otherwise
*/
@@ -94,29 +100,20 @@ bool PubKey::verify([[maybe_unused]] Span<const uint8_t> data,
return false;
#if HAVE_CRYPTO
- /*
- * Create and initialize a public key algorithm context for signature
- * verification.
- */
- EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pubkey_, nullptr);
+ EVP_MD_CTX *ctx = EVP_MD_CTX_new();
if (!ctx)
return false;
- if (EVP_PKEY_verify_init(ctx) <= 0 ||
- EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0 ||
- EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) {
- EVP_PKEY_CTX_free(ctx);
+ utils::scope_exit ctxGuard([&] { EVP_MD_CTX_free(ctx); });
+
+ const EVP_MD *md = (EVP_PKEY_get_id(pubkey_) == EVP_PKEY_RSA) ? EVP_sha256() : nullptr;
+ if (EVP_DigestVerifyInit(ctx, nullptr, md, nullptr,
+ pubkey_) <= 0)
return false;
- }
- /* Calculate the SHA256 digest of the data. */
- uint8_t digest[SHA256_DIGEST_LENGTH];
- SHA256(data.data(), data.size(), digest);
+ int ret = EVP_DigestVerify(ctx, sig.data(), sig.size(),
+ data.data(), data.size());
- /* Decrypt the signature and verify it matches the digest. */
- int ret = EVP_PKEY_verify(ctx, sig.data(), sig.size(), digest,
- SHA256_DIGEST_LENGTH);
- EVP_PKEY_CTX_free(ctx);
return ret == 1;
#elif HAVE_GNUTLS
const gnutls_datum_t gnuTlsData{
@@ -129,8 +126,31 @@ bool PubKey::verify([[maybe_unused]] Span<const uint8_t> data,
static_cast<unsigned int>(sig.size())
};
- int ret = gnutls_pubkey_verify_data2(pubkey_, GNUTLS_SIGN_RSA_SHA256, 0,
- &gnuTlsData, &gnuTlsSig);
+ gnutls_pk_algorithm_t pkeyAlgo = static_cast<gnutls_pk_algorithm_t>(gnutls_pubkey_get_pk_algorithm(pubkey_, nullptr));
+ if (pkeyAlgo == GNUTLS_PK_UNKNOWN)
+ return false;
+
+ gnutls_sign_algorithm_t algo;
+ gnutls_digest_algorithm_t hash;
+ int ret = gnutls_pubkey_get_preferred_hash_algorithm(pubkey_, &hash, nullptr);
+ if (ret < 0)
+ return false;
+
+ /* GNUTLS_DIG_UNKNOWN is a valid hash algorithm for ML-DSA-65 */
+ if (hash == GNUTLS_DIG_UNKNOWN) {
+ if (pkeyAlgo == GNUTLS_PK_MLDSA65)
+ algo = GNUTLS_SIGN_MLDSA65;
+ else
+ return false;
+ } else {
+ algo = gnutls_pk_to_sign(pkeyAlgo, hash);
+ if (algo == GNUTLS_SIGN_UNKNOWN)
+ return false;
+ }
+
+ ret = gnutls_pubkey_verify_data2(pubkey_, algo, 0,
+ &gnuTlsData, &gnuTlsSig);
+
return ret >= 0;
#else
return false;
With RSA slated for deprecation by 2035, the IPA signature algorithm must be migrated to a Post-Quantum Cryptography (PQC) standard. Accordingly, we are adopting the NIST-finalized ML-DSA signature scheme. Among the available variants, ML-DSA-44, ML-DSA-65, and ML-DSA-87, which offer varying levels of data integrity protection. ML-DSA-65 has been selected to sign the IPA due to its balanced performance for general-purpose applications. Link: https://csrc.nist.gov/projects/post-quantum-cryptography/post-quantum-cryptography-standardization/evaluation-criteria/security-(evaluation-criteria) Link: https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8547.ipd.pdf Signed-off-by: Kate Hsuan <hpa@redhat.com> --- src/libcamera/pub_key.cpp | 66 +++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-)