1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright (C) 2001, 2002, 2004, 2007, 2008, 2010 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may require
8 * a specific license from the United States Government. It is the
9 * responsibility of any person or organization contemplating export to
10 * obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
27 #include "crypto_int.h"
29 krb5_error_code KRB5_CALLCONV
30 krb5_c_random_seed(krb5_context context, krb5_data *data)
32 return krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OLDAPI, data);
35 /* Routines to get entropy from the OS. */
39 k5_get_os_entropy(unsigned char *buf, size_t len)
44 if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
47 result = CryptGenRandom(provider, len, buf);
48 (void)CryptReleaseContext(provider, 0);
52 krb5_error_code KRB5_CALLCONV
53 krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
57 krb5_data data = make_data(buf, sizeof(buf));
59 if (k5_get_os_entropy(buf, sizeof(buf)) &&
60 krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND,
64 *success = oursuccess;
68 #else /* not Windows */
72 #ifdef HAVE_SYS_STAT_H
76 /* Open device, ensure that it is not a regular file, and read entropy. Return
77 * true on success, false on failure. */
79 read_entropy_from_device(const char *device, unsigned char *buf, size_t len)
86 krb5_boolean result = FALSE;
88 fd = open(device, O_RDONLY);
92 if (fstat(fd, &sb) == -1 || S_ISREG(sb.st_mode))
95 for (bp = buf, left = len; left > 0;) {
96 count = read(fd, bp, left);
110 k5_get_os_entropy(unsigned char *buf, size_t len)
112 return read_entropy_from_device("/dev/urandom", buf, len);
115 /* Read entropy from device and contribute it to the PRNG. Returns true on
118 add_entropy_from_device(krb5_context context, const char *device)
121 unsigned char buf[64];
123 if (!read_entropy_from_device(device, buf, sizeof(buf)))
125 data = make_data(buf, sizeof(buf));
126 return (krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND,
130 krb5_error_code KRB5_CALLCONV
131 krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
134 int *oursuccess = (success != NULL) ? success : &unused;
137 /* If we are getting strong data then try that first. We are
138 guaranteed to cause a reseed of some kind if strong is true and
139 we have both /dev/random and /dev/urandom. We want the strong
140 data included in the reseed so we get it first.*/
142 if (add_entropy_from_device(context, "/dev/random"))
145 if (add_entropy_from_device(context, "/dev/urandom"))
150 #endif /* not Windows */