]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/rand/rand_crng_test.c
Reorganize local header files
[thirdparty/openssl.git] / crypto / rand / rand_crng_test.c
CommitLineData
d69226a3
P
1/*
2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
4 *
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11/*
12 * Implementation of the FIPS 140-2 section 4.9.2 Conditional Tests.
13 */
14
15#include <string.h>
8094a694 16#include <openssl/evp.h>
25f2138b 17#include "crypto/rand.h"
d69226a3 18#include "internal/thread_once.h"
4e297b74 19#include "internal/cryptlib.h"
706457b7 20#include "rand_local.h"
d69226a3 21
4e297b74
MC
22typedef struct crng_test_global_st {
23 unsigned char crngt_prev[EVP_MAX_MD_SIZE];
24 RAND_POOL *crngt_pool;
25} CRNG_TEST_GLOBAL;
d69226a3 26
57ca171a
MC
27int (*crngt_get_entropy)(OPENSSL_CTX *, RAND_POOL *, unsigned char *,
28 unsigned char *, unsigned int *)
8094a694 29 = &rand_crngt_get_entropy_cb;
d69226a3 30
4e297b74 31static void rand_crng_ossl_ctx_free(void *vcrngt_glob)
d69226a3 32{
4e297b74 33 CRNG_TEST_GLOBAL *crngt_glob = vcrngt_glob;
d69226a3 34
4e297b74
MC
35 rand_pool_free(crngt_glob->crngt_pool);
36 OPENSSL_free(crngt_glob);
d69226a3
P
37}
38
4e297b74 39static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx)
d69226a3 40{
8094a694 41 unsigned char buf[CRNGT_BUFSIZ];
4e297b74 42 CRNG_TEST_GLOBAL *crngt_glob = OPENSSL_zalloc(sizeof(*crngt_glob));
8094a694 43
4e297b74
MC
44 if (crngt_glob == NULL)
45 return NULL;
46
47 if ((crngt_glob->crngt_pool
1372560f 48 = rand_pool_new(0, 1, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) {
4e297b74
MC
49 OPENSSL_free(crngt_glob);
50 return NULL;
51 }
57ca171a
MC
52 if (crngt_get_entropy(ctx, crngt_glob->crngt_pool, buf,
53 crngt_glob->crngt_prev, NULL)) {
8094a694 54 OPENSSL_cleanse(buf, sizeof(buf));
4e297b74 55 return crngt_glob;
8094a694 56 }
4e297b74
MC
57 rand_pool_free(crngt_glob->crngt_pool);
58 OPENSSL_free(crngt_glob);
59 return NULL;
d69226a3
P
60}
61
4e297b74
MC
62static const OPENSSL_CTX_METHOD rand_crng_ossl_ctx_method = {
63 rand_crng_ossl_ctx_new,
64 rand_crng_ossl_ctx_free,
65};
d69226a3 66
4e297b74 67int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx,
57ca171a 68 RAND_POOL *pool,
4e297b74
MC
69 unsigned char *buf,
70 unsigned char *md,
71 unsigned int *md_size)
d69226a3 72{
4e297b74
MC
73 int r;
74 size_t n;
75 unsigned char *p;
4e297b74 76
57ca171a 77 if (pool == NULL)
4e297b74
MC
78 return 0;
79
57ca171a 80 n = rand_pool_acquire_entropy(pool);
4e297b74 81 if (n >= CRNGT_BUFSIZ) {
57ca171a
MC
82 EVP_MD *fmd = EVP_MD_fetch(ctx, "SHA256", "");
83 if (fmd == NULL)
84 return 0;
85 p = rand_pool_detach(pool);
86 r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, fmd, NULL);
4e297b74
MC
87 if (r != 0)
88 memcpy(buf, p, CRNGT_BUFSIZ);
57ca171a 89 rand_pool_reattach(pool, p);
3fd70262 90 EVP_MD_free(fmd);
4e297b74
MC
91 return r;
92 }
93 return 0;
d69226a3
P
94}
95
96size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
97 unsigned char **pout,
98 int entropy, size_t min_len, size_t max_len,
99 int prediction_resistance)
100{
8094a694
P
101 unsigned char buf[CRNGT_BUFSIZ], md[EVP_MAX_MD_SIZE];
102 unsigned int sz;
d69226a3
P
103 RAND_POOL *pool;
104 size_t q, r = 0, s, t = 0;
105 int attempts = 3;
4e297b74
MC
106 CRNG_TEST_GLOBAL *crngt_glob
107 = openssl_ctx_get_data(drbg->libctx, OPENSSL_CTX_RAND_CRNGT_INDEX,
108 &rand_crng_ossl_ctx_method);
d69226a3 109
4e297b74 110 if (crngt_glob == NULL)
d69226a3
P
111 return 0;
112
1372560f 113 if ((pool = rand_pool_new(entropy, 1, min_len, max_len)) == NULL)
d69226a3
P
114 return 0;
115
116 while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
117 s = q > sizeof(buf) ? sizeof(buf) : q;
57ca171a
MC
118 if (!crngt_get_entropy(drbg->libctx, crngt_glob->crngt_pool, buf, md,
119 &sz)
4e297b74 120 || memcmp(crngt_glob->crngt_prev, md, sz) == 0
d69226a3
P
121 || !rand_pool_add(pool, buf, s, s * 8))
122 goto err;
4e297b74 123 memcpy(crngt_glob->crngt_prev, md, sz);
d69226a3
P
124 t += s;
125 attempts++;
126 }
127 r = t;
128 *pout = rand_pool_detach(pool);
129err:
8094a694 130 OPENSSL_cleanse(buf, sizeof(buf));
d69226a3
P
131 rand_pool_free(pool);
132 return r;
133}
134
135void rand_crngt_cleanup_entropy(RAND_DRBG *drbg,
136 unsigned char *out, size_t outlen)
137{
138 OPENSSL_secure_clear_free(out, outlen);
139}