blob: 64b536aaa75ad35377c5191c9971c5a52cbac98d [file] [log] [blame]
Paul Bakker0e04d0e2011-11-27 14:46:59 +00001/*
2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
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
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
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.
Paul Bakker0e04d0e2011-11-27 14:46:59 +000024 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
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.
34 *
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.
39 *
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.
43 *
44 * **********
Paul Bakker0e04d0e2011-11-27 14:46:59 +000045 */
46/*
Paul Sokolovsky8d6d8c82018-02-10 11:11:41 +020047 * The NIST SP 800-90 DRBGs are described in the following publication.
Paul Bakker0e04d0e2011-11-27 14:46:59 +000048 *
49 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
50 */
51
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000053#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020054#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020056#endif
Paul Bakker0e04d0e2011-11-27 14:46:59 +000057
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#if defined(MBEDTLS_CTR_DRBG_C)
Paul Bakker0e04d0e2011-11-27 14:46:59 +000059
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000060#include "mbedtls/ctr_drbg.h"
Paul Bakker0e04d0e2011-11-27 14:46:59 +000061
Rich Evans00ab4702015-02-06 13:43:58 +000062#include <string.h>
63
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064#if defined(MBEDTLS_FS_IO)
Paul Bakkerfc754a92011-12-05 13:23:51 +000065#include <stdio.h>
66#endif
67
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if defined(MBEDTLS_SELF_TEST)
69#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000070#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010071#else
Rich Evans00ab4702015-02-06 13:43:58 +000072#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#define mbedtls_printf printf
74#endif /* MBEDTLS_PLATFORM_C */
75#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010076
Paul Bakkerfff03662014-06-18 16:21:25 +020077/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakkerfff03662014-06-18 16:21:25 +020079 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
80}
81
Paul Bakker18d32912011-12-10 21:42:49 +000082/*
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +020083 * CTR_DRBG context initialization
84 */
85void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
86{
87 memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010088
Gavin Acquroffceb99902020-03-01 17:06:11 -080089 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +020090}
91
Gavin Acquroffceb99902020-03-01 17:06:11 -080092/*
93 * This function resets CTR_DRBG context to the state immediately
94 * after initial call of mbedtls_ctr_drbg_init().
95 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
Paul Bakkerfff03662014-06-18 16:21:25 +020097{
98 if( ctx == NULL )
99 return;
100
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100101#if defined(MBEDTLS_THREADING_C)
Gilles Peskine085b69f2021-01-30 13:05:32 +0100102 if( ctx->f_entropy != NULL )
103 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100104#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105 mbedtls_aes_free( &ctx->aes_ctx );
106 mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
Gavin Acquroffceb99902020-03-01 17:06:11 -0800107 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
Paul Bakkerfff03662014-06-18 16:21:25 +0200108}
109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000111{
112 ctx->prediction_resistance = resistance;
113}
114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000116{
117 ctx->entropy_len = len;
118}
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000121{
122 ctx->reseed_interval = interval;
123}
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200124
125static int block_cipher_df( unsigned char *output,
126 const unsigned char *data, size_t data_len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000127{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
129 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
130 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
131 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
Manuel Pégourié-Gonnard7c593632014-01-20 10:27:13 +0100132 unsigned char *p, *iv;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133 mbedtls_aes_context aes_ctx;
Dvir Markovich1b364992017-06-26 13:43:34 +0300134 int ret = 0;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000135
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200136 int i, j;
137 size_t buf_len, use_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200139 if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
140 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard5cb4b312014-11-25 17:41:50 +0100141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142 memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
143 mbedtls_aes_init( &aes_ctx );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000144
145 /*
146 * Construct IV (16 bytes) and S in buffer
147 * IV = Counter (in 32-bits) padded to 16 with zeroes
148 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
149 * data || 0x80
150 * (Total is padded to a multiple of 16-bytes with zeroes)
151 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000153 *p++ = ( data_len >> 24 ) & 0xff;
154 *p++ = ( data_len >> 16 ) & 0xff;
155 *p++ = ( data_len >> 8 ) & 0xff;
156 *p++ = ( data_len ) & 0xff;
157 p += 3;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000159 memcpy( p, data, data_len );
160 p[data_len] = 0x80;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000161
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000165 key[i] = i;
166
Dvir Markovich1b364992017-06-26 13:43:34 +0300167 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
168 {
169 goto exit;
170 }
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000171
172 /*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000174 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000176 {
177 p = buf;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178 memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000179 use_len = buf_len;
180
181 while( use_len > 0 )
182 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183 for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000184 chain[i] ^= p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
186 use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
187 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000188
Dvir Markovich1b364992017-06-26 13:43:34 +0300189 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
190 {
191 goto exit;
192 }
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000193 }
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195 memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000196
197 /*
198 * Update IV
199 */
200 buf[3]++;
201 }
202
203 /*
204 * Do final encryption with reduced data
205 */
Dvir Markovich1b364992017-06-26 13:43:34 +0300206 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
207 {
208 goto exit;
209 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200210 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000211 p = output;
212
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000214 {
Dvir Markovich1b364992017-06-26 13:43:34 +0300215 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
216 {
217 goto exit;
218 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219 memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
220 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000221 }
Dvir Markovich1b364992017-06-26 13:43:34 +0300222exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223 mbedtls_aes_free( &aes_ctx );
Dvir Markovich1b364992017-06-26 13:43:34 +0300224 /*
225 * tidy up the stack
226 */
227 mbedtls_zeroize( buf, sizeof( buf ) );
228 mbedtls_zeroize( tmp, sizeof( tmp ) );
229 mbedtls_zeroize( key, sizeof( key ) );
230 mbedtls_zeroize( chain, sizeof( chain ) );
231 if( 0 != ret )
232 {
233 /*
234 * wipe partial seed from memory
235 */
236 mbedtls_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
237 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200238
Dvir Markovich1b364992017-06-26 13:43:34 +0300239 return( ret );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000240}
241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
243 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000244{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000246 unsigned char *p = tmp;
Paul Bakker369e14b2012-04-18 14:16:09 +0000247 int i, j;
Dvir Markovich1b364992017-06-26 13:43:34 +0300248 int ret = 0;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000249
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000251
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000253 {
254 /*
255 * Increase counter
256 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
Paul Bakker369e14b2012-04-18 14:16:09 +0000258 if( ++ctx->counter[i - 1] != 0 )
259 break;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000260
261 /*
262 * Crypt counter block
263 */
Dvir Markovich1b364992017-06-26 13:43:34 +0300264 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
Gilles Peskined324c592018-09-11 15:34:17 +0200265 goto exit;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000268 }
269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270 for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000271 tmp[i] ^= data[i];
272
273 /*
274 * Update key and counter
275 */
Dvir Markovich1b364992017-06-26 13:43:34 +0300276 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
Gilles Peskined324c592018-09-11 15:34:17 +0200277 goto exit;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200278 memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000279
Gilles Peskined324c592018-09-11 15:34:17 +0200280exit:
281 mbedtls_zeroize( tmp, sizeof( tmp ) );
282 return( ret );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000283}
284
Gilles Peskine9ce29722018-09-11 16:41:54 +0200285int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
286 const unsigned char *additional,
287 size_t add_len )
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000288{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
Gilles Peskine9ce29722018-09-11 16:41:54 +0200290 int ret;
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000291
Gilles Peskine9ce29722018-09-11 16:41:54 +0200292 if( add_len == 0 )
293 return( 0 );
Manuel Pégourié-Gonnard5cb4b312014-11-25 17:41:50 +0100294
Gilles Peskine9ce29722018-09-11 16:41:54 +0200295 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
296 goto exit;
297 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
298 goto exit;
299
300exit:
301 mbedtls_zeroize( add_input, sizeof( add_input ) );
302 return( ret );
303}
304
305/* Deprecated function, kept for backward compatibility. */
306void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
307 const unsigned char *additional,
308 size_t add_len )
309{
310 /* MAX_INPUT would be more logical here, but we have to match
311 * block_cipher_df()'s limits since we can't propagate errors */
312 if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
313 add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
314 (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000315}
316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000318 const unsigned char *additional, size_t len )
319{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000321 size_t seedlen = 0;
Dvir Markovich1b364992017-06-26 13:43:34 +0300322 int ret;
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000323
Andres Amaya Garcia6a543362017-01-17 23:04:22 +0000324 if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
325 len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000329
330 /*
Paul Bakker18f03412013-09-11 10:53:05 +0200331 * Gather entropy_len bytes of entropy to seed state
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000332 */
333 if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
334 ctx->entropy_len ) )
335 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000337 }
338
339 seedlen += ctx->entropy_len;
340
341 /*
342 * Add additional data
343 */
344 if( additional && len )
345 {
346 memcpy( seed + seedlen, additional, len );
347 seedlen += len;
348 }
349
350 /*
351 * Reduce to 384 bits
352 */
Dvir Markovich1b364992017-06-26 13:43:34 +0300353 if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
Gilles Peskined324c592018-09-11 15:34:17 +0200354 goto exit;
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000355
356 /*
357 * Update state
358 */
Dvir Markovich1b364992017-06-26 13:43:34 +0300359 if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
Gilles Peskined324c592018-09-11 15:34:17 +0200360 goto exit;
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000361 ctx->reseed_counter = 1;
362
Gilles Peskined324c592018-09-11 15:34:17 +0200363exit:
364 mbedtls_zeroize( seed, sizeof( seed ) );
365 return( ret );
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000366}
Paul Bakker9af723c2014-05-01 13:03:14 +0200367
Gilles Peskineb729e1b2019-10-04 12:15:55 +0200368int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
369 int (*f_entropy)(void *, unsigned char *, size_t),
370 void *p_entropy,
371 const unsigned char *custom,
372 size_t len )
Gilles Peskine845ac102019-10-02 20:31:54 +0200373{
374 int ret;
375 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
376
377 memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
378
Gilles Peskine085b69f2021-01-30 13:05:32 +0100379#if defined(MBEDTLS_THREADING_C)
380 mbedtls_mutex_init( &ctx->mutex );
381#endif
382
Gilles Peskine845ac102019-10-02 20:31:54 +0200383 mbedtls_aes_init( &ctx->aes_ctx );
384
385 ctx->f_entropy = f_entropy;
386 ctx->p_entropy = p_entropy;
387
Gilles Peskineb729e1b2019-10-04 12:15:55 +0200388 if( ctx->entropy_len == 0 )
389 ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
Gilles Peskine845ac102019-10-02 20:31:54 +0200390
391 /*
392 * Initialize with an empty key
393 */
394 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
395 {
396 return( ret );
397 }
398
399 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
400 {
401 return( ret );
402 }
403 return( 0 );
404}
405
Gilles Peskineb729e1b2019-10-04 12:15:55 +0200406/* Backward compatibility wrapper */
407int mbedtls_ctr_drbg_seed_entropy_len(
408 mbedtls_ctr_drbg_context *ctx,
409 int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
410 const unsigned char *custom, size_t len,
411 size_t entropy_len )
Gilles Peskine845ac102019-10-02 20:31:54 +0200412{
Gilles Peskineb729e1b2019-10-04 12:15:55 +0200413 mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len );
414 return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
Gilles Peskine845ac102019-10-02 20:31:54 +0200415}
416
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417int mbedtls_ctr_drbg_random_with_add( void *p_rng,
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000418 unsigned char *output, size_t output_len,
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000419 const unsigned char *additional, size_t add_len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000420{
421 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
423 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000424 unsigned char *p = output;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
Paul Bakker369e14b2012-04-18 14:16:09 +0000426 int i;
Paul Bakker23fd5ea2011-11-29 15:56:12 +0000427 size_t use_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
430 return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
433 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000436
437 if( ctx->reseed_counter > ctx->reseed_interval ||
438 ctx->prediction_resistance )
439 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Dvir Markovich1b364992017-06-26 13:43:34 +0300441 {
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000442 return( ret );
Dvir Markovich1b364992017-06-26 13:43:34 +0300443 }
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000444 add_len = 0;
445 }
446
447 if( add_len > 0 )
448 {
Dvir Markovich1b364992017-06-26 13:43:34 +0300449 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
Gilles Peskined324c592018-09-11 15:34:17 +0200450 goto exit;
Dvir Markovich1b364992017-06-26 13:43:34 +0300451 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
Gilles Peskined324c592018-09-11 15:34:17 +0200452 goto exit;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000453 }
454
455 while( output_len > 0 )
456 {
457 /*
458 * Increase counter
459 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
Paul Bakker369e14b2012-04-18 14:16:09 +0000461 if( ++ctx->counter[i - 1] != 0 )
462 break;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000463
464 /*
465 * Crypt counter block
466 */
Dvir Markovich1b364992017-06-26 13:43:34 +0300467 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
Gilles Peskined324c592018-09-11 15:34:17 +0200468 goto exit;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200471 output_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000472 /*
473 * Copy random block to destination
474 */
Paul Bakker23fd5ea2011-11-29 15:56:12 +0000475 memcpy( p, tmp, use_len );
476 p += use_len;
477 output_len -= use_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000478 }
479
Dvir Markovich1b364992017-06-26 13:43:34 +0300480 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
Gilles Peskined324c592018-09-11 15:34:17 +0200481 goto exit;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000482
483 ctx->reseed_counter++;
484
Gilles Peskined324c592018-09-11 15:34:17 +0200485exit:
486 mbedtls_zeroize( add_input, sizeof( add_input ) );
487 mbedtls_zeroize( tmp, sizeof( tmp ) );
Gilles Peskineb2be1fc2019-11-28 09:45:32 +0100488 return( ret );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000489}
490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000492{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100493 int ret;
494 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
495
496#if defined(MBEDTLS_THREADING_C)
497 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
498 return( ret );
499#endif
500
501 ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
502
503#if defined(MBEDTLS_THREADING_C)
504 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
505 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
506#endif
507
508 return( ret );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000509}
510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511#if defined(MBEDTLS_FS_IO)
512int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
Paul Bakkerfc754a92011-12-05 13:23:51 +0000513{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200514 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
Paul Bakkerfc754a92011-12-05 13:23:51 +0000515 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200516 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
Paul Bakkerfc754a92011-12-05 13:23:51 +0000517
518 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
Paul Bakkerc72d3f72013-05-14 13:22:41 +0200522 goto exit;
Paul Bakkerfc754a92011-12-05 13:23:51 +0000523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524 if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
Andres Amaya Garcia13f41e12017-06-26 10:56:58 +0100526 else
527 ret = 0;
Paul Bakkerfc754a92011-12-05 13:23:51 +0000528
Andres Amaya Garcia4e2c07c2017-06-27 16:57:26 +0100529exit:
Andres Amaya Garcia13f41e12017-06-26 10:56:58 +0100530 mbedtls_zeroize( buf, sizeof( buf ) );
Paul Bakkerc72d3f72013-05-14 13:22:41 +0200531
Paul Bakkerfc754a92011-12-05 13:23:51 +0000532 fclose( f );
Paul Bakkerc72d3f72013-05-14 13:22:41 +0200533 return( ret );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000534}
535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
Paul Bakkerfc754a92011-12-05 13:23:51 +0000537{
Andres Amaya Garcia13f41e12017-06-26 10:56:58 +0100538 int ret = 0;
Paul Bakkerfc754a92011-12-05 13:23:51 +0000539 FILE *f;
540 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
Paul Bakkerfc754a92011-12-05 13:23:51 +0000542
543 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000545
546 fseek( f, 0, SEEK_END );
547 n = (size_t) ftell( f );
548 fseek( f, 0, SEEK_SET );
549
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
Andres Amaya Garcia4e2c07c2017-06-27 16:57:26 +0100551 {
552 fclose( f );
553 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
554 }
555
556 if( fread( buf, 1, n, f ) != n )
Andres Amaya Garcia13f41e12017-06-26 10:56:58 +0100557 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
558 else
Gilles Peskine9ce29722018-09-11 16:41:54 +0200559 ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000560
Paul Bakkerfc754a92011-12-05 13:23:51 +0000561 fclose( f );
Paul Bakkerc72d3f72013-05-14 13:22:41 +0200562
Andres Amaya Garcia13f41e12017-06-26 10:56:58 +0100563 mbedtls_zeroize( buf, sizeof( buf ) );
564
565 if( ret != 0 )
566 return( ret );
Paul Bakkerc72d3f72013-05-14 13:22:41 +0200567
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568 return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000569}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570#endif /* MBEDTLS_FS_IO */
Paul Bakkerfc754a92011-12-05 13:23:51 +0000571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572#if defined(MBEDTLS_SELF_TEST)
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000573
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000574static const unsigned char entropy_source_pr[96] =
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000575 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
576 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
577 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
578 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
579 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
580 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
581 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
582 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
583 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
584 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
585 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
586 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
587
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000588static const unsigned char entropy_source_nopr[64] =
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000589 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
590 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
591 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
592 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
593 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
594 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
595 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
596 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
597
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100598static const unsigned char nonce_pers_pr[16] =
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000599 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
600 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
601
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100602static const unsigned char nonce_pers_nopr[16] =
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000603 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
604 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
605
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100606static const unsigned char result_pr[16] =
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000607 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
608 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
609
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100610static const unsigned char result_nopr[16] =
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000611 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
612 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
613
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100614static size_t test_offset;
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200615static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
616 size_t len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000617{
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100618 const unsigned char *p = data;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000619 memcpy( buf, p + test_offset, len );
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100620 test_offset += len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000621 return( 0 );
622}
623
Paul Bakker7dc4c442014-02-01 22:50:26 +0100624#define CHK( c ) if( (c) != 0 ) \
625 { \
626 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100628 return( 1 ); \
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100629 }
630
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000631/*
632 * Checkup routine
633 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634int mbedtls_ctr_drbg_self_test( int verbose )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000635{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 mbedtls_ctr_drbg_context ctx;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000637 unsigned char buf[16];
638
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +0200639 mbedtls_ctr_drbg_init( &ctx );
640
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000641 /*
642 * Based on a NIST CTR_DRBG test vector (PR = True)
643 */
644 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000646
647 test_offset = 0;
Gilles Peskineb729e1b2019-10-04 12:15:55 +0200648 mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
649 CHK( mbedtls_ctr_drbg_seed( &ctx,
650 ctr_drbg_self_test_entropy,
651 (void *) entropy_source_pr,
652 nonce_pers_pr, 16 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
654 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
655 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
656 CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000657
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100658 mbedtls_ctr_drbg_free( &ctx );
659
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000660 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661 mbedtls_printf( "passed\n" );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000662
663 /*
664 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
665 */
666 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200667 mbedtls_printf( " CTR_DRBG (PR = FALSE): " );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000668
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100669 mbedtls_ctr_drbg_init( &ctx );
670
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000671 test_offset = 0;
Gilles Peskineb729e1b2019-10-04 12:15:55 +0200672 mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
673 CHK( mbedtls_ctr_drbg_seed( &ctx,
674 ctr_drbg_self_test_entropy,
675 (void *) entropy_source_nopr,
676 nonce_pers_nopr, 16 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
678 CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
679 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100680 CHK( memcmp( buf, result_nopr, 16 ) );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000681
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100682 mbedtls_ctr_drbg_free( &ctx );
683
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000684 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685 mbedtls_printf( "passed\n" );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000686
687 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688 mbedtls_printf( "\n" );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000689
690 return( 0 );
691}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692#endif /* MBEDTLS_SELF_TEST */
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000693
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694#endif /* MBEDTLS_CTR_DRBG_C */