xref: /xnu-11417.140.69/EXTERNAL_HEADERS/corecrypto/ccentropy.h (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
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_CCENTROPY_H_
13 #define _CORECRYPTO_CCENTROPY_H_
14 
15 #include <corecrypto/cc.h>
16 #include <corecrypto/ccdigest.h>
17 
18 // An interface to provide high-entropy seeds to RNGs.
19 
20 typedef struct ccentropy_ctx ccentropy_ctx_t;
21 
22 typedef int (*ccentropy_get_seed_fn_t)(ccentropy_ctx_t *ctx,
23                                        size_t seed_nbytes,
24                                        void *seed);
25 
26 typedef int (*ccentropy_add_entropy_fn_t)(ccentropy_ctx_t *ctx,
27                                           uint32_t entropy_nsamples,
28                                           size_t entropy_nbytes,
29                                           const void *entropy);
30 
31 // A descriptor for an entropy implementation.
32 typedef struct ccentropy_info {
33     // This is a required function. Implementations should populate
34     // the seed with a full-entropy output. If they are temporarily
35     // unable due to insufficient entropy, they should return
36     // CCERR_OUT_OF_ENTROPY. If they are permanently unable they
37     // should return some other error (or abort).
38     ccentropy_get_seed_fn_t get_seed;
39 
40     // This is an optional function. The caller will provide a set of
41     // (potentially low-quality) entropy samples, and the
42     // implementation should mix these into its internal
43     // state. Implementations are free to omit this function if it
44     // does not make sense (e.g. see ccentropy_rng below).
45     ccentropy_add_entropy_fn_t add_entropy;
46 } ccentropy_info_t;
47 
48 // Common state for entropy implementations.
49 struct ccentropy_ctx {
50     // A pointer to the descriptor.
51     const ccentropy_info_t *info;
52 };
53 
54 /*!
55   @function ccentropy_get_seed
56   @abstract Get a high-entropy seed.
57 
58   @param ctx The entropy context.
59   @param seed_nbytes The size of the seed requested.
60   @param seed A buffer to receive the seed.
61 
62   @return CCERR_OK on success; CCERR_OUT_OF_ENTROPY if entropy is
63   temporarily unavailable; some implementation-defined error (or
64   abort) otherwise.
65 */
66 int ccentropy_get_seed(ccentropy_ctx_t *ctx,
67                        size_t seed_nbytes,
68                        void *seed);
69 
70 /*!
71   @function ccentropy_add_entropy
72   @abstract Add fresh entropy samples to the context.
73 
74   @param ctx The entropy context.
75   @param entropy_nsamples The count of samples included in this batch.
76   @param entropy_nbytes The size of the entropy payload in bytes.
77   @param entropy A buffer containing the fresh entropy samples.
78 
79   @return CCERR_OK on success; CCERR_NOT_SUPPORTED if this operation
80   is not supported for the implementation; some implementation-defined
81   error (or abort) otherwise.
82 
83   @discussion This operation is optional and will not be supported by
84   all implementations.
85 */
86 int ccentropy_add_entropy(ccentropy_ctx_t *ctx,
87                           uint32_t entropy_nsamples,
88                           size_t entropy_nbytes,
89                           const void *entropy);
90 
91 // A simple wrapper around a ccrng instance. This implementation does
92 // not support the add_entropy interface.
93 typedef struct ccentropy_rng_ctx {
94     ccentropy_ctx_t entropy_ctx;
95     struct ccrng_state *rng_ctx;
96     size_t seed_max_nbytes;
97 } ccentropy_rng_ctx_t;
98 
99 /*!
100   @function ccentropy_rng_init
101   @abstract Wrap a ccrng instance in the ccentropy interface.
102 
103   @param ctx The entropy context.
104   @param rng_ctx The RNG to wrap.
105   @param seed_max_nbytes The maximum seed size that this RNG can provide.
106 
107   @return CCERR_OK on success.
108 
109   @discussion seed_max_nbytes should correspond to the security level
110   of the underlying RNG.
111 */
112 int ccentropy_rng_init(ccentropy_rng_ctx_t *ctx,
113                        struct ccrng_state *rng_ctx,
114                        size_t seed_max_nbytes);
115 
116 // An entropy conditioner based on digest functions. We assume a fixed
117 // per-sample entropy estimate measured in millibits
118 // (i.e. mbits). This estimate should be determined via offline
119 // analysis.
120 typedef struct ccentropy_digest_ctx {
121     ccentropy_ctx_t entropy_ctx;
122     const struct ccdigest_info *digest_info;
123     ccdigest_ctx_decl(MAX_DIGEST_STATE_SIZE,
124                       MAX_DIGEST_BLOCK_SIZE,
125                       digest_ctx);
126     uint32_t entropy_mbits_per_sample;
127     uint32_t entropy_mbits;
128 } ccentropy_digest_ctx_t;
129 
130 #define CCENTROPY_MBITS_PER_BYTE ((uint32_t)(8000))
131 
132 /*!
133   @function ccentropy_digest_init
134   @abstract Initialize a digest-based entropy conditioner.
135 
136   @param ctx The entropy context.
137   @param digest_info A descriptor for the digest.
138   @param entropy_mbits_per_sample An estimate of per-sample entropy measured in millibits.
139 
140   @return CCERR_OK on success.
141 
142   @discussion The estimated entropy per sample should be determined
143   via offline analysis.
144 */
145 int ccentropy_digest_init(struct ccentropy_digest_ctx *ctx,
146                           const struct ccdigest_info *digest_info,
147                           uint32_t entropy_mbits_per_sample);
148 
149 #endif /* _CORECRYPTO_CCENTROPY_H_ */
150