2 * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
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.
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"
20 fake_random_generate_cb
*cb
;
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
;
35 static void *fake_rand_newctx(void *provctx
, void *parent
,
36 const OSSL_DISPATCH
*parent_dispatch
)
38 FAKE_RAND
*r
= OPENSSL_zalloc(sizeof(*r
));
41 r
->state
= EVP_RAND_STATE_UNINITIALISED
;
45 static void fake_rand_freectx(void *vrng
)
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
,
54 ossl_unused
const OSSL_PARAM params
[])
56 FAKE_RAND
*frng
= (FAKE_RAND
*)vrng
;
58 frng
->state
= EVP_RAND_STATE_READY
;
62 static int fake_rand_uninstantiate(void *vrng
)
64 FAKE_RAND
*frng
= (FAKE_RAND
*)vrng
;
66 frng
->state
= EVP_RAND_STATE_UNINITIALISED
;
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
)
74 FAKE_RAND
*frng
= (FAKE_RAND
*)vrng
;
79 return (*frng
->cb
)(out
, outlen
, frng
->name
, frng
->ctx
);
82 l
= outlen
< sizeof(r
) ? outlen
: sizeof(r
);
91 static int fake_rand_enable_locking(void *vrng
)
96 static int fake_rand_get_ctx_params(ossl_unused
void *vrng
, OSSL_PARAM params
[])
98 FAKE_RAND
*frng
= (FAKE_RAND
*)vrng
;
101 p
= OSSL_PARAM_locate(params
, OSSL_RAND_PARAM_STATE
);
102 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, frng
->state
))
105 p
= OSSL_PARAM_locate(params
, OSSL_RAND_PARAM_STRENGTH
);
106 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, 256))
109 p
= OSSL_PARAM_locate(params
, OSSL_RAND_PARAM_MAX_REQUEST
);
110 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, INT_MAX
))
115 static const OSSL_PARAM
*fake_rand_gettable_ctx_params(ossl_unused
void *vrng
,
116 ossl_unused
void *provctx
)
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
),
124 return known_gettable_ctx_params
;
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
},
140 static const OSSL_ALGORITHM fake_rand_rand
[] = {
141 { "FAKE", "provider=fake", fake_rand_functions
},
145 static const OSSL_ALGORITHM
*fake_rand_query(void *provctx
,
150 switch (operation_id
) {
152 return fake_rand_rand
;
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
},
164 static int fake_rand_provider_init(const OSSL_CORE_HANDLE
*handle
,
165 const OSSL_DISPATCH
*in
,
166 const OSSL_DISPATCH
**out
, void **provctx
)
168 if (!TEST_ptr(*provctx
= OSSL_LIB_CTX_new()))
170 *out
= fake_rand_method
;
174 static int check_rng(EVP_RAND_CTX
*rng
, const char *name
)
178 if (!TEST_ptr(rng
)) {
179 TEST_info("random: %s", name
);
188 OSSL_PROVIDER
*fake_rand_start(OSSL_LIB_CTX
*libctx
)
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)))
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
);
209 void fake_rand_finish(OSSL_PROVIDER
*p
)
211 OSSL_PROVIDER_unload(p
);
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
))
219 ((FAKE_RAND
*)rng
->algctx
)->cb
= cb
;
222 void fake_rand_set_public_private_callbacks(OSSL_LIB_CTX
*libctx
,
223 int (*cb
)(unsigned char *out
,
228 fake_rand_set_callback(RAND_get0_private(libctx
), cb
);
229 fake_rand_set_callback(RAND_get0_public(libctx
), cb
);