1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (C) 1998 by the FundsXpress, INC. 8 * 9 * All rights reserved. 10 * 11 * Export of this software from the United States of America may require 12 * a specific license from the United States Government. It is the 13 * responsibility of any person or organization contemplating export to 14 * obtain such a license before exporting. 15 * 16 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 17 * distribute this software and its documentation for any purpose and 18 * without fee is hereby granted, provided that the above copyright 19 * notice appear in all copies and that both that copyright notice and 20 * this permission notice appear in supporting documentation, and that 21 * the name of FundsXpress. not be used in advertising or publicity pertaining 22 * to distribution of the software without specific, written prior 23 * permission. FundsXpress makes no representations about the suitability of 24 * this software for any purpose. It is provided "as is" without express 25 * or implied warranty. 26 */ 27 28 #include <k5-int.h> 29 30 #ifdef _KERNEL 31 #include <sys/random.h> 32 #endif 33 34 #ifndef _KERNEL 35 36 /* 37 * Solaris kerberos: we don't need a random number generator 38 * for the /dev/[u]random, as it uses entropy in the kernel. 39 * Keep this function as some apps might call it directly. 40 */ 41 42 /*ARGSUSED*/ 43 krb5_error_code KRB5_CALLCONV 44 krb5_c_random_seed(krb5_context context, krb5_data *data) 45 { 46 /* 47 * We can't do much if this fails, so ignore the 48 * return code. /dev/urandom has its own entropy 49 * source, so seeding it from here is of questionable 50 * value in the first place. 51 */ 52 (void) C_SeedRandom(krb_ctx_hSession(context), 53 (CK_BYTE_PTR)data->data, 54 (CK_ULONG)data->length); 55 56 return(0); 57 } 58 #endif /* !_KERNEL */ 59 60 /* 61 * krb5_get_random_octets 62 * New for Solaris 9. This routine takes advantage of the new 63 * /dev/[u]random interface provided in Solaris 9 for getting random 64 * bytes generated from the kernel. The entropy produced there is generally 65 * considered better than the current MIT PRNG code that we are replacing. 66 * 67 * This func is visible so that it can be used to generate a 68 * random confounder. 69 */ 70 71 #ifndef _KERNEL 72 73 #endif /* ! _KERNEL */ 74 75 /* 76 * We can assume that the memory for data is already malloc'd. 77 * Return an error if there is an error, but don't clear the data->length 78 * or free data->data. This will be done by the calling function. 79 */ 80 81 /*ARGSUSED*/ 82 krb5_error_code KRB5_CALLCONV 83 krb5_c_random_make_octets(krb5_context context, krb5_data *data) 84 { 85 /* 86 * Solaris kerberos uses /dev/[u]random 87 */ 88 #ifndef _KERNEL /* User space code */ 89 90 krb5_error_code err = 0; 91 CK_RV rv; 92 93 KRB5_LOG0(KRB5_INFO, "krb5_c_random_make_octets() start, user space using " 94 "krb5_get_random_octets()\n"); 95 96 rv = C_GenerateRandom(krb_ctx_hSession(context), (CK_BYTE_PTR)data->data, 97 (CK_ULONG)data->length); 98 99 if (rv != CKR_OK) { 100 KRB5_LOG(KRB5_ERR, "C_GenerateRandom failed in " 101 "krb5_c_random_make_octets: rv = 0x%x.", rv); 102 err = PKCS_ERR; 103 } 104 if (err != 0) { 105 KRB5_LOG0(KRB5_ERR, "krb5_c_random_make_octets() end, error"); 106 return (err); 107 } 108 109 #else /* Kernel code section */ 110 111 /* 112 * Solaris Kerberos: for kernel code we use the randomness generator native 113 * to Solaris 9. We avoid global variables and other nastiness this way. 114 * 115 * Using random_get_pseudo_bytes() instead of random_get_bytes() because it 116 * will not return an error code if there isn't enough entropy but will use 117 * a pseudo random algorithm to produce randomness. Most of the time it 118 * should be as good as random_get_bytes() and we don't have to worry about 119 * dealing with a non-fatal error. 120 */ 121 KRB5_LOG0(KRB5_INFO, "krb5_c_random_make_octets() start, kernel using " 122 "random_get_pseudo_bytes()\n "); 123 124 if(random_get_pseudo_bytes((uint8_t *)data->data, data->length) != 0) { 125 KRB5_LOG0(KRB5_ERR, "krb5_c_random_make_octets() end, " 126 "random_get_pseudo_bytes() error.\n"); 127 return(KRB5_CRYPTO_INTERNAL); 128 } 129 130 #endif /* !_KERNEL */ 131 132 KRB5_LOG0(KRB5_INFO, "krb5_c_random_make_octets() end\n"); 133 return(0); 134 } 135