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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
pkcs12.c
00001 /* 00002 * PKCS#12 Personal Information Exchange Syntax 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 /* 00022 * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 00023 * 00024 * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf 00025 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn 00026 */ 00027 00028 #if !defined(MBEDTLS_CONFIG_FILE) 00029 #include "mbedtls/config.h" 00030 #else 00031 #include MBEDTLS_CONFIG_FILE 00032 #endif 00033 00034 #if defined(MBEDTLS_PKCS12_C) 00035 00036 #include "mbedtls/pkcs12.h" 00037 #include "mbedtls/asn1.h" 00038 #include "mbedtls/cipher.h" 00039 #include "mbedtls/platform_util.h" 00040 00041 #include <string.h> 00042 00043 #if defined(MBEDTLS_ARC4_C) 00044 #include "mbedtls/arc4.h" 00045 #endif 00046 00047 #if defined(MBEDTLS_DES_C) 00048 #include "mbedtls/des.h" 00049 #endif 00050 00051 #if defined(MBEDTLS_ASN1_PARSE_C) 00052 00053 static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, 00054 mbedtls_asn1_buf *salt, int *iterations ) 00055 { 00056 int ret; 00057 unsigned char **p = ¶ms->p; 00058 const unsigned char *end = params->p + params->len; 00059 00060 /* 00061 * pkcs-12PbeParams ::= SEQUENCE { 00062 * salt OCTET STRING, 00063 * iterations INTEGER 00064 * } 00065 * 00066 */ 00067 if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) 00068 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + 00069 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00070 00071 if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) 00072 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); 00073 00074 salt->p = *p; 00075 *p += salt->len; 00076 00077 if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 ) 00078 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); 00079 00080 if( *p != end ) 00081 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + 00082 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00083 00084 return( 0 ); 00085 } 00086 00087 #define PKCS12_MAX_PWDLEN 128 00088 00089 static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, 00090 const unsigned char *pwd, size_t pwdlen, 00091 unsigned char *key, size_t keylen, 00092 unsigned char *iv, size_t ivlen ) 00093 { 00094 int ret, iterations = 0; 00095 mbedtls_asn1_buf salt; 00096 size_t i; 00097 unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; 00098 00099 if( pwdlen > PKCS12_MAX_PWDLEN ) 00100 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 00101 00102 memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); 00103 memset( &unipwd, 0, sizeof(unipwd) ); 00104 00105 if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, 00106 &iterations ) ) != 0 ) 00107 return( ret ); 00108 00109 for( i = 0; i < pwdlen; i++ ) 00110 unipwd[i * 2 + 1] = pwd[i]; 00111 00112 if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, 00113 salt.p, salt.len, md_type, 00114 MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 ) 00115 { 00116 return( ret ); 00117 } 00118 00119 if( iv == NULL || ivlen == 0 ) 00120 return( 0 ); 00121 00122 if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, 00123 salt.p, salt.len, md_type, 00124 MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 ) 00125 { 00126 return( ret ); 00127 } 00128 return( 0 ); 00129 } 00130 00131 #undef PKCS12_MAX_PWDLEN 00132 00133 int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, 00134 const unsigned char *pwd, size_t pwdlen, 00135 const unsigned char *data, size_t len, 00136 unsigned char *output ) 00137 { 00138 #if !defined(MBEDTLS_ARC4_C) 00139 ((void) pbe_params); 00140 ((void) mode); 00141 ((void) pwd); 00142 ((void) pwdlen); 00143 ((void) data); 00144 ((void) len); 00145 ((void) output); 00146 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00147 #else 00148 int ret; 00149 unsigned char key[16]; 00150 mbedtls_arc4_context ctx; 00151 ((void) mode); 00152 00153 mbedtls_arc4_init( &ctx ); 00154 00155 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1, 00156 pwd, pwdlen, 00157 key, 16, NULL, 0 ) ) != 0 ) 00158 { 00159 return( ret ); 00160 } 00161 00162 mbedtls_arc4_setup( &ctx, key, 16 ); 00163 if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 ) 00164 goto exit; 00165 00166 exit: 00167 mbedtls_platform_zeroize( key, sizeof( key ) ); 00168 mbedtls_arc4_free( &ctx ); 00169 00170 return( ret ); 00171 #endif /* MBEDTLS_ARC4_C */ 00172 } 00173 00174 int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, 00175 mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, 00176 const unsigned char *pwd, size_t pwdlen, 00177 const unsigned char *data, size_t len, 00178 unsigned char *output ) 00179 { 00180 int ret, keylen = 0; 00181 unsigned char key[32]; 00182 unsigned char iv[16]; 00183 const mbedtls_cipher_info_t *cipher_info; 00184 mbedtls_cipher_context_t cipher_ctx; 00185 size_t olen = 0; 00186 00187 cipher_info = mbedtls_cipher_info_from_type( cipher_type ); 00188 if( cipher_info == NULL ) 00189 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00190 00191 keylen = cipher_info->key_bitlen / 8; 00192 00193 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, 00194 key, keylen, 00195 iv, cipher_info->iv_size ) ) != 0 ) 00196 { 00197 return( ret ); 00198 } 00199 00200 mbedtls_cipher_init( &cipher_ctx ); 00201 00202 if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) 00203 goto exit; 00204 00205 if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) 00206 goto exit; 00207 00208 if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) 00209 goto exit; 00210 00211 if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 ) 00212 goto exit; 00213 00214 if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len, 00215 output, &olen ) ) != 0 ) 00216 { 00217 goto exit; 00218 } 00219 00220 if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) 00221 ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; 00222 00223 exit: 00224 mbedtls_platform_zeroize( key, sizeof( key ) ); 00225 mbedtls_platform_zeroize( iv, sizeof( iv ) ); 00226 mbedtls_cipher_free( &cipher_ctx ); 00227 00228 return( ret ); 00229 } 00230 00231 #endif /* MBEDTLS_ASN1_PARSE_C */ 00232 00233 static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, 00234 const unsigned char *filler, size_t fill_len ) 00235 { 00236 unsigned char *p = data; 00237 size_t use_len; 00238 00239 while( data_len > 0 ) 00240 { 00241 use_len = ( data_len > fill_len ) ? fill_len : data_len; 00242 memcpy( p, filler, use_len ); 00243 p += use_len; 00244 data_len -= use_len; 00245 } 00246 } 00247 00248 int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, 00249 const unsigned char *pwd, size_t pwdlen, 00250 const unsigned char *salt, size_t saltlen, 00251 mbedtls_md_type_t md_type, int id, int iterations ) 00252 { 00253 int ret; 00254 unsigned int j; 00255 00256 unsigned char diversifier[128]; 00257 unsigned char salt_block[128], pwd_block[128], hash_block[128]; 00258 unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; 00259 unsigned char *p; 00260 unsigned char c; 00261 00262 size_t hlen, use_len, v, i; 00263 00264 const mbedtls_md_info_t *md_info; 00265 mbedtls_md_context_t md_ctx; 00266 00267 // This version only allows max of 64 bytes of password or salt 00268 if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) 00269 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 00270 00271 md_info = mbedtls_md_info_from_type( md_type ); 00272 if( md_info == NULL ) 00273 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00274 00275 mbedtls_md_init( &md_ctx ); 00276 00277 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) 00278 return( ret ); 00279 hlen = mbedtls_md_get_size( md_info ); 00280 00281 if( hlen <= 32 ) 00282 v = 64; 00283 else 00284 v = 128; 00285 00286 memset( diversifier, (unsigned char) id, v ); 00287 00288 pkcs12_fill_buffer( salt_block, v, salt, saltlen ); 00289 pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); 00290 00291 p = data; 00292 while( datalen > 0 ) 00293 { 00294 // Calculate hash( diversifier || salt_block || pwd_block ) 00295 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) 00296 goto exit; 00297 00298 if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 ) 00299 goto exit; 00300 00301 if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 ) 00302 goto exit; 00303 00304 if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 ) 00305 goto exit; 00306 00307 if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 ) 00308 goto exit; 00309 00310 // Perform remaining ( iterations - 1 ) recursive hash calculations 00311 for( i = 1; i < (size_t) iterations; i++ ) 00312 { 00313 if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 ) 00314 goto exit; 00315 } 00316 00317 use_len = ( datalen > hlen ) ? hlen : datalen; 00318 memcpy( p, hash_output, use_len ); 00319 datalen -= use_len; 00320 p += use_len; 00321 00322 if( datalen == 0 ) 00323 break; 00324 00325 // Concatenating copies of hash_output into hash_block (B) 00326 pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); 00327 00328 // B += 1 00329 for( i = v; i > 0; i-- ) 00330 if( ++hash_block[i - 1] != 0 ) 00331 break; 00332 00333 // salt_block += B 00334 c = 0; 00335 for( i = v; i > 0; i-- ) 00336 { 00337 j = salt_block[i - 1] + hash_block[i - 1] + c; 00338 c = (unsigned char) (j >> 8); 00339 salt_block[i - 1] = j & 0xFF; 00340 } 00341 00342 // pwd_block += B 00343 c = 0; 00344 for( i = v; i > 0; i-- ) 00345 { 00346 j = pwd_block[i - 1] + hash_block[i - 1] + c; 00347 c = (unsigned char) (j >> 8); 00348 pwd_block[i - 1] = j & 0xFF; 00349 } 00350 } 00351 00352 ret = 0; 00353 00354 exit: 00355 mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) ); 00356 mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) ); 00357 mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) ); 00358 mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) ); 00359 00360 mbedtls_md_free( &md_ctx ); 00361 00362 return( ret ); 00363 } 00364 00365 #endif /* MBEDTLS_PKCS12_C */
Generated on Tue Jul 12 2022 13:54:41 by
