1 /* Copyright (c) (2018-2021) Apple Inc. All rights reserved. 2 * 3 * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which 4 * is contained in the License.txt file distributed with corecrypto) and only to 5 * people who accept that license. IMPORTANT: Any license rights granted to you by 6 * Apple Inc. (if any) are limited to internal use within your organization only on 7 * devices and computers you own or control, for the sole purpose of verifying the 8 * security characteristics and correct functioning of the Apple Software. You may 9 * not, directly or indirectly, redistribute the Apple Software or any portions thereof. 10 */ 11 12 #ifndef _CORECRYPTO_CCKPRNG_H_ 13 #define _CORECRYPTO_CCKPRNG_H_ 14 15 #include <stdbool.h> 16 17 #include <corecrypto/cc.h> 18 #include "ccrng_fortuna.h" 19 #include "ccrng_crypto.h" 20 #include <corecrypto/ccrng_schedule.h> 21 #include <corecrypto/ccentropy.h> 22 #include <corecrypto/ccdrbg.h> 23 #include "cc_lock.h" 24 25 // This is a Fortuna-inspired PRNG. While it differs from Fortuna in 26 // many minor details, the biggest difference is its support for 27 // multiple independent output generators. This is to make it suitable 28 // for use in concurrent environments. 29 // 30 // This PRNG targets a 256-bit security level. 31 // 32 // First, the user should call cckprng_init. The user must specify the 33 // maximum number of output generators that might be 34 // needed. (Typically, users should align this argument with the 35 // number of available CPUs.) 36 // 37 // The user must also provide a read-only handle to an entropy 38 // source. This is a fixed-size buffer that will receive entropy 39 // updates out of band from the PRNG (e.g. in an interrupt 40 // handler). The PRNG will consume entropy from this buffer according 41 // to an internal schedule driven by calls to cckprng_refresh (see 42 // below). 43 // 44 // The user should call cckprng_initgen for as many output generators 45 // as are needed. The numeric argument is an identifier to be reused 46 // during calls to cckprng_generate (see below) and must be less than 47 // the maximum number of generators specified to cckprng_init. 48 // 49 // After initialization, the user is free to call cckprng_generate to 50 // generate random bytes. The user must specify the generator in this 51 // call using a numeric identifier passed in the call to 52 // cckprng_initgen. 53 // 54 // Output generation is limited to 256 bytes per request. Users should 55 // make multiple requests if more output is needed. 56 // 57 // The user is expected to call cckprng_refresh regularly. This 58 // function consumes entropy and mixes it into the output generators 59 // according to an internal schedule. 60 // 61 // This implementation is thread-safe. Internally, a set of mutexes 62 // guard access to internal state. Most functions rely on a single 63 // mutex to protect shared state. The main exception is the 64 // cckprng_generate function, which uses a per-generator mutex to 65 // allow concurrent output generation on different threads. 66 // 67 // Another important exception is cckprng_refresh. While this function 68 // relies on the shared mutex, it returns immediately if it cannot 69 // acquire it. 70 // 71 // The PRNG also supports user-initiated reseeds. This is to support a 72 // user-writable random device. 73 // 74 // This PRNG supports reseeds concurrent with output generation, 75 // i.e. it is safe to call cckprng_reseed or cckprng_refresh while 76 // another thread is calling cckprng_generate. 77 78 #define CCKPRNG_SEED_NBYTES 32 79 80 // A function pointer to fill an entropy buffer. It should return some 81 // estimate of entropy (e.g. the number of timing samples resident in 82 // the buffer). The implementation may return zero if no entropy is 83 // available. The implementation should return negative in case of an 84 // error (e.g. a failure in continuous health tests). 85 // 86 // The caller should set entropy_nbytes to the maximum size of the 87 // input buffer, and the implementation should set it to the number of 88 // bytes it has initialized. The third argument is arbitrary state the 89 // implementation provides and receives back on each call. 90 typedef ccrng_fortuna_getentropy cckprng_getentropy; 91 92 #define CCKPRNG_ENTROPY_SIZE 64 93 #define CCKPRNG_DRBG_STATE_MAX_SIZE ((size_t)1280) 94 #define CCKPRNG_CACHED_BUF_SIZE ((size_t)256) 95 #define CCKPRNG_MAX_REQUEST_SIZE ((size_t)4096) 96 97 struct cckprng_ctx { 98 // A flag set every time Fortuna reseeds itself 99 ccrng_schedule_atomic_flag_ctx_t schedule_ctx; 100 101 ccentropy_rng_ctx_t entropy_ctx; 102 103 cc_lock_ctx_t lock_ctx; 104 105 struct ccdrbg_info drbg_info; 106 uint8_t drbg_state[CCKPRNG_DRBG_STATE_MAX_SIZE]; 107 108 uint8_t cache[CCKPRNG_CACHED_BUF_SIZE]; 109 110 ccrng_crypto_ctx_t rng_ctx; 111 112 struct ccrng_fortuna_ctx fortuna_ctx; 113 }; 114 115 // This collection of function pointers is just a convenience for 116 // registering the PRNG with xnu 117 struct cckprng_funcs { 118 void (*CC_SPTR(cckprng_funcs, init))(struct cckprng_ctx *ctx, 119 size_t seed_nbytes, 120 const void *seed, 121 size_t nonce_nbytes, 122 const void *nonce, 123 cckprng_getentropy getentropy, 124 void *getentropy_arg); 125 void (*CC_SPTR(cckprng_funcs, initgen))(struct cckprng_ctx *ctx, unsigned gen_idx); 126 void (*CC_SPTR(cckprng_funcs, reseed))(struct cckprng_ctx *ctx, size_t nbytes, const void *seed); 127 void (*CC_SPTR(cckprng_funcs, refresh))(struct cckprng_ctx *ctx); 128 void (*CC_SPTR(cckprng_funcs, generate))(struct cckprng_ctx *ctx, unsigned gen_idx, size_t nbytes, void *out); 129 void (*CC_SPTR(cckprng_funcs, init_with_getentropy))(struct cckprng_ctx *ctx, 130 unsigned max_ngens, 131 size_t seed_nbytes, 132 const void *seed, 133 size_t nonce_nbytes, 134 const void *nonce, 135 cckprng_getentropy getentropy, 136 void *getentropy_arg); 137 }; 138 139 /* 140 @function cckprng_init 141 @abstract Initialize a kernel PRNG context. 142 143 @param ctx Context for this instance 144 @param seed_nbytes Length of the seed in bytes 145 @param seed Pointer to a high-entropy seed 146 @param nonce_nbytes Length of the nonce in bytes 147 @param nonce Pointer to a single-use nonce 148 @param getentropy A function pointer to fill an entropy buffer 149 @param getentropy_arg State provided to the entropy function 150 151 @discussion See the @p cckprng_getentropy type definition for discussion on its semantics. 152 153 */ 154 void cckprng_init(struct cckprng_ctx *ctx, 155 size_t seed_nbytes, 156 const void *seed, 157 size_t nonce_nbytes, 158 const void *nonce, 159 cckprng_getentropy getentropy, 160 void *getentropy_arg); 161 162 /* 163 @function cckprng_init_with_getentropy 164 @abstract Initialize a kernel PRNG context. 165 166 @param ctx Context for this instance 167 @param max_ngens Maximum count of generators that may be allocated 168 @param seed_nbytes Length of the seed in bytes 169 @param seed Pointer to a high-entropy seed 170 @param nonce_nbytes Length of the nonce in bytes 171 @param nonce Pointer to a single-use nonce 172 @param getentropy A function pointer to fill an entropy buffer 173 @param getentropy_arg State provided to the entropy function 174 175 @discussion @p max_ngens should be set based on an upper bound of CPUs available on the device. See the @p cckprng_getentropy type definition for discussion on its semantics. 176 */ 177 void cckprng_init_with_getentropy(struct cckprng_ctx *ctx, 178 unsigned max_ngens, 179 size_t seed_nbytes, 180 const void *seed, 181 size_t nonce_nbytes, 182 const void *nonce, 183 cckprng_getentropy getentropy, 184 void *getentropy_arg); 185 186 /* 187 @function cckprng_initgen 188 @abstract Initialize an output generator. 189 190 @param ctx Context for this instance 191 @param gen_idx Index of the generator 192 193 @discussion @p gen_idx must be less than @p max_ngens provided to @cckprng_init and must be unique within the lifetime of a PRNG context. This function will abort if these contracts are violated. 194 */ 195 void cckprng_initgen(struct cckprng_ctx *ctx, unsigned gen_idx); 196 197 /* 198 @function cckprng_reseed 199 @abstract Reseed a kernel PRNG context with a user-supplied seed. 200 201 @param ctx Context for this instance 202 @param nbytes Length of the seed in bytes 203 @param seed Pointer to a high-entropy seed 204 205 @discussion It is safe to expose this function to attacker-controlled requests (e.g. writes to /dev/random). 206 */ 207 void cckprng_reseed(struct cckprng_ctx *ctx, size_t nbytes, const void *seed); 208 209 /* 210 @function cckprng_refresh 211 @abstract Consume entropy and reseed according to an internal schedule. 212 213 @param ctx Context for this instance 214 215 @discussion This function should be called on a regular basis. (For example, it is reasonable to call this inline before a call to @p cckprng_generate.) This function will not necessarily consume entropy or reseed the internal state on any given invocation. To force an immediate reseed, call @p cckprng_reseed. 216 */ 217 void cckprng_refresh(struct cckprng_ctx *ctx); 218 219 #define CCKPRNG_GENERATE_MAX_NBYTES 256 220 221 /* 222 @function cckprng_generate 223 @abstract Generate random values for use in applications. 224 225 @param ctx Context for this instance 226 @param gen_idx Index of the output generator 227 @param nbytes Length of the desired output in bytes 228 @param out Pointer to the output buffer 229 230 @discussion @p gen_idx must be a previous argument to @p cckprng_initgen. @p nbytes must be less than or equal to @p CCKPRNG_GENERATE_MAX_NBYTES. (Callers may invoke this function in a loop to generate larger outputs.) This function will abort if these contracts are violated. 231 */ 232 void cckprng_generate(struct cckprng_ctx *ctx, unsigned gen_idx, size_t nbytes, void *out); 233 234 #endif /* _CORECRYPTO_CCKPRNG_H_ */ 235