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
30typedef enum {
31 CCRNG_SCHEDULE_CONTINUE = 1,
32 CCRNG_SCHEDULE_TRY_RESEED = 2,
33 CCRNG_SCHEDULE_MUST_RESEED = 3,
34} ccrng_schedule_action_t;
35
36typedef 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.
40typedef 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
45struct ccrng_schedule_ctx {
46 const ccrng_schedule_info_t *info;
47 bool must_reseed;
48};
49
50ccrng_schedule_action_t ccrng_schedule_read(ccrng_schedule_ctx_t *ctx);
51
52void 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.
59typedef 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
64void ccrng_schedule_atomic_flag_init(ccrng_schedule_atomic_flag_ctx_t *ctx);
65
66void 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.
70typedef 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
75void 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.
80typedef 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
87void 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.
94typedef 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
100void ccrng_schedule_tree_init(ccrng_schedule_tree_ctx_t *ctx,
101 ccrng_schedule_ctx_t *left,
102 ccrng_schedule_ctx_t *right);
103
104typedef 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
110void 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