1*e0c4386eSCy Schubert /*
2*e0c4386eSCy Schubert * Copyright 2016-2022 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 <openssl/core_names.h>
12*e0c4386eSCy Schubert #include <openssl/rand.h>
13*e0c4386eSCy Schubert #include <openssl/provider.h>
14*e0c4386eSCy Schubert #include "fuzzer.h"
15*e0c4386eSCy Schubert
16*e0c4386eSCy Schubert static OSSL_FUNC_rand_newctx_fn fuzz_rand_newctx;
17*e0c4386eSCy Schubert static OSSL_FUNC_rand_freectx_fn fuzz_rand_freectx;
18*e0c4386eSCy Schubert static OSSL_FUNC_rand_instantiate_fn fuzz_rand_instantiate;
19*e0c4386eSCy Schubert static OSSL_FUNC_rand_uninstantiate_fn fuzz_rand_uninstantiate;
20*e0c4386eSCy Schubert static OSSL_FUNC_rand_generate_fn fuzz_rand_generate;
21*e0c4386eSCy Schubert static OSSL_FUNC_rand_gettable_ctx_params_fn fuzz_rand_gettable_ctx_params;
22*e0c4386eSCy Schubert static OSSL_FUNC_rand_get_ctx_params_fn fuzz_rand_get_ctx_params;
23*e0c4386eSCy Schubert static OSSL_FUNC_rand_enable_locking_fn fuzz_rand_enable_locking;
24*e0c4386eSCy Schubert
fuzz_rand_newctx(void * provctx,void * parent,const OSSL_DISPATCH * parent_dispatch)25*e0c4386eSCy Schubert static void *fuzz_rand_newctx(
26*e0c4386eSCy Schubert void *provctx, void *parent, const OSSL_DISPATCH *parent_dispatch)
27*e0c4386eSCy Schubert {
28*e0c4386eSCy Schubert int *st = OPENSSL_malloc(sizeof(*st));
29*e0c4386eSCy Schubert
30*e0c4386eSCy Schubert if (st != NULL)
31*e0c4386eSCy Schubert *st = EVP_RAND_STATE_UNINITIALISED;
32*e0c4386eSCy Schubert return st;
33*e0c4386eSCy Schubert }
34*e0c4386eSCy Schubert
fuzz_rand_freectx(ossl_unused void * vrng)35*e0c4386eSCy Schubert static void fuzz_rand_freectx(ossl_unused void *vrng)
36*e0c4386eSCy Schubert {
37*e0c4386eSCy Schubert OPENSSL_free(vrng);
38*e0c4386eSCy Schubert }
39*e0c4386eSCy Schubert
fuzz_rand_instantiate(ossl_unused void * vrng,ossl_unused unsigned int strength,ossl_unused int prediction_resistance,ossl_unused const unsigned char * pstr,ossl_unused size_t pstr_len,ossl_unused const OSSL_PARAM params[])40*e0c4386eSCy Schubert static int fuzz_rand_instantiate(ossl_unused void *vrng,
41*e0c4386eSCy Schubert ossl_unused unsigned int strength,
42*e0c4386eSCy Schubert ossl_unused int prediction_resistance,
43*e0c4386eSCy Schubert ossl_unused const unsigned char *pstr,
44*e0c4386eSCy Schubert ossl_unused size_t pstr_len,
45*e0c4386eSCy Schubert ossl_unused const OSSL_PARAM params[])
46*e0c4386eSCy Schubert {
47*e0c4386eSCy Schubert *(int *)vrng = EVP_RAND_STATE_READY;
48*e0c4386eSCy Schubert return 1;
49*e0c4386eSCy Schubert }
50*e0c4386eSCy Schubert
fuzz_rand_uninstantiate(ossl_unused void * vrng)51*e0c4386eSCy Schubert static int fuzz_rand_uninstantiate(ossl_unused void *vrng)
52*e0c4386eSCy Schubert {
53*e0c4386eSCy Schubert *(int *)vrng = EVP_RAND_STATE_UNINITIALISED;
54*e0c4386eSCy Schubert return 1;
55*e0c4386eSCy Schubert }
56*e0c4386eSCy Schubert
fuzz_rand_generate(ossl_unused void * vdrbg,unsigned char * out,size_t outlen,ossl_unused unsigned int strength,ossl_unused int prediction_resistance,ossl_unused const unsigned char * adin,ossl_unused size_t adinlen)57*e0c4386eSCy Schubert static int fuzz_rand_generate(ossl_unused void *vdrbg,
58*e0c4386eSCy Schubert unsigned char *out, size_t outlen,
59*e0c4386eSCy Schubert ossl_unused unsigned int strength,
60*e0c4386eSCy Schubert ossl_unused int prediction_resistance,
61*e0c4386eSCy Schubert ossl_unused const unsigned char *adin,
62*e0c4386eSCy Schubert ossl_unused size_t adinlen)
63*e0c4386eSCy Schubert {
64*e0c4386eSCy Schubert unsigned char val = 1;
65*e0c4386eSCy Schubert size_t i;
66*e0c4386eSCy Schubert
67*e0c4386eSCy Schubert for (i = 0; i < outlen; i++)
68*e0c4386eSCy Schubert out[i] = val++;
69*e0c4386eSCy Schubert return 1;
70*e0c4386eSCy Schubert }
71*e0c4386eSCy Schubert
fuzz_rand_enable_locking(ossl_unused void * vrng)72*e0c4386eSCy Schubert static int fuzz_rand_enable_locking(ossl_unused void *vrng)
73*e0c4386eSCy Schubert {
74*e0c4386eSCy Schubert return 1;
75*e0c4386eSCy Schubert }
76*e0c4386eSCy Schubert
fuzz_rand_get_ctx_params(void * vrng,OSSL_PARAM params[])77*e0c4386eSCy Schubert static int fuzz_rand_get_ctx_params(void *vrng, OSSL_PARAM params[])
78*e0c4386eSCy Schubert {
79*e0c4386eSCy Schubert OSSL_PARAM *p;
80*e0c4386eSCy Schubert
81*e0c4386eSCy Schubert p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE);
82*e0c4386eSCy Schubert if (p != NULL && !OSSL_PARAM_set_int(p, *(int *)vrng))
83*e0c4386eSCy Schubert return 0;
84*e0c4386eSCy Schubert
85*e0c4386eSCy Schubert p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH);
86*e0c4386eSCy Schubert if (p != NULL && !OSSL_PARAM_set_int(p, 500))
87*e0c4386eSCy Schubert return 0;
88*e0c4386eSCy Schubert
89*e0c4386eSCy Schubert p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
90*e0c4386eSCy Schubert if (p != NULL && !OSSL_PARAM_set_size_t(p, INT_MAX))
91*e0c4386eSCy Schubert return 0;
92*e0c4386eSCy Schubert return 1;
93*e0c4386eSCy Schubert }
94*e0c4386eSCy Schubert
fuzz_rand_gettable_ctx_params(ossl_unused void * vrng,ossl_unused void * provctx)95*e0c4386eSCy Schubert static const OSSL_PARAM *fuzz_rand_gettable_ctx_params(ossl_unused void *vrng,
96*e0c4386eSCy Schubert ossl_unused void *provctx)
97*e0c4386eSCy Schubert {
98*e0c4386eSCy Schubert static const OSSL_PARAM known_gettable_ctx_params[] = {
99*e0c4386eSCy Schubert OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),
100*e0c4386eSCy Schubert OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
101*e0c4386eSCy Schubert OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
102*e0c4386eSCy Schubert OSSL_PARAM_END
103*e0c4386eSCy Schubert };
104*e0c4386eSCy Schubert return known_gettable_ctx_params;
105*e0c4386eSCy Schubert }
106*e0c4386eSCy Schubert
107*e0c4386eSCy Schubert static const OSSL_DISPATCH fuzz_rand_functions[] = {
108*e0c4386eSCy Schubert { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))fuzz_rand_newctx },
109*e0c4386eSCy Schubert { OSSL_FUNC_RAND_FREECTX, (void (*)(void))fuzz_rand_freectx },
110*e0c4386eSCy Schubert { OSSL_FUNC_RAND_INSTANTIATE, (void (*)(void))fuzz_rand_instantiate },
111*e0c4386eSCy Schubert { OSSL_FUNC_RAND_UNINSTANTIATE, (void (*)(void))fuzz_rand_uninstantiate },
112*e0c4386eSCy Schubert { OSSL_FUNC_RAND_GENERATE, (void (*)(void))fuzz_rand_generate },
113*e0c4386eSCy Schubert { OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))fuzz_rand_enable_locking },
114*e0c4386eSCy Schubert { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
115*e0c4386eSCy Schubert (void(*)(void))fuzz_rand_gettable_ctx_params },
116*e0c4386eSCy Schubert { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))fuzz_rand_get_ctx_params },
117*e0c4386eSCy Schubert { 0, NULL }
118*e0c4386eSCy Schubert };
119*e0c4386eSCy Schubert
120*e0c4386eSCy Schubert static const OSSL_ALGORITHM fuzz_rand_rand[] = {
121*e0c4386eSCy Schubert { "fuzz", "provider=fuzz-rand", fuzz_rand_functions },
122*e0c4386eSCy Schubert { NULL, NULL, NULL }
123*e0c4386eSCy Schubert };
124*e0c4386eSCy Schubert
fuzz_rand_query(void * provctx,int operation_id,int * no_cache)125*e0c4386eSCy Schubert static const OSSL_ALGORITHM *fuzz_rand_query(void *provctx,
126*e0c4386eSCy Schubert int operation_id,
127*e0c4386eSCy Schubert int *no_cache)
128*e0c4386eSCy Schubert {
129*e0c4386eSCy Schubert *no_cache = 0;
130*e0c4386eSCy Schubert switch (operation_id) {
131*e0c4386eSCy Schubert case OSSL_OP_RAND:
132*e0c4386eSCy Schubert return fuzz_rand_rand;
133*e0c4386eSCy Schubert }
134*e0c4386eSCy Schubert return NULL;
135*e0c4386eSCy Schubert }
136*e0c4386eSCy Schubert
137*e0c4386eSCy Schubert /* Functions we provide to the core */
138*e0c4386eSCy Schubert static const OSSL_DISPATCH fuzz_rand_method[] = {
139*e0c4386eSCy Schubert { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free },
140*e0c4386eSCy Schubert { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fuzz_rand_query },
141*e0c4386eSCy Schubert { 0, NULL }
142*e0c4386eSCy Schubert };
143*e0c4386eSCy Schubert
fuzz_rand_provider_init(const OSSL_CORE_HANDLE * handle,const OSSL_DISPATCH * in,const OSSL_DISPATCH ** out,void ** provctx)144*e0c4386eSCy Schubert static int fuzz_rand_provider_init(const OSSL_CORE_HANDLE *handle,
145*e0c4386eSCy Schubert const OSSL_DISPATCH *in,
146*e0c4386eSCy Schubert const OSSL_DISPATCH **out, void **provctx)
147*e0c4386eSCy Schubert {
148*e0c4386eSCy Schubert *provctx = OSSL_LIB_CTX_new();
149*e0c4386eSCy Schubert if (*provctx == NULL)
150*e0c4386eSCy Schubert return 0;
151*e0c4386eSCy Schubert *out = fuzz_rand_method;
152*e0c4386eSCy Schubert return 1;
153*e0c4386eSCy Schubert }
154*e0c4386eSCy Schubert
155*e0c4386eSCy Schubert static OSSL_PROVIDER *r_prov;
156*e0c4386eSCy Schubert
FuzzerSetRand(void)157*e0c4386eSCy Schubert void FuzzerSetRand(void)
158*e0c4386eSCy Schubert {
159*e0c4386eSCy Schubert if (!OSSL_PROVIDER_add_builtin(NULL, "fuzz-rand", fuzz_rand_provider_init)
160*e0c4386eSCy Schubert || !RAND_set_DRBG_type(NULL, "fuzz", NULL, NULL, NULL)
161*e0c4386eSCy Schubert || (r_prov = OSSL_PROVIDER_try_load(NULL, "fuzz-rand", 1)) == NULL)
162*e0c4386eSCy Schubert exit(1);
163*e0c4386eSCy Schubert }
164*e0c4386eSCy Schubert
FuzzerClearRand(void)165*e0c4386eSCy Schubert void FuzzerClearRand(void)
166*e0c4386eSCy Schubert {
167*e0c4386eSCy Schubert OSSL_PROVIDER_unload(r_prov);
168*e0c4386eSCy Schubert }
169