takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /*
kadonotakashi 0:8fdf9a60065b 2 * HMAC_DRBG implementation (NIST SP 800-90)
kadonotakashi 0:8fdf9a60065b 3 *
kadonotakashi 0:8fdf9a60065b 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
kadonotakashi 0:8fdf9a60065b 5 * SPDX-License-Identifier: Apache-2.0
kadonotakashi 0:8fdf9a60065b 6 *
kadonotakashi 0:8fdf9a60065b 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kadonotakashi 0:8fdf9a60065b 8 * not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 9 * You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 10 *
kadonotakashi 0:8fdf9a60065b 11 * http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 12 *
kadonotakashi 0:8fdf9a60065b 13 * Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kadonotakashi 0:8fdf9a60065b 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 16 * See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 17 * limitations under the License.
kadonotakashi 0:8fdf9a60065b 18 *
kadonotakashi 0:8fdf9a60065b 19 * This file is part of mbed TLS (https://tls.mbed.org)
kadonotakashi 0:8fdf9a60065b 20 */
kadonotakashi 0:8fdf9a60065b 21
kadonotakashi 0:8fdf9a60065b 22 /*
kadonotakashi 0:8fdf9a60065b 23 * The NIST SP 800-90A DRBGs are described in the following publication.
kadonotakashi 0:8fdf9a60065b 24 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
kadonotakashi 0:8fdf9a60065b 25 * References below are based on rev. 1 (January 2012).
kadonotakashi 0:8fdf9a60065b 26 */
kadonotakashi 0:8fdf9a60065b 27
kadonotakashi 0:8fdf9a60065b 28 #if !defined(MBEDTLS_CONFIG_FILE)
kadonotakashi 0:8fdf9a60065b 29 #include "mbedtls/config.h"
kadonotakashi 0:8fdf9a60065b 30 #else
kadonotakashi 0:8fdf9a60065b 31 #include MBEDTLS_CONFIG_FILE
kadonotakashi 0:8fdf9a60065b 32 #endif
kadonotakashi 0:8fdf9a60065b 33
kadonotakashi 0:8fdf9a60065b 34 #if defined(MBEDTLS_HMAC_DRBG_C)
kadonotakashi 0:8fdf9a60065b 35
kadonotakashi 0:8fdf9a60065b 36 #include "mbedtls/hmac_drbg.h"
kadonotakashi 0:8fdf9a60065b 37 #include "mbedtls/platform_util.h"
kadonotakashi 0:8fdf9a60065b 38
kadonotakashi 0:8fdf9a60065b 39 #include <string.h>
kadonotakashi 0:8fdf9a60065b 40
kadonotakashi 0:8fdf9a60065b 41 #if defined(MBEDTLS_FS_IO)
kadonotakashi 0:8fdf9a60065b 42 #include <stdio.h>
kadonotakashi 0:8fdf9a60065b 43 #endif
kadonotakashi 0:8fdf9a60065b 44
kadonotakashi 0:8fdf9a60065b 45 #if defined(MBEDTLS_SELF_TEST)
kadonotakashi 0:8fdf9a60065b 46 #if defined(MBEDTLS_PLATFORM_C)
kadonotakashi 0:8fdf9a60065b 47 #include "mbedtls/platform.h"
kadonotakashi 0:8fdf9a60065b 48 #else
kadonotakashi 0:8fdf9a60065b 49 #include <stdio.h>
kadonotakashi 0:8fdf9a60065b 50 #define mbedtls_printf printf
kadonotakashi 0:8fdf9a60065b 51 #endif /* MBEDTLS_SELF_TEST */
kadonotakashi 0:8fdf9a60065b 52 #endif /* MBEDTLS_PLATFORM_C */
kadonotakashi 0:8fdf9a60065b 53
kadonotakashi 0:8fdf9a60065b 54 /*
kadonotakashi 0:8fdf9a60065b 55 * HMAC_DRBG context initialization
kadonotakashi 0:8fdf9a60065b 56 */
kadonotakashi 0:8fdf9a60065b 57 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
kadonotakashi 0:8fdf9a60065b 58 {
kadonotakashi 0:8fdf9a60065b 59 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
kadonotakashi 0:8fdf9a60065b 60
kadonotakashi 0:8fdf9a60065b 61 #if defined(MBEDTLS_THREADING_C)
kadonotakashi 0:8fdf9a60065b 62 mbedtls_mutex_init( &ctx->mutex );
kadonotakashi 0:8fdf9a60065b 63 #endif
kadonotakashi 0:8fdf9a60065b 64 }
kadonotakashi 0:8fdf9a60065b 65
kadonotakashi 0:8fdf9a60065b 66 /*
kadonotakashi 0:8fdf9a60065b 67 * HMAC_DRBG update, using optional additional data (10.1.2.2)
kadonotakashi 0:8fdf9a60065b 68 */
kadonotakashi 0:8fdf9a60065b 69 void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
kadonotakashi 0:8fdf9a60065b 70 const unsigned char *additional, size_t add_len )
kadonotakashi 0:8fdf9a60065b 71 {
kadonotakashi 0:8fdf9a60065b 72 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
kadonotakashi 0:8fdf9a60065b 73 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
kadonotakashi 0:8fdf9a60065b 74 unsigned char sep[1];
kadonotakashi 0:8fdf9a60065b 75 unsigned char K[MBEDTLS_MD_MAX_SIZE];
kadonotakashi 0:8fdf9a60065b 76
kadonotakashi 0:8fdf9a60065b 77 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
kadonotakashi 0:8fdf9a60065b 78 {
kadonotakashi 0:8fdf9a60065b 79 /* Step 1 or 4 */
kadonotakashi 0:8fdf9a60065b 80 mbedtls_md_hmac_reset( &ctx->md_ctx );
kadonotakashi 0:8fdf9a60065b 81 mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
kadonotakashi 0:8fdf9a60065b 82 mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 );
kadonotakashi 0:8fdf9a60065b 83 if( rounds == 2 )
kadonotakashi 0:8fdf9a60065b 84 mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len );
kadonotakashi 0:8fdf9a60065b 85 mbedtls_md_hmac_finish( &ctx->md_ctx, K );
kadonotakashi 0:8fdf9a60065b 86
kadonotakashi 0:8fdf9a60065b 87 /* Step 2 or 5 */
kadonotakashi 0:8fdf9a60065b 88 mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len );
kadonotakashi 0:8fdf9a60065b 89 mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
kadonotakashi 0:8fdf9a60065b 90 mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
kadonotakashi 0:8fdf9a60065b 91 }
kadonotakashi 0:8fdf9a60065b 92 }
kadonotakashi 0:8fdf9a60065b 93
kadonotakashi 0:8fdf9a60065b 94 /*
kadonotakashi 0:8fdf9a60065b 95 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
kadonotakashi 0:8fdf9a60065b 96 */
kadonotakashi 0:8fdf9a60065b 97 int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
kadonotakashi 0:8fdf9a60065b 98 const mbedtls_md_info_t * md_info,
kadonotakashi 0:8fdf9a60065b 99 const unsigned char *data, size_t data_len )
kadonotakashi 0:8fdf9a60065b 100 {
kadonotakashi 0:8fdf9a60065b 101 int ret;
kadonotakashi 0:8fdf9a60065b 102
kadonotakashi 0:8fdf9a60065b 103 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
kadonotakashi 0:8fdf9a60065b 104 return( ret );
kadonotakashi 0:8fdf9a60065b 105
kadonotakashi 0:8fdf9a60065b 106 /*
kadonotakashi 0:8fdf9a60065b 107 * Set initial working state.
kadonotakashi 0:8fdf9a60065b 108 * Use the V memory location, which is currently all 0, to initialize the
kadonotakashi 0:8fdf9a60065b 109 * MD context with an all-zero key. Then set V to its initial value.
kadonotakashi 0:8fdf9a60065b 110 */
kadonotakashi 0:8fdf9a60065b 111 mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) );
kadonotakashi 0:8fdf9a60065b 112 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
kadonotakashi 0:8fdf9a60065b 113
kadonotakashi 0:8fdf9a60065b 114 mbedtls_hmac_drbg_update( ctx, data, data_len );
kadonotakashi 0:8fdf9a60065b 115
kadonotakashi 0:8fdf9a60065b 116 return( 0 );
kadonotakashi 0:8fdf9a60065b 117 }
kadonotakashi 0:8fdf9a60065b 118
kadonotakashi 0:8fdf9a60065b 119 /*
kadonotakashi 0:8fdf9a60065b 120 * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
kadonotakashi 0:8fdf9a60065b 121 */
kadonotakashi 0:8fdf9a60065b 122 int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
kadonotakashi 0:8fdf9a60065b 123 const unsigned char *additional, size_t len )
kadonotakashi 0:8fdf9a60065b 124 {
kadonotakashi 0:8fdf9a60065b 125 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
kadonotakashi 0:8fdf9a60065b 126 size_t seedlen;
kadonotakashi 0:8fdf9a60065b 127
kadonotakashi 0:8fdf9a60065b 128 /* III. Check input length */
kadonotakashi 0:8fdf9a60065b 129 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
kadonotakashi 0:8fdf9a60065b 130 ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
kadonotakashi 0:8fdf9a60065b 131 {
kadonotakashi 0:8fdf9a60065b 132 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
kadonotakashi 0:8fdf9a60065b 133 }
kadonotakashi 0:8fdf9a60065b 134
kadonotakashi 0:8fdf9a60065b 135 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
kadonotakashi 0:8fdf9a60065b 136
kadonotakashi 0:8fdf9a60065b 137 /* IV. Gather entropy_len bytes of entropy for the seed */
kadonotakashi 0:8fdf9a60065b 138 if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
kadonotakashi 0:8fdf9a60065b 139 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
kadonotakashi 0:8fdf9a60065b 140
kadonotakashi 0:8fdf9a60065b 141 seedlen = ctx->entropy_len;
kadonotakashi 0:8fdf9a60065b 142
kadonotakashi 0:8fdf9a60065b 143 /* 1. Concatenate entropy and additional data if any */
kadonotakashi 0:8fdf9a60065b 144 if( additional != NULL && len != 0 )
kadonotakashi 0:8fdf9a60065b 145 {
kadonotakashi 0:8fdf9a60065b 146 memcpy( seed + seedlen, additional, len );
kadonotakashi 0:8fdf9a60065b 147 seedlen += len;
kadonotakashi 0:8fdf9a60065b 148 }
kadonotakashi 0:8fdf9a60065b 149
kadonotakashi 0:8fdf9a60065b 150 /* 2. Update state */
kadonotakashi 0:8fdf9a60065b 151 mbedtls_hmac_drbg_update( ctx, seed, seedlen );
kadonotakashi 0:8fdf9a60065b 152
kadonotakashi 0:8fdf9a60065b 153 /* 3. Reset reseed_counter */
kadonotakashi 0:8fdf9a60065b 154 ctx->reseed_counter = 1;
kadonotakashi 0:8fdf9a60065b 155
kadonotakashi 0:8fdf9a60065b 156 /* 4. Done */
kadonotakashi 0:8fdf9a60065b 157 return( 0 );
kadonotakashi 0:8fdf9a60065b 158 }
kadonotakashi 0:8fdf9a60065b 159
kadonotakashi 0:8fdf9a60065b 160 /*
kadonotakashi 0:8fdf9a60065b 161 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
kadonotakashi 0:8fdf9a60065b 162 */
kadonotakashi 0:8fdf9a60065b 163 int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
kadonotakashi 0:8fdf9a60065b 164 const mbedtls_md_info_t * md_info,
kadonotakashi 0:8fdf9a60065b 165 int (*f_entropy)(void *, unsigned char *, size_t),
kadonotakashi 0:8fdf9a60065b 166 void *p_entropy,
kadonotakashi 0:8fdf9a60065b 167 const unsigned char *custom,
kadonotakashi 0:8fdf9a60065b 168 size_t len )
kadonotakashi 0:8fdf9a60065b 169 {
kadonotakashi 0:8fdf9a60065b 170 int ret;
kadonotakashi 0:8fdf9a60065b 171 size_t entropy_len, md_size;
kadonotakashi 0:8fdf9a60065b 172
kadonotakashi 0:8fdf9a60065b 173 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
kadonotakashi 0:8fdf9a60065b 174 return( ret );
kadonotakashi 0:8fdf9a60065b 175
kadonotakashi 0:8fdf9a60065b 176 md_size = mbedtls_md_get_size( md_info );
kadonotakashi 0:8fdf9a60065b 177
kadonotakashi 0:8fdf9a60065b 178 /*
kadonotakashi 0:8fdf9a60065b 179 * Set initial working state.
kadonotakashi 0:8fdf9a60065b 180 * Use the V memory location, which is currently all 0, to initialize the
kadonotakashi 0:8fdf9a60065b 181 * MD context with an all-zero key. Then set V to its initial value.
kadonotakashi 0:8fdf9a60065b 182 */
kadonotakashi 0:8fdf9a60065b 183 mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size );
kadonotakashi 0:8fdf9a60065b 184 memset( ctx->V, 0x01, md_size );
kadonotakashi 0:8fdf9a60065b 185
kadonotakashi 0:8fdf9a60065b 186 ctx->f_entropy = f_entropy;
kadonotakashi 0:8fdf9a60065b 187 ctx->p_entropy = p_entropy;
kadonotakashi 0:8fdf9a60065b 188
kadonotakashi 0:8fdf9a60065b 189 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
kadonotakashi 0:8fdf9a60065b 190
kadonotakashi 0:8fdf9a60065b 191 /*
kadonotakashi 0:8fdf9a60065b 192 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
kadonotakashi 0:8fdf9a60065b 193 * each hash function, then according to SP800-90A rev1 10.1 table 2,
kadonotakashi 0:8fdf9a60065b 194 * min_entropy_len (in bits) is security_strength.
kadonotakashi 0:8fdf9a60065b 195 *
kadonotakashi 0:8fdf9a60065b 196 * (This also matches the sizes used in the NIST test vectors.)
kadonotakashi 0:8fdf9a60065b 197 */
kadonotakashi 0:8fdf9a60065b 198 entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
kadonotakashi 0:8fdf9a60065b 199 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
kadonotakashi 0:8fdf9a60065b 200 32; /* better (256+) -> 256 bits */
kadonotakashi 0:8fdf9a60065b 201
kadonotakashi 0:8fdf9a60065b 202 /*
kadonotakashi 0:8fdf9a60065b 203 * For initialisation, use more entropy to emulate a nonce
kadonotakashi 0:8fdf9a60065b 204 * (Again, matches test vectors.)
kadonotakashi 0:8fdf9a60065b 205 */
kadonotakashi 0:8fdf9a60065b 206 ctx->entropy_len = entropy_len * 3 / 2;
kadonotakashi 0:8fdf9a60065b 207
kadonotakashi 0:8fdf9a60065b 208 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
kadonotakashi 0:8fdf9a60065b 209 return( ret );
kadonotakashi 0:8fdf9a60065b 210
kadonotakashi 0:8fdf9a60065b 211 ctx->entropy_len = entropy_len;
kadonotakashi 0:8fdf9a60065b 212
kadonotakashi 0:8fdf9a60065b 213 return( 0 );
kadonotakashi 0:8fdf9a60065b 214 }
kadonotakashi 0:8fdf9a60065b 215
kadonotakashi 0:8fdf9a60065b 216 /*
kadonotakashi 0:8fdf9a60065b 217 * Set prediction resistance
kadonotakashi 0:8fdf9a60065b 218 */
kadonotakashi 0:8fdf9a60065b 219 void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
kadonotakashi 0:8fdf9a60065b 220 int resistance )
kadonotakashi 0:8fdf9a60065b 221 {
kadonotakashi 0:8fdf9a60065b 222 ctx->prediction_resistance = resistance;
kadonotakashi 0:8fdf9a60065b 223 }
kadonotakashi 0:8fdf9a60065b 224
kadonotakashi 0:8fdf9a60065b 225 /*
kadonotakashi 0:8fdf9a60065b 226 * Set entropy length grabbed for reseeds
kadonotakashi 0:8fdf9a60065b 227 */
kadonotakashi 0:8fdf9a60065b 228 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
kadonotakashi 0:8fdf9a60065b 229 {
kadonotakashi 0:8fdf9a60065b 230 ctx->entropy_len = len;
kadonotakashi 0:8fdf9a60065b 231 }
kadonotakashi 0:8fdf9a60065b 232
kadonotakashi 0:8fdf9a60065b 233 /*
kadonotakashi 0:8fdf9a60065b 234 * Set reseed interval
kadonotakashi 0:8fdf9a60065b 235 */
kadonotakashi 0:8fdf9a60065b 236 void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
kadonotakashi 0:8fdf9a60065b 237 {
kadonotakashi 0:8fdf9a60065b 238 ctx->reseed_interval = interval;
kadonotakashi 0:8fdf9a60065b 239 }
kadonotakashi 0:8fdf9a60065b 240
kadonotakashi 0:8fdf9a60065b 241 /*
kadonotakashi 0:8fdf9a60065b 242 * HMAC_DRBG random function with optional additional data:
kadonotakashi 0:8fdf9a60065b 243 * 10.1.2.5 (arabic) + 9.3 (Roman)
kadonotakashi 0:8fdf9a60065b 244 */
kadonotakashi 0:8fdf9a60065b 245 int mbedtls_hmac_drbg_random_with_add( void *p_rng,
kadonotakashi 0:8fdf9a60065b 246 unsigned char *output, size_t out_len,
kadonotakashi 0:8fdf9a60065b 247 const unsigned char *additional, size_t add_len )
kadonotakashi 0:8fdf9a60065b 248 {
kadonotakashi 0:8fdf9a60065b 249 int ret;
kadonotakashi 0:8fdf9a60065b 250 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
kadonotakashi 0:8fdf9a60065b 251 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
kadonotakashi 0:8fdf9a60065b 252 size_t left = out_len;
kadonotakashi 0:8fdf9a60065b 253 unsigned char *out = output;
kadonotakashi 0:8fdf9a60065b 254
kadonotakashi 0:8fdf9a60065b 255 /* II. Check request length */
kadonotakashi 0:8fdf9a60065b 256 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
kadonotakashi 0:8fdf9a60065b 257 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
kadonotakashi 0:8fdf9a60065b 258
kadonotakashi 0:8fdf9a60065b 259 /* III. Check input length */
kadonotakashi 0:8fdf9a60065b 260 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
kadonotakashi 0:8fdf9a60065b 261 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
kadonotakashi 0:8fdf9a60065b 262
kadonotakashi 0:8fdf9a60065b 263 /* 1. (aka VII and IX) Check reseed counter and PR */
kadonotakashi 0:8fdf9a60065b 264 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
kadonotakashi 0:8fdf9a60065b 265 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
kadonotakashi 0:8fdf9a60065b 266 ctx->reseed_counter > ctx->reseed_interval ) )
kadonotakashi 0:8fdf9a60065b 267 {
kadonotakashi 0:8fdf9a60065b 268 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
kadonotakashi 0:8fdf9a60065b 269 return( ret );
kadonotakashi 0:8fdf9a60065b 270
kadonotakashi 0:8fdf9a60065b 271 add_len = 0; /* VII.4 */
kadonotakashi 0:8fdf9a60065b 272 }
kadonotakashi 0:8fdf9a60065b 273
kadonotakashi 0:8fdf9a60065b 274 /* 2. Use additional data if any */
kadonotakashi 0:8fdf9a60065b 275 if( additional != NULL && add_len != 0 )
kadonotakashi 0:8fdf9a60065b 276 mbedtls_hmac_drbg_update( ctx, additional, add_len );
kadonotakashi 0:8fdf9a60065b 277
kadonotakashi 0:8fdf9a60065b 278 /* 3, 4, 5. Generate bytes */
kadonotakashi 0:8fdf9a60065b 279 while( left != 0 )
kadonotakashi 0:8fdf9a60065b 280 {
kadonotakashi 0:8fdf9a60065b 281 size_t use_len = left > md_len ? md_len : left;
kadonotakashi 0:8fdf9a60065b 282
kadonotakashi 0:8fdf9a60065b 283 mbedtls_md_hmac_reset( &ctx->md_ctx );
kadonotakashi 0:8fdf9a60065b 284 mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
kadonotakashi 0:8fdf9a60065b 285 mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
kadonotakashi 0:8fdf9a60065b 286
kadonotakashi 0:8fdf9a60065b 287 memcpy( out, ctx->V, use_len );
kadonotakashi 0:8fdf9a60065b 288 out += use_len;
kadonotakashi 0:8fdf9a60065b 289 left -= use_len;
kadonotakashi 0:8fdf9a60065b 290 }
kadonotakashi 0:8fdf9a60065b 291
kadonotakashi 0:8fdf9a60065b 292 /* 6. Update */
kadonotakashi 0:8fdf9a60065b 293 mbedtls_hmac_drbg_update( ctx, additional, add_len );
kadonotakashi 0:8fdf9a60065b 294
kadonotakashi 0:8fdf9a60065b 295 /* 7. Update reseed counter */
kadonotakashi 0:8fdf9a60065b 296 ctx->reseed_counter++;
kadonotakashi 0:8fdf9a60065b 297
kadonotakashi 0:8fdf9a60065b 298 /* 8. Done */
kadonotakashi 0:8fdf9a60065b 299 return( 0 );
kadonotakashi 0:8fdf9a60065b 300 }
kadonotakashi 0:8fdf9a60065b 301
kadonotakashi 0:8fdf9a60065b 302 /*
kadonotakashi 0:8fdf9a60065b 303 * HMAC_DRBG random function
kadonotakashi 0:8fdf9a60065b 304 */
kadonotakashi 0:8fdf9a60065b 305 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
kadonotakashi 0:8fdf9a60065b 306 {
kadonotakashi 0:8fdf9a60065b 307 int ret;
kadonotakashi 0:8fdf9a60065b 308 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
kadonotakashi 0:8fdf9a60065b 309
kadonotakashi 0:8fdf9a60065b 310 #if defined(MBEDTLS_THREADING_C)
kadonotakashi 0:8fdf9a60065b 311 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
kadonotakashi 0:8fdf9a60065b 312 return( ret );
kadonotakashi 0:8fdf9a60065b 313 #endif
kadonotakashi 0:8fdf9a60065b 314
kadonotakashi 0:8fdf9a60065b 315 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
kadonotakashi 0:8fdf9a60065b 316
kadonotakashi 0:8fdf9a60065b 317 #if defined(MBEDTLS_THREADING_C)
kadonotakashi 0:8fdf9a60065b 318 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
kadonotakashi 0:8fdf9a60065b 319 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
kadonotakashi 0:8fdf9a60065b 320 #endif
kadonotakashi 0:8fdf9a60065b 321
kadonotakashi 0:8fdf9a60065b 322 return( ret );
kadonotakashi 0:8fdf9a60065b 323 }
kadonotakashi 0:8fdf9a60065b 324
kadonotakashi 0:8fdf9a60065b 325 /*
kadonotakashi 0:8fdf9a60065b 326 * Free an HMAC_DRBG context
kadonotakashi 0:8fdf9a60065b 327 */
kadonotakashi 0:8fdf9a60065b 328 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
kadonotakashi 0:8fdf9a60065b 329 {
kadonotakashi 0:8fdf9a60065b 330 if( ctx == NULL )
kadonotakashi 0:8fdf9a60065b 331 return;
kadonotakashi 0:8fdf9a60065b 332
kadonotakashi 0:8fdf9a60065b 333 #if defined(MBEDTLS_THREADING_C)
kadonotakashi 0:8fdf9a60065b 334 mbedtls_mutex_free( &ctx->mutex );
kadonotakashi 0:8fdf9a60065b 335 #endif
kadonotakashi 0:8fdf9a60065b 336 mbedtls_md_free( &ctx->md_ctx );
kadonotakashi 0:8fdf9a60065b 337 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
kadonotakashi 0:8fdf9a60065b 338 }
kadonotakashi 0:8fdf9a60065b 339
kadonotakashi 0:8fdf9a60065b 340 #if defined(MBEDTLS_FS_IO)
kadonotakashi 0:8fdf9a60065b 341 int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
kadonotakashi 0:8fdf9a60065b 342 {
kadonotakashi 0:8fdf9a60065b 343 int ret;
kadonotakashi 0:8fdf9a60065b 344 FILE *f;
kadonotakashi 0:8fdf9a60065b 345 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
kadonotakashi 0:8fdf9a60065b 346
kadonotakashi 0:8fdf9a60065b 347 if( ( f = fopen( path, "wb" ) ) == NULL )
kadonotakashi 0:8fdf9a60065b 348 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
kadonotakashi 0:8fdf9a60065b 349
kadonotakashi 0:8fdf9a60065b 350 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
kadonotakashi 0:8fdf9a60065b 351 goto exit;
kadonotakashi 0:8fdf9a60065b 352
kadonotakashi 0:8fdf9a60065b 353 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
kadonotakashi 0:8fdf9a60065b 354 {
kadonotakashi 0:8fdf9a60065b 355 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
kadonotakashi 0:8fdf9a60065b 356 goto exit;
kadonotakashi 0:8fdf9a60065b 357 }
kadonotakashi 0:8fdf9a60065b 358
kadonotakashi 0:8fdf9a60065b 359 ret = 0;
kadonotakashi 0:8fdf9a60065b 360
kadonotakashi 0:8fdf9a60065b 361 exit:
kadonotakashi 0:8fdf9a60065b 362 fclose( f );
kadonotakashi 0:8fdf9a60065b 363 mbedtls_platform_zeroize( buf, sizeof( buf ) );
kadonotakashi 0:8fdf9a60065b 364
kadonotakashi 0:8fdf9a60065b 365 return( ret );
kadonotakashi 0:8fdf9a60065b 366 }
kadonotakashi 0:8fdf9a60065b 367
kadonotakashi 0:8fdf9a60065b 368 int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
kadonotakashi 0:8fdf9a60065b 369 {
kadonotakashi 0:8fdf9a60065b 370 int ret = 0;
kadonotakashi 0:8fdf9a60065b 371 FILE *f;
kadonotakashi 0:8fdf9a60065b 372 size_t n;
kadonotakashi 0:8fdf9a60065b 373 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
kadonotakashi 0:8fdf9a60065b 374
kadonotakashi 0:8fdf9a60065b 375 if( ( f = fopen( path, "rb" ) ) == NULL )
kadonotakashi 0:8fdf9a60065b 376 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
kadonotakashi 0:8fdf9a60065b 377
kadonotakashi 0:8fdf9a60065b 378 fseek( f, 0, SEEK_END );
kadonotakashi 0:8fdf9a60065b 379 n = (size_t) ftell( f );
kadonotakashi 0:8fdf9a60065b 380 fseek( f, 0, SEEK_SET );
kadonotakashi 0:8fdf9a60065b 381
kadonotakashi 0:8fdf9a60065b 382 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
kadonotakashi 0:8fdf9a60065b 383 {
kadonotakashi 0:8fdf9a60065b 384 fclose( f );
kadonotakashi 0:8fdf9a60065b 385 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
kadonotakashi 0:8fdf9a60065b 386 }
kadonotakashi 0:8fdf9a60065b 387
kadonotakashi 0:8fdf9a60065b 388 if( fread( buf, 1, n, f ) != n )
kadonotakashi 0:8fdf9a60065b 389 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
kadonotakashi 0:8fdf9a60065b 390 else
kadonotakashi 0:8fdf9a60065b 391 mbedtls_hmac_drbg_update( ctx, buf, n );
kadonotakashi 0:8fdf9a60065b 392
kadonotakashi 0:8fdf9a60065b 393 fclose( f );
kadonotakashi 0:8fdf9a60065b 394
kadonotakashi 0:8fdf9a60065b 395 mbedtls_platform_zeroize( buf, sizeof( buf ) );
kadonotakashi 0:8fdf9a60065b 396
kadonotakashi 0:8fdf9a60065b 397 if( ret != 0 )
kadonotakashi 0:8fdf9a60065b 398 return( ret );
kadonotakashi 0:8fdf9a60065b 399
kadonotakashi 0:8fdf9a60065b 400 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
kadonotakashi 0:8fdf9a60065b 401 }
kadonotakashi 0:8fdf9a60065b 402 #endif /* MBEDTLS_FS_IO */
kadonotakashi 0:8fdf9a60065b 403
kadonotakashi 0:8fdf9a60065b 404
kadonotakashi 0:8fdf9a60065b 405 #if defined(MBEDTLS_SELF_TEST)
kadonotakashi 0:8fdf9a60065b 406
kadonotakashi 0:8fdf9a60065b 407 #if !defined(MBEDTLS_SHA1_C)
kadonotakashi 0:8fdf9a60065b 408 /* Dummy checkup routine */
kadonotakashi 0:8fdf9a60065b 409 int mbedtls_hmac_drbg_self_test( int verbose )
kadonotakashi 0:8fdf9a60065b 410 {
kadonotakashi 0:8fdf9a60065b 411 (void) verbose;
kadonotakashi 0:8fdf9a60065b 412 return( 0 );
kadonotakashi 0:8fdf9a60065b 413 }
kadonotakashi 0:8fdf9a60065b 414 #else
kadonotakashi 0:8fdf9a60065b 415
kadonotakashi 0:8fdf9a60065b 416 #define OUTPUT_LEN 80
kadonotakashi 0:8fdf9a60065b 417
kadonotakashi 0:8fdf9a60065b 418 /* From a NIST PR=true test vector */
kadonotakashi 0:8fdf9a60065b 419 static const unsigned char entropy_pr[] = {
kadonotakashi 0:8fdf9a60065b 420 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
kadonotakashi 0:8fdf9a60065b 421 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
kadonotakashi 0:8fdf9a60065b 422 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
kadonotakashi 0:8fdf9a60065b 423 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
kadonotakashi 0:8fdf9a60065b 424 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
kadonotakashi 0:8fdf9a60065b 425 static const unsigned char result_pr[OUTPUT_LEN] = {
kadonotakashi 0:8fdf9a60065b 426 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
kadonotakashi 0:8fdf9a60065b 427 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
kadonotakashi 0:8fdf9a60065b 428 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
kadonotakashi 0:8fdf9a60065b 429 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
kadonotakashi 0:8fdf9a60065b 430 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
kadonotakashi 0:8fdf9a60065b 431 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
kadonotakashi 0:8fdf9a60065b 432 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
kadonotakashi 0:8fdf9a60065b 433
kadonotakashi 0:8fdf9a60065b 434 /* From a NIST PR=false test vector */
kadonotakashi 0:8fdf9a60065b 435 static const unsigned char entropy_nopr[] = {
kadonotakashi 0:8fdf9a60065b 436 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
kadonotakashi 0:8fdf9a60065b 437 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
kadonotakashi 0:8fdf9a60065b 438 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
kadonotakashi 0:8fdf9a60065b 439 0xe9, 0x9d, 0xfe, 0xdf };
kadonotakashi 0:8fdf9a60065b 440 static const unsigned char result_nopr[OUTPUT_LEN] = {
kadonotakashi 0:8fdf9a60065b 441 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
kadonotakashi 0:8fdf9a60065b 442 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
kadonotakashi 0:8fdf9a60065b 443 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
kadonotakashi 0:8fdf9a60065b 444 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
kadonotakashi 0:8fdf9a60065b 445 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
kadonotakashi 0:8fdf9a60065b 446 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
kadonotakashi 0:8fdf9a60065b 447 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
kadonotakashi 0:8fdf9a60065b 448
kadonotakashi 0:8fdf9a60065b 449 /* "Entropy" from buffer */
kadonotakashi 0:8fdf9a60065b 450 static size_t test_offset;
kadonotakashi 0:8fdf9a60065b 451 static int hmac_drbg_self_test_entropy( void *data,
kadonotakashi 0:8fdf9a60065b 452 unsigned char *buf, size_t len )
kadonotakashi 0:8fdf9a60065b 453 {
kadonotakashi 0:8fdf9a60065b 454 const unsigned char *p = data;
kadonotakashi 0:8fdf9a60065b 455 memcpy( buf, p + test_offset, len );
kadonotakashi 0:8fdf9a60065b 456 test_offset += len;
kadonotakashi 0:8fdf9a60065b 457 return( 0 );
kadonotakashi 0:8fdf9a60065b 458 }
kadonotakashi 0:8fdf9a60065b 459
kadonotakashi 0:8fdf9a60065b 460 #define CHK( c ) if( (c) != 0 ) \
kadonotakashi 0:8fdf9a60065b 461 { \
kadonotakashi 0:8fdf9a60065b 462 if( verbose != 0 ) \
kadonotakashi 0:8fdf9a60065b 463 mbedtls_printf( "failed\n" ); \
kadonotakashi 0:8fdf9a60065b 464 return( 1 ); \
kadonotakashi 0:8fdf9a60065b 465 }
kadonotakashi 0:8fdf9a60065b 466
kadonotakashi 0:8fdf9a60065b 467 /*
kadonotakashi 0:8fdf9a60065b 468 * Checkup routine for HMAC_DRBG with SHA-1
kadonotakashi 0:8fdf9a60065b 469 */
kadonotakashi 0:8fdf9a60065b 470 int mbedtls_hmac_drbg_self_test( int verbose )
kadonotakashi 0:8fdf9a60065b 471 {
kadonotakashi 0:8fdf9a60065b 472 mbedtls_hmac_drbg_context ctx;
kadonotakashi 0:8fdf9a60065b 473 unsigned char buf[OUTPUT_LEN];
kadonotakashi 0:8fdf9a60065b 474 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
kadonotakashi 0:8fdf9a60065b 475
kadonotakashi 0:8fdf9a60065b 476 mbedtls_hmac_drbg_init( &ctx );
kadonotakashi 0:8fdf9a60065b 477
kadonotakashi 0:8fdf9a60065b 478 /*
kadonotakashi 0:8fdf9a60065b 479 * PR = True
kadonotakashi 0:8fdf9a60065b 480 */
kadonotakashi 0:8fdf9a60065b 481 if( verbose != 0 )
kadonotakashi 0:8fdf9a60065b 482 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
kadonotakashi 0:8fdf9a60065b 483
kadonotakashi 0:8fdf9a60065b 484 test_offset = 0;
kadonotakashi 0:8fdf9a60065b 485 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
kadonotakashi 0:8fdf9a60065b 486 hmac_drbg_self_test_entropy, (void *) entropy_pr,
kadonotakashi 0:8fdf9a60065b 487 NULL, 0 ) );
kadonotakashi 0:8fdf9a60065b 488 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
kadonotakashi 0:8fdf9a60065b 489 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
kadonotakashi 0:8fdf9a60065b 490 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
kadonotakashi 0:8fdf9a60065b 491 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
kadonotakashi 0:8fdf9a60065b 492 mbedtls_hmac_drbg_free( &ctx );
kadonotakashi 0:8fdf9a60065b 493
kadonotakashi 0:8fdf9a60065b 494 mbedtls_hmac_drbg_free( &ctx );
kadonotakashi 0:8fdf9a60065b 495
kadonotakashi 0:8fdf9a60065b 496 if( verbose != 0 )
kadonotakashi 0:8fdf9a60065b 497 mbedtls_printf( "passed\n" );
kadonotakashi 0:8fdf9a60065b 498
kadonotakashi 0:8fdf9a60065b 499 /*
kadonotakashi 0:8fdf9a60065b 500 * PR = False
kadonotakashi 0:8fdf9a60065b 501 */
kadonotakashi 0:8fdf9a60065b 502 if( verbose != 0 )
kadonotakashi 0:8fdf9a60065b 503 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
kadonotakashi 0:8fdf9a60065b 504
kadonotakashi 0:8fdf9a60065b 505 mbedtls_hmac_drbg_init( &ctx );
kadonotakashi 0:8fdf9a60065b 506
kadonotakashi 0:8fdf9a60065b 507 test_offset = 0;
kadonotakashi 0:8fdf9a60065b 508 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
kadonotakashi 0:8fdf9a60065b 509 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
kadonotakashi 0:8fdf9a60065b 510 NULL, 0 ) );
kadonotakashi 0:8fdf9a60065b 511 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
kadonotakashi 0:8fdf9a60065b 512 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
kadonotakashi 0:8fdf9a60065b 513 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
kadonotakashi 0:8fdf9a60065b 514 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
kadonotakashi 0:8fdf9a60065b 515 mbedtls_hmac_drbg_free( &ctx );
kadonotakashi 0:8fdf9a60065b 516
kadonotakashi 0:8fdf9a60065b 517 mbedtls_hmac_drbg_free( &ctx );
kadonotakashi 0:8fdf9a60065b 518
kadonotakashi 0:8fdf9a60065b 519 if( verbose != 0 )
kadonotakashi 0:8fdf9a60065b 520 mbedtls_printf( "passed\n" );
kadonotakashi 0:8fdf9a60065b 521
kadonotakashi 0:8fdf9a60065b 522 if( verbose != 0 )
kadonotakashi 0:8fdf9a60065b 523 mbedtls_printf( "\n" );
kadonotakashi 0:8fdf9a60065b 524
kadonotakashi 0:8fdf9a60065b 525 return( 0 );
kadonotakashi 0:8fdf9a60065b 526 }
kadonotakashi 0:8fdf9a60065b 527 #endif /* MBEDTLS_SHA1_C */
kadonotakashi 0:8fdf9a60065b 528 #endif /* MBEDTLS_SELF_TEST */
kadonotakashi 0:8fdf9a60065b 529
kadonotakashi 0:8fdf9a60065b 530 #endif /* MBEDTLS_HMAC_DRBG_C */