]> git.saurik.com Git - apple/xnu.git/blob - osfmk/prng/entropy.c
xnu-7195.81.3.tar.gz
[apple/xnu.git] / osfmk / prng / entropy.c
1 /*
2 * Copyright (c) 2019 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 <libkern/crypto/sha2.h>
30 #include <libkern/crypto/crypto_internal.h>
31 #include <os/atomic_private.h>
32 #include <kern/assert.h>
33 #include <kern/percpu.h>
34 #include <kern/zalloc.h>
35 #include <kern/lock_group.h>
36 #include <kern/locks.h>
37 #include <kern/misc_protos.h>
38 #include <pexpert/pexpert.h>
39 #include <prng/entropy.h>
40 #include <crypto/entropy/entropy_sysctl.h>
41 #include <machine/machine_routines.h>
42 #include <libkern/section_keywords.h>
43 #include <sys/cdefs.h>
44
45 // The number of samples we can hold in an entropy buffer.
46 #define ENTROPY_MAX_SAMPLE_COUNT (2048)
47
48 // The state for a per-CPU entropy buffer.
49 typedef struct entropy_cpu_data {
50 // A buffer to hold entropy samples.
51 entropy_sample_t samples[ENTROPY_MAX_SAMPLE_COUNT];
52
53 // A count of samples resident in the buffer. It also functions as
54 // an index to the buffer. All entries at indices less than the
55 // sample count are considered valid for consumption by the
56 // reader. The reader resets this to zero after consuming the
57 // available entropy.
58 uint32_t _Atomic sample_count;
59 } entropy_cpu_data_t;
60
61 // This structure holds the state for an instance of a FIPS continuous
62 // health test. In practice, we do not expect these tests to fail.
63 typedef struct entropy_health_test {
64 // The initial sample observed in this test instance. Tests look
65 // for some repetition of the sample, either consecutively or
66 // within a window.
67 entropy_sample_t init_observation;
68
69 // The count of times the initial observation has recurred within
70 // the span of the current test.
71 uint64_t observation_count;
72
73 // The statistics are only relevant for telemetry and parameter
74 // tuning. They do not drive any actual logic in the module.
75 entropy_health_stats_t *stats;
76 } entropy_health_test_t;
77
78 typedef enum health_test_result {
79 health_test_failure,
80 health_test_success
81 } health_test_result_t;
82
83 // Along with various counters and the buffer itself, this includes
84 // the state for two FIPS continuous health tests.
85 typedef struct entropy_data {
86 // State for a SHA256 computation. This is used to accumulate
87 // entropy samples from across all CPUs. It is finalized when
88 // entropy is provided to the consumer of this module.
89 SHA256_CTX sha256_ctx;
90
91 // Since the corecrypto kext is not loaded when this module is
92 // initialized, we cannot initialize the SHA256 state at that
93 // time. Instead, we initialize it lazily during entropy
94 // consumption. This flag tracks whether initialization is
95 // complete.
96 bool sha256_ctx_init;
97
98 // A total count of entropy samples that have passed through this
99 // structure. It is incremented as new samples are accumulated
100 // from the various per-CPU structures. The "current" count of
101 // samples is the difference between this field and the "read"
102 // sample count below (which see).
103 uint64_t total_sample_count;
104
105 // Initially zero, this flag is reset to the current sample count
106 // if and when we fail a health test. We consider the startup
107 // health tests to be complete when the difference between the
108 // total sample count and this field is at least 1024. In other
109 // words, we must accumulate 1024 good samples to demonstrate
110 // viability. We refuse to provide any entropy before that
111 // threshold is reached.
112 uint64_t startup_sample_count;
113
114 // The count of samples from the last time we provided entropy to
115 // the kernel RNG. We use this to compute how many new samples we
116 // have to contribute. This value is also reset to the current
117 // sample count in case of health test failure.
118 uint64_t read_sample_count;
119
120 // The lock group for this structure; see below.
121 lck_grp_t lock_group;
122
123 // This structure accumulates entropy samples from across all CPUs
124 // for a single point of consumption protected by a mutex.
125 lck_mtx_t mutex;
126
127 // State for the Repetition Count Test.
128 entropy_health_test_t repetition_count_test;
129
130 // State for the Adaptive Proportion Test.
131 entropy_health_test_t adaptive_proportion_test;
132 } entropy_data_t;
133
134 static entropy_cpu_data_t PERCPU_DATA(entropy_cpu_data);
135
136 int entropy_health_startup_done;
137 entropy_health_stats_t entropy_health_rct_stats;
138 entropy_health_stats_t entropy_health_apt_stats;
139
140 static entropy_data_t entropy_data = {
141 .repetition_count_test = {
142 .init_observation = -1,
143 .stats = &entropy_health_rct_stats,
144 },
145 .adaptive_proportion_test = {
146 .init_observation = -1,
147 .stats = &entropy_health_apt_stats,
148 },
149 };
150
151 __security_const_late entropy_sample_t *entropy_analysis_buffer;
152 __security_const_late uint32_t entropy_analysis_buffer_size;
153 static __security_const_late uint32_t entropy_analysis_max_sample_count;
154 static uint32_t entropy_analysis_sample_count;
155
156 __startup_func
157 static void
158 entropy_analysis_init(uint32_t sample_count)
159 {
160 entropy_analysis_max_sample_count = sample_count;
161 entropy_analysis_buffer_size = sample_count * sizeof(entropy_sample_t);
162 entropy_analysis_buffer = zalloc_permanent(entropy_analysis_buffer_size, ZALIGN(entropy_sample_t));
163 entropy_analysis_register_sysctls();
164 }
165
166 __startup_func
167 void
168 entropy_init(void)
169 {
170 lck_grp_init(&entropy_data.lock_group, "entropy-data", LCK_GRP_ATTR_NULL);
171 lck_mtx_init(&entropy_data.mutex, &entropy_data.lock_group, LCK_ATTR_NULL);
172
173 // The below path is used only for testing. This boot arg is used
174 // to collect raw entropy samples for offline analysis. The "ebsz"
175 // name is supported only until dependent tools can be updated to
176 // use the more descriptive "entropy-analysis-sample-count".
177 uint32_t sample_count = 0;
178 if (__improbable(PE_parse_boot_argn("entropy-analysis-sample-count", &sample_count, sizeof(sample_count)))) {
179 entropy_analysis_init(sample_count);
180 } else if (__improbable(PE_parse_boot_argn("ebsz", &sample_count, sizeof(sample_count)))) {
181 entropy_analysis_init(sample_count);
182 }
183 }
184
185 void
186 entropy_collect(void)
187 {
188 // This function is called from within the interrupt handler, so
189 // we do not need to disable interrupts.
190
191 entropy_cpu_data_t *e = PERCPU_GET(entropy_cpu_data);
192
193 uint32_t sample_count = os_atomic_load(&e->sample_count, relaxed);
194
195 assert(sample_count <= ENTROPY_MAX_SAMPLE_COUNT);
196
197 // If the buffer is full, we return early without collecting
198 // entropy.
199 if (sample_count == ENTROPY_MAX_SAMPLE_COUNT) {
200 return;
201 }
202
203 e->samples[sample_count] = (entropy_sample_t)ml_get_timebase_entropy();
204
205 // If the consumer has reset the sample count on us, the only
206 // consequence is a dropped sample. We effectively abort the
207 // entropy collection in this case.
208 (void)os_atomic_cmpxchg(&e->sample_count, sample_count, sample_count + 1, release);
209 }
210
211 // For information on the following tests, see NIST SP 800-90B 4
212 // Health Tests. These tests are intended to detect catastrophic
213 // degradations in entropy. As noted in that document:
214 //
215 // > Health tests are expected to raise an alarm in three cases:
216 // > 1. When there is a significant decrease in the entropy of the
217 // > outputs,
218 // > 2. When noise source failures occur, or
219 // > 3. When hardware fails, and implementations do not work
220 // > correctly.
221 //
222 // Each entropy accumulator declines to release entropy until the
223 // startup tests required by NIST are complete. In the event that a
224 // health test does fail, all entropy accumulators are reset and
225 // decline to release further entropy until their startup tests can be
226 // repeated.
227
228 static health_test_result_t
229 add_observation(entropy_health_test_t *t, uint64_t bound)
230 {
231 t->observation_count += 1;
232 t->stats->max_observation_count = MAX(t->stats->max_observation_count, (uint32_t)t->observation_count);
233 if (__improbable(t->observation_count >= bound)) {
234 t->stats->failure_count += 1;
235 return health_test_failure;
236 }
237
238 return health_test_success;
239 }
240
241 static void
242 reset_test(entropy_health_test_t *t, entropy_sample_t observation)
243 {
244 t->stats->reset_count += 1;
245 t->init_observation = observation;
246 t->observation_count = 1;
247 t->stats->max_observation_count = MAX(t->stats->max_observation_count, (uint32_t)t->observation_count);
248 }
249
250 // 4.4.1 Repetition Count Test
251 //
252 // Like the name implies, this test counts consecutive occurrences of
253 // the same value.
254 //
255 // We compute the bound C as:
256 //
257 // A = 2^-128
258 // H = 1
259 // C = 1 + ceil(-log(A, 2) / H) = 129
260 //
261 // With A the acceptable chance of false positive and H a conservative
262 // estimate for the entropy (in bits) of each sample.
263
264 #define REPETITION_COUNT_BOUND (129)
265
266 static health_test_result_t
267 repetition_count_test(entropy_sample_t observation)
268 {
269 entropy_health_test_t *t = &entropy_data.repetition_count_test;
270
271 if (t->init_observation == observation) {
272 return add_observation(t, REPETITION_COUNT_BOUND);
273 } else {
274 reset_test(t, observation);
275 }
276
277 return health_test_success;
278 }
279
280 // 4.4.2 Adaptive Proportion Test
281 //
282 // This test counts occurrences of a value within a window of samples.
283 //
284 // We use a non-binary alphabet, giving us a window size of 512. (In
285 // particular, we consider the least-significant byte of each time
286 // sample.)
287 //
288 // Assuming one bit of entropy, we can compute the binomial cumulative
289 // distribution function over 512 trials in SageMath as:
290 //
291 // k = var('k')
292 // f(x) = sum(binomial(512, k), k, x, 512) / 2^512
293 //
294 // We compute the bound C as the minimal x for which:
295 //
296 // f(x) < 2^-128
297 //
298 // Is true.
299 //
300 // Empirically, we have C = 400.
301
302 #define ADAPTIVE_PROPORTION_BOUND (400)
303 #define ADAPTIVE_PROPORTION_WINDOW (512)
304
305 // This mask definition requires the window be a power of two.
306 static_assert(__builtin_popcount(ADAPTIVE_PROPORTION_WINDOW) == 1);
307 #define ADAPTIVE_PROPORTION_INDEX_MASK (ADAPTIVE_PROPORTION_WINDOW - 1)
308
309 static health_test_result_t
310 adaptive_proportion_test(entropy_sample_t observation, uint32_t offset)
311 {
312 entropy_health_test_t *t = &entropy_data.adaptive_proportion_test;
313
314 // We work in windows of size ADAPTIVE_PROPORTION_WINDOW, so we
315 // can compute our index by taking the entropy buffer's overall
316 // sample count plus the offset of this observation modulo the
317 // window size.
318 uint32_t index = (entropy_data.total_sample_count + offset) & ADAPTIVE_PROPORTION_INDEX_MASK;
319
320 if (index == 0) {
321 reset_test(t, observation);
322 } else if (t->init_observation == observation) {
323 return add_observation(t, ADAPTIVE_PROPORTION_BOUND);
324 }
325
326 return health_test_success;
327 }
328
329 static health_test_result_t
330 entropy_health_test(uint32_t sample_count, entropy_sample_t *samples)
331 {
332 health_test_result_t result = health_test_success;
333
334 for (uint32_t i = 0; i < sample_count; i += 1) {
335 // We only consider the low bits of each sample, since that is
336 // where we expect the entropy to be concentrated.
337 entropy_sample_t observation = samples[i] & 0xff;
338
339 if (__improbable(repetition_count_test(observation) == health_test_failure)) {
340 result = health_test_failure;
341 }
342
343 if (__improbable(adaptive_proportion_test(observation, i) == health_test_failure)) {
344 result = health_test_failure;
345 }
346 }
347
348 return result;
349 }
350
351 static void
352 entropy_analysis_store(uint32_t sample_count, entropy_sample_t *samples)
353 {
354 lck_mtx_assert(&entropy_data.mutex, LCK_MTX_ASSERT_OWNED);
355
356 sample_count = MIN(sample_count, (entropy_analysis_max_sample_count - entropy_analysis_sample_count));
357 if (sample_count == 0) {
358 return;
359 }
360
361 size_t size = sample_count * sizeof(samples[0]);
362 memcpy(&entropy_analysis_buffer[entropy_analysis_sample_count], samples, size);
363 entropy_analysis_sample_count += sample_count;
364 }
365
366 int32_t
367 entropy_provide(size_t *entropy_size, void *entropy, __unused void *arg)
368 {
369 #if (DEVELOPMENT || DEBUG)
370 if (*entropy_size < SHA256_DIGEST_LENGTH) {
371 panic("[entropy_provide] recipient entropy buffer is too small\n");
372 }
373 #endif
374
375 int32_t sample_count = 0;
376 *entropy_size = 0;
377
378 // The first call to this function comes while the corecrypto kext
379 // is being loaded. We require SHA256 to accumulate entropy
380 // samples.
381 if (__improbable(!g_crypto_funcs)) {
382 return sample_count;
383 }
384
385 // There is only one consumer (the kernel PRNG), but they could
386 // try to consume entropy from different threads. We simply fail
387 // if a consumption is already in progress.
388 if (!lck_mtx_try_lock(&entropy_data.mutex)) {
389 return sample_count;
390 }
391
392 // This only happens on the first call to this function. We cannot
393 // perform this initialization in entropy_init because the
394 // corecrypto kext is not loaded yet.
395 if (__improbable(!entropy_data.sha256_ctx_init)) {
396 SHA256_Init(&entropy_data.sha256_ctx);
397 entropy_data.sha256_ctx_init = true;
398 }
399
400 health_test_result_t health_test_result = health_test_success;
401
402 // We accumulate entropy from all CPUs.
403 percpu_foreach(e, entropy_cpu_data) {
404 // On each CPU, the sample count functions as an index into
405 // the entropy buffer. All samples before that index are valid
406 // for consumption.
407 uint32_t cpu_sample_count = os_atomic_load(&e->sample_count, acquire);
408
409 assert(cpu_sample_count <= ENTROPY_MAX_SAMPLE_COUNT);
410
411 // The health test depends in part on the current state of
412 // the entropy data, so we test the new sample before
413 // accumulating it.
414 if (__improbable(entropy_health_test(cpu_sample_count, e->samples) == health_test_failure)) {
415 health_test_result = health_test_failure;
416 }
417
418 // We accumulate the samples regardless of whether the test
419 // failed. It cannot hurt.
420 entropy_data.total_sample_count += cpu_sample_count;
421 SHA256_Update(&entropy_data.sha256_ctx, e->samples, cpu_sample_count * sizeof(e->samples[0]));
422
423 // This code path is only used for testing. Its use is governed by
424 // a boot arg; see its initialization above.
425 if (__improbable(entropy_analysis_buffer)) {
426 entropy_analysis_store(cpu_sample_count, e->samples);
427 }
428
429 // "Drain" the per-CPU buffer by resetting its sample count.
430 os_atomic_store(&e->sample_count, 0, relaxed);
431 }
432
433 // We expect this never to happen.
434 //
435 // But if it does happen, we need to return negative to signal the
436 // consumer (i.e. the kernel PRNG) that there has been a failure.
437 if (__improbable(health_test_result == health_test_failure)) {
438 entropy_health_startup_done = 0;
439 entropy_data.startup_sample_count = entropy_data.total_sample_count;
440 entropy_data.read_sample_count = entropy_data.total_sample_count;
441 sample_count = -1;
442 goto out;
443 }
444
445 // FIPS requires we pass our startup health tests before providing
446 // any entropy. This condition is only true during startup and in
447 // case of reset due to test failure.
448 if (__improbable((entropy_data.total_sample_count - entropy_data.startup_sample_count) < 1024)) {
449 goto out;
450 }
451
452 entropy_health_startup_done = 1;
453
454 // The count of new samples from the consumer's perspective.
455 int32_t n = (int32_t)(entropy_data.total_sample_count - entropy_data.read_sample_count);
456
457 // For performance reasons, we require a small threshold of
458 // samples to have built up before we provide any to the PRNG.
459 if (n < 32) {
460 goto out;
461 }
462
463 SHA256_Final(entropy, &entropy_data.sha256_ctx);
464 SHA256_Init(&entropy_data.sha256_ctx);
465 entropy_data.read_sample_count = entropy_data.total_sample_count;
466
467 sample_count = n;
468 *entropy_size = SHA256_DIGEST_LENGTH;
469
470 out:
471 lck_mtx_unlock(&entropy_data.mutex);
472
473 return sample_count;
474 }