Latest update.
This commit is contained in:
@@ -1,3 +1,2 @@
|
||||
|
||||
SOURCE[../fips]=fipsprov.c selftest.c
|
||||
INCLUDE[../fips]=../implementations/include ../common/include
|
||||
SOURCE[../fips]=fipsprov.c self_test.c self_test_kats.c self_test_event.c
|
||||
INCLUDE[../fips]=../implementations/include ../common/include ../..
|
||||
+261
-56
@@ -25,11 +25,16 @@
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/property.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "prov/implementations.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
#include "prov/providercommon.h"
|
||||
#include "selftest.h"
|
||||
#include "prov/provider_util.h"
|
||||
#include "self_test.h"
|
||||
|
||||
#define ALGC(NAMES, FUNC, CHECK) { { NAMES, "fips=yes", FUNC }, CHECK }
|
||||
#define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL)
|
||||
|
||||
extern OSSL_core_thread_start_fn *c_thread_start;
|
||||
|
||||
@@ -116,6 +121,49 @@ static OSSL_PARAM core_params[] =
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
/*
|
||||
* This routine is currently necessary as bn params are currently processed
|
||||
* using BN_native2bn when raw data is received. This means we need to do
|
||||
* magic to reverse the order of the bytes to match native format.
|
||||
* The array of hexdata is to get around compilers that dont like
|
||||
* strings longer than 509 bytes,
|
||||
*/
|
||||
static int rawnative_fromhex(const char *hex_data[],
|
||||
unsigned char **native, size_t *nativelen)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char *data = NULL;
|
||||
BIGNUM *bn = NULL;
|
||||
int i, slen, datalen, sz;
|
||||
char *str = NULL;
|
||||
|
||||
for (slen = 0, i = 0; hex_data[i] != NULL; ++i)
|
||||
slen += strlen(hex_data[i]);
|
||||
str = OPENSSL_zalloc(slen + 1);
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
for (i = 0; hex_data[i] != NULL; ++i)
|
||||
strcat(str, hex_data[i]);
|
||||
|
||||
if (BN_hex2bn(&bn, str) <= 0)
|
||||
return 0;
|
||||
|
||||
datalen = slen / 2;
|
||||
data = (unsigned char *)str; /* reuse the str buffer */
|
||||
|
||||
sz = BN_bn2nativepad(bn, data, datalen);
|
||||
if (sz <= 0)
|
||||
goto err;
|
||||
ret = 1;
|
||||
*native = data;
|
||||
*nativelen = datalen;
|
||||
data = NULL; /* so it does not get freed */
|
||||
err:
|
||||
BN_free(bn);
|
||||
OPENSSL_free(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO(3.0): To be removed */
|
||||
static int dummy_evp_call(void *provctx)
|
||||
{
|
||||
@@ -123,6 +171,58 @@ static int dummy_evp_call(void *provctx)
|
||||
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
||||
EVP_MD *sha256 = EVP_MD_fetch(libctx, "SHA256", NULL);
|
||||
EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF2, NULL);
|
||||
EVP_PKEY_CTX *sctx = NULL, *kctx = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
OSSL_PARAM *p;
|
||||
OSSL_PARAM params[16];
|
||||
unsigned char sig[64];
|
||||
size_t siglen, sigdgstlen;
|
||||
unsigned char *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
|
||||
unsigned char *dsa_pub = NULL, *dsa_priv = NULL;
|
||||
size_t dsa_p_len, dsa_q_len, dsa_g_len, dsa_pub_len, dsa_priv_len;
|
||||
|
||||
/* dsa 2048 */
|
||||
static const char *dsa_p_hex[] = {
|
||||
"a29b8872ce8b8423b7d5d21d4b02f57e03e9e6b8a258dc16611ba098ab543415"
|
||||
"e415f156997a3ee236658fa093260de3ad422e05e046f9ec29161a375f0eb4ef"
|
||||
"fcef58285c5d39ed425d7a62ca12896c4a92cb1946f2952a48133f07da364d1b"
|
||||
"df6b0f7139983e693c80059b0eacd1479ba9f2857754ede75f112b07ebbf3534",
|
||||
"8bbf3e01e02f2d473de39453f99dd2367541caca3ba01166343d7b5b58a37bd1"
|
||||
"b7521db2f13b86707132fe09f4cd09dc1618fa3401ebf9cc7b19fa94aa472088"
|
||||
"133d6cb2d35c1179c8c8ff368758d507d9f9a17d46c110fe3144ce9b022b42e4"
|
||||
"19eb4f5388613bfc3e26241a432e8706bc58ef76117278deab6cf692618291b7",
|
||||
NULL
|
||||
};
|
||||
static const char *dsa_q_hex[] = {
|
||||
"a3bfd9ab7884794e383450d5891dc18b65157bdcfcdac51518902867",
|
||||
NULL
|
||||
};
|
||||
static const char *dsa_g_hex[] = {
|
||||
"6819278869c7fd3d2d7b77f77e8150d9ad433bea3ba85efc80415aa3545f78f7"
|
||||
"2296f06cb19ceda06c94b0551cfe6e6f863e31d1de6eed7dab8b0c9df231e084"
|
||||
"34d1184f91d033696bb382f8455e9888f5d31d4784ec40120246f4bea61794bb"
|
||||
"a5866f09746463bdf8e9e108cd9529c3d0f6df80316e2e70aaeb1b26cdb8ad97",
|
||||
"bc3d287e0b8d616c42e65b87db20deb7005bc416747a6470147a68a7820388eb"
|
||||
"f44d52e0628af9cf1b7166d03465f35acc31b6110c43dabc7c5d591e671eaf7c"
|
||||
"252c1c145336a1a4ddf13244d55e835680cab2533b82df2efe55ec18c1e6cd00"
|
||||
"7bb089758bb17c2cbe14441bd093ae66e5976d53733f4fa3269701d31d23d467",
|
||||
NULL
|
||||
};
|
||||
static const char *dsa_pub_hex[] = {
|
||||
"a012b3b170b307227957b7ca2061a816ac7a2b3d9ae995a5119c385b603bf6f6"
|
||||
"c5de4dc5ecb5dfa4a41c68662eb25b638b7e2620ba898d07da6c4991e76cc0ec"
|
||||
"d1ad3421077067e47c18f58a92a72ad43199ecb7bd84e7d3afb9019f0e9dd0fb"
|
||||
"aa487300b13081e33c902876436f7b03c345528481d362815e24fe59dac5ac34",
|
||||
"660d4c8a76cb99a7c7de93eb956cd6bc88e58d901034944a094b01803a43c672"
|
||||
"b9688c0e01d8f4fc91c62a3f88021f7bd6a651b1a88f43aa4ef27653d12bf8b7"
|
||||
"099fdf6b461082f8e939107bfd2f7210087d326c375200f1f51e7e74a3413190"
|
||||
"1bcd0863521ff8d676c48581868736c5e51b16a4e39215ea0b17c4735974c516",
|
||||
NULL
|
||||
};
|
||||
static const char *dsa_priv_hex[] = {
|
||||
"6ccaeef6d73b4e80f11c17b8e9627c036635bac39423505e407e5cb7",
|
||||
NULL
|
||||
};
|
||||
char msg[] = "Hello World!";
|
||||
const unsigned char exptd[] = {
|
||||
0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
|
||||
@@ -181,7 +281,54 @@ static int dummy_evp_call(void *provctx)
|
||||
if (!EC_KEY_generate_key(key))
|
||||
goto err;
|
||||
#endif
|
||||
if (!rawnative_fromhex(dsa_p_hex, &dsa_p, &dsa_p_len)
|
||||
|| !rawnative_fromhex(dsa_q_hex, &dsa_q, &dsa_q_len)
|
||||
|| !rawnative_fromhex(dsa_g_hex, &dsa_g, &dsa_g_len)
|
||||
|| !rawnative_fromhex(dsa_pub_hex, &dsa_pub, &dsa_pub_len)
|
||||
|| !rawnative_fromhex(dsa_priv_hex, &dsa_priv, &dsa_priv_len))
|
||||
goto err;
|
||||
|
||||
p = params;
|
||||
*p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_P, dsa_p, dsa_p_len);
|
||||
*p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_Q, dsa_q, dsa_q_len);
|
||||
*p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_G, dsa_g, dsa_g_len);
|
||||
*p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_DSA_PUB_KEY,
|
||||
dsa_pub, dsa_pub_len);
|
||||
*p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_DSA_PRIV_KEY,
|
||||
dsa_priv, dsa_priv_len);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
kctx = EVP_PKEY_CTX_new_from_name(libctx, SN_dsa, "");
|
||||
if (kctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_key_fromdata_init(kctx) <= 0
|
||||
|| EVP_PKEY_fromdata(kctx, &pkey, params) <= 0)
|
||||
goto err;
|
||||
|
||||
sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey);
|
||||
if (sctx == NULL)
|
||||
goto err;;
|
||||
|
||||
if (EVP_PKEY_sign_init(sctx) <= 0)
|
||||
goto err;
|
||||
|
||||
/* set signature parameters */
|
||||
sigdgstlen = SHA256_DIGEST_LENGTH;
|
||||
p = params;
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
|
||||
SN_sha256,
|
||||
strlen(SN_sha256) + 1);
|
||||
|
||||
*p++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
|
||||
&sigdgstlen);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
if (EVP_PKEY_CTX_set_params(sctx, params) <= 0)
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0
|
||||
|| EVP_PKEY_verify_init(sctx) <= 0
|
||||
|| EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0)
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(bnctx);
|
||||
@@ -194,6 +341,14 @@ static int dummy_evp_call(void *provctx)
|
||||
#ifndef OPENSSL_NO_EC
|
||||
EC_KEY_free(key);
|
||||
#endif
|
||||
OPENSSL_free(dsa_p);
|
||||
OPENSSL_free(dsa_q);
|
||||
OPENSSL_free(dsa_g);
|
||||
OPENSSL_free(dsa_pub);
|
||||
OPENSSL_free(dsa_priv);
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_CTX_free(kctx);
|
||||
EVP_PKEY_CTX_free(sctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -300,6 +455,14 @@ const char *ossl_prov_util_nid_to_name(int nid)
|
||||
return "DES-EDE3";
|
||||
case NID_des_ede3_cbc:
|
||||
return "DES-EDE3-CBC";
|
||||
case NID_aes_256_cbc_hmac_sha256:
|
||||
return "AES-256-CBC-HMAC-SHA256";
|
||||
case NID_aes_128_cbc_hmac_sha256:
|
||||
return "AES-128-CBC-HMAC-SHA256";
|
||||
case NID_aes_256_cbc_hmac_sha1:
|
||||
return "AES-256-CBC-HMAC-SHA1";
|
||||
case NID_aes_128_cbc_hmac_sha1:
|
||||
return "AES-128-CBC-HMAC-SHA1";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -349,52 +512,58 @@ static const OSSL_ALGORITHM fips_digests[] = {
|
||||
{ "SHA3-384", "fips=yes", sha3_384_functions },
|
||||
{ "SHA3-512", "fips=yes", sha3_512_functions },
|
||||
/*
|
||||
* KECCAK_KMAC128 and KECCAK_KMAC256 as hashes are mostly useful for
|
||||
* KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for
|
||||
* KMAC128 and KMAC256.
|
||||
*/
|
||||
{ "KECCAK_KMAC128", "fips=yes", keccak_kmac_128_functions },
|
||||
{ "KECCAK_KMAC256", "fips=yes", keccak_kmac_256_functions },
|
||||
{ "KECCAK-KMAC-128:KECCAK-KMAC128", "fips=yes", keccak_kmac_128_functions },
|
||||
{ "KECCAK-KMAC-256:KECCAK-KMAC256", "fips=yes", keccak_kmac_256_functions },
|
||||
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static const OSSL_ALGORITHM fips_ciphers[] = {
|
||||
static const OSSL_ALGORITHM_CAPABLE fips_ciphers[] = {
|
||||
/* Our primary name[:ASN.1 OID name][:our older names] */
|
||||
{ "AES-256-ECB", "fips=yes", aes256ecb_functions },
|
||||
{ "AES-192-ECB", "fips=yes", aes192ecb_functions },
|
||||
{ "AES-128-ECB", "fips=yes", aes128ecb_functions },
|
||||
{ "AES-256-CBC", "fips=yes", aes256cbc_functions },
|
||||
{ "AES-192-CBC", "fips=yes", aes192cbc_functions },
|
||||
{ "AES-128-CBC", "fips=yes", aes128cbc_functions },
|
||||
{ "AES-256-CTR", "fips=yes", aes256ctr_functions },
|
||||
{ "AES-192-CTR", "fips=yes", aes192ctr_functions },
|
||||
{ "AES-128-CTR", "fips=yes", aes128ctr_functions },
|
||||
{ "AES-256-XTS", "fips=yes", aes256xts_functions },
|
||||
{ "AES-128-XTS", "fips=yes", aes128xts_functions },
|
||||
{ "AES-256-GCM:id-aes256-GCM", "fips=yes", aes256gcm_functions },
|
||||
{ "AES-192-GCM:id-aes192-GCM", "fips=yes", aes192gcm_functions },
|
||||
{ "AES-128-GCM:id-aes128-GCM", "fips=yes", aes128gcm_functions },
|
||||
{ "AES-256-CCM:id-aes256-CCM", "fips=yes", aes256ccm_functions },
|
||||
{ "AES-192-CCM:id-aes192-CCM", "fips=yes", aes192ccm_functions },
|
||||
{ "AES-128-CCM:id-aes128-CCM", "fips=yes", aes128ccm_functions },
|
||||
{ "AES-256-WRAP:id-aes256-wrap:AES256-WRAP", "fips=yes",
|
||||
aes256wrap_functions },
|
||||
{ "AES-192-WRAP:id-aes192-wrap:AES192-WRAP", "fips=yes",
|
||||
aes192wrap_functions },
|
||||
{ "AES-128-WRAP:id-aes128-wrap:AES128-WRAP", "fips=yes",
|
||||
aes128wrap_functions },
|
||||
{ "AES-256-WRAP-PAD:id-aes256-wrap-pad:AES256-WRAP-PAD", "fips=yes",
|
||||
aes256wrappad_functions },
|
||||
{ "AES-192-WRAP-PAD:id-aes192-wrap-pad:AES192-WRAP-PAD", "fips=yes",
|
||||
aes192wrappad_functions },
|
||||
{ "AES-128-WRAP-PAD:id-aes128-wrap-pad:AES128-WRAP-PAD", "fips=yes",
|
||||
aes128wrappad_functions },
|
||||
ALG("AES-256-ECB", aes256ecb_functions),
|
||||
ALG("AES-192-ECB", aes192ecb_functions),
|
||||
ALG("AES-128-ECB", aes128ecb_functions),
|
||||
ALG("AES-256-CBC", aes256cbc_functions),
|
||||
ALG("AES-192-CBC", aes192cbc_functions),
|
||||
ALG("AES-128-CBC", aes128cbc_functions),
|
||||
ALG("AES-256-CTR", aes256ctr_functions),
|
||||
ALG("AES-192-CTR", aes192ctr_functions),
|
||||
ALG("AES-128-CTR", aes128ctr_functions),
|
||||
ALG("AES-256-XTS", aes256xts_functions),
|
||||
ALG("AES-128-XTS", aes128xts_functions),
|
||||
ALG("AES-256-GCM:id-aes256-GCM", aes256gcm_functions),
|
||||
ALG("AES-192-GCM:id-aes192-GCM", aes192gcm_functions),
|
||||
ALG("AES-128-GCM:id-aes128-GCM", aes128gcm_functions),
|
||||
ALG("AES-256-CCM:id-aes256-CCM", aes256ccm_functions),
|
||||
ALG("AES-192-CCM:id-aes192-CCM", aes192ccm_functions),
|
||||
ALG("AES-128-CCM:id-aes128-CCM", aes128ccm_functions),
|
||||
ALG("AES-256-WRAP:id-aes256-wrap:AES256-WRAP", aes256wrap_functions),
|
||||
ALG("AES-192-WRAP:id-aes192-wrap:AES192-WRAP", aes192wrap_functions),
|
||||
ALG("AES-128-WRAP:id-aes128-wrap:AES128-WRAP", aes128wrap_functions),
|
||||
ALG("AES-256-WRAP-PAD:id-aes256-wrap-pad:AES256-WRAP-PAD",
|
||||
aes256wrappad_functions),
|
||||
ALG("AES-192-WRAP-PAD:id-aes192-wrap-pad:AES192-WRAP-PAD",
|
||||
aes192wrappad_functions),
|
||||
ALG("AES-128-WRAP-PAD:id-aes128-wrap-pad:AES128-WRAP-PAD",
|
||||
aes128wrappad_functions),
|
||||
ALGC("AES-128-CBC-HMAC-SHA1", aes128cbc_hmac_sha1_functions,
|
||||
cipher_capable_aes_cbc_hmac_sha1),
|
||||
ALGC("AES-256-CBC-HMAC-SHA1", aes256cbc_hmac_sha1_functions,
|
||||
cipher_capable_aes_cbc_hmac_sha1),
|
||||
ALGC("AES-128-CBC-HMAC-SHA256", aes128cbc_hmac_sha256_functions,
|
||||
cipher_capable_aes_cbc_hmac_sha256),
|
||||
ALGC("AES-256-CBC-HMAC-SHA256", aes256cbc_hmac_sha256_functions,
|
||||
cipher_capable_aes_cbc_hmac_sha256),
|
||||
#ifndef OPENSSL_NO_DES
|
||||
{ "DES-EDE3-ECB:DES-EDE3", "fips=yes", tdes_ede3_ecb_functions },
|
||||
{ "DES-EDE3-CBC:DES3", "fips=yes", tdes_ede3_cbc_functions },
|
||||
ALG("DES-EDE3-ECB:DES-EDE3", tdes_ede3_ecb_functions),
|
||||
ALG("DES-EDE3-CBC:DES3", tdes_ede3_cbc_functions),
|
||||
#endif /* OPENSSL_NO_DES */
|
||||
{ NULL, NULL, NULL }
|
||||
{ { NULL, NULL, NULL }, NULL }
|
||||
};
|
||||
static OSSL_ALGORITHM exported_fips_ciphers[OSSL_NELEM(fips_ciphers)];
|
||||
|
||||
static const OSSL_ALGORITHM fips_macs[] = {
|
||||
#ifndef OPENSSL_NO_CMAC
|
||||
@@ -402,17 +571,31 @@ static const OSSL_ALGORITHM fips_macs[] = {
|
||||
#endif
|
||||
{ "GMAC", "fips=yes", gmac_functions },
|
||||
{ "HMAC", "fips=yes", hmac_functions },
|
||||
{ "KMAC128", "fips=yes", kmac128_functions },
|
||||
{ "KMAC256", "fips=yes", kmac256_functions },
|
||||
{ "KMAC-128:KMAC128", "fips=yes", kmac128_functions },
|
||||
{ "KMAC-256:KMAC256", "fips=yes", kmac256_functions },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static const OSSL_ALGORITHM fips_kdfs[] = {
|
||||
{ OSSL_KDF_NAME_HKDF, "fips=yes", kdf_hkdf_functions },
|
||||
{ OSSL_KDF_NAME_SSKDF, "fips=yes", kdf_sskdf_functions },
|
||||
{ OSSL_KDF_NAME_PBKDF2, "fips=yes", kdf_pbkdf2_functions },
|
||||
{ OSSL_KDF_NAME_TLS1_PRF, "fips=yes", kdf_tls1_prf_functions },
|
||||
{ OSSL_KDF_NAME_KBKDF, "fips=yes", kdf_kbkdf_functions },
|
||||
{ "HKDF", "fips=yes", kdf_hkdf_functions },
|
||||
{ "SSKDF", "fips=yes", kdf_sskdf_functions },
|
||||
{ "PBKDF2", "fips=yes", kdf_pbkdf2_functions },
|
||||
{ "TLS1-PRF", "fips=yes", kdf_tls1_prf_functions },
|
||||
{ "KBKDF", "fips=yes", kdf_kbkdf_functions },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static const OSSL_ALGORITHM fips_signature[] = {
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
{ "DSA:dsaEncryption", "fips=yes", dsa_signature_functions },
|
||||
#endif
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static const OSSL_ALGORITHM fips_keymgmt[] = {
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
{ "DSA", "fips=yes", dsa_keymgmt_functions },
|
||||
#endif
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -425,11 +608,16 @@ static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
|
||||
case OSSL_OP_DIGEST:
|
||||
return fips_digests;
|
||||
case OSSL_OP_CIPHER:
|
||||
return fips_ciphers;
|
||||
ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers);
|
||||
return exported_fips_ciphers;
|
||||
case OSSL_OP_MAC:
|
||||
return fips_macs;
|
||||
case OSSL_OP_KDF:
|
||||
return fips_kdfs;
|
||||
case OSSL_OP_KEYMGMT:
|
||||
return fips_keymgmt;
|
||||
case OSSL_OP_SIGNATURE:
|
||||
return fips_signature;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -461,9 +649,14 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
{
|
||||
FIPS_GLOBAL *fgbl;
|
||||
OPENSSL_CTX *ctx;
|
||||
OSSL_self_test_cb_fn *stcbfn = NULL;
|
||||
OSSL_core_get_library_context_fn *c_get_libctx = NULL;
|
||||
|
||||
for (; in->function_id != 0; in++) {
|
||||
switch (in->function_id) {
|
||||
case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT:
|
||||
c_get_libctx = OSSL_get_core_get_library_context(in);
|
||||
break;
|
||||
case OSSL_FUNC_CORE_GETTABLE_PARAMS:
|
||||
c_gettable_params = OSSL_get_core_gettable_params(in);
|
||||
break;
|
||||
@@ -527,12 +720,25 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
case OSSL_FUNC_BIO_FREE:
|
||||
selftest_params.bio_free_cb = OSSL_get_BIO_free(in);
|
||||
break;
|
||||
case OSSL_FUNC_SELF_TEST_CB: {
|
||||
stcbfn = OSSL_get_self_test_cb(in);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Just ignore anything we don't understand */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stcbfn != NULL && c_get_libctx != NULL) {
|
||||
stcbfn(c_get_libctx(provider), &selftest_params.event_cb,
|
||||
&selftest_params.event_cb_arg);
|
||||
}
|
||||
else {
|
||||
selftest_params.event_cb = NULL;
|
||||
selftest_params.event_cb_arg = NULL;
|
||||
}
|
||||
|
||||
if (!c_get_params(provider, core_params))
|
||||
return 0;
|
||||
|
||||
@@ -548,7 +754,16 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
fgbl->prov = provider;
|
||||
|
||||
selftest_params.libctx = PROV_LIBRARY_CONTEXT_OF(ctx);
|
||||
if (!SELF_TEST_post(&selftest_params)) {
|
||||
if (!SELF_TEST_post(&selftest_params, 0)) {
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(3.0): Remove me. This is just a dummy call to demonstrate making
|
||||
* EVP calls from within the FIPS module.
|
||||
*/
|
||||
if (!dummy_evp_call(ctx)) {
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
@@ -556,16 +771,6 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
*out = fips_dispatch_table;
|
||||
*provctx = ctx;
|
||||
|
||||
/*
|
||||
* TODO(3.0): Remove me. This is just a dummy call to demonstrate making
|
||||
* EVP calls from within the FIPS module.
|
||||
*/
|
||||
if (!dummy_evp_call(*provctx)) {
|
||||
OPENSSL_CTX_free(*provctx);
|
||||
*provctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "e_os.h"
|
||||
/*
|
||||
* We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS
|
||||
* module because all such initialisation should be associated with an
|
||||
* individual OPENSSL_CTX. That doesn't work with the self test though because
|
||||
* it should be run once regardless of the number of OPENSSL_CTXs we have.
|
||||
*/
|
||||
#define ALLOW_RUN_ONCE_IN_FIPS
|
||||
#include <internal/thread_once.h>
|
||||
#include "self_test.h"
|
||||
|
||||
#define FIPS_STATE_INIT 0
|
||||
#define FIPS_STATE_SELFTEST 1
|
||||
#define FIPS_STATE_RUNNING 2
|
||||
#define FIPS_STATE_ERROR 3
|
||||
|
||||
/* The size of a temp buffer used to read in data */
|
||||
#define INTEGRITY_BUF_SIZE (4096)
|
||||
#define MAX_MD_SIZE 64
|
||||
#define MAC_NAME "HMAC"
|
||||
#define DIGEST_NAME "SHA256"
|
||||
|
||||
static int FIPS_state = FIPS_STATE_INIT;
|
||||
static CRYPTO_RWLOCK *self_test_lock = NULL;
|
||||
static unsigned char fixed_key[32] = { 0 };
|
||||
|
||||
static CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)
|
||||
{
|
||||
/*
|
||||
* This lock gets freed in platform specific ways that may occur after we
|
||||
* do mem leak checking. If we don't know how to free it for a particular
|
||||
* platform then we just leak it deliberately. So we temporarily disable the
|
||||
* mem leak checking while we allocate this.
|
||||
*/
|
||||
self_test_lock = CRYPTO_THREAD_lock_new();
|
||||
return self_test_lock != NULL;
|
||||
}
|
||||
|
||||
#define DEP_DECLARE() \
|
||||
void init(void); \
|
||||
void cleanup(void);
|
||||
|
||||
/*
|
||||
* This is the Default Entry Point (DEP) code. Every platform must have a DEP.
|
||||
* See FIPS 140-2 IG 9.10
|
||||
*
|
||||
* If we're run on a platform where we don't know how to define the DEP then
|
||||
* the self-tests will never get triggered (FIPS_state never moves to
|
||||
* FIPS_STATE_SELFTEST). This will be detected as an error when SELF_TEST_post()
|
||||
* is called from OSSL_provider_init(), and so the fips module will be unusable
|
||||
* on those platforms.
|
||||
*/
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# ifdef __CYGWIN__
|
||||
/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
|
||||
# include <windows.h>
|
||||
/*
|
||||
* this has side-effect of _WIN32 getting defined, which otherwise is
|
||||
* mutually exclusive with __CYGWIN__...
|
||||
*/
|
||||
# endif
|
||||
|
||||
DEP_DECLARE()
|
||||
# define DEP_INIT_ATTRIBUTE
|
||||
# define DEP_FINI_ATTRIBUTE
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
init();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
cleanup();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#elif defined(__sun)
|
||||
|
||||
DEP_DECLARE() /* must be declared before pragma */
|
||||
# define DEP_INIT_ATTRIBUTE
|
||||
# define DEP_FINI_ATTRIBUTE
|
||||
# pragma init(init)
|
||||
# pragma fini(cleanup)
|
||||
|
||||
#elif defined(__hpux)
|
||||
|
||||
DEP_DECLARE()
|
||||
# define DEP_INIT_ATTRIBUTE
|
||||
# define DEP_FINI_ATTRIBUTE
|
||||
# pragma init "init"
|
||||
# pragma fini "cleanup"
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
# define DEP_INIT_ATTRIBUTE static __attribute__((constructor))
|
||||
# define DEP_FINI_ATTRIBUTE static __attribute__((destructor))
|
||||
#endif
|
||||
|
||||
#if defined(DEP_INIT_ATTRIBUTE) && defined(DEP_FINI_ATTRIBUTE)
|
||||
DEP_INIT_ATTRIBUTE void init(void)
|
||||
{
|
||||
FIPS_state = FIPS_STATE_SELFTEST;
|
||||
}
|
||||
|
||||
DEP_FINI_ATTRIBUTE void cleanup(void)
|
||||
{
|
||||
CRYPTO_THREAD_lock_free(self_test_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify
|
||||
* the result matches the expected value.
|
||||
* Return 1 if verified, or 0 if it fails.
|
||||
*/
|
||||
static int verify_integrity(BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb,
|
||||
unsigned char *expected, size_t expected_len,
|
||||
OPENSSL_CTX *libctx, OSSL_ST_EVENT *ev,
|
||||
const char *event_type)
|
||||
{
|
||||
int ret = 0, status;
|
||||
unsigned char out[MAX_MD_SIZE];
|
||||
unsigned char buf[INTEGRITY_BUF_SIZE];
|
||||
size_t bytes_read = 0, out_len = 0;
|
||||
EVP_MAC *mac = NULL;
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
OSSL_PARAM params[3], *p = params;
|
||||
|
||||
SELF_TEST_EVENT_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
|
||||
|
||||
mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
|
||||
ctx = EVP_MAC_CTX_new(mac);
|
||||
if (mac == NULL || ctx == NULL)
|
||||
goto err;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME,
|
||||
strlen(DIGEST_NAME) + 1);
|
||||
*p++ = OSSL_PARAM_construct_octet_string("key", fixed_key,
|
||||
sizeof(fixed_key));
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
if (EVP_MAC_CTX_set_params(ctx, params) <= 0
|
||||
|| !EVP_MAC_init(ctx))
|
||||
goto err;
|
||||
|
||||
while (1) {
|
||||
status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read);
|
||||
if (status != 1)
|
||||
break;
|
||||
if (!EVP_MAC_update(ctx, buf, bytes_read))
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
|
||||
goto err;
|
||||
|
||||
SELF_TEST_EVENT_oncorrupt_byte(ev, out);
|
||||
if (expected_len != out_len
|
||||
|| memcmp(expected, out, out_len) != 0)
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
SELF_TEST_EVENT_onend(ev, ret);
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
EVP_MAC_free(mac);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This API is triggered either on loading of the FIPS module or on demand */
|
||||
int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
|
||||
{
|
||||
int ok = 0;
|
||||
int kats_already_passed = 0;
|
||||
long checksum_len;
|
||||
BIO *bio_module = NULL, *bio_indicator = NULL;
|
||||
unsigned char *module_checksum = NULL;
|
||||
unsigned char *indicator_checksum = NULL;
|
||||
int loclstate;
|
||||
OSSL_ST_EVENT ev;
|
||||
|
||||
if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
|
||||
return 0;
|
||||
|
||||
CRYPTO_THREAD_read_lock(self_test_lock);
|
||||
loclstate = FIPS_state;
|
||||
CRYPTO_THREAD_unlock(self_test_lock);
|
||||
|
||||
if (loclstate == FIPS_STATE_RUNNING) {
|
||||
if (!on_demand_test)
|
||||
return 1;
|
||||
} else if (loclstate != FIPS_STATE_SELFTEST) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CRYPTO_THREAD_write_lock(self_test_lock);
|
||||
if (FIPS_state == FIPS_STATE_RUNNING) {
|
||||
if (!on_demand_test) {
|
||||
CRYPTO_THREAD_unlock(self_test_lock);
|
||||
return 1;
|
||||
}
|
||||
FIPS_state = FIPS_STATE_SELFTEST;
|
||||
} else if (FIPS_state != FIPS_STATE_SELFTEST) {
|
||||
CRYPTO_THREAD_unlock(self_test_lock);
|
||||
return 0;
|
||||
}
|
||||
if (st == NULL
|
||||
|| st->module_checksum_data == NULL)
|
||||
goto end;
|
||||
|
||||
SELF_TEST_EVENT_init(&ev, st->event_cb, st->event_cb_arg);
|
||||
|
||||
module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
|
||||
&checksum_len);
|
||||
if (module_checksum == NULL)
|
||||
goto end;
|
||||
bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb");
|
||||
|
||||
/* Always check the integrity of the fips module */
|
||||
if (bio_module == NULL
|
||||
|| !verify_integrity(bio_module, st->bio_read_ex_cb,
|
||||
module_checksum, checksum_len, st->libctx,
|
||||
&ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY))
|
||||
goto end;
|
||||
|
||||
/* This will be NULL during installation - so the self test KATS will run */
|
||||
if (st->indicator_data != NULL) {
|
||||
/*
|
||||
* If the kats have already passed indicator is set - then check the
|
||||
* integrity of the indicator.
|
||||
*/
|
||||
if (st->indicator_checksum_data == NULL)
|
||||
goto end;
|
||||
indicator_checksum = OPENSSL_hexstr2buf(st->indicator_checksum_data,
|
||||
&checksum_len);
|
||||
if (indicator_checksum == NULL)
|
||||
goto end;
|
||||
|
||||
bio_indicator =
|
||||
(*st->bio_new_buffer_cb)(st->indicator_data,
|
||||
strlen(st->indicator_data));
|
||||
if (bio_indicator == NULL
|
||||
|| !verify_integrity(bio_indicator, st->bio_read_ex_cb,
|
||||
indicator_checksum, checksum_len,
|
||||
st->libctx, &ev,
|
||||
OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY))
|
||||
goto end;
|
||||
else
|
||||
kats_already_passed = 1;
|
||||
}
|
||||
|
||||
/* Only runs the KAT's during installation OR on_demand() */
|
||||
if (on_demand_test || kats_already_passed == 0) {
|
||||
if (!SELF_TEST_kats(&ev, st->libctx))
|
||||
goto end;
|
||||
}
|
||||
ok = 1;
|
||||
end:
|
||||
OPENSSL_free(module_checksum);
|
||||
OPENSSL_free(indicator_checksum);
|
||||
|
||||
if (st != NULL) {
|
||||
(*st->bio_free_cb)(bio_indicator);
|
||||
(*st->bio_free_cb)(bio_module);
|
||||
}
|
||||
FIPS_state = ok ? FIPS_STATE_RUNNING : FIPS_STATE_ERROR;
|
||||
CRYPTO_THREAD_unlock(self_test_lock);
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <openssl/core_numbers.h>
|
||||
#include <openssl/types.h>
|
||||
#include <openssl/self_test.h>
|
||||
|
||||
typedef struct self_test_post_params_st {
|
||||
/* FIPS module integrity check parameters */
|
||||
@@ -25,8 +26,31 @@ typedef struct self_test_post_params_st {
|
||||
OSSL_BIO_new_membuf_fn *bio_new_buffer_cb;
|
||||
OSSL_BIO_read_ex_fn *bio_read_ex_cb;
|
||||
OSSL_BIO_free_fn *bio_free_cb;
|
||||
OSSL_CALLBACK *event_cb;
|
||||
void *event_cb_arg;
|
||||
OPENSSL_CTX *libctx;
|
||||
|
||||
} SELF_TEST_POST_PARAMS;
|
||||
|
||||
int SELF_TEST_post(SELF_TEST_POST_PARAMS *st);
|
||||
typedef struct st_event_st
|
||||
{
|
||||
/* local state variables */
|
||||
const char *phase;
|
||||
const char *type;
|
||||
const char *desc;
|
||||
OSSL_CALLBACK *cb;
|
||||
|
||||
/* callback related variables used to pass the state back to the user */
|
||||
OSSL_PARAM params[4];
|
||||
void *cb_arg;
|
||||
|
||||
} OSSL_ST_EVENT;
|
||||
|
||||
int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test);
|
||||
int SELF_TEST_kats(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx);
|
||||
|
||||
void SELF_TEST_EVENT_init(OSSL_ST_EVENT *ev, OSSL_CALLBACK *cb, void *cbarg);
|
||||
void SELF_TEST_EVENT_onbegin(OSSL_ST_EVENT *ev, const char *type,
|
||||
const char *desc);
|
||||
void SELF_TEST_EVENT_onend(OSSL_ST_EVENT *ev, int ret);
|
||||
void SELF_TEST_EVENT_oncorrupt_byte(OSSL_ST_EVENT *ev, unsigned char *bytes);
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
typedef struct st_kat_st {
|
||||
const char *desc;
|
||||
const char *algorithm;
|
||||
const unsigned char *pt;
|
||||
size_t pt_len;
|
||||
const unsigned char *expected;
|
||||
size_t expected_len;
|
||||
} ST_KAT;
|
||||
|
||||
typedef ST_KAT ST_KAT_DIGEST;
|
||||
typedef struct st_kat_cipher_st {
|
||||
ST_KAT base;
|
||||
const unsigned char *key;
|
||||
size_t key_len;
|
||||
const unsigned char *iv;
|
||||
size_t iv_len;
|
||||
const unsigned char *aad;
|
||||
size_t aad_len;
|
||||
const unsigned char *tag;
|
||||
size_t tag_len;
|
||||
} ST_KAT_CIPHER;
|
||||
|
||||
typedef struct st_kat_nvp_st {
|
||||
const char *name;
|
||||
const char *value;
|
||||
} ST_KAT_NVP;
|
||||
|
||||
typedef struct st_kat_kdf_st {
|
||||
const char *desc;
|
||||
const char *algorithm;
|
||||
const ST_KAT_NVP *ctrls;
|
||||
const unsigned char *expected;
|
||||
size_t expected_len;
|
||||
} ST_KAT_KDF;
|
||||
|
||||
/* Macros to build Self test data */
|
||||
#define ITM(x) x, sizeof(x)
|
||||
#define ITM_STR(x) x, sizeof(x) - 1
|
||||
|
||||
/*- DIGEST TEST DATA */
|
||||
static const unsigned char sha1_pt[] = "abc";
|
||||
static const unsigned char sha1_digest[] = {
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 0x25, 0x71,
|
||||
0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D
|
||||
};
|
||||
|
||||
static const unsigned char sha512_pt[] = "abc";
|
||||
static const unsigned char sha512_digest[] = {
|
||||
0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, 0xCC, 0x41, 0x73, 0x49,
|
||||
0xAE, 0x20, 0x41, 0x31, 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
|
||||
0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, 0x21, 0x92, 0x99, 0x2A,
|
||||
0x27, 0x4F, 0xC1, 0xA8, 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
|
||||
0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, 0x2A, 0x9A, 0xC9, 0x4F,
|
||||
0xA5, 0x4C, 0xA4, 0x9F
|
||||
};
|
||||
static const unsigned char sha3_256_pt[] = { 0xe7, 0x37, 0x21, 0x05 };
|
||||
static const unsigned char sha3_256_digest[] = {
|
||||
0x3a, 0x42, 0xb6, 0x8a, 0xb0, 0x79, 0xf2, 0x8c, 0x4c, 0xa3, 0xc7, 0x52,
|
||||
0x29, 0x6f, 0x27, 0x90, 0x06, 0xc4, 0xfe, 0x78, 0xb1, 0xeb, 0x79, 0xd9,
|
||||
0x89, 0x77, 0x7f, 0x05, 0x1e, 0x40, 0x46, 0xae
|
||||
};
|
||||
|
||||
static const ST_KAT_DIGEST st_kat_digest_tests[] =
|
||||
{
|
||||
{
|
||||
OSSL_SELF_TEST_DESC_MD_SHA1,
|
||||
"SHA1",
|
||||
ITM_STR(sha1_pt),
|
||||
ITM(sha1_digest),
|
||||
},
|
||||
{
|
||||
OSSL_SELF_TEST_DESC_MD_SHA2,
|
||||
"SHA512",
|
||||
ITM_STR(sha512_pt),
|
||||
ITM(sha512_digest),
|
||||
},
|
||||
{
|
||||
OSSL_SELF_TEST_DESC_MD_SHA3,
|
||||
"SHA3-256",
|
||||
ITM(sha3_256_pt),
|
||||
ITM(sha3_256_digest),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/*- CIPHER TEST DATA */
|
||||
|
||||
/* DES3 test data */
|
||||
static const unsigned char des_ede3_cbc_pt[] = {
|
||||
0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11,
|
||||
0x73, 0x93, 0x17, 0x2A, 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
|
||||
0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51
|
||||
};
|
||||
|
||||
static const unsigned char des_ede3_cbc_key[] = {
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
|
||||
0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
|
||||
};
|
||||
static const unsigned char des_ede3_cbc_iv[] = {
|
||||
0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17
|
||||
};
|
||||
static const unsigned char des_ede3_cbc_ct[] = {
|
||||
0x20, 0x79, 0xC3, 0xD5, 0x3A, 0xA7, 0x63, 0xE1, 0x93, 0xB7, 0x9E, 0x25,
|
||||
0x69, 0xAB, 0x52, 0x62, 0x51, 0x65, 0x70, 0x48, 0x1F, 0x25, 0xB5, 0x0F,
|
||||
0x73, 0xC0, 0xBD, 0xA8, 0x5C, 0x8E, 0x0D, 0xA7
|
||||
};
|
||||
|
||||
static const unsigned char aes_256_gcm_key[] = {
|
||||
0x92,0xe1,0x1d,0xcd,0xaa,0x86,0x6f,0x5c,0xe7,0x90,0xfd,0x24,
|
||||
0x50,0x1f,0x92,0x50,0x9a,0xac,0xf4,0xcb,0x8b,0x13,0x39,0xd5,
|
||||
0x0c,0x9c,0x12,0x40,0x93,0x5d,0xd0,0x8b
|
||||
};
|
||||
static const unsigned char aes_256_gcm_iv[] = {
|
||||
0xac,0x93,0xa1,0xa6,0x14,0x52,0x99,0xbd,0xe9,0x02,0xf2,0x1a
|
||||
};
|
||||
static const unsigned char aes_256_gcm_pt[] = {
|
||||
0x2d,0x71,0xbc,0xfa,0x91,0x4e,0x4a,0xc0,0x45,0xb2,0xaa,0x60,
|
||||
0x95,0x5f,0xad,0x24
|
||||
};
|
||||
static const unsigned char aes_256_gcm_aad[] = {
|
||||
0x1e,0x08,0x89,0x01,0x6f,0x67,0x60,0x1c,0x8e,0xbe,0xa4,0x94,
|
||||
0x3b,0xc2,0x3a,0xd6
|
||||
};
|
||||
static const unsigned char aes_256_gcm_ct[] = {
|
||||
0x89,0x95,0xae,0x2e,0x6d,0xf3,0xdb,0xf9,0x6f,0xac,0x7b,0x71,
|
||||
0x37,0xba,0xe6,0x7f
|
||||
};
|
||||
static const unsigned char aes_256_gcm_tag[] = {
|
||||
0xec,0xa5,0xaa,0x77,0xd5,0x1d,0x4a,0x0a,0x14,0xd9,0xc5,0x1e,
|
||||
0x1d,0xa4,0x74,0xab
|
||||
};
|
||||
|
||||
static const ST_KAT_CIPHER st_kat_cipher_tests[] = {
|
||||
{
|
||||
{
|
||||
OSSL_SELF_TEST_DESC_CIPHER_TDES,
|
||||
"DES-EDE3-CBC",
|
||||
ITM(des_ede3_cbc_pt),
|
||||
ITM(des_ede3_cbc_ct)
|
||||
},
|
||||
ITM(des_ede3_cbc_key),
|
||||
ITM(des_ede3_cbc_iv),
|
||||
},
|
||||
{
|
||||
{
|
||||
OSSL_SELF_TEST_DESC_CIPHER_AES_GCM,
|
||||
"AES-256-GCM",
|
||||
ITM(aes_256_gcm_pt),
|
||||
ITM(aes_256_gcm_ct),
|
||||
},
|
||||
ITM(aes_256_gcm_key),
|
||||
ITM(aes_256_gcm_iv),
|
||||
ITM(aes_256_gcm_aad),
|
||||
ITM(aes_256_gcm_tag)
|
||||
}
|
||||
};
|
||||
|
||||
/*- KDF TEST DATA */
|
||||
|
||||
static const ST_KAT_NVP hkdf_ctrl[] =
|
||||
{
|
||||
{ "digest", "SHA256" },
|
||||
{ "key", "secret" },
|
||||
{ "salt", "salt" },
|
||||
{ "info", "label" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
static const unsigned char hkdf_expected[] = {
|
||||
0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13
|
||||
};
|
||||
|
||||
static const ST_KAT_KDF st_kat_kdf_tests[] =
|
||||
{
|
||||
{
|
||||
OSSL_SELF_TEST_DESC_KDF_HKDF,
|
||||
"HKDF",
|
||||
hkdf_ctrl,
|
||||
ITM(hkdf_expected)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include "self_test.h"
|
||||
|
||||
static void self_test_event_setparams(OSSL_ST_EVENT *ev)
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
if (ev->cb != NULL) {
|
||||
ev->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE,
|
||||
(char *)ev->phase, 0);
|
||||
ev->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE,
|
||||
(char *)ev->type, 0);
|
||||
ev->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC,
|
||||
(char *)ev->desc, 0);
|
||||
}
|
||||
ev->params[n++] = OSSL_PARAM_construct_end();
|
||||
}
|
||||
|
||||
void SELF_TEST_EVENT_init(OSSL_ST_EVENT *ev, OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
if (ev == NULL)
|
||||
return;
|
||||
|
||||
ev->cb = cb;
|
||||
ev->cb_arg = cbarg;
|
||||
ev->phase = "";
|
||||
ev->type = "";
|
||||
ev->desc = "";
|
||||
self_test_event_setparams(ev);
|
||||
}
|
||||
|
||||
/* Can be used during application testing to log that a test has started. */
|
||||
void SELF_TEST_EVENT_onbegin(OSSL_ST_EVENT *ev, const char *type,
|
||||
const char *desc)
|
||||
{
|
||||
if (ev != NULL && ev->cb != NULL) {
|
||||
ev->phase = OSSL_SELF_TEST_PHASE_START;
|
||||
ev->type = type;
|
||||
ev->desc = desc;
|
||||
self_test_event_setparams(ev);
|
||||
(void)ev->cb(ev->params, ev->cb_arg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Can be used during application testing to log that a test has either
|
||||
* passed or failed.
|
||||
*/
|
||||
void SELF_TEST_EVENT_onend(OSSL_ST_EVENT *ev, int ret)
|
||||
{
|
||||
if (ev != NULL && ev->cb != NULL) {
|
||||
ev->phase =
|
||||
(ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL);
|
||||
self_test_event_setparams(ev);
|
||||
(void)ev->cb(ev->params, ev->cb_arg);
|
||||
|
||||
ev->phase = OSSL_SELF_TEST_PHASE_NONE;
|
||||
ev->type = OSSL_SELF_TEST_TYPE_NONE;
|
||||
ev->desc = OSSL_SELF_TEST_DESC_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for failure testing.
|
||||
*
|
||||
* Call the applications SELF_TEST_cb() if it exists.
|
||||
* If the application callback decides to return 0 then the first byte of 'bytes'
|
||||
* is modified (corrupted). This is used to modify output signatures or
|
||||
* ciphertext before they are verified or decrypted.
|
||||
*/
|
||||
void SELF_TEST_EVENT_oncorrupt_byte(OSSL_ST_EVENT *ev, unsigned char *bytes)
|
||||
{
|
||||
if (ev != NULL && ev->cb != NULL) {
|
||||
ev->phase = OSSL_SELF_TEST_PHASE_CORRUPT;
|
||||
self_test_event_setparams(ev);
|
||||
if (!ev->cb(ev->params, ev->cb_arg))
|
||||
bytes[0] ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include "internal/nelem.h"
|
||||
#include "self_test.h"
|
||||
#include "self_test_data.inc"
|
||||
|
||||
static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_ST_EVENT *event,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ok = 0;
|
||||
unsigned char out[EVP_MAX_MD_SIZE];
|
||||
unsigned int out_len = 0;
|
||||
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
||||
EVP_MD *md = EVP_MD_fetch(libctx, t->algorithm, NULL);
|
||||
|
||||
SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_KAT_DIGEST, t->desc);
|
||||
|
||||
if (ctx == NULL
|
||||
|| md == NULL
|
||||
|| !EVP_DigestInit_ex(ctx, md, NULL)
|
||||
|| !EVP_DigestUpdate(ctx, t->pt, t->pt_len)
|
||||
|| !EVP_DigestFinal(ctx, out, &out_len))
|
||||
goto err;
|
||||
|
||||
/* Optional corruption */
|
||||
SELF_TEST_EVENT_oncorrupt_byte(event, out);
|
||||
|
||||
if (out_len != t->expected_len
|
||||
|| memcmp(out, t->expected, out_len) != 0)
|
||||
goto err;
|
||||
ok = 1;
|
||||
err:
|
||||
SELF_TEST_EVENT_onend(event, ok);
|
||||
EVP_MD_free(md);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to setup a EVP_CipherInit
|
||||
* Used to hide the complexity of Authenticated ciphers.
|
||||
*/
|
||||
static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
const ST_KAT_CIPHER *t, int enc)
|
||||
{
|
||||
unsigned char *in_tag = NULL;
|
||||
int pad = 0, tmp;
|
||||
|
||||
/* Flag required for Key wrapping */
|
||||
EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
|
||||
if (t->tag == NULL) {
|
||||
/* Use a normal cipher init */
|
||||
return EVP_CipherInit_ex(ctx, cipher, NULL, t->key, t->iv, enc)
|
||||
&& EVP_CIPHER_CTX_set_padding(ctx, pad);
|
||||
}
|
||||
|
||||
/* The authenticated cipher init */
|
||||
if (!enc)
|
||||
in_tag = (unsigned char *)t->tag;
|
||||
|
||||
return EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)
|
||||
&& EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, t->iv_len, NULL)
|
||||
&& (in_tag == NULL
|
||||
|| EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, t->tag_len,
|
||||
in_tag))
|
||||
&& EVP_CipherInit_ex(ctx, NULL, NULL, t->key, t->iv, enc)
|
||||
&& EVP_CIPHER_CTX_set_padding(ctx, pad)
|
||||
&& EVP_CipherUpdate(ctx, NULL, &tmp, t->aad, t->aad_len);
|
||||
}
|
||||
|
||||
/* Test a single KAT for encrypt/decrypt */
|
||||
static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 0, encrypt = 1, len, ct_len = 0, pt_len = 0;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
unsigned char ct_buf[256] = { 0 };
|
||||
unsigned char pt_buf[256] = { 0 };
|
||||
|
||||
SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_KAT_CIPHER, t->base.desc);
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto end;
|
||||
cipher = EVP_CIPHER_fetch(libctx, t->base.algorithm, "");
|
||||
if (cipher == NULL)
|
||||
goto end;
|
||||
|
||||
/* Encrypt plain text message */
|
||||
if (!cipher_init(ctx, cipher, t, encrypt)
|
||||
|| !EVP_CipherUpdate(ctx, ct_buf, &len, t->base.pt, t->base.pt_len)
|
||||
|| !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len))
|
||||
goto end;
|
||||
|
||||
SELF_TEST_EVENT_oncorrupt_byte(event, ct_buf);
|
||||
ct_len += len;
|
||||
if (ct_len != (int)t->base.expected_len
|
||||
|| memcmp(t->base.expected, ct_buf, ct_len) != 0)
|
||||
goto end;
|
||||
|
||||
if (t->tag != NULL) {
|
||||
unsigned char tag[16] = { 0 };
|
||||
|
||||
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, t->tag_len, tag)
|
||||
|| memcmp(tag, t->tag, t->tag_len) != 0)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(cipher_init(ctx, cipher, t, !encrypt)
|
||||
&& EVP_CipherUpdate(ctx, pt_buf, &len, ct_buf, ct_len)
|
||||
&& EVP_CipherFinal_ex(ctx, pt_buf + len, &pt_len)))
|
||||
goto end;
|
||||
pt_len += len;
|
||||
|
||||
if (pt_len != (int)t->base.pt_len
|
||||
|| memcmp(pt_buf, t->base.pt, pt_len) != 0)
|
||||
goto end;
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
EVP_CIPHER_free(cipher);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
SELF_TEST_EVENT_onend(event, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int self_test_kdf(const ST_KAT_KDF *t, OSSL_ST_EVENT *event,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
unsigned char out[64];
|
||||
EVP_KDF *kdf = NULL;
|
||||
EVP_KDF_CTX *ctx = NULL;
|
||||
OSSL_PARAM params[16];
|
||||
const OSSL_PARAM *settables = NULL;
|
||||
|
||||
SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc);
|
||||
|
||||
kdf = EVP_KDF_fetch(libctx, t->algorithm, "");
|
||||
ctx = EVP_KDF_CTX_new(kdf);
|
||||
if (ctx == NULL)
|
||||
goto end;
|
||||
|
||||
settables = EVP_KDF_settable_ctx_params(kdf);
|
||||
for (i = 0; t->ctrls[i].name != NULL; ++i) {
|
||||
if (!OSSL_PARAM_allocate_from_text(¶ms[i], settables,
|
||||
t->ctrls[i].name,
|
||||
t->ctrls[i].value,
|
||||
strlen(t->ctrls[i].value)))
|
||||
goto end;
|
||||
}
|
||||
params[i] = OSSL_PARAM_construct_end();
|
||||
if (!EVP_KDF_CTX_set_params(ctx, params))
|
||||
goto end;
|
||||
|
||||
if (t->expected_len > sizeof(out))
|
||||
goto end;
|
||||
if (EVP_KDF_derive(ctx, out, t->expected_len) <= 0)
|
||||
goto end;
|
||||
|
||||
SELF_TEST_EVENT_oncorrupt_byte(event, out);
|
||||
|
||||
if (memcmp(out, t->expected, t->expected_len) != 0)
|
||||
goto end;
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
for (i = 0; params[i].key != NULL; ++i)
|
||||
OPENSSL_free(params[i].data);
|
||||
EVP_KDF_free(kdf);
|
||||
EVP_KDF_CTX_free(ctx);
|
||||
SELF_TEST_EVENT_onend(event, 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 if any test fails.
|
||||
*/
|
||||
static int self_test_digests(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
||||
{
|
||||
int i, ret = 1;
|
||||
|
||||
for (i = 0; i < (int)OSSL_NELEM(st_kat_digest_tests); ++i) {
|
||||
if (!self_test_digest(&st_kat_digest_tests[i], event, libctx))
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int self_test_ciphers(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
||||
{
|
||||
int i, ret = 1;
|
||||
|
||||
for (i = 0; i < (int)OSSL_NELEM(st_kat_cipher_tests); ++i) {
|
||||
if (!self_test_cipher(&st_kat_cipher_tests[i], event, libctx))
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int self_test_kdfs(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
||||
{
|
||||
int i, ret = 1;
|
||||
|
||||
for (i = 0; i < (int)OSSL_NELEM(st_kat_kdf_tests); ++i) {
|
||||
if (!self_test_kdf(&st_kat_kdf_tests[i], event, libctx))
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the algorithm KAT's.
|
||||
* Return 1 is successful, otherwise return 0.
|
||||
* This runs all the tests regardless of if any fail.
|
||||
*
|
||||
* TODO(3.0) Add self tests for KA, DRBG, Sign/Verify when they become available
|
||||
*/
|
||||
int SELF_TEST_kats(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (!self_test_digests(event, libctx))
|
||||
ret = 0;
|
||||
if (!self_test_ciphers(event, libctx))
|
||||
ret = 0;
|
||||
if (!self_test_kdfs(event, libctx))
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/params.h>
|
||||
#include "selftest.h"
|
||||
|
||||
#define FIPS_STATE_INIT 0
|
||||
#define FIPS_STATE_RUNNING 1
|
||||
#define FIPS_STATE_SELFTEST 2
|
||||
#define FIPS_STATE_ERROR 3
|
||||
|
||||
/* The size of a temp buffer used to read in data */
|
||||
#define INTEGRITY_BUF_SIZE (4096)
|
||||
#define MAX_MD_SIZE 64
|
||||
#define MAC_NAME "HMAC"
|
||||
#define DIGEST_NAME "SHA256"
|
||||
|
||||
static int FIPS_state = FIPS_STATE_INIT;
|
||||
static unsigned char fixed_key[32] = { 0 };
|
||||
|
||||
/*
|
||||
* Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify
|
||||
* the result matches the expected value.
|
||||
* Return 1 if verified, or 0 if it fails.
|
||||
*/
|
||||
static int verify_integrity(BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb,
|
||||
unsigned char *expected, size_t expected_len,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 0, status;
|
||||
unsigned char out[MAX_MD_SIZE];
|
||||
unsigned char buf[INTEGRITY_BUF_SIZE];
|
||||
size_t bytes_read = 0, out_len = 0;
|
||||
EVP_MAC *mac = NULL;
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
OSSL_PARAM params[3], *p = params;
|
||||
|
||||
mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
|
||||
ctx = EVP_MAC_CTX_new(mac);
|
||||
if (mac == NULL || ctx == NULL)
|
||||
goto err;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME,
|
||||
strlen(DIGEST_NAME) + 1);
|
||||
*p++ = OSSL_PARAM_construct_octet_string("key", fixed_key,
|
||||
sizeof(fixed_key));
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
if (EVP_MAC_CTX_set_params(ctx, params) <= 0
|
||||
|| !EVP_MAC_init(ctx))
|
||||
goto err;
|
||||
|
||||
while (1) {
|
||||
status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read);
|
||||
if (status != 1)
|
||||
break;
|
||||
if (!EVP_MAC_update(ctx, buf, bytes_read))
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
|
||||
goto err;
|
||||
|
||||
if (expected_len != out_len
|
||||
|| memcmp(expected, out, out_len) != 0)
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
EVP_MAC_free(mac);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This API is triggered either on loading of the FIPS module or on demand */
|
||||
int SELF_TEST_post(SELF_TEST_POST_PARAMS *st)
|
||||
{
|
||||
int ok = 0;
|
||||
int kats_already_passed = 0;
|
||||
int on_demand_test = (FIPS_state != FIPS_STATE_INIT);
|
||||
long checksum_len;
|
||||
BIO *bio_module = NULL, *bio_indicator = NULL;
|
||||
unsigned char *module_checksum = NULL;
|
||||
unsigned char *indicator_checksum = NULL;
|
||||
|
||||
if (st == NULL
|
||||
|| FIPS_state == FIPS_STATE_ERROR
|
||||
|| FIPS_state == FIPS_STATE_SELFTEST
|
||||
|| st->module_checksum_data == NULL)
|
||||
goto end;
|
||||
|
||||
module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
|
||||
&checksum_len);
|
||||
if (module_checksum == NULL)
|
||||
goto end;
|
||||
bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb");
|
||||
|
||||
/* Always check the integrity of the fips module */
|
||||
if (bio_module == NULL
|
||||
|| !verify_integrity(bio_module, st->bio_read_ex_cb,
|
||||
module_checksum, checksum_len, st->libctx))
|
||||
goto end;
|
||||
|
||||
/* This will be NULL during installation - so the self test KATS will run */
|
||||
if (st->indicator_data != NULL) {
|
||||
/*
|
||||
* If the kats have already passed indicator is set - then check the
|
||||
* integrity of the indicator.
|
||||
*/
|
||||
if (st->indicator_checksum_data == NULL)
|
||||
goto end;
|
||||
indicator_checksum = OPENSSL_hexstr2buf(st->indicator_checksum_data,
|
||||
&checksum_len);
|
||||
if (indicator_checksum == NULL)
|
||||
goto end;
|
||||
|
||||
bio_indicator =
|
||||
(*st->bio_new_buffer_cb)(st->indicator_data,
|
||||
strlen(st->indicator_data));
|
||||
if (bio_indicator == NULL
|
||||
|| !verify_integrity(bio_indicator, st->bio_read_ex_cb,
|
||||
indicator_checksum, checksum_len,
|
||||
st->libctx))
|
||||
goto end;
|
||||
else
|
||||
kats_already_passed = 1;
|
||||
}
|
||||
|
||||
/* Only runs the KAT's during installation OR on_demand() */
|
||||
if (on_demand_test || kats_already_passed == 0) {
|
||||
/*TODO (3.0) Add self test KATS */
|
||||
}
|
||||
ok = 1;
|
||||
end:
|
||||
OPENSSL_free(module_checksum);
|
||||
OPENSSL_free(indicator_checksum);
|
||||
|
||||
if (st != NULL) {
|
||||
(*st->bio_free_cb)(bio_indicator);
|
||||
(*st->bio_free_cb)(bio_module);
|
||||
}
|
||||
FIPS_state = ok ? FIPS_STATE_RUNNING : FIPS_STATE_ERROR;
|
||||
|
||||
return ok;
|
||||
}
|
||||
Reference in New Issue
Block a user