blob: 6a4b3b0f307fa6d71a5d6160c414bef4db95a6b5 [file] [log] [blame]
Paul Bakkerb0c19a42013-06-24 19:26:38 +02001/**
2 * \file pkcs5.c
3 *
4 * \brief PKCS#5 functions
5 *
6 * \author Mathias Olsson <mathias@kompetensum.com>
7 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02008 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02009 * SPDX-License-Identifier: Apache-2.0
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
Paul Bakkerb0c19a42013-06-24 19:26:38 +020022 */
23/*
24 * PKCS#5 includes PBKDF2 and more
25 *
26 * http://tools.ietf.org/html/rfc2898 (Specification)
27 * http://tools.ietf.org/html/rfc6070 (Test vectors)
28 */
29
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakkerb0c19a42013-06-24 19:26:38 +020031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_PKCS5_C)
Paul Bakkerb0c19a42013-06-24 19:26:38 +020033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/pkcs5.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Marcos Del Sol Vives8a0dfac2016-11-06 12:22:25 +010036
37#if defined(MBEDTLS_ASN1_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/asn1.h"
39#include "mbedtls/cipher.h"
40#include "mbedtls/oid.h"
Andres Amaya Garciaaf9a4862018-03-27 20:53:07 +010041#endif /* MBEDTLS_ASN1_PARSE_C */
42
43#include <string.h>
Rich Evans00ab4702015-02-06 13:43:58 +000044
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Hanno Becker1ea604d2018-10-12 10:57:33 +010047#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010048static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params,
49 mbedtls_asn1_buf *salt, int *iterations,
50 int *keylen, mbedtls_md_type_t *md_type)
Paul Bakker28144de2013-06-24 19:28:55 +020051{
Janos Follath24eed8d2019-11-22 13:21:35 +000052 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053 mbedtls_asn1_buf prf_alg_oid;
Manuel Pégourié-Gonnardedc3ab22014-06-12 17:08:27 +020054 unsigned char *p = params->p;
Paul Bakkerf8d018a2013-06-29 12:16:17 +020055 const unsigned char *end = params->p + params->len;
Paul Bakker28144de2013-06-24 19:28:55 +020056
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010057 if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
58 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
59 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
60 }
Paul Bakker28144de2013-06-24 19:28:55 +020061 /*
62 * PBKDF2-params ::= SEQUENCE {
63 * salt OCTET STRING,
64 * iterationCount INTEGER,
65 * keyLength INTEGER OPTIONAL
66 * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1
67 * }
68 *
69 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010070 if ((ret = mbedtls_asn1_get_tag(&p, end, &salt->len,
71 MBEDTLS_ASN1_OCTET_STRING)) != 0) {
72 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret);
73 }
Paul Bakker28144de2013-06-24 19:28:55 +020074
Manuel Pégourié-Gonnardedc3ab22014-06-12 17:08:27 +020075 salt->p = p;
76 p += salt->len;
Paul Bakker28144de2013-06-24 19:28:55 +020077
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010078 if ((ret = mbedtls_asn1_get_int(&p, end, iterations)) != 0) {
79 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret);
Paul Bakker28144de2013-06-24 19:28:55 +020080 }
81
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010082 if (p == end) {
83 return 0;
84 }
Paul Bakker28144de2013-06-24 19:28:55 +020085
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010086 if ((ret = mbedtls_asn1_get_int(&p, end, keylen)) != 0) {
87 if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
88 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret);
89 }
90 }
Paul Bakker28144de2013-06-24 19:28:55 +020091
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010092 if (p == end) {
93 return 0;
94 }
Paul Bakker28144de2013-06-24 19:28:55 +020095
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010096 if ((ret = mbedtls_asn1_get_alg_null(&p, end, &prf_alg_oid)) != 0) {
97 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret);
98 }
Paul Bakker28144de2013-06-24 19:28:55 +020099
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100100 if (mbedtls_oid_get_md_hmac(&prf_alg_oid, md_type) != 0) {
101 return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE;
102 }
103
104 if (p != end) {
105 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
106 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
107 }
108
109 return 0;
Paul Bakker28144de2013-06-24 19:28:55 +0200110}
111
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100112int mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
113 const unsigned char *pwd, size_t pwdlen,
114 const unsigned char *data, size_t datalen,
115 unsigned char *output)
Paul Bakker28144de2013-06-24 19:28:55 +0200116{
117 int ret, iterations = 0, keylen = 0;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200118 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200119 mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params;
120 mbedtls_asn1_buf salt;
121 mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
Paul Bakker28144de2013-06-24 19:28:55 +0200122 unsigned char key[32], iv[32];
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200123 size_t olen = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 const mbedtls_md_info_t *md_info;
125 const mbedtls_cipher_info_t *cipher_info;
126 mbedtls_md_context_t md_ctx;
127 mbedtls_cipher_type_t cipher_alg;
128 mbedtls_cipher_context_t cipher_ctx;
Paul Bakker28144de2013-06-24 19:28:55 +0200129
130 p = pbe_params->p;
131 end = p + pbe_params->len;
132
133 /*
134 * PBES2-params ::= SEQUENCE {
135 * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
136 * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
137 * }
138 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100139 if (pbe_params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
140 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
141 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
142 }
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200143
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100144 if ((ret = mbedtls_asn1_get_alg(&p, end, &kdf_alg_oid,
145 &kdf_alg_params)) != 0) {
146 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret);
147 }
Paul Bakker28144de2013-06-24 19:28:55 +0200148
149 // Only PBKDF2 supported at the moment
150 //
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100151 if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid) != 0) {
152 return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE;
Paul Bakker28144de2013-06-24 19:28:55 +0200153 }
154
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100155 if ((ret = pkcs5_parse_pbkdf2_params(&kdf_alg_params,
156 &salt, &iterations, &keylen,
157 &md_type)) != 0) {
158 return ret;
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200159 }
Paul Bakker28144de2013-06-24 19:28:55 +0200160
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100161 md_info = mbedtls_md_info_from_type(md_type);
162 if (md_info == NULL) {
163 return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE;
164 }
Paul Bakker28144de2013-06-24 19:28:55 +0200165
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100166 if ((ret = mbedtls_asn1_get_alg(&p, end, &enc_scheme_oid,
167 &enc_scheme_params)) != 0) {
168 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret);
169 }
170
171 if (mbedtls_oid_get_cipher_alg(&enc_scheme_oid, &cipher_alg) != 0) {
172 return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE;
173 }
174
175 cipher_info = mbedtls_cipher_info_from_type(cipher_alg);
176 if (cipher_info == NULL) {
177 return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE;
178 }
Paul Bakker28144de2013-06-24 19:28:55 +0200179
Manuel Pégourié-Gonnard66aca932014-06-12 13:14:55 +0200180 /*
181 * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
182 * since it is optional and we don't know if it was set or not
183 */
Manuel Pégourié-Gonnard898e0aa2015-06-18 15:28:12 +0200184 keylen = cipher_info->key_bitlen / 8;
Paul Bakker28144de2013-06-24 19:28:55 +0200185
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100186 if (enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING ||
187 enc_scheme_params.len != cipher_info->iv_size) {
188 return MBEDTLS_ERR_PKCS5_INVALID_FORMAT;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200189 }
Paul Bakker28144de2013-06-24 19:28:55 +0200190
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100191 mbedtls_md_init(&md_ctx);
192 mbedtls_cipher_init(&cipher_ctx);
Paul Bakker84bbeb52014-07-01 14:53:22 +0200193
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100194 memcpy(iv, enc_scheme_params.p, enc_scheme_params.len);
Paul Bakker28144de2013-06-24 19:28:55 +0200195
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100196 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) {
Paul Bakker46320832013-07-03 14:01:52 +0200197 goto exit;
Paul Bakker28144de2013-06-24 19:28:55 +0200198 }
199
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100200 if ((ret = mbedtls_pkcs5_pbkdf2_hmac(&md_ctx, pwd, pwdlen, salt.p, salt.len,
201 iterations, keylen, key)) != 0) {
Paul Bakker46320832013-07-03 14:01:52 +0200202 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100203 }
Paul Bakker46320832013-07-03 14:01:52 +0200204
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100205 if ((ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info)) != 0) {
Paul Bakker46320832013-07-03 14:01:52 +0200206 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100207 }
Paul Bakker28144de2013-06-24 19:28:55 +0200208
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209 if ((ret = mbedtls_cipher_setkey(&cipher_ctx, key, 8 * keylen,
210 (mbedtls_operation_t) mode)) != 0) {
211 goto exit;
212 }
213
Waleed Elmelegy412629c2023-07-19 14:01:35 +0100214 /* PKCS5 uses CBC with PKCS7 padding (which is the same as
215 * "PKCS5 padding" except that it's typically only called PKCS5
216 * with 64-bit-block ciphers).
217 */
218 mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7;
219#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
220 /* For historical reasons, when decrypting, this function works when
221 * decrypting even when support for PKCS7 padding is disabled. In this
222 * case, it ignores the padding, and so will never report a
223 * password mismatch.
224 */
225 if (mode == MBEDTLS_DECRYPT)
226 padding = MBEDTLS_PADDING_NONE;
227#endif
228 if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) {
229 goto exit;
230 }
231
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232 if ((ret = mbedtls_cipher_crypt(&cipher_ctx, iv, enc_scheme_params.len,
233 data, datalen, output, &olen)) != 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234 ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100235 }
Paul Bakker28144de2013-06-24 19:28:55 +0200236
Paul Bakker46320832013-07-03 14:01:52 +0200237exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100238 mbedtls_md_free(&md_ctx);
239 mbedtls_cipher_free(&cipher_ctx);
Paul Bakker46320832013-07-03 14:01:52 +0200240
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100241 return ret;
Paul Bakker28144de2013-06-24 19:28:55 +0200242}
Marcos Del Sol Vives8a0dfac2016-11-06 12:22:25 +0100243#endif /* MBEDTLS_ASN1_PARSE_C */
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200244
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100245int mbedtls_pkcs5_pbkdf2_hmac(mbedtls_md_context_t *ctx,
246 const unsigned char *password,
247 size_t plen, const unsigned char *salt, size_t slen,
248 unsigned int iteration_count,
249 uint32_t key_length, unsigned char *output)
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200250{
gabor-mezei-armb8513fa2020-08-24 09:53:04 +0200251 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
252 int j;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200253 unsigned int i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 unsigned char md1[MBEDTLS_MD_MAX_SIZE];
255 unsigned char work[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100256 unsigned char md_size = mbedtls_md_get_size(ctx->md_info);
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200257 size_t use_len;
258 unsigned char *out_p = output;
259 unsigned char counter[4];
260
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100261 memset(counter, 0, 4);
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200262 counter[3] = 1;
263
Azim Khan45b79cf2018-05-23 16:55:16 +0100264#if UINT_MAX > 0xFFFFFFFF
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265 if (iteration_count > 0xFFFFFFFF) {
266 return MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA;
267 }
Azim Khan45b79cf2018-05-23 16:55:16 +0100268#endif
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270 if ((ret = mbedtls_md_hmac_starts(ctx, password, plen)) != 0) {
271 return ret;
272 }
273 while (key_length) {
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200274 // U1 ends up in work
275 //
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100276 if ((ret = mbedtls_md_hmac_update(ctx, salt, slen)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200277 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200279
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100280 if ((ret = mbedtls_md_hmac_update(ctx, counter, 4)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200281 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200283
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100284 if ((ret = mbedtls_md_hmac_finish(ctx, work)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200285 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200287
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 if ((ret = mbedtls_md_hmac_reset(ctx)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200289 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100290 }
Jack Lloyd71657492019-09-23 19:15:54 -0400291
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292 memcpy(md1, work, md_size);
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200293
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100294 for (i = 1; i < iteration_count; i++) {
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200295 // U2 ends up in md1
296 //
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100297 if ((ret = mbedtls_md_hmac_update(ctx, md1, md_size)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200298 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100299 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200300
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100301 if ((ret = mbedtls_md_hmac_finish(ctx, md1)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200302 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100303 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305 if ((ret = mbedtls_md_hmac_reset(ctx)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200306 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100307 }
Jack Lloyd71657492019-09-23 19:15:54 -0400308
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200309 // U1 xor U2
310 //
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100311 for (j = 0; j < md_size; j++) {
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200312 work[j] ^= md1[j];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100313 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200314 }
315
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100316 use_len = (key_length < md_size) ? key_length : md_size;
317 memcpy(out_p, work, use_len);
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200318
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200319 key_length -= (uint32_t) use_len;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200320 out_p += use_len;
321
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322 for (i = 4; i > 0; i--) {
323 if (++counter[i - 1] != 0) {
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200324 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100325 }
326 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200327 }
328
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200329cleanup:
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200330 /* Zeroise buffers to clear sensitive data from memory. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 mbedtls_platform_zeroize(work, MBEDTLS_MD_MAX_SIZE);
332 mbedtls_platform_zeroize(md1, MBEDTLS_MD_MAX_SIZE);
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200333
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334 return ret;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200335}
336
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337#if defined(MBEDTLS_SELF_TEST)
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339#if !defined(MBEDTLS_SHA1_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100340int mbedtls_pkcs5_self_test(int verbose)
Manuel Pégourié-Gonnard2a8afa92014-06-12 12:00:44 +0200341{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 if (verbose != 0) {
343 mbedtls_printf(" PBKDF2 (SHA1): skipped\n\n");
344 }
Manuel Pégourié-Gonnard2a8afa92014-06-12 12:00:44 +0200345
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100346 return 0;
Manuel Pégourié-Gonnard2a8afa92014-06-12 12:00:44 +0200347}
348#else
349
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200350#define MAX_TESTS 6
351
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100352static const size_t plen_test_data[MAX_TESTS] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100353{ 8, 8, 8, 24, 9 };
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200354
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100355static const unsigned char password_test_data[MAX_TESTS][32] =
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200356{
357 "password",
358 "password",
359 "password",
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200360 "passwordPASSWORDpassword",
361 "pass\0word",
362};
363
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100364static const size_t slen_test_data[MAX_TESTS] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100365{ 4, 4, 4, 36, 5 };
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200366
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100367static const unsigned char salt_test_data[MAX_TESTS][40] =
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200368{
369 "salt",
370 "salt",
371 "salt",
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200372 "saltSALTsaltSALTsaltSALTsaltSALTsalt",
373 "sa\0lt",
374};
375
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100376static const uint32_t it_cnt_test_data[MAX_TESTS] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100377{ 1, 2, 4096, 4096, 4096 };
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200378
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100379static const uint32_t key_len_test_data[MAX_TESTS] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100380{ 20, 20, 20, 25, 16 };
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200381
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100382static const unsigned char result_key_test_data[MAX_TESTS][32] =
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200383{
384 { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
385 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
386 0x2f, 0xe0, 0x37, 0xa6 },
387 { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
388 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
389 0xd8, 0xde, 0x89, 0x57 },
390 { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
391 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
392 0x65, 0xa4, 0x29, 0xc1 },
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200393 { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
394 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
395 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
396 0x38 },
397 { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
398 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
399};
400
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100401int mbedtls_pkcs5_self_test(int verbose)
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200402{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 mbedtls_md_context_t sha1_ctx;
404 const mbedtls_md_info_t *info_sha1;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200405 int ret, i;
406 unsigned char key[64];
407
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100408 mbedtls_md_init(&sha1_ctx);
Paul Bakker84bbeb52014-07-01 14:53:22 +0200409
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100410 info_sha1 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
411 if (info_sha1 == NULL) {
Paul Bakker84bbeb52014-07-01 14:53:22 +0200412 ret = 1;
413 goto exit;
414 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200415
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100416 if ((ret = mbedtls_md_setup(&sha1_ctx, info_sha1, 1)) != 0) {
Paul Bakker84bbeb52014-07-01 14:53:22 +0200417 ret = 1;
418 goto exit;
419 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200420
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100421 for (i = 0; i < MAX_TESTS; i++) {
422 if (verbose != 0) {
423 mbedtls_printf(" PBKDF2 (SHA1) #%d: ", i);
424 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200425
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100426 ret = mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, password_test_data[i],
427 plen_test_data[i], salt_test_data[i],
428 slen_test_data[i], it_cnt_test_data[i],
429 key_len_test_data[i], key);
430 if (ret != 0 ||
431 memcmp(result_key_test_data[i], key, key_len_test_data[i]) != 0) {
432 if (verbose != 0) {
433 mbedtls_printf("failed\n");
434 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200435
Paul Bakker84bbeb52014-07-01 14:53:22 +0200436 ret = 1;
437 goto exit;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200438 }
439
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100440 if (verbose != 0) {
441 mbedtls_printf("passed\n");
442 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200443 }
444
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100445 if (verbose != 0) {
446 mbedtls_printf("\n");
447 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200448
Paul Bakker84bbeb52014-07-01 14:53:22 +0200449exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100450 mbedtls_md_free(&sha1_ctx);
Paul Bakkerf8634852013-07-03 13:31:52 +0200451
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100452 return ret;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200453}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454#endif /* MBEDTLS_SHA1_C */
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456#endif /* MBEDTLS_SELF_TEST */
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458#endif /* MBEDTLS_PKCS5_C */