summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rand
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rand')
-rw-r--r--src/lib/libcrypto/rand/md_rand.c31
-rw-r--r--src/lib/libcrypto/rand/rand.h9
-rw-r--r--src/lib/libcrypto/rand/rand_err.c6
-rw-r--r--src/lib/libcrypto/rand/rand_lib.c119
-rw-r--r--src/lib/libcrypto/rand/randfile.c2
5 files changed, 149 insertions, 18 deletions
diff --git a/src/lib/libcrypto/rand/md_rand.c b/src/lib/libcrypto/rand/md_rand.c
index b2f04ff13e..fcdd3f2a84 100644
--- a/src/lib/libcrypto/rand/md_rand.c
+++ b/src/lib/libcrypto/rand/md_rand.c
@@ -109,6 +109,8 @@
109 * 109 *
110 */ 110 */
111 111
112#define OPENSSL_FIPSEVP
113
112#ifdef MD_RAND_DEBUG 114#ifdef MD_RAND_DEBUG
113# ifndef NDEBUG 115# ifndef NDEBUG
114# define NDEBUG 116# define NDEBUG
@@ -157,13 +159,14 @@ const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
157static void ssleay_rand_cleanup(void); 159static void ssleay_rand_cleanup(void);
158static void ssleay_rand_seed(const void *buf, int num); 160static void ssleay_rand_seed(const void *buf, int num);
159static void ssleay_rand_add(const void *buf, int num, double add_entropy); 161static void ssleay_rand_add(const void *buf, int num, double add_entropy);
160static int ssleay_rand_bytes(unsigned char *buf, int num); 162static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo);
163static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
161static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num); 164static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
162static int ssleay_rand_status(void); 165static int ssleay_rand_status(void);
163 166
164RAND_METHOD rand_ssleay_meth={ 167RAND_METHOD rand_ssleay_meth={
165 ssleay_rand_seed, 168 ssleay_rand_seed,
166 ssleay_rand_bytes, 169 ssleay_rand_nopseudo_bytes,
167 ssleay_rand_cleanup, 170 ssleay_rand_cleanup,
168 ssleay_rand_add, 171 ssleay_rand_add,
169 ssleay_rand_pseudo_bytes, 172 ssleay_rand_pseudo_bytes,
@@ -328,7 +331,7 @@ static void ssleay_rand_seed(const void *buf, int num)
328 ssleay_rand_add(buf, num, (double)num); 331 ssleay_rand_add(buf, num, (double)num);
329 } 332 }
330 333
331static int ssleay_rand_bytes(unsigned char *buf, int num) 334static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
332 { 335 {
333 static volatile int stirred_pool = 0; 336 static volatile int stirred_pool = 0;
334 int i,j,k,st_num,st_idx; 337 int i,j,k,st_num,st_idx;
@@ -517,7 +520,9 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
517 EVP_MD_CTX_cleanup(&m); 520 EVP_MD_CTX_cleanup(&m);
518 if (ok) 521 if (ok)
519 return(1); 522 return(1);
520 else 523 else if (pseudo)
524 return 0;
525 else
521 { 526 {
522 RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED); 527 RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
523 ERR_add_error_data(1, "You need to read the OpenSSL FAQ, " 528 ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
@@ -526,22 +531,16 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
526 } 531 }
527 } 532 }
528 533
534static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
535 {
536 return ssleay_rand_bytes(buf, num, 0);
537 }
538
529/* pseudo-random bytes that are guaranteed to be unique but not 539/* pseudo-random bytes that are guaranteed to be unique but not
530 unpredictable */ 540 unpredictable */
531static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) 541static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
532 { 542 {
533 int ret; 543 return ssleay_rand_bytes(buf, num, 1);
534 unsigned long err;
535
536 ret = RAND_bytes(buf, num);
537 if (ret == 0)
538 {
539 err = ERR_peek_error();
540 if (ERR_GET_LIB(err) == ERR_LIB_RAND &&
541 ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED)
542 ERR_clear_error();
543 }
544 return (ret);
545 } 544 }
546 545
547static int ssleay_rand_status(void) 546static int ssleay_rand_status(void)
diff --git a/src/lib/libcrypto/rand/rand.h b/src/lib/libcrypto/rand/rand.h
index ac6c021763..dc8fcf94c5 100644
--- a/src/lib/libcrypto/rand/rand.h
+++ b/src/lib/libcrypto/rand/rand.h
@@ -119,6 +119,11 @@ int RAND_event(UINT, WPARAM, LPARAM);
119 119
120#endif 120#endif
121 121
122#ifdef OPENSSL_FIPS
123void RAND_set_fips_drbg_type(int type, int flags);
124int RAND_init_fips(void);
125#endif
126
122/* BEGIN ERROR CODES */ 127/* BEGIN ERROR CODES */
123/* The following lines are auto generated by the script mkerr.pl. Any changes 128/* The following lines are auto generated by the script mkerr.pl. Any changes
124 * made after this point may be overwritten when the script is next run. 129 * made after this point may be overwritten when the script is next run.
@@ -129,9 +134,13 @@ void ERR_load_RAND_strings(void);
129 134
130/* Function codes. */ 135/* Function codes. */
131#define RAND_F_RAND_GET_RAND_METHOD 101 136#define RAND_F_RAND_GET_RAND_METHOD 101
137#define RAND_F_RAND_INIT_FIPS 102
132#define RAND_F_SSLEAY_RAND_BYTES 100 138#define RAND_F_SSLEAY_RAND_BYTES 100
133 139
134/* Reason codes. */ 140/* Reason codes. */
141#define RAND_R_ERROR_INITIALISING_DRBG 102
142#define RAND_R_ERROR_INSTANTIATING_DRBG 103
143#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101
135#define RAND_R_PRNG_NOT_SEEDED 100 144#define RAND_R_PRNG_NOT_SEEDED 100
136 145
137#ifdef __cplusplus 146#ifdef __cplusplus
diff --git a/src/lib/libcrypto/rand/rand_err.c b/src/lib/libcrypto/rand/rand_err.c
index 03cda4dd92..b8586c8f4a 100644
--- a/src/lib/libcrypto/rand/rand_err.c
+++ b/src/lib/libcrypto/rand/rand_err.c
@@ -1,6 +1,6 @@
1/* crypto/rand/rand_err.c */ 1/* crypto/rand/rand_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -71,12 +71,16 @@
71static ERR_STRING_DATA RAND_str_functs[]= 71static ERR_STRING_DATA RAND_str_functs[]=
72 { 72 {
73{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, 73{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"},
74{ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"},
74{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, 75{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"},
75{0,NULL} 76{0,NULL}
76 }; 77 };
77 78
78static ERR_STRING_DATA RAND_str_reasons[]= 79static ERR_STRING_DATA RAND_str_reasons[]=
79 { 80 {
81{ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
82{ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"},
83{ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET),"no fips random method set"},
80{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"}, 84{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"},
81{0,NULL} 85{0,NULL}
82 }; 86 };
diff --git a/src/lib/libcrypto/rand/rand_lib.c b/src/lib/libcrypto/rand/rand_lib.c
index 513e338985..daf1dab973 100644
--- a/src/lib/libcrypto/rand/rand_lib.c
+++ b/src/lib/libcrypto/rand/rand_lib.c
@@ -60,10 +60,16 @@
60#include <time.h> 60#include <time.h>
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include <openssl/rand.h> 62#include <openssl/rand.h>
63
63#ifndef OPENSSL_NO_ENGINE 64#ifndef OPENSSL_NO_ENGINE
64#include <openssl/engine.h> 65#include <openssl/engine.h>
65#endif 66#endif
66 67
68#ifdef OPENSSL_FIPS
69#include <openssl/fips.h>
70#include <openssl/fips_rand.h>
71#endif
72
67#ifndef OPENSSL_NO_ENGINE 73#ifndef OPENSSL_NO_ENGINE
68/* non-NULL if default_RAND_meth is ENGINE-provided */ 74/* non-NULL if default_RAND_meth is ENGINE-provided */
69static ENGINE *funct_ref =NULL; 75static ENGINE *funct_ref =NULL;
@@ -174,3 +180,116 @@ int RAND_status(void)
174 return meth->status(); 180 return meth->status();
175 return 0; 181 return 0;
176 } 182 }
183
184#ifdef OPENSSL_FIPS
185
186/* FIPS DRBG initialisation code. This sets up the DRBG for use by the
187 * rest of OpenSSL.
188 */
189
190/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
191 * entropy internally through RAND_poll().
192 */
193
194static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
195 int entropy, size_t min_len, size_t max_len)
196 {
197 /* Round up request to multiple of block size */
198 min_len = ((min_len + 19) / 20) * 20;
199 *pout = OPENSSL_malloc(min_len);
200 if (!*pout)
201 return 0;
202 if (RAND_SSLeay()->bytes(*pout, min_len) <= 0)
203 {
204 OPENSSL_free(*pout);
205 *pout = NULL;
206 return 0;
207 }
208 return min_len;
209 }
210
211static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
212 {
213 OPENSSL_cleanse(out, olen);
214 OPENSSL_free(out);
215 }
216
217/* Set "additional input" when generating random data. This uses the
218 * current PID, a time value and a counter.
219 */
220
221static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
222 {
223 /* Use of static variables is OK as this happens under a lock */
224 static unsigned char buf[16];
225 static unsigned long counter;
226 FIPS_get_timevec(buf, &counter);
227 *pout = buf;
228 return sizeof(buf);
229 }
230
231/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
232 * correctly seeded by RAND_poll().
233 */
234
235static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
236 double entropy)
237 {
238 RAND_SSLeay()->add(in, inlen, entropy);
239 return 1;
240 }
241
242static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
243 {
244 RAND_SSLeay()->seed(in, inlen);
245 return 1;
246 }
247
248#ifndef OPENSSL_DRBG_DEFAULT_TYPE
249#define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr
250#endif
251#ifndef OPENSSL_DRBG_DEFAULT_FLAGS
252#define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF
253#endif
254
255static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
256static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
257
258void RAND_set_fips_drbg_type(int type, int flags)
259 {
260 fips_drbg_type = type;
261 fips_drbg_flags = flags;
262 }
263
264int RAND_init_fips(void)
265 {
266 DRBG_CTX *dctx;
267 size_t plen;
268 unsigned char pers[32], *p;
269 dctx = FIPS_get_default_drbg();
270 if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
271 {
272 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
273 return 0;
274 }
275
276 FIPS_drbg_set_callbacks(dctx,
277 drbg_get_entropy, drbg_free_entropy, 20,
278 drbg_get_entropy, drbg_free_entropy);
279 FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
280 drbg_rand_seed, drbg_rand_add);
281 /* Personalisation string: a string followed by date time vector */
282 strcpy((char *)pers, "OpenSSL DRBG2.0");
283 plen = drbg_get_adin(dctx, &p);
284 memcpy(pers + 16, p, plen);
285
286 if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0)
287 {
288 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
289 return 0;
290 }
291 FIPS_rand_set_method(FIPS_drbg_method());
292 return 1;
293 }
294
295#endif
diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c
index bc7d9c5804..030e07f418 100644
--- a/src/lib/libcrypto/rand/randfile.c
+++ b/src/lib/libcrypto/rand/randfile.c
@@ -137,7 +137,7 @@ int RAND_load_file(const char *file, long bytes)
137 in=fopen(file,"rb"); 137 in=fopen(file,"rb");
138#endif 138#endif
139 if (in == NULL) goto err; 139 if (in == NULL) goto err;
140#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO) 140#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
141 if (sb.st_mode & (S_IFBLK | S_IFCHR)) { 141 if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
142 /* this file is a device. we don't want read an infinite number 142 /* this file is a device. we don't want read an infinite number
143 * of bytes from a random device, nor do we want to use buffered 143 * of bytes from a random device, nor do we want to use buffered