]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/libntp/ntp_crypto_rnd.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / ntp / libntp / ntp_crypto_rnd.c
1 /*
2  * Crypto-quality random number functions
3  *
4  * Author: Harlan Stenn, 2014
5  *
6  * This file is Copyright (c) 2014 by Network Time Foundation.
7  * BSD terms apply: see the file COPYRIGHT in the distribution root for details.
8  */
9
10 #include "config.h"
11 #include <sys/types.h>
12 #ifdef HAVE_UNISTD_H
13 # include <unistd.h>
14 #endif
15 #include <stdio.h>
16
17 #include <l_stdlib.h>
18 #include <ntp_random.h>
19
20 #ifdef USE_OPENSSL_CRYPTO_RAND
21 #include <openssl/err.h>
22 #include <openssl/rand.h>
23
24 int crypto_rand_init = 0;
25 #else
26
27 # ifndef HAVE_ARC4RANDOM_BUF
28 static void
29 arc4random_buf(void *buf, size_t nbytes);
30
31 void
32 evutil_secure_rng_get_bytes(void *buf, size_t nbytes);
33
34 static void
35 arc4random_buf(void *buf, size_t nbytes)
36 {
37         evutil_secure_rng_get_bytes(buf, nbytes);
38         return;
39 }
40 # endif
41 #endif
42
43 /*
44  * As of late 2014, here's how we plan to provide cryptographic-quality
45  * random numbers:
46  * 
47  * - If we are building with OpenSSL, use RAND_poll() and RAND_bytes().
48  * - Otherwise, use arc4random().
49  * 
50  * Use of arc4random() can be forced using configure --disable-openssl-random
51  *
52  * We can count on arc4random existing, thru the OS or thru libevent.
53  * The quality of arc4random depends on the implementor.
54  * 
55  * RAND_poll() doesn't show up until XXX.  If it's not present, we
56  * need to either provide our own or use arc4random().
57  */
58
59 /*
60  * ntp_crypto_srandom:
61  *
62  * Initialize the random number generator, if needed by the underlying
63  * crypto random number generation mechanism.
64  */
65
66 void
67 ntp_crypto_srandom(
68         void
69         )
70 {
71 #ifdef USE_OPENSSL_CRYPTO_RAND
72         if (!crypto_rand_init) {
73                 RAND_poll();
74                 crypto_rand_init = 1;
75         }
76 #else
77         /* No initialization needed for arc4random() */
78 #endif
79 }
80
81
82 /*
83  * ntp_crypto_random_buf:
84  *
85  * Returns 0 on success, -1 on error.
86  */
87 int
88 ntp_crypto_random_buf(
89         void *buf,
90         size_t nbytes
91         )
92 {
93 #ifdef USE_OPENSSL_CRYPTO_RAND
94         int rc;
95
96         rc = RAND_bytes(buf, nbytes);
97         if (1 != rc) {
98                 unsigned long err;
99                 char *err_str;
100
101                 err = ERR_get_error();
102                 err_str = ERR_error_string(err, NULL);
103                 /* XXX: Log the error */
104                 (void)&err_str;
105
106                 return -1;
107         }
108         return 0;
109 #else
110         arc4random_buf(buf, nbytes);
111         return 0;
112 #endif
113 }