2 * HMAC_DRBG implementation (NIST SP 800-90)
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
17 * http://www.apache.org/licenses/LICENSE-2.0
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
28 * GNU General Public License v2.0 or later:
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
48 * The NIST SP 800-90A DRBGs are described in the following publication.
49 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
50 * References below are based on rev. 1 (January 2012).
53 #if !defined(MBEDTLS_CONFIG_FILE)
54 #include "mbedtls/config.h"
56 #include MBEDTLS_CONFIG_FILE
59 #if defined(MBEDTLS_HMAC_DRBG_C)
61 #include "mbedtls/hmac_drbg.h"
62 #include "mbedtls/platform_util.h"
66 #if defined(MBEDTLS_FS_IO)
70 #if defined(MBEDTLS_SELF_TEST)
71 #if defined(MBEDTLS_PLATFORM_C)
72 #include "mbedtls/platform.h"
75 #define mbedtls_printf printf
76 #endif /* MBEDTLS_SELF_TEST */
77 #endif /* MBEDTLS_PLATFORM_C */
80 * HMAC_DRBG context initialization
82 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context
*ctx
)
84 memset( ctx
, 0, sizeof( mbedtls_hmac_drbg_context
) );
86 ctx
->reseed_interval
= MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
;
90 * HMAC_DRBG update, using optional additional data (10.1.2.2)
92 int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context
*ctx
,
93 const unsigned char *additional
,
96 size_t md_len
= mbedtls_md_get_size( ctx
->md_ctx
.md_info
);
97 unsigned char rounds
= ( additional
!= NULL
&& add_len
!= 0 ) ? 2 : 1;
99 unsigned char K
[MBEDTLS_MD_MAX_SIZE
];
102 for( sep
[0] = 0; sep
[0] < rounds
; sep
[0]++ )
105 if( ( ret
= mbedtls_md_hmac_reset( &ctx
->md_ctx
) ) != 0 )
107 if( ( ret
= mbedtls_md_hmac_update( &ctx
->md_ctx
,
108 ctx
->V
, md_len
) ) != 0 )
110 if( ( ret
= mbedtls_md_hmac_update( &ctx
->md_ctx
,
115 if( ( ret
= mbedtls_md_hmac_update( &ctx
->md_ctx
,
116 additional
, add_len
) ) != 0 )
119 if( ( ret
= mbedtls_md_hmac_finish( &ctx
->md_ctx
, K
) ) != 0 )
123 if( ( ret
= mbedtls_md_hmac_starts( &ctx
->md_ctx
, K
, md_len
) ) != 0 )
125 if( ( ret
= mbedtls_md_hmac_update( &ctx
->md_ctx
,
126 ctx
->V
, md_len
) ) != 0 )
128 if( ( ret
= mbedtls_md_hmac_finish( &ctx
->md_ctx
, ctx
->V
) ) != 0 )
133 mbedtls_platform_zeroize( K
, sizeof( K
) );
137 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
138 void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context
*ctx
,
139 const unsigned char *additional
,
142 (void) mbedtls_hmac_drbg_update_ret( ctx
, additional
, add_len
);
144 #endif /* MBEDTLS_DEPRECATED_REMOVED */
147 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
149 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context
*ctx
,
150 const mbedtls_md_info_t
* md_info
,
151 const unsigned char *data
, size_t data_len
)
155 if( ( ret
= mbedtls_md_setup( &ctx
->md_ctx
, md_info
, 1 ) ) != 0 )
158 #if defined(MBEDTLS_THREADING_C)
159 mbedtls_mutex_init( &ctx
->mutex
);
163 * Set initial working state.
164 * Use the V memory location, which is currently all 0, to initialize the
165 * MD context with an all-zero key. Then set V to its initial value.
167 if( ( ret
= mbedtls_md_hmac_starts( &ctx
->md_ctx
, ctx
->V
,
168 mbedtls_md_get_size( md_info
) ) ) != 0 )
170 memset( ctx
->V
, 0x01, mbedtls_md_get_size( md_info
) );
172 if( ( ret
= mbedtls_hmac_drbg_update_ret( ctx
, data
, data_len
) ) != 0 )
179 * Internal function used both for seeding and reseeding the DRBG.
180 * Comments starting with arabic numbers refer to section 10.1.2.4
181 * of SP800-90A, while roman numbers refer to section 9.2.
183 static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context
*ctx
,
184 const unsigned char *additional
, size_t len
,
187 unsigned char seed
[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT
];
192 size_t total_entropy_len
;
195 total_entropy_len
= ctx
->entropy_len
;
197 total_entropy_len
= ctx
->entropy_len
* 3 / 2;
199 /* III. Check input length */
200 if( len
> MBEDTLS_HMAC_DRBG_MAX_INPUT
||
201 total_entropy_len
+ len
> MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT
)
203 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
);
207 memset( seed
, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT
);
209 /* IV. Gather entropy_len bytes of entropy for the seed */
210 if( ( ret
= ctx
->f_entropy( ctx
->p_entropy
,
211 seed
, ctx
->entropy_len
) ) != 0 )
213 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
);
215 seedlen
+= ctx
->entropy_len
;
217 /* For initial seeding, allow adding of nonce generated
218 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
221 /* Note: We don't merge the two calls to f_entropy() in order
222 * to avoid requesting too much entropy from f_entropy()
223 * at once. Specifically, if the underlying digest is not
224 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
225 * is larger than the maximum of 32 Bytes that our own
226 * entropy source implementation can emit in a single
227 * call in configurations disabling SHA-512. */
228 if( ( ret
= ctx
->f_entropy( ctx
->p_entropy
,
230 ctx
->entropy_len
/ 2 ) ) != 0 )
232 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
);
235 seedlen
+= ctx
->entropy_len
/ 2;
239 /* 1. Concatenate entropy and additional data if any */
240 if( additional
!= NULL
&& len
!= 0 )
242 memcpy( seed
+ seedlen
, additional
, len
);
246 /* 2. Update state */
247 if( ( ret
= mbedtls_hmac_drbg_update_ret( ctx
, seed
, seedlen
) ) != 0 )
250 /* 3. Reset reseed_counter */
251 ctx
->reseed_counter
= 1;
255 mbedtls_platform_zeroize( seed
, seedlen
);
260 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
262 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context
*ctx
,
263 const unsigned char *additional
, size_t len
)
265 return( hmac_drbg_reseed_core( ctx
, additional
, len
, 0 ) );
269 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
271 * The nonce is not passed as a separate parameter but extracted
272 * from the entropy source as suggested in 8.6.7.
274 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context
*ctx
,
275 const mbedtls_md_info_t
* md_info
,
276 int (*f_entropy
)(void *, unsigned char *, size_t),
278 const unsigned char *custom
,
284 if( ( ret
= mbedtls_md_setup( &ctx
->md_ctx
, md_info
, 1 ) ) != 0 )
287 /* The mutex is initialized iff the md context is set up. */
288 #if defined(MBEDTLS_THREADING_C)
289 mbedtls_mutex_init( &ctx
->mutex
);
292 md_size
= mbedtls_md_get_size( md_info
);
295 * Set initial working state.
296 * Use the V memory location, which is currently all 0, to initialize the
297 * MD context with an all-zero key. Then set V to its initial value.
299 if( ( ret
= mbedtls_md_hmac_starts( &ctx
->md_ctx
, ctx
->V
, md_size
) ) != 0 )
301 memset( ctx
->V
, 0x01, md_size
);
303 ctx
->f_entropy
= f_entropy
;
304 ctx
->p_entropy
= p_entropy
;
306 if( ctx
->entropy_len
== 0 )
309 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
310 * each hash function, then according to SP800-90A rev1 10.1 table 2,
311 * min_entropy_len (in bits) is security_strength.
313 * (This also matches the sizes used in the NIST test vectors.)
315 ctx
->entropy_len
= md_size
<= 20 ? 16 : /* 160-bits hash -> 128 bits */
316 md_size
<= 28 ? 24 : /* 224-bits hash -> 192 bits */
317 32; /* better (256+) -> 256 bits */
320 if( ( ret
= hmac_drbg_reseed_core( ctx
, custom
, len
,
321 1 /* add nonce */ ) ) != 0 )
330 * Set prediction resistance
332 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context
*ctx
,
335 ctx
->prediction_resistance
= resistance
;
339 * Set entropy length grabbed for seeding
341 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context
*ctx
, size_t len
)
343 ctx
->entropy_len
= len
;
347 * Set reseed interval
349 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context
*ctx
, int interval
)
351 ctx
->reseed_interval
= interval
;
355 * HMAC_DRBG random function with optional additional data:
356 * 10.1.2.5 (arabic) + 9.3 (Roman)
358 int mbedtls_hmac_drbg_random_with_add( void *p_rng
,
359 unsigned char *output
, size_t out_len
,
360 const unsigned char *additional
, size_t add_len
)
363 mbedtls_hmac_drbg_context
*ctx
= (mbedtls_hmac_drbg_context
*) p_rng
;
364 size_t md_len
= mbedtls_md_get_size( ctx
->md_ctx
.md_info
);
365 size_t left
= out_len
;
366 unsigned char *out
= output
;
368 /* II. Check request length */
369 if( out_len
> MBEDTLS_HMAC_DRBG_MAX_REQUEST
)
370 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG
);
372 /* III. Check input length */
373 if( add_len
> MBEDTLS_HMAC_DRBG_MAX_INPUT
)
374 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
);
376 /* 1. (aka VII and IX) Check reseed counter and PR */
377 if( ctx
->f_entropy
!= NULL
&& /* For no-reseeding instances */
378 ( ctx
->prediction_resistance
== MBEDTLS_HMAC_DRBG_PR_ON
||
379 ctx
->reseed_counter
> ctx
->reseed_interval
) )
381 if( ( ret
= mbedtls_hmac_drbg_reseed( ctx
, additional
, add_len
) ) != 0 )
384 add_len
= 0; /* VII.4 */
387 /* 2. Use additional data if any */
388 if( additional
!= NULL
&& add_len
!= 0 )
390 if( ( ret
= mbedtls_hmac_drbg_update_ret( ctx
,
391 additional
, add_len
) ) != 0 )
395 /* 3, 4, 5. Generate bytes */
398 size_t use_len
= left
> md_len
? md_len
: left
;
400 if( ( ret
= mbedtls_md_hmac_reset( &ctx
->md_ctx
) ) != 0 )
402 if( ( ret
= mbedtls_md_hmac_update( &ctx
->md_ctx
,
403 ctx
->V
, md_len
) ) != 0 )
405 if( ( ret
= mbedtls_md_hmac_finish( &ctx
->md_ctx
, ctx
->V
) ) != 0 )
408 memcpy( out
, ctx
->V
, use_len
);
414 if( ( ret
= mbedtls_hmac_drbg_update_ret( ctx
,
415 additional
, add_len
) ) != 0 )
418 /* 7. Update reseed counter */
419 ctx
->reseed_counter
++;
427 * HMAC_DRBG random function
429 int mbedtls_hmac_drbg_random( void *p_rng
, unsigned char *output
, size_t out_len
)
432 mbedtls_hmac_drbg_context
*ctx
= (mbedtls_hmac_drbg_context
*) p_rng
;
434 #if defined(MBEDTLS_THREADING_C)
435 if( ( ret
= mbedtls_mutex_lock( &ctx
->mutex
) ) != 0 )
439 ret
= mbedtls_hmac_drbg_random_with_add( ctx
, output
, out_len
, NULL
, 0 );
441 #if defined(MBEDTLS_THREADING_C)
442 if( mbedtls_mutex_unlock( &ctx
->mutex
) != 0 )
443 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
450 * This function resets HMAC_DRBG context to the state immediately
451 * after initial call of mbedtls_hmac_drbg_init().
453 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context
*ctx
)
458 #if defined(MBEDTLS_THREADING_C)
459 /* The mutex is initialized iff the md context is set up. */
460 if( ctx
->md_ctx
.md_info
!= NULL
)
461 mbedtls_mutex_free( &ctx
->mutex
);
463 mbedtls_md_free( &ctx
->md_ctx
);
464 mbedtls_platform_zeroize( ctx
, sizeof( mbedtls_hmac_drbg_context
) );
465 ctx
->reseed_interval
= MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
;
468 #if defined(MBEDTLS_FS_IO)
469 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context
*ctx
, const char *path
)
473 unsigned char buf
[ MBEDTLS_HMAC_DRBG_MAX_INPUT
];
475 if( ( f
= fopen( path
, "wb" ) ) == NULL
)
476 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR
);
478 if( ( ret
= mbedtls_hmac_drbg_random( ctx
, buf
, sizeof( buf
) ) ) != 0 )
481 if( fwrite( buf
, 1, sizeof( buf
), f
) != sizeof( buf
) )
483 ret
= MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR
;
491 mbedtls_platform_zeroize( buf
, sizeof( buf
) );
496 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context
*ctx
, const char *path
)
501 unsigned char buf
[ MBEDTLS_HMAC_DRBG_MAX_INPUT
];
504 if( ( f
= fopen( path
, "rb" ) ) == NULL
)
505 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR
);
507 n
= fread( buf
, 1, sizeof( buf
), f
);
508 if( fread( &c
, 1, 1, f
) != 0 )
510 ret
= MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
;
513 if( n
== 0 || ferror( f
) )
515 ret
= MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR
;
521 ret
= mbedtls_hmac_drbg_update_ret( ctx
, buf
, n
);
524 mbedtls_platform_zeroize( buf
, sizeof( buf
) );
529 return( mbedtls_hmac_drbg_write_seed_file( ctx
, path
) );
531 #endif /* MBEDTLS_FS_IO */
534 #if defined(MBEDTLS_SELF_TEST)
536 #if !defined(MBEDTLS_SHA1_C)
537 /* Dummy checkup routine */
538 int mbedtls_hmac_drbg_self_test( int verbose
)
545 #define OUTPUT_LEN 80
547 /* From a NIST PR=true test vector */
548 static const unsigned char entropy_pr
[] = {
549 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
550 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
551 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
552 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
553 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
554 static const unsigned char result_pr
[OUTPUT_LEN
] = {
555 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
556 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
557 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
558 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
559 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
560 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
561 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
563 /* From a NIST PR=false test vector */
564 static const unsigned char entropy_nopr
[] = {
565 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
566 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
567 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
568 0xe9, 0x9d, 0xfe, 0xdf };
569 static const unsigned char result_nopr
[OUTPUT_LEN
] = {
570 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
571 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
572 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
573 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
574 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
575 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
576 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
578 /* "Entropy" from buffer */
579 static size_t test_offset
;
580 static int hmac_drbg_self_test_entropy( void *data
,
581 unsigned char *buf
, size_t len
)
583 const unsigned char *p
= data
;
584 memcpy( buf
, p
+ test_offset
, len
);
589 #define CHK( c ) if( (c) != 0 ) \
592 mbedtls_printf( "failed\n" ); \
597 * Checkup routine for HMAC_DRBG with SHA-1
599 int mbedtls_hmac_drbg_self_test( int verbose
)
601 mbedtls_hmac_drbg_context ctx
;
602 unsigned char buf
[OUTPUT_LEN
];
603 const mbedtls_md_info_t
*md_info
= mbedtls_md_info_from_type( MBEDTLS_MD_SHA1
);
605 mbedtls_hmac_drbg_init( &ctx
);
611 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
614 CHK( mbedtls_hmac_drbg_seed( &ctx
, md_info
,
615 hmac_drbg_self_test_entropy
, (void *) entropy_pr
,
617 mbedtls_hmac_drbg_set_prediction_resistance( &ctx
, MBEDTLS_HMAC_DRBG_PR_ON
);
618 CHK( mbedtls_hmac_drbg_random( &ctx
, buf
, OUTPUT_LEN
) );
619 CHK( mbedtls_hmac_drbg_random( &ctx
, buf
, OUTPUT_LEN
) );
620 CHK( memcmp( buf
, result_pr
, OUTPUT_LEN
) );
621 mbedtls_hmac_drbg_free( &ctx
);
623 mbedtls_hmac_drbg_free( &ctx
);
626 mbedtls_printf( "passed\n" );
632 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
634 mbedtls_hmac_drbg_init( &ctx
);
637 CHK( mbedtls_hmac_drbg_seed( &ctx
, md_info
,
638 hmac_drbg_self_test_entropy
, (void *) entropy_nopr
,
640 CHK( mbedtls_hmac_drbg_reseed( &ctx
, NULL
, 0 ) );
641 CHK( mbedtls_hmac_drbg_random( &ctx
, buf
, OUTPUT_LEN
) );
642 CHK( mbedtls_hmac_drbg_random( &ctx
, buf
, OUTPUT_LEN
) );
643 CHK( memcmp( buf
, result_nopr
, OUTPUT_LEN
) );
644 mbedtls_hmac_drbg_free( &ctx
);
646 mbedtls_hmac_drbg_free( &ctx
);
649 mbedtls_printf( "passed\n" );
652 mbedtls_printf( "\n" );
656 #endif /* MBEDTLS_SHA1_C */
657 #endif /* MBEDTLS_SELF_TEST */
659 #endif /* MBEDTLS_HMAC_DRBG_C */