This is a fork due to permission issues

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

Committer:
timbeight
Date:
Thu May 19 16:02:10 2016 +0000
Revision:
1:0ddbe2d3319c
Parent:
0:f7c60d3e7b8a
This is my first commit while in the class.

Who changed what in which revision?

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