1*e0c4386eSCy Schubert /* 2*e0c4386eSCy Schubert * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. 3*e0c4386eSCy Schubert * 4*e0c4386eSCy Schubert * Licensed under the Apache License 2.0 (the "License"); 5*e0c4386eSCy Schubert * you may not use this file except in compliance with the License. 6*e0c4386eSCy Schubert * You may obtain a copy of the License at 7*e0c4386eSCy Schubert * https://www.openssl.org/source/license.html 8*e0c4386eSCy Schubert * or in the file LICENSE in the source distribution. 9*e0c4386eSCy Schubert */ 10*e0c4386eSCy Schubert 11*e0c4386eSCy Schubert #include <string.h> 12*e0c4386eSCy Schubert #include <openssl/core_names.h> 13*e0c4386eSCy Schubert #include <openssl/rand.h> 14*e0c4386eSCy Schubert #include <openssl/provider.h> 15*e0c4386eSCy Schubert #include "../include/crypto/evp.h" 16*e0c4386eSCy Schubert #include "../../crypto/evp/evp_local.h" 17*e0c4386eSCy Schubert #include "../testutil.h" 18*e0c4386eSCy Schubert 19*e0c4386eSCy Schubert typedef struct { 20*e0c4386eSCy Schubert fake_random_generate_cb *cb; 21*e0c4386eSCy Schubert int state; 22*e0c4386eSCy Schubert const char *name; 23*e0c4386eSCy Schubert EVP_RAND_CTX *ctx; 24*e0c4386eSCy Schubert } FAKE_RAND; 25*e0c4386eSCy Schubert 26*e0c4386eSCy Schubert static OSSL_FUNC_rand_newctx_fn fake_rand_newctx; 27*e0c4386eSCy Schubert static OSSL_FUNC_rand_freectx_fn fake_rand_freectx; 28*e0c4386eSCy Schubert static OSSL_FUNC_rand_instantiate_fn fake_rand_instantiate; 29*e0c4386eSCy Schubert static OSSL_FUNC_rand_uninstantiate_fn fake_rand_uninstantiate; 30*e0c4386eSCy Schubert static OSSL_FUNC_rand_generate_fn fake_rand_generate; 31*e0c4386eSCy Schubert static OSSL_FUNC_rand_gettable_ctx_params_fn fake_rand_gettable_ctx_params; 32*e0c4386eSCy Schubert static OSSL_FUNC_rand_get_ctx_params_fn fake_rand_get_ctx_params; 33*e0c4386eSCy Schubert static OSSL_FUNC_rand_enable_locking_fn fake_rand_enable_locking; 34*e0c4386eSCy Schubert 35*e0c4386eSCy Schubert static void *fake_rand_newctx(void *provctx, void *parent, 36*e0c4386eSCy Schubert const OSSL_DISPATCH *parent_dispatch) 37*e0c4386eSCy Schubert { 38*e0c4386eSCy Schubert FAKE_RAND *r = OPENSSL_zalloc(sizeof(*r)); 39*e0c4386eSCy Schubert 40*e0c4386eSCy Schubert if (r != NULL) 41*e0c4386eSCy Schubert r->state = EVP_RAND_STATE_UNINITIALISED; 42*e0c4386eSCy Schubert return r; 43*e0c4386eSCy Schubert } 44*e0c4386eSCy Schubert 45*e0c4386eSCy Schubert static void fake_rand_freectx(void *vrng) 46*e0c4386eSCy Schubert { 47*e0c4386eSCy Schubert OPENSSL_free(vrng); 48*e0c4386eSCy Schubert } 49*e0c4386eSCy Schubert 50*e0c4386eSCy Schubert static int fake_rand_instantiate(void *vrng, ossl_unused unsigned int strength, 51*e0c4386eSCy Schubert ossl_unused int prediction_resistance, 52*e0c4386eSCy Schubert ossl_unused const unsigned char *pstr, 53*e0c4386eSCy Schubert size_t pstr_len, 54*e0c4386eSCy Schubert ossl_unused const OSSL_PARAM params[]) 55*e0c4386eSCy Schubert { 56*e0c4386eSCy Schubert FAKE_RAND *frng = (FAKE_RAND *)vrng; 57*e0c4386eSCy Schubert 58*e0c4386eSCy Schubert frng->state = EVP_RAND_STATE_READY; 59*e0c4386eSCy Schubert return 1; 60*e0c4386eSCy Schubert } 61*e0c4386eSCy Schubert 62*e0c4386eSCy Schubert static int fake_rand_uninstantiate(void *vrng) 63*e0c4386eSCy Schubert { 64*e0c4386eSCy Schubert FAKE_RAND *frng = (FAKE_RAND *)vrng; 65*e0c4386eSCy Schubert 66*e0c4386eSCy Schubert frng->state = EVP_RAND_STATE_UNINITIALISED; 67*e0c4386eSCy Schubert return 1; 68*e0c4386eSCy Schubert } 69*e0c4386eSCy Schubert 70*e0c4386eSCy Schubert static int fake_rand_generate(void *vrng, unsigned char *out, size_t outlen, 71*e0c4386eSCy Schubert unsigned int strength, int prediction_resistance, 72*e0c4386eSCy Schubert const unsigned char *adin, size_t adinlen) 73*e0c4386eSCy Schubert { 74*e0c4386eSCy Schubert FAKE_RAND *frng = (FAKE_RAND *)vrng; 75*e0c4386eSCy Schubert size_t l; 76*e0c4386eSCy Schubert uint32_t r; 77*e0c4386eSCy Schubert 78*e0c4386eSCy Schubert if (frng->cb != NULL) 79*e0c4386eSCy Schubert return (*frng->cb)(out, outlen, frng->name, frng->ctx); 80*e0c4386eSCy Schubert while (outlen > 0) { 81*e0c4386eSCy Schubert r = test_random(); 82*e0c4386eSCy Schubert l = outlen < sizeof(r) ? outlen : sizeof(r); 83*e0c4386eSCy Schubert 84*e0c4386eSCy Schubert memcpy(out, &r, l); 85*e0c4386eSCy Schubert out += l; 86*e0c4386eSCy Schubert outlen -= l; 87*e0c4386eSCy Schubert } 88*e0c4386eSCy Schubert return 1; 89*e0c4386eSCy Schubert } 90*e0c4386eSCy Schubert 91*e0c4386eSCy Schubert static int fake_rand_enable_locking(void *vrng) 92*e0c4386eSCy Schubert { 93*e0c4386eSCy Schubert return 1; 94*e0c4386eSCy Schubert } 95*e0c4386eSCy Schubert 96*e0c4386eSCy Schubert static int fake_rand_get_ctx_params(ossl_unused void *vrng, OSSL_PARAM params[]) 97*e0c4386eSCy Schubert { 98*e0c4386eSCy Schubert FAKE_RAND *frng = (FAKE_RAND *)vrng; 99*e0c4386eSCy Schubert OSSL_PARAM *p; 100*e0c4386eSCy Schubert 101*e0c4386eSCy Schubert p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE); 102*e0c4386eSCy Schubert if (p != NULL && !OSSL_PARAM_set_int(p, frng->state)) 103*e0c4386eSCy Schubert return 0; 104*e0c4386eSCy Schubert 105*e0c4386eSCy Schubert p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH); 106*e0c4386eSCy Schubert if (p != NULL && !OSSL_PARAM_set_int(p, 256)) 107*e0c4386eSCy Schubert return 0; 108*e0c4386eSCy Schubert 109*e0c4386eSCy Schubert p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); 110*e0c4386eSCy Schubert if (p != NULL && !OSSL_PARAM_set_size_t(p, INT_MAX)) 111*e0c4386eSCy Schubert return 0; 112*e0c4386eSCy Schubert return 1; 113*e0c4386eSCy Schubert } 114*e0c4386eSCy Schubert 115*e0c4386eSCy Schubert static const OSSL_PARAM *fake_rand_gettable_ctx_params(ossl_unused void *vrng, 116*e0c4386eSCy Schubert ossl_unused void *provctx) 117*e0c4386eSCy Schubert { 118*e0c4386eSCy Schubert static const OSSL_PARAM known_gettable_ctx_params[] = { 119*e0c4386eSCy Schubert OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL), 120*e0c4386eSCy Schubert OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL), 121*e0c4386eSCy Schubert OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL), 122*e0c4386eSCy Schubert OSSL_PARAM_END 123*e0c4386eSCy Schubert }; 124*e0c4386eSCy Schubert return known_gettable_ctx_params; 125*e0c4386eSCy Schubert } 126*e0c4386eSCy Schubert 127*e0c4386eSCy Schubert static const OSSL_DISPATCH fake_rand_functions[] = { 128*e0c4386eSCy Schubert { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))fake_rand_newctx }, 129*e0c4386eSCy Schubert { OSSL_FUNC_RAND_FREECTX, (void (*)(void))fake_rand_freectx }, 130*e0c4386eSCy Schubert { OSSL_FUNC_RAND_INSTANTIATE, (void (*)(void))fake_rand_instantiate }, 131*e0c4386eSCy Schubert { OSSL_FUNC_RAND_UNINSTANTIATE, (void (*)(void))fake_rand_uninstantiate }, 132*e0c4386eSCy Schubert { OSSL_FUNC_RAND_GENERATE, (void (*)(void))fake_rand_generate }, 133*e0c4386eSCy Schubert { OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))fake_rand_enable_locking }, 134*e0c4386eSCy Schubert { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS, 135*e0c4386eSCy Schubert (void(*)(void))fake_rand_gettable_ctx_params }, 136*e0c4386eSCy Schubert { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))fake_rand_get_ctx_params }, 137*e0c4386eSCy Schubert { 0, NULL } 138*e0c4386eSCy Schubert }; 139*e0c4386eSCy Schubert 140*e0c4386eSCy Schubert static const OSSL_ALGORITHM fake_rand_rand[] = { 141*e0c4386eSCy Schubert { "FAKE", "provider=fake", fake_rand_functions }, 142*e0c4386eSCy Schubert { NULL, NULL, NULL } 143*e0c4386eSCy Schubert }; 144*e0c4386eSCy Schubert 145*e0c4386eSCy Schubert static const OSSL_ALGORITHM *fake_rand_query(void *provctx, 146*e0c4386eSCy Schubert int operation_id, 147*e0c4386eSCy Schubert int *no_cache) 148*e0c4386eSCy Schubert { 149*e0c4386eSCy Schubert *no_cache = 0; 150*e0c4386eSCy Schubert switch (operation_id) { 151*e0c4386eSCy Schubert case OSSL_OP_RAND: 152*e0c4386eSCy Schubert return fake_rand_rand; 153*e0c4386eSCy Schubert } 154*e0c4386eSCy Schubert return NULL; 155*e0c4386eSCy Schubert } 156*e0c4386eSCy Schubert 157*e0c4386eSCy Schubert /* Functions we provide to the core */ 158*e0c4386eSCy Schubert static const OSSL_DISPATCH fake_rand_method[] = { 159*e0c4386eSCy Schubert { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free }, 160*e0c4386eSCy Schubert { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fake_rand_query }, 161*e0c4386eSCy Schubert { 0, NULL } 162*e0c4386eSCy Schubert }; 163*e0c4386eSCy Schubert 164*e0c4386eSCy Schubert static int fake_rand_provider_init(const OSSL_CORE_HANDLE *handle, 165*e0c4386eSCy Schubert const OSSL_DISPATCH *in, 166*e0c4386eSCy Schubert const OSSL_DISPATCH **out, void **provctx) 167*e0c4386eSCy Schubert { 168*e0c4386eSCy Schubert if (!TEST_ptr(*provctx = OSSL_LIB_CTX_new())) 169*e0c4386eSCy Schubert return 0; 170*e0c4386eSCy Schubert *out = fake_rand_method; 171*e0c4386eSCy Schubert return 1; 172*e0c4386eSCy Schubert } 173*e0c4386eSCy Schubert 174*e0c4386eSCy Schubert static int check_rng(EVP_RAND_CTX *rng, const char *name) 175*e0c4386eSCy Schubert { 176*e0c4386eSCy Schubert FAKE_RAND *f; 177*e0c4386eSCy Schubert 178*e0c4386eSCy Schubert if (!TEST_ptr(rng)) { 179*e0c4386eSCy Schubert TEST_info("random: %s", name); 180*e0c4386eSCy Schubert return 0; 181*e0c4386eSCy Schubert } 182*e0c4386eSCy Schubert f = rng->algctx; 183*e0c4386eSCy Schubert f->name = name; 184*e0c4386eSCy Schubert f->ctx = rng; 185*e0c4386eSCy Schubert return 1; 186*e0c4386eSCy Schubert } 187*e0c4386eSCy Schubert 188*e0c4386eSCy Schubert OSSL_PROVIDER *fake_rand_start(OSSL_LIB_CTX *libctx) 189*e0c4386eSCy Schubert { 190*e0c4386eSCy Schubert OSSL_PROVIDER *p; 191*e0c4386eSCy Schubert 192*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, "fake-rand", 193*e0c4386eSCy Schubert fake_rand_provider_init)) 194*e0c4386eSCy Schubert || !TEST_true(RAND_set_DRBG_type(libctx, "fake", NULL, NULL, NULL)) 195*e0c4386eSCy Schubert || !TEST_ptr(p = OSSL_PROVIDER_try_load(libctx, "fake-rand", 1))) 196*e0c4386eSCy Schubert return NULL; 197*e0c4386eSCy Schubert 198*e0c4386eSCy Schubert /* Ensure that the fake rand is initialized. */ 199*e0c4386eSCy Schubert if (!TEST_true(check_rng(RAND_get0_primary(libctx), "primary")) 200*e0c4386eSCy Schubert || !TEST_true(check_rng(RAND_get0_private(libctx), "private")) 201*e0c4386eSCy Schubert || !TEST_true(check_rng(RAND_get0_public(libctx), "public"))) { 202*e0c4386eSCy Schubert OSSL_PROVIDER_unload(p); 203*e0c4386eSCy Schubert return NULL; 204*e0c4386eSCy Schubert } 205*e0c4386eSCy Schubert 206*e0c4386eSCy Schubert return p; 207*e0c4386eSCy Schubert } 208*e0c4386eSCy Schubert 209*e0c4386eSCy Schubert void fake_rand_finish(OSSL_PROVIDER *p) 210*e0c4386eSCy Schubert { 211*e0c4386eSCy Schubert OSSL_PROVIDER_unload(p); 212*e0c4386eSCy Schubert } 213*e0c4386eSCy Schubert 214*e0c4386eSCy Schubert void fake_rand_set_callback(EVP_RAND_CTX *rng, 215*e0c4386eSCy Schubert int (*cb)(unsigned char *out, size_t outlen, 216*e0c4386eSCy Schubert const char *name, EVP_RAND_CTX *ctx)) 217*e0c4386eSCy Schubert { 218*e0c4386eSCy Schubert if (rng != NULL) 219*e0c4386eSCy Schubert ((FAKE_RAND *)rng->algctx)->cb = cb; 220*e0c4386eSCy Schubert } 221*e0c4386eSCy Schubert 222*e0c4386eSCy Schubert void fake_rand_set_public_private_callbacks(OSSL_LIB_CTX *libctx, 223*e0c4386eSCy Schubert int (*cb)(unsigned char *out, 224*e0c4386eSCy Schubert size_t outlen, 225*e0c4386eSCy Schubert const char *name, 226*e0c4386eSCy Schubert EVP_RAND_CTX *ctx)) 227*e0c4386eSCy Schubert { 228*e0c4386eSCy Schubert fake_rand_set_callback(RAND_get0_private(libctx), cb); 229*e0c4386eSCy Schubert fake_rand_set_callback(RAND_get0_public(libctx), cb); 230*e0c4386eSCy Schubert } 231*e0c4386eSCy Schubert 232