PolarSSL v1.3.7
hmac_drbg.c
Go to the documentation of this file.
1 /*
2  * HMAC_DRBG implementation (NIST SP 800-90)
3  *
4  * Copyright (C) 2014, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 /*
27  * The NIST SP 800-90A DRBGs are described in the following publication.
28  * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
29  * References below are based on rev. 1 (January 2012).
30  */
31 
32 #if !defined(POLARSSL_CONFIG_FILE)
33 #include "polarssl/config.h"
34 #else
35 #include POLARSSL_CONFIG_FILE
36 #endif
37 
38 #if defined(POLARSSL_HMAC_DRBG_C)
39 
40 #include "polarssl/hmac_drbg.h"
41 
42 #if defined(POLARSSL_FS_IO)
43 #include <stdio.h>
44 #endif
45 
46 #if defined(POLARSSL_PLATFORM_C)
47 #include "polarssl/platform.h"
48 #else
49 #define polarssl_printf printf
50 #endif
51 
52 /*
53  * HMAC_DRBG update, using optional additional data (10.1.2.2)
54  */
56  const unsigned char *additional, size_t add_len )
57 {
58  size_t md_len = ctx->md_ctx.md_info->size;
59  unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
60  unsigned char sep[1];
61  unsigned char K[POLARSSL_MD_MAX_SIZE];
62 
63  for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
64  {
65  /* Step 1 or 4 */
66  md_hmac_reset( &ctx->md_ctx );
67  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
68  md_hmac_update( &ctx->md_ctx, sep, 1 );
69  if( rounds == 2 )
70  md_hmac_update( &ctx->md_ctx, additional, add_len );
71  md_hmac_finish( &ctx->md_ctx, K );
72 
73  /* Step 2 or 5 */
74  md_hmac_starts( &ctx->md_ctx, K, md_len );
75  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
76  md_hmac_finish( &ctx->md_ctx, ctx->V );
77  }
78 }
79 
80 /*
81  * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
82  */
84  const md_info_t * md_info,
85  const unsigned char *data, size_t data_len )
86 {
87  int ret;
88 
89  memset( ctx, 0, sizeof( hmac_drbg_context ) );
90 
91  if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
92  return( ret );
93 
94  /*
95  * Set initial working state.
96  * Use the V memory location, which is currently all 0, to initialize the
97  * MD context with an all-zero key. Then set V to its initial value.
98  */
99  md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size );
100  memset( ctx->V, 0x01, md_info->size );
101 
102  hmac_drbg_update( ctx, data, data_len );
103 
104  return( 0 );
105 }
106 
107 /*
108  * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
109  */
111  const unsigned char *additional, size_t len )
112 {
113  unsigned char seed[POLARSSL_HMAC_DRBG_MAX_SEED_INPUT];
114  size_t seedlen;
115 
116  /* III. Check input length */
117  if( len > POLARSSL_HMAC_DRBG_MAX_INPUT ||
119  {
121  }
122 
123  memset( seed, 0, POLARSSL_HMAC_DRBG_MAX_SEED_INPUT );
124 
125  /* IV. Gather entropy_len bytes of entropy for the seed */
126  if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
128 
129  seedlen = ctx->entropy_len;
130 
131  /* 1. Concatenate entropy and additional data if any */
132  if( additional != NULL && len != 0 )
133  {
134  memcpy( seed + seedlen, additional, len );
135  seedlen += len;
136  }
137 
138  /* 2. Update state */
139  hmac_drbg_update( ctx, seed, seedlen );
140 
141  /* 3. Reset reseed_counter */
142  ctx->reseed_counter = 1;
143 
144  /* 4. Done */
145  return( 0 );
146 }
147 
148 /*
149  * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
150  */
152  const md_info_t * md_info,
153  int (*f_entropy)(void *, unsigned char *, size_t),
154  void *p_entropy,
155  const unsigned char *custom,
156  size_t len )
157 {
158  int ret;
159  size_t entropy_len;
160 
161  memset( ctx, 0, sizeof( hmac_drbg_context ) );
162 
163  if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
164  return( ret );
165 
166  /*
167  * Set initial working state.
168  * Use the V memory location, which is currently all 0, to initialize the
169  * MD context with an all-zero key. Then set V to its initial value.
170  */
171  md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size );
172  memset( ctx->V, 0x01, md_info->size );
173 
174  ctx->f_entropy = f_entropy;
175  ctx->p_entropy = p_entropy;
176 
178 
179  /*
180  * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
181  * each hash function, then according to SP800-90A rev1 10.1 table 2,
182  * min_entropy_len (in bits) is security_strength.
183  *
184  * (This also matches the sizes used in the NIST test vectors.)
185  */
186  entropy_len = md_info->size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
187  md_info->size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
188  32; /* better (256+) -> 256 bits */
189 
190  /*
191  * For initialisation, use more entropy to emulate a nonce
192  * (Again, matches test vectors.)
193  */
194  ctx->entropy_len = entropy_len * 3 / 2;
195 
196  if( ( ret = hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
197  return( ret );
198 
199  ctx->entropy_len = entropy_len;
200 
201  return( 0 );
202 }
203 
204 /*
205  * Set prediction resistance
206  */
208  int resistance )
209 {
210  ctx->prediction_resistance = resistance;
211 }
212 
213 /*
214  * Set entropy length grabbed for reseeds
215  */
216 void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, size_t len )
217 {
218  ctx->entropy_len = len;
219 }
220 
221 /*
222  * Set reseed interval
223  */
224 void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, int interval )
225 {
226  ctx->reseed_interval = interval;
227 }
228 
229 /*
230  * HMAC_DRBG random function with optional additional data:
231  * 10.1.2.5 (arabic) + 9.3 (Roman)
232  */
233 int hmac_drbg_random_with_add( void *p_rng,
234  unsigned char *output, size_t out_len,
235  const unsigned char *additional, size_t add_len )
236 {
237  int ret;
238  hmac_drbg_context *ctx = (hmac_drbg_context *) p_rng;
239  size_t md_len = md_get_size( ctx->md_ctx.md_info );
240  size_t left = out_len;
241  unsigned char *out = output;
242 
243  /* II. Check request length */
244  if( out_len > POLARSSL_HMAC_DRBG_MAX_REQUEST )
246 
247  /* III. Check input length */
248  if( add_len > POLARSSL_HMAC_DRBG_MAX_INPUT )
250 
251  /* 1. (aka VII and IX) Check reseed counter and PR */
252  if( ctx->f_entropy != NULL && /* For no-reseeding instances */
254  ctx->reseed_counter > ctx->reseed_interval ) )
255  {
256  if( ( ret = hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
257  return( ret );
258 
259  add_len = 0; /* VII.4 */
260  }
261 
262  /* 2. Use additional data if any */
263  if( additional != NULL && add_len != 0 )
264  hmac_drbg_update( ctx, additional, add_len );
265 
266  /* 3, 4, 5. Generate bytes */
267  while( left != 0 )
268  {
269  size_t use_len = left > md_len ? md_len : left;
270 
271  md_hmac_reset( &ctx->md_ctx );
272  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
273  md_hmac_finish( &ctx->md_ctx, ctx->V );
274 
275  memcpy( out, ctx->V, use_len );
276  out += use_len;
277  left -= use_len;
278  }
279 
280  /* 6. Update */
281  hmac_drbg_update( ctx, additional, add_len );
282 
283  /* 7. Update reseed counter */
284  ctx->reseed_counter++;
285 
286  /* 8. Done */
287  return( 0 );
288 }
289 
290 /*
291  * HMAC_DRBG random function
292  */
293 int hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
294 {
295  return( hmac_drbg_random_with_add( p_rng, output, out_len, NULL, 0 ) );
296 }
297 
298 /*
299  * Free an HMAC_DRBG context
300  */
302 {
303  if( ctx == NULL )
304  return;
305 
306  md_free_ctx( &ctx->md_ctx );
307 
308  memset( ctx, 0, sizeof( hmac_drbg_context ) );
309 }
310 
311 #if defined(POLARSSL_FS_IO)
312 int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path )
313 {
314  int ret;
315  FILE *f;
316  unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ];
317 
318  if( ( f = fopen( path, "wb" ) ) == NULL )
320 
321  if( ( ret = hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
322  goto exit;
323 
324  if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
325  {
327  goto exit;
328  }
329 
330  ret = 0;
331 
332 exit:
333  fclose( f );
334  return( ret );
335 }
336 
337 int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path )
338 {
339  FILE *f;
340  size_t n;
341  unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ];
342 
343  if( ( f = fopen( path, "rb" ) ) == NULL )
345 
346  fseek( f, 0, SEEK_END );
347  n = (size_t) ftell( f );
348  fseek( f, 0, SEEK_SET );
349 
351  {
352  fclose( f );
354  }
355 
356  if( fread( buf, 1, n, f ) != n )
357  {
358  fclose( f );
360  }
361 
362  fclose( f );
363 
364  hmac_drbg_update( ctx, buf, n );
365 
366  return( hmac_drbg_write_seed_file( ctx, path ) );
367 }
368 #endif /* POLARSSL_FS_IO */
369 
370 
371 #if defined(POLARSSL_SELF_TEST)
372 
373 #include <stdio.h>
374 
375 #if !defined(POLARSSL_SHA1_C)
376 /* Dummy checkup routine */
377 int hmac_drbg_self_test( int verbose )
378 {
379 
380  if( verbose != 0 )
381  polarssl_printf( "\n" );
382 
383  return( 0 );
384 }
385 #else
386 
387 #define OUTPUT_LEN 80
388 
389 /* From a NIST PR=true test vector */
390 static unsigned char entropy_pr[] = {
391  0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
392  0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
393  0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
394  0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
395  0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
396 static const unsigned char result_pr[OUTPUT_LEN] = {
397  0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
398  0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
399  0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
400  0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
401  0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
402  0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
403  0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
404 
405 /* From a NIST PR=false test vector */
406 static unsigned char entropy_nopr[] = {
407  0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
408  0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
409  0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
410  0xe9, 0x9d, 0xfe, 0xdf };
411 static const unsigned char result_nopr[OUTPUT_LEN] = {
412  0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
413  0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
414  0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
415  0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
416  0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
417  0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
418  0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
419 
420 /* "Entropy" from buffer */
421 static size_t test_offset;
422 static int hmac_drbg_self_test_entropy( void *data,
423  unsigned char *buf, size_t len )
424 {
425  const unsigned char *p = data;
426  memcpy( buf, p + test_offset, len );
427  test_offset += len;
428  return( 0 );
429 }
430 
431 #define CHK( c ) if( (c) != 0 ) \
432  { \
433  if( verbose != 0 ) \
434  polarssl_printf( "failed\n" ); \
435  return( 1 ); \
436  }
437 
438 /*
439  * Checkup routine for HMAC_DRBG with SHA-1
440  */
441 int hmac_drbg_self_test( int verbose )
442 {
443  hmac_drbg_context ctx;
444  unsigned char buf[OUTPUT_LEN];
445  const md_info_t *md_info = md_info_from_type( POLARSSL_MD_SHA1 );
446 
447  /*
448  * PR = True
449  */
450  if( verbose != 0 )
451  polarssl_printf( " HMAC_DRBG (PR = True) : " );
452 
453  test_offset = 0;
454  CHK( hmac_drbg_init( &ctx, md_info,
455  hmac_drbg_self_test_entropy, entropy_pr,
456  NULL, 0 ) );
458  CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
459  CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
460  CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
461  hmac_drbg_free( &ctx );
462 
463  if( verbose != 0 )
464  polarssl_printf( "passed\n" );
465 
466  /*
467  * PR = False
468  */
469  if( verbose != 0 )
470  polarssl_printf( " HMAC_DRBG (PR = False) : " );
471 
472  test_offset = 0;
473  CHK( hmac_drbg_init( &ctx, md_info,
474  hmac_drbg_self_test_entropy, entropy_nopr,
475  NULL, 0 ) );
476  CHK( hmac_drbg_reseed( &ctx, NULL, 0 ) );
477  CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
478  CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
479  CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
480  hmac_drbg_free( &ctx );
481 
482  if( verbose != 0 )
483  polarssl_printf( "passed\n" );
484 
485  if( verbose != 0 )
486  polarssl_printf( "\n" );
487 
488  return( 0 );
489 }
490 #endif /* POLARSSL_SHA1_C */
491 #endif /* POLARSSL_SELF_TEST */
492 
493 #endif /* POLARSSL_HMAC_DRBG_C */
unsigned char V[POLARSSL_MD_MAX_SIZE]
Definition: hmac_drbg.h:81
#define POLARSSL_HMAC_DRBG_MAX_INPUT
Maximum number of additional input bytes.
Definition: hmac_drbg.h:53
#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL
Interval before reseed is performed by default.
Definition: hmac_drbg.h:49
void hmac_drbg_set_entropy_len(hmac_drbg_context *ctx, size_t len)
Set the amount of entropy grabbed on each reseed (Default: given by the security strength, which depends on the hash used, see hmac_drbg_init() )
int(* f_entropy)(void *, unsigned char *, size_t)
Definition: hmac_drbg.h:91
int hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len)
HMAC_DRBG generate random.
void hmac_drbg_set_reseed_interval(hmac_drbg_context *ctx, int interval)
Set the reseed interval (Default: POLARSSL_HMAC_DRBG_RESEED_INTERVAL)
#define POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
The entropy source failed.
Definition: hmac_drbg.h:38
#define POLARSSL_HMAC_DRBG_MAX_REQUEST
Maximum number of requested bytes per call.
Definition: hmac_drbg.h:57
int md_init_ctx(md_context_t *ctx, const md_info_t *md_info)
Initialises and fills the message digest context structure with the appropriate values.
Configuration options (set of defines)
static unsigned char md_get_size(const md_info_t *md_info)
Returns the size of the message digest output.
Definition: md.h:208
#define POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG
Input too large (Entropy + additional).
Definition: hmac_drbg.h:36
PolarSSL Platform abstraction layer.
#define POLARSSL_HMAC_DRBG_PR_ON
Prediction resistance enabled.
Definition: hmac_drbg.h:67
const md_info_t * md_info
Information about the associated message digest.
Definition: md.h:134
const md_info_t * md_info_from_type(md_type_t md_type)
Returns the message digest information associated with the given digest type.
#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT
Maximum size of (re)seed buffer.
Definition: hmac_drbg.h:61
#define POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR
Read/write error in file.
Definition: hmac_drbg.h:37
int hmac_drbg_reseed(hmac_drbg_context *ctx, const unsigned char *additional, size_t len)
HMAC_DRBG reseeding (extracts data from entropy source)
HMAC_DRBG context.
Definition: hmac_drbg.h:76
void hmac_drbg_free(hmac_drbg_context *ctx)
Free an HMAC_DRBG context.
void * p_entropy
Definition: hmac_drbg.h:92
int md_hmac_starts(md_context_t *ctx, const unsigned char *key, size_t keylen)
Generic HMAC context setup.
void hmac_drbg_set_prediction_resistance(hmac_drbg_context *ctx, int resistance)
Enable / disable prediction resistance (Default: Off)
int md_hmac_reset(md_context_t *ctx)
Generic HMAC context reset.
#define POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG
Too many random requested in single call.
Definition: hmac_drbg.h:35
int hmac_drbg_init(hmac_drbg_context *ctx, const md_info_t *md_info, int(*f_entropy)(void *, unsigned char *, size_t), void *p_entropy, const unsigned char *custom, size_t len)
HMAC_DRBG initialisation.
int md_hmac_update(md_context_t *ctx, const unsigned char *input, size_t ilen)
Generic HMAC process buffer.
#define POLARSSL_MD_MAX_SIZE
Definition: md.h:67
int hmac_drbg_random_with_add(void *p_rng, unsigned char *output, size_t output_len, const unsigned char *additional, size_t add_len)
HMAC_DRBG generate random with additional update input.
md_context_t md_ctx
Definition: hmac_drbg.h:80
#define polarssl_printf
Definition: platform.h:109
int hmac_drbg_init_buf(hmac_drbg_context *ctx, const md_info_t *md_info, const unsigned char *data, size_t data_len)
Initilisation of simpified HMAC_DRBG (never reseeds).
int prediction_resistance
Definition: hmac_drbg.h:86
int size
Output length of the digest function.
Definition: md.h:82
void hmac_drbg_update(hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len)
HMAC_DRBG update state.
size_t entropy_len
Definition: hmac_drbg.h:85
int md_free_ctx(md_context_t *ctx)
Free the message-specific context of ctx.
Message digest information.
Definition: md.h:74
int md_hmac_finish(md_context_t *ctx, unsigned char *output)
Generic HMAC final digest.
HMAC_DRBG (NIST SP 800-90A)