]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Reject private keys with an incorrect pk hash
authorViktor Dukhovni <openssl-users@dukhovni.org>
Sun, 9 Feb 2025 02:41:04 +0000 (13:41 +1100)
committerTomas Mraz <tomas@openssl.org>
Fri, 14 Feb 2025 09:46:04 +0000 (10:46 +0100)
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/26674)

crypto/ml_dsa/ml_dsa_encoders.c
crypto/ml_dsa/ml_dsa_key.c
include/crypto/ml_dsa.h
providers/implementations/keymgmt/ml_dsa_kmgmt.c

index 67b750fbaf4dac305a14fa615d680b78043d7862..28c2b0c55df2d166289a42f80a01e99a8fc5e1de 100644 (file)
@@ -764,6 +764,7 @@ int ossl_ml_dsa_sk_decode(ML_DSA_KEY *key, const uint8_t *in, size_t in_len)
     DECODE_FN *decode_fn;
     const ML_DSA_PARAMS *params = key->params;
     size_t i, k = params->k, l = params->l;
+    uint8_t input_tr[ML_DSA_TR_BYTES];
     PACKET pkt;
 
     /* When loading from an explicit key, drop the seed. */
@@ -788,7 +789,7 @@ int ossl_ml_dsa_sk_decode(ML_DSA_KEY *key, const uint8_t *in, size_t in_len)
     if (!PACKET_buf_init(&pkt, in, in_len)
             || !PACKET_copy_bytes(&pkt, key->rho, sizeof(key->rho))
             || !PACKET_copy_bytes(&pkt, key->K, sizeof(key->K))
-            || !PACKET_copy_bytes(&pkt, key->tr, sizeof(key->tr)))
+            || !PACKET_copy_bytes(&pkt, input_tr, sizeof(input_tr)))
         return 0;
 
     for (i = 0; i < l; ++i)
@@ -805,7 +806,17 @@ int ossl_ml_dsa_sk_decode(ML_DSA_KEY *key, const uint8_t *in, size_t in_len)
     if (key->priv_encoding == NULL
         && (key->priv_encoding = OPENSSL_memdup(in, in_len)) == NULL)
         return 0;
-    return ossl_ml_dsa_key_public_from_private(key);
+    /*
+     * Computing the public key also computes its hash, which must be equal to
+     * the |tr| value in the private key, else the key was corrupted.
+     */
+    if (ossl_ml_dsa_key_public_from_private(key) != 0
+        && memcmp(input_tr, key->tr, sizeof(input_tr)) == 0)
+        return 1;
+
+    /* On error, reset the key back to uninitialised. */
+    ossl_ml_dsa_key_reset(key);
+    return 0;
 }
 
 /*
index 12b28b28f5a2f5929fc465db097c7a3cea690c0c..e0667f8902d7bd29a9f24b1b620d7cd372148e24 100644 (file)
@@ -132,7 +132,7 @@ int ossl_ml_dsa_key_priv_alloc(ML_DSA_KEY *key)
 }
 
 /**
- * @brief Destroy a ML_DSA_KEY object
+ * @brief Destroy an ML_DSA_KEY object
  */
 void ossl_ml_dsa_key_free(ML_DSA_KEY *key)
 {
@@ -141,6 +141,15 @@ void ossl_ml_dsa_key_free(ML_DSA_KEY *key)
 
     EVP_MD_free(key->shake128_md);
     EVP_MD_free(key->shake256_md);
+    ossl_ml_dsa_key_reset(key);
+    OPENSSL_free(key);
+}
+
+/**
+ * @brief Factory reset an ML_DSA_KEY object
+ */
+void ossl_ml_dsa_key_reset(ML_DSA_KEY *key)
+{
     vector_zero(&key->s2);
     vector_zero(&key->s1);
     vector_zero(&key->t0);
@@ -148,11 +157,13 @@ void ossl_ml_dsa_key_free(ML_DSA_KEY *key)
     vector_free(&key->t1);
     OPENSSL_cleanse(key->K, sizeof(key->K));
     OPENSSL_free(key->pub_encoding);
+    key->pub_encoding = NULL;
     if (key->priv_encoding != NULL)
         OPENSSL_clear_free(key->priv_encoding, key->params->sk_len);
+    key->priv_encoding = NULL;
     if (key->seed != NULL)
         OPENSSL_clear_free(key->seed, ML_DSA_SEED_BYTES);
-    OPENSSL_free(key);
+    key->seed = NULL;
 }
 
 /**
index 2999fe488f14388bd6ff138f7a446e36e4d3db20..b3fef85e39eec36a1e24686f8571fa657eb8ee1e 100644 (file)
@@ -70,6 +70,8 @@ const ML_DSA_PARAMS *ossl_ml_dsa_params_get(int evp_type);
 const ML_DSA_PARAMS *ossl_ml_dsa_key_params(const ML_DSA_KEY *key);
 __owur ML_DSA_KEY *ossl_ml_dsa_key_new(OSSL_LIB_CTX *libctx, const char *propq,
                                        int evp_type);
+/* Factory reset for keys that fail initialisation */
+void ossl_ml_dsa_key_reset(ML_DSA_KEY *key);
 __owur int ossl_ml_dsa_key_pub_alloc(ML_DSA_KEY *key);
 __owur int ossl_ml_dsa_key_priv_alloc(ML_DSA_KEY *key);
 void ossl_ml_dsa_key_free(ML_DSA_KEY *key);
index ec49cb3efef79880c14c828e0dab7f65fee63141..c38a5a3ec43558ae94cd3980bb581fc6934b3829 100644 (file)
@@ -255,8 +255,10 @@ static int ml_dsa_import(void *keydata, int selection, const OSSL_PARAM params[]
 #ifdef FIPS_MODULE
     if (res > 0) {
         res = ml_dsa_pairwise_test(key);
-        if (res <= 0)
+        if (res <= 0) {
+            ossl_ml_dsa_key_reset(key);
             ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
+        }
     }
 #endif
     return res;