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 if( pwd == NULL && pwdlen != 0 ) 183 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 184 185 cipher_info = mbedtls_cipher_info_from_type( cipher_type ); 186 if( cipher_info == NULL ) 187 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 188 189 keylen = cipher_info->key_bitlen / 8; 190 191 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, 192 key, keylen, 193 iv, cipher_info->iv_size ) ) != 0 ) 194 { 195 return( ret ); 196 } 197 198 mbedtls_cipher_init( &cipher_ctx ); 199 200 if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) 201 goto exit; 202 203 if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) 204 goto exit; 205 206 if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) 207 goto exit; 208 209 if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 ) 210 goto exit; 211 212 if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len, 213 output, &olen ) ) != 0 ) 214 { 215 goto exit; 216 } 217 218 if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) 219 ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; 220 221 exit: 222 mbedtls_platform_zeroize( key, sizeof( key ) ); 223 mbedtls_platform_zeroize( iv, sizeof( iv ) ); 224 mbedtls_cipher_free( &cipher_ctx ); 225 226 return( ret ); 227 } 228 229 #endif /* MBEDTLS_ASN1_PARSE_C */ 230 231 static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, 232 const unsigned char *filler, size_t fill_len ) 233 { 234 unsigned char *p = data; 235 size_t use_len; 236 237 if( filler != NULL && fill_len != 0 ) 238 { 239 while( data_len > 0 ) 240 { 241 use_len = ( data_len > fill_len ) ? fill_len : data_len; 242 memcpy( p, filler, use_len ); 243 p += use_len; 244 data_len -= use_len; 245 } 246 } 247 else 248 { 249 /* If either of the above are not true then clearly there is nothing 250 * that this function can do. The function should *not* be called 251 * under either of those circumstances, as you could end up with an 252 * incorrect output but for safety's sake, leaving the check in as 253 * otherwise we could end up with memory corruption.*/ 254 } 255 } 256 257 int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, 258 const unsigned char *pwd, size_t pwdlen, 259 const unsigned char *salt, size_t saltlen, 260 mbedtls_md_type_t md_type, int id, int iterations ) 261 { 262 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 263 unsigned int j; 264 265 unsigned char diversifier[128]; 266 unsigned char salt_block[128], pwd_block[128], hash_block[128]; 267 unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; 268 unsigned char *p; 269 unsigned char c; 270 int use_password = 0; 271 int use_salt = 0; 272 273 size_t hlen, use_len, v, i; 274 275 const mbedtls_md_info_t *md_info; 276 mbedtls_md_context_t md_ctx; 277 278 // This version only allows max of 64 bytes of password or salt 279 if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) 280 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 281 282 if( pwd == NULL && pwdlen != 0 ) 283 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 284 285 if( salt == NULL && saltlen != 0 ) 286 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); 287 288 use_password = ( pwd && pwdlen != 0 ); 289 use_salt = ( salt && saltlen != 0 ); 290 291 md_info = mbedtls_md_info_from_type( md_type ); 292 if( md_info == NULL ) 293 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); 294 295 mbedtls_md_init( &md_ctx ); 296 297 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) 298 return( ret ); 299 hlen = mbedtls_md_get_size( md_info ); 300 301 if( hlen <= 32 ) 302 v = 64; 303 else 304 v = 128; 305 306 memset( diversifier, (unsigned char) id, v ); 307 308 if( use_salt != 0 ) 309 { 310 pkcs12_fill_buffer( salt_block, v, salt, saltlen ); 311 } 312 313 if( use_password != 0 ) 314 { 315 pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); 316 } 317 318 p = data; 319 while( datalen > 0 ) 320 { 321 // Calculate hash( diversifier || salt_block || pwd_block ) 322 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) 323 goto exit; 324 325 if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 ) 326 goto exit; 327 328 if( use_salt != 0 ) 329 { 330 if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v )) != 0 ) 331 goto exit; 332 } 333 334 if( use_password != 0) 335 { 336 if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v )) != 0 ) 337 goto exit; 338 } 339 340 if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 ) 341 goto exit; 342 343 // Perform remaining ( iterations - 1 ) recursive hash calculations 344 for( i = 1; i < (size_t) iterations; i++ ) 345 { 346 if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 ) 347 goto exit; 348 } 349 350 use_len = ( datalen > hlen ) ? hlen : datalen; 351 memcpy( p, hash_output, use_len ); 352 datalen -= use_len; 353 p += use_len; 354 355 if( datalen == 0 ) 356 break; 357 358 // Concatenating copies of hash_output into hash_block (B) 359 pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); 360 361 // B += 1 362 for( i = v; i > 0; i-- ) 363 if( ++hash_block[i - 1] != 0 ) 364 break; 365 366 if( use_salt != 0 ) 367 { 368 // salt_block += B 369 c = 0; 370 for( i = v; i > 0; i-- ) 371 { 372 j = salt_block[i - 1] + hash_block[i - 1] + c; 373 c = MBEDTLS_BYTE_1( j ); 374 salt_block[i - 1] = MBEDTLS_BYTE_0( j ); 375 } 376 } 377 378 if( use_password != 0 ) 379 { 380 // pwd_block += B 381 c = 0; 382 for( i = v; i > 0; i-- ) 383 { 384 j = pwd_block[i - 1] + hash_block[i - 1] + c; 385 c = MBEDTLS_BYTE_1( j ); 386 pwd_block[i - 1] = MBEDTLS_BYTE_0( j ); 387 } 388 } 389 } 390 391 ret = 0; 392 393 exit: 394 mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) ); 395 mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) ); 396 mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) ); 397 mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) ); 398 399 mbedtls_md_free( &md_ctx ); 400 401 return( ret ); 402 } 403 404 #endif /* MBEDTLS_PKCS12_C */ 405