From 47c239c6b8d6e5d66a6ceef3a2c543b6ea338759 Mon Sep 17 00:00:00 2001 From: Shane Lontis Date: Tue, 3 Mar 2020 14:02:36 +1000 Subject: Add pairwise consistency self tests to asym keygenerators Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/10952) --- crypto/self_test_core.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) (limited to 'crypto/self_test_core.c') diff --git a/crypto/self_test_core.c b/crypto/self_test_core.c index 77864a230b..bee3161ed5 100644 --- a/crypto/self_test_core.c +++ b/crypto/self_test_core.c @@ -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 +#include +#include #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; + } +} -- cgit v1.2.3