mirror of https://github.com/openssl/openssl.git
Add pairwise consistency self tests to asym keygenerators
Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10952)
This commit is contained in:
parent
97ace6c2da
commit
47c239c6b8
|
@ -61,9 +61,9 @@ ENDIF
|
|||
|
||||
# The Core
|
||||
$CORE_COMMON=provider_core.c provider_predefined.c \
|
||||
core_fetch.c core_algorithm.c core_namemap.c
|
||||
core_fetch.c core_algorithm.c core_namemap.c self_test_core.c
|
||||
|
||||
SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c self_test_core.c
|
||||
SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c
|
||||
SOURCE[../providers/libfips.a]=$CORE_COMMON
|
||||
|
||||
# Central utilities
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -15,6 +15,11 @@
|
|||
/*
|
||||
* DH low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*
|
||||
* NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
|
||||
* states that no additional pairwise tests are required (apart from the tests
|
||||
* specified in SP800-56A) when generating keys. Hence DH pairwise tests are
|
||||
* omitted here.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -17,10 +17,12 @@
|
|||
#include <time.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "crypto/dsa.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
static int dsa_builtin_keygen(DSA *dsa);
|
||||
static int dsa_keygen(DSA *dsa, int pairwise_test);
|
||||
static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg);
|
||||
|
||||
int DSA_generate_key(DSA *dsa)
|
||||
{
|
||||
|
@ -28,7 +30,7 @@ int DSA_generate_key(DSA *dsa)
|
|||
if (dsa->meth->dsa_keygen != NULL)
|
||||
return dsa->meth->dsa_keygen(dsa);
|
||||
#endif
|
||||
return dsa_builtin_keygen(dsa);
|
||||
return dsa_keygen(dsa, 0);
|
||||
}
|
||||
|
||||
int dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, const BIGNUM *priv_key,
|
||||
|
@ -50,7 +52,7 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int dsa_builtin_keygen(DSA *dsa)
|
||||
static int dsa_keygen(DSA *dsa, int pairwise_test)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
|
@ -82,8 +84,26 @@ static int dsa_builtin_keygen(DSA *dsa)
|
|||
|
||||
dsa->priv_key = priv_key;
|
||||
dsa->pub_key = pub_key;
|
||||
dsa->dirty_cnt++;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
pairwise_test = 1;
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
ok = 1;
|
||||
if (pairwise_test) {
|
||||
OSSL_CALLBACK *cb = NULL;
|
||||
void *cbarg = NULL;
|
||||
|
||||
OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg);
|
||||
ok = dsa_keygen_pairwise_test(dsa, cb, cbarg);
|
||||
if (!ok) {
|
||||
BN_free(dsa->pub_key);
|
||||
BN_clear_free(dsa->priv_key);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
dsa->dirty_cnt++;
|
||||
|
||||
err:
|
||||
if (pub_key != dsa->pub_key)
|
||||
|
@ -91,5 +111,42 @@ static int dsa_builtin_keygen(DSA *dsa)
|
|||
if (priv_key != dsa->priv_key)
|
||||
BN_free(priv_key);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIPS 140-2 IG 9.9 AS09.33
|
||||
* Perform a sign/verify operation.
|
||||
*/
|
||||
static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char dgst[16] = {0};
|
||||
unsigned int dgst_len = (unsigned int)sizeof(dgst);
|
||||
DSA_SIG *sig = NULL;
|
||||
OSSL_SELF_TEST *st = NULL;
|
||||
|
||||
st = OSSL_SELF_TEST_new(cb, cbarg);
|
||||
if (st == NULL)
|
||||
goto err;
|
||||
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
|
||||
OSSL_SELF_TEST_DESC_PCT_DSA);
|
||||
|
||||
sig = DSA_do_sign(dgst, (int)dgst_len, dsa);
|
||||
if (sig == NULL)
|
||||
goto err;
|
||||
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, dgst);
|
||||
|
||||
if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
OSSL_SELF_TEST_free(st);
|
||||
DSA_SIG_free(sig);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
|
@ -20,8 +20,12 @@
|
|||
#include "internal/refcount.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "crypto/bn.h"
|
||||
|
||||
static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
|
||||
void *cbarg);
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
EC_KEY *EC_KEY_new(void)
|
||||
{
|
||||
|
@ -241,11 +245,14 @@ int ossl_ec_key_gen(EC_KEY *eckey)
|
|||
* See SP800-56AR3 5.6.1.2.2 "Key Pair Generation by Testing Candidates"
|
||||
*
|
||||
* Params:
|
||||
* libctx A context containing an optional self test callback.
|
||||
* eckey An EC key object that contains domain params. The generated keypair
|
||||
* is stored in this object.
|
||||
* pairwise_test Set to non zero to perform a pairwise test. If the test
|
||||
* fails then the keypair is not generated,
|
||||
* Returns 1 if the keypair was generated or 0 otherwise.
|
||||
*/
|
||||
int ec_key_simple_generate_key(EC_KEY *eckey)
|
||||
int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test)
|
||||
{
|
||||
int ok = 0;
|
||||
BIGNUM *priv_key = NULL;
|
||||
|
@ -305,8 +312,18 @@ int ec_key_simple_generate_key(EC_KEY *eckey)
|
|||
|
||||
eckey->dirty_cnt++;
|
||||
|
||||
ok = 1;
|
||||
#ifdef FIPS_MODE
|
||||
pairwise_test = 1;
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
ok = 1;
|
||||
if (pairwise_test) {
|
||||
OSSL_CALLBACK *cb = NULL;
|
||||
void *cbarg = NULL;
|
||||
|
||||
OSSL_SELF_TEST_get_callback(libctx, &cb, &cbarg);
|
||||
ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg);
|
||||
}
|
||||
err:
|
||||
/* Step (9): If there is an error return an invalid keypair. */
|
||||
if (!ok) {
|
||||
|
@ -321,6 +338,11 @@ err:
|
|||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_simple_generate_key(EC_KEY *eckey)
|
||||
{
|
||||
return ec_generate_key(NULL, eckey, 0);
|
||||
}
|
||||
|
||||
int ec_key_simple_generate_public_key(EC_KEY *eckey)
|
||||
{
|
||||
int ret;
|
||||
|
@ -849,3 +871,45 @@ int EC_KEY_can_sign(const EC_KEY *eckey)
|
|||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIPS 140-2 IG 9.9 AS09.33
|
||||
* Perform a sign/verify operation.
|
||||
*
|
||||
* NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
|
||||
* states that no additional pairwise tests are required (apart from the tests
|
||||
* specified in SP800-56A) when generating keys. Hence pairwise ECDH tests are
|
||||
* omitted here.
|
||||
*/
|
||||
static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
|
||||
void *cbarg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char dgst[16] = {0};
|
||||
int dgst_len = (int)sizeof(dgst);
|
||||
ECDSA_SIG *sig = NULL;
|
||||
OSSL_SELF_TEST *st = NULL;
|
||||
|
||||
st = OSSL_SELF_TEST_new(cb, cbarg);
|
||||
if (st == NULL)
|
||||
return 0;
|
||||
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
|
||||
OSSL_SELF_TEST_DESC_PCT_ECDSA);
|
||||
|
||||
sig = ECDSA_do_sign(dgst, dgst_len, eckey);
|
||||
if (sig == NULL)
|
||||
goto err;
|
||||
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, dgst);
|
||||
|
||||
if (ECDSA_do_verify(dgst, dgst_len, sig, eckey) != 1)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
OSSL_SELF_TEST_free(st);
|
||||
ECDSA_SIG_free(sig);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -169,12 +169,13 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
|
|||
|
||||
if (r == NULL || kinv == NULL) {
|
||||
/*
|
||||
* Generate random k and copy to param param block. RAND_priv_bytes
|
||||
* Generate random k and copy to param param block. RAND_priv_bytes_ex
|
||||
* is used instead of BN_priv_rand_range or BN_generate_dsa_nonce
|
||||
* because kdsa instruction constructs an in-range, invertible nonce
|
||||
* internally implementing counter-measures for RNG weakness.
|
||||
*/
|
||||
if (RAND_priv_bytes(param + S390X_OFF_RN(len), len) != 1) {
|
||||
if (RAND_priv_bytes_ex(eckey->libctx, param + S390X_OFF_RN(len),
|
||||
len) != 1) {
|
||||
ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG,
|
||||
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
|
||||
goto ret;
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
#include <time.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "rsa_local.h"
|
||||
|
||||
static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
||||
BN_GENCB *cb);
|
||||
static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg);
|
||||
static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes,
|
||||
BIGNUM *e_value, BN_GENCB *cb, int pairwise_test);
|
||||
|
||||
/*
|
||||
* NB: this wrapper would normally be placed in rsa_lib.c and the static
|
||||
|
@ -65,19 +67,21 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes,
|
|||
return 0;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
return rsa_builtin_keygen(rsa, bits, primes, e_value, cb);
|
||||
return rsa_keygen(NULL, rsa, bits, primes, e_value, cb, 0);
|
||||
}
|
||||
|
||||
static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
||||
BN_GENCB *cb)
|
||||
static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes,
|
||||
BIGNUM *e_value, BN_GENCB *cb, int pairwise_test)
|
||||
{
|
||||
int ok = -1;
|
||||
#ifdef FIPS_MODE
|
||||
if (primes != 2)
|
||||
return 0;
|
||||
return rsa_sp800_56b_generate_key(rsa, bits, e_value, cb);
|
||||
ok = rsa_sp800_56b_generate_key(rsa, bits, e_value, cb);
|
||||
pairwise_test = 1; /* FIPS MODE needs to always run the pairwise test */
|
||||
#else
|
||||
BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime;
|
||||
int ok = -1, n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0;
|
||||
int n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0;
|
||||
int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0;
|
||||
RSA_PRIME_INFO *pinfo = NULL;
|
||||
STACK_OF(RSA_PRIME_INFO) *prime_infos = NULL;
|
||||
|
@ -87,13 +91,13 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
|||
|
||||
if (bits < RSA_MIN_MODULUS_BITS) {
|
||||
ok = 0; /* we set our own err */
|
||||
RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
|
||||
RSAerr(0, RSA_R_KEY_SIZE_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (primes < RSA_DEFAULT_PRIME_NUM || primes > rsa_multip_cap(bits)) {
|
||||
ok = 0; /* we set our own err */
|
||||
RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_PRIME_NUM_INVALID);
|
||||
RSAerr(0, RSA_R_KEY_PRIME_NUM_INVALID);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -398,11 +402,83 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
|||
ok = 1;
|
||||
err:
|
||||
if (ok == -1) {
|
||||
RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
|
||||
RSAerr(0, ERR_LIB_BN);
|
||||
ok = 0;
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
if (pairwise_test && ok > 0) {
|
||||
OSSL_CALLBACK *stcb = NULL;
|
||||
void *stcbarg = NULL;
|
||||
|
||||
OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg);
|
||||
ok = rsa_keygen_pairwise_test(rsa, stcb, stcbarg);
|
||||
if (!ok) {
|
||||
/* Clear intermediate results */
|
||||
BN_clear_free(rsa->d);
|
||||
BN_clear_free(rsa->p);
|
||||
BN_clear_free(rsa->q);
|
||||
BN_clear_free(rsa->dmp1);
|
||||
BN_clear_free(rsa->dmq1);
|
||||
BN_clear_free(rsa->iqmp);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* For RSA key generation it is not known whether the key pair will be used
|
||||
* for key transport or signatures. FIPS 140-2 IG 9.9 states that in this case
|
||||
* either a signature verification OR an encryption operation may be used to
|
||||
* perform the pairwise consistency check. The simpler encrypt/decrypt operation
|
||||
* has been chosen for this case.
|
||||
*/
|
||||
static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int ciphertxt_len;
|
||||
unsigned char *ciphertxt = NULL;
|
||||
const unsigned char plaintxt[16] = {0};
|
||||
unsigned char decoded[256];
|
||||
unsigned int decoded_len;
|
||||
unsigned int plaintxt_len = (unsigned int)sizeof(plaintxt_len);
|
||||
int padding = RSA_PKCS1_PADDING;
|
||||
OSSL_SELF_TEST *st = NULL;
|
||||
|
||||
st = OSSL_SELF_TEST_new(cb, cbarg);
|
||||
if (st == NULL)
|
||||
goto err;
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
|
||||
OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1);
|
||||
|
||||
ciphertxt_len = RSA_size(rsa);
|
||||
ciphertxt = OPENSSL_zalloc(ciphertxt_len);
|
||||
if (ciphertxt == NULL)
|
||||
goto err;
|
||||
|
||||
ciphertxt_len = RSA_public_encrypt(plaintxt_len, plaintxt, ciphertxt, rsa,
|
||||
padding);
|
||||
if (ciphertxt_len <= 0)
|
||||
goto err;
|
||||
if (ciphertxt_len == plaintxt_len
|
||||
&& memcmp(decoded, plaintxt, plaintxt_len) == 0)
|
||||
goto err;
|
||||
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, ciphertxt);
|
||||
|
||||
decoded_len = RSA_private_decrypt(ciphertxt_len, ciphertxt, decoded, rsa,
|
||||
padding);
|
||||
if (decoded_len != plaintxt_len
|
||||
|| memcmp(decoded, plaintxt, decoded_len) != 0)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
OSSL_SELF_TEST_free(st);
|
||||
OPENSSL_free(ciphertxt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -8,6 +8,8 @@
|
|||
*/
|
||||
|
||||
#include <openssl/self_test.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
typedef struct self_test_cb_st
|
||||
|
@ -16,6 +18,19 @@ typedef struct self_test_cb_st
|
|||
void *cbarg;
|
||||
} SELF_TEST_CB;
|
||||
|
||||
struct ossl_self_test_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;
|
||||
};
|
||||
|
||||
static void *self_test_set_callback_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
SELF_TEST_CB *stcb;
|
||||
|
@ -40,6 +55,7 @@ static SELF_TEST_CB *get_self_test_callback(OPENSSL_CTX *libctx)
|
|||
&self_test_set_callback_method);
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb,
|
||||
void *cbarg)
|
||||
{
|
||||
|
@ -50,6 +66,8 @@ void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb,
|
|||
stcb->cbarg = cbarg;
|
||||
}
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb,
|
||||
void **cbarg)
|
||||
{
|
||||
|
@ -60,3 +78,91 @@ void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb,
|
|||
if (cbarg != NULL)
|
||||
*cbarg = (stcb != NULL ? stcb->cbarg : NULL);
|
||||
}
|
||||
|
||||
static void self_test_setparams(OSSL_SELF_TEST *st)
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
if (st->cb != NULL) {
|
||||
st->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE,
|
||||
(char *)st->phase, 0);
|
||||
st->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE,
|
||||
(char *)st->type, 0);
|
||||
st->params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC,
|
||||
(char *)st->desc, 0);
|
||||
}
|
||||
st->params[n++] = OSSL_PARAM_construct_end();
|
||||
}
|
||||
|
||||
OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
OSSL_SELF_TEST *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
ret->cb = cb;
|
||||
ret->cb_arg = cbarg;
|
||||
ret->phase = "";
|
||||
ret->type = "";
|
||||
ret->desc = "";
|
||||
self_test_setparams(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st)
|
||||
{
|
||||
OPENSSL_free(st);
|
||||
}
|
||||
|
||||
/* Can be used during application testing to log that a test has started. */
|
||||
void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
|
||||
const char *desc)
|
||||
{
|
||||
if (st != NULL && st->cb != NULL) {
|
||||
st->phase = OSSL_SELF_TEST_PHASE_START;
|
||||
st->type = type;
|
||||
st->desc = desc;
|
||||
self_test_setparams(st);
|
||||
(void)st->cb(st->params, st->cb_arg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Can be used during application testing to log that a test has either
|
||||
* passed or failed.
|
||||
*/
|
||||
void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret)
|
||||
{
|
||||
if (st != NULL && st->cb != NULL) {
|
||||
st->phase =
|
||||
(ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL);
|
||||
self_test_setparams(st);
|
||||
(void)st->cb(st->params, st->cb_arg);
|
||||
|
||||
st->phase = OSSL_SELF_TEST_PHASE_NONE;
|
||||
st->type = OSSL_SELF_TEST_TYPE_NONE;
|
||||
st->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 OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes)
|
||||
{
|
||||
if (st != NULL && st->cb != NULL) {
|
||||
st->phase = OSSL_SELF_TEST_PHASE_CORRUPT;
|
||||
self_test_setparams(st);
|
||||
if (!st->cb(st->params, st->cb_arg))
|
||||
bytes[0] ^= 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
OSSL_SELF_TEST_new,
|
||||
OSSL_SELF_TEST_free,
|
||||
OSSL_SELF_TEST_onbegin,
|
||||
OSSL_SELF_TEST_oncorrupt_byte,
|
||||
OSSL_SELF_TEST_onend - functionality to trigger a callback during a self test
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/self_test.h>
|
||||
|
||||
OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg);
|
||||
void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st);
|
||||
|
||||
void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
|
||||
const char *desc);
|
||||
void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes);
|
||||
void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
These methods are intended for use by provider implementors, to display
|
||||
diagnostic information during self testing.
|
||||
|
||||
OSSL_SELF_TEST_new() allocates an opaque B<OSSL_SELF_TEST> object that has a
|
||||
callback and callback argument associated with it.
|
||||
|
||||
The callback I<cb> may be triggered multiple times by a self test to indicate
|
||||
different phases.
|
||||
|
||||
OSSL_SELF_TEST_free() frees the space allocated by OSSL_SELF_TEST_new().
|
||||
|
||||
OSSL_SELF_TEST_onbegin() may be inserted at the start of a block of self test
|
||||
code. It can be used for diagnostic purposes.
|
||||
If this method is called the callback I<cb> will receive the following
|
||||
B<OSSL_PARAM> object.
|
||||
|
||||
=over 4
|
||||
|
||||
=item "st-phase" (B<OSSL_PROV_PARAM_SELF_TEST_PHASE>) <UTF8 string>
|
||||
|
||||
The value is the string "Start"
|
||||
|
||||
=back
|
||||
|
||||
OSSL_SELF_TEST_oncorrupt_byte() may be inserted just after the known answer is
|
||||
calculated, but before the self test compares the result. The first byte in the
|
||||
passed in array of I<bytes> will be corrupted if the callback returns 0,
|
||||
otherwise it leaves the array unaltered. It can be used for failure testing.
|
||||
The I<type> and I<desc> can be used to identify an individual self test to
|
||||
target for failure testing.
|
||||
If this method is called the callback I<cb> will receive the following
|
||||
B<OSSL_PARAM> object.
|
||||
|
||||
=over 4
|
||||
|
||||
=item "st-phase" (B<OSSL_PROV_PARAM_SELF_TEST_PHASE>) <UTF8 string>
|
||||
|
||||
The value is the string "Corrupt"
|
||||
|
||||
=back
|
||||
|
||||
OSSL_SELF_TEST_onend() may be inserted at the end of a block of self test code
|
||||
just before cleanup to indicate if the test passed or failed. It can be used for
|
||||
diagnostic purposes.
|
||||
If this method is called the callback I<cb> will receive the following
|
||||
B<OSSL_PARAM> object.
|
||||
|
||||
=over 4
|
||||
|
||||
=item "st-phase" (B<OSSL_PROV_PARAM_SELF_TEST_PHASE>) <UTF8 string>
|
||||
|
||||
The value of the string is "Pass" if I<ret> is non zero, otherwise it has the
|
||||
value "Fail".
|
||||
|
||||
=back
|
||||
|
||||
After the callback I<cb> has been called the values that were set by
|
||||
OSSL_SELF_TEST_onbegin() for I<type> and I<desc> are set to the value "None".
|
||||
|
||||
If OSSL_SELF_TEST_onbegin(), OSSL_SELF_TEST_oncorrupt_byte() or
|
||||
OSSL_SELF_TEST_onend() is called the following additional B<OSSL_PARAM> are
|
||||
passed to the callback.
|
||||
|
||||
=over 4
|
||||
|
||||
=item "st-type" (B<OSSL_PROV_PARAM_SELF_TEST_TYPE>) <UTF8 string>
|
||||
|
||||
The value is setup by the I<type> passed to OSSL_SELF_TEST_onbegin().
|
||||
This allows the callback to identify the type of test being run.
|
||||
|
||||
=item "st-desc" (B<OSSL_PROV_PARAM_SELF_TEST_DESC>) <UTF8 string>
|
||||
|
||||
The value is setup by the I<type> passed to OSSL_SELF_TEST_onbegin().
|
||||
This allows the callback to identify the sub category of the test being run.
|
||||
|
||||
=back
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_SELF_TEST_new() returns the allocated B<OSSL_SELF_TEST> object, or NULL if
|
||||
it fails.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
A single self test could be set up in the following way:
|
||||
|
||||
OSSL_SELF_TEST *st = NULL;
|
||||
OSSL_CALLBACK *cb;
|
||||
void *cbarg;
|
||||
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);
|
||||
|
||||
/*
|
||||
* Retrieve the callback - will be NULL if not set by the application via
|
||||
* OSSL_SELF_TEST_set_callback().
|
||||
*/
|
||||
OSSL_SELF_TEST_get_callback(libctx, &cb, &cbarg);
|
||||
|
||||
st = OSSL_SELF_TEST_new(cb, cb_arg);
|
||||
|
||||
/* Trigger the optional callback */
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_DIGEST,
|
||||
OSSL_SELF_TEST_DESC_MD_SHA2);
|
||||
|
||||
if (!EVP_DigestInit_ex(ctx, md, NULL)
|
||||
|| !EVP_DigestUpdate(ctx, pt, pt_len)
|
||||
|| !EVP_DigestFinal(ctx, out, &out_len))
|
||||
goto err;
|
||||
|
||||
/* Optional corruption - If the application callback returns 0 */
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, out);
|
||||
|
||||
if (out_len != t->expected_len
|
||||
|| memcmp(out, t->expected, out_len) != 0)
|
||||
goto err;
|
||||
ok = 1;
|
||||
err:
|
||||
OSSL_SELF_TEST_onend(st, ok);
|
||||
EVP_MD_free(md);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
Multiple self test's can be set up in a similar way by repeating the pattern of
|
||||
OSSL_SELF_TEST_onbegin(), OSSL_SELF_TEST_oncorrupt_byte(), OSSL_SELF_TEST_onend()
|
||||
for each test.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<OSSL_SELF_TEST_set_callback(3)>,
|
||||
L<openssl-core.h(7)>,
|
||||
L<OSSL_PROVIDER-FIPS(7)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The functions described here were added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License 2.0 (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
|
||||
L<https://www.openssl.org/source/license.html>.
|
||||
|
||||
=cut
|
|
@ -32,6 +32,7 @@ not been called.
|
|||
|
||||
L<openssl-core.h(7)>,
|
||||
L<OSSL_PROVIDER-FIPS(7)>
|
||||
L<OSSL_SELF_TEST_new(3)>
|
||||
L<OPENSSL_CTX(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
|
|
@ -17,59 +17,16 @@ One of the requirements for the FIPS module is self testing. An optional callbac
|
|||
mechanism is available to return information to the user using
|
||||
L<OSSL_SELF_TEST_set_callback(3)>.
|
||||
|
||||
The parameters passed to the callback are described in L<OSSL_SELF_TEST_new(3)>
|
||||
|
||||
The OPENSSL FIPS module uses the following mechanism to provide information
|
||||
about the self tests as they run.
|
||||
This is useful for debugging if a self test is failing.
|
||||
The callback also allows forcing any self test to fail, in order to check that
|
||||
it operates correctly on failure.
|
||||
|
||||
The 'args' parameter of B<OSSL_CALLBACK> contains the B<OPENSSL_CTX> associated
|
||||
with the provider that is triggering the self test. This may be useful if
|
||||
multiple fips providers are present.
|
||||
|
||||
The OSSL_PARAM names used are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item "st-phase" (B<OSSL_PROV_PARAM_SELF_TEST_PHASE>) <UTF8 string>
|
||||
|
||||
Each self test calls the callback 3 times with the following string values
|
||||
for the phase.
|
||||
|
||||
=over 4
|
||||
|
||||
=item "Start" (B<OSSL_SELF_TEST_PHASE_START>)
|
||||
|
||||
This is the initial phase before the self test has run.
|
||||
This is used for informational purposes only.
|
||||
The value returned by the callback is ignored.
|
||||
|
||||
=item "Corrupt" (B<OSSL_SELF_TEST_PHASE_CORRUPT>)
|
||||
|
||||
The corrupt phase is run after the self test has calculated its known value.
|
||||
The callback may be used to force the self test to fail by returning a value
|
||||
of 0 from the callback during this phase.
|
||||
Returning any other value from the callback causes the self test to run normally.
|
||||
|
||||
=item "Pass" (B<OSSL_SELF_TEST_PHASE_PASS>)
|
||||
|
||||
=item "Fail" (B<OSSL_SELF_TEST_PHASE_FAIL>)
|
||||
|
||||
The final phase runs after the self test is complete and indicates if a self
|
||||
test passed or failed. This is used for informational purposes only.
|
||||
The value returned by the callback is ignored.
|
||||
"Fail" should normally only be returned if any self test was forced to fail
|
||||
during the "Corrupt" phase (or if there was an error such as the integrity
|
||||
check of the module failed).
|
||||
|
||||
Note that all self tests run even if a self test failure occurs.
|
||||
|
||||
=back
|
||||
|
||||
=item "st-type" (B<OSSL_PROV_PARAM_SELF_TEST_TYPE>) <UTF8 string>
|
||||
|
||||
Used as a category to identify the type of self test being run.
|
||||
It includes the following string values:
|
||||
The FIPS module passes the following type(s) to OSSL_SELF_TEST_onbegin().
|
||||
|
||||
=over 4
|
||||
|
||||
|
@ -126,10 +83,8 @@ All other self test categories are run once at installation time, except for the
|
|||
There is only one instance of the "Module_Integrity" and "Install_Integrity"
|
||||
self tests. All other self tests may have multiple instances.
|
||||
|
||||
=item "st-desc" (B<OSSL_PROV_PARAM_SELF_TEST_DESC>) <UTF8 string>
|
||||
|
||||
Used as a sub category to identify an individual self test.
|
||||
The following description strings are used.
|
||||
The FIPS module passes the following descriptions(s) to OSSL_SELF_TEST_onbegin().
|
||||
|
||||
=over 4
|
||||
|
||||
|
@ -187,8 +142,6 @@ DRBG tests used with the "DRBG" type.
|
|||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
A simple self test callback is shown below for illustrative purposes.
|
||||
|
@ -241,6 +194,7 @@ A simple self test callback is shown below for illustrative purposes.
|
|||
L<openssl-fipsinstall(1)>,
|
||||
L<fips_config(5)>,
|
||||
L<OSSL_SELF_TEST_set_callback(3)>,
|
||||
L<OSSL_SELF_TEST_new(3)>,
|
||||
L<OSSL_PARAM(3)>,
|
||||
L<openssl-core.h(7)>
|
||||
|
||||
|
@ -250,7 +204,7 @@ The type and functions described here were added in OpenSSL 3.0.
|
|||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
|
|
|
@ -49,5 +49,6 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
|
|||
const unsigned char *sinfo, size_t sinfolen,
|
||||
const EVP_MD *md);
|
||||
|
||||
int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test);
|
||||
# endif /* OPENSSL_NO_EC */
|
||||
#endif
|
||||
|
|
|
@ -65,4 +65,12 @@ void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb,
|
|||
void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb,
|
||||
void **cbarg);
|
||||
|
||||
OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg);
|
||||
void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st);
|
||||
|
||||
void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
|
||||
const char *desc);
|
||||
void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes);
|
||||
void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret);
|
||||
|
||||
#endif /* OPENSSL_SELF_TEST_H */
|
||||
|
|
|
@ -209,6 +209,8 @@ typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata);
|
|||
typedef struct ossl_serializer_st OSSL_SERIALIZER;
|
||||
typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX;
|
||||
|
||||
typedef struct ossl_self_test_st OSSL_SELF_TEST;
|
||||
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
|
||||
defined(INTMAX_MAX) && defined(UINTMAX_MAX)
|
||||
typedef intmax_t ossl_intmax_t;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
SOURCE[../fips]=fipsprov.c self_test.c self_test_kats.c self_test_event.c
|
||||
SOURCE[../fips]=fipsprov.c self_test.c self_test_kats.c
|
||||
INCLUDE[../fips]=../implementations/include ../common/include ../..
|
||||
|
|
|
@ -966,12 +966,12 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
|||
}
|
||||
|
||||
if (stcbfn != NULL && c_get_libctx != NULL) {
|
||||
stcbfn(c_get_libctx(provider), &selftest_params.event_cb,
|
||||
&selftest_params.event_cb_arg);
|
||||
stcbfn(c_get_libctx(provider), &selftest_params.cb,
|
||||
&selftest_params.cb_arg);
|
||||
}
|
||||
else {
|
||||
selftest_params.event_cb = NULL;
|
||||
selftest_params.event_cb_arg = NULL;
|
||||
selftest_params.cb = NULL;
|
||||
selftest_params.cb_arg = NULL;
|
||||
}
|
||||
|
||||
if (!c_get_params(provider, core_params))
|
||||
|
|
|
@ -132,7 +132,7 @@ DEP_FINI_ATTRIBUTE void cleanup(void)
|
|||
*/
|
||||
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,
|
||||
OPENSSL_CTX *libctx, OSSL_SELF_TEST *ev,
|
||||
const char *event_type)
|
||||
{
|
||||
int ret = 0, status;
|
||||
|
@ -143,7 +143,7 @@ static int verify_integrity(BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb,
|
|||
EVP_MAC_CTX *ctx = NULL;
|
||||
OSSL_PARAM params[3], *p = params;
|
||||
|
||||
SELF_TEST_EVENT_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
|
||||
OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
|
||||
|
||||
mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
|
||||
ctx = EVP_MAC_CTX_new(mac);
|
||||
|
@ -170,13 +170,13 @@ static int verify_integrity(BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb,
|
|||
if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
|
||||
goto err;
|
||||
|
||||
SELF_TEST_EVENT_oncorrupt_byte(ev, out);
|
||||
OSSL_SELF_TEST_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);
|
||||
OSSL_SELF_TEST_onend(ev, ret);
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
EVP_MAC_free(mac);
|
||||
return ret;
|
||||
|
@ -192,7 +192,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
|
|||
unsigned char *module_checksum = NULL;
|
||||
unsigned char *indicator_checksum = NULL;
|
||||
int loclstate;
|
||||
OSSL_ST_EVENT ev;
|
||||
OSSL_SELF_TEST *ev = NULL;
|
||||
|
||||
if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
|
||||
return 0;
|
||||
|
@ -223,7 +223,9 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
|
|||
|| st->module_checksum_data == NULL)
|
||||
goto end;
|
||||
|
||||
SELF_TEST_EVENT_init(&ev, st->event_cb, st->event_cb_arg);
|
||||
ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg);
|
||||
if (ev == NULL)
|
||||
goto end;
|
||||
|
||||
module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
|
||||
&checksum_len);
|
||||
|
@ -235,7 +237,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
|
|||
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))
|
||||
ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY))
|
||||
goto end;
|
||||
|
||||
/* This will be NULL during installation - so the self test KATS will run */
|
||||
|
@ -257,7 +259,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
|
|||
if (bio_indicator == NULL
|
||||
|| !verify_integrity(bio_indicator, st->bio_read_ex_cb,
|
||||
indicator_checksum, checksum_len,
|
||||
st->libctx, &ev,
|
||||
st->libctx, ev,
|
||||
OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY))
|
||||
goto end;
|
||||
else
|
||||
|
@ -266,11 +268,12 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
|
|||
|
||||
/* 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))
|
||||
if (!SELF_TEST_kats(ev, st->libctx))
|
||||
goto end;
|
||||
}
|
||||
ok = 1;
|
||||
end:
|
||||
OSSL_SELF_TEST_free(ev);
|
||||
OPENSSL_free(module_checksum);
|
||||
OPENSSL_free(indicator_checksum);
|
||||
|
||||
|
|
|
@ -26,31 +26,11 @@ 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;
|
||||
OSSL_CALLBACK *cb;
|
||||
void *cb_arg;
|
||||
OPENSSL_CTX *libctx;
|
||||
|
||||
} SELF_TEST_POST_PARAMS;
|
||||
|
||||
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);
|
||||
int SELF_TEST_kats(OSSL_SELF_TEST *event, OPENSSL_CTX *libctx);
|
||||
|
|
|
@ -1,93 +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 <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;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
#define DRBG_PARAM_ENTROPY "DRBG-ENTROPY"
|
||||
#define DRBG_PARAM_NONCE "DRBG-NONCE"
|
||||
|
||||
static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_ST_EVENT *event,
|
||||
static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ok = 0;
|
||||
|
@ -29,7 +29,7 @@ static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_ST_EVENT *event,
|
|||
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);
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_DIGEST, t->desc);
|
||||
|
||||
if (ctx == NULL
|
||||
|| md == NULL
|
||||
|
@ -39,14 +39,14 @@ static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_ST_EVENT *event,
|
|||
goto err;
|
||||
|
||||
/* Optional corruption */
|
||||
SELF_TEST_EVENT_oncorrupt_byte(event, out);
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, 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);
|
||||
OSSL_SELF_TEST_onend(st, ok);
|
||||
EVP_MD_free(md);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
|
@ -86,7 +86,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
|||
}
|
||||
|
||||
/* Test a single KAT for encrypt/decrypt */
|
||||
static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
|
||||
static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_SELF_TEST *st,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 0, encrypt = 1, len, ct_len = 0, pt_len = 0;
|
||||
|
@ -95,7 +95,7 @@ static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
|
|||
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);
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_CIPHER, t->base.desc);
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL)
|
||||
|
@ -110,7 +110,7 @@ static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
|
|||
|| !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len))
|
||||
goto err;
|
||||
|
||||
SELF_TEST_EVENT_oncorrupt_byte(event, ct_buf);
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, ct_buf);
|
||||
ct_len += len;
|
||||
if (ct_len != (int)t->base.expected_len
|
||||
|| memcmp(t->base.expected, ct_buf, ct_len) != 0)
|
||||
|
@ -138,11 +138,11 @@ static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
|
|||
err:
|
||||
EVP_CIPHER_free(cipher);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
SELF_TEST_EVENT_onend(event, ret);
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int self_test_kdf(const ST_KAT_KDF *t, OSSL_ST_EVENT *event,
|
||||
static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -154,7 +154,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_ST_EVENT *event,
|
|||
const OSSL_PARAM *settables = NULL;
|
||||
|
||||
numparams = OSSL_NELEM(params);
|
||||
SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc);
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc);
|
||||
|
||||
/* Zeroize the params array to avoid mem leaks on error */
|
||||
for (i = 0; i < numparams; ++i)
|
||||
|
@ -183,7 +183,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_ST_EVENT *event,
|
|||
if (EVP_KDF_derive(ctx, out, t->expected_len) <= 0)
|
||||
goto err;
|
||||
|
||||
SELF_TEST_EVENT_oncorrupt_byte(event, out);
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, out);
|
||||
|
||||
if (memcmp(out, t->expected, t->expected_len) != 0)
|
||||
goto err;
|
||||
|
@ -194,7 +194,7 @@ err:
|
|||
OPENSSL_free(params[i].data);
|
||||
EVP_KDF_free(kdf);
|
||||
EVP_KDF_CTX_free(ctx);
|
||||
SELF_TEST_EVENT_onend(event, ret);
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ static size_t drbg_kat_nonce_cb(RAND_DRBG *drbg, unsigned char **pout,
|
|||
return p->data_size;
|
||||
}
|
||||
|
||||
static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_ST_EVENT *event,
|
||||
static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -236,7 +236,7 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_ST_EVENT *event,
|
|||
};
|
||||
static const unsigned char zero[sizeof(drbg->data)] = { 0 };
|
||||
|
||||
SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_DRBG, t->desc);
|
||||
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_DRBG, t->desc);
|
||||
|
||||
if (strcmp(t->desc, OSSL_SELF_TEST_DESC_DRBG_HMAC) == 0)
|
||||
flags |= RAND_DRBG_FLAG_HMAC;
|
||||
|
@ -280,7 +280,7 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_ST_EVENT *event,
|
|||
t->entropyaddin2, t->entropyaddin2len))
|
||||
goto err;
|
||||
|
||||
SELF_TEST_EVENT_oncorrupt_byte(event, out);
|
||||
OSSL_SELF_TEST_oncorrupt_byte(st, out);
|
||||
|
||||
if (memcmp(out, t->expected, t->expectedlen) != 0)
|
||||
goto err;
|
||||
|
@ -296,7 +296,7 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_ST_EVENT *event,
|
|||
ret = 1;
|
||||
err:
|
||||
RAND_DRBG_free(drbg);
|
||||
SELF_TEST_EVENT_onend(event, ret);
|
||||
OSSL_SELF_TEST_onend(st, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -305,45 +305,45 @@ err:
|
|||
* 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)
|
||||
static int self_test_digests(OSSL_SELF_TEST *st, 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))
|
||||
if (!self_test_digest(&st_kat_digest_tests[i], st, libctx))
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int self_test_ciphers(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
||||
static int self_test_ciphers(OSSL_SELF_TEST *st, 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))
|
||||
if (!self_test_cipher(&st_kat_cipher_tests[i], st, libctx))
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int self_test_kdfs(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
||||
static int self_test_kdfs(OSSL_SELF_TEST *st, 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))
|
||||
if (!self_test_kdf(&st_kat_kdf_tests[i], st, libctx))
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int self_test_drbgs(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
||||
static int self_test_drbgs(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx)
|
||||
{
|
||||
int i, ret = 1;
|
||||
|
||||
for (i = 0; i < (int)OSSL_NELEM(st_kat_drbg_tests); ++i) {
|
||||
if (!self_test_drbg(&st_kat_drbg_tests[i], event, libctx))
|
||||
if (!self_test_drbg(&st_kat_drbg_tests[i], st, libctx))
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
|
@ -356,17 +356,17 @@ static int self_test_drbgs(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
|||
*
|
||||
* TODO(3.0) Add self tests for KA, Sign/Verify when they become available
|
||||
*/
|
||||
int SELF_TEST_kats(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
|
||||
int SELF_TEST_kats(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (!self_test_digests(event, libctx))
|
||||
if (!self_test_digests(st, libctx))
|
||||
ret = 0;
|
||||
if (!self_test_ciphers(event, libctx))
|
||||
if (!self_test_ciphers(st, libctx))
|
||||
ret = 0;
|
||||
if (!self_test_kdfs(event, libctx))
|
||||
if (!self_test_kdfs(st, libctx))
|
||||
ret = 0;
|
||||
if (!self_test_drbgs(event, libctx))
|
||||
if (!self_test_drbgs(st, libctx))
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -4947,3 +4947,8 @@ EVP_PKEY_CTX_set0_ecdh_kdf_ukm ? 3_0_0 EXIST::FUNCTION:EC
|
|||
EVP_PKEY_CTX_get0_ecdh_kdf_ukm ? 3_0_0 EXIST::FUNCTION:EC
|
||||
EVP_PKEY_CTX_set_rsa_pss_saltlen ? 3_0_0 EXIST::FUNCTION:RSA
|
||||
EVP_PKEY_CTX_get_rsa_pss_saltlen ? 3_0_0 EXIST::FUNCTION:RSA
|
||||
OSSL_SELF_TEST_new ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_SELF_TEST_free ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_SELF_TEST_onbegin ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_SELF_TEST_oncorrupt_byte ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_SELF_TEST_onend ? 3_0_0 EXIST::FUNCTION:
|
||||
|
|
Loading…
Reference in New Issue