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 | |