]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
fips: refactor to unify the ST_KAT_PARAM -> OSSL_PARAM code
authorPauli <ppzgs1@gmail.com>
Fri, 21 Feb 2025 00:37:43 +0000 (11:37 +1100)
committerViktor Dukhovni <openssl-users@dukhovni.org>
Sat, 22 Feb 2025 06:31:43 +0000 (17:31 +1100)
This code was duplicated multiple times throughout the self tests.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26859)

providers/fips/self_test_kats.c

index c31472b9d79874467db3645307fca3fc456cad38..365de58c90315a80913d73344230ff3cab622144 100644 (file)
@@ -201,6 +201,49 @@ err:
     return ret;
 }
 
+#if defined(__GNUC__) && __GNUC__ >= 4
+# define SENTINEL __attribute__((sentinel))
+#endif
+
+#if !defined(SENTINEL) && defined(__clang_major__) && __clang_major__ > 14
+# define SENTINEL __attribute__((sentinel))
+#endif
+
+#ifndef SENTINEL
+# define SENTINEL
+#endif
+
+static SENTINEL OSSL_PARAM *kat_params_to_ossl_params(OSSL_LIB_CTX *libctx, ...)
+{
+    BN_CTX *bnc = NULL;
+    OSSL_PARAM *params = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    const ST_KAT_PARAM *pms;
+    va_list ap;
+
+    bnc = BN_CTX_new_ex(libctx);
+    if (bnc == NULL)
+        goto err;
+    bld = OSSL_PARAM_BLD_new();
+    if (bld == NULL)
+        goto err;
+
+    va_start(ap, libctx);
+    while ((pms = va_arg(ap, const ST_KAT_PARAM *)) != NULL)
+        if (!add_params(bld, pms, bnc)) {
+            va_end(ap);
+            goto err;
+        }
+    va_end(ap);
+
+    params = OSSL_PARAM_BLD_to_param(bld);
+
+ err:
+    OSSL_PARAM_BLD_free(bld);
+    BN_CTX_free(bnc);
+    return params;
+}
+
 static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st,
                          OSSL_LIB_CTX *libctx)
 {
@@ -208,16 +251,10 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st,
     unsigned char out[128];
     EVP_KDF *kdf = NULL;
     EVP_KDF_CTX *ctx = NULL;
-    BN_CTX *bnctx = NULL;
-    OSSL_PARAM *params  = NULL;
-    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *params = NULL;
 
     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc);
 
-    bld = OSSL_PARAM_BLD_new();
-    if (bld == NULL)
-        goto err;
-
     kdf = EVP_KDF_fetch(libctx, t->algorithm, "");
     if (kdf == NULL)
         goto err;
@@ -226,12 +263,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st,
     if (ctx == NULL)
         goto err;
 
-    bnctx = BN_CTX_new_ex(libctx);
-    if (bnctx == NULL)
-        goto err;
-    if (!add_params(bld, t->params, bnctx))
-        goto err;
-    params = OSSL_PARAM_BLD_to_param(bld);
+    params = kat_params_to_ossl_params(libctx, t->params, NULL);
     if (params == NULL)
         goto err;
 
@@ -249,9 +281,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st,
 err:
     EVP_KDF_free(kdf);
     EVP_KDF_CTX_free(ctx);
-    BN_CTX_free(bnctx);
     OSSL_PARAM_free(params);
-    OSSL_PARAM_BLD_free(bld);
     OSSL_SELF_TEST_onend(st, ret);
     return ret;
 }
@@ -378,32 +408,16 @@ static int self_test_ka(const ST_KAT_KAS *t,
     OSSL_PARAM *params_peer = NULL;
     unsigned char secret[256];
     size_t secret_len = t->expected_len;
-    OSSL_PARAM_BLD *bld = NULL;
-    BN_CTX *bnctx = NULL;
 
     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KA, t->desc);
 
     if (secret_len > sizeof(secret))
         goto err;
 
-    bnctx = BN_CTX_new_ex(libctx);
-    if (bnctx == NULL)
-        goto err;
-
-    bld = OSSL_PARAM_BLD_new();
-    if (bld == NULL)
-        goto err;
-
-    if (!add_params(bld, t->key_group, bnctx)
-        || !add_params(bld, t->key_host_data, bnctx))
-        goto err;
-    params = OSSL_PARAM_BLD_to_param(bld);
-
-    if (!add_params(bld, t->key_group, bnctx)
-        || !add_params(bld, t->key_peer_data, bnctx))
-        goto err;
-
-    params_peer = OSSL_PARAM_BLD_to_param(bld);
+    params = kat_params_to_ossl_params(libctx, t->key_group,
+                                       t->key_host_data, NULL);
+    params_peer = kat_params_to_ossl_params(libctx, t->key_group,
+                                            t->key_peer_data, NULL);
     if (params == NULL || params_peer == NULL)
         goto err;
 
@@ -435,14 +449,12 @@ static int self_test_ka(const ST_KAT_KAS *t,
         goto err;
     ret = 1;
 err:
-    BN_CTX_free(bnctx);
     EVP_PKEY_free(pkey);
     EVP_PKEY_free(peerkey);
     EVP_PKEY_CTX_free(kactx);
     EVP_PKEY_CTX_free(dctx);
     OSSL_PARAM_free(params_peer);
     OSSL_PARAM_free(params);
-    OSSL_PARAM_BLD_free(bld);
     OSSL_SELF_TEST_onend(st, ret);
     return ret;
 }
@@ -473,13 +485,11 @@ static int self_test_digest_sign(const ST_KAT_SIGN *t,
 {
     int ret = 0;
     OSSL_PARAM *paramskey = NULL, *paramsinit = NULL, *paramsverify = NULL;
-    OSSL_PARAM_BLD *bldkey = NULL, *bldinit = NULL, *bldverify = NULL;
     EVP_SIGNATURE *sigalg = NULL;
     EVP_PKEY_CTX *ctx = NULL;
     EVP_PKEY_CTX *fromctx = NULL;
     EVP_PKEY *pkey = NULL;
     unsigned char sig[MAX_ML_DSA_SIG_LEN], *psig = sig;
-    BN_CTX *bnctx = NULL;
     size_t siglen;
     int digested = 0;
     const char *typ = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE;
@@ -498,23 +508,9 @@ static int self_test_digest_sign(const ST_KAT_SIGN *t,
             goto err;
     }
 
-    bnctx = BN_CTX_new_ex(libctx);
-    if (bnctx == NULL)
-        goto err;
-
-    bldkey = OSSL_PARAM_BLD_new();
-    bldinit = OSSL_PARAM_BLD_new();
-    bldverify = OSSL_PARAM_BLD_new();
-    if (bldkey == NULL || bldinit == NULL || bldverify == NULL)
-        goto err;
-
-    if (!add_params(bldkey, t->key, bnctx)
-            || !add_params(bldinit, t->init, bnctx)
-            || !add_params(bldverify, t->verify, bnctx))
-        goto err;
-    paramskey = OSSL_PARAM_BLD_to_param(bldkey);
-    paramsinit = OSSL_PARAM_BLD_to_param(bldinit);
-    paramsverify = OSSL_PARAM_BLD_to_param(bldverify);
+    paramskey = kat_params_to_ossl_params(libctx, t->key, NULL);
+    paramsinit = kat_params_to_ossl_params(libctx, t->init, NULL);
+    paramsverify = kat_params_to_ossl_params(libctx, t->verify, NULL);
 
     fromctx = EVP_PKEY_CTX_new_from_name(libctx, t->keytype, NULL);
     if (fromctx == NULL
@@ -593,7 +589,6 @@ static int self_test_digest_sign(const ST_KAT_SIGN *t,
 err:
     if (psig != sig)
         OPENSSL_free(psig);
-    BN_CTX_free(bnctx);
     EVP_PKEY_free(pkey);
     EVP_PKEY_CTX_free(fromctx);
     EVP_PKEY_CTX_free(ctx);
@@ -601,9 +596,6 @@ err:
     OSSL_PARAM_free(paramskey);
     OSSL_PARAM_free(paramsinit);
     OSSL_PARAM_free(paramsverify);
-    OSSL_PARAM_BLD_free(bldkey);
-    OSSL_PARAM_BLD_free(bldinit);
-    OSSL_PARAM_BLD_free(bldverify);
     if (t->entropy != NULL) {
         if (!reset_main_drbg(libctx))
             ret = 0;
@@ -622,7 +614,6 @@ static int self_test_asym_keygen(const ST_KAT_ASYM_KEYGEN *t, OSSL_SELF_TEST *st
     int ret = 0;
     const ST_KAT_PARAM *expected;
     OSSL_PARAM *key_params = NULL;
-    OSSL_PARAM_BLD *key_bld = NULL;
     EVP_PKEY_CTX *key_ctx = NULL;
     EVP_PKEY *key = NULL;
     uint8_t out[MAX_ML_DSA_PRIV_LEN];
@@ -634,11 +625,7 @@ static int self_test_asym_keygen(const ST_KAT_ASYM_KEYGEN *t, OSSL_SELF_TEST *st
     if (key_ctx == NULL)
         goto err;
     if (t->keygen_params != NULL) {
-        key_bld = OSSL_PARAM_BLD_new();
-        if (key_bld == NULL
-                || !add_params(key_bld, t->keygen_params, NULL))
-            goto err;
-        key_params = OSSL_PARAM_BLD_to_param(key_bld);
+        key_params = kat_params_to_ossl_params(libctx, t->keygen_params, NULL);
         if (key_params == NULL)
             goto err;
     }
@@ -663,7 +650,6 @@ err:
     EVP_PKEY_free(key);
     EVP_PKEY_CTX_free(key_ctx);
     OSSL_PARAM_free(key_params);
-    OSSL_PARAM_BLD_free(key_bld);
     OSSL_SELF_TEST_onend(st, ret);
     return ret;
 }
@@ -784,58 +770,6 @@ static int self_test_kem_decapsulate(const ST_KAT_KEM *t, OSSL_SELF_TEST *st,
     return ret;
 }
 
-/*
- * FIPS 140-3 IG 10.3.A resolution 14 mandates a CAST for ML-KEM
- * key generation.
- */
-static EVP_PKEY *self_test_kem_keygen(const ST_KAT_KEM *t, OSSL_SELF_TEST *st,
-                                      OSSL_LIB_CTX *libctx)
-{
-    EVP_PKEY_CTX *genctx;
-    EVP_PKEY *ret = NULL, *r = NULL;
-    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
-    unsigned char *buf = NULL;
-    const size_t s = t->public_key_len < t->private_key_len ? t->private_key_len
-                                                            : t->public_key_len;
-
-    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KEM,
-                           OSSL_SELF_TEST_DESC_KEYGEN_KEM);
-
-    genctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, "");
-    if (genctx == NULL || EVP_PKEY_keygen_init(genctx) <= 0)
-        goto err;
-    *params = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_ML_KEM_SEED,
-                                                (unsigned char *)t->seed,
-                                                t->seed_len);
-    if (!EVP_PKEY_CTX_set_params(genctx, params)
-            || !EVP_PKEY_keygen(genctx, &r))
-        goto err;
-
-    /* Allocate output space */
-    buf = OPENSSL_malloc(s);
-    if (buf == NULL)
-        goto err;
-
-    /* Compare outputs */
-    *params = OSSL_PARAM_construct_octet_string(
-        OSSL_PKEY_PARAM_PRIV_KEY, buf, s);
-    if (!EVP_PKEY_get_params(r, params))
-        goto err;
-    OSSL_SELF_TEST_oncorrupt_byte(st, buf);
-    if (params->return_size != t->private_key_len
-            || memcmp(buf, t->private_key, t->private_key_len) != 0)
-        goto err;
-
-    ret = r;
-    r = NULL;
- err:
-    OPENSSL_free(buf);
-    EVP_PKEY_CTX_free(genctx);
-    EVP_PKEY_free(r);
-    OSSL_SELF_TEST_onend(st, ret != NULL);
-    return ret;
-}
-
 /*
  * Test encapsulation, decapsulation for KEM.
  *
@@ -850,9 +784,18 @@ static int self_test_kem(const ST_KAT_KEM *t, OSSL_SELF_TEST *st,
 {
     int ret = 0;
     EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx;
+    OSSL_PARAM *params = NULL;
+
+    ctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL);
+    if (ctx == NULL)
+        goto err;
+    params = kat_params_to_ossl_params(libctx, t->key, NULL);
+    if (params == NULL)
+        goto err;
 
-    pkey = self_test_kem_keygen(t, st, libctx);
-    if (pkey == NULL)
+    if (EVP_PKEY_fromdata_init(ctx) <= 0
+            || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
         goto err;
 
     if (!self_test_kem_encapsulate(t, st, libctx, pkey)
@@ -862,7 +805,9 @@ static int self_test_kem(const ST_KAT_KEM *t, OSSL_SELF_TEST *st,
 
     ret = 1;
 err:
+    EVP_PKEY_CTX_free(ctx);
     EVP_PKEY_free(pkey);
+    OSSL_PARAM_free(params);
     return ret;
 }
 #endif