]>
Commit | Line | Data |
---|---|---|
03bede0c | 1 | /* |
556009c5 | 2 | * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. |
03bede0c P |
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 | ||
4cde7585 | 10 | #include "rand_local.h" |
03bede0c P |
11 | #include "crypto/rand.h" |
12 | #include "crypto/rand_pool.h" | |
4cde7585 | 13 | #include "internal/core.h" |
03bede0c P |
14 | #include <openssl/core_dispatch.h> |
15 | #include <openssl/err.h> | |
16 | ||
4cde7585 | 17 | size_t ossl_rand_get_entropy(ossl_unused OSSL_LIB_CTX *ctx, |
03bede0c P |
18 | unsigned char **pout, int entropy, |
19 | size_t min_len, size_t max_len) | |
20 | { | |
21 | size_t ret = 0; | |
22 | size_t entropy_available; | |
23 | RAND_POOL *pool; | |
24 | ||
1335ca4b | 25 | pool = ossl_rand_pool_new(entropy, 1, min_len, max_len); |
03bede0c | 26 | if (pool == NULL) { |
e077455e | 27 | ERR_raise(ERR_LIB_RAND, ERR_R_RAND_LIB); |
03bede0c P |
28 | return 0; |
29 | } | |
30 | ||
31 | /* Get entropy by polling system entropy sources. */ | |
32 | entropy_available = ossl_pool_acquire_entropy(pool); | |
33 | ||
34 | if (entropy_available > 0) { | |
1335ca4b SL |
35 | ret = ossl_rand_pool_length(pool); |
36 | *pout = ossl_rand_pool_detach(pool); | |
03bede0c P |
37 | } |
38 | ||
1335ca4b | 39 | ossl_rand_pool_free(pool); |
03bede0c P |
40 | return ret; |
41 | } | |
42 | ||
4cde7585 P |
43 | size_t ossl_rand_get_user_entropy(OSSL_LIB_CTX *ctx, |
44 | unsigned char **pout, int entropy, | |
45 | size_t min_len, size_t max_len) | |
46 | { | |
47 | unsigned char *buf; | |
48 | EVP_RAND_CTX *rng = ossl_rand_get0_seed_noncreating(ctx); | |
49 | size_t ret; | |
50 | ||
51 | if (rng == NULL) | |
52 | return ossl_rand_get_entropy(ctx, pout, entropy, min_len, max_len); | |
53 | ||
54 | /* Determine how many bytes to generate */ | |
55 | ret = entropy > 0 ? (size_t)(7 + entropy) / 8 : min_len; | |
56 | if (ret < min_len) | |
57 | ret = min_len; | |
58 | else if (ret > max_len) | |
59 | ret = max_len; | |
60 | ||
61 | /* Allocate the return buffer */ | |
62 | if ((buf = OPENSSL_secure_malloc(ret)) == NULL) | |
63 | return 0; | |
64 | ||
65 | /* Fill the buffer */ | |
66 | if (!EVP_RAND_generate(rng, buf, ret, entropy, 0, NULL, 0)) { | |
67 | OPENSSL_free(buf); | |
68 | return 0; | |
69 | } | |
70 | *pout = buf; | |
71 | return ret; | |
72 | } | |
73 | ||
74 | void ossl_rand_cleanup_entropy(ossl_unused OSSL_LIB_CTX *ctx, | |
03bede0c P |
75 | unsigned char *buf, size_t len) |
76 | { | |
77 | OPENSSL_secure_clear_free(buf, len); | |
78 | } | |
79 | ||
4cde7585 P |
80 | size_t ossl_rand_get_nonce(ossl_unused OSSL_LIB_CTX *ctx, |
81 | unsigned char **pout, | |
82 | size_t min_len, ossl_unused size_t max_len, | |
03bede0c P |
83 | const void *salt, size_t salt_len) |
84 | { | |
85 | size_t ret = 0; | |
86 | RAND_POOL *pool; | |
87 | ||
1335ca4b | 88 | pool = ossl_rand_pool_new(0, 0, min_len, max_len); |
03bede0c | 89 | if (pool == NULL) { |
e077455e | 90 | ERR_raise(ERR_LIB_RAND, ERR_R_RAND_LIB); |
03bede0c P |
91 | return 0; |
92 | } | |
93 | ||
94 | if (!ossl_pool_add_nonce_data(pool)) | |
95 | goto err; | |
96 | ||
1335ca4b | 97 | if (salt != NULL && !ossl_rand_pool_add(pool, salt, salt_len, 0)) |
03bede0c | 98 | goto err; |
1335ca4b SL |
99 | ret = ossl_rand_pool_length(pool); |
100 | *pout = ossl_rand_pool_detach(pool); | |
03bede0c | 101 | err: |
1335ca4b | 102 | ossl_rand_pool_free(pool); |
03bede0c P |
103 | return ret; |
104 | } | |
105 | ||
4cde7585 P |
106 | size_t ossl_rand_get_user_nonce(OSSL_LIB_CTX *ctx, |
107 | unsigned char **pout, | |
108 | size_t min_len, size_t max_len, | |
109 | const void *salt, size_t salt_len) | |
110 | { | |
111 | unsigned char *buf; | |
112 | EVP_RAND_CTX *rng = ossl_rand_get0_seed_noncreating(ctx); | |
113 | ||
114 | if (rng == NULL) | |
115 | return ossl_rand_get_nonce(ctx, pout, min_len, max_len, salt, salt_len); | |
116 | ||
117 | if ((buf = OPENSSL_malloc(min_len)) == NULL) | |
118 | return 0; | |
119 | ||
120 | if (!EVP_RAND_generate(rng, buf, min_len, 0, 0, salt, salt_len)) { | |
121 | OPENSSL_free(buf); | |
122 | return 0; | |
123 | } | |
124 | *pout = buf; | |
125 | return min_len; | |
126 | } | |
127 | ||
128 | void ossl_rand_cleanup_nonce(ossl_unused OSSL_LIB_CTX *ctx, | |
03bede0c P |
129 | unsigned char *buf, size_t len) |
130 | { | |
131 | OPENSSL_clear_free(buf, len); | |
132 | } |