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
20typedef struct ccentropy_ctx ccentropy_ctx_t;
21
22typedef int (*ccentropy_get_seed_fn_t)(ccentropy_ctx_t *ctx,
23 size_t seed_nbytes,
24 void *seed);
25
26typedef 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.
32typedef 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.
49struct 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*/
66int 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*/
86int 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.
93typedef 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*/
112int 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.
120typedef 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*/
145int 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