0de8e387 |
1 | /** |
2 | * \file hmac_drbg.h |
3 | * |
4 | * \brief HMAC_DRBG (NIST SP 800-90A) |
5 | * |
6 | * Copyright (C) 2014, ARM Limited, All Rights Reserved |
7 | * |
8 | * This file is part of mbed TLS (https://tls.mbed.org) |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. |
14 | * |
15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. |
19 | * |
20 | * You should have received a copy of the GNU General Public License along |
21 | * with this program; if not, write to the Free Software Foundation, Inc., |
22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
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 "mbedtls/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 |
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 mbetls_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 | * \note Additional data is optional, pass NULL and 0 as second |
199 | * third argument if no additional data is being used. |
200 | */ |
201 | void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, |
202 | const unsigned char *additional, size_t add_len ); |
203 | |
204 | /** |
205 | * \brief HMAC_DRBG reseeding (extracts data from entropy source) |
206 | * |
207 | * \param ctx HMAC_DRBG context |
208 | * \param additional Additional data to add to state (Can be NULL) |
209 | * \param len Length of additional data |
210 | * |
211 | * \return 0 if successful, or |
212 | * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED |
213 | */ |
214 | int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, |
215 | const unsigned char *additional, size_t len ); |
216 | |
217 | /** |
218 | * \brief HMAC_DRBG generate random with additional update input |
219 | * |
220 | * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. |
221 | * |
222 | * \param p_rng HMAC_DRBG context |
223 | * \param output Buffer to fill |
224 | * \param output_len Length of the buffer |
225 | * \param additional Additional data to update with (can be NULL) |
226 | * \param add_len Length of additional data (can be 0) |
227 | * |
228 | * \return 0 if successful, or |
229 | * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or |
230 | * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or |
231 | * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG. |
232 | */ |
233 | int mbedtls_hmac_drbg_random_with_add( void *p_rng, |
234 | unsigned char *output, size_t output_len, |
235 | const unsigned char *additional, |
236 | size_t add_len ); |
237 | |
238 | /** |
239 | * \brief HMAC_DRBG generate random |
240 | * |
241 | * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. |
242 | * |
243 | * \param p_rng HMAC_DRBG context |
244 | * \param output Buffer to fill |
245 | * \param out_len Length of the buffer |
246 | * |
247 | * \return 0 if successful, or |
248 | * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or |
249 | * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG |
250 | */ |
251 | int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); |
252 | |
253 | /** |
254 | * \brief Free an HMAC_DRBG context |
255 | * |
256 | * \param ctx HMAC_DRBG context to free. |
257 | */ |
258 | void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); |
259 | |
260 | #if defined(MBEDTLS_FS_IO) |
261 | /** |
262 | * \brief Write a seed file |
263 | * |
264 | * \param ctx HMAC_DRBG context |
265 | * \param path Name of the file |
266 | * |
267 | * \return 0 if successful, 1 on file error, or |
268 | * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED |
269 | */ |
270 | int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); |
271 | |
272 | /** |
273 | * \brief Read and update a seed file. Seed is added to this |
274 | * instance |
275 | * |
276 | * \param ctx HMAC_DRBG context |
277 | * \param path Name of the file |
278 | * |
279 | * \return 0 if successful, 1 on file error, |
280 | * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or |
281 | * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG |
282 | */ |
283 | int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); |
284 | #endif /* MBEDTLS_FS_IO */ |
285 | |
286 | |
287 | #if defined(MBEDTLS_SELF_TEST) |
288 | /** |
289 | * \brief Checkup routine |
290 | * |
291 | * \return 0 if successful, or 1 if the test failed |
292 | */ |
293 | int mbedtls_hmac_drbg_self_test( int verbose ); |
294 | #endif |
295 | |
296 | #ifdef __cplusplus |
297 | } |
298 | #endif |
299 | |
300 | #endif /* hmac_drbg.h */ |