test_rng.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /*
  2. * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <openssl/core_dispatch.h>
  12. #include <openssl/e_os2.h>
  13. #include <openssl/params.h>
  14. #include <openssl/core_names.h>
  15. #include <openssl/evp.h>
  16. #include <openssl/err.h>
  17. #include <openssl/randerr.h>
  18. #include "prov/providercommon.h"
  19. #include "prov/provider_ctx.h"
  20. #include "prov/provider_util.h"
  21. #include "prov/implementations.h"
  22. static OSSL_FUNC_rand_newctx_fn test_rng_new;
  23. static OSSL_FUNC_rand_freectx_fn test_rng_free;
  24. static OSSL_FUNC_rand_instantiate_fn test_rng_instantiate;
  25. static OSSL_FUNC_rand_uninstantiate_fn test_rng_uninstantiate;
  26. static OSSL_FUNC_rand_generate_fn test_rng_generate;
  27. static OSSL_FUNC_rand_reseed_fn test_rng_reseed;
  28. static OSSL_FUNC_rand_nonce_fn test_rng_nonce;
  29. static OSSL_FUNC_rand_settable_ctx_params_fn test_rng_settable_ctx_params;
  30. static OSSL_FUNC_rand_set_ctx_params_fn test_rng_set_ctx_params;
  31. static OSSL_FUNC_rand_gettable_ctx_params_fn test_rng_gettable_ctx_params;
  32. static OSSL_FUNC_rand_get_ctx_params_fn test_rng_get_ctx_params;
  33. static OSSL_FUNC_rand_verify_zeroization_fn test_rng_verify_zeroization;
  34. static OSSL_FUNC_rand_enable_locking_fn test_rng_enable_locking;
  35. static OSSL_FUNC_rand_lock_fn test_rng_lock;
  36. static OSSL_FUNC_rand_unlock_fn test_rng_unlock;
  37. static OSSL_FUNC_rand_get_seed_fn test_rng_get_seed;
  38. typedef struct {
  39. void *provctx;
  40. unsigned int generate;
  41. int state;
  42. unsigned int strength;
  43. size_t max_request;
  44. unsigned char *entropy, *nonce;
  45. size_t entropy_len, entropy_pos, nonce_len;
  46. CRYPTO_RWLOCK *lock;
  47. uint32_t seed;
  48. } PROV_TEST_RNG;
  49. static void *test_rng_new(void *provctx, void *parent,
  50. const OSSL_DISPATCH *parent_dispatch)
  51. {
  52. PROV_TEST_RNG *t;
  53. t = OPENSSL_zalloc(sizeof(*t));
  54. if (t == NULL)
  55. return NULL;
  56. t->max_request = INT_MAX;
  57. t->provctx = provctx;
  58. t->state = EVP_RAND_STATE_UNINITIALISED;
  59. return t;
  60. }
  61. static void test_rng_free(void *vtest)
  62. {
  63. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  64. if (t == NULL)
  65. return;
  66. OPENSSL_free(t->entropy);
  67. OPENSSL_free(t->nonce);
  68. CRYPTO_THREAD_lock_free(t->lock);
  69. OPENSSL_free(t);
  70. }
  71. static int test_rng_instantiate(void *vtest, unsigned int strength,
  72. int prediction_resistance,
  73. const unsigned char *pstr, size_t pstr_len,
  74. const OSSL_PARAM params[])
  75. {
  76. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  77. if (!test_rng_set_ctx_params(t, params) || strength > t->strength)
  78. return 0;
  79. t->state = EVP_RAND_STATE_READY;
  80. t->entropy_pos = 0;
  81. t->seed = 221953166; /* Value doesn't matter, so long as it isn't zero */
  82. return 1;
  83. }
  84. static int test_rng_uninstantiate(void *vtest)
  85. {
  86. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  87. t->entropy_pos = 0;
  88. t->state = EVP_RAND_STATE_UNINITIALISED;
  89. return 1;
  90. }
  91. static unsigned char gen_byte(PROV_TEST_RNG *t)
  92. {
  93. uint32_t n;
  94. /*
  95. * Implement the 32 bit xorshift as suggested by George Marsaglia in:
  96. * https://doi.org/10.18637/jss.v008.i14
  97. *
  98. * This is a very fast PRNG so there is no need to extract bytes one at a
  99. * time and use the entire value each time.
  100. */
  101. n = t->seed;
  102. n ^= n << 13;
  103. n ^= n >> 17;
  104. n ^= n << 5;
  105. t->seed = n;
  106. return n & 0xff;
  107. }
  108. static int test_rng_generate(void *vtest, unsigned char *out, size_t outlen,
  109. unsigned int strength, int prediction_resistance,
  110. const unsigned char *adin, size_t adin_len)
  111. {
  112. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  113. size_t i;
  114. if (strength > t->strength)
  115. return 0;
  116. if (t->generate) {
  117. for (i = 0; i < outlen; i++)
  118. out[i] = gen_byte(t);
  119. } else {
  120. if (t->entropy_len - t->entropy_pos < outlen)
  121. return 0;
  122. memcpy(out, t->entropy + t->entropy_pos, outlen);
  123. t->entropy_pos += outlen;
  124. }
  125. return 1;
  126. }
  127. static int test_rng_reseed(ossl_unused void *vtest,
  128. ossl_unused int prediction_resistance,
  129. ossl_unused const unsigned char *ent,
  130. ossl_unused size_t ent_len,
  131. ossl_unused const unsigned char *adin,
  132. ossl_unused size_t adin_len)
  133. {
  134. return 1;
  135. }
  136. static size_t test_rng_nonce(void *vtest, unsigned char *out,
  137. unsigned int strength, size_t min_noncelen,
  138. ossl_unused size_t max_noncelen)
  139. {
  140. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  141. size_t i;
  142. if (strength > t->strength)
  143. return 0;
  144. if (t->generate) {
  145. for (i = 0; i < min_noncelen; i++)
  146. out[i] = gen_byte(t);
  147. return min_noncelen;
  148. }
  149. if (t->nonce == NULL)
  150. return 0;
  151. if (out != NULL)
  152. memcpy(out, t->nonce, t->nonce_len);
  153. return t->nonce_len;
  154. }
  155. static int test_rng_get_ctx_params(void *vtest, OSSL_PARAM params[])
  156. {
  157. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  158. OSSL_PARAM *p;
  159. p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE);
  160. if (p != NULL && !OSSL_PARAM_set_int(p, t->state))
  161. return 0;
  162. p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH);
  163. if (p != NULL && !OSSL_PARAM_set_int(p, t->strength))
  164. return 0;
  165. p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
  166. if (p != NULL && !OSSL_PARAM_set_size_t(p, t->max_request))
  167. return 0;
  168. p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_GENERATE);
  169. if (p != NULL && OSSL_PARAM_set_uint(p, t->generate))
  170. return 0;
  171. return 1;
  172. }
  173. static const OSSL_PARAM *test_rng_gettable_ctx_params(ossl_unused void *vtest,
  174. ossl_unused void *provctx)
  175. {
  176. static const OSSL_PARAM known_gettable_ctx_params[] = {
  177. OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),
  178. OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
  179. OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
  180. OSSL_PARAM_uint(OSSL_RAND_PARAM_GENERATE, NULL),
  181. OSSL_PARAM_END
  182. };
  183. return known_gettable_ctx_params;
  184. }
  185. static int test_rng_set_ctx_params(void *vtest, const OSSL_PARAM params[])
  186. {
  187. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  188. const OSSL_PARAM *p;
  189. void *ptr = NULL;
  190. size_t size = 0;
  191. if (params == NULL)
  192. return 1;
  193. p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_STRENGTH);
  194. if (p != NULL && !OSSL_PARAM_get_uint(p, &t->strength))
  195. return 0;
  196. p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_TEST_ENTROPY);
  197. if (p != NULL) {
  198. if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size))
  199. return 0;
  200. OPENSSL_free(t->entropy);
  201. t->entropy = ptr;
  202. t->entropy_len = size;
  203. t->entropy_pos = 0;
  204. ptr = NULL;
  205. }
  206. p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_TEST_NONCE);
  207. if (p != NULL) {
  208. if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size))
  209. return 0;
  210. OPENSSL_free(t->nonce);
  211. t->nonce = ptr;
  212. t->nonce_len = size;
  213. }
  214. p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_MAX_REQUEST);
  215. if (p != NULL && !OSSL_PARAM_get_size_t(p, &t->max_request))
  216. return 0;
  217. p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_GENERATE);
  218. if (p != NULL && !OSSL_PARAM_get_uint(p, &t->generate))
  219. return 0;
  220. return 1;
  221. }
  222. static const OSSL_PARAM *test_rng_settable_ctx_params(ossl_unused void *vtest,
  223. ossl_unused void *provctx)
  224. {
  225. static const OSSL_PARAM known_settable_ctx_params[] = {
  226. OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, NULL, 0),
  227. OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_NONCE, NULL, 0),
  228. OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
  229. OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
  230. OSSL_PARAM_uint(OSSL_RAND_PARAM_GENERATE, NULL),
  231. OSSL_PARAM_END
  232. };
  233. return known_settable_ctx_params;
  234. }
  235. static int test_rng_verify_zeroization(ossl_unused void *vtest)
  236. {
  237. return 1;
  238. }
  239. static size_t test_rng_get_seed(void *vtest, unsigned char **pout,
  240. int entropy, size_t min_len, size_t max_len,
  241. ossl_unused int prediction_resistance,
  242. ossl_unused const unsigned char *adin,
  243. ossl_unused size_t adin_len)
  244. {
  245. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  246. *pout = t->entropy;
  247. return t->entropy_len > max_len ? max_len : t->entropy_len;
  248. }
  249. static int test_rng_enable_locking(void *vtest)
  250. {
  251. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  252. if (t != NULL && t->lock == NULL) {
  253. t->lock = CRYPTO_THREAD_lock_new();
  254. if (t->lock == NULL) {
  255. ERR_raise(ERR_LIB_PROV, RAND_R_FAILED_TO_CREATE_LOCK);
  256. return 0;
  257. }
  258. }
  259. return 1;
  260. }
  261. static int test_rng_lock(void *vtest)
  262. {
  263. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  264. if (t == NULL || t->lock == NULL)
  265. return 1;
  266. return CRYPTO_THREAD_write_lock(t->lock);
  267. }
  268. static void test_rng_unlock(void *vtest)
  269. {
  270. PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
  271. if (t != NULL && t->lock != NULL)
  272. CRYPTO_THREAD_unlock(t->lock);
  273. }
  274. const OSSL_DISPATCH ossl_test_rng_functions[] = {
  275. { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))test_rng_new },
  276. { OSSL_FUNC_RAND_FREECTX, (void(*)(void))test_rng_free },
  277. { OSSL_FUNC_RAND_INSTANTIATE,
  278. (void(*)(void))test_rng_instantiate },
  279. { OSSL_FUNC_RAND_UNINSTANTIATE,
  280. (void(*)(void))test_rng_uninstantiate },
  281. { OSSL_FUNC_RAND_GENERATE, (void(*)(void))test_rng_generate },
  282. { OSSL_FUNC_RAND_RESEED, (void(*)(void))test_rng_reseed },
  283. { OSSL_FUNC_RAND_NONCE, (void(*)(void))test_rng_nonce },
  284. { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))test_rng_enable_locking },
  285. { OSSL_FUNC_RAND_LOCK, (void(*)(void))test_rng_lock },
  286. { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))test_rng_unlock },
  287. { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
  288. (void(*)(void))test_rng_settable_ctx_params },
  289. { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))test_rng_set_ctx_params },
  290. { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
  291. (void(*)(void))test_rng_gettable_ctx_params },
  292. { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))test_rng_get_ctx_params },
  293. { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
  294. (void(*)(void))test_rng_verify_zeroization },
  295. { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))test_rng_get_seed },
  296. OSSL_DISPATCH_END
  297. };