Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:27:58 2016 +0000
Revision:
0:6c56fb4bc5f0
Moving to library for sharing updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 0:6c56fb4bc5f0 1 /**
nexpaq 0:6c56fb4bc5f0 2 * \file pkcs5.c
nexpaq 0:6c56fb4bc5f0 3 *
nexpaq 0:6c56fb4bc5f0 4 * \brief PKCS#5 functions
nexpaq 0:6c56fb4bc5f0 5 *
nexpaq 0:6c56fb4bc5f0 6 * \author Mathias Olsson <mathias@kompetensum.com>
nexpaq 0:6c56fb4bc5f0 7 *
nexpaq 0:6c56fb4bc5f0 8 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
nexpaq 0:6c56fb4bc5f0 9 * SPDX-License-Identifier: Apache-2.0
nexpaq 0:6c56fb4bc5f0 10 *
nexpaq 0:6c56fb4bc5f0 11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
nexpaq 0:6c56fb4bc5f0 12 * not use this file except in compliance with the License.
nexpaq 0:6c56fb4bc5f0 13 * You may obtain a copy of the License at
nexpaq 0:6c56fb4bc5f0 14 *
nexpaq 0:6c56fb4bc5f0 15 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 0:6c56fb4bc5f0 16 *
nexpaq 0:6c56fb4bc5f0 17 * Unless required by applicable law or agreed to in writing, software
nexpaq 0:6c56fb4bc5f0 18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
nexpaq 0:6c56fb4bc5f0 19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 0:6c56fb4bc5f0 20 * See the License for the specific language governing permissions and
nexpaq 0:6c56fb4bc5f0 21 * limitations under the License.
nexpaq 0:6c56fb4bc5f0 22 *
nexpaq 0:6c56fb4bc5f0 23 * This file is part of mbed TLS (https://tls.mbed.org)
nexpaq 0:6c56fb4bc5f0 24 */
nexpaq 0:6c56fb4bc5f0 25 /*
nexpaq 0:6c56fb4bc5f0 26 * PKCS#5 includes PBKDF2 and more
nexpaq 0:6c56fb4bc5f0 27 *
nexpaq 0:6c56fb4bc5f0 28 * http://tools.ietf.org/html/rfc2898 (Specification)
nexpaq 0:6c56fb4bc5f0 29 * http://tools.ietf.org/html/rfc6070 (Test vectors)
nexpaq 0:6c56fb4bc5f0 30 */
nexpaq 0:6c56fb4bc5f0 31
nexpaq 0:6c56fb4bc5f0 32 #if !defined(MBEDTLS_CONFIG_FILE)
nexpaq 0:6c56fb4bc5f0 33 #include "mbedtls/config.h"
nexpaq 0:6c56fb4bc5f0 34 #else
nexpaq 0:6c56fb4bc5f0 35 #include MBEDTLS_CONFIG_FILE
nexpaq 0:6c56fb4bc5f0 36 #endif
nexpaq 0:6c56fb4bc5f0 37
nexpaq 0:6c56fb4bc5f0 38 #if defined(MBEDTLS_PKCS5_C)
nexpaq 0:6c56fb4bc5f0 39
nexpaq 0:6c56fb4bc5f0 40 #include "mbedtls/pkcs5.h"
nexpaq 0:6c56fb4bc5f0 41 #include "mbedtls/asn1.h"
nexpaq 0:6c56fb4bc5f0 42 #include "mbedtls/cipher.h"
nexpaq 0:6c56fb4bc5f0 43 #include "mbedtls/oid.h"
nexpaq 0:6c56fb4bc5f0 44
nexpaq 0:6c56fb4bc5f0 45 #include <string.h>
nexpaq 0:6c56fb4bc5f0 46
nexpaq 0:6c56fb4bc5f0 47 #if defined(MBEDTLS_PLATFORM_C)
nexpaq 0:6c56fb4bc5f0 48 #include "mbedtls/platform.h"
nexpaq 0:6c56fb4bc5f0 49 #else
nexpaq 0:6c56fb4bc5f0 50 #include <stdio.h>
nexpaq 0:6c56fb4bc5f0 51 #define mbedtls_printf printf
nexpaq 0:6c56fb4bc5f0 52 #endif
nexpaq 0:6c56fb4bc5f0 53
nexpaq 0:6c56fb4bc5f0 54 static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
nexpaq 0:6c56fb4bc5f0 55 mbedtls_asn1_buf *salt, int *iterations,
nexpaq 0:6c56fb4bc5f0 56 int *keylen, mbedtls_md_type_t *md_type )
nexpaq 0:6c56fb4bc5f0 57 {
nexpaq 0:6c56fb4bc5f0 58 int ret;
nexpaq 0:6c56fb4bc5f0 59 mbedtls_asn1_buf prf_alg_oid;
nexpaq 0:6c56fb4bc5f0 60 unsigned char *p = params->p;
nexpaq 0:6c56fb4bc5f0 61 const unsigned char *end = params->p + params->len;
nexpaq 0:6c56fb4bc5f0 62
nexpaq 0:6c56fb4bc5f0 63 if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
nexpaq 0:6c56fb4bc5f0 64 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
nexpaq 0:6c56fb4bc5f0 65 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
nexpaq 0:6c56fb4bc5f0 66 /*
nexpaq 0:6c56fb4bc5f0 67 * PBKDF2-params ::= SEQUENCE {
nexpaq 0:6c56fb4bc5f0 68 * salt OCTET STRING,
nexpaq 0:6c56fb4bc5f0 69 * iterationCount INTEGER,
nexpaq 0:6c56fb4bc5f0 70 * keyLength INTEGER OPTIONAL
nexpaq 0:6c56fb4bc5f0 71 * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1
nexpaq 0:6c56fb4bc5f0 72 * }
nexpaq 0:6c56fb4bc5f0 73 *
nexpaq 0:6c56fb4bc5f0 74 */
nexpaq 0:6c56fb4bc5f0 75 if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 76 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 77
nexpaq 0:6c56fb4bc5f0 78 salt->p = p;
nexpaq 0:6c56fb4bc5f0 79 p += salt->len;
nexpaq 0:6c56fb4bc5f0 80
nexpaq 0:6c56fb4bc5f0 81 if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 82 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 83
nexpaq 0:6c56fb4bc5f0 84 if( p == end )
nexpaq 0:6c56fb4bc5f0 85 return( 0 );
nexpaq 0:6c56fb4bc5f0 86
nexpaq 0:6c56fb4bc5f0 87 if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 88 {
nexpaq 0:6c56fb4bc5f0 89 if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
nexpaq 0:6c56fb4bc5f0 90 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 91 }
nexpaq 0:6c56fb4bc5f0 92
nexpaq 0:6c56fb4bc5f0 93 if( p == end )
nexpaq 0:6c56fb4bc5f0 94 return( 0 );
nexpaq 0:6c56fb4bc5f0 95
nexpaq 0:6c56fb4bc5f0 96 if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 97 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 98
nexpaq 0:6c56fb4bc5f0 99 if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 )
nexpaq 0:6c56fb4bc5f0 100 return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
nexpaq 0:6c56fb4bc5f0 101
nexpaq 0:6c56fb4bc5f0 102 *md_type = MBEDTLS_MD_SHA1;
nexpaq 0:6c56fb4bc5f0 103
nexpaq 0:6c56fb4bc5f0 104 if( p != end )
nexpaq 0:6c56fb4bc5f0 105 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
nexpaq 0:6c56fb4bc5f0 106 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
nexpaq 0:6c56fb4bc5f0 107
nexpaq 0:6c56fb4bc5f0 108 return( 0 );
nexpaq 0:6c56fb4bc5f0 109 }
nexpaq 0:6c56fb4bc5f0 110
nexpaq 0:6c56fb4bc5f0 111 int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
nexpaq 0:6c56fb4bc5f0 112 const unsigned char *pwd, size_t pwdlen,
nexpaq 0:6c56fb4bc5f0 113 const unsigned char *data, size_t datalen,
nexpaq 0:6c56fb4bc5f0 114 unsigned char *output )
nexpaq 0:6c56fb4bc5f0 115 {
nexpaq 0:6c56fb4bc5f0 116 int ret, iterations = 0, keylen = 0;
nexpaq 0:6c56fb4bc5f0 117 unsigned char *p, *end;
nexpaq 0:6c56fb4bc5f0 118 mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params;
nexpaq 0:6c56fb4bc5f0 119 mbedtls_asn1_buf salt;
nexpaq 0:6c56fb4bc5f0 120 mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
nexpaq 0:6c56fb4bc5f0 121 unsigned char key[32], iv[32];
nexpaq 0:6c56fb4bc5f0 122 size_t olen = 0;
nexpaq 0:6c56fb4bc5f0 123 const mbedtls_md_info_t *md_info;
nexpaq 0:6c56fb4bc5f0 124 const mbedtls_cipher_info_t *cipher_info;
nexpaq 0:6c56fb4bc5f0 125 mbedtls_md_context_t md_ctx;
nexpaq 0:6c56fb4bc5f0 126 mbedtls_cipher_type_t cipher_alg;
nexpaq 0:6c56fb4bc5f0 127 mbedtls_cipher_context_t cipher_ctx;
nexpaq 0:6c56fb4bc5f0 128
nexpaq 0:6c56fb4bc5f0 129 p = pbe_params->p;
nexpaq 0:6c56fb4bc5f0 130 end = p + pbe_params->len;
nexpaq 0:6c56fb4bc5f0 131
nexpaq 0:6c56fb4bc5f0 132 /*
nexpaq 0:6c56fb4bc5f0 133 * PBES2-params ::= SEQUENCE {
nexpaq 0:6c56fb4bc5f0 134 * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
nexpaq 0:6c56fb4bc5f0 135 * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
nexpaq 0:6c56fb4bc5f0 136 * }
nexpaq 0:6c56fb4bc5f0 137 */
nexpaq 0:6c56fb4bc5f0 138 if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
nexpaq 0:6c56fb4bc5f0 139 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
nexpaq 0:6c56fb4bc5f0 140 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
nexpaq 0:6c56fb4bc5f0 141
nexpaq 0:6c56fb4bc5f0 142 if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 143 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 144
nexpaq 0:6c56fb4bc5f0 145 // Only PBKDF2 supported at the moment
nexpaq 0:6c56fb4bc5f0 146 //
nexpaq 0:6c56fb4bc5f0 147 if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 )
nexpaq 0:6c56fb4bc5f0 148 return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
nexpaq 0:6c56fb4bc5f0 149
nexpaq 0:6c56fb4bc5f0 150 if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params,
nexpaq 0:6c56fb4bc5f0 151 &salt, &iterations, &keylen,
nexpaq 0:6c56fb4bc5f0 152 &md_type ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 153 {
nexpaq 0:6c56fb4bc5f0 154 return( ret );
nexpaq 0:6c56fb4bc5f0 155 }
nexpaq 0:6c56fb4bc5f0 156
nexpaq 0:6c56fb4bc5f0 157 md_info = mbedtls_md_info_from_type( md_type );
nexpaq 0:6c56fb4bc5f0 158 if( md_info == NULL )
nexpaq 0:6c56fb4bc5f0 159 return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
nexpaq 0:6c56fb4bc5f0 160
nexpaq 0:6c56fb4bc5f0 161 if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
nexpaq 0:6c56fb4bc5f0 162 &enc_scheme_params ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 163 {
nexpaq 0:6c56fb4bc5f0 164 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 165 }
nexpaq 0:6c56fb4bc5f0 166
nexpaq 0:6c56fb4bc5f0 167 if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
nexpaq 0:6c56fb4bc5f0 168 return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
nexpaq 0:6c56fb4bc5f0 169
nexpaq 0:6c56fb4bc5f0 170 cipher_info = mbedtls_cipher_info_from_type( cipher_alg );
nexpaq 0:6c56fb4bc5f0 171 if( cipher_info == NULL )
nexpaq 0:6c56fb4bc5f0 172 return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
nexpaq 0:6c56fb4bc5f0 173
nexpaq 0:6c56fb4bc5f0 174 /*
nexpaq 0:6c56fb4bc5f0 175 * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
nexpaq 0:6c56fb4bc5f0 176 * since it is optional and we don't know if it was set or not
nexpaq 0:6c56fb4bc5f0 177 */
nexpaq 0:6c56fb4bc5f0 178 keylen = cipher_info->key_bitlen / 8;
nexpaq 0:6c56fb4bc5f0 179
nexpaq 0:6c56fb4bc5f0 180 if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING ||
nexpaq 0:6c56fb4bc5f0 181 enc_scheme_params.len != cipher_info->iv_size )
nexpaq 0:6c56fb4bc5f0 182 {
nexpaq 0:6c56fb4bc5f0 183 return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT );
nexpaq 0:6c56fb4bc5f0 184 }
nexpaq 0:6c56fb4bc5f0 185
nexpaq 0:6c56fb4bc5f0 186 mbedtls_md_init( &md_ctx );
nexpaq 0:6c56fb4bc5f0 187 mbedtls_cipher_init( &cipher_ctx );
nexpaq 0:6c56fb4bc5f0 188
nexpaq 0:6c56fb4bc5f0 189 memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
nexpaq 0:6c56fb4bc5f0 190
nexpaq 0:6c56fb4bc5f0 191 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 192 goto exit;
nexpaq 0:6c56fb4bc5f0 193
nexpaq 0:6c56fb4bc5f0 194 if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
nexpaq 0:6c56fb4bc5f0 195 iterations, keylen, key ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 196 {
nexpaq 0:6c56fb4bc5f0 197 goto exit;
nexpaq 0:6c56fb4bc5f0 198 }
nexpaq 0:6c56fb4bc5f0 199
nexpaq 0:6c56fb4bc5f0 200 if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 201 goto exit;
nexpaq 0:6c56fb4bc5f0 202
nexpaq 0:6c56fb4bc5f0 203 if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 204 goto exit;
nexpaq 0:6c56fb4bc5f0 205
nexpaq 0:6c56fb4bc5f0 206 if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
nexpaq 0:6c56fb4bc5f0 207 data, datalen, output, &olen ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 208 ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
nexpaq 0:6c56fb4bc5f0 209
nexpaq 0:6c56fb4bc5f0 210 exit:
nexpaq 0:6c56fb4bc5f0 211 mbedtls_md_free( &md_ctx );
nexpaq 0:6c56fb4bc5f0 212 mbedtls_cipher_free( &cipher_ctx );
nexpaq 0:6c56fb4bc5f0 213
nexpaq 0:6c56fb4bc5f0 214 return( ret );
nexpaq 0:6c56fb4bc5f0 215 }
nexpaq 0:6c56fb4bc5f0 216
nexpaq 0:6c56fb4bc5f0 217 int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
nexpaq 0:6c56fb4bc5f0 218 size_t plen, const unsigned char *salt, size_t slen,
nexpaq 0:6c56fb4bc5f0 219 unsigned int iteration_count,
nexpaq 0:6c56fb4bc5f0 220 uint32_t key_length, unsigned char *output )
nexpaq 0:6c56fb4bc5f0 221 {
nexpaq 0:6c56fb4bc5f0 222 int ret, j;
nexpaq 0:6c56fb4bc5f0 223 unsigned int i;
nexpaq 0:6c56fb4bc5f0 224 unsigned char md1[MBEDTLS_MD_MAX_SIZE];
nexpaq 0:6c56fb4bc5f0 225 unsigned char work[MBEDTLS_MD_MAX_SIZE];
nexpaq 0:6c56fb4bc5f0 226 unsigned char md_size = mbedtls_md_get_size( ctx->md_info );
nexpaq 0:6c56fb4bc5f0 227 size_t use_len;
nexpaq 0:6c56fb4bc5f0 228 unsigned char *out_p = output;
nexpaq 0:6c56fb4bc5f0 229 unsigned char counter[4];
nexpaq 0:6c56fb4bc5f0 230
nexpaq 0:6c56fb4bc5f0 231 memset( counter, 0, 4 );
nexpaq 0:6c56fb4bc5f0 232 counter[3] = 1;
nexpaq 0:6c56fb4bc5f0 233
nexpaq 0:6c56fb4bc5f0 234 if( iteration_count > 0xFFFFFFFF )
nexpaq 0:6c56fb4bc5f0 235 return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
nexpaq 0:6c56fb4bc5f0 236
nexpaq 0:6c56fb4bc5f0 237 while( key_length )
nexpaq 0:6c56fb4bc5f0 238 {
nexpaq 0:6c56fb4bc5f0 239 // U1 ends up in work
nexpaq 0:6c56fb4bc5f0 240 //
nexpaq 0:6c56fb4bc5f0 241 if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 242 return( ret );
nexpaq 0:6c56fb4bc5f0 243
nexpaq 0:6c56fb4bc5f0 244 if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 245 return( ret );
nexpaq 0:6c56fb4bc5f0 246
nexpaq 0:6c56fb4bc5f0 247 if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 248 return( ret );
nexpaq 0:6c56fb4bc5f0 249
nexpaq 0:6c56fb4bc5f0 250 if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 251 return( ret );
nexpaq 0:6c56fb4bc5f0 252
nexpaq 0:6c56fb4bc5f0 253 memcpy( md1, work, md_size );
nexpaq 0:6c56fb4bc5f0 254
nexpaq 0:6c56fb4bc5f0 255 for( i = 1; i < iteration_count; i++ )
nexpaq 0:6c56fb4bc5f0 256 {
nexpaq 0:6c56fb4bc5f0 257 // U2 ends up in md1
nexpaq 0:6c56fb4bc5f0 258 //
nexpaq 0:6c56fb4bc5f0 259 if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 260 return( ret );
nexpaq 0:6c56fb4bc5f0 261
nexpaq 0:6c56fb4bc5f0 262 if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 263 return( ret );
nexpaq 0:6c56fb4bc5f0 264
nexpaq 0:6c56fb4bc5f0 265 if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 266 return( ret );
nexpaq 0:6c56fb4bc5f0 267
nexpaq 0:6c56fb4bc5f0 268 // U1 xor U2
nexpaq 0:6c56fb4bc5f0 269 //
nexpaq 0:6c56fb4bc5f0 270 for( j = 0; j < md_size; j++ )
nexpaq 0:6c56fb4bc5f0 271 work[j] ^= md1[j];
nexpaq 0:6c56fb4bc5f0 272 }
nexpaq 0:6c56fb4bc5f0 273
nexpaq 0:6c56fb4bc5f0 274 use_len = ( key_length < md_size ) ? key_length : md_size;
nexpaq 0:6c56fb4bc5f0 275 memcpy( out_p, work, use_len );
nexpaq 0:6c56fb4bc5f0 276
nexpaq 0:6c56fb4bc5f0 277 key_length -= (uint32_t) use_len;
nexpaq 0:6c56fb4bc5f0 278 out_p += use_len;
nexpaq 0:6c56fb4bc5f0 279
nexpaq 0:6c56fb4bc5f0 280 for( i = 4; i > 0; i-- )
nexpaq 0:6c56fb4bc5f0 281 if( ++counter[i - 1] != 0 )
nexpaq 0:6c56fb4bc5f0 282 break;
nexpaq 0:6c56fb4bc5f0 283 }
nexpaq 0:6c56fb4bc5f0 284
nexpaq 0:6c56fb4bc5f0 285 return( 0 );
nexpaq 0:6c56fb4bc5f0 286 }
nexpaq 0:6c56fb4bc5f0 287
nexpaq 0:6c56fb4bc5f0 288 #if defined(MBEDTLS_SELF_TEST)
nexpaq 0:6c56fb4bc5f0 289
nexpaq 0:6c56fb4bc5f0 290 #if !defined(MBEDTLS_SHA1_C)
nexpaq 0:6c56fb4bc5f0 291 int mbedtls_pkcs5_self_test( int verbose )
nexpaq 0:6c56fb4bc5f0 292 {
nexpaq 0:6c56fb4bc5f0 293 if( verbose != 0 )
nexpaq 0:6c56fb4bc5f0 294 mbedtls_printf( " PBKDF2 (SHA1): skipped\n\n" );
nexpaq 0:6c56fb4bc5f0 295
nexpaq 0:6c56fb4bc5f0 296 return( 0 );
nexpaq 0:6c56fb4bc5f0 297 }
nexpaq 0:6c56fb4bc5f0 298 #else
nexpaq 0:6c56fb4bc5f0 299
nexpaq 0:6c56fb4bc5f0 300 #define MAX_TESTS 6
nexpaq 0:6c56fb4bc5f0 301
nexpaq 0:6c56fb4bc5f0 302 static const size_t plen[MAX_TESTS] =
nexpaq 0:6c56fb4bc5f0 303 { 8, 8, 8, 24, 9 };
nexpaq 0:6c56fb4bc5f0 304
nexpaq 0:6c56fb4bc5f0 305 static const unsigned char password[MAX_TESTS][32] =
nexpaq 0:6c56fb4bc5f0 306 {
nexpaq 0:6c56fb4bc5f0 307 "password",
nexpaq 0:6c56fb4bc5f0 308 "password",
nexpaq 0:6c56fb4bc5f0 309 "password",
nexpaq 0:6c56fb4bc5f0 310 "passwordPASSWORDpassword",
nexpaq 0:6c56fb4bc5f0 311 "pass\0word",
nexpaq 0:6c56fb4bc5f0 312 };
nexpaq 0:6c56fb4bc5f0 313
nexpaq 0:6c56fb4bc5f0 314 static const size_t slen[MAX_TESTS] =
nexpaq 0:6c56fb4bc5f0 315 { 4, 4, 4, 36, 5 };
nexpaq 0:6c56fb4bc5f0 316
nexpaq 0:6c56fb4bc5f0 317 static const unsigned char salt[MAX_TESTS][40] =
nexpaq 0:6c56fb4bc5f0 318 {
nexpaq 0:6c56fb4bc5f0 319 "salt",
nexpaq 0:6c56fb4bc5f0 320 "salt",
nexpaq 0:6c56fb4bc5f0 321 "salt",
nexpaq 0:6c56fb4bc5f0 322 "saltSALTsaltSALTsaltSALTsaltSALTsalt",
nexpaq 0:6c56fb4bc5f0 323 "sa\0lt",
nexpaq 0:6c56fb4bc5f0 324 };
nexpaq 0:6c56fb4bc5f0 325
nexpaq 0:6c56fb4bc5f0 326 static const uint32_t it_cnt[MAX_TESTS] =
nexpaq 0:6c56fb4bc5f0 327 { 1, 2, 4096, 4096, 4096 };
nexpaq 0:6c56fb4bc5f0 328
nexpaq 0:6c56fb4bc5f0 329 static const uint32_t key_len[MAX_TESTS] =
nexpaq 0:6c56fb4bc5f0 330 { 20, 20, 20, 25, 16 };
nexpaq 0:6c56fb4bc5f0 331
nexpaq 0:6c56fb4bc5f0 332 static const unsigned char result_key[MAX_TESTS][32] =
nexpaq 0:6c56fb4bc5f0 333 {
nexpaq 0:6c56fb4bc5f0 334 { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
nexpaq 0:6c56fb4bc5f0 335 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
nexpaq 0:6c56fb4bc5f0 336 0x2f, 0xe0, 0x37, 0xa6 },
nexpaq 0:6c56fb4bc5f0 337 { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
nexpaq 0:6c56fb4bc5f0 338 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
nexpaq 0:6c56fb4bc5f0 339 0xd8, 0xde, 0x89, 0x57 },
nexpaq 0:6c56fb4bc5f0 340 { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
nexpaq 0:6c56fb4bc5f0 341 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
nexpaq 0:6c56fb4bc5f0 342 0x65, 0xa4, 0x29, 0xc1 },
nexpaq 0:6c56fb4bc5f0 343 { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
nexpaq 0:6c56fb4bc5f0 344 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
nexpaq 0:6c56fb4bc5f0 345 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
nexpaq 0:6c56fb4bc5f0 346 0x38 },
nexpaq 0:6c56fb4bc5f0 347 { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
nexpaq 0:6c56fb4bc5f0 348 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
nexpaq 0:6c56fb4bc5f0 349 };
nexpaq 0:6c56fb4bc5f0 350
nexpaq 0:6c56fb4bc5f0 351 int mbedtls_pkcs5_self_test( int verbose )
nexpaq 0:6c56fb4bc5f0 352 {
nexpaq 0:6c56fb4bc5f0 353 mbedtls_md_context_t sha1_ctx;
nexpaq 0:6c56fb4bc5f0 354 const mbedtls_md_info_t *info_sha1;
nexpaq 0:6c56fb4bc5f0 355 int ret, i;
nexpaq 0:6c56fb4bc5f0 356 unsigned char key[64];
nexpaq 0:6c56fb4bc5f0 357
nexpaq 0:6c56fb4bc5f0 358 mbedtls_md_init( &sha1_ctx );
nexpaq 0:6c56fb4bc5f0 359
nexpaq 0:6c56fb4bc5f0 360 info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
nexpaq 0:6c56fb4bc5f0 361 if( info_sha1 == NULL )
nexpaq 0:6c56fb4bc5f0 362 {
nexpaq 0:6c56fb4bc5f0 363 ret = 1;
nexpaq 0:6c56fb4bc5f0 364 goto exit;
nexpaq 0:6c56fb4bc5f0 365 }
nexpaq 0:6c56fb4bc5f0 366
nexpaq 0:6c56fb4bc5f0 367 if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 368 {
nexpaq 0:6c56fb4bc5f0 369 ret = 1;
nexpaq 0:6c56fb4bc5f0 370 goto exit;
nexpaq 0:6c56fb4bc5f0 371 }
nexpaq 0:6c56fb4bc5f0 372
nexpaq 0:6c56fb4bc5f0 373 for( i = 0; i < MAX_TESTS; i++ )
nexpaq 0:6c56fb4bc5f0 374 {
nexpaq 0:6c56fb4bc5f0 375 if( verbose != 0 )
nexpaq 0:6c56fb4bc5f0 376 mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i );
nexpaq 0:6c56fb4bc5f0 377
nexpaq 0:6c56fb4bc5f0 378 ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
nexpaq 0:6c56fb4bc5f0 379 slen[i], it_cnt[i], key_len[i], key );
nexpaq 0:6c56fb4bc5f0 380 if( ret != 0 ||
nexpaq 0:6c56fb4bc5f0 381 memcmp( result_key[i], key, key_len[i] ) != 0 )
nexpaq 0:6c56fb4bc5f0 382 {
nexpaq 0:6c56fb4bc5f0 383 if( verbose != 0 )
nexpaq 0:6c56fb4bc5f0 384 mbedtls_printf( "failed\n" );
nexpaq 0:6c56fb4bc5f0 385
nexpaq 0:6c56fb4bc5f0 386 ret = 1;
nexpaq 0:6c56fb4bc5f0 387 goto exit;
nexpaq 0:6c56fb4bc5f0 388 }
nexpaq 0:6c56fb4bc5f0 389
nexpaq 0:6c56fb4bc5f0 390 if( verbose != 0 )
nexpaq 0:6c56fb4bc5f0 391 mbedtls_printf( "passed\n" );
nexpaq 0:6c56fb4bc5f0 392 }
nexpaq 0:6c56fb4bc5f0 393
nexpaq 0:6c56fb4bc5f0 394 mbedtls_printf( "\n" );
nexpaq 0:6c56fb4bc5f0 395
nexpaq 0:6c56fb4bc5f0 396 exit:
nexpaq 0:6c56fb4bc5f0 397 mbedtls_md_free( &sha1_ctx );
nexpaq 0:6c56fb4bc5f0 398
nexpaq 0:6c56fb4bc5f0 399 return( ret );
nexpaq 0:6c56fb4bc5f0 400 }
nexpaq 0:6c56fb4bc5f0 401 #endif /* MBEDTLS_SHA1_C */
nexpaq 0:6c56fb4bc5f0 402
nexpaq 0:6c56fb4bc5f0 403 #endif /* MBEDTLS_SELF_TEST */
nexpaq 0:6c56fb4bc5f0 404
nexpaq 0:6c56fb4bc5f0 405 #endif /* MBEDTLS_PKCS5_C */