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.
Dependencies: nRF51_Vdd TextLCD BME280
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 static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, 00052 mbedtls_asn1_buf *salt, int *iterations ) 00053 { 00054 int ret; 00055 unsigned char **p = ¶ms->p; 00056 const unsigned char *end = params->p + params->len; 00057 00058 /* 00059 * pkcs-12PbeParams ::= SEQUENCE { 00060 * salt OCTET STRING, 00061 * iterations INTEGER 00062 * } 00063 * 00064 */ 00065 if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) 00066 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + 00067 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00068 00069 if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) 00070 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); 00071 00072 salt->p = *p; 00073 *p += salt->len; 00074 00075 if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 ) 00076 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); 00077 00078 if( *p != end ) 00079 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + 00080 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00081 00082 return( 0 ); 00083 } 00084 00085 #define PKCS12_MAX_PWDLEN 128 00086 00087 static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, 00088 const unsigned char *pwd, size_t pwdlen, 00089 unsigned char *key, size_t keylen, 00090 unsigned char *iv, size_t ivlen ) 00091 { 00092 int ret, iterations = 0; 00093 mbedtls_asn1_buf salt; 00094 size_t i; 00095 unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; 00096 00097 if( pwdlen > PKCS12_MAX_PWDLEN ) 00098 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 00099 00100 memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); 00101 memset( &unipwd, 0, sizeof(unipwd) ); 00102 00103 if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, 00104 &iterations ) ) != 0 ) 00105 return( ret ); 00106 00107 for( i = 0; i < pwdlen; i++ ) 00108 unipwd[i * 2 + 1] = pwd[i]; 00109 00110 if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, 00111 salt.p, salt.len, md_type, 00112 MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 ) 00113 { 00114 return( ret ); 00115 } 00116 00117 if( iv == NULL || ivlen == 0 ) 00118 return( 0 ); 00119 00120 if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, 00121 salt.p, salt.len, md_type, 00122 MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 ) 00123 { 00124 return( ret ); 00125 } 00126 return( 0 ); 00127 } 00128 00129 #undef PKCS12_MAX_PWDLEN 00130 00131 int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, 00132 const unsigned char *pwd, size_t pwdlen, 00133 const unsigned char *data, size_t len, 00134 unsigned char *output ) 00135 { 00136 #if !defined(MBEDTLS_ARC4_C) 00137 ((void) pbe_params); 00138 ((void) mode); 00139 ((void) pwd); 00140 ((void) pwdlen); 00141 ((void) data); 00142 ((void) len); 00143 ((void) output); 00144 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00145 #else 00146 int ret; 00147 unsigned char key[16]; 00148 mbedtls_arc4_context ctx; 00149 ((void) mode); 00150 00151 mbedtls_arc4_init( &ctx ); 00152 00153 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1, 00154 pwd, pwdlen, 00155 key, 16, NULL, 0 ) ) != 0 ) 00156 { 00157 return( ret ); 00158 } 00159 00160 mbedtls_arc4_setup( &ctx, key, 16 ); 00161 if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 ) 00162 goto exit; 00163 00164 exit: 00165 mbedtls_platform_zeroize( key, sizeof( key ) ); 00166 mbedtls_arc4_free( &ctx ); 00167 00168 return( ret ); 00169 #endif /* MBEDTLS_ARC4_C */ 00170 } 00171 00172 int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, 00173 mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, 00174 const unsigned char *pwd, size_t pwdlen, 00175 const unsigned char *data, size_t len, 00176 unsigned char *output ) 00177 { 00178 int ret, keylen = 0; 00179 unsigned char key[32]; 00180 unsigned char iv[16]; 00181 const mbedtls_cipher_info_t *cipher_info; 00182 mbedtls_cipher_context_t cipher_ctx; 00183 size_t olen = 0; 00184 00185 cipher_info = mbedtls_cipher_info_from_type( cipher_type ); 00186 if( cipher_info == NULL ) 00187 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00188 00189 keylen = cipher_info->key_bitlen / 8; 00190 00191 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, 00192 key, keylen, 00193 iv, cipher_info->iv_size ) ) != 0 ) 00194 { 00195 return( ret ); 00196 } 00197 00198 mbedtls_cipher_init( &cipher_ctx ); 00199 00200 if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) 00201 goto exit; 00202 00203 if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) 00204 goto exit; 00205 00206 if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) 00207 goto exit; 00208 00209 if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 ) 00210 goto exit; 00211 00212 if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len, 00213 output, &olen ) ) != 0 ) 00214 { 00215 goto exit; 00216 } 00217 00218 if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) 00219 ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; 00220 00221 exit: 00222 mbedtls_platform_zeroize( key, sizeof( key ) ); 00223 mbedtls_platform_zeroize( iv, sizeof( iv ) ); 00224 mbedtls_cipher_free( &cipher_ctx ); 00225 00226 return( ret ); 00227 } 00228 00229 static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, 00230 const unsigned char *filler, size_t fill_len ) 00231 { 00232 unsigned char *p = data; 00233 size_t use_len; 00234 00235 while( data_len > 0 ) 00236 { 00237 use_len = ( data_len > fill_len ) ? fill_len : data_len; 00238 memcpy( p, filler, use_len ); 00239 p += use_len; 00240 data_len -= use_len; 00241 } 00242 } 00243 00244 int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, 00245 const unsigned char *pwd, size_t pwdlen, 00246 const unsigned char *salt, size_t saltlen, 00247 mbedtls_md_type_t md_type, int id, int iterations ) 00248 { 00249 int ret; 00250 unsigned int j; 00251 00252 unsigned char diversifier[128]; 00253 unsigned char salt_block[128], pwd_block[128], hash_block[128]; 00254 unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; 00255 unsigned char *p; 00256 unsigned char c; 00257 00258 size_t hlen, use_len, v, i; 00259 00260 const mbedtls_md_info_t *md_info; 00261 mbedtls_md_context_t md_ctx; 00262 00263 // This version only allows max of 64 bytes of password or salt 00264 if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) 00265 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 00266 00267 md_info = mbedtls_md_info_from_type( md_type ); 00268 if( md_info == NULL ) 00269 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00270 00271 mbedtls_md_init( &md_ctx ); 00272 00273 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) 00274 return( ret ); 00275 hlen = mbedtls_md_get_size( md_info ); 00276 00277 if( hlen <= 32 ) 00278 v = 64; 00279 else 00280 v = 128; 00281 00282 memset( diversifier, (unsigned char) id, v ); 00283 00284 pkcs12_fill_buffer( salt_block, v, salt, saltlen ); 00285 pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); 00286 00287 p = data; 00288 while( datalen > 0 ) 00289 { 00290 // Calculate hash( diversifier || salt_block || pwd_block ) 00291 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) 00292 goto exit; 00293 00294 if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 ) 00295 goto exit; 00296 00297 if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 ) 00298 goto exit; 00299 00300 if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 ) 00301 goto exit; 00302 00303 if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 ) 00304 goto exit; 00305 00306 // Perform remaining ( iterations - 1 ) recursive hash calculations 00307 for( i = 1; i < (size_t) iterations; i++ ) 00308 { 00309 if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 ) 00310 goto exit; 00311 } 00312 00313 use_len = ( datalen > hlen ) ? hlen : datalen; 00314 memcpy( p, hash_output, use_len ); 00315 datalen -= use_len; 00316 p += use_len; 00317 00318 if( datalen == 0 ) 00319 break; 00320 00321 // Concatenating copies of hash_output into hash_block (B) 00322 pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); 00323 00324 // B += 1 00325 for( i = v; i > 0; i-- ) 00326 if( ++hash_block[i - 1] != 0 ) 00327 break; 00328 00329 // salt_block += B 00330 c = 0; 00331 for( i = v; i > 0; i-- ) 00332 { 00333 j = salt_block[i - 1] + hash_block[i - 1] + c; 00334 c = (unsigned char) (j >> 8); 00335 salt_block[i - 1] = j & 0xFF; 00336 } 00337 00338 // pwd_block += B 00339 c = 0; 00340 for( i = v; i > 0; i-- ) 00341 { 00342 j = pwd_block[i - 1] + hash_block[i - 1] + c; 00343 c = (unsigned char) (j >> 8); 00344 pwd_block[i - 1] = j & 0xFF; 00345 } 00346 } 00347 00348 ret = 0; 00349 00350 exit: 00351 mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) ); 00352 mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) ); 00353 mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) ); 00354 mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) ); 00355 00356 mbedtls_md_free( &md_ctx ); 00357 00358 return( ret ); 00359 } 00360 00361 #endif /* MBEDTLS_PKCS12_C */
Generated on Tue Jul 12 2022 15:15:56 by
