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