1 | /* |
2 | * Copyright (c) 2013 Apple Inc. All rights reserved. |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
5 | * |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License |
8 | * Version 2.0 (the 'License'). You may not use this file except in |
9 | * compliance with the License. The rights granted to you under the License |
10 | * may not be used to create, or enable the creation or redistribution of, |
11 | * unlawful or unlicensed copies of an Apple operating system, or to |
12 | * circumvent, violate, or enable the circumvention or violation of, any |
13 | * terms of an Apple operating system software license agreement. |
14 | * |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this 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_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ |
28 | |
29 | #include <kern/locks.h> |
30 | #include <kern/cpu_number.h> |
31 | #include <libkern/section_keywords.h> |
32 | #include <libkern/crypto/sha2.h> |
33 | #include <machine/machine_cpu.h> |
34 | #include <machine/machine_routines.h> |
35 | #include <pexpert/pexpert.h> |
36 | #include <sys/random.h> |
37 | #include <prng/random.h> |
38 | #include <prng/entropy.h> |
39 | #include <corecrypto/ccdigest.h> |
40 | #include <corecrypto/ccdrbg.h> |
41 | #include <corecrypto/cckprng.h> |
42 | #include <corecrypto/ccsha2.h> |
43 | |
44 | static struct cckprng_ctx *prng_ctx; |
45 | |
46 | static SECURITY_READ_ONLY_LATE(struct cckprng_funcs) prng_funcs; |
47 | static SECURITY_READ_ONLY_LATE(int) prng_ready; |
48 | |
49 | #define SEED_SIZE (SHA256_DIGEST_LENGTH) |
50 | static uint8_t bootseed[SEED_SIZE]; |
51 | |
52 | static void |
53 | bootseed_init_bootloader(const struct ccdigest_info * di, ccdigest_ctx_t ctx) |
54 | { |
55 | uint8_t seed[64]; |
56 | uint32_t n; |
57 | |
58 | n = PE_get_random_seed(dst_random_seed: seed, request_size: sizeof(seed)); |
59 | if (n < sizeof(seed)) { |
60 | /* |
61 | * Insufficient entropy is fatal. We must fill the |
62 | * entire entropy buffer during initializaton. |
63 | */ |
64 | panic("Expected %lu seed bytes from bootloader, but got %u." , sizeof(seed), n); |
65 | } |
66 | |
67 | ccdigest_update(di, ctx, len: sizeof(seed), data: seed); |
68 | cc_clear(len: sizeof(seed), dst: seed); |
69 | } |
70 | |
71 | #if defined(__x86_64__) |
72 | #include <i386/cpuid.h> |
73 | |
74 | static void |
75 | bootseed_init_native(const struct ccdigest_info * di, ccdigest_ctx_t ctx) |
76 | { |
77 | uint64_t x; |
78 | uint8_t ok; |
79 | size_t i = 0; |
80 | size_t n; |
81 | |
82 | if (cpuid_leaf7_features() & CPUID_LEAF7_FEATURE_RDSEED) { |
83 | n = SEED_SIZE / sizeof(x); |
84 | |
85 | while (i < n) { |
86 | asm volatile ("rdseed %0; setc %1" : "=r" (x), "=qm" (ok) : : "cc" ); |
87 | if (ok) { |
88 | ccdigest_update(di, ctx, sizeof(x), &x); |
89 | i += 1; |
90 | } else { |
91 | // Intel recommends to pause between unsuccessful rdseed attempts. |
92 | cpu_pause(); |
93 | } |
94 | } |
95 | } else if (cpuid_features() & CPUID_FEATURE_RDRAND) { |
96 | // The Intel documentation guarantees a reseed every 512 rdrand calls. |
97 | n = (SEED_SIZE / sizeof(x)) * 512; |
98 | |
99 | while (i < n) { |
100 | asm volatile ("rdrand %0; setc %1" : "=r" (x), "=qm" (ok) : : "cc" ); |
101 | if (ok) { |
102 | ccdigest_update(di, ctx, sizeof(x), &x); |
103 | i += 1; |
104 | } else { |
105 | // Intel does not recommend pausing between unsuccessful rdrand attempts. |
106 | } |
107 | } |
108 | } |
109 | |
110 | cc_clear(sizeof(x), &x); |
111 | } |
112 | |
113 | #else |
114 | |
115 | static void |
116 | bootseed_init_native(__unused const struct ccdigest_info * di, __unused ccdigest_ctx_t ctx) |
117 | { |
118 | } |
119 | |
120 | #endif |
121 | |
122 | static void |
123 | bootseed_init(void) |
124 | { |
125 | const struct ccdigest_info * di = &ccsha256_ltc_di; |
126 | |
127 | ccdigest_di_decl(di, ctx); |
128 | ccdigest_init(di, ctx); |
129 | |
130 | bootseed_init_bootloader(di, ctx); |
131 | bootseed_init_native(di, ctx); |
132 | |
133 | ccdigest_final(di, ctx, digest: bootseed); |
134 | ccdigest_di_clear(di, ctx); |
135 | } |
136 | |
137 | #define EARLY_RANDOM_STATE_STATIC_SIZE (264) |
138 | |
139 | static struct { |
140 | uint8_t drbg_state[EARLY_RANDOM_STATE_STATIC_SIZE]; |
141 | struct ccdrbg_info drbg_info; |
142 | const struct ccdrbg_nisthmac_custom drbg_custom; |
143 | } erandom = {.drbg_custom = { |
144 | .di = &ccsha256_ltc_di, |
145 | .strictFIPS = 0, |
146 | }}; |
147 | |
148 | static void read_erandom(void * buf, size_t nbytes); |
149 | |
150 | /* |
151 | * Return a uniformly distributed 64-bit random number. |
152 | * |
153 | * This interface should have minimal dependencies on kernel services, |
154 | * and thus be available very early in the life of the kernel. |
155 | * |
156 | * This provides cryptographically secure randomness contingent on the |
157 | * quality of the seed. It is seeded (lazily) with entropy provided by |
158 | * the Booter. |
159 | * |
160 | * The implementation is a NIST HMAC-SHA256 DRBG instance used as |
161 | * follows: |
162 | * |
163 | * - When first called (on macOS this is very early while page tables |
164 | * are being built) early_random() calls ccdrbg_factory_hmac() to |
165 | * set-up a ccdbrg info structure. |
166 | * |
167 | * - The boot seed (64 bytes) is hashed with SHA256. Where available, |
168 | * hardware RNG outputs are mixed into the seed. (See |
169 | * bootseed_init.) The resulting seed is 32 bytes. |
170 | * |
171 | * - The ccdrbg state structure is a statically allocated area which |
172 | * is then initialized by calling the ccdbrg_init method. The |
173 | * initial entropy is the 32-byte seed described above. The nonce |
174 | * is an 8-byte timestamp from ml_get_timebase(). The |
175 | * personalization data provided is a fixed string. |
176 | * |
177 | * - 64-bit outputs are generated via read_erandom, a wrapper around |
178 | * the ccdbrg_generate method. (Since "strict FIPS" is disabled, |
179 | * the DRBG will never request a reseed.) |
180 | * |
181 | * - After the kernel PRNG is initialized, read_erandom defers |
182 | * generation to it via read_random_generate. (Note that this |
183 | * function acquires a per-processor mutex.) |
184 | */ |
185 | uint64_t |
186 | early_random(void) |
187 | { |
188 | uint64_t result; |
189 | uint64_t nonce; |
190 | int rc; |
191 | const char ps[] = "xnu early random" ; |
192 | static int init = 0; |
193 | |
194 | if (init == 0) { |
195 | bootseed_init(); |
196 | |
197 | /* Init DRBG for NIST HMAC */ |
198 | ccdrbg_factory_nisthmac(info: &erandom.drbg_info, custom: &erandom.drbg_custom); |
199 | assert(erandom.drbg_info.size <= sizeof(erandom.drbg_state)); |
200 | |
201 | /* |
202 | * Init our DBRG from the boot entropy and a timestamp as nonce |
203 | * and the cpu number as personalization. |
204 | */ |
205 | assert(sizeof(bootseed) > sizeof(nonce)); |
206 | nonce = ml_get_timebase(); |
207 | rc = ccdrbg_init(info: &erandom.drbg_info, drbg: (struct ccdrbg_state *)erandom.drbg_state, entropyLength: sizeof(bootseed), entropy: bootseed, nonceLength: sizeof(nonce), nonce: &nonce, psLength: sizeof(ps) - 1, ps); |
208 | if (rc != CCDRBG_STATUS_OK) { |
209 | panic("ccdrbg_init() returned %d" , rc); |
210 | } |
211 | |
212 | cc_clear(len: sizeof(nonce), dst: &nonce); |
213 | |
214 | init = 1; |
215 | } |
216 | |
217 | read_erandom(buf: &result, nbytes: sizeof(result)); |
218 | |
219 | return result; |
220 | } |
221 | |
222 | static void |
223 | read_random_generate(uint8_t *buffer, size_t numbytes); |
224 | |
225 | static void |
226 | read_erandom(void * buf, size_t nbytes) |
227 | { |
228 | uint8_t * buffer_bytes = buf; |
229 | size_t n; |
230 | int rc; |
231 | |
232 | // We defer to the kernel PRNG after it has been installed and |
233 | // initialized. This happens during corecrypto kext |
234 | // initialization. |
235 | if (prng_ready) { |
236 | read_random_generate(buffer: buf, numbytes: nbytes); |
237 | return; |
238 | } |
239 | |
240 | // The DBRG request size is limited, so we break the request into |
241 | // chunks. |
242 | while (nbytes > 0) { |
243 | n = MIN(nbytes, PAGE_SIZE); |
244 | |
245 | // Since "strict FIPS" is disabled, the DRBG will never |
246 | // request a reseed; therefore, we panic on any error |
247 | rc = ccdrbg_generate(info: &erandom.drbg_info, drbg: (struct ccdrbg_state *)erandom.drbg_state, dataOutLength: n, dataOut: buffer_bytes, additionalLength: 0, NULL); |
248 | if (rc != CCDRBG_STATUS_OK) { |
249 | panic("read_erandom ccdrbg error %d" , rc); |
250 | } |
251 | |
252 | buffer_bytes += n; |
253 | nbytes -= n; |
254 | } |
255 | } |
256 | |
257 | void |
258 | read_frandom(void * buffer, u_int numBytes) |
259 | { |
260 | read_erandom(buf: buffer, nbytes: numBytes); |
261 | } |
262 | |
263 | void |
264 | register_and_init_prng(struct cckprng_ctx *ctx, const struct cckprng_funcs *funcs) |
265 | { |
266 | assert(cpu_number() == master_cpu); |
267 | assert(!prng_ready); |
268 | |
269 | entropy_init(); |
270 | |
271 | prng_ctx = ctx; |
272 | prng_funcs = *funcs; |
273 | |
274 | uint64_t nonce = ml_get_timebase(); |
275 | prng_funcs.init_with_getentropy(prng_ctx, MAX_CPUS, sizeof(bootseed), bootseed, sizeof(nonce), &nonce, entropy_provide, NULL); |
276 | prng_funcs.initgen(prng_ctx, master_cpu); |
277 | prng_ready = 1; |
278 | |
279 | cc_clear(len: sizeof(bootseed), dst: bootseed); |
280 | cc_clear(len: sizeof(erandom), dst: &erandom); |
281 | } |
282 | |
283 | void |
284 | random_cpu_init(int cpu) |
285 | { |
286 | assert(cpu != master_cpu); |
287 | |
288 | if (!prng_ready) { |
289 | panic("random_cpu_init: kernel prng has not been installed" ); |
290 | } |
291 | |
292 | prng_funcs.initgen(prng_ctx, cpu); |
293 | } |
294 | |
295 | /* export good random numbers to the rest of the kernel */ |
296 | void |
297 | read_random(void * buffer, u_int numbytes) |
298 | { |
299 | prng_funcs.refresh(prng_ctx); |
300 | read_random_generate(buffer, numbytes); |
301 | } |
302 | |
303 | static void |
304 | ensure_gsbase(void) |
305 | { |
306 | #if defined(__x86_64__) && (DEVELOPMENT || DEBUG) |
307 | /* |
308 | * Calling cpu_number() before gsbase is initialized is potentially |
309 | * catastrophic, so assert that it's not set to the magic value set |
310 | * in i386_init.c before proceeding with the call. We cannot use |
311 | * assert here because it ultimately calls panic, which executes |
312 | * operations that involve accessing %gs-relative data (and additionally |
313 | * causes a debug trap which will not work properly this early in boot.) |
314 | */ |
315 | if (rdmsr64(MSR_IA32_GS_BASE) == EARLY_GSBASE_MAGIC) { |
316 | kprintf("[early_random] Cannot proceed: GSBASE is not initialized\n" ); |
317 | hlt(); |
318 | /*NOTREACHED*/ |
319 | } |
320 | #endif |
321 | } |
322 | |
323 | static void |
324 | read_random_generate(uint8_t *buffer, size_t numbytes) |
325 | { |
326 | ensure_gsbase(); |
327 | |
328 | while (numbytes > 0) { |
329 | size_t n = MIN(numbytes, CCKPRNG_GENERATE_MAX_NBYTES); |
330 | |
331 | prng_funcs.generate(prng_ctx, cpu_number(), n, buffer); |
332 | |
333 | buffer += n; |
334 | numbytes -= n; |
335 | } |
336 | } |
337 | |
338 | int |
339 | write_random(void * buffer, u_int numbytes) |
340 | { |
341 | uint8_t seed[SHA256_DIGEST_LENGTH]; |
342 | SHA256_CTX ctx; |
343 | |
344 | /* hash the input to minimize the time we need to hold the lock */ |
345 | SHA256_Init(ctx: &ctx); |
346 | SHA256_Update(ctx: &ctx, data: buffer, len: numbytes); |
347 | SHA256_Final(digest: seed, ctx: &ctx); |
348 | |
349 | prng_funcs.reseed(prng_ctx, sizeof(seed), seed); |
350 | cc_clear(len: sizeof(seed), dst: seed); |
351 | |
352 | return 0; |
353 | } |
354 | |
355 | /* |
356 | * Boolean PRNG for generating booleans to randomize order of elements |
357 | * in certain kernel data structures. The algorithm is a |
358 | * modified version of the KISS RNG proposed in the paper: |
359 | * http://stat.fsu.edu/techreports/M802.pdf |
360 | * The modifications have been documented in the technical paper |
361 | * paper from UCL: |
362 | * http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf |
363 | */ |
364 | |
365 | /* Initialize the PRNG structures. */ |
366 | void |
367 | random_bool_init(struct bool_gen * bg) |
368 | { |
369 | /* Seed the random boolean generator */ |
370 | read_frandom(buffer: bg->seed, numBytes: sizeof(bg->seed)); |
371 | bg->state = 0; |
372 | simple_lock_init(&bg->lock, 0); |
373 | } |
374 | |
375 | /* Generate random bits and add them to an entropy pool. */ |
376 | void |
377 | random_bool_gen_entropy(struct bool_gen * bg, unsigned int * buffer, int count) |
378 | { |
379 | simple_lock(&bg->lock, LCK_GRP_NULL); |
380 | int i, t; |
381 | for (i = 0; i < count; i++) { |
382 | bg->seed[1] ^= (bg->seed[1] << 5); |
383 | bg->seed[1] ^= (bg->seed[1] >> 7); |
384 | bg->seed[1] ^= (bg->seed[1] << 22); |
385 | t = bg->seed[2] + bg->seed[3] + bg->state; |
386 | bg->seed[2] = bg->seed[3]; |
387 | bg->state = t < 0; |
388 | bg->seed[3] = t & 2147483647; |
389 | bg->seed[0] += 1411392427; |
390 | buffer[i] = (bg->seed[0] + bg->seed[1] + bg->seed[3]); |
391 | } |
392 | simple_unlock(&bg->lock); |
393 | } |
394 | |
395 | /* Get some number of bits from the entropy pool, refilling if necessary. */ |
396 | unsigned int |
397 | random_bool_gen_bits(struct bool_gen * bg, unsigned int * buffer, unsigned int count, unsigned int numbits) |
398 | { |
399 | unsigned int index = 0; |
400 | unsigned int rbits = 0; |
401 | for (unsigned int bitct = 0; bitct < numbits; bitct++) { |
402 | /* |
403 | * Find a portion of the buffer that hasn't been emptied. |
404 | * We might have emptied our last index in the previous iteration. |
405 | */ |
406 | while (index < count && buffer[index] == 0) { |
407 | index++; |
408 | } |
409 | |
410 | /* If we've exhausted the pool, refill it. */ |
411 | if (index == count) { |
412 | random_bool_gen_entropy(bg, buffer, count); |
413 | index = 0; |
414 | } |
415 | |
416 | /* Collect-a-bit */ |
417 | unsigned int bit = buffer[index] & 1; |
418 | buffer[index] = buffer[index] >> 1; |
419 | rbits = bit | (rbits << 1); |
420 | } |
421 | return rbits; |
422 | } |
423 | |