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