]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Update FIPS KATs for 140-3
authorPauli <pauli@openssl.org>
Wed, 26 Oct 2022 00:48:58 +0000 (11:48 +1100)
committerPauli <pauli@openssl.org>
Tue, 1 Nov 2022 21:42:46 +0000 (08:42 +1100)
Co-authored-by: Randall Steck <rsteck@thinqsoft.com>
Co-authored-by: Mark J. Minnoch <mark@keypair.us>
Co-authored-by: Steve Weymann <steve@keypair.us>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/19510)

include/openssl/self_test.h
providers/fips/self_test.c
providers/fips/self_test_data.inc
providers/fips/self_test_kats.c

index ee4949e5a640ddd0becd636421a627004032d9e2..337a3190ceadf298edc5b9d82b1b71b00ecac466 100644 (file)
@@ -30,6 +30,8 @@ extern "C" {
 # define OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY  "Install_Integrity"
 # define OSSL_SELF_TEST_TYPE_CRNG               "Continuous_RNG_Test"
 # define OSSL_SELF_TEST_TYPE_PCT                "Conditional_PCT"
+# define OSSL_SELF_TEST_TYPE_PCT_KAT            "Conditional_KAT"
+# define OSSL_SELF_TEST_TYPE_KAT_INTEGRITY      "KAT_Integrity"
 # define OSSL_SELF_TEST_TYPE_KAT_CIPHER         "KAT_Cipher"
 # define OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER    "KAT_AsymmetricCipher"
 # define OSSL_SELF_TEST_TYPE_KAT_DIGEST         "KAT_Digest"
index 42df9a4b87575c449b0eee8320b015eb4fd99203..e10b00b5aab77dee8e7251ec9ba491e84ca36607 100644 (file)
@@ -172,6 +172,64 @@ DEP_FINI_ATTRIBUTE void cleanup(void)
 }
 #endif
 
+/*
+ * We need an explicit HMAC-SHA-256 KAT even though it is also
+ * checked as part of the KDF KATs.  Refer IG 10.3.
+ */
+static const unsigned char hmac_kat_pt[] = {
+    0xdd, 0x0c, 0x30, 0x33, 0x35, 0xf9, 0xe4, 0x2e,
+    0xc2, 0xef, 0xcc, 0xbf, 0x07, 0x95, 0xee, 0xa2
+};
+static const unsigned char hmac_kat_key[] = {
+    0xf4, 0x55, 0x66, 0x50, 0xac, 0x31, 0xd3, 0x54,
+    0x61, 0x61, 0x0b, 0xac, 0x4e, 0xd8, 0x1b, 0x1a,
+    0x18, 0x1b, 0x2d, 0x8a, 0x43, 0xea, 0x28, 0x54,
+    0xcb, 0xae, 0x22, 0xca, 0x74, 0x56, 0x08, 0x13
+};
+static const unsigned char hmac_kat_digest[] = {
+    0xf5, 0xf5, 0xe5, 0xf2, 0x66, 0x49, 0xe2, 0x40,
+    0xfc, 0x9e, 0x85, 0x7f, 0x2b, 0x9a, 0xbe, 0x28,
+    0x20, 0x12, 0x00, 0x92, 0x82, 0x21, 0x3e, 0x51,
+    0x44, 0x5d, 0xe3, 0x31, 0x04, 0x01, 0x72, 0x6b
+};
+
+static int integrity_self_test(OSSL_SELF_TEST *ev, OSSL_LIB_CTX *libctx)
+{
+    int ok = 0;
+    unsigned char out[EVP_MAX_MD_SIZE];
+    size_t out_len = 0;
+
+    OSSL_PARAM   params[2];
+    EVP_MAC     *mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
+    EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac);
+
+    OSSL_SELF_TEST_onbegin(ev, OSSL_SELF_TEST_TYPE_KAT_INTEGRITY,
+                               OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
+
+    params[0] = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0);
+    params[1] = OSSL_PARAM_construct_end();
+
+    if (ctx == NULL
+            || mac == NULL
+            || !EVP_MAC_init(ctx, hmac_kat_key, sizeof(hmac_kat_key), params)
+            || !EVP_MAC_update(ctx, hmac_kat_pt, sizeof(hmac_kat_pt))
+            || !EVP_MAC_final(ctx, out, &out_len, MAX_MD_SIZE))
+        goto err;
+
+    /* Optional corruption */
+    OSSL_SELF_TEST_oncorrupt_byte(ev, out);
+
+    if (out_len != sizeof(hmac_kat_digest)
+            || memcmp(out, hmac_kat_digest, out_len) != 0)
+        goto err;
+    ok = 1;
+err:
+    OSSL_SELF_TEST_onend(ev, ok);
+    EVP_MAC_free(mac);
+    EVP_MAC_CTX_free(ctx);
+    return ok;
+}
+
 /*
  * Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify
  * the result matches the expected value.
@@ -190,6 +248,9 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex
     EVP_MAC_CTX *ctx = NULL;
     OSSL_PARAM params[2], *p = params;
 
+    if (!integrity_self_test(ev, libctx))
+        goto err;
+
     OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
 
     mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
@@ -355,6 +416,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
             goto end;
         }
     }
+
     ok = 1;
 end:
     OSSL_SELF_TEST_free(ev);
index 8ae8cd6f4a5a31683dd8d4a7100766c0228c2fcf..5895a31a5becfd6bb0b4523f5baa4568bbd913ea 100644 (file)
@@ -106,6 +106,12 @@ typedef struct st_kat_sign_st {
     const char *algorithm;
     const char *mdalgorithm;
     const ST_KAT_PARAM *key;
+    const unsigned char *entropy;
+    size_t entropy_len;
+    const unsigned char *nonce;
+    size_t nonce_len;
+    const unsigned char *persstr;
+    size_t persstr_len;
     const unsigned char *sig_expected; /* Set to NULL if this value changes */
     size_t sig_expected_len;
 } ST_KAT_SIGN;
@@ -235,19 +241,6 @@ static const unsigned char aes_128_ecb_ct[] = {
 };
 
 static const ST_KAT_CIPHER st_kat_cipher_tests[] = {
-#ifndef OPENSSL_NO_DES
-    {
-        {
-            OSSL_SELF_TEST_DESC_CIPHER_TDES,
-            "DES-EDE3-CBC",
-            ITM(des_ede3_cbc_pt),
-            ITM(des_ede3_cbc_ct)
-        },
-        CIPHER_MODE_ENCRYPT | CIPHER_MODE_DECRYPT,
-        ITM(des_ede3_cbc_key),
-        ITM(des_ede3_cbc_iv),
-    },
-#endif
     {
         {
             OSSL_SELF_TEST_DESC_CIPHER_AES_GCM,
@@ -1396,6 +1389,16 @@ static const unsigned char ecd_prime_pub[] = {
     0xc4, 0xb7, 0x33, 0x68, 0xe4, 0x24, 0xa9, 0x12,
     0x82
 };
+static const unsigned char ecdsa_prime_expected_sig[] = {
+    0x30, 0x3d, 0x02, 0x1d, 0x00, 0xd2, 0x4a, 0xc9,
+    0x4f, 0xaf, 0xdb, 0x62, 0xfc, 0x41, 0x4a, 0x81,
+    0x2a, 0x9f, 0xcf, 0xa3, 0xda, 0xfe, 0xa3, 0x49,
+    0xbd, 0xea, 0xbf, 0x2a, 0x51, 0xb4, 0x0b, 0xc3,
+    0xbc, 0x02, 0x1c, 0x7f, 0x30, 0xb7, 0xad, 0xab,
+    0x09, 0x6e, 0x3c, 0xad, 0x7f, 0xf9, 0x5e, 0xaa,
+    0xe2, 0x38, 0xe5, 0x29, 0x16, 0xc4, 0xc8, 0x77,
+    0xa1, 0xf8, 0x60, 0x77, 0x39, 0x7a, 0xec
+};
 static const ST_KAT_PARAM ecdsa_prime_key[] = {
     ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_prime_curve_name),
     ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecd_prime_pub),
@@ -1421,6 +1424,17 @@ static const unsigned char ecd_bin_pub[] = {
     0x02, 0xa8, 0xe9, 0x6f, 0x54, 0xfd, 0x3a, 0x6b,
     0x99, 0xb6, 0x8f, 0x80, 0x46
 };
+static const unsigned char ecdsa_bin_expected_sig[] = {
+    0x30, 0x3f, 0x02, 0x1d, 0x08, 0x11, 0x7c, 0xcd,
+    0xf4, 0xa1, 0x31, 0x9a, 0xc1, 0xfd, 0x50, 0x0e,
+    0x5d, 0xa9, 0xb6, 0x0e, 0x95, 0x49, 0xe1, 0xbd,
+    0x44, 0xe3, 0x5b, 0xa9, 0x35, 0x94, 0xa5, 0x2f,
+    0xae, 0x02, 0x1e, 0x00, 0xe3, 0xba, 0xb8, 0x8f,
+    0x4b, 0x05, 0x76, 0x88, 0x1e, 0x49, 0xd6, 0x62,
+    0x76, 0xd3, 0x22, 0x4d, 0xa3, 0x7b, 0x04, 0xcc,
+    0xfa, 0x7b, 0x41, 0x9b, 0x8c, 0xaf, 0x1b, 0x6d,
+    0xbd
+};
 static const ST_KAT_PARAM ecdsa_bin_key[] = {
     ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_bin_curve_name),
     ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecd_bin_pub),
@@ -1546,6 +1560,16 @@ static const unsigned char dsa_priv[] = {
     0x66, 0x35, 0xba, 0xc3, 0x94, 0x23, 0x50, 0x5e,
     0x40, 0x7e, 0x5c, 0xb7
 };
+static const unsigned char dsa_expected_sig[] = {
+    0x30, 0x3c, 0x02, 0x1c, 0x70, 0xa4, 0x77, 0xb6,
+    0x02, 0xb5, 0xd3, 0x07, 0x21, 0x22, 0x2d, 0xe3,
+    0x4f, 0x7d, 0xfd, 0xfd, 0x6b, 0x4f, 0x03, 0x27,
+    0x4c, 0xd3, 0xb2, 0x8c, 0x7c, 0xc5, 0xc4, 0xdf,
+    0x02, 0x1c, 0x11, 0x52, 0x65, 0x16, 0x9f, 0xbd,
+    0x4c, 0xe5, 0xab, 0xb2, 0x01, 0xd0, 0x7a, 0x30,
+    0x5c, 0xc5, 0xba, 0x22, 0xc6, 0x62, 0x7e, 0xa6,
+    0x7d, 0x98, 0x96, 0xc9, 0x77, 0x00
+};
 
 static const ST_KAT_PARAM dsa_key[] = {
     ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_FFC_P, dsa_p),
@@ -1557,12 +1581,31 @@ static const ST_KAT_PARAM dsa_key[] = {
 };
 #endif /* OPENSSL_NO_DSA */
 
+/* Hash DRBG inputs for signature KATs */
+static const unsigned char sig_kat_entropyin[] = {
+    0x06, 0x6d, 0xc8, 0xce, 0x75, 0xb2, 0x89, 0x66, 0xa6, 0x85, 0x16, 0x3f,
+    0xe2, 0xa4, 0xd4, 0x27, 0xfb, 0xdb, 0x61, 0x66, 0x50, 0x61, 0x6b, 0xa2,
+    0x82, 0xfc, 0x33, 0x2b, 0x4e, 0x6f, 0x12, 0x20
+};
+static const unsigned char sig_kat_nonce[] = {
+    0x55, 0x9f, 0x7c, 0x64, 0x89, 0x70, 0x83, 0xec, 0x2d, 0x73, 0x70, 0xd9,
+    0xf0, 0xe5, 0x07, 0x1f
+};
+static const unsigned char sig_kat_persstr[] = {
+    0x88, 0x6f, 0x54, 0x9a, 0xad, 0x1a, 0xc6, 0x3d, 0x18, 0xcb, 0xcc, 0x66,
+    0x85, 0xda, 0xa2, 0xc2, 0xf7, 0x9e, 0xb0, 0x89, 0x4c, 0xb4, 0xae, 0xf1,
+    0xac, 0x54, 0x4f, 0xce, 0x57, 0xf1, 0x5e, 0x11
+};
+
 static const ST_KAT_SIGN st_kat_sign_tests[] = {
     {
         OSSL_SELF_TEST_DESC_SIGN_RSA,
         "RSA",
         "SHA-256",
         rsa_crt_key,
+        ITM(sig_kat_entropyin),
+        ITM(sig_kat_nonce),
+        ITM(sig_kat_persstr),
         ITM(rsa_expected_sig)
     },
 #ifndef OPENSSL_NO_EC
@@ -1571,10 +1614,10 @@ static const ST_KAT_SIGN st_kat_sign_tests[] = {
         "EC",
         "SHA-256",
         ecdsa_prime_key,
-        /*
-         * The ECDSA signature changes each time due to it using a random k.
-         * So there is no expected KAT for this case.
-         */
+        ITM(sig_kat_entropyin),
+        ITM(sig_kat_nonce),
+        ITM(sig_kat_persstr),
+        ITM(ecdsa_prime_expected_sig)
     },
 # ifndef OPENSSL_NO_EC2M
     {
@@ -1582,10 +1625,10 @@ static const ST_KAT_SIGN st_kat_sign_tests[] = {
         "EC",
         "SHA-256",
         ecdsa_bin_key,
-        /*
-         * The ECDSA signature changes each time due to it using a random k.
-         * So there is no expected KAT for this case.
-         */
+        ITM(sig_kat_entropyin),
+        ITM(sig_kat_nonce),
+        ITM(sig_kat_persstr),
+        ITM(ecdsa_bin_expected_sig)
     },
 # endif
 #endif /* OPENSSL_NO_EC */
@@ -1595,10 +1638,10 @@ static const ST_KAT_SIGN st_kat_sign_tests[] = {
         "DSA",
         "SHA-256",
         dsa_key,
-        /*
-         * The DSA signature changes each time due to it using a random k.
-         * So there is no expected KAT for this case.
-         */
+        ITM(sig_kat_entropyin),
+        ITM(sig_kat_nonce),
+        ITM(sig_kat_persstr),
+        ITM(dsa_expected_sig)
     },
 #endif /* OPENSSL_NO_DSA */
 };
index 3a7d095c7b6a96f3ea706849611eab17e16dfd9d..bdf599aaada4188a9b8482b4cef1ea382e691dd1 100644 (file)
 #include <openssl/kdf.h>
 #include <openssl/core_names.h>
 #include <openssl/param_build.h>
+#include <openssl/rand.h>
 #include "internal/cryptlib.h"
 #include "internal/nelem.h"
 #include "self_test.h"
 #include "self_test_data.inc"
 
+static int set_kat_drbg(OSSL_LIB_CTX *ctx,
+                        const unsigned char *entropy, size_t entropy_len,
+                        const unsigned char *nonce, size_t nonce_len,
+                        const unsigned char *persstr, size_t persstr_len);
+static int reset_original_drbg(OSSL_LIB_CTX *ctx);
+
 static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st,
                             OSSL_LIB_CTX *libctx)
 {
@@ -437,7 +444,7 @@ err:
 #endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */
 
 static int self_test_sign(const ST_KAT_SIGN *t,
-                         OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
+                          OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
 {
     int ret = 0;
     OSSL_PARAM *params = NULL, *params_sig = NULL;
@@ -499,10 +506,6 @@ static int self_test_sign(const ST_KAT_SIGN *t,
         || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0)
         goto err;
 
-    /*
-     * Used by RSA, for other key types where the signature changes, we
-     * can only use the verify.
-     */
     if (t->sig_expected != NULL
         && (siglen != t->sig_expected_len
             || memcmp(sig, t->sig_expected, t->sig_expected_len) != 0))
@@ -689,9 +692,16 @@ static int self_test_kas(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
 static int self_test_signatures(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
 {
     int i, ret = 1;
-
-    for (i = 0; i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) {
-        if (!self_test_sign(&st_kat_sign_tests[i], st, libctx))
+    const ST_KAT_SIGN *t;
+
+    for (i = 0; ret && i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) {
+        t = st_kat_sign_tests + i;
+        if (!set_kat_drbg(libctx, t->entropy, t->entropy_len,
+                          t->nonce, t->nonce_len, t->persstr, t->persstr_len))
+            return 0;
+        if (!self_test_sign(t, st, libctx))
+            ret = 0;
+        if (!reset_original_drbg(libctx))
             ret = 0;
     }
     return ret;
@@ -723,3 +733,121 @@ int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
 
     return ret;
 }
+
+/*
+ * Swap the library context DRBG for KAT testing
+ *
+ * In FIPS 140-3, the asymmetric POST must be a KAT, not a PCT.  For DSA and ECDSA,
+ * the sign operation includes the random value 'k'.  For a KAT to work, we
+ * have to have control of the DRBG to make sure it is in a "test" state, where
+ * its output is truly deterministic.
+ *
+ */
+
+/*
+ * The default private DRBG of the library context, saved for the duration
+ * of KAT testing.
+ */
+static EVP_RAND_CTX *saved_rand = NULL;
+
+/* Replacement "random" source */
+static EVP_RAND_CTX *kat_rand = NULL;
+
+static int set_kat_drbg(OSSL_LIB_CTX *ctx,
+                        const unsigned char *entropy, size_t entropy_len,
+                        const unsigned char *nonce, size_t nonce_len,
+                        const unsigned char *persstr, size_t persstr_len) {
+    EVP_RAND *rand;
+    unsigned int strength = 256;
+    EVP_RAND_CTX *parent_rand = NULL;
+    OSSL_PARAM drbg_params[3] = {
+        OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END
+    };
+
+    /* If not NULL, we didn't cleanup from last call: BAD */
+    if (kat_rand != NULL || saved_rand != NULL)
+        return 0;
+
+    rand = EVP_RAND_fetch(ctx, "TEST-RAND", NULL);
+    if (rand == NULL)
+        return 0;
+
+    parent_rand = EVP_RAND_CTX_new(rand, NULL);
+    EVP_RAND_free(rand);
+    if (parent_rand == NULL)
+        goto err;
+
+    drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &strength);
+    if (!EVP_RAND_CTX_set_params(parent_rand, drbg_params))
+        goto err;
+
+    rand = EVP_RAND_fetch(ctx, "HASH-DRBG", NULL);
+    if (rand == NULL)
+        goto err;
+
+    kat_rand = EVP_RAND_CTX_new(rand, parent_rand);
+    EVP_RAND_free(rand);
+    if (kat_rand == NULL)
+        goto err;
+
+    drbg_params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA256", 0);
+    if (!EVP_RAND_CTX_set_params(kat_rand, drbg_params))
+        goto err;
+
+    /* Instantiate the RNGs */
+    drbg_params[0] =
+        OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
+                                          (void *)entropy, entropy_len);
+    drbg_params[1] =
+        OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE,
+                                          (void *)nonce, nonce_len);
+    if (!EVP_RAND_instantiate(parent_rand, strength, 0, NULL, 0, drbg_params))
+        goto err;
+
+    EVP_RAND_CTX_free(parent_rand);
+    parent_rand = NULL;
+
+    if (!EVP_RAND_instantiate(kat_rand, strength, 0, persstr, persstr_len, NULL))
+        goto err;
+
+    /* Update the library context DRBG */
+    if ((saved_rand = RAND_get0_private(ctx)) != NULL)
+        /* Avoid freeing this since we replace it */
+        if (!EVP_RAND_CTX_up_ref(saved_rand)) {
+            saved_rand = NULL;
+            goto err;
+        }
+    if (RAND_set0_private(ctx, kat_rand) > 0) {
+        /* Keeping a copy to verify zeroization */
+        if (EVP_RAND_CTX_up_ref(kat_rand))
+            return 1;
+        if (saved_rand != NULL)
+            RAND_set0_private(ctx, saved_rand);
+    }
+
+ err:
+    EVP_RAND_CTX_free(parent_rand);
+    EVP_RAND_CTX_free(saved_rand);
+    EVP_RAND_CTX_free(kat_rand);
+    kat_rand = saved_rand = NULL;
+    return 0;
+}
+
+static int reset_original_drbg(OSSL_LIB_CTX *ctx) {
+    int ret = 1;
+
+    if (saved_rand != NULL) {
+        if (!RAND_set0_private(ctx, saved_rand))
+            ret = 0;
+        saved_rand = NULL;
+    }
+    if (kat_rand != NULL) {
+        if (!EVP_RAND_uninstantiate(kat_rand)
+                || !EVP_RAND_verify_zeroization(kat_rand))
+            ret = 0;
+        EVP_RAND_CTX_free(kat_rand);
+        kat_rand = NULL;
+    }
+    return ret;
+}
+