Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : 4 : Functions to create reasonable random numbers for crypto use. 5 : 6 : Copyright (C) Jeremy Allison 2001 7 : 8 : This program is free software; you can redistribute it and/or modify 9 : it under the terms of the GNU General Public License as published by 10 : the Free Software Foundation; either version 3 of the License, or 11 : (at your option) any later version. 12 : 13 : This program is distributed in the hope that it will be useful, 14 : but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : GNU General Public License for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with this program. If not, see <http://www.gnu.org/licenses/>. 20 : */ 21 : 22 : #include "replace.h" 23 : #include "lib/util/fault.h" 24 : #include "lib/util/genrand.h" 25 : 26 : #include <gnutls/gnutls.h> 27 : #include <gnutls/crypto.h> 28 : 29 : /* 30 : * Details about the GnuTLS CSPRNG: 31 : * 32 : * https://nikmav.blogspot.com/2017/03/improving-by-simplifying-gnutls-prng.html 33 : */ 34 : 35 : 36 0 : _NORETURN_ static void genrand_panic(int err, 37 : const char *location, 38 : const char *func) 39 : { 40 0 : char buf[200]; 41 0 : snprintf(buf, sizeof(buf), 42 : "%s:%s: GnuTLS could not generate a random buffer: %s [%d]\n", 43 : location, func, gnutls_strerror_name(err), err); 44 0 : smb_panic(buf); 45 : } 46 : 47 : 48 2461449 : _PUBLIC_ void generate_random_buffer(uint8_t *out, size_t len) 49 : { 50 : /* Random number generator for temporary keys. */ 51 2461449 : int ret = gnutls_rnd(GNUTLS_RND_RANDOM, out, len); 52 2461449 : if (ret != 0) { 53 0 : genrand_panic(ret, __location__, __func__); 54 : } 55 2461449 : } 56 : 57 59403 : _PUBLIC_ void generate_secret_buffer(uint8_t *out, size_t len) 58 : { 59 : /* 60 : * Random number generator for long term keys. 61 : * 62 : * The key generator, will re-seed after a fixed amount of bytes is 63 : * generated (typically less than the nonce), and will also re-seed 64 : * based on time, i.e., after few hours of operation without reaching 65 : * the limit for a re-seed. For its re-seed it mixes data obtained 66 : * from the OS random device with the previous key. 67 : */ 68 59403 : int ret = gnutls_rnd(GNUTLS_RND_KEY, out, len); 69 59403 : if (ret != 0) { 70 0 : genrand_panic(ret, __location__, __func__); 71 : } 72 59403 : } 73 : 74 631672 : _PUBLIC_ void generate_nonce_buffer(uint8_t *out, size_t len) 75 : { 76 : /* 77 : * Random number generator for nonce and initialization vectors. 78 : * 79 : * The nonce generator will reseed after outputting a fixed amount of 80 : * bytes (typically few megabytes), or after few hours of operation 81 : * without reaching the limit has passed. 82 : */ 83 631672 : int ret = gnutls_rnd(GNUTLS_RND_NONCE, out, len); 84 631672 : if (ret != 0) { 85 0 : genrand_panic(ret, __location__, __func__); 86 : } 87 631672 : }