1 /* Copyright (c) (2021,2022) Apple Inc. All rights reserved. 2 * 3 * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which 4 * is contained in the License.txt file distributed with corecrypto) and only to 5 * people who accept that license. IMPORTANT: Any license rights granted to you by 6 * Apple Inc. (if any) are limited to internal use within your organization only on 7 * devices and computers you own or control, for the sole purpose of verifying the 8 * security characteristics and correct functioning of the Apple Software. You may 9 * not, directly or indirectly, redistribute the Apple Software or any portions thereof. 10 */ 11 12 #ifndef _CORECRYPTO_CCRNG_SCHEDULE_H_ 13 #define _CORECRYPTO_CCRNG_SCHEDULE_H_ 14 15 #include <corecrypto/cc.h> 16 #include <corecrypto/ccdrbg.h> 17 #include <stdatomic.h> 18 19 // Depending on the environment and platform APIs available, different 20 // RNGs will use different reseed strategies. For example, an RNG that 21 // can communicate with its entropy source might check a flag set by 22 // the latter when entropy is available. In another case, the RNG 23 // might poll its entropy source on a time interval. In some cases, 24 // the RNG might always (or never) want to try to reseed. 25 // 26 // This module provides a common interface for such reseed 27 // schedules. It is intended for use as a component by RNG 28 // implementations. 29 30 typedef enum { 31 CCRNG_SCHEDULE_CONTINUE = 1, 32 CCRNG_SCHEDULE_TRY_RESEED = 2, 33 CCRNG_SCHEDULE_MUST_RESEED = 3, 34 } ccrng_schedule_action_t; 35 36 typedef struct ccrng_schedule_ctx ccrng_schedule_ctx_t; 37 38 // The schedule interface provides two function pointers: one to check 39 // the schedule and one to notify the schedule of a successful reseed. 40 typedef struct ccrng_schedule_info { 41 ccrng_schedule_action_t (*read)(ccrng_schedule_ctx_t *ctx); 42 void (*notify_reseed)(ccrng_schedule_ctx_t *ctx); 43 } ccrng_schedule_info_t; 44 45 struct ccrng_schedule_ctx { 46 const ccrng_schedule_info_t *info; 47 bool must_reseed; 48 }; 49 50 ccrng_schedule_action_t ccrng_schedule_read(ccrng_schedule_ctx_t *ctx); 51 52 void ccrng_schedule_notify_reseed(ccrng_schedule_ctx_t *ctx); 53 54 // This is a concrete schedule implementation where the state of the 55 // entropy source is communicated via a flag. The entropy source can 56 // set the flag with ccrng_schedule_atomic_flag_set to indicate 57 // entropy is available. The flag is cleared automatically on read and 58 // reset if the reseed fails. 59 typedef struct ccrng_schedule_atomic_flag_ctx { 60 ccrng_schedule_ctx_t schedule_ctx; 61 _Atomic ccrng_schedule_action_t flag; 62 } ccrng_schedule_atomic_flag_ctx_t; 63 64 void ccrng_schedule_atomic_flag_init(ccrng_schedule_atomic_flag_ctx_t *ctx); 65 66 void ccrng_schedule_atomic_flag_set(ccrng_schedule_atomic_flag_ctx_t *ctx); 67 68 // This is a concrete schedule implementation that simply always 69 // returns a constant action. 70 typedef struct ccrng_schedule_constant_ctx { 71 ccrng_schedule_ctx_t schedule_ctx; 72 ccrng_schedule_action_t action; 73 } ccrng_schedule_constant_ctx_t; 74 75 void ccrng_schedule_constant_init(ccrng_schedule_constant_ctx_t *ctx, 76 ccrng_schedule_action_t action); 77 78 // This is a concrete schedule implementation that returns "must 79 // reseed" over a given interval of time. 80 typedef struct ccrng_schedule_timer_ctx { 81 ccrng_schedule_ctx_t schedule_ctx; 82 uint64_t (*get_time)(void); 83 uint64_t reseed_interval; 84 uint64_t last_reseed_time; 85 } ccrng_schedule_timer_ctx_t; 86 87 void ccrng_schedule_timer_init(ccrng_schedule_timer_ctx_t *ctx, 88 uint64_t (*get_time)(void), 89 uint64_t reseed_interval); 90 91 // This is a concrete schedule implementation that combines the 92 // results of two constituent sub-schedules. Specifically, it returns 93 // the more "urgent" recommendation between the two. 94 typedef struct ccrng_schedule_tree_ctx { 95 ccrng_schedule_ctx_t schedule_ctx; 96 ccrng_schedule_ctx_t *left; 97 ccrng_schedule_ctx_t *right; 98 } ccrng_schedule_tree_ctx_t; 99 100 void ccrng_schedule_tree_init(ccrng_schedule_tree_ctx_t *ctx, 101 ccrng_schedule_ctx_t *left, 102 ccrng_schedule_ctx_t *right); 103 104 typedef struct ccrng_schedule_drbg_ctx { 105 ccrng_schedule_ctx_t schedule_ctx; 106 const struct ccdrbg_info *drbg_info; 107 struct ccdrbg_state *drbg_ctx; 108 } ccrng_schedule_drbg_ctx_t; 109 110 void ccrng_schedule_drbg_init(ccrng_schedule_drbg_ctx_t *ctx, 111 const struct ccdrbg_info *drbg_info, 112 struct ccdrbg_state *drbg_ctx); 113 114 #endif /* _CORECRYPTO_CCRNG_SCHEDULE_H_ */ 115