PolarSSL v1.3.8
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 /* Implementation that should never be optimized out by the compiler */
53 static void polarssl_zeroize( void *v, size_t n ) {
54  volatile unsigned char *p = v; while( n-- ) *p++ = 0;
55 }
56 
57 /*
58  * HMAC_DRBG update, using optional additional data (10.1.2.2)
59  */
61  const unsigned char *additional, size_t add_len )
62 {
63  size_t md_len = ctx->md_ctx.md_info->size;
64  unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
65  unsigned char sep[1];
66  unsigned char K[POLARSSL_MD_MAX_SIZE];
67 
68  for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
69  {
70  /* Step 1 or 4 */
71  md_hmac_reset( &ctx->md_ctx );
72  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
73  md_hmac_update( &ctx->md_ctx, sep, 1 );
74  if( rounds == 2 )
75  md_hmac_update( &ctx->md_ctx, additional, add_len );
76  md_hmac_finish( &ctx->md_ctx, K );
77 
78  /* Step 2 or 5 */
79  md_hmac_starts( &ctx->md_ctx, K, md_len );
80  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
81  md_hmac_finish( &ctx->md_ctx, ctx->V );
82  }
83 }
84 
85 /*
86  * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
87  */
89  const md_info_t * md_info,
90  const unsigned char *data, size_t data_len )
91 {
92  int ret;
93 
94  memset( ctx, 0, sizeof( hmac_drbg_context ) );
95 
96  md_init( &ctx->md_ctx );
97 
98  if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
99  return( ret );
100 
101  /*
102  * Set initial working state.
103  * Use the V memory location, which is currently all 0, to initialize the
104  * MD context with an all-zero key. Then set V to its initial value.
105  */
106  md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size );
107  memset( ctx->V, 0x01, md_info->size );
108 
109  hmac_drbg_update( ctx, data, data_len );
110 
111  return( 0 );
112 }
113 
114 /*
115  * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
116  */
118  const unsigned char *additional, size_t len )
119 {
120  unsigned char seed[POLARSSL_HMAC_DRBG_MAX_SEED_INPUT];
121  size_t seedlen;
122 
123  /* III. Check input length */
124  if( len > POLARSSL_HMAC_DRBG_MAX_INPUT ||
126  {
128  }
129 
130  memset( seed, 0, POLARSSL_HMAC_DRBG_MAX_SEED_INPUT );
131 
132  /* IV. Gather entropy_len bytes of entropy for the seed */
133  if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
135 
136  seedlen = ctx->entropy_len;
137 
138  /* 1. Concatenate entropy and additional data if any */
139  if( additional != NULL && len != 0 )
140  {
141  memcpy( seed + seedlen, additional, len );
142  seedlen += len;
143  }
144 
145  /* 2. Update state */
146  hmac_drbg_update( ctx, seed, seedlen );
147 
148  /* 3. Reset reseed_counter */
149  ctx->reseed_counter = 1;
150 
151  /* 4. Done */
152  return( 0 );
153 }
154 
155 /*
156  * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
157  */
159  const md_info_t * md_info,
160  int (*f_entropy)(void *, unsigned char *, size_t),
161  void *p_entropy,
162  const unsigned char *custom,
163  size_t len )
164 {
165  int ret;
166  size_t entropy_len;
167 
168  memset( ctx, 0, sizeof( hmac_drbg_context ) );
169 
170  md_init( &ctx->md_ctx );
171 
172  if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
173  return( ret );
174 
175  /*
176  * Set initial working state.
177  * Use the V memory location, which is currently all 0, to initialize the
178  * MD context with an all-zero key. Then set V to its initial value.
179  */
180  md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size );
181  memset( ctx->V, 0x01, md_info->size );
182 
183  ctx->f_entropy = f_entropy;
184  ctx->p_entropy = p_entropy;
185 
187 
188  /*
189  * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
190  * each hash function, then according to SP800-90A rev1 10.1 table 2,
191  * min_entropy_len (in bits) is security_strength.
192  *
193  * (This also matches the sizes used in the NIST test vectors.)
194  */
195  entropy_len = md_info->size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
196  md_info->size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
197  32; /* better (256+) -> 256 bits */
198 
199  /*
200  * For initialisation, use more entropy to emulate a nonce
201  * (Again, matches test vectors.)
202  */
203  ctx->entropy_len = entropy_len * 3 / 2;
204 
205  if( ( ret = hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
206  return( ret );
207 
208  ctx->entropy_len = entropy_len;
209 
210  return( 0 );
211 }
212 
213 /*
214  * Set prediction resistance
215  */
217  int resistance )
218 {
219  ctx->prediction_resistance = resistance;
220 }
221 
222 /*
223  * Set entropy length grabbed for reseeds
224  */
225 void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, size_t len )
226 {
227  ctx->entropy_len = len;
228 }
229 
230 /*
231  * Set reseed interval
232  */
233 void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, int interval )
234 {
235  ctx->reseed_interval = interval;
236 }
237 
238 /*
239  * HMAC_DRBG random function with optional additional data:
240  * 10.1.2.5 (arabic) + 9.3 (Roman)
241  */
242 int hmac_drbg_random_with_add( void *p_rng,
243  unsigned char *output, size_t out_len,
244  const unsigned char *additional, size_t add_len )
245 {
246  int ret;
247  hmac_drbg_context *ctx = (hmac_drbg_context *) p_rng;
248  size_t md_len = md_get_size( ctx->md_ctx.md_info );
249  size_t left = out_len;
250  unsigned char *out = output;
251 
252  /* II. Check request length */
253  if( out_len > POLARSSL_HMAC_DRBG_MAX_REQUEST )
255 
256  /* III. Check input length */
257  if( add_len > POLARSSL_HMAC_DRBG_MAX_INPUT )
259 
260  /* 1. (aka VII and IX) Check reseed counter and PR */
261  if( ctx->f_entropy != NULL && /* For no-reseeding instances */
263  ctx->reseed_counter > ctx->reseed_interval ) )
264  {
265  if( ( ret = hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
266  return( ret );
267 
268  add_len = 0; /* VII.4 */
269  }
270 
271  /* 2. Use additional data if any */
272  if( additional != NULL && add_len != 0 )
273  hmac_drbg_update( ctx, additional, add_len );
274 
275  /* 3, 4, 5. Generate bytes */
276  while( left != 0 )
277  {
278  size_t use_len = left > md_len ? md_len : left;
279 
280  md_hmac_reset( &ctx->md_ctx );
281  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
282  md_hmac_finish( &ctx->md_ctx, ctx->V );
283 
284  memcpy( out, ctx->V, use_len );
285  out += use_len;
286  left -= use_len;
287  }
288 
289  /* 6. Update */
290  hmac_drbg_update( ctx, additional, add_len );
291 
292  /* 7. Update reseed counter */
293  ctx->reseed_counter++;
294 
295  /* 8. Done */
296  return( 0 );
297 }
298 
299 /*
300  * HMAC_DRBG random function
301  */
302 int hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
303 {
304  return( hmac_drbg_random_with_add( p_rng, output, out_len, NULL, 0 ) );
305 }
306 
307 /*
308  * Free an HMAC_DRBG context
309  */
311 {
312  if( ctx == NULL )
313  return;
314 
315  md_free_ctx( &ctx->md_ctx );
316 
317  polarssl_zeroize( ctx, sizeof( hmac_drbg_context ) );
318 }
319 
320 #if defined(POLARSSL_FS_IO)
321 int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path )
322 {
323  int ret;
324  FILE *f;
325  unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ];
326 
327  if( ( f = fopen( path, "wb" ) ) == NULL )
329 
330  if( ( ret = hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
331  goto exit;
332 
333  if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
334  {
336  goto exit;
337  }
338 
339  ret = 0;
340 
341 exit:
342  fclose( f );
343  return( ret );
344 }
345 
346 int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path )
347 {
348  FILE *f;
349  size_t n;
350  unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ];
351 
352  if( ( f = fopen( path, "rb" ) ) == NULL )
354 
355  fseek( f, 0, SEEK_END );
356  n = (size_t) ftell( f );
357  fseek( f, 0, SEEK_SET );
358 
360  {
361  fclose( f );
363  }
364 
365  if( fread( buf, 1, n, f ) != n )
366  {
367  fclose( f );
369  }
370 
371  fclose( f );
372 
373  hmac_drbg_update( ctx, buf, n );
374 
375  return( hmac_drbg_write_seed_file( ctx, path ) );
376 }
377 #endif /* POLARSSL_FS_IO */
378 
379 
380 #if defined(POLARSSL_SELF_TEST)
381 
382 #include <stdio.h>
383 
384 #if !defined(POLARSSL_SHA1_C)
385 /* Dummy checkup routine */
386 int hmac_drbg_self_test( int verbose )
387 {
388 
389  if( verbose != 0 )
390  polarssl_printf( "\n" );
391 
392  return( 0 );
393 }
394 #else
395 
396 #define OUTPUT_LEN 80
397 
398 /* From a NIST PR=true test vector */
399 static unsigned char entropy_pr[] = {
400  0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
401  0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
402  0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
403  0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
404  0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
405 static const unsigned char result_pr[OUTPUT_LEN] = {
406  0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
407  0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
408  0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
409  0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
410  0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
411  0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
412  0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
413 
414 /* From a NIST PR=false test vector */
415 static unsigned char entropy_nopr[] = {
416  0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
417  0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
418  0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
419  0xe9, 0x9d, 0xfe, 0xdf };
420 static const unsigned char result_nopr[OUTPUT_LEN] = {
421  0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
422  0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
423  0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
424  0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
425  0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
426  0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
427  0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
428 
429 /* "Entropy" from buffer */
430 static size_t test_offset;
431 static int hmac_drbg_self_test_entropy( void *data,
432  unsigned char *buf, size_t len )
433 {
434  const unsigned char *p = data;
435  memcpy( buf, p + test_offset, len );
436  test_offset += len;
437  return( 0 );
438 }
439 
440 #define CHK( c ) if( (c) != 0 ) \
441  { \
442  if( verbose != 0 ) \
443  polarssl_printf( "failed\n" ); \
444  return( 1 ); \
445  }
446 
447 /*
448  * Checkup routine for HMAC_DRBG with SHA-1
449  */
450 int hmac_drbg_self_test( int verbose )
451 {
452  hmac_drbg_context ctx;
453  unsigned char buf[OUTPUT_LEN];
454  const md_info_t *md_info = md_info_from_type( POLARSSL_MD_SHA1 );
455 
456  /*
457  * PR = True
458  */
459  if( verbose != 0 )
460  polarssl_printf( " HMAC_DRBG (PR = True) : " );
461 
462  test_offset = 0;
463  CHK( hmac_drbg_init( &ctx, md_info,
464  hmac_drbg_self_test_entropy, entropy_pr,
465  NULL, 0 ) );
467  CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
468  CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
469  CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
470  hmac_drbg_free( &ctx );
471 
472  if( verbose != 0 )
473  polarssl_printf( "passed\n" );
474 
475  /*
476  * PR = False
477  */
478  if( verbose != 0 )
479  polarssl_printf( " HMAC_DRBG (PR = False) : " );
480 
481  test_offset = 0;
482  CHK( hmac_drbg_init( &ctx, md_info,
483  hmac_drbg_self_test_entropy, entropy_nopr,
484  NULL, 0 ) );
485  CHK( hmac_drbg_reseed( &ctx, NULL, 0 ) );
486  CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
487  CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
488  CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
489  hmac_drbg_free( &ctx );
490 
491  if( verbose != 0 )
492  polarssl_printf( "passed\n" );
493 
494  if( verbose != 0 )
495  polarssl_printf( "\n" );
496 
497  return( 0 );
498 }
499 #endif /* POLARSSL_SHA1_C */
500 #endif /* POLARSSL_SELF_TEST */
501 
502 #endif /* POLARSSL_HMAC_DRBG_C */