pkcs12.c 13 KB

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