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 #ifndef _PRNG_ENTROPY_H_ 30 #define _PRNG_ENTROPY_H_ 31 32 #include <kern/kern_types.h> 33 #include <kern/bits.h> 34 #include <sys/cdefs.h> 35 36 __BEGIN_DECLS 37 38 // This module is used to accumulate entropy from hardware interrupts 39 // for consumption by a higher-level PRNG. 40 // 41 // The raw entropy samples are collected from CPU counters during 42 // hardware interrupts. We do not perform synchronization before 43 // reading the counter (unlike ml_get_timebase and similar functions). 44 // 45 // This entropy accumulator performs continuous health tests in 46 // accordance with NIST SP 800-90B. The parameters have been chosen 47 // with the expectation that test failures should never occur except 48 // in case of catastrophic hardware failure. 49 50 typedef uint32_t entropy_sample_t; 51 52 // Called during startup to initialize internal data structures. 53 void entropy_init(size_t seed_size, uint8_t *seed); 54 55 // Called during hardware interrupts to collect entropy in per-CPU 56 // structures. 57 void entropy_collect(void); 58 59 // Called by the higher-level PRNG. The module performs continuous 60 // health tests and decides whether to release entropy based on the 61 // values of various counters. Returns negative in case of error 62 // (e.g. health test failure). 63 int32_t entropy_provide(size_t *entropy_size, void *entropy, void *arg); 64 65 // Called internally when entropy_provide() is called or when exporting 66 // analysis entropy with the "kern.entropy.analysis.filter" sysctl. This 67 // function applies a filter to input entropy and returns a bitmap indicating 68 // whether a particular sample is counted. The return value is the count of 69 // samples that passed the filter. "filter" may be NULL in which case only 70 // the number of unfiltered samples that passed the filter will be calculated. 71 // 72 // Each bit in the bitmap_t "filter" indicates whether a sample 73 // is kept (when the bit is set) or filtered (when the bit is not set). 74 // In other words, "bitmap_test(filter, n)" indicates whether 75 // "sample[n]" is kept. 76 uint32_t entropy_filter(uint32_t sample_count, entropy_sample_t *samples, uint32_t filter_count, bitmap_t *filter); 77 78 #if (DEVELOPMENT || DEBUG) 79 #define ENTROPY_ANALYSIS_SUPPORTED 1 80 #else 81 #define ENTROPY_ANALYSIS_SUPPORTED 0 82 #endif 83 84 #define ENTROPY_ANALYSIS_BOOTARG "entropy-analysis-sample-count" 85 86 #if ENTROPY_ANALYSIS_SUPPORTED 87 // Whether analysis is enabled via the "ENTROPY_ANALYSIS_BOOTARG" boot-arg 88 extern int entropy_analysis_enabled; 89 90 // The size (in bytes) of the filter 91 extern uint32_t entropy_analysis_filter_size; 92 93 // The size (in bytes) of the entropy analysis buffer 94 extern uint32_t entropy_analysis_buffer_size; 95 // The maximum number of entropy_sample_t elements in the analysis buffer 96 extern uint32_t entropy_analysis_max_sample_count; 97 98 // The number of entropy_sample_t elements in the analysis buffer 99 extern uint32_t entropy_analysis_sample_count; 100 101 extern entropy_sample_t *entropy_analysis_buffer; 102 #endif // ENTROPY_ANALYSIS_SUPPORTED 103 104 typedef struct entropy_health_stats { 105 // A total count of times the test has been reset with a new 106 // initial observation. This can be thought of as the number of 107 // tests, but note that a single "test" can theoretically accrue 108 // multiple failures. 109 uint32_t reset_count; 110 111 // A total count of failures of this test instance since 112 // boot. Since we do not expect any test failures (ever) in 113 // practice, this counter should always be zero. 114 uint32_t failure_count; 115 116 // The maximum count of times an initial observation has recurred 117 // across all instances of this test. 118 uint32_t max_observation_count; 119 } entropy_health_stats_t; 120 121 extern int entropy_health_startup_done; 122 extern entropy_health_stats_t entropy_health_rct_stats; 123 extern entropy_health_stats_t entropy_health_apt_stats; 124 125 // The total number of samples processed 126 extern uint64_t entropy_filter_total_sample_count; 127 // The number of samples that passed the filter 128 extern uint64_t entropy_filter_accepted_sample_count; 129 // The number of samples that were rejected by the filters 130 extern uint64_t entropy_filter_rejected_sample_count; 131 132 133 __END_DECLS 134 135 #endif /* _PRNG_ENTROPY_H_ */ 136