diff --git a/tests/api/test_evp.c b/tests/api/test_evp.c index 354d056660..5a89b171f7 100644 --- a/tests/api/test_evp.c +++ b/tests/api/test_evp.c @@ -584,6 +584,33 @@ int test_wolfSSL_EVP_DecodeUpdate(void) 0); } + /* decode input holding a NUL byte at the start of a 4 byte group, followed + * by more data than the context buffer can hold */ + + { + unsigned char enc5[64]; + + XMEMSET(enc5, 'A', sizeof(enc5)); + enc5[0] = '\0'; + + EVP_DecodeInit(ctx); + + ExpectIntEQ( + EVP_DecodeUpdate( + ctx, + decOutBuff, + &outl, + enc5, + (int)sizeof(enc5)), + 1 /* expected result code 1: success */ + ); + ExpectIntEQ(outl, 0); + /* Before the fix all 64 input bytes were buffered into the 48 byte + * ctx->data. The NUL byte ends the input, so nothing may be buffered + * at all. */ + ExpectIntEQ(ctx->remaining, 0); + } + EVP_ENCODE_CTX_free(ctx); #endif /* OPENSSL && WOLFSSL_BASE_DECODE */ return EXPECT_RESULT(); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 37f6ba5155..2d178c2505 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -13925,6 +13925,8 @@ int wolfSSL_EVP_DecodeUpdate(WOLFSSL_EVP_ENCODE_CTX* ctx, } e[0] = in[j++]; if (e[0] == '\0') { + /* a NUL byte ends the input, nothing is left to buffer */ + inLen = 0; break; } inLen--; @@ -14005,6 +14007,15 @@ int wolfSSL_EVP_DecodeUpdate(WOLFSSL_EVP_ENCODE_CTX* ctx, if (c == '=') { pad = 1; } + if (i >= BASE64_DECODE_BLOCK_SIZE) { + /* More leftover data than one decode block can hold. The loops + * above leave at most a partial block behind, so this is a + * bound on the buffer and not a reachable input error. */ + XMEMSET(ctx->data, 0, sizeof(ctx->data)); + ctx->remaining = 0; + *outl = 0; + return -1; + } ctx->data[i++] = c; ctx->remaining++; inLen--;