1 /* 2 * PKCS#12 Personal Information Exchange Syntax 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 * not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 /* 20 * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 21 * 22 * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf 23 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn 24 */ 25 26 #include "common.h" 27 28 #if defined(MBEDTLS_PKCS12_C) 29 30 #include "mbedtls/pkcs12.h" 31 #include "mbedtls/asn1.h" 32 #include "mbedtls/cipher.h" 33 #include "mbedtls/platform_util.h" 34 #include "mbedtls/error.h" 35 36 #include <string.h> 37 38 #if defined(MBEDTLS_ARC4_C) 39 #include "mbedtls/arc4.h" 40 #endif 41 42 #if defined(MBEDTLS_DES_C) 43 #include "mbedtls/des.h" 44 #endif 45 46 #if defined(MBEDTLS_ASN1_PARSE_C) 47 48 static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, 49 mbedtls_asn1_buf *salt, int *iterations ) 50 { 51 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 52 unsigned char **p = ¶ms->p; 53 const unsigned char *end = params->p + params->len; 54 55 /* 56 * pkcs-12PbeParams ::= SEQUENCE { 57 * salt OCTET STRING, 58 * iterations INTEGER 59 * } 60 * 61 */ 62 if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) 63 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, 64 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ); 65 66 if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) 67 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret ) ); 68 69 salt->p = *p; 70 *p += salt->len; 71 72 if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 ) 73 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret ) ); 74 75 if( *p != end ) 76 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, 77 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 78 79 return( 0 ); 80 } 81 82 #define PKCS12_MAX_PWDLEN 128 83 84 static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, 85 const unsigned char *pwd, size_t pwdlen, 86 unsigned char *key, size_t keylen, 87 unsigned char *iv, size_t ivlen ) 88 { 89 int ret, iterations = 0; 90 mbedtls_asn1_buf salt; 91 size_t i; 92 unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; 93 94 if( pwdlen > PKCS12_MAX_PWDLEN ) 95 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 96 97 memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); 98 memset( &unipwd, 0, sizeof(unipwd) ); 99 100 if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, 101 &iterations ) ) != 0 ) 102 return( ret ); 103 104 for( i = 0; i < pwdlen; i++ ) 105 unipwd[i * 2 + 1] = pwd[i]; 106 107 if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, 108 salt.p, salt.len, md_type, 109 MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 ) 110 { 111 return( ret ); 112 } 113 114 if( iv == NULL || ivlen == 0 ) 115 return( 0 ); 116 117 if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, 118 salt.p, salt.len, md_type, 119 MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 ) 120 { 121 return( ret ); 122 } 123 return( 0 ); 124 } 125 126 #undef PKCS12_MAX_PWDLEN 127 128 int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, 129 const unsigned char *pwd, size_t pwdlen, 130 const unsigned char *data, size_t len, 131 unsigned char *output ) 132 { 133 #if !defined(MBEDTLS_ARC4_C) 134 ((void) pbe_params); 135 ((void) mode); 136 ((void) pwd); 137 ((void) pwdlen); 138 ((void) data); 139 ((void) len); 140 ((void) output); 141 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 142 #else 143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 144 unsigned char key[16]; 145 mbedtls_arc4_context ctx; 146 ((void) mode); 147 148 mbedtls_arc4_init( &ctx ); 149 150 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1, 151 pwd, pwdlen, 152 key, 16, NULL, 0 ) ) != 0 ) 153 { 154 return( ret ); 155 } 156 157 mbedtls_arc4_setup( &ctx, key, 16 ); 158 if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 ) 159 goto exit; 160 161 exit: 162 mbedtls_platform_zeroize( key, sizeof( key ) ); 163 mbedtls_arc4_free( &ctx ); 164 165 return( ret ); 166 #endif /* MBEDTLS_ARC4_C */ 167 } 168 169 int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, 170 mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, 171 const unsigned char *pwd, size_t pwdlen, 172 const unsigned char *data, size_t len, 173 unsigned char *output ) 174 { 175 int ret, keylen = 0; 176 unsigned char key[32]; 177 unsigned char iv[16]; 178 const mbedtls_cipher_info_t *cipher_info; 179 mbedtls_cipher_context_t cipher_ctx; 180 size_t olen = 0; 181 182 cipher_info = mbedtls_cipher_info_from_type( cipher_type ); 183 if( cipher_info == NULL ) 184 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 185 186 keylen = cipher_info->key_bitlen / 8; 187 188 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, 189 key, keylen, 190 iv, cipher_info->iv_size ) ) != 0 ) 191 { 192 return( ret ); 193 } 194 195 mbedtls_cipher_init( &cipher_ctx ); 196 197 if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) 198 goto exit; 199 200 if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) 201 goto exit; 202 203 if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) 204 goto exit; 205 206 if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 ) 207 goto exit; 208 209 if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len, 210 output, &olen ) ) != 0 ) 211 { 212 goto exit; 213 } 214 215 if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) 216 ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; 217 218 exit: 219 mbedtls_platform_zeroize( key, sizeof( key ) ); 220 mbedtls_platform_zeroize( iv, sizeof( iv ) ); 221 mbedtls_cipher_free( &cipher_ctx ); 222 223 return( ret ); 224 } 225 226 #endif /* MBEDTLS_ASN1_PARSE_C */ 227 228 static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, 229 const unsigned char *filler, size_t fill_len ) 230 { 231 unsigned char *p = data; 232 size_t use_len; 233 234 while( data_len > 0 ) 235 { 236 use_len = ( data_len > fill_len ) ? fill_len : data_len; 237 memcpy( p, filler, use_len ); 238 p += use_len; 239 data_len -= use_len; 240 } 241 } 242 243 int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, 244 const unsigned char *pwd, size_t pwdlen, 245 const unsigned char *salt, size_t saltlen, 246 mbedtls_md_type_t md_type, int id, int iterations ) 247 { 248 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 249 unsigned int j; 250 251 unsigned char diversifier[128]; 252 unsigned char salt_block[128], pwd_block[128], hash_block[128]; 253 unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; 254 unsigned char *p; 255 unsigned char c; 256 257 size_t hlen, use_len, v, i; 258 259 const mbedtls_md_info_t *md_info; 260 mbedtls_md_context_t md_ctx; 261 262 // This version only allows max of 64 bytes of password or salt 263 if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) 264 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 265 266 md_info = mbedtls_md_info_from_type( md_type ); 267 if( md_info == NULL ) 268 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 269 270 mbedtls_md_init( &md_ctx ); 271 272 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) 273 return( ret ); 274 hlen = mbedtls_md_get_size( md_info ); 275 276 if( hlen <= 32 ) 277 v = 64; 278 else 279 v = 128; 280 281 memset( diversifier, (unsigned char) id, v ); 282 283 pkcs12_fill_buffer( salt_block, v, salt, saltlen ); 284 pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); 285 286 p = data; 287 while( datalen > 0 ) 288 { 289 // Calculate hash( diversifier || salt_block || pwd_block ) 290 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) 291 goto exit; 292 293 if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 ) 294 goto exit; 295 296 if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 ) 297 goto exit; 298 299 if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 ) 300 goto exit; 301 302 if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 ) 303 goto exit; 304 305 // Perform remaining ( iterations - 1 ) recursive hash calculations 306 for( i = 1; i < (size_t) iterations; i++ ) 307 { 308 if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 ) 309 goto exit; 310 } 311 312 use_len = ( datalen > hlen ) ? hlen : datalen; 313 memcpy( p, hash_output, use_len ); 314 datalen -= use_len; 315 p += use_len; 316 317 if( datalen == 0 ) 318 break; 319 320 // Concatenating copies of hash_output into hash_block (B) 321 pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); 322 323 // B += 1 324 for( i = v; i > 0; i-- ) 325 if( ++hash_block[i - 1] != 0 ) 326 break; 327 328 // salt_block += B 329 c = 0; 330 for( i = v; i > 0; i-- ) 331 { 332 j = salt_block[i - 1] + hash_block[i - 1] + c; 333 c = (unsigned char) (j >> 8); 334 salt_block[i - 1] = j & 0xFF; 335 } 336 337 // pwd_block += B 338 c = 0; 339 for( i = v; i > 0; i-- ) 340 { 341 j = pwd_block[i - 1] + hash_block[i - 1] + c; 342 c = (unsigned char) (j >> 8); 343 pwd_block[i - 1] = j & 0xFF; 344 } 345 } 346 347 ret = 0; 348 349 exit: 350 mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) ); 351 mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) ); 352 mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) ); 353 mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) ); 354 355 mbedtls_md_free( &md_ctx ); 356 357 return( ret ); 358 } 359 360 #endif /* MBEDTLS_PKCS12_C */ 361