blob: 52f1a0df22be65ed3403ae09218bfac2d2abc7aa [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
214 if ((ret = mbedtls_cipher_crypt(&cipher_ctx, iv, enc_scheme_params.len,
215 data, datalen, output, &olen)) != 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216 ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100217 }
Paul Bakker28144de2013-06-24 19:28:55 +0200218
Paul Bakker46320832013-07-03 14:01:52 +0200219exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100220 mbedtls_md_free(&md_ctx);
221 mbedtls_cipher_free(&cipher_ctx);
Paul Bakker46320832013-07-03 14:01:52 +0200222
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100223 return ret;
Paul Bakker28144de2013-06-24 19:28:55 +0200224}
Marcos Del Sol Vives8a0dfac2016-11-06 12:22:25 +0100225#endif /* MBEDTLS_ASN1_PARSE_C */
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200226
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100227int mbedtls_pkcs5_pbkdf2_hmac(mbedtls_md_context_t *ctx,
228 const unsigned char *password,
229 size_t plen, const unsigned char *salt, size_t slen,
230 unsigned int iteration_count,
231 uint32_t key_length, unsigned char *output)
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200232{
gabor-mezei-armb8513fa2020-08-24 09:53:04 +0200233 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
234 int j;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200235 unsigned int i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236 unsigned char md1[MBEDTLS_MD_MAX_SIZE];
237 unsigned char work[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100238 unsigned char md_size = mbedtls_md_get_size(ctx->md_info);
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200239 size_t use_len;
240 unsigned char *out_p = output;
241 unsigned char counter[4];
242
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100243 memset(counter, 0, 4);
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200244 counter[3] = 1;
245
Azim Khan45b79cf2018-05-23 16:55:16 +0100246#if UINT_MAX > 0xFFFFFFFF
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247 if (iteration_count > 0xFFFFFFFF) {
248 return MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA;
249 }
Azim Khan45b79cf2018-05-23 16:55:16 +0100250#endif
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200251
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100252 if ((ret = mbedtls_md_hmac_starts(ctx, password, plen)) != 0) {
253 return ret;
254 }
255 while (key_length) {
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200256 // U1 ends up in work
257 //
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100258 if ((ret = mbedtls_md_hmac_update(ctx, salt, slen)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200259 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100260 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200261
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100262 if ((ret = mbedtls_md_hmac_update(ctx, counter, 4)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200263 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100264 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200265
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100266 if ((ret = mbedtls_md_hmac_finish(ctx, work)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200267 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100268 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270 if ((ret = mbedtls_md_hmac_reset(ctx)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200271 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100272 }
Jack Lloyd71657492019-09-23 19:15:54 -0400273
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 memcpy(md1, work, md_size);
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200275
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100276 for (i = 1; i < iteration_count; i++) {
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200277 // U2 ends up in md1
278 //
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100279 if ((ret = mbedtls_md_hmac_update(ctx, md1, md_size)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200280 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100281 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200282
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100283 if ((ret = mbedtls_md_hmac_finish(ctx, md1)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200284 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100285 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200286
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100287 if ((ret = mbedtls_md_hmac_reset(ctx)) != 0) {
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200288 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100289 }
Jack Lloyd71657492019-09-23 19:15:54 -0400290
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200291 // U1 xor U2
292 //
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100293 for (j = 0; j < md_size; j++) {
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200294 work[j] ^= md1[j];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100295 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200296 }
297
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298 use_len = (key_length < md_size) ? key_length : md_size;
299 memcpy(out_p, work, use_len);
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200300
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200301 key_length -= (uint32_t) use_len;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200302 out_p += use_len;
303
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100304 for (i = 4; i > 0; i--) {
305 if (++counter[i - 1] != 0) {
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200306 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100307 }
308 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200309 }
310
gabor-mezei-arm4553dd42020-08-19 14:01:03 +0200311cleanup:
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200312 /* Zeroise buffers to clear sensitive data from memory. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100313 mbedtls_platform_zeroize(work, MBEDTLS_MD_MAX_SIZE);
314 mbedtls_platform_zeroize(md1, MBEDTLS_MD_MAX_SIZE);
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200315
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100316 return ret;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200317}
318
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319#if defined(MBEDTLS_SELF_TEST)
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321#if !defined(MBEDTLS_SHA1_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322int mbedtls_pkcs5_self_test(int verbose)
Manuel Pégourié-Gonnard2a8afa92014-06-12 12:00:44 +0200323{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100324 if (verbose != 0) {
325 mbedtls_printf(" PBKDF2 (SHA1): skipped\n\n");
326 }
Manuel Pégourié-Gonnard2a8afa92014-06-12 12:00:44 +0200327
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100328 return 0;
Manuel Pégourié-Gonnard2a8afa92014-06-12 12:00:44 +0200329}
330#else
331
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200332#define MAX_TESTS 6
333
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100334static const size_t plen_test_data[MAX_TESTS] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100335{ 8, 8, 8, 24, 9 };
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200336
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100337static const unsigned char password_test_data[MAX_TESTS][32] =
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200338{
339 "password",
340 "password",
341 "password",
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200342 "passwordPASSWORDpassword",
343 "pass\0word",
344};
345
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100346static const size_t slen_test_data[MAX_TESTS] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100347{ 4, 4, 4, 36, 5 };
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200348
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100349static const unsigned char salt_test_data[MAX_TESTS][40] =
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200350{
351 "salt",
352 "salt",
353 "salt",
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200354 "saltSALTsaltSALTsaltSALTsaltSALTsalt",
355 "sa\0lt",
356};
357
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100358static const uint32_t it_cnt_test_data[MAX_TESTS] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100359{ 1, 2, 4096, 4096, 4096 };
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200360
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100361static const uint32_t key_len_test_data[MAX_TESTS] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362{ 20, 20, 20, 25, 16 };
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200363
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100364static const unsigned char result_key_test_data[MAX_TESTS][32] =
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200365{
366 { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
367 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
368 0x2f, 0xe0, 0x37, 0xa6 },
369 { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
370 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
371 0xd8, 0xde, 0x89, 0x57 },
372 { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
373 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
374 0x65, 0xa4, 0x29, 0xc1 },
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200375 { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
376 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
377 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
378 0x38 },
379 { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
380 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
381};
382
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100383int mbedtls_pkcs5_self_test(int verbose)
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200384{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 mbedtls_md_context_t sha1_ctx;
386 const mbedtls_md_info_t *info_sha1;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200387 int ret, i;
388 unsigned char key[64];
389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 mbedtls_md_init(&sha1_ctx);
Paul Bakker84bbeb52014-07-01 14:53:22 +0200391
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100392 info_sha1 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
393 if (info_sha1 == NULL) {
Paul Bakker84bbeb52014-07-01 14:53:22 +0200394 ret = 1;
395 goto exit;
396 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200397
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100398 if ((ret = mbedtls_md_setup(&sha1_ctx, info_sha1, 1)) != 0) {
Paul Bakker84bbeb52014-07-01 14:53:22 +0200399 ret = 1;
400 goto exit;
401 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200402
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403 for (i = 0; i < MAX_TESTS; i++) {
404 if (verbose != 0) {
405 mbedtls_printf(" PBKDF2 (SHA1) #%d: ", i);
406 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200407
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100408 ret = mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, password_test_data[i],
409 plen_test_data[i], salt_test_data[i],
410 slen_test_data[i], it_cnt_test_data[i],
411 key_len_test_data[i], key);
412 if (ret != 0 ||
413 memcmp(result_key_test_data[i], key, key_len_test_data[i]) != 0) {
414 if (verbose != 0) {
415 mbedtls_printf("failed\n");
416 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200417
Paul Bakker84bbeb52014-07-01 14:53:22 +0200418 ret = 1;
419 goto exit;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200420 }
421
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 if (verbose != 0) {
423 mbedtls_printf("passed\n");
424 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200425 }
426
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100427 if (verbose != 0) {
428 mbedtls_printf("\n");
429 }
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200430
Paul Bakker84bbeb52014-07-01 14:53:22 +0200431exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100432 mbedtls_md_free(&sha1_ctx);
Paul Bakkerf8634852013-07-03 13:31:52 +0200433
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100434 return ret;
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200435}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436#endif /* MBEDTLS_SHA1_C */
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438#endif /* MBEDTLS_SELF_TEST */
Paul Bakkerb0c19a42013-06-24 19:26:38 +0200439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440#endif /* MBEDTLS_PKCS5_C */