1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <openssl/self_test.h> 11e1051a39Sopenharmony_ci#include <openssl/core_names.h> 12e1051a39Sopenharmony_ci#include <openssl/params.h> 13e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 14e1051a39Sopenharmony_ci 15e1051a39Sopenharmony_citypedef struct self_test_cb_st 16e1051a39Sopenharmony_ci{ 17e1051a39Sopenharmony_ci OSSL_CALLBACK *cb; 18e1051a39Sopenharmony_ci void *cbarg; 19e1051a39Sopenharmony_ci} SELF_TEST_CB; 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_cistruct ossl_self_test_st 22e1051a39Sopenharmony_ci{ 23e1051a39Sopenharmony_ci /* local state variables */ 24e1051a39Sopenharmony_ci const char *phase; 25e1051a39Sopenharmony_ci const char *type; 26e1051a39Sopenharmony_ci const char *desc; 27e1051a39Sopenharmony_ci OSSL_CALLBACK *cb; 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ci /* callback related variables used to pass the state back to the user */ 30e1051a39Sopenharmony_ci OSSL_PARAM params[4]; 31e1051a39Sopenharmony_ci void *cb_arg; 32e1051a39Sopenharmony_ci}; 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 35e1051a39Sopenharmony_cistatic void *self_test_set_callback_new(OSSL_LIB_CTX *ctx) 36e1051a39Sopenharmony_ci{ 37e1051a39Sopenharmony_ci SELF_TEST_CB *stcb; 38e1051a39Sopenharmony_ci 39e1051a39Sopenharmony_ci stcb = OPENSSL_zalloc(sizeof(*stcb)); 40e1051a39Sopenharmony_ci return stcb; 41e1051a39Sopenharmony_ci} 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_cistatic void self_test_set_callback_free(void *stcb) 44e1051a39Sopenharmony_ci{ 45e1051a39Sopenharmony_ci OPENSSL_free(stcb); 46e1051a39Sopenharmony_ci} 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_cistatic const OSSL_LIB_CTX_METHOD self_test_set_callback_method = { 49e1051a39Sopenharmony_ci OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, 50e1051a39Sopenharmony_ci self_test_set_callback_new, 51e1051a39Sopenharmony_ci self_test_set_callback_free, 52e1051a39Sopenharmony_ci}; 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_cistatic SELF_TEST_CB *get_self_test_callback(OSSL_LIB_CTX *libctx) 55e1051a39Sopenharmony_ci{ 56e1051a39Sopenharmony_ci return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_SELF_TEST_CB_INDEX, 57e1051a39Sopenharmony_ci &self_test_set_callback_method); 58e1051a39Sopenharmony_ci} 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_civoid OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb, 61e1051a39Sopenharmony_ci void *cbarg) 62e1051a39Sopenharmony_ci{ 63e1051a39Sopenharmony_ci SELF_TEST_CB *stcb = get_self_test_callback(libctx); 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci if (stcb != NULL) { 66e1051a39Sopenharmony_ci stcb->cb = cb; 67e1051a39Sopenharmony_ci stcb->cbarg = cbarg; 68e1051a39Sopenharmony_ci } 69e1051a39Sopenharmony_ci} 70e1051a39Sopenharmony_ci 71e1051a39Sopenharmony_civoid OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, 72e1051a39Sopenharmony_ci void **cbarg) 73e1051a39Sopenharmony_ci{ 74e1051a39Sopenharmony_ci SELF_TEST_CB *stcb = get_self_test_callback(libctx); 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci if (cb != NULL) 77e1051a39Sopenharmony_ci *cb = (stcb != NULL ? stcb->cb : NULL); 78e1051a39Sopenharmony_ci if (cbarg != NULL) 79e1051a39Sopenharmony_ci *cbarg = (stcb != NULL ? stcb->cbarg : NULL); 80e1051a39Sopenharmony_ci} 81e1051a39Sopenharmony_ci#endif /* FIPS_MODULE */ 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_cistatic void self_test_setparams(OSSL_SELF_TEST *st) 84e1051a39Sopenharmony_ci{ 85e1051a39Sopenharmony_ci size_t n = 0; 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_ci if (st->cb != NULL) { 88e1051a39Sopenharmony_ci st->params[n++] = 89e1051a39Sopenharmony_ci OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE, 90e1051a39Sopenharmony_ci (char *)st->phase, 0); 91e1051a39Sopenharmony_ci st->params[n++] = 92e1051a39Sopenharmony_ci OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE, 93e1051a39Sopenharmony_ci (char *)st->type, 0); 94e1051a39Sopenharmony_ci st->params[n++] = 95e1051a39Sopenharmony_ci OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC, 96e1051a39Sopenharmony_ci (char *)st->desc, 0); 97e1051a39Sopenharmony_ci } 98e1051a39Sopenharmony_ci st->params[n++] = OSSL_PARAM_construct_end(); 99e1051a39Sopenharmony_ci} 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ciOSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg) 102e1051a39Sopenharmony_ci{ 103e1051a39Sopenharmony_ci OSSL_SELF_TEST *ret = OPENSSL_zalloc(sizeof(*ret)); 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci if (ret == NULL) 106e1051a39Sopenharmony_ci return NULL; 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ci ret->cb = cb; 109e1051a39Sopenharmony_ci ret->cb_arg = cbarg; 110e1051a39Sopenharmony_ci ret->phase = ""; 111e1051a39Sopenharmony_ci ret->type = ""; 112e1051a39Sopenharmony_ci ret->desc = ""; 113e1051a39Sopenharmony_ci self_test_setparams(ret); 114e1051a39Sopenharmony_ci return ret; 115e1051a39Sopenharmony_ci} 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_civoid OSSL_SELF_TEST_free(OSSL_SELF_TEST *st) 118e1051a39Sopenharmony_ci{ 119e1051a39Sopenharmony_ci OPENSSL_free(st); 120e1051a39Sopenharmony_ci} 121e1051a39Sopenharmony_ci 122e1051a39Sopenharmony_ci/* Can be used during application testing to log that a test has started. */ 123e1051a39Sopenharmony_civoid OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type, 124e1051a39Sopenharmony_ci const char *desc) 125e1051a39Sopenharmony_ci{ 126e1051a39Sopenharmony_ci if (st != NULL && st->cb != NULL) { 127e1051a39Sopenharmony_ci st->phase = OSSL_SELF_TEST_PHASE_START; 128e1051a39Sopenharmony_ci st->type = type; 129e1051a39Sopenharmony_ci st->desc = desc; 130e1051a39Sopenharmony_ci self_test_setparams(st); 131e1051a39Sopenharmony_ci (void)st->cb(st->params, st->cb_arg); 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci} 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ci/* 136e1051a39Sopenharmony_ci * Can be used during application testing to log that a test has either 137e1051a39Sopenharmony_ci * passed or failed. 138e1051a39Sopenharmony_ci */ 139e1051a39Sopenharmony_civoid OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret) 140e1051a39Sopenharmony_ci{ 141e1051a39Sopenharmony_ci if (st != NULL && st->cb != NULL) { 142e1051a39Sopenharmony_ci st->phase = 143e1051a39Sopenharmony_ci (ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL); 144e1051a39Sopenharmony_ci self_test_setparams(st); 145e1051a39Sopenharmony_ci (void)st->cb(st->params, st->cb_arg); 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci st->phase = OSSL_SELF_TEST_PHASE_NONE; 148e1051a39Sopenharmony_ci st->type = OSSL_SELF_TEST_TYPE_NONE; 149e1051a39Sopenharmony_ci st->desc = OSSL_SELF_TEST_DESC_NONE; 150e1051a39Sopenharmony_ci } 151e1051a39Sopenharmony_ci} 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci/* 154e1051a39Sopenharmony_ci * Used for failure testing. 155e1051a39Sopenharmony_ci * 156e1051a39Sopenharmony_ci * Call the applications SELF_TEST_cb() if it exists. 157e1051a39Sopenharmony_ci * If the application callback decides to return 0 then the first byte of 'bytes' 158e1051a39Sopenharmony_ci * is modified (corrupted). This is used to modify output signatures or 159e1051a39Sopenharmony_ci * ciphertext before they are verified or decrypted. 160e1051a39Sopenharmony_ci */ 161e1051a39Sopenharmony_ciint OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes) 162e1051a39Sopenharmony_ci{ 163e1051a39Sopenharmony_ci if (st != NULL && st->cb != NULL) { 164e1051a39Sopenharmony_ci st->phase = OSSL_SELF_TEST_PHASE_CORRUPT; 165e1051a39Sopenharmony_ci self_test_setparams(st); 166e1051a39Sopenharmony_ci if (!st->cb(st->params, st->cb_arg)) { 167e1051a39Sopenharmony_ci bytes[0] ^= 1; 168e1051a39Sopenharmony_ci return 1; 169e1051a39Sopenharmony_ci } 170e1051a39Sopenharmony_ci } 171e1051a39Sopenharmony_ci return 0; 172e1051a39Sopenharmony_ci} 173