]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ml-dsa: update to use TRIE decoder
authorPauli <ppzgs1@gmail.com>
Wed, 4 Jun 2025 04:24:31 +0000 (14:24 +1000)
committerPauli <ppzgs1@gmail.com>
Fri, 6 Jun 2025 06:26:21 +0000 (16:26 +1000)
For get params and from data calls.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27756)

providers/implementations/keymgmt/ml_dsa_kmgmt.c.in

index 33b0ab860bed48819cf8858a6c3844f7953eb22a..5ab8fb741fca6363cf5e0c99a31c56f86fc13f3a 100644 (file)
@@ -6,6 +6,9 @@
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
  */
+{-
+use OpenSSL::paramnames qw(produce_param_list);
+-}
 
 #include <openssl/core_dispatch.h>
 #include <openssl/core_names.h>
@@ -16,6 +19,7 @@
 #include "crypto/ml_dsa.h"
 #include "internal/fips.h"
 #include "internal/param_build_set.h"
+#include "internal/param_names.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
@@ -179,6 +183,15 @@ static int ml_dsa_validate(const void *key_data, int selection, int check_type)
     return 1;
 }
 
+/* Machine generated by util/perl/OpenSSL/paramnames.pm */
+{- produce_param_list('static', 'ml_dsa_key_types',
+                      'static', 'ml_dsa_key_types_find_pidx',
+                      (['PKEY_PARAM_ML_DSA_SEED',           'octet_string'],
+                       ['PKEY_PARAM_PUB_KEY',               'octet_string'],
+                       ['PKEY_PARAM_PRIV_KEY',              'octet_string'],
+                      )); -}
+/* End of machine generated */
+
 /**
  * @brief Load a ML_DSA key from raw data.
  *
@@ -196,37 +209,49 @@ static int ml_dsa_key_fromdata(ML_DSA_KEY *key, const OSSL_PARAM params[],
     const uint8_t *pk = NULL, *sk = NULL, *seed = NULL;
     size_t pk_len = 0, sk_len = 0, seed_len = 0;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
-    if (p != NULL
-        && !OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pk, &pk_len))
-        return 0;
-    if (pk != NULL && pk_len != key_params->pk_len) {
-        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH,
-                       "Invalid %s public key length", key_params->alg);
-        return 0;
-    }
-
-    /* Private key is optional */
-    if (include_private) {
-        p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ML_DSA_SEED);
-        if (p != NULL
-            && !OSSL_PARAM_get_octet_string_ptr(p, (const void **)&seed,
-                                                &seed_len))
-            return 0;
-        if (seed != NULL && seed_len != ML_DSA_SEED_BYTES) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
-            return 0;
+    for (p = params; p->key != NULL; p++)
+        switch (ml_dsa_key_types_find_pidx(p->key)) {
+        default:
+            break;
+
+        case PIDX_PKEY_PARAM_PUB_KEY:
+            if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pk, &pk_len))
+                return 0;
+            if (pk != NULL && pk_len != key_params->pk_len) {
+                ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH,
+                               "Invalid %s public key length", key_params->alg);
+                return 0;
+            }
+            break;
+
+        /* Private key seed is optional */
+        case PIDX_PKEY_PARAM_ML_DSA_SEED:
+            if (include_private) {
+                if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&seed,
+                                                     &seed_len))
+                    return 0;
+                if (seed != NULL && seed_len != ML_DSA_SEED_BYTES) {
+                    ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
+                    return 0;
+                }
+            }
+            break;
+
+        /* Private key is optional */
+        case PIDX_PKEY_PARAM_PRIV_KEY:
+            if (include_private) {
+                if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&sk,
+                                                     &sk_len))
+                    return 0;
+                if (sk != NULL && sk_len != key_params->sk_len) {
+                    ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH,
+                                   "Invalid %s private key length",
+                                   key_params->alg);
+                    return 0;
+                }
+            }
+            break;
         }
-        p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
-        if (p != NULL
-            && !OSSL_PARAM_get_octet_string_ptr(p, (const void **)&sk, &sk_len))
-            return 0;
-        if (sk != NULL && sk_len != key_params->sk_len) {
-            ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH,
-                           "Invalid %s private key length", key_params->alg);
-            return 0;
-        }
-    }
 
     /* The caller MUST specify at least one of seed, private or public keys. */
     if (seed_len == 0 && pk_len == 0 && sk_len == 0) {
@@ -278,15 +303,6 @@ static int ml_dsa_import(void *keydata, int selection, const OSSL_PARAM params[]
     return ml_dsa_key_fromdata(key, params, include_priv);
 }
 
-#define ML_DSA_IMEXPORTABLE_PARAMETERS \
-    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ML_DSA_SEED, NULL, 0), \
-    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
-    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
-
-static const OSSL_PARAM ml_dsa_key_types[] = {
-    ML_DSA_IMEXPORTABLE_PARAMETERS,
-    OSSL_PARAM_END
-};
 static const OSSL_PARAM *ml_dsa_imexport_types(int selection)
 {
     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
@@ -294,15 +310,20 @@ static const OSSL_PARAM *ml_dsa_imexport_types(int selection)
     return ml_dsa_key_types;
 }
 
-static const OSSL_PARAM ml_dsa_params[] = {
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
-    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL),
-    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
-    ML_DSA_IMEXPORTABLE_PARAMETERS,
-    OSSL_PARAM_END
-};
+/* Machine generated by util/perl/OpenSSL/paramnames.pm */
+{- produce_param_list('static', 'ml_dsa_params',
+                      'static', 'ml_dsa_get_params_find_pidx',
+                      (['PKEY_PARAM_BITS',                  'int'],
+                       ['PKEY_PARAM_SECURITY_BITS',         'int'],
+                       ['PKEY_PARAM_MAX_SIZE',              'int'],
+                       ['PKEY_PARAM_SECURITY_CATEGORY',     'int'],
+                       ['PKEY_PARAM_MANDATORY_DIGEST',      'utf8_string'],
+                       ['PKEY_PARAM_ML_DSA_SEED',           'octet_string'],
+                       ['PKEY_PARAM_PUB_KEY',               'octet_string'],
+                       ['PKEY_PARAM_PRIV_KEY',              'octet_string'],
+                      )); -}
+/* End of machine generated */
+
 static const OSSL_PARAM *ml_dsa_gettable_params(void *provctx)
 {
     return ml_dsa_params;
@@ -312,47 +333,67 @@ static int ml_dsa_get_params(void *keydata, OSSL_PARAM params[])
 {
     ML_DSA_KEY *key = keydata;
     OSSL_PARAM *p;
-    const uint8_t *pub, *priv, *seed;
-
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
-            && !OSSL_PARAM_set_int(p, 8 * ossl_ml_dsa_key_get_pub_len(key)))
-        return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
-            && !OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_collision_strength_bits(key)))
-        return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
-            && !OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_sig_len(key)))
-        return 0;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_CATEGORY)) != NULL
-            && !OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_security_category(key)))
-        return 0;
-
-    pub = ossl_ml_dsa_key_get_pub(key);
-    priv = ossl_ml_dsa_key_get_priv(key);
-    seed = ossl_ml_dsa_key_get_seed(key);
-
-    if (seed != NULL
-        && (p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ML_DSA_SEED)) != NULL
-        && !OSSL_PARAM_set_octet_string(p, seed, ML_DSA_SEED_BYTES))
-        return 0;
-    if (priv != NULL
-        && (p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY)) != NULL
-        && !OSSL_PARAM_set_octet_string(p, priv,
-                                        ossl_ml_dsa_key_get_priv_len(key)))
-        return 0;
-    if (pub != NULL
-        && (p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY)) != NULL
-        && !OSSL_PARAM_set_octet_string(p, pub,
-                                        ossl_ml_dsa_key_get_pub_len(key)))
-        return 0;
-    /*
-     * This allows apps to use an empty digest, so that the old API
-     * for digest signing can be used.
-     */
-    p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MANDATORY_DIGEST);
-    if (p != NULL && !OSSL_PARAM_set_utf8_string(p, ""))
-        return 0;
-
+    const uint8_t *d;
+    size_t len;
+
+    for (p = params; p->key != NULL; p++)
+        switch (ml_dsa_get_params_find_pidx(p->key)) {
+        default:
+            break;
+
+        case PIDX_PKEY_PARAM_BITS:
+            if (!OSSL_PARAM_set_int(p, 8 * ossl_ml_dsa_key_get_pub_len(key)))
+                return 0;
+            break;
+
+        case PIDX_PKEY_PARAM_SECURITY_BITS:
+            if (!OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_collision_strength_bits(key)))
+                return 0;
+            break;
+
+        case PIDX_PKEY_PARAM_MAX_SIZE:
+            if (!OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_sig_len(key)))
+                return 0;
+            break;
+
+        case PIDX_PKEY_PARAM_SECURITY_CATEGORY:
+            if (!OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_security_category(key)))
+                return 0;
+            break;
+
+        case PIDX_PKEY_PARAM_ML_DSA_SEED:
+            d = ossl_ml_dsa_key_get_seed(key);
+            if (d != NULL && !OSSL_PARAM_set_octet_string(p, d, ML_DSA_SEED_BYTES))
+                return 0;
+            break;
+
+        case PIDX_PKEY_PARAM_PRIV_KEY:
+            d = ossl_ml_dsa_key_get_priv(key);
+            if (d != NULL) {
+                len = ossl_ml_dsa_key_get_priv_len(key);
+                if (!OSSL_PARAM_set_octet_string(p, d, len))
+                    return 0;
+            }
+            break;
+
+        case PIDX_PKEY_PARAM_PUB_KEY:
+            d = ossl_ml_dsa_key_get_pub(key);
+            if (d != NULL) {
+                len = ossl_ml_dsa_key_get_pub_len(key);
+                if (!OSSL_PARAM_set_octet_string(p, d, len))
+                    return 0;
+            }
+            break;
+
+        /*
+         * This allows apps to use an empty digest, so that the old API
+         * for digest signing can be used.
+         */
+        case PIDX_PKEY_PARAM_MANDATORY_DIGEST:
+            if (!OSSL_PARAM_set_utf8_string(p, ""))
+                return 0;
+            break;
+        }
     return 1;
 }