Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 39 additions & 15 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -13585,6 +13585,7 @@ static int test_wolfSSL_PKCS5(void)
const char *passwd = "pass1234";
#endif
const unsigned char *salt = (unsigned char *)"salt1234";
const unsigned char *salt16 = (unsigned char *)"salt1234salt5678";
unsigned char *out = (unsigned char *)XMALLOC(WC_SHA_DIGEST_SIZE, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
int ret = 0;
Expand All @@ -13593,11 +13594,16 @@ static int test_wolfSSL_PKCS5(void)
ExpectIntEQ(ret = PKCS5_PBKDF2_HMAC_SHA1(passwd,(int)XSTRLEN(passwd), salt,
(int)XSTRLEN((const char *) salt), 10, WC_SHA_DIGEST_SIZE,out),
WOLFSSL_SUCCESS);
/* A 16-byte salt gets no FIPS v7 indicator, so none may be cleared. */
ExpectIntEQ(PKCS5_PBKDF2_HMAC_SHA1(passwd, (int)XSTRLEN(passwd), salt16,
16, 10, WC_SHA_DIGEST_SIZE, out), WOLFSSL_SUCCESS);

#ifdef WOLFSSL_SHA512
ExpectIntEQ(ret = PKCS5_PBKDF2_HMAC(passwd,(int)XSTRLEN(passwd), salt,
(int)XSTRLEN((const char *) salt), 10, wolfSSL_EVP_sha512(),
WC_SHA_DIGEST_SIZE, out), SSL_SUCCESS);
ExpectIntEQ(PKCS5_PBKDF2_HMAC(passwd, (int)XSTRLEN(passwd), salt16, 16,
10, wolfSSL_EVP_sha512(), WC_SHA_DIGEST_SIZE, out), SSL_SUCCESS);
#endif

XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Expand Down Expand Up @@ -21812,7 +21818,7 @@ static int test_wolfSSL_PKCS8_d2i(void)
#if !defined(NO_DES3) && !defined(NO_SHA) && defined(HAVE_PBKDF2)
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
/* Write Encrypted PKCS#8 PEM to BIO. */
bytes = 1834;
bytes = 1846;
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_des_ede3_cbc(),
NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_des_ede3_cbc(),
Expand Down Expand Up @@ -21895,8 +21901,8 @@ static int test_wolfSSL_PKCS8_d2i(void)
bio = NULL;
#ifdef HAVE_PBKDF2
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
/* Write Encrypted PKCS#8 PEM to BIO (test write 0 then 379) */
bytes = 379;
/* Write Encrypted PKCS#8 PEM to BIO (test write 0 then 391) */
bytes = 391;
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_aes_256_cbc(),
NULL, 0, NoPasswordCallBack, (void*)"yassl123"), 0);
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_aes_256_cbc(),
Expand Down Expand Up @@ -28153,35 +28159,33 @@ static int test_wolfSSL_CRYPTO_memcmp(void)
| wolfCrypt ASN
*----------------------------------------------------------------------------*/

static int test_wc_CreateEncryptedPKCS8Key(void)
{
EXPECT_DECLS;
#if defined(HAVE_PKCS8) && !defined(NO_PWDBASED) && defined(WOLFSSL_AES_256) \
&& !defined(NO_AES_CBC) && !defined(NO_RSA) && !defined(NO_SHA) && \
!defined(NO_ASN_CRYPT) && defined(HAVE_PBKDF2)
WC_RNG rng;
/* Encrypt server_key_der_2048 with salt (NULL for the default), decrypt it
* and compare with the original. */
static int create_enc_pkcs8_check(WC_RNG* rng, byte* salt, word32 saltSz)
{
EXPECT_DECLS;
byte* encKey = NULL;
word32 encKeySz = 0;
word32 decKeySz = 0;
const char password[] = "Lorem ipsum dolor sit amet";
word32 passwordSz = (word32)XSTRLEN(password);
word32 tradIdx = 0;

XMEMSET(&rng, 0, sizeof(WC_RNG));
ExpectIntEQ(wc_InitRng(&rng), 0);
PRIVATE_KEY_UNLOCK();
/* Call with NULL for out buffer to get necessary length. */
ExpectIntEQ(wc_CreateEncryptedPKCS8Key((byte*)server_key_der_2048,
sizeof_server_key_der_2048, NULL, &encKeySz, password, (int)passwordSz,
PKCS5, PBES2, AES256CBCb, NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL),
WC_NO_ERR_TRACE(LENGTH_ONLY_E));
PKCS5, PBES2, AES256CBCb, salt, saltSz, WC_PKCS12_ITT_DEFAULT, rng,
NULL), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectNotNull(encKey = (byte*)XMALLOC(encKeySz, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER));
/* Call with the allocated out buffer. */
ExpectIntGT(wc_CreateEncryptedPKCS8Key((byte*)server_key_der_2048,
sizeof_server_key_der_2048, encKey, &encKeySz, password, (int)passwordSz,
PKCS5, PBES2, AES256CBCb, NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL),
0);
PKCS5, PBES2, AES256CBCb, salt, saltSz, WC_PKCS12_ITT_DEFAULT, rng,
NULL), 0);
/* Decrypt the encrypted PKCS8 key we just made. */
ExpectIntGT((decKeySz = (word32)wc_DecryptPKCS8Key(encKey, encKeySz, password,
(int)passwordSz)), 0);
Expand All @@ -28190,9 +28194,29 @@ static int test_wc_CreateEncryptedPKCS8Key(void)
/* Check that the decrypted key matches the key prior to encryption. */
ExpectIntEQ(XMEMCMP(encKey + tradIdx, server_key_der_2048,
sizeof_server_key_der_2048), 0);
PRIVATE_KEY_LOCK();

XFREE(encKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
return EXPECT_RESULT();
}
#endif

static int test_wc_CreateEncryptedPKCS8Key(void)
{
EXPECT_DECLS;
#if defined(HAVE_PKCS8) && !defined(NO_PWDBASED) && defined(WOLFSSL_AES_256) \
&& !defined(NO_AES_CBC) && !defined(NO_RSA) && !defined(NO_SHA) && \
!defined(NO_ASN_CRYPT) && defined(HAVE_PBKDF2)
WC_RNG rng;
byte salt8[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };

XMEMSET(&rng, 0, sizeof(WC_RNG));
ExpectIntEQ(wc_InitRng(&rng), 0);
PRIVATE_KEY_UNLOCK();
EXPECT_TEST(create_enc_pkcs8_check(&rng, NULL, 0));
/* An 8-byte salt: FIPS v7 flags it, and the key must still round-trip. */
EXPECT_TEST(create_enc_pkcs8_check(&rng, salt8, sizeof(salt8)));
PRIVATE_KEY_LOCK();

wc_FreeRng(&rng);
#endif
return EXPECT_RESULT();
Expand Down
30 changes: 30 additions & 0 deletions tests/api/test_asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -6923,8 +6923,10 @@ int test_wc_Pkcs8EncryptDecisionCoverage(void)
WC_RNG rng;
byte key[32];
byte out[512];
byte fill[512];
byte salt[8];
word32 outSz;
word32 need = 0;

XMEMSET(key, 3, sizeof(key));
XMEMSET(salt, 4, sizeof(salt));
Expand All @@ -6949,6 +6951,34 @@ int test_wc_Pkcs8EncryptDecisionCoverage(void)
"pw", 2, PKCS5, PBES2, AES128CBCb, salt, sizeof(salt), 1000,
0x7FFFFFFF, &rng, HEAP_HINT), WC_NO_ERR_TRACE(ALGO_ID_E));

/* Zero and one byte short return BUFFER_E and leave the buffer
* untouched; the queried size succeeds. */
outSz = 0;
ExpectIntEQ(wc_EncryptPKCS8Key_ex(key, sizeof(key), NULL, &outSz,
"pw", 2, PKCS5, PBES2, AES128CBCb, NULL, 0, 1000, 0, &rng,
HEAP_HINT), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
need = outSz;
ExpectIntGT(need, 1);
ExpectIntLE(need, sizeof(out));
XMEMSET(out, 0xA5, sizeof(out));
XMEMSET(fill, 0xA5, sizeof(fill));
outSz = 0;
ExpectIntEQ(wc_EncryptPKCS8Key_ex(key, sizeof(key), out, &outSz,
"pw", 2, PKCS5, PBES2, AES128CBCb, NULL, 0, 1000, 0, &rng,
HEAP_HINT), WC_NO_ERR_TRACE(BUFFER_E));
outSz = need - 1;
ExpectIntEQ(wc_EncryptPKCS8Key_ex(key, sizeof(key), out, &outSz,
"pw", 2, PKCS5, PBES2, AES128CBCb, NULL, 0, 1000, 0, &rng,
HEAP_HINT), WC_NO_ERR_TRACE(BUFFER_E));
ExpectBufEQ(out, fill, sizeof(out));
#if defined(HAVE_PBKDF2) && !defined(NO_HMAC) && !defined(NO_SHA)
outSz = need;
ExpectIntEQ(wc_EncryptPKCS8Key_ex(key, sizeof(key), out, &outSz,
"pw", 2, PKCS5, PBES2, AES128CBCb, NULL, 0, 1000, 0, &rng,
HEAP_HINT), (int)need);
ExpectBufEQ(out + need, fill + need, sizeof(out) - need);
#endif

ExpectIntEQ(wc_FreeRng(&rng), 0);
#endif /* HAVE_AES_CBC && !NO_AES && WOLFSSL_AES_128 && !FIPS */
return EXPECT_RESULT();
Expand Down
8 changes: 6 additions & 2 deletions tests/api/test_ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,9 +808,13 @@ int test_wc_ecc_shared_secret_at_infinity(void)
EXPECT_DECLS;
#ifdef TEST_ECC_SHARED_SECRET_AT_INFINITY
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && \
(ECC_MIN_KEY_SZ <= 224) && !defined(WOLFSSL_SP_MATH)
(ECC_MIN_KEY_SZ <= 224) && !defined(WOLFSSL_SP_MATH) && \
!(FIPS_VERSION3_GE(7,0,0) && defined(WC_HAVE_FIPS_INDICATOR) && \
!defined(FIPS_NO_WRAPPERS))
/* secp224r1 is not single precision accelerated, so this drives the
* software ECDH path even in SP builds that offload P-256. */
* software ECDH path even in SP builds that offload P-256. The v7
* module refuses ECDH on P-224 (outside its KAS-ECC-SSC curve set), so
* there the P-256 case below carries the identity check. */
ExpectIntEQ(ecc_shared_secret_inf_case(
"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
Expand Down
23 changes: 23 additions & 0 deletions tests/api/test_pwdbased.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ int test_wc_PBKDF2DecisionCoverage(void)
0x5d, 0x63, 0xcb, 0x06 };
byte derived[24] = {0};
int prevMax;
#if FIPS_VERSION3_GE(7,0,0) && defined(WC_HAVE_FIPS_INDICATOR) && \
!defined(FIPS_NO_WRAPPERS)
static const byte salt16[16] = { 0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63,
0xcb, 0x06, 0x78, 0x57, 0x8E, 0x5a,
0x5d, 0x63, 0xcb, 0x06 };
#endif

/* output==NULL || pLen<0 || sLen<0 || kLen<0 -- vary each operand alone. */
ExpectIntEQ(wc_PBKDF2_ex(NULL, passwd, (int)sizeof(passwd),
Expand Down Expand Up @@ -200,9 +206,26 @@ int test_wc_PBKDF2DecisionCoverage(void)
WC_NO_ERR_TRACE(BAD_FUNC_ARG));

/* valid derivation */
#if FIPS_VERSION3_GE(7,0,0) && defined(WC_HAVE_FIPS_INDICATOR) && \
!defined(FIPS_NO_WRAPPERS)
/* The 8-byte salt is below the SP 800-132 Section 5.1 minimum of 128
* bits, so the v7 module derives the key and flags it not approved. */
ExpectIntEQ(wc_PBKDF2_ex(derived, passwd, (int)sizeof(passwd),
salt, (int)sizeof(salt), 2, (int)sizeof(derived),
WC_SHA256, HEAP_HINT, INVALID_DEVID), WC_FIPS_NOT_APPROVED);
/* wc_CryptKey and the EVP PBKDF2 calls clear the indicator only under
* 16 bytes, so the module must flag 15 and not 16. */
ExpectIntEQ(wc_PBKDF2_ex(derived, passwd, (int)sizeof(passwd),
salt16, (int)sizeof(salt16) - 1, 2, (int)sizeof(derived),
WC_SHA256, HEAP_HINT, INVALID_DEVID), WC_FIPS_NOT_APPROVED);
ExpectIntEQ(wc_PBKDF2_ex(derived, passwd, (int)sizeof(passwd),
salt16, (int)sizeof(salt16), 2, (int)sizeof(derived),
WC_SHA256, HEAP_HINT, INVALID_DEVID), 0);
#else
ExpectIntEQ(wc_PBKDF2_ex(derived, passwd, (int)sizeof(passwd),
salt, (int)sizeof(salt), 2, (int)sizeof(derived),
WC_SHA256, HEAP_HINT, INVALID_DEVID), 0);
#endif
#endif
return EXPECT_RESULT();
}
Expand Down
9 changes: 7 additions & 2 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -11213,6 +11213,7 @@ int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz,
word32 pbeLen = 0;
word32 kdfLen = 0;
word32 encLen = 0;
word32 outerLen = 0;
byte cbcIv[MAX_IV_SIZE];
word32 idx = 0;
word32 encIdx = 0;
Expand All @@ -11234,7 +11235,7 @@ int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz,
}
if (ret == 0 && (salt == NULL || saltSz == 0)) {
genSalt = 1;
saltSz = 8;
saltSz = (version == PKCS5v2) ? PKCS5V2_SALT_SZ : PKCS5_SALT_SZ;
}
if (ret == 0 && version == PKCS5v2) {
ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &pbeId, &blockSz);
Expand Down Expand Up @@ -11296,7 +11297,7 @@ int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz,
if (ret == 0) {
/* outerLen = length of PBE encoding + octet string data */
/* Plus 2 for tag and length for pbe */
word32 outerLen = 2 + pbeLen;
outerLen = 2 + pbeLen;
/* Octet string tag, length */
outerLen += 1 + SetLength(keySz + padSz, NULL);
/* Octet string bytes */
Expand All @@ -11306,6 +11307,10 @@ int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz,
*outSz = 1 + SetLength(outerLen, NULL) + outerLen;
return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
}
if (*outSz < 1 + SetLength(outerLen, NULL) + outerLen)
ret = BUFFER_E;
Comment thread
kaleb-himes marked this conversation as resolved.
Resolved
}
if (ret == 0) {
SetOctetString(keySz + padSz, out);

idx += SetSequence(outerLen, out + idx);
Expand Down
14 changes: 14 additions & 0 deletions wolfcrypt/src/evp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5537,6 +5537,13 @@ int wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,

ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen,
iter, keylen, WC_SHA);
#if FIPS_VERSION3_GE(7,0,0) && defined(WC_HAVE_FIPS_INDICATOR) && \
!defined(FIPS_NO_WRAPPERS)
/* Key is derived; a salt under 128 bits is the expected indicator
* (SP 800-132 sec 5.1). Any other one fails below. */
if (ret == WC_FIPS_NOT_APPROVED && saltlen < 16)
ret = 0;
#endif
if (ret == 0)
return WOLFSSL_SUCCESS;
else
Expand Down Expand Up @@ -5566,6 +5573,13 @@ int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen,

ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen,
iter, keylen, pbkdf2HashType);
#if FIPS_VERSION3_GE(7,0,0) && defined(WC_HAVE_FIPS_INDICATOR) && \
!defined(FIPS_NO_WRAPPERS)
/* Key is derived; a salt under 128 bits is the expected indicator
* (SP 800-132 sec 5.1). Any other one fails below. */
if (ret == WC_FIPS_NOT_APPROVED && saltlen < 16)
ret = 0;
#endif
if (ret == 0)
return WOLFSSL_SUCCESS;
else
Expand Down
11 changes: 11 additions & 0 deletions wolfcrypt/src/wc_encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,17 @@ int wc_CryptKey(const char* password, int passwordSz, const byte* salt,
ret = wc_PBKDF2(key, (const byte*)password, passwordSz,
salt, saltSz, iterations, (int)derivedLen, typeH);
PRIVATE_KEY_LOCK();
#if FIPS_VERSION3_GE(7,0,0) && defined(WC_HAVE_FIPS_INDICATOR) && \
!defined(FIPS_NO_WRAPPERS)
/* Key is derived; a salt under 128 bits is the expected
* indicator (SP 800-132 sec 5.1). Any other one fails. */
if (ret == WC_FIPS_NOT_APPROVED && saltSz < 16)
ret = 0;
else if (ret == WC_FIPS_NOT_APPROVED) {
ret = FIPS_UNAPPROVED_E;
WOLFSSL_ERROR_VERBOSE(ret);
}
#endif
break;
#endif
#ifndef NO_SHA
Expand Down
Loading
Loading