Skip to content

Commit 6631871

Browse files
authored
Merge pull request #9878 from embhorn/f377
Fix checkPad to test for zero padding
2 parents 1b25c46 + 998967e commit 6631871

3 files changed

Lines changed: 63 additions & 1 deletion

File tree

tests/api/test_evp_cipher.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2719,6 +2719,66 @@ int test_wolfSSL_EVP_mdc2(void)
27192719
* AAD that triggers the overflow. A properly-fixed implementation should detect
27202720
* the overflow and return WOLFSSL_FAILURE before attempting the allocation.
27212721
*/
2722+
int test_evp_cipher_pkcs7_pad_zero(void)
2723+
{
2724+
EXPECT_DECLS;
2725+
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128) && \
2726+
defined(OPENSSL_EXTRA)
2727+
EVP_CIPHER_CTX *ctx = NULL;
2728+
/* AES-128-CBC key and IV */
2729+
byte key[AES_BLOCK_SIZE] = {
2730+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2731+
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
2732+
};
2733+
byte iv[AES_BLOCK_SIZE] = {0};
2734+
/* Two plaintext blocks, with the last byte set to 0x00. When decrypted
2735+
* with padding enabled, the last byte (0x00) will be interpreted as the
2736+
* PKCS#7 padding length, which is invalid (valid range is 1..block_size).
2737+
* Using two blocks ensures CipherUpdate outputs the first block and
2738+
* CipherFinal processes the second (last) block through checkPad. */
2739+
byte plain[AES_BLOCK_SIZE * 2] = {
2740+
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2741+
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2742+
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2743+
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x00
2744+
};
2745+
byte cipher[AES_BLOCK_SIZE * 3];
2746+
byte decrypted[AES_BLOCK_SIZE * 3];
2747+
int outl = 0;
2748+
int total = 0;
2749+
2750+
/* Encrypt two plaintext blocks with padding disabled so the ciphertext
2751+
* is exactly two blocks. */
2752+
ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
2753+
ExpectIntEQ(EVP_CipherInit(ctx, EVP_aes_128_cbc(), key, iv, 1),
2754+
WOLFSSL_SUCCESS);
2755+
ExpectIntEQ(EVP_CIPHER_CTX_set_padding(ctx, 0), WOLFSSL_SUCCESS);
2756+
ExpectIntEQ(EVP_CipherUpdate(ctx, cipher, &outl, plain,
2757+
AES_BLOCK_SIZE * 2), WOLFSSL_SUCCESS);
2758+
total = outl;
2759+
ExpectIntEQ(EVP_CipherFinal(ctx, cipher + total, &outl), WOLFSSL_SUCCESS);
2760+
total += outl;
2761+
ExpectIntEQ(total, AES_BLOCK_SIZE * 2);
2762+
EVP_CIPHER_CTX_free(ctx);
2763+
ctx = NULL;
2764+
2765+
/* Decrypt the ciphertext with padding enabled (the default).
2766+
* CipherUpdate should output the first block. CipherFinal processes
2767+
* the last block through checkPad, which should reject padding value 0. */
2768+
ExpectNotNull(ctx = EVP_CIPHER_CTX_new());
2769+
ExpectIntEQ(EVP_CipherInit(ctx, EVP_aes_128_cbc(), key, iv, 0),
2770+
WOLFSSL_SUCCESS);
2771+
ExpectIntEQ(EVP_CipherUpdate(ctx, decrypted, &outl, cipher, total),
2772+
WOLFSSL_SUCCESS);
2773+
ExpectIntEQ(outl, AES_BLOCK_SIZE);
2774+
ExpectIntNE(EVP_CipherFinal(ctx, decrypted + outl, &outl),
2775+
WOLFSSL_SUCCESS);
2776+
EVP_CIPHER_CTX_free(ctx);
2777+
2778+
#endif /* !NO_AES && HAVE_AES_CBC && WOLFSSL_AES_128 && OPENSSL_EXTRA */
2779+
return EXPECT_RESULT();
2780+
}
2781+
27222782
int test_evp_cipher_aead_aad_overflow(void)
27232783
{
27242784
EXPECT_DECLS;

tests/api/test_evp_cipher.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ int test_wolfSSL_EVP_rc4(void);
6363
int test_wolfSSL_EVP_enc_null(void);
6464
int test_wolfSSL_EVP_rc2_cbc(void);
6565
int test_wolfSSL_EVP_mdc2(void);
66+
int test_evp_cipher_pkcs7_pad_zero(void);
6667
int test_evp_cipher_aead_aad_overflow(void);
6768

6869
#define TEST_EVP_CIPHER_DECLS \
@@ -105,6 +106,7 @@ int test_evp_cipher_aead_aad_overflow(void);
105106
TEST_DECL_GROUP("evp_cipher", test_wolfSSL_EVP_enc_null), \
106107
TEST_DECL_GROUP("evp_cipher", test_wolfSSL_EVP_rc2_cbc), \
107108
TEST_DECL_GROUP("evp_cipher", test_wolfSSL_EVP_mdc2), \
109+
TEST_DECL_GROUP("evp_cipher", test_evp_cipher_pkcs7_pad_zero), \
108110
TEST_DECL_GROUP("evp_cipher", test_evp_cipher_aead_aad_overflow)
109111

110112
#endif /* WOLFCRYPT_TEST_EVP_CIPHER_H */

wolfcrypt/src/evp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff)
12641264
int i;
12651265
int n;
12661266
n = buff[ctx->block_size-1];
1267-
if (n > ctx->block_size) return -1;
1267+
if (n > ctx->block_size || n == 0) return -1;
12681268
for (i = 0; i < n; i++) {
12691269
if (buff[ctx->block_size-i-1] != n)
12701270
return -1;

0 commit comments

Comments
 (0)