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_MD_C) 39 #include "mbedtls/psa_util.h" 40 #define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ 41 psa_to_md_errors, \ 42 psa_generic_status_to_mbedtls) 43 #endif 44 45 #if defined(MBEDTLS_DES_C) 46 #include "mbedtls/des.h" 47 #endif 48 49 #include "hash_info.h" 50 #include "mbedtls/psa_util.h" 51 52 #if defined(MBEDTLS_ASN1_PARSE_C) 53 54 static int pkcs12_parse_pbe_params(mbedtls_asn1_buf *params, 55 mbedtls_asn1_buf *salt, int *iterations) 56 { 57 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 58 unsigned char **p = ¶ms->p; 59 const unsigned char *end = params->p + params->len; 60 61 /* 62 * pkcs-12PbeParams ::= SEQUENCE { 63 * salt OCTET STRING, 64 * iterations INTEGER 65 * } 66 * 67 */ 68 if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { 69 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, 70 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); 71 } 72 73 if ((ret = mbedtls_asn1_get_tag(p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { 74 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret); 75 } 76 77 salt->p = *p; 78 *p += salt->len; 79 80 if ((ret = mbedtls_asn1_get_int(p, end, iterations)) != 0) { 81 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret); 82 } 83 84 if (*p != end) { 85 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, 86 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); 87 } 88 89 return 0; 90 } 91 92 #define PKCS12_MAX_PWDLEN 128 93 94 static int pkcs12_pbe_derive_key_iv(mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, 95 const unsigned char *pwd, size_t pwdlen, 96 unsigned char *key, size_t keylen, 97 unsigned char *iv, size_t ivlen) 98 { 99 int ret, iterations = 0; 100 mbedtls_asn1_buf salt; 101 size_t i; 102 unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; 103 104 if (pwdlen > PKCS12_MAX_PWDLEN) { 105 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; 106 } 107 108 memset(&salt, 0, sizeof(mbedtls_asn1_buf)); 109 memset(&unipwd, 0, sizeof(unipwd)); 110 111 if ((ret = pkcs12_parse_pbe_params(pbe_params, &salt, 112 &iterations)) != 0) { 113 return ret; 114 } 115 116 for (i = 0; i < pwdlen; i++) { 117 unipwd[i * 2 + 1] = pwd[i]; 118 } 119 120 if ((ret = mbedtls_pkcs12_derivation(key, keylen, unipwd, pwdlen * 2 + 2, 121 salt.p, salt.len, md_type, 122 MBEDTLS_PKCS12_DERIVE_KEY, iterations)) != 0) { 123 return ret; 124 } 125 126 if (iv == NULL || ivlen == 0) { 127 return 0; 128 } 129 130 if ((ret = mbedtls_pkcs12_derivation(iv, ivlen, unipwd, pwdlen * 2 + 2, 131 salt.p, salt.len, md_type, 132 MBEDTLS_PKCS12_DERIVE_IV, iterations)) != 0) { 133 return ret; 134 } 135 return 0; 136 } 137 138 #undef PKCS12_MAX_PWDLEN 139 140 int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode, 141 mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, 142 const unsigned char *pwd, size_t pwdlen, 143 const unsigned char *data, size_t len, 144 unsigned char *output) 145 { 146 int ret, keylen = 0; 147 unsigned char key[32]; 148 unsigned char iv[16]; 149 const mbedtls_cipher_info_t *cipher_info; 150 mbedtls_cipher_context_t cipher_ctx; 151 size_t olen = 0; 152 153 if (pwd == NULL && pwdlen != 0) { 154 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; 155 } 156 157 cipher_info = mbedtls_cipher_info_from_type(cipher_type); 158 if (cipher_info == NULL) { 159 return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE; 160 } 161 162 keylen = cipher_info->key_bitlen / 8; 163 164 if ((ret = pkcs12_pbe_derive_key_iv(pbe_params, md_type, pwd, pwdlen, 165 key, keylen, 166 iv, cipher_info->iv_size)) != 0) { 167 return ret; 168 } 169 170 mbedtls_cipher_init(&cipher_ctx); 171 172 if ((ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info)) != 0) { 173 goto exit; 174 } 175 176 if ((ret = 177 mbedtls_cipher_setkey(&cipher_ctx, key, 8 * keylen, 178 (mbedtls_operation_t) mode)) != 0) { 179 goto exit; 180 } 181 182 if ((ret = mbedtls_cipher_set_iv(&cipher_ctx, iv, cipher_info->iv_size)) != 0) { 183 goto exit; 184 } 185 186 if ((ret = mbedtls_cipher_reset(&cipher_ctx)) != 0) { 187 goto exit; 188 } 189 190 if ((ret = mbedtls_cipher_update(&cipher_ctx, data, len, 191 output, &olen)) != 0) { 192 goto exit; 193 } 194 195 if ((ret = mbedtls_cipher_finish(&cipher_ctx, output + olen, &olen)) != 0) { 196 ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; 197 } 198 199 exit: 200 mbedtls_platform_zeroize(key, sizeof(key)); 201 mbedtls_platform_zeroize(iv, sizeof(iv)); 202 mbedtls_cipher_free(&cipher_ctx); 203 204 return ret; 205 } 206 207 #endif /* MBEDTLS_ASN1_PARSE_C */ 208 209 static void pkcs12_fill_buffer(unsigned char *data, size_t data_len, 210 const unsigned char *filler, size_t fill_len) 211 { 212 unsigned char *p = data; 213 size_t use_len; 214 215 if (filler != NULL && fill_len != 0) { 216 while (data_len > 0) { 217 use_len = (data_len > fill_len) ? fill_len : data_len; 218 memcpy(p, filler, use_len); 219 p += use_len; 220 data_len -= use_len; 221 } 222 } else { 223 /* If either of the above are not true then clearly there is nothing 224 * that this function can do. The function should *not* be called 225 * under either of those circumstances, as you could end up with an 226 * incorrect output but for safety's sake, leaving the check in as 227 * otherwise we could end up with memory corruption.*/ 228 } 229 } 230 231 232 static int calculate_hashes(mbedtls_md_type_t md_type, int iterations, 233 unsigned char *diversifier, unsigned char *salt_block, 234 unsigned char *pwd_block, unsigned char *hash_output, int use_salt, 235 int use_password, size_t hlen, size_t v) 236 { 237 #if defined(MBEDTLS_MD_C) 238 int ret = -1; 239 size_t i; 240 const mbedtls_md_info_t *md_info; 241 mbedtls_md_context_t md_ctx; 242 md_info = mbedtls_md_info_from_type(md_type); 243 if (md_info == NULL) { 244 return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE; 245 } 246 247 mbedtls_md_init(&md_ctx); 248 249 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { 250 return ret; 251 } 252 // Calculate hash( diversifier || salt_block || pwd_block ) 253 if ((ret = mbedtls_md_starts(&md_ctx)) != 0) { 254 goto exit; 255 } 256 257 if ((ret = mbedtls_md_update(&md_ctx, diversifier, v)) != 0) { 258 goto exit; 259 } 260 261 if (use_salt != 0) { 262 if ((ret = mbedtls_md_update(&md_ctx, salt_block, v)) != 0) { 263 goto exit; 264 } 265 } 266 267 if (use_password != 0) { 268 if ((ret = mbedtls_md_update(&md_ctx, pwd_block, v)) != 0) { 269 goto exit; 270 } 271 } 272 273 if ((ret = mbedtls_md_finish(&md_ctx, hash_output)) != 0) { 274 goto exit; 275 } 276 277 // Perform remaining ( iterations - 1 ) recursive hash calculations 278 for (i = 1; i < (size_t) iterations; i++) { 279 if ((ret = mbedtls_md(md_info, hash_output, hlen, hash_output)) 280 != 0) { 281 goto exit; 282 } 283 } 284 285 exit: 286 mbedtls_md_free(&md_ctx); 287 return ret; 288 #else 289 psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; 290 psa_algorithm_t alg = mbedtls_psa_translate_md(md_type); 291 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 292 psa_status_t status_abort = PSA_ERROR_CORRUPTION_DETECTED; 293 size_t i, out_len, out_size = PSA_HASH_LENGTH(alg); 294 295 if (alg == PSA_ALG_NONE) { 296 return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE; 297 } 298 299 if ((status = psa_hash_setup(&op, alg)) != PSA_SUCCESS) { 300 goto exit; 301 } 302 303 // Calculate hash( diversifier || salt_block || pwd_block ) 304 if ((status = psa_hash_update(&op, diversifier, v)) != PSA_SUCCESS) { 305 goto exit; 306 } 307 308 if (use_salt != 0) { 309 if ((status = psa_hash_update(&op, salt_block, v)) != PSA_SUCCESS) { 310 goto exit; 311 } 312 } 313 314 if (use_password != 0) { 315 if ((status = psa_hash_update(&op, pwd_block, v)) != PSA_SUCCESS) { 316 goto exit; 317 } 318 } 319 320 if ((status = psa_hash_finish(&op, hash_output, out_size, &out_len)) 321 != PSA_SUCCESS) { 322 goto exit; 323 } 324 325 // Perform remaining ( iterations - 1 ) recursive hash calculations 326 for (i = 1; i < (size_t) iterations; i++) { 327 if ((status = psa_hash_compute(alg, hash_output, hlen, hash_output, 328 out_size, &out_len)) != PSA_SUCCESS) { 329 goto exit; 330 } 331 } 332 333 exit: 334 status_abort = psa_hash_abort(&op); 335 if (status == PSA_SUCCESS) { 336 status = status_abort; 337 } 338 return PSA_TO_MBEDTLS_ERR(status); 339 #endif /* !MBEDTLS_MD_C */ 340 } 341 342 343 int mbedtls_pkcs12_derivation(unsigned char *data, size_t datalen, 344 const unsigned char *pwd, size_t pwdlen, 345 const unsigned char *salt, size_t saltlen, 346 mbedtls_md_type_t md_type, int id, int iterations) 347 { 348 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 349 unsigned int j; 350 351 unsigned char diversifier[128]; 352 unsigned char salt_block[128], pwd_block[128], hash_block[128] = { 0 }; 353 unsigned char hash_output[MBEDTLS_HASH_MAX_SIZE]; 354 unsigned char *p; 355 unsigned char c; 356 int use_password = 0; 357 int use_salt = 0; 358 359 size_t hlen, use_len, v, i; 360 361 // This version only allows max of 64 bytes of password or salt 362 if (datalen > 128 || pwdlen > 64 || saltlen > 64) { 363 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; 364 } 365 366 if (pwd == NULL && pwdlen != 0) { 367 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; 368 } 369 370 if (salt == NULL && saltlen != 0) { 371 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; 372 } 373 374 use_password = (pwd && pwdlen != 0); 375 use_salt = (salt && saltlen != 0); 376 377 hlen = mbedtls_hash_info_get_size(md_type); 378 379 if (hlen <= 32) { 380 v = 64; 381 } else { 382 v = 128; 383 } 384 385 memset(diversifier, (unsigned char) id, v); 386 387 if (use_salt != 0) { 388 pkcs12_fill_buffer(salt_block, v, salt, saltlen); 389 } 390 391 if (use_password != 0) { 392 pkcs12_fill_buffer(pwd_block, v, pwd, pwdlen); 393 } 394 395 p = data; 396 while (datalen > 0) { 397 if (calculate_hashes(md_type, iterations, diversifier, salt_block, 398 pwd_block, hash_output, use_salt, use_password, hlen, 399 v) != 0) { 400 goto exit; 401 } 402 403 use_len = (datalen > hlen) ? hlen : datalen; 404 memcpy(p, hash_output, use_len); 405 datalen -= use_len; 406 p += use_len; 407 408 if (datalen == 0) { 409 break; 410 } 411 412 // Concatenating copies of hash_output into hash_block (B) 413 pkcs12_fill_buffer(hash_block, v, hash_output, hlen); 414 415 // B += 1 416 for (i = v; i > 0; i--) { 417 if (++hash_block[i - 1] != 0) { 418 break; 419 } 420 } 421 422 if (use_salt != 0) { 423 // salt_block += B 424 c = 0; 425 for (i = v; i > 0; i--) { 426 j = salt_block[i - 1] + hash_block[i - 1] + c; 427 c = MBEDTLS_BYTE_1(j); 428 salt_block[i - 1] = MBEDTLS_BYTE_0(j); 429 } 430 } 431 432 if (use_password != 0) { 433 // pwd_block += B 434 c = 0; 435 for (i = v; i > 0; i--) { 436 j = pwd_block[i - 1] + hash_block[i - 1] + c; 437 c = MBEDTLS_BYTE_1(j); 438 pwd_block[i - 1] = MBEDTLS_BYTE_0(j); 439 } 440 } 441 } 442 443 ret = 0; 444 445 exit: 446 mbedtls_platform_zeroize(salt_block, sizeof(salt_block)); 447 mbedtls_platform_zeroize(pwd_block, sizeof(pwd_block)); 448 mbedtls_platform_zeroize(hash_block, sizeof(hash_block)); 449 mbedtls_platform_zeroize(hash_output, sizeof(hash_output)); 450 451 return ret; 452 } 453 454 #endif /* MBEDTLS_PKCS12_C */ 455