# 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_ASYM_KEYGEN "KAT_AsymmetricKeyGeneration"
# define OSSL_SELF_TEST_TYPE_KAT_DIGEST "KAT_Digest"
# define OSSL_SELF_TEST_TYPE_KAT_SIGNATURE "KAT_Signature"
# define OSSL_SELF_TEST_TYPE_PCT_SIGNATURE "PCT_Signature"
# define OSSL_SELF_TEST_DESC_KDF_TLS13_EXTRACT "TLS13_KDF_EXTRACT"
# define OSSL_SELF_TEST_DESC_KDF_TLS13_EXPAND "TLS13_KDF_EXPAND"
# define OSSL_SELF_TEST_DESC_RNG "RNG"
+# define OSSL_SELF_TEST_DESC_KEYGEN_ML_DSA "ML-DSA"
void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb,
void *cbarg);
size_t expected_len;
} ST_KAT_ASYM_CIPHER;
+typedef struct st_kat_keygen_st {
+ const char *desc;
+ const char *algorithm;
+ const ST_KAT_PARAM *keygen_params;
+ const ST_KAT_PARAM *expected_params;
+} ST_KAT_ASYM_KEYGEN;
+
/*- DIGEST SELF TEST DATA */
static const unsigned char sha512_pt[] = "abc";
static const unsigned char sha512_digest[] = {
* it fails the h_ones rejection test on iteration three
* it successfully generates the signature on iteration four
* Thus, it is an optimal self test in terms of iterations and coverage.
+ *
+ * Refer to FIPS 140-3 IG 10.3.A.15 for details of the testing requirements.
*/
static const unsigned char ml_dsa_65_msg[] = {
0x23, 0x37, 0x34, 0x37, 0x36, 0x38, 0x23
},
#endif /* OPENSSL_NO_ML_DSA */
};
+
+
+#if !defined(OPENSSL_NO_ML_DSA)
+static const ST_KAT_PARAM ml_dsa_keygen_params[] = {
+ ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_ML_DSA_SEED, sig_kat_entropyin),
+ ST_KAT_PARAM_END()
+};
+
+static const ST_KAT_ASYM_KEYGEN st_kat_asym_keygen_tests[] = {
+ {
+ OSSL_SELF_TEST_DESC_KEYGEN_ML_DSA,
+ "ML-DSA-65",
+ ml_dsa_keygen_params,
+ ml_dsa_key
+ },
+};
+#endif /* !OPENSSL_NO_ML_DSA */
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include <openssl/rand.h>
+#include "crypto/ml_dsa.h"
#include "crypto/rand.h"
#include "internal/cryptlib.h"
#include "internal/nelem.h"
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY_CTX *fromctx = NULL;
EVP_PKEY *pkey = NULL;
- unsigned char sig[5000];
+ unsigned char sig[MAX_ML_DSA_SIG_LEN];
BN_CTX *bnctx = NULL;
size_t siglen = sizeof(sig);
int digested = 0;
return ret;
}
+/*
+ * Test that a deterministic key generation produces the correct key
+ */
+static int self_test_asym_keygen(const ST_KAT_ASYM_KEYGEN *t, OSSL_SELF_TEST *st,
+ OSSL_LIB_CTX *libctx)
+{
+ 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];
+ size_t out_len = 0;
+
+ OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_ASYM_KEYGEN, t->desc);
+
+ key_ctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL);
+ 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);
+ if (key_params == NULL)
+ goto err;
+ }
+ if (EVP_PKEY_keygen_init(key_ctx) != 1
+ || EVP_PKEY_CTX_set_params(key_ctx, key_params) != 1
+ || EVP_PKEY_generate(key_ctx, &key) != 1)
+ goto err;
+
+ for (expected = t->expected_params; expected->data != NULL; ++expected) {
+ if (expected->type != OSSL_PARAM_OCTET_STRING
+ || !EVP_PKEY_get_octet_string_param(key, expected->name,
+ out, sizeof(out), &out_len))
+ goto err;
+ OSSL_SELF_TEST_oncorrupt_byte(st, out);
+ /* Check the KAT */
+ if (out_len != expected->data_len
+ || memcmp(out, expected->data, expected->data_len) != 0)
+ goto err;
+ }
+ ret = 1;
+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;
+}
+
/*
* Test a data driven list of KAT's for digest algorithms.
* All tests are run regardless of if they fail or not.
return 0;
}
+static int self_test_asym_keygens(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
+{
+ int i, ret = 1;
+
+ for (i = 0; i < (int)OSSL_NELEM(st_kat_asym_keygen_tests); ++i) {
+ if (!self_test_asym_keygen(&st_kat_asym_keygen_tests[i], st, libctx))
+ ret = 0;
+ }
+ return ret;
+}
+
/*
* Run the algorithm KAT's.
* Return 1 is successful, otherwise return 0.
ret = 0;
if (!self_test_kas(st, libctx))
ret = 0;
+ if (!self_test_asym_keygens(st, libctx))
+ ret = 0;
RAND_set0_private(libctx, saved_rand);
return ret;