blob: f186b5c8ef30b772773516bf73f2859010d19835 [file] [log] [blame]
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01001/*
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/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010027 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010028 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010029 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010030 */
31
32#include "polarssl/config.h"
33
34#if defined(POLARSSL_HMAC_DRBG_C)
35
36#include "polarssl/hmac_drbg.h"
37
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010038#if defined(POLARSSL_FS_IO)
39#include <stdio.h>
40#endif
41
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010042/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010043 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010044 */
45void hmac_drbg_update( hmac_drbg_context *ctx,
46 const unsigned char *additional, size_t add_len )
47{
48 size_t md_len = ctx->md_ctx.md_info->size;
49 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
50 unsigned char sep[1];
51
52 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
53 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010054 /* Step 1 or 4 */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010055 md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
56 md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
57 md_hmac_update( &ctx->md_ctx, sep, 1 );
58 if( rounds == 2 )
59 md_hmac_update( &ctx->md_ctx, additional, add_len );
60 md_hmac_finish( &ctx->md_ctx, ctx->K );
61
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010062 /* Step 2 or 5 */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010063 md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
64 md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
65 md_hmac_finish( &ctx->md_ctx, ctx->V );
66 }
67}
68
69/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +010070 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010071 */
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +010072int hmac_drbg_init_buf( hmac_drbg_context *ctx,
73 const md_info_t * md_info,
74 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010075{
76 int ret;
77
78 memset( ctx, 0, sizeof( hmac_drbg_context ) );
79
80 if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
81 return( ret );
82
83 memset( ctx->V, 0x01, md_info->size );
84 /* ctx->K is already 0 */
85
86 hmac_drbg_update( ctx, data, data_len );
87
88 return( 0 );
89}
90
91/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +010092 * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +010093 */
94int hmac_drbg_reseed( hmac_drbg_context *ctx,
95 const unsigned char *additional, size_t len )
96{
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +010097 unsigned char seed[POLARSSL_HMAC_DRBG_MAX_SEED_INPUT];
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +010098 size_t seedlen;
99
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100100 /* III. Check input length */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100101 if( len > POLARSSL_HMAC_DRBG_MAX_INPUT ||
102 ctx->entropy_len + len > POLARSSL_HMAC_DRBG_MAX_SEED_INPUT )
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100103 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100104 return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100105 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100106
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100107 memset( seed, 0, POLARSSL_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100108
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100109 /* IV. Gather entropy_len bytes of entropy for the seed */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100110 if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
111 return( POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
112
113 seedlen = ctx->entropy_len;
114
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100115 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100116 if( additional != NULL && len != 0 )
117 {
118 memcpy( seed + seedlen, additional, len );
119 seedlen += len;
120 }
121
122 /* 2. Update state */
123 hmac_drbg_update( ctx, seed, seedlen );
124
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100125 /* 3. Reset reseed_counter */
126 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100127
128 /* 4. Done */
129 return( 0 );
130}
131
132/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100133 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100134 */
135int hmac_drbg_init( hmac_drbg_context *ctx,
136 const md_info_t * md_info,
137 int (*f_entropy)(void *, unsigned char *, size_t),
138 void *p_entropy,
139 const unsigned char *custom,
140 size_t len )
141{
142 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100143 size_t entropy_len;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100144
145 memset( ctx, 0, sizeof( hmac_drbg_context ) );
146
147 if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
148 return( ret );
149
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100150 /* Set initial working state */
151 memset( ctx->V, 0x01, md_info->size );
152 /* ctx->K is already 0 */
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100153
154 ctx->f_entropy = f_entropy;
155 ctx->p_entropy = p_entropy;
156
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100157 ctx->reseed_interval = POLARSSL_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100158
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100159 /*
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100160 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
161 * each hash function, then according to SP800-90A rev1 10.1 table 2,
162 * min_entropy_len (in bits) is security_strength.
163 *
164 * (This also matches the sizes used in the NIST test vectors.)
165 */
166 entropy_len = md_info->size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
167 md_info->size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
168 32; /* better (256+) -> 256 bits */
169
170 /*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100171 * For initialisation, use more entropy to emulate a nonce
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100172 * (Again, matches test vectors.)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100173 */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100174 ctx->entropy_len = entropy_len * 3 / 2;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100175
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100176 if( ( ret = hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
177 return( ret );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100178
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100179 ctx->entropy_len = entropy_len;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100180
181 return( 0 );
182}
183
184/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100185 * Set prediction resistance
186 */
187void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx,
188 int resistance )
189{
190 ctx->prediction_resistance = resistance;
191}
192
193/*
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100194 * Set entropy length grabbed for reseeds
195 */
196void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, size_t len )
197{
198 ctx->entropy_len = len;
199}
200
201/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100202 * Set reseed interval
203 */
204void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, int interval )
205{
206 ctx->reseed_interval = interval;
207}
208
209/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100210 * HMAC_DRBG random function with optional additional data:
211 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100212 */
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100213int hmac_drbg_random_with_add( void *p_rng,
214 unsigned char *output, size_t out_len,
215 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100216{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100217 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100218 hmac_drbg_context *ctx = (hmac_drbg_context *) p_rng;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100219 size_t md_len = md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100220 size_t left = out_len;
221 unsigned char *out = output;
222
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100223 /* II. Check request length */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100224 if( out_len > POLARSSL_HMAC_DRBG_MAX_REQUEST )
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100225 return( POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
226
227 /* III. Check input length */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100228 if( add_len > POLARSSL_HMAC_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100229 return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG );
230
231 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100232 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
233 ( ctx->prediction_resistance == POLARSSL_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100234 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100235 {
236 if( ( ret = hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
237 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100238
239 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100240 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100241
242 /* 2. Use additional data if any */
243 if( additional != NULL && add_len != 0 )
244 hmac_drbg_update( ctx, additional, add_len );
245
246 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100247 while( left != 0 )
248 {
249 size_t use_len = left > md_len ? md_len : left;
250
Manuel Pégourié-Gonnardd742a032014-01-30 19:07:22 +0100251 md_hmac_reset( &ctx->md_ctx );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100252 md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
253 md_hmac_finish( &ctx->md_ctx, ctx->V );
254
255 memcpy( out, ctx->V, use_len );
256 out += use_len;
257 left -= use_len;
258 }
259
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100260 /* 6. Update */
261 hmac_drbg_update( ctx, additional, add_len );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100262
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100263 /* 7. Update reseed counter */
264 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100265
266 /* 8. Done */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100267 return( 0 );
268}
269
270/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100271 * HMAC_DRBG random function
272 */
273int hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
274{
275 return( hmac_drbg_random_with_add( p_rng, output, out_len, NULL, 0 ) );
276}
277
278/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100279 * Free an HMAC_DRBG context
280 */
281void hmac_drbg_free( hmac_drbg_context *ctx )
282{
283 if( ctx == NULL )
284 return;
285
286 md_free_ctx( &ctx->md_ctx );
287
288 memset( ctx, 0, sizeof( hmac_drbg_context ) );
289}
290
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100291#if defined(POLARSSL_FS_IO)
292int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path )
293{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100294 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100295 FILE *f;
296 unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ];
297
298 if( ( f = fopen( path, "wb" ) ) == NULL )
299 return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR );
300
301 if( ( ret = hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
302 goto exit;
303
304 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
305 {
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100306 ret = POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR; /* LCOV_EXCL_LINE */
307 goto exit; /* LCOV_EXCL_LINE */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100308 }
309
310 ret = 0;
311
312exit:
313 fclose( f );
314 return( ret );
315}
316
317int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path )
318{
319 FILE *f;
320 size_t n;
321 unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ];
322
323 if( ( f = fopen( path, "rb" ) ) == NULL )
324 return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR );
325
326 fseek( f, 0, SEEK_END );
327 n = (size_t) ftell( f );
328 fseek( f, 0, SEEK_SET );
329
330 if( n > POLARSSL_HMAC_DRBG_MAX_INPUT )
331 {
332 fclose( f );
333 return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG );
334 }
335
336 if( fread( buf, 1, n, f ) != n )
337 {
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100338 fclose( f ); /* LCOV_EXCL_LINE */
339 return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); /* LCOV_EXCL_LINE */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100340 }
341
342 fclose( f );
343
344 hmac_drbg_update( ctx, buf, n );
345
346 return( hmac_drbg_write_seed_file( ctx, path ) );
347}
348#endif /* POLARSSL_FS_IO */
349
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100350
351#if defined(POLARSSL_SELF_TEST)
352
353#include <stdio.h>
354
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100355#if !defined(POLARSSL_SHA1_C)
356/* Dummy checkup routine */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100357int hmac_drbg_self_test( int verbose )
358{
359
360 if( verbose != 0 )
361 printf( "\n" );
362
363 return( 0 );
364}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100365#else
366
367#define OUTPUT_LEN 80
368
369/* From a NIST PR=true test vector */
370static unsigned char entropy_pr[] = {
371 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
372 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
373 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
374 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
375 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
376static const unsigned char result_pr[OUTPUT_LEN] = {
377 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
378 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
379 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
380 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
381 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
382 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
383 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
384
385/* From a NIST PR=false test vector */
386static unsigned char entropy_nopr[] = {
387 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
388 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
389 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
390 0xe9, 0x9d, 0xfe, 0xdf };
391static const unsigned char result_nopr[OUTPUT_LEN] = {
392 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
393 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
394 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
395 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
396 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
397 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
398 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
399
400/* "Entropy" from buffer */
401static int test_offset;
402static int hmac_drbg_self_test_entropy( void *data,
403 unsigned char *buf, size_t len )
404{
405 const unsigned char *p = data;
406 memcpy( buf, p + test_offset, len );
407 test_offset += len;
408 return( 0 );
409}
410
411#define CHK( c ) if( (c) != 0 ) \
412 { \
413 if( verbose != 0 ) \
414 printf( "failed\n" ); \
415 return( 1 ); \
416 }
417
418/*
419 * Checkup routine for HMAC_DRBG with SHA-1
420 */
421int hmac_drbg_self_test( int verbose )
422{
423 hmac_drbg_context ctx;
424 unsigned char buf[OUTPUT_LEN];
425 const md_info_t *md_info = md_info_from_type( POLARSSL_MD_SHA1 );
426
427 /*
428 * PR = True
429 */
430 if( verbose != 0 )
431 printf( " HMAC_DRBG (PR = True) : " );
432
433 test_offset = 0;
434 CHK( hmac_drbg_init( &ctx, md_info,
435 hmac_drbg_self_test_entropy, entropy_pr,
436 NULL, 0 ) );
437 hmac_drbg_set_prediction_resistance( &ctx, POLARSSL_HMAC_DRBG_PR_ON );
438 CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
439 CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
440 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
441 hmac_drbg_free( &ctx );
442
443 if( verbose != 0 )
444 printf( "passed\n" );
445
446 /*
447 * PR = False
448 */
449 if( verbose != 0 )
450 printf( " HMAC_DRBG (PR = False) : " );
451
452 test_offset = 0;
453 CHK( hmac_drbg_init( &ctx, md_info,
454 hmac_drbg_self_test_entropy, entropy_nopr,
455 NULL, 0 ) );
456 CHK( hmac_drbg_reseed( &ctx, NULL, 0 ) );
457 CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
458 CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
459 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
460 hmac_drbg_free( &ctx );
461
462 if( verbose != 0 )
463 printf( "passed\n" );
464
465 if( verbose != 0 )
466 printf( "\n" );
467
468 return( 0 );
469}
470#endif /* POLARSSL_SHA1_C */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100471#endif /* POLARSSL_SELF_TEST */
472
473#endif /* POLARSSL_HMAC_DRBG_C */