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