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