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