1 /** 2 * \file ctr_drbg.h 3 * 4 * \brief CTR_DRBG based on AES-256 (NIST SP 800-90) 5 * 6 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 7 * SPDX-License-Identifier: Apache-2.0 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may 10 * not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 * This file is part of mbed TLS (https://tls.mbed.org) 22 */ 23 #ifndef MBEDTLS_CTR_DRBG_H 24 #define MBEDTLS_CTR_DRBG_H 25 26 #include "aes.h" 27 28 #if defined(MBEDTLS_THREADING_C) 29 #include "mbedtls/threading.h" 30 #endif 31 32 #define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */ 33 #define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */ 34 #define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */ 35 #define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read/write error in file. */ 36 37 #define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< Block size used by the cipher */ 38 #define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< Key size used by the cipher */ 39 #define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) 40 #define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) 41 /**< The seed length (counter + AES key) */ 42 43 /** 44 * \name SECTION: Module settings 45 * 46 * The configuration options you can set for this module are in this section. 47 * Either change them in config.h or define them on the compiler command line. 48 * \{ 49 */ 50 51 #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) 52 #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) 53 #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ 54 #else 55 #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ 56 #endif 57 #endif 58 59 #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) 60 #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ 61 #endif 62 63 #if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT) 64 #define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ 65 #endif 66 67 #if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST) 68 #define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ 69 #endif 70 71 #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) 72 #define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ 73 #endif 74 75 /* \} name SECTION: Module settings */ 76 77 #define MBEDTLS_CTR_DRBG_PR_OFF 0 /**< No prediction resistance */ 78 #define MBEDTLS_CTR_DRBG_PR_ON 1 /**< Prediction resistance enabled */ 79 80 #ifdef __cplusplus 81 extern "C" { 82 #endif 83 84 /** 85 * \brief CTR_DRBG context structure 86 */ 87 typedef struct 88 { 89 unsigned char counter[16]; /*!< counter (V) */ 90 int reseed_counter; /*!< reseed counter */ 91 int prediction_resistance; /*!< enable prediction resistance (Automatic 92 reseed before every random generation) */ 93 size_t entropy_len; /*!< amount of entropy grabbed on each 94 (re)seed */ 95 int reseed_interval; /*!< reseed interval */ 96 97 mbedtls_aes_context aes_ctx; /*!< AES context */ 98 99 /* 100 * Callbacks (Entropy) 101 */ 102 int (*f_entropy)(void *, unsigned char *, size_t); 103 104 void *p_entropy; /*!< context for the entropy function */ 105 106 #if defined(MBEDTLS_THREADING_C) 107 mbedtls_threading_mutex_t mutex; 108 #endif 109 } 110 mbedtls_ctr_drbg_context; 111 112 /** 113 * \brief CTR_DRBG context initialization 114 * Makes the context ready for mbedtls_ctr_drbg_seed() or 115 * mbedtls_ctr_drbg_free(). 116 * 117 * \param ctx CTR_DRBG context to be initialized 118 */ 119 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); 120 121 /** 122 * \brief CTR_DRBG initial seeding 123 * Seed and setup entropy source for future reseeds. 124 * 125 * Note: Personalization data can be provided in addition to the more generic 126 * entropy source to make this instantiation as unique as possible. 127 * 128 * \param ctx CTR_DRBG context to be seeded 129 * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer 130 * length) 131 * \param p_entropy Entropy context 132 * \param custom Personalization data (Device specific identifiers) 133 * (Can be NULL) 134 * \param len Length of personalization data 135 * 136 * \return 0 if successful, or 137 * MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED 138 */ 139 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, 140 int (*f_entropy)(void *, unsigned char *, size_t), 141 void *p_entropy, 142 const unsigned char *custom, 143 size_t len ); 144 145 /** 146 * \brief Clear CTR_CRBG context data 147 * 148 * \param ctx CTR_DRBG context to clear 149 */ 150 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ); 151 152 /** 153 * \brief Enable / disable prediction resistance (Default: Off) 154 * 155 * Note: If enabled, entropy is used for ctx->entropy_len before each call! 156 * Only use this if you have ample supply of good entropy! 157 * 158 * \param ctx CTR_DRBG context 159 * \param resistance MBEDTLS_CTR_DRBG_PR_ON or MBEDTLS_CTR_DRBG_PR_OFF 160 */ 161 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, 162 int resistance ); 163 164 /** 165 * \brief Set the amount of entropy grabbed on each (re)seed 166 * (Default: MBEDTLS_CTR_DRBG_ENTROPY_LEN) 167 * 168 * \param ctx CTR_DRBG context 169 * \param len Amount of entropy to grab 170 */ 171 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, 172 size_t len ); 173 174 /** 175 * \brief Set the reseed interval 176 * (Default: MBEDTLS_CTR_DRBG_RESEED_INTERVAL) 177 * 178 * \param ctx CTR_DRBG context 179 * \param interval Reseed interval 180 */ 181 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, 182 int interval ); 183 184 /** 185 * \brief CTR_DRBG reseeding (extracts data from entropy source) 186 * 187 * \param ctx CTR_DRBG context 188 * \param additional Additional data to add to state (Can be NULL) 189 * \param len Length of additional data 190 * 191 * \return 0 if successful, or 192 * MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED 193 */ 194 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, 195 const unsigned char *additional, size_t len ); 196 197 /** 198 * \brief CTR_DRBG update state 199 * 200 * \param ctx CTR_DRBG context 201 * \param additional Additional data to update state with 202 * \param add_len Length of additional data 203 * 204 * \note If add_len is greater than MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, 205 * only the first MBEDTLS_CTR_DRBG_MAX_SEED_INPUT bytes are used, 206 * the remaining ones are silently discarded. 207 */ 208 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, 209 const unsigned char *additional, size_t add_len ); 210 211 /** 212 * \brief CTR_DRBG generate random with additional update input 213 * 214 * Note: Automatically reseeds if reseed_counter is reached. 215 * 216 * \param p_rng CTR_DRBG context 217 * \param output Buffer to fill 218 * \param output_len Length of the buffer 219 * \param additional Additional data to update with (Can be NULL) 220 * \param add_len Length of additional data 221 * 222 * \return 0 if successful, or 223 * MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or 224 * MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG 225 */ 226 int mbedtls_ctr_drbg_random_with_add( void *p_rng, 227 unsigned char *output, size_t output_len, 228 const unsigned char *additional, size_t add_len ); 229 230 /** 231 * \brief CTR_DRBG generate random 232 * 233 * Note: Automatically reseeds if reseed_counter is reached. 234 * 235 * \param p_rng CTR_DRBG context 236 * \param output Buffer to fill 237 * \param output_len Length of the buffer 238 * 239 * \return 0 if successful, or 240 * MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or 241 * MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG 242 */ 243 int mbedtls_ctr_drbg_random( void *p_rng, 244 unsigned char *output, size_t output_len ); 245 246 #if defined(MBEDTLS_FS_IO) 247 /** 248 * \brief Write a seed file 249 * 250 * \param ctx CTR_DRBG context 251 * \param path Name of the file 252 * 253 * \return 0 if successful, 254 * MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or 255 * MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED 256 */ 257 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); 258 259 /** 260 * \brief Read and update a seed file. Seed is added to this 261 * instance 262 * 263 * \param ctx CTR_DRBG context 264 * \param path Name of the file 265 * 266 * \return 0 if successful, 267 * MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, 268 * MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or 269 * MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG 270 */ 271 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); 272 #endif /* MBEDTLS_FS_IO */ 273 274 /** 275 * \brief Checkup routine 276 * 277 * \return 0 if successful, or 1 if the test failed 278 */ 279 int mbedtls_ctr_drbg_self_test( int verbose ); 280 281 /* Internal functions (do not call directly) */ 282 int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *, 283 int (*)(void *, unsigned char *, size_t), void *, 284 const unsigned char *, size_t, size_t ); 285 286 #ifdef __cplusplus 287 } 288 #endif 289 290 #endif /* ctr_drbg.h */ 291