Path: blob/main/crypto/openssl/providers/fips/self_test_kats.c
48262 views
/*1* Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <string.h>10#include <openssl/evp.h>11#include <openssl/kdf.h>12#include <openssl/core_names.h>13#include <openssl/param_build.h>14#include <openssl/rand.h>15#include "crypto/ml_dsa.h"16#include "crypto/rand.h"17#include "internal/cryptlib.h"18#include "internal/nelem.h"19#include "self_test.h"20#include "crypto/ml_kem.h"21#include "self_test_data.inc"2223static int set_kat_drbg(OSSL_LIB_CTX *ctx,24const unsigned char *entropy, size_t entropy_len,25const unsigned char *nonce, size_t nonce_len,26const unsigned char *persstr, size_t persstr_len);27static int reset_main_drbg(OSSL_LIB_CTX *ctx);2829static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st,30OSSL_LIB_CTX *libctx)31{32int ok = 0;33unsigned char out[EVP_MAX_MD_SIZE];34unsigned int out_len = 0;35EVP_MD_CTX *ctx = EVP_MD_CTX_new();36EVP_MD *md = EVP_MD_fetch(libctx, t->algorithm, NULL);3738OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_DIGEST, t->desc);3940if (ctx == NULL41|| md == NULL42|| !EVP_DigestInit_ex(ctx, md, NULL)43|| !EVP_DigestUpdate(ctx, t->pt, t->pt_len)44|| !EVP_DigestFinal(ctx, out, &out_len))45goto err;4647/* Optional corruption */48OSSL_SELF_TEST_oncorrupt_byte(st, out);4950if (out_len != t->expected_len51|| memcmp(out, t->expected, out_len) != 0)52goto err;53ok = 1;54err:55EVP_MD_free(md);56EVP_MD_CTX_free(ctx);57OSSL_SELF_TEST_onend(st, ok);58return ok;59}6061/*62* Helper function to setup a EVP_CipherInit63* Used to hide the complexity of Authenticated ciphers.64*/65static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,66const ST_KAT_CIPHER *t, int enc)67{68unsigned char *in_tag = NULL;69int pad = 0, tmp;7071/* Flag required for Key wrapping */72EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);73if (t->tag == NULL) {74/* Use a normal cipher init */75return EVP_CipherInit_ex(ctx, cipher, NULL, t->key, t->iv, enc)76&& EVP_CIPHER_CTX_set_padding(ctx, pad);77}7879/* The authenticated cipher init */80if (!enc)81in_tag = (unsigned char *)t->tag;8283return EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)84&& (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, t->iv_len, NULL) > 0)85&& (in_tag == NULL86|| EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, t->tag_len,87in_tag) > 0)88&& EVP_CipherInit_ex(ctx, NULL, NULL, t->key, t->iv, enc)89&& EVP_CIPHER_CTX_set_padding(ctx, pad)90&& EVP_CipherUpdate(ctx, NULL, &tmp, t->aad, t->aad_len);91}9293/* Test a single KAT for encrypt/decrypt */94static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_SELF_TEST *st,95OSSL_LIB_CTX *libctx)96{97int ret = 0, encrypt = 1, len = 0, ct_len = 0, pt_len = 0;98EVP_CIPHER_CTX *ctx = NULL;99EVP_CIPHER *cipher = NULL;100unsigned char ct_buf[256] = { 0 };101unsigned char pt_buf[256] = { 0 };102103OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_CIPHER, t->base.desc);104105ctx = EVP_CIPHER_CTX_new();106if (ctx == NULL)107goto err;108cipher = EVP_CIPHER_fetch(libctx, t->base.algorithm, NULL);109if (cipher == NULL)110goto err;111112/* Encrypt plain text message */113if ((t->mode & CIPHER_MODE_ENCRYPT) != 0) {114if (!cipher_init(ctx, cipher, t, encrypt)115|| !EVP_CipherUpdate(ctx, ct_buf, &len, t->base.pt,116t->base.pt_len)117|| !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len))118goto err;119120OSSL_SELF_TEST_oncorrupt_byte(st, ct_buf);121ct_len += len;122if (ct_len != (int)t->base.expected_len123|| memcmp(t->base.expected, ct_buf, ct_len) != 0)124goto err;125126if (t->tag != NULL) {127unsigned char tag[16] = { 0 };128129if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, t->tag_len,130tag) <= 0131|| memcmp(tag, t->tag, t->tag_len) != 0)132goto err;133}134}135136/* Decrypt cipher text */137if ((t->mode & CIPHER_MODE_DECRYPT) != 0) {138if (!(cipher_init(ctx, cipher, t, !encrypt)139&& EVP_CipherUpdate(ctx, pt_buf, &len,140t->base.expected, t->base.expected_len)141&& EVP_CipherFinal_ex(ctx, pt_buf + len, &pt_len)))142goto err;143OSSL_SELF_TEST_oncorrupt_byte(st, pt_buf);144pt_len += len;145if (pt_len != (int)t->base.pt_len146|| memcmp(pt_buf, t->base.pt, pt_len) != 0)147goto err;148}149150ret = 1;151err:152EVP_CIPHER_free(cipher);153EVP_CIPHER_CTX_free(ctx);154OSSL_SELF_TEST_onend(st, ret);155return ret;156}157158static int add_params(OSSL_PARAM_BLD *bld, const ST_KAT_PARAM *params,159BN_CTX *ctx)160{161int ret = 0;162const ST_KAT_PARAM *p;163164if (params == NULL)165return 1;166for (p = params; p->data != NULL; ++p) {167switch (p->type) {168case OSSL_PARAM_UNSIGNED_INTEGER: {169BIGNUM *bn = BN_CTX_get(ctx);170171if (bn == NULL172|| (BN_bin2bn(p->data, p->data_len, bn) == NULL)173|| !OSSL_PARAM_BLD_push_BN(bld, p->name, bn))174goto err;175break;176}177case OSSL_PARAM_UTF8_STRING: {178if (!OSSL_PARAM_BLD_push_utf8_string(bld, p->name, p->data,179p->data_len))180goto err;181break;182}183case OSSL_PARAM_OCTET_STRING: {184if (!OSSL_PARAM_BLD_push_octet_string(bld, p->name, p->data,185p->data_len))186goto err;187break;188}189case OSSL_PARAM_INTEGER: {190if (!OSSL_PARAM_BLD_push_int(bld, p->name, *(int *)p->data))191goto err;192break;193}194default:195break;196}197}198ret = 1;199err:200return ret;201}202203#if defined(__GNUC__) && __GNUC__ >= 4204# define SENTINEL __attribute__((sentinel))205#endif206207#if !defined(SENTINEL) && defined(__clang_major__) && __clang_major__ > 14208# define SENTINEL __attribute__((sentinel))209#endif210211#ifndef SENTINEL212# define SENTINEL213#endif214215static SENTINEL OSSL_PARAM *kat_params_to_ossl_params(OSSL_LIB_CTX *libctx, ...)216{217BN_CTX *bnc = NULL;218OSSL_PARAM *params = NULL;219OSSL_PARAM_BLD *bld = NULL;220const ST_KAT_PARAM *pms;221va_list ap;222223bnc = BN_CTX_new_ex(libctx);224if (bnc == NULL)225goto err;226bld = OSSL_PARAM_BLD_new();227if (bld == NULL)228goto err;229230va_start(ap, libctx);231while ((pms = va_arg(ap, const ST_KAT_PARAM *)) != NULL)232if (!add_params(bld, pms, bnc)) {233va_end(ap);234goto err;235}236va_end(ap);237238params = OSSL_PARAM_BLD_to_param(bld);239240err:241OSSL_PARAM_BLD_free(bld);242BN_CTX_free(bnc);243return params;244}245246static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st,247OSSL_LIB_CTX *libctx)248{249int ret = 0;250unsigned char out[128];251EVP_KDF *kdf = NULL;252EVP_KDF_CTX *ctx = NULL;253OSSL_PARAM *params = NULL;254255OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc);256257kdf = EVP_KDF_fetch(libctx, t->algorithm, "");258if (kdf == NULL)259goto err;260261ctx = EVP_KDF_CTX_new(kdf);262if (ctx == NULL)263goto err;264265params = kat_params_to_ossl_params(libctx, t->params, NULL);266if (params == NULL)267goto err;268269if (t->expected_len > sizeof(out))270goto err;271if (EVP_KDF_derive(ctx, out, t->expected_len, params) <= 0)272goto err;273274OSSL_SELF_TEST_oncorrupt_byte(st, out);275276if (memcmp(out, t->expected, t->expected_len) != 0)277goto err;278279ret = 1;280err:281EVP_KDF_free(kdf);282EVP_KDF_CTX_free(ctx);283OSSL_PARAM_free(params);284OSSL_SELF_TEST_onend(st, ret);285return ret;286}287288static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st,289OSSL_LIB_CTX *libctx)290{291int ret = 0;292unsigned char out[256];293EVP_RAND *rand;294EVP_RAND_CTX *test = NULL, *drbg = NULL;295unsigned int strength = 256;296int prediction_resistance = 1; /* Causes a reseed */297OSSL_PARAM drbg_params[3] = {298OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END299};300301OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_DRBG, t->desc);302303rand = EVP_RAND_fetch(libctx, "TEST-RAND", NULL);304if (rand == NULL)305goto err;306307test = EVP_RAND_CTX_new(rand, NULL);308EVP_RAND_free(rand);309if (test == NULL)310goto err;311312drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH,313&strength);314if (!EVP_RAND_CTX_set_params(test, drbg_params))315goto err;316317rand = EVP_RAND_fetch(libctx, t->algorithm, NULL);318if (rand == NULL)319goto err;320321drbg = EVP_RAND_CTX_new(rand, test);322EVP_RAND_free(rand);323if (drbg == NULL)324goto err;325326strength = EVP_RAND_get_strength(drbg);327328drbg_params[0] = OSSL_PARAM_construct_utf8_string(t->param_name,329t->param_value, 0);330/* This is only used by HMAC-DRBG but it is ignored by the others */331drbg_params[1] =332OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_MAC, "HMAC", 0);333if (!EVP_RAND_CTX_set_params(drbg, drbg_params))334goto err;335336drbg_params[0] =337OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,338(void *)t->entropyin,339t->entropyinlen);340drbg_params[1] =341OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE,342(void *)t->nonce, t->noncelen);343if (!EVP_RAND_instantiate(test, strength, 0, NULL, 0, drbg_params))344goto err;345if (!EVP_RAND_instantiate(drbg, strength, 0, t->persstr, t->persstrlen,346NULL))347goto err;348349drbg_params[0] =350OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,351(void *)t->entropyinpr1,352t->entropyinpr1len);353if (!EVP_RAND_CTX_set_params(test, drbg_params))354goto err;355356if (!EVP_RAND_generate(drbg, out, t->expectedlen, strength,357prediction_resistance,358t->entropyaddin1, t->entropyaddin1len))359goto err;360361drbg_params[0] =362OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,363(void *)t->entropyinpr2,364t->entropyinpr2len);365if (!EVP_RAND_CTX_set_params(test, drbg_params))366goto err;367368/*369* This calls ossl_prov_drbg_reseed() internally when370* prediction_resistance = 1371*/372if (!EVP_RAND_generate(drbg, out, t->expectedlen, strength,373prediction_resistance,374t->entropyaddin2, t->entropyaddin2len))375goto err;376377OSSL_SELF_TEST_oncorrupt_byte(st, out);378379if (memcmp(out, t->expected, t->expectedlen) != 0)380goto err;381382if (!EVP_RAND_uninstantiate(drbg))383goto err;384/*385* Check that the DRBG data has been zeroized after386* ossl_prov_drbg_uninstantiate.387*/388if (!EVP_RAND_verify_zeroization(drbg))389goto err;390391ret = 1;392err:393EVP_RAND_CTX_free(drbg);394EVP_RAND_CTX_free(test);395OSSL_SELF_TEST_onend(st, ret);396return ret;397}398399#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)400static int self_test_ka(const ST_KAT_KAS *t,401OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)402{403int ret = 0;404EVP_PKEY_CTX *kactx = NULL, *dctx = NULL;405EVP_PKEY *pkey = NULL, *peerkey = NULL;406OSSL_PARAM *params = NULL;407OSSL_PARAM *params_peer = NULL;408unsigned char secret[256];409size_t secret_len = t->expected_len;410411OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KA, t->desc);412413if (secret_len > sizeof(secret))414goto err;415416params = kat_params_to_ossl_params(libctx, t->key_group,417t->key_host_data, NULL);418params_peer = kat_params_to_ossl_params(libctx, t->key_group,419t->key_peer_data, NULL);420if (params == NULL || params_peer == NULL)421goto err;422423/* Create a EVP_PKEY_CTX to load the DH keys into */424kactx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, "");425if (kactx == NULL)426goto err;427if (EVP_PKEY_fromdata_init(kactx) <= 0428|| EVP_PKEY_fromdata(kactx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)429goto err;430if (EVP_PKEY_fromdata_init(kactx) <= 0431|| EVP_PKEY_fromdata(kactx, &peerkey, EVP_PKEY_KEYPAIR, params_peer) <= 0)432goto err;433434/* Create a EVP_PKEY_CTX to perform key derivation */435dctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL);436if (dctx == NULL)437goto err;438439if (EVP_PKEY_derive_init(dctx) <= 0440|| EVP_PKEY_derive_set_peer(dctx, peerkey) <= 0441|| EVP_PKEY_derive(dctx, secret, &secret_len) <= 0)442goto err;443444OSSL_SELF_TEST_oncorrupt_byte(st, secret);445446if (secret_len != t->expected_len447|| memcmp(secret, t->expected, t->expected_len) != 0)448goto err;449ret = 1;450err:451EVP_PKEY_free(pkey);452EVP_PKEY_free(peerkey);453EVP_PKEY_CTX_free(kactx);454EVP_PKEY_CTX_free(dctx);455OSSL_PARAM_free(params_peer);456OSSL_PARAM_free(params);457OSSL_SELF_TEST_onend(st, ret);458return ret;459}460#endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */461462static int digest_signature(const uint8_t *sig, size_t sig_len,463uint8_t *out, size_t *out_len,464OSSL_LIB_CTX *lib_ctx)465{466int ret;467unsigned int len = 0;468EVP_MD_CTX *ctx = EVP_MD_CTX_new();469EVP_MD *md = EVP_MD_fetch(lib_ctx, "SHA256", NULL);470471ret = ctx != NULL472&& md != NULL473&& EVP_DigestInit_ex(ctx, md, NULL) == 1474&& EVP_DigestUpdate(ctx, sig, sig_len) == 1475&& EVP_DigestFinal(ctx, out, &len) == 1;476EVP_MD_free(md);477EVP_MD_CTX_free(ctx);478*out_len = len;479return ret;480}481482static int self_test_digest_sign(const ST_KAT_SIGN *t,483OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)484{485int ret = 0;486OSSL_PARAM *paramskey = NULL, *paramsinit = NULL, *paramsverify = NULL;487EVP_SIGNATURE *sigalg = NULL;488EVP_PKEY_CTX *ctx = NULL;489EVP_PKEY_CTX *fromctx = NULL;490EVP_PKEY *pkey = NULL;491unsigned char sig[MAX_ML_DSA_SIG_LEN], *psig = sig;492size_t siglen;493int digested = 0;494const char *typ = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE;495496if (t->sig_expected_len > sizeof(sig))497goto err;498499if (t->sig_expected == NULL)500typ = OSSL_SELF_TEST_TYPE_PCT_SIGNATURE;501502OSSL_SELF_TEST_onbegin(st, typ, t->desc);503504if (t->entropy != NULL) {505if (!set_kat_drbg(libctx, t->entropy, t->entropy_len,506t->nonce, t->nonce_len, t->persstr, t->persstr_len))507goto err;508}509510paramskey = kat_params_to_ossl_params(libctx, t->key, NULL);511paramsinit = kat_params_to_ossl_params(libctx, t->init, NULL);512paramsverify = kat_params_to_ossl_params(libctx, t->verify, NULL);513514fromctx = EVP_PKEY_CTX_new_from_name(libctx, t->keytype, NULL);515if (fromctx == NULL516|| paramskey == NULL517|| paramsinit == NULL518|| paramsverify == NULL)519goto err;520if (EVP_PKEY_fromdata_init(fromctx) <= 0521|| EVP_PKEY_fromdata(fromctx, &pkey, EVP_PKEY_KEYPAIR, paramskey) <= 0)522goto err;523524sigalg = EVP_SIGNATURE_fetch(libctx, t->sigalgorithm, NULL);525if (sigalg == NULL)526goto err;527ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL);528if (ctx == NULL)529goto err;530531digested = ((t->mode & SIGNATURE_MODE_DIGESTED) != 0);532533if ((t->mode & SIGNATURE_MODE_VERIFY_ONLY) != 0) {534siglen = t->sig_expected_len;535memcpy(psig, t->sig_expected, siglen);536} else {537if (digested) {538if (EVP_PKEY_sign_init_ex2(ctx, sigalg, paramsinit) <= 0)539goto err;540} else {541if (EVP_PKEY_sign_message_init(ctx, sigalg, paramsinit) <= 0)542goto err;543}544siglen = sizeof(sig);545if ((t->mode & SIGNATURE_MODE_SIG_DIGESTED) != 0) {546if (EVP_PKEY_sign(ctx, NULL, &siglen, t->msg, t->msg_len) <= 0)547goto err;548if (siglen > sizeof(sig)) {549psig = OPENSSL_malloc(siglen);550if (psig == NULL)551goto err;552}553}554if (EVP_PKEY_sign(ctx, psig, &siglen, t->msg, t->msg_len) <= 0)555goto err;556557if (t->sig_expected != NULL) {558if ((t->mode & SIGNATURE_MODE_SIG_DIGESTED) != 0) {559uint8_t digested_sig[EVP_MAX_MD_SIZE];560size_t digested_sig_len = 0;561562if (!digest_signature(psig, siglen, digested_sig,563&digested_sig_len, libctx)564|| digested_sig_len != t->sig_expected_len565|| memcmp(digested_sig, t->sig_expected, t->sig_expected_len) != 0)566goto err;567} else {568if (siglen != t->sig_expected_len569|| memcmp(psig, t->sig_expected, t->sig_expected_len) != 0)570goto err;571}572}573}574575if ((t->mode & SIGNATURE_MODE_SIGN_ONLY) == 0) {576if (digested) {577if (EVP_PKEY_verify_init_ex2(ctx, sigalg, paramsverify) <= 0)578goto err;579} else {580if (EVP_PKEY_verify_message_init(ctx, sigalg, paramsverify) <= 0)581goto err;582}583OSSL_SELF_TEST_oncorrupt_byte(st, psig);584if (EVP_PKEY_verify(ctx, psig, siglen, t->msg, t->msg_len) <= 0)585goto err;586}587ret = 1;588err:589if (psig != sig)590OPENSSL_free(psig);591EVP_PKEY_free(pkey);592EVP_PKEY_CTX_free(fromctx);593EVP_PKEY_CTX_free(ctx);594EVP_SIGNATURE_free(sigalg);595OSSL_PARAM_free(paramskey);596OSSL_PARAM_free(paramsinit);597OSSL_PARAM_free(paramsverify);598if (t->entropy != NULL) {599if (!reset_main_drbg(libctx))600ret = 0;601}602OSSL_SELF_TEST_onend(st, ret);603return ret;604}605606#if !defined(OPENSSL_NO_ML_DSA) || !defined(OPENSSL_NO_SLH_DSA)607/*608* Test that a deterministic key generation produces the correct key609*/610static int self_test_asym_keygen(const ST_KAT_ASYM_KEYGEN *t, OSSL_SELF_TEST *st,611OSSL_LIB_CTX *libctx)612{613int ret = 0;614const ST_KAT_PARAM *expected;615OSSL_PARAM *key_params = NULL;616EVP_PKEY_CTX *key_ctx = NULL;617EVP_PKEY *key = NULL;618uint8_t out[MAX_ML_DSA_PRIV_LEN];619size_t out_len = 0;620621OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_ASYM_KEYGEN, t->desc);622623key_ctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL);624if (key_ctx == NULL)625goto err;626if (t->keygen_params != NULL) {627key_params = kat_params_to_ossl_params(libctx, t->keygen_params, NULL);628if (key_params == NULL)629goto err;630}631if (EVP_PKEY_keygen_init(key_ctx) != 1632|| EVP_PKEY_CTX_set_params(key_ctx, key_params) != 1633|| EVP_PKEY_generate(key_ctx, &key) != 1)634goto err;635636for (expected = t->expected_params; expected->data != NULL; ++expected) {637if (expected->type != OSSL_PARAM_OCTET_STRING638|| !EVP_PKEY_get_octet_string_param(key, expected->name,639out, sizeof(out), &out_len))640goto err;641OSSL_SELF_TEST_oncorrupt_byte(st, out);642/* Check the KAT */643if (out_len != expected->data_len644|| memcmp(out, expected->data, expected->data_len) != 0)645goto err;646}647ret = 1;648err:649EVP_PKEY_free(key);650EVP_PKEY_CTX_free(key_ctx);651OSSL_PARAM_free(key_params);652OSSL_SELF_TEST_onend(st, ret);653return ret;654}655#endif /* OPENSSL_NO_ML_DSA */656657#ifndef OPENSSL_NO_ML_KEM658/*659* FIPS 140-3 IG 10.3.A resolution 14 mandates a CAST for ML-KEM660* encapsulation.661*/662static int self_test_kem_encapsulate(const ST_KAT_KEM *t, OSSL_SELF_TEST *st,663OSSL_LIB_CTX *libctx, EVP_PKEY *pkey)664{665int ret = 0;666EVP_PKEY_CTX *ctx;667unsigned char *wrapped = NULL, *secret = NULL;668size_t wrappedlen = t->cipher_text_len, secretlen = t->secret_len;669OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };670671OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KEM,672OSSL_SELF_TEST_DESC_ENCAP_KEM);673674ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, "");675if (ctx == NULL)676goto err;677678*params = OSSL_PARAM_construct_octet_string(OSSL_KEM_PARAM_IKME,679(unsigned char *)t->entropy,680t->entropy_len);681if (EVP_PKEY_encapsulate_init(ctx, params) <= 0)682goto err;683684/* Allocate output buffers */685wrapped = OPENSSL_malloc(wrappedlen);686secret = OPENSSL_malloc(secretlen);687if (wrapped == NULL || secret == NULL)688goto err;689690/* Encapsulate */691if (EVP_PKEY_encapsulate(ctx, wrapped, &wrappedlen, secret, &secretlen) <= 0)692goto err;693694/* Compare outputs */695OSSL_SELF_TEST_oncorrupt_byte(st, wrapped);696if (wrappedlen != t->cipher_text_len697|| memcmp(wrapped, t->cipher_text, t->cipher_text_len) != 0)698goto err;699700OSSL_SELF_TEST_oncorrupt_byte(st, secret);701if (secretlen != t->secret_len702|| memcmp(secret, t->secret, t->secret_len) != 0)703goto err;704705ret = 1;706err:707OPENSSL_free(wrapped);708OPENSSL_free(secret);709EVP_PKEY_CTX_free(ctx);710OSSL_SELF_TEST_onend(st, ret);711return ret;712}713714/*715* FIPS 140-3 IG 10.3.A resolution 14 mandates a CAST for ML-KEM716* decapsulation both for the rejection path and the normal path.717*/718static int self_test_kem_decapsulate(const ST_KAT_KEM *t, OSSL_SELF_TEST *st,719OSSL_LIB_CTX *libctx, EVP_PKEY *pkey,720int reject)721{722int ret = 0;723EVP_PKEY_CTX *ctx = NULL;724unsigned char *secret = NULL, *alloced = NULL;725const unsigned char *test_secret = t->secret;726const unsigned char *cipher_text = t->cipher_text;727size_t secretlen = t->secret_len;728729OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KEM,730reject ? OSSL_SELF_TEST_DESC_DECAP_KEM_FAIL731: OSSL_SELF_TEST_DESC_DECAP_KEM);732733if (reject) {734cipher_text = alloced = OPENSSL_zalloc(t->cipher_text_len);735if (alloced == NULL)736goto err;737test_secret = t->reject_secret;738}739740ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, "");741if (ctx == NULL)742goto err;743744if (EVP_PKEY_decapsulate_init(ctx, NULL) <= 0)745goto err;746747/* Allocate output buffer */748secret = OPENSSL_malloc(secretlen);749if (secret == NULL)750goto err;751752/* Decapsulate */753if (EVP_PKEY_decapsulate(ctx, secret, &secretlen,754cipher_text, t->cipher_text_len) <= 0)755goto err;756757/* Compare output */758OSSL_SELF_TEST_oncorrupt_byte(st, secret);759if (secretlen != t->secret_len760|| memcmp(secret, test_secret, t->secret_len) != 0)761goto err;762763ret = 1;764err:765OPENSSL_free(alloced);766OPENSSL_free(secret);767EVP_PKEY_CTX_free(ctx);768OSSL_SELF_TEST_onend(st, ret);769return ret;770}771772/*773* Test encapsulation, decapsulation for KEM.774*775* FIPS 140-3 IG 10.3.A resolution 14 mandates a CAST for:776* 1 ML-KEM encapsulation777* 2a ML-KEM decapsulation non-rejection path778* 2b ML-KEM decapsulation implicit rejection path779* 3 ML-KEM key generation780*/781static int self_test_kem(const ST_KAT_KEM *t, OSSL_SELF_TEST *st,782OSSL_LIB_CTX *libctx)783{784int ret = 0;785EVP_PKEY *pkey = NULL;786EVP_PKEY_CTX *ctx;787OSSL_PARAM *params = NULL;788789ctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL);790if (ctx == NULL)791goto err;792params = kat_params_to_ossl_params(libctx, t->key, NULL);793if (params == NULL)794goto err;795796if (EVP_PKEY_fromdata_init(ctx) <= 0797|| EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)798goto err;799800if (!self_test_kem_encapsulate(t, st, libctx, pkey)801|| !self_test_kem_decapsulate(t, st, libctx, pkey, 0)802|| !self_test_kem_decapsulate(t, st, libctx, pkey, 1))803goto err;804805ret = 1;806err:807EVP_PKEY_CTX_free(ctx);808EVP_PKEY_free(pkey);809OSSL_PARAM_free(params);810return ret;811}812#endif813814/*815* Test an encrypt or decrypt KAT..816*817* FIPS 140-2 IG D.9 states that separate KAT tests are needed for encrypt818* and decrypt..819*/820static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, OSSL_SELF_TEST *st,821OSSL_LIB_CTX *libctx)822{823int ret = 0;824OSSL_PARAM *keyparams = NULL, *initparams = NULL;825OSSL_PARAM_BLD *keybld = NULL, *initbld = NULL;826EVP_PKEY_CTX *encctx = NULL, *keyctx = NULL;827EVP_PKEY *key = NULL;828BN_CTX *bnctx = NULL;829unsigned char out[256];830size_t outlen = sizeof(out);831832OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER, t->desc);833834bnctx = BN_CTX_new_ex(libctx);835if (bnctx == NULL)836goto err;837838/* Load a public or private key from data */839keybld = OSSL_PARAM_BLD_new();840if (keybld == NULL841|| !add_params(keybld, t->key, bnctx))842goto err;843keyparams = OSSL_PARAM_BLD_to_param(keybld);844keyctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL);845if (keyctx == NULL || keyparams == NULL)846goto err;847if (EVP_PKEY_fromdata_init(keyctx) <= 0848|| EVP_PKEY_fromdata(keyctx, &key, EVP_PKEY_KEYPAIR, keyparams) <= 0)849goto err;850851/* Create a EVP_PKEY_CTX to use for the encrypt or decrypt operation */852encctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL);853if (encctx == NULL854|| (t->encrypt && EVP_PKEY_encrypt_init(encctx) <= 0)855|| (!t->encrypt && EVP_PKEY_decrypt_init(encctx) <= 0))856goto err;857858/* Add any additional parameters such as padding */859if (t->postinit != NULL) {860initbld = OSSL_PARAM_BLD_new();861if (initbld == NULL)862goto err;863if (!add_params(initbld, t->postinit, bnctx))864goto err;865initparams = OSSL_PARAM_BLD_to_param(initbld);866if (initparams == NULL)867goto err;868if (EVP_PKEY_CTX_set_params(encctx, initparams) <= 0)869goto err;870}871872if (t->encrypt) {873if (EVP_PKEY_encrypt(encctx, out, &outlen,874t->in, t->in_len) <= 0)875goto err;876} else {877if (EVP_PKEY_decrypt(encctx, out, &outlen,878t->in, t->in_len) <= 0)879goto err;880}881/* Check the KAT */882OSSL_SELF_TEST_oncorrupt_byte(st, out);883if (outlen != t->expected_len884|| memcmp(out, t->expected, t->expected_len) != 0)885goto err;886887ret = 1;888err:889BN_CTX_free(bnctx);890EVP_PKEY_free(key);891EVP_PKEY_CTX_free(encctx);892EVP_PKEY_CTX_free(keyctx);893OSSL_PARAM_free(keyparams);894OSSL_PARAM_BLD_free(keybld);895OSSL_PARAM_free(initparams);896OSSL_PARAM_BLD_free(initbld);897OSSL_SELF_TEST_onend(st, ret);898return ret;899}900901/*902* Test a data driven list of KAT's for digest algorithms.903* All tests are run regardless of if they fail or not.904* Return 0 if any test fails.905*/906static int self_test_digests(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)907{908int i, ret = 1;909910for (i = 0; i < (int)OSSL_NELEM(st_kat_digest_tests); ++i) {911if (!self_test_digest(&st_kat_digest_tests[i], st, libctx))912ret = 0;913}914return ret;915}916917static int self_test_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)918{919int i, ret = 1;920921for (i = 0; i < (int)OSSL_NELEM(st_kat_cipher_tests); ++i) {922if (!self_test_cipher(&st_kat_cipher_tests[i], st, libctx))923ret = 0;924}925return ret;926}927928static int self_test_kems(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)929{930int ret = 1;931#ifndef OPENSSL_NO_ML_KEM932int i;933934for (i = 0; i < (int)OSSL_NELEM(st_kat_kem_tests); ++i) {935if (!self_test_kem(&st_kat_kem_tests[i], st, libctx))936ret = 0;937}938#endif939return ret;940}941942static int self_test_asym_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)943{944int i, ret = 1;945946for (i = 0; i < (int)OSSL_NELEM(st_kat_asym_cipher_tests); ++i) {947if (!self_test_asym_cipher(&st_kat_asym_cipher_tests[i], st, libctx))948ret = 0;949}950return ret;951}952953static int self_test_kdfs(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)954{955int i, ret = 1;956957for (i = 0; i < (int)OSSL_NELEM(st_kat_kdf_tests); ++i) {958if (!self_test_kdf(&st_kat_kdf_tests[i], st, libctx))959ret = 0;960}961return ret;962}963964static int self_test_drbgs(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)965{966int i, ret = 1;967968for (i = 0; i < (int)OSSL_NELEM(st_kat_drbg_tests); ++i) {969if (!self_test_drbg(&st_kat_drbg_tests[i], st, libctx))970ret = 0;971}972return ret;973}974975static int self_test_kas(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)976{977int ret = 1;978#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)979int i;980981for (i = 0; i < (int)OSSL_NELEM(st_kat_kas_tests); ++i) {982if (!self_test_ka(&st_kat_kas_tests[i], st, libctx))983ret = 0;984}985#endif986987return ret;988}989990static int self_test_signatures(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)991{992int i, ret = 1;993994for (i = 0; i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) {995if (!self_test_digest_sign(&st_kat_sign_tests[i], st, libctx))996ret = 0;997}998return ret;999}10001001/*1002* Swap the library context DRBG for KAT testing1003*1004* In FIPS 140-3, the asymmetric POST must be a KAT, not a PCT. For DSA and ECDSA,1005* the sign operation includes the random value 'k'. For a KAT to work, we1006* have to have control of the DRBG to make sure it is in a "test" state, where1007* its output is truly deterministic.1008*1009*/10101011/*1012* Replacement "random" sources1013* main_rand is used for most tests and it's set to generate mode.1014* kat_rand is used for KATs where specific input is mandated.1015*/1016static EVP_RAND_CTX *kat_rand = NULL;1017static EVP_RAND_CTX *main_rand = NULL;10181019static int set_kat_drbg(OSSL_LIB_CTX *ctx,1020const unsigned char *entropy, size_t entropy_len,1021const unsigned char *nonce, size_t nonce_len,1022const unsigned char *persstr, size_t persstr_len) {1023EVP_RAND *rand;1024unsigned int strength = 256;1025EVP_RAND_CTX *parent_rand = NULL;1026OSSL_PARAM drbg_params[3] = {1027OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END1028};10291030/* If not NULL, we didn't cleanup from last call: BAD */1031if (kat_rand != NULL)1032return 0;10331034rand = EVP_RAND_fetch(ctx, "TEST-RAND", NULL);1035if (rand == NULL)1036return 0;10371038parent_rand = EVP_RAND_CTX_new(rand, NULL);1039EVP_RAND_free(rand);1040if (parent_rand == NULL)1041goto err;10421043drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH,1044&strength);1045if (!EVP_RAND_CTX_set_params(parent_rand, drbg_params))1046goto err;10471048rand = EVP_RAND_fetch(ctx, "HASH-DRBG", NULL);1049if (rand == NULL)1050goto err;10511052kat_rand = EVP_RAND_CTX_new(rand, parent_rand);1053EVP_RAND_free(rand);1054if (kat_rand == NULL)1055goto err;10561057drbg_params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA256", 0);1058if (!EVP_RAND_CTX_set_params(kat_rand, drbg_params))1059goto err;10601061/* Instantiate the RNGs */1062drbg_params[0] =1063OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,1064(void *)entropy, entropy_len);1065drbg_params[1] =1066OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE,1067(void *)nonce, nonce_len);1068if (!EVP_RAND_instantiate(parent_rand, strength, 0, NULL, 0, drbg_params))1069goto err;10701071EVP_RAND_CTX_free(parent_rand);1072parent_rand = NULL;10731074if (!EVP_RAND_instantiate(kat_rand, strength, 0, persstr, persstr_len, NULL))1075goto err;10761077/* When we set the new private generator this one is freed, so upref it */1078if (!EVP_RAND_CTX_up_ref(main_rand))1079goto err;10801081/* Update the library context DRBG */1082if (RAND_set0_private(ctx, kat_rand) > 0) {1083/* Keeping a copy to verify zeroization */1084if (EVP_RAND_CTX_up_ref(kat_rand))1085return 1;1086RAND_set0_private(ctx, main_rand);1087}10881089err:1090EVP_RAND_CTX_free(parent_rand);1091EVP_RAND_CTX_free(kat_rand);1092kat_rand = NULL;1093return 0;1094}10951096static int reset_main_drbg(OSSL_LIB_CTX *ctx) {1097int ret = 1;10981099if (!RAND_set0_private(ctx, main_rand))1100ret = 0;1101if (kat_rand != NULL) {1102if (!EVP_RAND_uninstantiate(kat_rand)1103|| !EVP_RAND_verify_zeroization(kat_rand))1104ret = 0;1105EVP_RAND_CTX_free(kat_rand);1106kat_rand = NULL;1107}1108return ret;1109}11101111static int setup_main_random(OSSL_LIB_CTX *libctx)1112{1113OSSL_PARAM drbg_params[3] = {1114OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END1115};1116unsigned int strength = 256, generate = 1;1117EVP_RAND *rand;11181119rand = EVP_RAND_fetch(libctx, "TEST-RAND", NULL);1120if (rand == NULL)1121return 0;11221123main_rand = EVP_RAND_CTX_new(rand, NULL);1124EVP_RAND_free(rand);1125if (main_rand == NULL)1126goto err;11271128drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_GENERATE,1129&generate);1130drbg_params[1] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH,1131&strength);11321133if (!EVP_RAND_instantiate(main_rand, strength, 0, NULL, 0, drbg_params))1134goto err;1135return 1;1136err:1137EVP_RAND_CTX_free(main_rand);1138return 0;1139}11401141static int self_test_asym_keygens(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)1142{1143#if !defined(OPENSSL_NO_ML_DSA) || !defined(OPENSSL_NO_SLH_DSA)1144int i, ret = 1;11451146for (i = 0; i < (int)OSSL_NELEM(st_kat_asym_keygen_tests); ++i) {1147if (!self_test_asym_keygen(&st_kat_asym_keygen_tests[i], st, libctx))1148ret = 0;1149}1150return ret;1151#else1152return 1;1153#endif /* OPENSSL_NO_ML_DSA */1154}11551156/*1157* Run the algorithm KAT's.1158* Return 1 is successful, otherwise return 0.1159* This runs all the tests regardless of if any fail.1160*/1161int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)1162{1163EVP_RAND_CTX *saved_rand = ossl_rand_get0_private_noncreating(libctx);1164int ret = 1;11651166if (saved_rand != NULL && !EVP_RAND_CTX_up_ref(saved_rand))1167return 0;1168if (!setup_main_random(libctx)1169|| !RAND_set0_private(libctx, main_rand)) {1170/* Decrement saved_rand reference counter */1171EVP_RAND_CTX_free(saved_rand);1172EVP_RAND_CTX_free(main_rand);1173return 0;1174}11751176if (!self_test_digests(st, libctx))1177ret = 0;1178if (!self_test_ciphers(st, libctx))1179ret = 0;1180if (!self_test_signatures(st, libctx))1181ret = 0;1182if (!self_test_kdfs(st, libctx))1183ret = 0;1184if (!self_test_drbgs(st, libctx))1185ret = 0;1186if (!self_test_kas(st, libctx))1187ret = 0;1188if (!self_test_asym_keygens(st, libctx))1189ret = 0;1190if (!self_test_kems(st, libctx))1191ret = 0;1192if (!self_test_asym_ciphers(st, libctx))1193ret = 0;11941195RAND_set0_private(libctx, saved_rand);1196return ret;1197}1198119912001201