Skip to content

Commit 78a5740

Browse files
authored
Merge pull request #10504 from miyazakh/f-2180_pbkdf
f-2180: fix clamp iterations <= 0 to 1 instead of returning an error
2 parents c922080 + afb3ca4 commit 78a5740

8 files changed

Lines changed: 134 additions & 7 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,6 +2951,7 @@ if(WOLFSSL_EXAMPLES)
29512951
tests/api/test_asn.c
29522952
tests/api/test_pkcs7.c
29532953
tests/api/test_pkcs12.c
2954+
tests/api/test_pwdbased.c
29542955
tests/api/test_ossl_asn1.c
29552956
tests/api/test_ossl_bio.c
29562957
tests/api/test_ossl_bn.c

tests/api.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@
242242
#include <tests/api/test_asn.h>
243243
#include <tests/api/test_pkcs7.h>
244244
#include <tests/api/test_pkcs12.h>
245+
#include <tests/api/test_pwdbased.h>
245246
#include <tests/api/test_ossl_asn1.h>
246247
#include <tests/api/test_ossl_bn.h>
247248
#include <tests/api/test_ossl_bio.h>
@@ -40260,6 +40261,9 @@ TEST_CASE testCases[] = {
4026040261
/* wolfCrypt PKCS#12 */
4026140262
TEST_PKCS12_DECLS,
4026240263

40264+
/* wolfCrypt pwdbased (PBKDF1/PBKDF2) */
40265+
TEST_PWDBASED_DECLS,
40266+
4026340267
/*
4026440268
* test_wolfCrypt_Cleanup needs to come after the above wolfCrypt tests to
4026540269
* avoid memory leaks.

tests/api/include.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ tests_unit_test_SOURCES += tests/api/test_asn.c
6666
tests_unit_test_SOURCES += tests/api/test_pkcs7.c
6767
# PKCS#12
6868
tests_unit_test_SOURCES += tests/api/test_pkcs12.c
69+
# pwdbased (PBKDF1/PBKDF2)
70+
tests_unit_test_SOURCES += tests/api/test_pwdbased.c
6971
# OpenSSL ASN.1
7072
tests_unit_test_SOURCES += tests/api/test_ossl_asn1.c
7173
# OpenSSL BN
@@ -166,6 +168,7 @@ EXTRA_DIST += tests/api/test_x509.h
166168
EXTRA_DIST += tests/api/test_asn.h
167169
EXTRA_DIST += tests/api/test_pkcs7.h
168170
EXTRA_DIST += tests/api/test_pkcs12.h
171+
EXTRA_DIST += tests/api/test_pwdbased.h
169172
EXTRA_DIST += tests/api/test_ossl_asn1.h
170173
EXTRA_DIST += tests/api/test_ossl_bn.h
171174
EXTRA_DIST += tests/api/test_ossl_bio.h

tests/api/test_pkcs12.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -647,10 +647,11 @@ int test_wc_PKCS12_PBKDF(void)
647647
salt2, (int)sizeof(salt2), 1000, 24, WC_SHA256, 1), 0);
648648
ExpectIntEQ(XMEMCMP(derived, verify2, 24), 0);
649649

650-
/* iterations <= 0 treated as 1 */
650+
/* iterations <= 0 must be rejected */
651651
ExpectIntEQ(wc_PKCS12_PBKDF(derived, passwd, (int)sizeof(passwd),
652-
salt, (int)sizeof(salt), 0, 24, WC_SHA256, 1), 0);
653-
ExpectIntEQ(XMEMCMP(derived, verify, 24), 0);
652+
salt, (int)sizeof(salt), 0, 24, WC_SHA256, 1), BAD_FUNC_ARG);
653+
ExpectIntEQ(wc_PKCS12_PBKDF(derived, passwd, (int)sizeof(passwd),
654+
salt, (int)sizeof(salt), -1, 24, WC_SHA256, 1), BAD_FUNC_ARG);
654655
#endif
655656
return EXPECT_RESULT();
656657
}
@@ -714,6 +715,14 @@ int test_wc_PKCS12_PBKDF_ex(void)
714715
salt, (int)sizeof(salt), 1, 24, WC_SHA256, 2, NULL), 0);
715716
ExpectIntEQ(wc_PKCS12_PBKDF_ex(derived, passwd, (int)sizeof(passwd),
716717
salt, (int)sizeof(salt), 1, 24, WC_SHA256, 3, NULL), 0);
718+
719+
/* iterations <= 0 must be rejected */
720+
ExpectIntEQ(wc_PKCS12_PBKDF_ex(derived, passwd, (int)sizeof(passwd),
721+
salt, (int)sizeof(salt), 0, 24, WC_SHA256, 1, NULL),
722+
BAD_FUNC_ARG);
723+
ExpectIntEQ(wc_PKCS12_PBKDF_ex(derived, passwd, (int)sizeof(passwd),
724+
salt, (int)sizeof(salt), -1, 24, WC_SHA256, 1, NULL),
725+
BAD_FUNC_ARG);
717726
#endif
718727
return EXPECT_RESULT();
719728
}

tests/api/test_pwdbased.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* test_pwdbased.c
2+
*
3+
* Copyright (C) 2006-2026 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL.
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
#include <tests/unit.h>
23+
#include <wolfssl/wolfcrypt/pwdbased.h>
24+
#include <tests/api/api.h>
25+
#include <tests/api/test_pwdbased.h>
26+
27+
/* test that wc_PBKDF1_ex rejects iterations <= 0 */
28+
int test_wc_PBKDF1_ex_iterations(void)
29+
{
30+
EXPECT_DECLS;
31+
#if defined(HAVE_PBKDF1) && !defined(NO_PWDBASED) && !defined(NO_SHA) && \
32+
!defined(HAVE_SELFTEST)
33+
static const byte passwd[] = { 'p', 'a', 's', 's' };
34+
static const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a,
35+
0x5d, 0x63, 0xcb, 0x06 };
36+
byte derived[16];
37+
38+
ExpectIntEQ(wc_PBKDF1_ex(derived, (int)sizeof(derived), NULL, 0,
39+
passwd, (int)sizeof(passwd),
40+
salt, (int)sizeof(salt), 0, WC_SHA, HEAP_HINT),
41+
BAD_FUNC_ARG);
42+
ExpectIntEQ(wc_PBKDF1_ex(derived, (int)sizeof(derived), NULL, 0,
43+
passwd, (int)sizeof(passwd),
44+
salt, (int)sizeof(salt), -1, WC_SHA, HEAP_HINT),
45+
BAD_FUNC_ARG);
46+
#endif
47+
return EXPECT_RESULT();
48+
}
49+
50+
/* test that wc_PBKDF2_ex rejects iterations <= 0 */
51+
int test_wc_PBKDF2_ex_iterations(void)
52+
{
53+
EXPECT_DECLS;
54+
#if defined(HAVE_PBKDF2) && !defined(NO_PWDBASED) && !defined(NO_HMAC) && \
55+
!defined(NO_SHA256) && !defined(HAVE_SELFTEST) && \
56+
(!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0))
57+
static const byte passwd[] = { 'p', 'a', 's', 's' };
58+
static const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a,
59+
0x5d, 0x63, 0xcb, 0x06 };
60+
byte derived[24];
61+
62+
ExpectIntEQ(wc_PBKDF2_ex(derived, passwd, (int)sizeof(passwd),
63+
salt, (int)sizeof(salt), 0,
64+
(int)sizeof(derived), WC_SHA256, HEAP_HINT, INVALID_DEVID),
65+
BAD_FUNC_ARG);
66+
ExpectIntEQ(wc_PBKDF2_ex(derived, passwd, (int)sizeof(passwd),
67+
salt, (int)sizeof(salt), -1,
68+
(int)sizeof(derived), WC_SHA256, HEAP_HINT, INVALID_DEVID),
69+
BAD_FUNC_ARG);
70+
#endif
71+
return EXPECT_RESULT();
72+
}

tests/api/test_pwdbased.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* test_pwdbased.h
2+
*
3+
* Copyright (C) 2006-2026 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL.
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
#ifndef WOLFCRYPT_TEST_PWDBASED_H
23+
#define WOLFCRYPT_TEST_PWDBASED_H
24+
25+
#include <tests/api/api_decl.h>
26+
27+
int test_wc_PBKDF1_ex_iterations(void);
28+
int test_wc_PBKDF2_ex_iterations(void);
29+
30+
#define TEST_PWDBASED_DECLS \
31+
TEST_DECL_GROUP("pwdbased", test_wc_PBKDF1_ex_iterations), \
32+
TEST_DECL_GROUP("pwdbased", test_wc_PBKDF2_ex_iterations)
33+
34+
#endif /* WOLFCRYPT_TEST_PWDBASED_H */

wolfcrypt/src/evp.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6791,6 +6791,10 @@ void wolfSSL_EVP_init(void)
67916791
if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
67926792
goto end;
67936793

6794+
/* OpenSSL treats count <= 0 as 1 iteration */
6795+
if (count <= 0)
6796+
count = 1;
6797+
67946798
ret = wc_PBKDF1_ex(key, (int)info->keySz, iv, (int)info->ivSz, data, sz,
67956799
salt, EVP_SALT_SIZE, count, hashType, NULL);
67966800
if (ret == 0)

wolfcrypt/src/pwdbased.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
9898
return BAD_FUNC_ARG;
9999

100100
if (iterations <= 0)
101-
iterations = 1;
101+
return BAD_FUNC_ARG;
102102

103103
if (iterations > current_wc_pbkdf_max_iterations) {
104104
WOLFSSL_MSG("PBKDF1 iteration count exceeds current_wc_pbkdf_max_iterations");
@@ -239,7 +239,7 @@ int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, const byte* salt,
239239
}
240240
#endif
241241
if (iterations <= 0)
242-
iterations = 1;
242+
return BAD_FUNC_ARG;
243243

244244
if (iterations > current_wc_pbkdf_max_iterations) {
245245
WOLFSSL_MSG("PBKDF2 iteration count exceeds current_wc_pbkdf_max_iterations");
@@ -432,7 +432,7 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
432432
}
433433

434434
if (iterations <= 0)
435-
iterations = 1;
435+
return BAD_FUNC_ARG;
436436

437437
if (iterations > current_wc_pbkdf_max_iterations) {
438438
WOLFSSL_MSG("PKCS12 PBKDF iteration count exceeds "
@@ -660,7 +660,7 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
660660
}
661661

662662
if (iterations <= 0) {
663-
iterations = 1;
663+
return BAD_FUNC_ARG;
664664
}
665665

666666
if (iterations > current_wc_pbkdf_max_iterations) {

0 commit comments

Comments
 (0)