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