Bug Summary

File:Externals/polarssl/library/ctr_drbg.c
Location:line 108, column 20
Description:Value stored to 'p' during its initialization is never read

Annotated Source Code

1/*
2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
3 *
4 * Copyright (C) 2006-2011, 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 * The NIST SP 800-90 DRBGs are described in the following publucation.
27 *
28 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
29 */
30
31#include "polarssl/config.h"
32
33#if defined(POLARSSL_CTR_DRBG_C)
34
35#include "polarssl/ctr_drbg.h"
36
37#if defined(POLARSSL_FS_IO)
38#include <stdio.h>
39#endif
40
41/*
42 * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
43 * tests to succeed (which require known length fixed entropy)
44 */
45int ctr_drbg_init_entropy_len(
46 ctr_drbg_context *ctx,
47 int (*f_entropy)(void *, unsigned char *, size_t),
48 void *p_entropy,
49 const unsigned char *custom,
50 size_t len,
51 size_t entropy_len )
52{
53 int ret;
54 unsigned char key[CTR_DRBG_KEYSIZE32];
55
56 memset( ctx, 0, sizeof(ctr_drbg_context) );
57 memset( key, 0, CTR_DRBG_KEYSIZE32 );
58
59 ctx->f_entropy = f_entropy;
60 ctx->p_entropy = p_entropy;
61
62 ctx->entropy_len = entropy_len;
63 ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL10000;
64
65 /*
66 * Initialize with an empty key
67 */
68 aes_setkey_enc( &ctx->aes_ctx, key, CTR_DRBG_KEYBITS( 32 * 8 ) );
69
70 if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
71 return( ret );
72
73 return( 0 );
74}
75
76int ctr_drbg_init( ctr_drbg_context *ctx,
77 int (*f_entropy)(void *, unsigned char *, size_t),
78 void *p_entropy,
79 const unsigned char *custom,
80 size_t len )
81{
82 return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len,
83 CTR_DRBG_ENTROPY_LEN48 ) );
84}
85
86void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance )
87{
88 ctx->prediction_resistance = resistance;
89}
90
91void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len )
92{
93 ctx->entropy_len = len;
94}
95
96void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval )
97{
98 ctx->reseed_interval = interval;
99}
100
101int block_cipher_df( unsigned char *output,
102 const unsigned char *data, size_t data_len )
103{
104 unsigned char buf[CTR_DRBG_MAX_SEED_INPUT384 + CTR_DRBG_BLOCKSIZE16 + 16];
105 unsigned char tmp[CTR_DRBG_SEEDLEN( 32 + 16 )];
106 unsigned char key[CTR_DRBG_KEYSIZE32];
107 unsigned char chain[CTR_DRBG_BLOCKSIZE16];
108 unsigned char *p = buf, *iv;
Value stored to 'p' during its initialization is never read
109 aes_context aes_ctx;
110
111 int i, j, buf_len, use_len;
112
113 memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT384 + CTR_DRBG_BLOCKSIZE16 + 16 );
114
115 /*
116 * Construct IV (16 bytes) and S in buffer
117 * IV = Counter (in 32-bits) padded to 16 with zeroes
118 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
119 * data || 0x80
120 * (Total is padded to a multiple of 16-bytes with zeroes)
121 */
122 p = buf + CTR_DRBG_BLOCKSIZE16;
123 *p++ = ( data_len >> 24 ) & 0xff;
124 *p++ = ( data_len >> 16 ) & 0xff;
125 *p++ = ( data_len >> 8 ) & 0xff;
126 *p++ = ( data_len ) & 0xff;
127 p += 3;
128 *p++ = CTR_DRBG_SEEDLEN( 32 + 16 );
129 memcpy( p, data, data_len );
130 p[data_len] = 0x80;
131
132 buf_len = CTR_DRBG_BLOCKSIZE16 + 8 + data_len + 1;
133
134 for( i = 0; i < CTR_DRBG_KEYSIZE32; i++ )
135 key[i] = i;
136
137 aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS( 32 * 8 ) );
138
139 /*
140 * Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data
141 */
142 for( j = 0; j < CTR_DRBG_SEEDLEN( 32 + 16 ); j += CTR_DRBG_BLOCKSIZE16 )
143 {
144 p = buf;
145 memset( chain, 0, CTR_DRBG_BLOCKSIZE16 );
146 use_len = buf_len;
147
148 while( use_len > 0 )
149 {
150 for( i = 0; i < CTR_DRBG_BLOCKSIZE16; i++ )
151 chain[i] ^= p[i];
152 p += CTR_DRBG_BLOCKSIZE16;
153 use_len -= CTR_DRBG_BLOCKSIZE16;
154
155 aes_crypt_ecb( &aes_ctx, AES_ENCRYPT1, chain, chain );
156 }
157
158 memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE16 );
159
160 /*
161 * Update IV
162 */
163 buf[3]++;
164 }
165
166 /*
167 * Do final encryption with reduced data
168 */
169 aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS( 32 * 8 ) );
170 iv = tmp + CTR_DRBG_KEYSIZE32;
171 p = output;
172
173 for( j = 0; j < CTR_DRBG_SEEDLEN( 32 + 16 ); j += CTR_DRBG_BLOCKSIZE16 )
174 {
175 aes_crypt_ecb( &aes_ctx, AES_ENCRYPT1, iv, iv );
176 memcpy( p, iv, CTR_DRBG_BLOCKSIZE16 );
177 p += CTR_DRBG_BLOCKSIZE16;
178 }
179
180 return( 0 );
181}
182
183int ctr_drbg_update_internal( ctr_drbg_context *ctx,
184 const unsigned char data[CTR_DRBG_SEEDLEN( 32 + 16 )] )
185{
186 unsigned char tmp[CTR_DRBG_SEEDLEN( 32 + 16 )];
187 unsigned char *p = tmp;
188 int i, j;
189
190 memset( tmp, 0, CTR_DRBG_SEEDLEN( 32 + 16 ) );
191
192 for( j = 0; j < CTR_DRBG_SEEDLEN( 32 + 16 ); j += CTR_DRBG_BLOCKSIZE16 )
193 {
194 /*
195 * Increase counter
196 */
197 for( i = CTR_DRBG_BLOCKSIZE16; i > 0; i-- )
198 if( ++ctx->counter[i - 1] != 0 )
199 break;
200
201 /*
202 * Crypt counter block
203 */
204 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT1, ctx->counter, p );
205
206 p += CTR_DRBG_BLOCKSIZE16;
207 }
208
209 for( i = 0; i < CTR_DRBG_SEEDLEN( 32 + 16 ); i++ )
210 tmp[i] ^= data[i];
211
212 /*
213 * Update key and counter
214 */
215 aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS( 32 * 8 ) );
216 memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE32, CTR_DRBG_BLOCKSIZE16 );
217
218 return( 0 );
219}
220
221void ctr_drbg_update( ctr_drbg_context *ctx,
222 const unsigned char *additional, size_t add_len )
223{
224 unsigned char add_input[CTR_DRBG_SEEDLEN( 32 + 16 )];
225
226 if( add_len > 0 )
227 {
228 block_cipher_df( add_input, additional, add_len );
229 ctr_drbg_update_internal( ctx, add_input );
230 }
231}
232
233int ctr_drbg_reseed( ctr_drbg_context *ctx,
234 const unsigned char *additional, size_t len )
235{
236 unsigned char seed[CTR_DRBG_MAX_SEED_INPUT384];
237 size_t seedlen = 0;
238
239 if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT384 )
240 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG-0x0038 );
241
242 memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT384 );
243
244 /*
245 * Gather enropy_len bytes of entropy to seed state
246 */
247 if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
248 ctx->entropy_len ) )
249 {
250 return( POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED-0x0034 );
251 }
252
253 seedlen += ctx->entropy_len;
254
255 /*
256 * Add additional data
257 */
258 if( additional && len )
259 {
260 memcpy( seed + seedlen, additional, len );
261 seedlen += len;
262 }
263
264 /*
265 * Reduce to 384 bits
266 */
267 block_cipher_df( seed, seed, seedlen );
268
269 /*
270 * Update state
271 */
272 ctr_drbg_update_internal( ctx, seed );
273 ctx->reseed_counter = 1;
274
275 return( 0 );
276}
277
278int ctr_drbg_random_with_add( void *p_rng,
279 unsigned char *output, size_t output_len,
280 const unsigned char *additional, size_t add_len )
281{
282 int ret = 0;
283 ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng;
284 unsigned char add_input[CTR_DRBG_SEEDLEN( 32 + 16 )];
285 unsigned char *p = output;
286 unsigned char tmp[CTR_DRBG_BLOCKSIZE16];
287 int i;
288 size_t use_len;
289
290 if( output_len > CTR_DRBG_MAX_REQUEST1024 )
291 return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG-0x0036 );
292
293 if( add_len > CTR_DRBG_MAX_INPUT256 )
294 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG-0x0038 );
295
296 memset( add_input, 0, CTR_DRBG_SEEDLEN( 32 + 16 ) );
297
298 if( ctx->reseed_counter > ctx->reseed_interval ||
299 ctx->prediction_resistance )
300 {
301 if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
302 return( ret );
303
304 add_len = 0;
305 }
306
307 if( add_len > 0 )
308 {
309 block_cipher_df( add_input, additional, add_len );
310 ctr_drbg_update_internal( ctx, add_input );
311 }
312
313 while( output_len > 0 )
314 {
315 /*
316 * Increase counter
317 */
318 for( i = CTR_DRBG_BLOCKSIZE16; i > 0; i-- )
319 if( ++ctx->counter[i - 1] != 0 )
320 break;
321
322 /*
323 * Crypt counter block
324 */
325 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT1, ctx->counter, tmp );
326
327 use_len = (output_len > CTR_DRBG_BLOCKSIZE16 ) ? CTR_DRBG_BLOCKSIZE16 : output_len;
328 /*
329 * Copy random block to destination
330 */
331 memcpy( p, tmp, use_len );
332 p += use_len;
333 output_len -= use_len;
334 }
335
336 ctr_drbg_update_internal( ctx, add_input );
337
338 ctx->reseed_counter++;
339
340 return( 0 );
341}
342
343int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
344{
345 return ctr_drbg_random_with_add( p_rng, output, output_len, NULL((void*)0), 0 );
346}
347
348#if defined(POLARSSL_FS_IO)
349int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path )
350{
351 int ret;
352 FILE *f;
353 unsigned char buf[ CTR_DRBG_MAX_INPUT256 ];
354
355 if( ( f = fopen( path, "wb" ) ) == NULL((void*)0) )
356 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR-0x003A );
357
358 if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT256 ) ) != 0 )
359 return( ret );
360
361 if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT256, f ) != CTR_DRBG_MAX_INPUT256 )
362 {
363 fclose( f );
364 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR-0x003A );
365 }
366
367 fclose( f );
368 return( 0 );
369}
370
371int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
372{
373 FILE *f;
374 size_t n;
375 unsigned char buf[ CTR_DRBG_MAX_INPUT256 ];
376
377 if( ( f = fopen( path, "rb" ) ) == NULL((void*)0) )
378 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR-0x003A );
379
380 fseek( f, 0, SEEK_END2 );
381 n = (size_t) ftell( f );
382 fseek( f, 0, SEEK_SET0 );
383
384 if( n > CTR_DRBG_MAX_INPUT256 )
385 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG-0x0038 );
386
387 if( fread( buf, 1, n, f ) != n )
388 {
389 fclose( f );
390 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR-0x003A );
391 }
392
393 ctr_drbg_update( ctx, buf, n );
394
395 fclose( f );
396
397 return( ctr_drbg_write_seed_file( ctx, path ) );
398}
399#endif /* POLARSSL_FS_IO */
400
401#if defined(POLARSSL_SELF_TEST)
402
403#include <stdio.h>
404
405unsigned char entropy_source_pr[96] =
406 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
407 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
408 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
409 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
410 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
411 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
412 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
413 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
414 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
415 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
416 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
417 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
418
419unsigned char entropy_source_nopr[64] =
420 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
421 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
422 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
423 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
424 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
425 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
426 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
427 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
428
429unsigned char nonce_pers_pr[16] =
430 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
431 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
432
433unsigned char nonce_pers_nopr[16] =
434 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
435 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
436
437unsigned char result_pr[16] =
438 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
439 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
440
441unsigned char result_nopr[16] =
442 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
443 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
444
445int test_offset;
446int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len )
447{
448 unsigned char *p = data;
449 memcpy( buf, p + test_offset, len );
450 test_offset += 32;
451 return( 0 );
452}
453
454/*
455 * Checkup routine
456 */
457int ctr_drbg_self_test( int verbose )
458{
459 ctr_drbg_context ctx;
460 unsigned char buf[16];
461
462 /*
463 * Based on a NIST CTR_DRBG test vector (PR = True)
464 */
465 if( verbose != 0 )
466 printf( " CTR_DRBG (PR = TRUE) : " );
467
468 test_offset = 0;
469 if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_pr, nonce_pers_pr, 16, 32 ) != 0 )
470 {
471 if( verbose != 0 )
472 printf( "failed\n" );
473
474 return( 1 );
475 }
476 ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON1 );
477
478 if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE16 ) != 0 )
479 {
480 if( verbose != 0 )
481 printf( "failed\n" );
482
483 return( 1 );
484 }
485
486 if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE16 ) != 0 )
487 {
488 if( verbose != 0 )
489 printf( "failed\n" );
490
491 return( 1 );
492 }
493
494 if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE16 ) != 0 )
495 {
496 if( verbose != 0 )
497 printf( "failed\n" );
498
499 return( 1 );
500 }
501
502 if( verbose != 0 )
503 printf( "passed\n" );
504
505 /*
506 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
507 */
508 if( verbose != 0 )
509 printf( " CTR_DRBG (PR = FALSE): " );
510
511 test_offset = 0;
512 if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_nopr, nonce_pers_nopr, 16, 32 ) != 0 )
513 {
514 if( verbose != 0 )
515 printf( "failed\n" );
516
517 return( 1 );
518 }
519
520 if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
521 {
522 if( verbose != 0 )
523 printf( "failed\n" );
524
525 return( 1 );
526 }
527
528 if( ctr_drbg_reseed( &ctx, NULL((void*)0), 0 ) != 0 )
529 {
530 if( verbose != 0 )
531 printf( "failed\n" );
532
533 return( 1 );
534 }
535
536 if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
537 {
538 if( verbose != 0 )
539 printf( "failed\n" );
540
541 return( 1 );
542 }
543
544 if( memcmp( buf, result_nopr, 16 ) != 0 )
545 {
546 if( verbose != 0 )
547 printf( "failed\n" );
548
549 return( 1 );
550 }
551
552 if( verbose != 0 )
553 printf( "passed\n" );
554
555 if( verbose != 0 )
556 printf( "\n" );
557
558 return( 0 );
559}
560#endif
561
562#endif