• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * \file hmac_drbg.h
3  *
4  * \brief The HMAC_DRBG pseudorandom generator.
5  *
6  * This module implements the HMAC_DRBG pseudorandom generator described
7  * in <em>NIST SP 800-90A: Recommendation for Random Number Generation Using
8  * Deterministic Random Bit Generators</em>.
9  */
10 /*
11  *  Copyright (C) 2006-2019, ARM Limited, All Rights Reserved
12  *  SPDX-License-Identifier: Apache-2.0
13  *
14  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
15  *  not use this file except in compliance with the License.
16  *  You may obtain a copy of the License at
17  *
18  *  http://www.apache.org/licenses/LICENSE-2.0
19  *
20  *  Unless required by applicable law or agreed to in writing, software
21  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
22  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23  *  See the License for the specific language governing permissions and
24  *  limitations under the License.
25  *
26  *  This file is part of mbed TLS (https://tls.mbed.org)
27  */
28 #ifndef MBEDTLS_HMAC_DRBG_H
29 #define MBEDTLS_HMAC_DRBG_H
30 
31 #if !defined(MBEDTLS_CONFIG_FILE)
32 #include "config.h"
33 #else
34 #include MBEDTLS_CONFIG_FILE
35 #endif
36 
37 #include "md.h"
38 
39 #if defined(MBEDTLS_THREADING_C)
40 #include "threading.h"
41 #endif
42 
43 /*
44  * Error codes
45  */
46 #define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG              -0x0003  /**< Too many random requested in single call. */
47 #define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG                -0x0005  /**< Input too large (Entropy + additional). */
48 #define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR                -0x0007  /**< Read/write error in file. */
49 #define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED        -0x0009  /**< The entropy source failed. */
50 
51 /**
52  * \name SECTION: Module settings
53  *
54  * The configuration options you can set for this module are in this section.
55  * Either change them in config.h or define them on the compiler command line.
56  * \{
57  */
58 
59 #if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
60 #define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL   10000   /**< Interval before reseed is performed by default */
61 #endif
62 
63 #if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT)
64 #define MBEDTLS_HMAC_DRBG_MAX_INPUT         256     /**< Maximum number of additional input bytes */
65 #endif
66 
67 #if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST)
68 #define MBEDTLS_HMAC_DRBG_MAX_REQUEST       1024    /**< Maximum number of requested bytes per call */
69 #endif
70 
71 #if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT)
72 #define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT    384     /**< Maximum size of (re)seed buffer */
73 #endif
74 
75 /* \} name SECTION: Module settings */
76 
77 #define MBEDTLS_HMAC_DRBG_PR_OFF   0   /**< No prediction resistance       */
78 #define MBEDTLS_HMAC_DRBG_PR_ON    1   /**< Prediction resistance enabled  */
79 
80 #ifdef __cplusplus
81 extern "C" {
82 #endif
83 
84 /**
85  * HMAC_DRBG context.
86  */
87 typedef struct mbedtls_hmac_drbg_context
88 {
89     /* Working state: the key K is not stored explicitly,
90      * but is implied by the HMAC context */
91     mbedtls_md_context_t md_ctx;                    /*!< HMAC context (inc. K)  */
92     unsigned char V[MBEDTLS_MD_MAX_SIZE];  /*!< V in the spec          */
93     int reseed_counter;                     /*!< reseed counter         */
94 
95     /* Administrative state */
96     size_t entropy_len;         /*!< entropy bytes grabbed on each (re)seed */
97     int prediction_resistance;  /*!< enable prediction resistance (Automatic
98                                      reseed before every random generation) */
99     int reseed_interval;        /*!< reseed interval   */
100 
101     /* Callbacks */
102     int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */
103     void *p_entropy;            /*!< context for the entropy function        */
104 
105 #if defined(MBEDTLS_THREADING_C)
106     mbedtls_threading_mutex_t mutex;
107 #endif
108 } mbedtls_hmac_drbg_context;
109 
110 /**
111  * \brief               HMAC_DRBG context initialization.
112  *
113  * This function makes the context ready for mbedtls_hmac_drbg_seed(),
114  * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
115  *
116  * \param ctx           HMAC_DRBG context to be initialized.
117  */
118 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
119 
120 /**
121  * \brief               HMAC_DRBG initial seeding.
122  *
123  * Set the initial seed and set up the entropy source for future reseeds.
124  *
125  * A typical choice for the \p f_entropy and \p p_entropy parameters is
126  * to use the entropy module:
127  * - \p f_entropy is mbedtls_entropy_func();
128  * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
129  *   with mbedtls_entropy_init() (which registers the platform's default
130  *   entropy sources).
131  *
132  * You can provide a personalization string in addition to the
133  * entropy source, to make this instantiation as unique as possible.
134  *
135  * \note                By default, the security strength as defined by NIST is:
136  *                      - 128 bits if \p md_info is SHA-1;
137  *                      - 192 bits if \p md_info is SHA-224;
138  *                      - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512.
139  *                      Note that SHA-256 is just as efficient as SHA-224.
140  *                      The security strength can be reduced if a smaller
141  *                      entropy length is set with
142  *                      mbedtls_hmac_drbg_set_entropy_len().
143  *
144  * \note                The default entropy length is the security strength
145  *                      (converted from bits to bytes). You can override
146  *                      it by calling mbedtls_hmac_drbg_set_entropy_len().
147  *
148  * \note                During the initial seeding, this function calls
149  *                      the entropy source to obtain a nonce
150  *                      whose length is half the entropy length.
151  *
152  * \param ctx           HMAC_DRBG context to be seeded.
153  * \param md_info       MD algorithm to use for HMAC_DRBG.
154  * \param f_entropy     The entropy callback, taking as arguments the
155  *                      \p p_entropy context, the buffer to fill, and the
156  *                      length of the buffer.
157  *                      \p f_entropy is always called with a length that is
158  *                      less than or equal to the entropy length.
159  * \param p_entropy     The entropy context to pass to \p f_entropy.
160  * \param custom        The personalization string.
161  *                      This can be \c NULL, in which case the personalization
162  *                      string is empty regardless of the value of \p len.
163  * \param len           The length of the personalization string.
164  *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
165  *                      and also at most
166  *                      #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2
167  *                      where \p entropy_len is the entropy length
168  *                      described above.
169  *
170  * \return              \c 0 if successful.
171  * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
172  *                      invalid.
173  * \return              #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
174  *                      memory to allocate context data.
175  * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
176  *                      if the call to \p f_entropy failed.
177  */
178 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
179                     const mbedtls_md_info_t * md_info,
180                     int (*f_entropy)(void *, unsigned char *, size_t),
181                     void *p_entropy,
182                     const unsigned char *custom,
183                     size_t len );
184 
185 /**
186  * \brief               Initilisation of simpified HMAC_DRBG (never reseeds).
187  *
188  * This function is meant for use in algorithms that need a pseudorandom
189  * input such as deterministic ECDSA.
190  *
191  * \param ctx           HMAC_DRBG context to be initialised.
192  * \param md_info       MD algorithm to use for HMAC_DRBG.
193  * \param data          Concatenation of the initial entropy string and
194  *                      the additional data.
195  * \param data_len      Length of \p data in bytes.
196  *
197  * \return              \c 0 if successful. or
198  * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
199  *                      invalid.
200  * \return              #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
201  *                      memory to allocate context data.
202  */
203 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
204                         const mbedtls_md_info_t * md_info,
205                         const unsigned char *data, size_t data_len );
206 
207 /**
208  * \brief               This function turns prediction resistance on or off.
209  *                      The default value is off.
210  *
211  * \note                If enabled, entropy is gathered at the beginning of
212  *                      every call to mbedtls_hmac_drbg_random_with_add()
213  *                      or mbedtls_hmac_drbg_random().
214  *                      Only use this if your entropy source has sufficient
215  *                      throughput.
216  *
217  * \param ctx           The HMAC_DRBG context.
218  * \param resistance    #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF.
219  */
220 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
221                                           int resistance );
222 
223 /**
224  * \brief               This function sets the amount of entropy grabbed on each
225  *                      seed or reseed.
226  *
227  * See the documentation of mbedtls_hmac_drbg_seed() for the default value.
228  *
229  * \param ctx           The HMAC_DRBG context.
230  * \param len           The amount of entropy to grab, in bytes.
231  */
232 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
233                                 size_t len );
234 
235 /**
236  * \brief               Set the reseed interval.
237  *
238  * The reseed interval is the number of calls to mbedtls_hmac_drbg_random()
239  * or mbedtls_hmac_drbg_random_with_add() after which the entropy function
240  * is called again.
241  *
242  * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL.
243  *
244  * \param ctx           The HMAC_DRBG context.
245  * \param interval      The reseed interval.
246  */
247 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
248                                     int interval );
249 
250 /**
251  * \brief               This function updates the state of the HMAC_DRBG context.
252  *
253  * \param ctx           The HMAC_DRBG context.
254  * \param additional    The data to update the state with.
255  *                      If this is \c NULL, there is no additional data.
256  * \param add_len       Length of \p additional in bytes.
257  *                      Unused if \p additional is \c NULL.
258  *
259  * \return              \c 0 on success, or an error from the underlying
260  *                      hash calculation.
261  */
262 int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
263                        const unsigned char *additional, size_t add_len );
264 
265 /**
266  * \brief               This function reseeds the HMAC_DRBG context, that is
267  *                      extracts data from the entropy source.
268  *
269  * \param ctx           The HMAC_DRBG context.
270  * \param additional    Additional data to add to the state.
271  *                      If this is \c NULL, there is no additional data
272  *                      and \p len should be \c 0.
273  * \param len           The length of the additional data.
274  *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
275  *                      and also at most
276  *                      #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len
277  *                      where \p entropy_len is the entropy length
278  *                      (see mbedtls_hmac_drbg_set_entropy_len()).
279  *
280  * \return              \c 0 if successful.
281  * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
282  *                      if a call to the entropy function failed.
283  */
284 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
285                       const unsigned char *additional, size_t len );
286 
287 /**
288  * \brief   This function updates an HMAC_DRBG instance with additional
289  *          data and uses it to generate random data.
290  *
291  * This function automatically reseeds if the reseed counter is exceeded
292  * or prediction resistance is enabled.
293  *
294  * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
295  *                      #mbedtls_hmac_drbg_context structure.
296  * \param output        The buffer to fill.
297  * \param output_len    The length of the buffer in bytes.
298  *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
299  * \param additional    Additional data to update with.
300  *                      If this is \c NULL, there is no additional data
301  *                      and \p add_len should be \c 0.
302  * \param add_len       The length of the additional data.
303  *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT.
304  *
305  * \return              \c 0 if successful.
306  * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
307  *                      if a call to the entropy source failed.
308  * \return              #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
309  *                      \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
310  * \return              #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if
311  *                      \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT.
312  */
313 int mbedtls_hmac_drbg_random_with_add( void *p_rng,
314                                unsigned char *output, size_t output_len,
315                                const unsigned char *additional,
316                                size_t add_len );
317 
318 /**
319  * \brief   This function uses HMAC_DRBG to generate random data.
320  *
321  * This function automatically reseeds if the reseed counter is exceeded
322  * or prediction resistance is enabled.
323  *
324  * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
325  *                      #mbedtls_hmac_drbg_context structure.
326  * \param output        The buffer to fill.
327  * \param out_len       The length of the buffer in bytes.
328  *                      This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
329  *
330  * \return              \c 0 if successful.
331  * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
332  *                      if a call to the entropy source failed.
333  * \return              #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
334  *                      \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
335  */
336 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
337 
338 /**
339  * \brief               Free an HMAC_DRBG context
340  *
341  * \param ctx           The HMAC_DRBG context to free.
342  */
343 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
344 
345 #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
346 #if defined(MBEDTLS_DEPRECATED_WARNING)
347 #define MBEDTLS_DEPRECATED    __attribute__((deprecated))
348 #else
349 #define MBEDTLS_DEPRECATED
350 #endif
351 /**
352  * \brief               This function updates the state of the HMAC_DRBG context.
353  *
354  * \deprecated          Superseded by mbedtls_hmac_drbg_update_ret()
355  *                      in 2.16.0.
356  *
357  * \param ctx           The HMAC_DRBG context.
358  * \param additional    The data to update the state with.
359  *                      If this is \c NULL, there is no additional data.
360  * \param add_len       Length of \p additional in bytes.
361  *                      Unused if \p additional is \c NULL.
362  */
363 MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
364     mbedtls_hmac_drbg_context *ctx,
365     const unsigned char *additional, size_t add_len );
366 #undef MBEDTLS_DEPRECATED
367 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
368 
369 #if defined(MBEDTLS_FS_IO)
370 /**
371  * \brief               This function writes a seed file.
372  *
373  * \param ctx           The HMAC_DRBG context.
374  * \param path          The name of the file.
375  *
376  * \return              \c 0 on success.
377  * \return              #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
378  * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed
379  *                      failure.
380  */
381 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
382 
383 /**
384  * \brief               This function reads and updates a seed file. The seed
385  *                      is added to this instance.
386  *
387  * \param ctx           The HMAC_DRBG context.
388  * \param path          The name of the file.
389  *
390  * \return              \c 0 on success.
391  * \return              #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
392  * \return              #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on
393  *                      reseed failure.
394  * \return              #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing
395  *                      seed file is too large.
396  */
397 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
398 #endif /* MBEDTLS_FS_IO */
399 
400 
401 #if defined(MBEDTLS_SELF_TEST)
402 /**
403  * \brief               The HMAC_DRBG Checkup routine.
404  *
405  * \return              \c 0 if successful.
406  * \return              \c 1 if the test failed.
407  */
408 int mbedtls_hmac_drbg_self_test( int verbose );
409 #endif
410 
411 #ifdef __cplusplus
412 }
413 #endif
414 
415 #endif /* hmac_drbg.h */
416