pkcs12.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /*
  2. * PKCS#12 Personal Information Exchange Syntax
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  6. */
  7. /*
  8. * The PKCS #12 Personal Information Exchange Syntax Standard v1.1
  9. *
  10. * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
  11. * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
  12. */
  13. #include "common.h"
  14. #if defined(MBEDTLS_PKCS12_C)
  15. #include "mbedtls/pkcs12.h"
  16. #include "mbedtls/asn1.h"
  17. #if defined(MBEDTLS_CIPHER_C)
  18. #include "mbedtls/cipher.h"
  19. #endif /* MBEDTLS_CIPHER_C */
  20. #include "mbedtls/platform_util.h"
  21. #include "mbedtls/error.h"
  22. #include <string.h>
  23. #if defined(MBEDTLS_DES_C)
  24. #include "mbedtls/des.h"
  25. #endif
  26. #include "psa_util_internal.h"
  27. #if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C)
  28. static int pkcs12_parse_pbe_params(mbedtls_asn1_buf *params,
  29. mbedtls_asn1_buf *salt, int *iterations)
  30. {
  31. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  32. unsigned char **p = &params->p;
  33. const unsigned char *end = params->p + params->len;
  34. /*
  35. * pkcs-12PbeParams ::= SEQUENCE {
  36. * salt OCTET STRING,
  37. * iterations INTEGER
  38. * }
  39. *
  40. */
  41. if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
  42. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT,
  43. MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
  44. }
  45. if ((ret = mbedtls_asn1_get_tag(p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
  46. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret);
  47. }
  48. salt->p = *p;
  49. *p += salt->len;
  50. if ((ret = mbedtls_asn1_get_int(p, end, iterations)) != 0) {
  51. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret);
  52. }
  53. if (*p != end) {
  54. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT,
  55. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  56. }
  57. return 0;
  58. }
  59. #define PKCS12_MAX_PWDLEN 128
  60. static int pkcs12_pbe_derive_key_iv(mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type,
  61. const unsigned char *pwd, size_t pwdlen,
  62. unsigned char *key, size_t keylen,
  63. unsigned char *iv, size_t ivlen)
  64. {
  65. int ret, iterations = 0;
  66. mbedtls_asn1_buf salt;
  67. size_t i;
  68. unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2];
  69. if (pwdlen > PKCS12_MAX_PWDLEN) {
  70. return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
  71. }
  72. memset(&salt, 0, sizeof(mbedtls_asn1_buf));
  73. memset(&unipwd, 0, sizeof(unipwd));
  74. if ((ret = pkcs12_parse_pbe_params(pbe_params, &salt,
  75. &iterations)) != 0) {
  76. return ret;
  77. }
  78. for (i = 0; i < pwdlen; i++) {
  79. unipwd[i * 2 + 1] = pwd[i];
  80. }
  81. if ((ret = mbedtls_pkcs12_derivation(key, keylen, unipwd, pwdlen * 2 + 2,
  82. salt.p, salt.len, md_type,
  83. MBEDTLS_PKCS12_DERIVE_KEY, iterations)) != 0) {
  84. return ret;
  85. }
  86. if (iv == NULL || ivlen == 0) {
  87. return 0;
  88. }
  89. if ((ret = mbedtls_pkcs12_derivation(iv, ivlen, unipwd, pwdlen * 2 + 2,
  90. salt.p, salt.len, md_type,
  91. MBEDTLS_PKCS12_DERIVE_IV, iterations)) != 0) {
  92. return ret;
  93. }
  94. return 0;
  95. }
  96. #undef PKCS12_MAX_PWDLEN
  97. #if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
  98. int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode,
  99. mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
  100. const unsigned char *pwd, size_t pwdlen,
  101. const unsigned char *data, size_t len,
  102. unsigned char *output, size_t output_size,
  103. size_t *output_len);
  104. #endif
  105. #if !defined(MBEDTLS_DEPRECATED_REMOVED)
  106. int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
  107. mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
  108. const unsigned char *pwd, size_t pwdlen,
  109. const unsigned char *data, size_t len,
  110. unsigned char *output)
  111. {
  112. size_t output_len = 0;
  113. /* We assume caller of the function is providing a big enough output buffer
  114. * so we pass output_size as SIZE_MAX to pass checks, However, no guarantees
  115. * for the output size actually being correct.
  116. */
  117. return mbedtls_pkcs12_pbe_ext(pbe_params, mode, cipher_type, md_type,
  118. pwd, pwdlen, data, len, output, SIZE_MAX,
  119. &output_len);
  120. }
  121. #endif
  122. int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode,
  123. mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
  124. const unsigned char *pwd, size_t pwdlen,
  125. const unsigned char *data, size_t len,
  126. unsigned char *output, size_t output_size,
  127. size_t *output_len)
  128. {
  129. int ret, keylen = 0;
  130. unsigned char key[32];
  131. unsigned char iv[16];
  132. const mbedtls_cipher_info_t *cipher_info;
  133. mbedtls_cipher_context_t cipher_ctx;
  134. size_t iv_len = 0;
  135. size_t finish_olen = 0;
  136. unsigned int padlen = 0;
  137. if (pwd == NULL && pwdlen != 0) {
  138. return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
  139. }
  140. cipher_info = mbedtls_cipher_info_from_type(cipher_type);
  141. if (cipher_info == NULL) {
  142. return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE;
  143. }
  144. keylen = (int) mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
  145. if (mode == MBEDTLS_PKCS12_PBE_DECRYPT) {
  146. if (output_size < len) {
  147. return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
  148. }
  149. }
  150. if (mode == MBEDTLS_PKCS12_PBE_ENCRYPT) {
  151. padlen = cipher_info->block_size - (len % cipher_info->block_size);
  152. if (output_size < (len + padlen)) {
  153. return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
  154. }
  155. }
  156. iv_len = mbedtls_cipher_info_get_iv_size(cipher_info);
  157. if ((ret = pkcs12_pbe_derive_key_iv(pbe_params, md_type, pwd, pwdlen,
  158. key, keylen,
  159. iv, iv_len)) != 0) {
  160. return ret;
  161. }
  162. mbedtls_cipher_init(&cipher_ctx);
  163. if ((ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info)) != 0) {
  164. goto exit;
  165. }
  166. if ((ret = mbedtls_cipher_setkey(&cipher_ctx, key, 8 * keylen,
  167. (mbedtls_operation_t) mode)) != 0) {
  168. goto exit;
  169. }
  170. #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
  171. {
  172. /* PKCS12 uses CBC with PKCS7 padding */
  173. mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7;
  174. #if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
  175. /* For historical reasons, when decrypting, this function works when
  176. * decrypting even when support for PKCS7 padding is disabled. In this
  177. * case, it ignores the padding, and so will never report a
  178. * password mismatch.
  179. */
  180. if (mode == MBEDTLS_PKCS12_PBE_DECRYPT) {
  181. padding = MBEDTLS_PADDING_NONE;
  182. }
  183. #endif
  184. if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) {
  185. goto exit;
  186. }
  187. }
  188. #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
  189. ret = mbedtls_cipher_crypt(&cipher_ctx, iv, iv_len, data, len, output, &finish_olen);
  190. if (ret == MBEDTLS_ERR_CIPHER_INVALID_PADDING) {
  191. ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
  192. }
  193. *output_len += finish_olen;
  194. exit:
  195. mbedtls_platform_zeroize(key, sizeof(key));
  196. mbedtls_platform_zeroize(iv, sizeof(iv));
  197. mbedtls_cipher_free(&cipher_ctx);
  198. return ret;
  199. }
  200. #endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C */
  201. static void pkcs12_fill_buffer(unsigned char *data, size_t data_len,
  202. const unsigned char *filler, size_t fill_len)
  203. {
  204. unsigned char *p = data;
  205. size_t use_len;
  206. if (filler != NULL && fill_len != 0) {
  207. while (data_len > 0) {
  208. use_len = (data_len > fill_len) ? fill_len : data_len;
  209. memcpy(p, filler, use_len);
  210. p += use_len;
  211. data_len -= use_len;
  212. }
  213. } else {
  214. /* If either of the above are not true then clearly there is nothing
  215. * that this function can do. The function should *not* be called
  216. * under either of those circumstances, as you could end up with an
  217. * incorrect output but for safety's sake, leaving the check in as
  218. * otherwise we could end up with memory corruption.*/
  219. }
  220. }
  221. static int calculate_hashes(mbedtls_md_type_t md_type, int iterations,
  222. unsigned char *diversifier, unsigned char *salt_block,
  223. unsigned char *pwd_block, unsigned char *hash_output, int use_salt,
  224. int use_password, size_t hlen, size_t v)
  225. {
  226. int ret = -1;
  227. size_t i;
  228. const mbedtls_md_info_t *md_info;
  229. mbedtls_md_context_t md_ctx;
  230. md_info = mbedtls_md_info_from_type(md_type);
  231. if (md_info == NULL) {
  232. return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE;
  233. }
  234. mbedtls_md_init(&md_ctx);
  235. if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) {
  236. return ret;
  237. }
  238. // Calculate hash( diversifier || salt_block || pwd_block )
  239. if ((ret = mbedtls_md_starts(&md_ctx)) != 0) {
  240. goto exit;
  241. }
  242. if ((ret = mbedtls_md_update(&md_ctx, diversifier, v)) != 0) {
  243. goto exit;
  244. }
  245. if (use_salt != 0) {
  246. if ((ret = mbedtls_md_update(&md_ctx, salt_block, v)) != 0) {
  247. goto exit;
  248. }
  249. }
  250. if (use_password != 0) {
  251. if ((ret = mbedtls_md_update(&md_ctx, pwd_block, v)) != 0) {
  252. goto exit;
  253. }
  254. }
  255. if ((ret = mbedtls_md_finish(&md_ctx, hash_output)) != 0) {
  256. goto exit;
  257. }
  258. // Perform remaining ( iterations - 1 ) recursive hash calculations
  259. for (i = 1; i < (size_t) iterations; i++) {
  260. if ((ret = mbedtls_md(md_info, hash_output, hlen, hash_output))
  261. != 0) {
  262. goto exit;
  263. }
  264. }
  265. exit:
  266. mbedtls_md_free(&md_ctx);
  267. return ret;
  268. }
  269. int mbedtls_pkcs12_derivation(unsigned char *data, size_t datalen,
  270. const unsigned char *pwd, size_t pwdlen,
  271. const unsigned char *salt, size_t saltlen,
  272. mbedtls_md_type_t md_type, int id, int iterations)
  273. {
  274. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  275. unsigned int j;
  276. unsigned char diversifier[128];
  277. unsigned char salt_block[128], pwd_block[128], hash_block[128] = { 0 };
  278. unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
  279. unsigned char *p;
  280. unsigned char c;
  281. int use_password = 0;
  282. int use_salt = 0;
  283. size_t hlen, use_len, v, i;
  284. // This version only allows max of 64 bytes of password or salt
  285. if (datalen > 128 || pwdlen > 64 || saltlen > 64) {
  286. return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
  287. }
  288. if (pwd == NULL && pwdlen != 0) {
  289. return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
  290. }
  291. if (salt == NULL && saltlen != 0) {
  292. return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
  293. }
  294. use_password = (pwd && pwdlen != 0);
  295. use_salt = (salt && saltlen != 0);
  296. hlen = mbedtls_md_get_size_from_type(md_type);
  297. if (hlen <= 32) {
  298. v = 64;
  299. } else {
  300. v = 128;
  301. }
  302. memset(diversifier, (unsigned char) id, v);
  303. if (use_salt != 0) {
  304. pkcs12_fill_buffer(salt_block, v, salt, saltlen);
  305. }
  306. if (use_password != 0) {
  307. pkcs12_fill_buffer(pwd_block, v, pwd, pwdlen);
  308. }
  309. p = data;
  310. while (datalen > 0) {
  311. if (calculate_hashes(md_type, iterations, diversifier, salt_block,
  312. pwd_block, hash_output, use_salt, use_password, hlen,
  313. v) != 0) {
  314. goto exit;
  315. }
  316. use_len = (datalen > hlen) ? hlen : datalen;
  317. memcpy(p, hash_output, use_len);
  318. datalen -= use_len;
  319. p += use_len;
  320. if (datalen == 0) {
  321. break;
  322. }
  323. // Concatenating copies of hash_output into hash_block (B)
  324. pkcs12_fill_buffer(hash_block, v, hash_output, hlen);
  325. // B += 1
  326. for (i = v; i > 0; i--) {
  327. if (++hash_block[i - 1] != 0) {
  328. break;
  329. }
  330. }
  331. if (use_salt != 0) {
  332. // salt_block += B
  333. c = 0;
  334. for (i = v; i > 0; i--) {
  335. j = salt_block[i - 1] + hash_block[i - 1] + c;
  336. c = MBEDTLS_BYTE_1(j);
  337. salt_block[i - 1] = MBEDTLS_BYTE_0(j);
  338. }
  339. }
  340. if (use_password != 0) {
  341. // pwd_block += B
  342. c = 0;
  343. for (i = v; i > 0; i--) {
  344. j = pwd_block[i - 1] + hash_block[i - 1] + c;
  345. c = MBEDTLS_BYTE_1(j);
  346. pwd_block[i - 1] = MBEDTLS_BYTE_0(j);
  347. }
  348. }
  349. }
  350. ret = 0;
  351. exit:
  352. mbedtls_platform_zeroize(salt_block, sizeof(salt_block));
  353. mbedtls_platform_zeroize(pwd_block, sizeof(pwd_block));
  354. mbedtls_platform_zeroize(hash_block, sizeof(hash_block));
  355. mbedtls_platform_zeroize(hash_output, sizeof(hash_output));
  356. return ret;
  357. }
  358. #endif /* MBEDTLS_PKCS12_C */