1#ifndef COMMONRANDOM_H 2#define COMMONRANDOM_H 1 3 4/* 5 * CommonRandom.h 6 * 7 * Copyright � 2010-2011 by Apple, Inc. All rights reserved. 8 * 9 * @APPLE_LICENSE_HEADER_START@ 10 * 11 * This file contains Original Code and/or Modifications of Original Code 12 * as defined in and that are subject to the Apple Public Source License 13 * Version 2.0 (the 'License'). You may not use this file except in 14 * compliance with the License. Please obtain a copy of the License at 15 * http://www.opensource.apple.com/apsl/ and read it before using this 16 * file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_LICENSE_HEADER_END@ 27 * 28 */ 29 30#include <dispatch/dispatch.h> 31#include <dispatch/queue.h> 32#include <Availability.h> 33#include <stdint.h> 34#include <sys/types.h> 35#include <CommonCrypto/CommonCryptor.h> 36 37/*! 38 39 @header CommonRNG.h 40 @abstract An interface to a system random number generator. This module 41 provides a managed way either to get random numbers from a 42 NIST-approved random number generator or /dev/random. The NIST 43 random number generator gets its entropy from /dev/random, but 44 operates 9x-10x faster than it. 45 46 @discussion It is inconvenient to call system random number generators 47 directly. In the simple case of calling /dev/random, the caller 48 has to open the device and close it in addition to managing it 49 while it's open. This module has as its immediate raison d'�tre 50 the inconvenience of doing this. It manages a file descriptor to 51 /dev/random including the exception processing of what happens 52 in a fork() and exec(). Call CCRandomCopyBytes() and all the 53 fiddly bits are managed for you. Just get on with whatever you 54 were really trying to do. 55 56 More importantly, though, it also manages a FIPS 140-compliant 57 way to get random numbers. NIST created in their document SP 58 800-90 a new type of AES-based "Deterministic Random Bit 59 Generator" (DRBG) (what is often called a PRNG) and guidelines 60 on how to use it. There are two reasons to prefer it over 61 directly calling /dev/random. It's a standard and immediately 62 compliant with FIPS 140, and it is dramatically faster per-byte. 63 For complete disclosure, this implements an AES-CTR DRBG with 64 derivation function using AES-128 as the cipher and prediction 65 resistance. 66 67 Thus, we provide two RNGs to call, kCCRandomDefault (the NIST 68 one) and kCCRandomDevRandom (a managed wrapper around 69 /dev/random). If you are doing anything involving security, call 70 the default one. You'll be glad you did, because it does much 71 security-related housekeeping for you and you don't have to 72 think about it. Really. 73 74 In implementation details, the first time you call 75 CCRandomCopyBytes(), it will open up /dev/random and seed the RNG 76 with 64 bytes. After each call, there is a reseed operation that 77 happens on an async GCD queue that reseeds with 32 bytes and a 78 nonce from mach_absolute_time(). All access to the internal DRBG 79 is serialized through a GCD queue and is therefore thread safe. 80 81 Should you need to create your own RNG context or have a secondary 82 RNG context, CCRNGCreate() and CCRNGRelease() will let you create 83 an RNG yourself and then call CCRandomCopyBytes() with that 84 context. 85 */ 86 87#include <CommonCrypto/CommonRandom.h> 88 89#if defined(__cplusplus) 90extern "C" { 91#endif 92 93/*! 94 @typedef CCRandomRef 95 @abstract Abstract Reference to a random number generator. 96 97*/ 98#ifndef COMMONRANDOMPRIV_H // Check for the private header 99typedef struct __CCRandom *CCRandomRef; 100#endif 101 102/*! 103 @function CCRandomCopyBytes 104 105 @abstract Return random bytes in a buffer allocated by the caller. 106 107 @discussion The default PRNG returns cryptographically strong random 108 bits suitable for use as cryptographic keys, IVs, nonces etc. 109 110 @param rnd The random number generator to use. Pre-defined values: 111 kCCRandomDefault, the NIST AES-based one and 112 kCCRandomDevRandom, /dev/random itself. 113 114 Alternately, you can create one with CCRNGCreate(). 115 116 @param bytes Pointer to the return buffer. 117 @param count Number of random bytes to return. 118 119 @result Return kCCSuccess on success. Other values are ... 120 */ 121 122int CCRandomCopyBytes(CCRandomRef rnd, void *bytes, size_t count) 123__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); 124 125extern const CCRandomRef kCCRandomDefault 126__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); 127 128extern const CCRandomRef kCCRandomDevRandom 129__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); 130 131/*! 132 @function CCRNGCreate 133 134 @abstract Create an RNG context. 135 136 @discussion This creates a CCRandomRef that you can then pass into 137 CCRandomCopyBytes(). Only call this if you need to create 138 your own context. You can call CCRandomCopyBytes() with this 139 context. Remember to release it. 140 141 @param options Option flags. See below. Unless you have a very 142 good reason, just use kCCRNGOptionCryptoRNG. 143 144 @param rngRef A pointer to a CCRandomRef. 145 146 @result Returns kCCSuccess on success. 147 148 149 */ 150 151CCRNGStatus 152CCRNGCreate(uint32_t options, CCRandomRef *rngRef) 153__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); 154 155/*! 156 @function CCRNGRelease 157 158 @abstract Release an RNG context. 159 160 @discussion This releases and deallocates a context. 161 162 @param rng A CCRandomRef. 163 164 @result Returns kCCSuccess on success. 165 166 167 */ 168 169CCRNGStatus 170CCRNGRelease(CCRandomRef rng) 171__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); 172 173 174/* 175 Options flags 176 177 The option flags are not exposed through the default use of CCRandomGetBytes(). 178 They are only exposed through direct use of a CCRandomRef. 179 180 The polarity is reversed here for two reasons. One is that I want people to 181 think before they make a non-FIPS, predictable RNG. If you're doing any sort of 182 crypto, you want FIPS and you want prediction resistance. Prediction resistance 183 reseeds after every query which is slightly slower, but more secure. Non-FIPS 184 is about 20% faster for very large reads, where very large means well over a MB 185 per get, which you will probably never do. If you pull under 500 bytes from the 186 RNG, there is *NO* change in performance for non-FIPS. 187 188 Non-FIPS makes two changes. First, it increments the counter in machine-natural 189 order, which on little-endian machines makes a very small performance 190 improvement. It saves you two byte-swaps for every 32-bit increment of the 191 counter, for every int that has to be incremented, which is admittedly not 192 much. It is so much not much that this is a compile-time option in the DRBG, 193 and likely to be turned off. 194 195 But something that makes a difference is that it reads from the DRBG in one 196 lump sum, instead of in 500 byte chunks, as FIPS demands. On a 50MB test, runs 197 about 20% faster, but obviously for 500 bytes would run the same. 198 199 Arguably, we should remove the non-FIPS thing because in most circumstances it 200 matters naught. Also, as we've said before, if you're interested in security, 201 you shouldn't be worrying about a small performance tweaks. 202 203 Prediction resistance re-seeds the DRBG after every request with 32 bytes from 204 /dev/random and a timestamp from mach_absolute_time(). This is a legitimate 205 thing you might want and a difference between a "random" and a "urandom" 206 variant. 207 208*/ 209 210enum { 211 kCCRNGOptionIgnoreFIPS = 0x00000001, 212 kCCRNGOptionNoPredictionResistance = 0x00000002, 213 214 kCCRNGOptionCryptoRNG = 0x00000000, 215}; 216 217// Accessor functions to get the rng "states" for internal Security Framework 218// use. 219#include <corecrypto/ccdrbg.h> 220#include <corecrypto/ccrng_system.h> 221 222struct ccrng_state *ccDevRandomGetRngState(void) 223__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); 224 225struct ccrng_state *ccDRBGGetRngState(void) 226__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); 227 228 229#if defined(__cplusplus) 230} 231#endif 232 233#endif /* COMMONRANDOM_H */ 234 235