xref: /xnu-8796.121.2/EXTERNAL_HEADERS/corecrypto/ccrng_schedule.h (revision c54f35ca767986246321eb901baf8f5ff7923f6a)
1 /* Copyright (c) (2021) 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 <stdatomic.h>
17 
18 // Depending on the environment and platform APIs available, different
19 // RNGs will use different reseed strategies. For example, an RNG that
20 // can communicate with its entropy source might check a flag set by
21 // the latter when entropy is available. In another case, the RNG
22 // might poll its entropy source on a time interval. In some cases,
23 // the RNG might always (or never) want to try to reseed.
24 //
25 // This module provides a common interface for such reseed
26 // schedules. It is intended for use as a component by RNG
27 // implementations.
28 
29 typedef enum {
30     CCRNG_SCHEDULE_CONTINUE = 1,
31     CCRNG_SCHEDULE_TRY_RESEED = 2,
32     CCRNG_SCHEDULE_MUST_RESEED = 3,
33 } ccrng_schedule_action_t;
34 
35 CC_INLINE bool
ccrng_schedule_action_is_reseed(ccrng_schedule_action_t action)36 ccrng_schedule_action_is_reseed(ccrng_schedule_action_t action)
37 {
38     return (action == CCRNG_SCHEDULE_TRY_RESEED ||
39             action == CCRNG_SCHEDULE_MUST_RESEED);
40 }
41 
42 typedef enum {
43     CCRNG_SCHEDULE_RESEED_SUCCEEDED = 1,
44     CCRNG_SCHEDULE_RESEED_FAILED = 2,
45 } ccrng_schedule_result_t;
46 
47 typedef struct ccrng_schedule_ctx ccrng_schedule_ctx_t;
48 
49 // The schedule interface provides two function pointers: one to check the
50 // schedule and one to propagate the result of the reseed.
51 typedef struct ccrng_schedule_info {
52     ccrng_schedule_action_t (*read)(ccrng_schedule_ctx_t *ctx);
53     void (*update)(ccrng_schedule_ctx_t *ctx, ccrng_schedule_result_t result);
54 } ccrng_schedule_info_t;
55 
56 struct ccrng_schedule_ctx {
57     const ccrng_schedule_info_t *info;
58 };
59 
60 ccrng_schedule_action_t ccrng_schedule_read(ccrng_schedule_ctx_t *ctx);
61 
62 void ccrng_schedule_update(ccrng_schedule_ctx_t *ctx, ccrng_schedule_result_t update);
63 
64 // This is a concrete schedule implementation where the state of the
65 // entropy source is communicated via a flag. The entropy source can
66 // set the flag with ccrng_schedule_atomic_flag_set to indicate
67 // entropy is available. The flag is cleared automatically on read and
68 // reset if the reseed fails.
69 typedef struct ccrng_schedule_atomic_flag_ctx {
70     ccrng_schedule_ctx_t schedule_ctx;
71     _Atomic ccrng_schedule_action_t flag;
72 } ccrng_schedule_atomic_flag_ctx_t;
73 
74 void ccrng_schedule_atomic_flag_init(ccrng_schedule_atomic_flag_ctx_t *ctx);
75 
76 void ccrng_schedule_atomic_flag_set(ccrng_schedule_atomic_flag_ctx_t *ctx);
77 
78 // This is a concrete schedule implementation that simply always
79 // returns a constant action.
80 typedef struct ccrng_schedule_constant_ctx {
81     ccrng_schedule_ctx_t schedule_ctx;
82     ccrng_schedule_action_t action;
83 } ccrng_schedule_constant_ctx_t;
84 
85 void ccrng_schedule_constant_init(ccrng_schedule_constant_ctx_t *ctx,
86                                   ccrng_schedule_action_t action);
87 
88 typedef struct ccrng_schedule_timer_ctx {
89     ccrng_schedule_ctx_t schedule_ctx;
90     uint64_t (*get_time)(void);
91     uint64_t reseed_interval;
92     uint64_t last_read_time;
93     uint64_t last_reseed_time;
94 } ccrng_schedule_timer_ctx_t;
95 
96 void ccrng_schedule_timer_init(ccrng_schedule_timer_ctx_t *ctx,
97                                uint64_t (*get_time)(void),
98                                uint64_t reseed_interval);
99 
100 #endif /* _CORECRYPTO_CCRNG_SCHEDULE_H_ */
101