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