blob: 515d9e13704333540e7780bda8115fd9bf73ba4f [file] [log] [blame]
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02001/*
2 * PKCS#12 Personal Information Exchange Syntax
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * 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.
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020018 */
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
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_PKCS12_C)
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/pkcs12.h"
31#include "mbedtls/asn1.h"
32#include "mbedtls/cipher.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050033#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000034#include "mbedtls/error.h"
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020035
Rich Evans00ab4702015-02-06 13:43:58 +000036#include <string.h>
37
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_DES_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000039#include "mbedtls/des.h"
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020040#endif
41
Andrzej Kurek7bd12c52022-08-24 10:47:10 -040042#include "hash_info.h"
43#include "mbedtls/psa_util.h"
44
Hanno Becker8a89f9f2018-10-12 10:46:32 +010045#if defined(MBEDTLS_ASN1_PARSE_C)
46
Gilles Peskine449bd832023-01-11 14:50:10 +010047static int pkcs12_parse_pbe_params(mbedtls_asn1_buf *params,
48 mbedtls_asn1_buf *salt, int *iterations)
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020049{
Janos Follath24eed8d2019-11-22 13:21:35 +000050 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +020051 unsigned char **p = &params->p;
52 const unsigned char *end = params->p + params->len;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020053
54 /*
55 * pkcs-12PbeParams ::= SEQUENCE {
56 * salt OCTET STRING,
57 * iterations INTEGER
58 * }
59 *
60 */
Gilles Peskine449bd832023-01-11 14:50:10 +010061 if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
62 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT,
63 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
64 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020065
Gilles Peskine449bd832023-01-11 14:50:10 +010066 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 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020069
70 salt->p = *p;
71 *p += salt->len;
72
Gilles Peskine449bd832023-01-11 14:50:10 +010073 if ((ret = mbedtls_asn1_get_int(p, end, iterations)) != 0) {
74 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret);
75 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020076
Gilles Peskine449bd832023-01-11 14:50:10 +010077 if (*p != end) {
78 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT,
79 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
80 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020081
Gilles Peskine449bd832023-01-11 14:50:10 +010082 return 0;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020083}
84
Manuel Pégourié-Gonnardd02a1da2015-09-28 18:34:48 +020085#define PKCS12_MAX_PWDLEN 128
86
Gilles Peskine449bd832023-01-11 14:50:10 +010087static int pkcs12_pbe_derive_key_iv(mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type,
88 const unsigned char *pwd, size_t pwdlen,
89 unsigned char *key, size_t keylen,
90 unsigned char *iv, size_t ivlen)
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020091{
Nicholas Wilson409401c2016-04-13 11:48:25 +010092 int ret, iterations = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093 mbedtls_asn1_buf salt;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +020094 size_t i;
Manuel Pégourié-Gonnardd02a1da2015-09-28 18:34:48 +020095 unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2];
96
Gilles Peskine449bd832023-01-11 14:50:10 +010097 if (pwdlen > PKCS12_MAX_PWDLEN) {
98 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
99 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200100
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 memset(&salt, 0, sizeof(mbedtls_asn1_buf));
102 memset(&unipwd, 0, sizeof(unipwd));
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200103
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 if ((ret = pkcs12_parse_pbe_params(pbe_params, &salt,
105 &iterations)) != 0) {
106 return ret;
107 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 for (i = 0; i < pwdlen; i++) {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200110 unipwd[i * 2 + 1] = pwd[i];
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200111 }
112
Gilles Peskine449bd832023-01-11 14:50:10 +0100113 if ((ret = mbedtls_pkcs12_derivation(key, keylen, unipwd, pwdlen * 2 + 2,
114 salt.p, salt.len, md_type,
115 MBEDTLS_PKCS12_DERIVE_KEY, iterations)) != 0) {
116 return ret;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200117 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100118
119 if (iv == NULL || ivlen == 0) {
120 return 0;
121 }
122
123 if ((ret = mbedtls_pkcs12_derivation(iv, ivlen, unipwd, pwdlen * 2 + 2,
124 salt.p, salt.len, md_type,
125 MBEDTLS_PKCS12_DERIVE_IV, iterations)) != 0) {
126 return ret;
127 }
128 return 0;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200129}
130
Manuel Pégourié-Gonnardd02a1da2015-09-28 18:34:48 +0200131#undef PKCS12_MAX_PWDLEN
132
Gilles Peskine449bd832023-01-11 14:50:10 +0100133int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
134 mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
135 const unsigned char *pwd, size_t pwdlen,
136 const unsigned char *data, size_t len,
137 unsigned char *output)
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200138{
Paul Bakker38b50d72013-06-24 19:33:27 +0200139 int ret, keylen = 0;
140 unsigned char key[32];
141 unsigned char iv[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142 const mbedtls_cipher_info_t *cipher_info;
143 mbedtls_cipher_context_t cipher_ctx;
Paul Bakker38b50d72013-06-24 19:33:27 +0200144 size_t olen = 0;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 if (pwd == NULL && pwdlen != 0) {
147 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
148 }
Paul Elliott853c0da2021-11-11 19:00:38 +0000149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
151 if (cipher_info == NULL) {
152 return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE;
153 }
Paul Bakker38b50d72013-06-24 19:33:27 +0200154
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200155 keylen = cipher_info->key_bitlen / 8;
Paul Bakker38b50d72013-06-24 19:33:27 +0200156
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 if ((ret = pkcs12_pbe_derive_key_iv(pbe_params, md_type, pwd, pwdlen,
158 key, keylen,
159 iv, cipher_info->iv_size)) != 0) {
160 return ret;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200161 }
162
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 mbedtls_cipher_init(&cipher_ctx);
Paul Bakker84bbeb52014-07-01 14:53:22 +0200164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165 if ((ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info)) != 0) {
Paul Bakkerbd552442013-07-03 14:44:40 +0200166 goto exit;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200167 }
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 if ((ret =
170 mbedtls_cipher_setkey(&cipher_ctx, key, 8 * keylen,
171 (mbedtls_operation_t) mode)) != 0) {
172 goto exit;
173 }
174
175 if ((ret = mbedtls_cipher_set_iv(&cipher_ctx, iv, cipher_info->iv_size)) != 0) {
176 goto exit;
177 }
178
179 if ((ret = mbedtls_cipher_reset(&cipher_ctx)) != 0) {
180 goto exit;
181 }
182
183 if ((ret = mbedtls_cipher_update(&cipher_ctx, data, len,
184 output, &olen)) != 0) {
185 goto exit;
186 }
187
188 if ((ret = mbedtls_cipher_finish(&cipher_ctx, output + olen, &olen)) != 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200191
Paul Bakkerbd552442013-07-03 14:44:40 +0200192exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 mbedtls_platform_zeroize(key, sizeof(key));
194 mbedtls_platform_zeroize(iv, sizeof(iv));
195 mbedtls_cipher_free(&cipher_ctx);
Paul Bakkerbd552442013-07-03 14:44:40 +0200196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 return ret;
Paul Bakker531e2942013-06-24 19:23:12 +0200198}
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200199
Hanno Becker8a89f9f2018-10-12 10:46:32 +0100200#endif /* MBEDTLS_ASN1_PARSE_C */
201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202static void pkcs12_fill_buffer(unsigned char *data, size_t data_len,
203 const unsigned char *filler, size_t fill_len)
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200204{
205 unsigned char *p = data;
206 size_t use_len;
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 if (filler != NULL && fill_len != 0) {
209 while (data_len > 0) {
210 use_len = (data_len > fill_len) ? fill_len : data_len;
211 memcpy(p, filler, use_len);
Paul Elliott853c0da2021-11-11 19:00:38 +0000212 p += use_len;
213 data_len -= use_len;
214 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 } else {
Paul Elliott7298bef2021-12-02 17:51:34 +0000216 /* If either of the above are not true then clearly there is nothing
217 * that this function can do. The function should *not* be called
218 * under either of those circumstances, as you could end up with an
219 * incorrect output but for safety's sake, leaving the check in as
220 * otherwise we could end up with memory corruption.*/
221 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200222}
223
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400224
Gilles Peskine449bd832023-01-11 14:50:10 +0100225static int calculate_hashes(mbedtls_md_type_t md_type, int iterations,
226 unsigned char *diversifier, unsigned char *salt_block,
227 unsigned char *pwd_block, unsigned char *hash_output, int use_salt,
228 int use_password, size_t hlen, size_t v)
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400229{
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400230 int ret = -1;
231 size_t i;
232 const mbedtls_md_info_t *md_info;
233 mbedtls_md_context_t md_ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 md_info = mbedtls_md_info_from_type(md_type);
235 if (md_info == NULL) {
236 return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE;
237 }
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 mbedtls_md_init(&md_ctx);
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400240
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) {
242 return ret;
243 }
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400244 // Calculate hash( diversifier || salt_block || pwd_block )
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 if ((ret = mbedtls_md_starts(&md_ctx)) != 0) {
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400246 goto exit;
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400247 }
248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 if ((ret = mbedtls_md_update(&md_ctx, diversifier, v)) != 0) {
250 goto exit;
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400251 }
252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 if (use_salt != 0) {
254 if ((ret = mbedtls_md_update(&md_ctx, salt_block, v)) != 0) {
255 goto exit;
256 }
257 }
258
259 if (use_password != 0) {
260 if ((ret = mbedtls_md_update(&md_ctx, pwd_block, v)) != 0) {
261 goto exit;
262 }
263 }
264
265 if ((ret = mbedtls_md_finish(&md_ctx, hash_output)) != 0) {
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400266 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 }
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400268
269 // Perform remaining ( iterations - 1 ) recursive hash calculations
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 for (i = 1; i < (size_t) iterations; i++) {
271 if ((ret = mbedtls_md(md_info, hash_output, hlen, hash_output))
272 != 0) {
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400273 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 }
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400275 }
276
277exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 mbedtls_md_free(&md_ctx);
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400279 return ret;
Andrzej Kurek7bd12c52022-08-24 10:47:10 -0400280}
281
282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283int mbedtls_pkcs12_derivation(unsigned char *data, size_t datalen,
284 const unsigned char *pwd, size_t pwdlen,
285 const unsigned char *salt, size_t saltlen,
286 mbedtls_md_type_t md_type, int id, int iterations)
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200287{
Janos Follath24eed8d2019-11-22 13:21:35 +0000288 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200289 unsigned int j;
290
291 unsigned char diversifier[128];
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 unsigned char salt_block[128], pwd_block[128], hash_block[128] = { 0 };
Przemek Stekiel40afdd22022-09-06 13:08:28 +0200293 unsigned char hash_output[MBEDTLS_HASH_MAX_SIZE];
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200294 unsigned char *p;
295 unsigned char c;
Paul Elliott4086bdb2021-11-18 14:02:21 +0000296 int use_password = 0;
297 int use_salt = 0;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200298
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200299 size_t hlen, use_len, v, i;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200300
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200301 // This version only allows max of 64 bytes of password or salt
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 if (datalen > 128 || pwdlen > 64 || saltlen > 64) {
303 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
Paul Elliott4086bdb2021-11-18 14:02:21 +0000304 }
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 if (pwd == NULL && pwdlen != 0) {
307 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
308 }
309
310 if (salt == NULL && saltlen != 0) {
311 return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
312 }
313
314 use_password = (pwd && pwdlen != 0);
315 use_salt = (salt && saltlen != 0);
316
317 hlen = mbedtls_hash_info_get_size(md_type);
318
319 if (hlen <= 32) {
320 v = 64;
321 } else {
322 v = 128;
323 }
324
325 memset(diversifier, (unsigned char) id, v);
326
327 if (use_salt != 0) {
328 pkcs12_fill_buffer(salt_block, v, salt, saltlen);
329 }
330
331 if (use_password != 0) {
332 pkcs12_fill_buffer(pwd_block, v, pwd, pwdlen);
Paul Elliott4086bdb2021-11-18 14:02:21 +0000333 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200334
335 p = data;
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 while (datalen > 0) {
337 if (calculate_hashes(md_type, iterations, diversifier, salt_block,
338 pwd_block, hash_output, use_salt, use_password, hlen,
339 v) != 0) {
Paul Bakkerbd552442013-07-03 14:44:40 +0200340 goto exit;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200341 }
342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 use_len = (datalen > hlen) ? hlen : datalen;
344 memcpy(p, hash_output, use_len);
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200345 datalen -= use_len;
346 p += use_len;
347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 if (datalen == 0) {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200349 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200351
352 // Concatenating copies of hash_output into hash_block (B)
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 pkcs12_fill_buffer(hash_block, v, hash_output, hlen);
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200354
355 // B += 1
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 for (i = v; i > 0; i--) {
357 if (++hash_block[i - 1] != 0) {
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200358 break;
Paul Elliott4086bdb2021-11-18 14:02:21 +0000359 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200360 }
361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 if (use_salt != 0) {
363 // salt_block += B
364 c = 0;
365 for (i = v; i > 0; i--) {
366 j = salt_block[i - 1] + hash_block[i - 1] + c;
367 c = MBEDTLS_BYTE_1(j);
368 salt_block[i - 1] = MBEDTLS_BYTE_0(j);
369 }
370 }
371
372 if (use_password != 0) {
Paul Elliott4086bdb2021-11-18 14:02:21 +0000373 // pwd_block += B
374 c = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 for (i = v; i > 0; i--) {
Paul Elliott4086bdb2021-11-18 14:02:21 +0000376 j = pwd_block[i - 1] + hash_block[i - 1] + c;
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 c = MBEDTLS_BYTE_1(j);
378 pwd_block[i - 1] = MBEDTLS_BYTE_0(j);
Paul Elliott4086bdb2021-11-18 14:02:21 +0000379 }
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200380 }
381 }
382
Paul Bakkerbd552442013-07-03 14:44:40 +0200383 ret = 0;
384
385exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 mbedtls_platform_zeroize(salt_block, sizeof(salt_block));
387 mbedtls_platform_zeroize(pwd_block, sizeof(pwd_block));
388 mbedtls_platform_zeroize(hash_block, sizeof(hash_block));
389 mbedtls_platform_zeroize(hash_output, sizeof(hash_output));
Paul Bakker91c301a2014-06-18 13:59:38 +0200390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 return ret;
Paul Bakkerf1f21fe2013-06-24 19:17:19 +0200392}
393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394#endif /* MBEDTLS_PKCS12_C */