1 /** 2 * \file hmac_drbg.h 3 * 4 * \brief HMAC_DRBG (NIST SP 800-90A) 5 */ 6 /* 7 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 8 * SPDX-License-Identifier: Apache-2.0 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); you may 11 * not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 * 22 * This file is part of mbed TLS (https://tls.mbed.org) 23 */ 24 #ifndef MBEDTLS_HMAC_DRBG_H 25 #define MBEDTLS_HMAC_DRBG_H 26 27 #include "md.h" 28 29 #if defined(MBEDTLS_THREADING_C) 30 #include "threading.h" 31 #endif 32 33 /* 34 * Error codes 35 */ 36 #define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */ 37 #define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */ 38 #define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */ 39 #define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */ 40 41 /** 42 * \name SECTION: Module settings 43 * 44 * The configuration options you can set for this module are in this section. 45 * Either change them in config.h or define them on the compiler command line. 46 * \{ 47 */ 48 49 #if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) 50 #define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ 51 #endif 52 53 #if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT) 54 #define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ 55 #endif 56 57 #if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST) 58 #define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ 59 #endif 60 61 #if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) 62 #define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ 63 #endif 64 65 /* \} name SECTION: Module settings */ 66 67 #define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ 68 #define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ 69 70 #ifdef __cplusplus 71 extern "C" { 72 #endif 73 74 /** 75 * HMAC_DRBG context. 76 */ 77 typedef struct mbedtls_hmac_drbg_context 78 { 79 /* Working state: the key K is not stored explicitely, 80 * but is implied by the HMAC context */ 81 mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */ 82 unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */ 83 int reseed_counter; /*!< reseed counter */ 84 85 /* Administrative state */ 86 size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ 87 int prediction_resistance; /*!< enable prediction resistance (Automatic 88 reseed before every random generation) */ 89 int reseed_interval; /*!< reseed interval */ 90 91 /* Callbacks */ 92 int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */ 93 void *p_entropy; /*!< context for the entropy function */ 94 95 #if defined(MBEDTLS_THREADING_C) 96 mbedtls_threading_mutex_t mutex; 97 #endif 98 } mbedtls_hmac_drbg_context; 99 100 /** 101 * \brief HMAC_DRBG context initialization 102 * Makes the context ready for mbedtls_hmac_drbg_seed(), 103 * mbedtls_hmac_drbg_seed_buf() or 104 * mbedtls_hmac_drbg_free(). 105 * 106 * \param ctx HMAC_DRBG context to be initialized 107 */ 108 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); 109 110 /** 111 * \brief HMAC_DRBG initial seeding 112 * Seed and setup entropy source for future reseeds. 113 * 114 * \param ctx HMAC_DRBG context to be seeded 115 * \param md_info MD algorithm to use for HMAC_DRBG 116 * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer 117 * length) 118 * \param p_entropy Entropy context 119 * \param custom Personalization data (Device specific identifiers) 120 * (Can be NULL) 121 * \param len Length of personalization data 122 * 123 * \note The "security strength" as defined by NIST is set to: 124 * 128 bits if md_alg is SHA-1, 125 * 192 bits if md_alg is SHA-224, 126 * 256 bits if md_alg is SHA-256 or higher. 127 * Note that SHA-256 is just as efficient as SHA-224. 128 * 129 * \return 0 if successful, or 130 * MBEDTLS_ERR_MD_BAD_INPUT_DATA, or 131 * MBEDTLS_ERR_MD_ALLOC_FAILED, or 132 * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED. 133 */ 134 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, 135 const mbedtls_md_info_t * md_info, 136 int (*f_entropy)(void *, unsigned char *, size_t), 137 void *p_entropy, 138 const unsigned char *custom, 139 size_t len ); 140 141 /** 142 * \brief Initilisation of simpified HMAC_DRBG (never reseeds). 143 * (For use with deterministic ECDSA.) 144 * 145 * \param ctx HMAC_DRBG context to be initialised 146 * \param md_info MD algorithm to use for HMAC_DRBG 147 * \param data Concatenation of entropy string and additional data 148 * \param data_len Length of data in bytes 149 * 150 * \return 0 if successful, or 151 * MBEDTLS_ERR_MD_BAD_INPUT_DATA, or 152 * MBEDTLS_ERR_MD_ALLOC_FAILED. 153 */ 154 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, 155 const mbedtls_md_info_t * md_info, 156 const unsigned char *data, size_t data_len ); 157 158 /** 159 * \brief Enable / disable prediction resistance (Default: Off) 160 * 161 * Note: If enabled, entropy is used for ctx->entropy_len before each call! 162 * Only use this if you have ample supply of good entropy! 163 * 164 * \param ctx HMAC_DRBG context 165 * \param resistance MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF 166 */ 167 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, 168 int resistance ); 169 170 /** 171 * \brief Set the amount of entropy grabbed on each reseed 172 * (Default: given by the security strength, which 173 * depends on the hash used, see \c mbedtls_hmac_drbg_init() ) 174 * 175 * \param ctx HMAC_DRBG context 176 * \param len Amount of entropy to grab, in bytes 177 */ 178 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, 179 size_t len ); 180 181 /** 182 * \brief Set the reseed interval 183 * (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) 184 * 185 * \param ctx HMAC_DRBG context 186 * \param interval Reseed interval 187 */ 188 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, 189 int interval ); 190 191 /** 192 * \brief HMAC_DRBG update state 193 * 194 * \param ctx HMAC_DRBG context 195 * \param additional Additional data to update state with, or NULL 196 * \param add_len Length of additional data, or 0 197 * 198 * \return \c 0 on success, or an error from the underlying 199 * hash calculation. 200 * 201 * \note Additional data is optional, pass NULL and 0 as second 202 * third argument if no additional data is being used. 203 */ 204 int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, 205 const unsigned char *additional, size_t add_len ); 206 207 /** 208 * \brief HMAC_DRBG reseeding (extracts data from entropy source) 209 * 210 * \param ctx HMAC_DRBG context 211 * \param additional Additional data to add to state (Can be NULL) 212 * \param len Length of additional data 213 * 214 * \return 0 if successful, or 215 * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED 216 */ 217 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, 218 const unsigned char *additional, size_t len ); 219 220 /** 221 * \brief HMAC_DRBG generate random with additional update input 222 * 223 * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. 224 * 225 * \param p_rng HMAC_DRBG context 226 * \param output Buffer to fill 227 * \param output_len Length of the buffer 228 * \param additional Additional data to update with (can be NULL) 229 * \param add_len Length of additional data (can be 0) 230 * 231 * \return 0 if successful, or 232 * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or 233 * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or 234 * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG. 235 */ 236 int mbedtls_hmac_drbg_random_with_add( void *p_rng, 237 unsigned char *output, size_t output_len, 238 const unsigned char *additional, 239 size_t add_len ); 240 241 /** 242 * \brief HMAC_DRBG generate random 243 * 244 * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. 245 * 246 * \param p_rng HMAC_DRBG context 247 * \param output Buffer to fill 248 * \param out_len Length of the buffer 249 * 250 * \return 0 if successful, or 251 * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or 252 * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG 253 */ 254 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); 255 256 /** 257 * \brief Free an HMAC_DRBG context 258 * 259 * \param ctx HMAC_DRBG context to free. 260 */ 261 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); 262 263 #if ! defined(MBEDTLS_DEPRECATED_REMOVED) 264 #if defined(MBEDTLS_DEPRECATED_WARNING) 265 #define MBEDTLS_DEPRECATED __attribute__((deprecated)) 266 #else 267 #define MBEDTLS_DEPRECATED 268 #endif 269 /** 270 * \brief HMAC_DRBG update state 271 * 272 * \deprecated Superseded by mbedtls_hmac_drbg_update_ret() 273 * in 2.16.0. 274 * 275 * \param ctx HMAC_DRBG context 276 * \param additional Additional data to update state with, or NULL 277 * \param add_len Length of additional data, or 0 278 * 279 * \note Additional data is optional, pass NULL and 0 as second 280 * third argument if no additional data is being used. 281 */ 282 MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( 283 mbedtls_hmac_drbg_context *ctx, 284 const unsigned char *additional, size_t add_len ); 285 #undef MBEDTLS_DEPRECATED 286 #endif /* !MBEDTLS_DEPRECATED_REMOVED */ 287 288 #if defined(MBEDTLS_FS_IO) 289 /** 290 * \brief Write a seed file 291 * 292 * \param ctx HMAC_DRBG context 293 * \param path Name of the file 294 * 295 * \return 0 if successful, 1 on file error, or 296 * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED 297 */ 298 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); 299 300 /** 301 * \brief Read and update a seed file. Seed is added to this 302 * instance 303 * 304 * \param ctx HMAC_DRBG context 305 * \param path Name of the file 306 * 307 * \return 0 if successful, 1 on file error, 308 * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or 309 * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG 310 */ 311 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); 312 #endif /* MBEDTLS_FS_IO */ 313 314 315 #if defined(MBEDTLS_SELF_TEST) 316 /** 317 * \brief Checkup routine 318 * 319 * \return 0 if successful, or 1 if the test failed 320 */ 321 int mbedtls_hmac_drbg_self_test( int verbose ); 322 #endif 323 324 #ifdef __cplusplus 325 } 326 #endif 327 328 #endif /* hmac_drbg.h */ 329