Add a legacy version of the wolfSSL_EVP_CipherFinal() function that

performs the decrypt in the old manner before a particular bug was
fixed. The old method didn't add padding when the data to encrypt was
multiple of the block_size in length. The decrypt happened to ignore the
error returned by checkPad.
This commit is contained in:
John Safranek 2019-06-14 14:43:45 -07:00
parent 2435ec2d6b
commit 36fb4e2f2d
2 changed files with 53 additions and 0 deletions

View File

@ -461,6 +461,57 @@ WOLFSSL_API int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
return WOLFSSL_SUCCESS;
}
#ifdef WOLFSSL_EVP_DECRYPT_LEGACY
/* This is a version of DecryptFinal to work with data encrypted with
* wolfSSL_EVP_EncryptFinal() with the broken padding. (pre-v3.12.0)
* Only call this after wolfSSL_EVP_CipherFinal() fails on a decrypt.
* Note, you don't know if the padding is good or bad with the old
* encrypt, but it is likely to be or bad. It will update the output
* length with the block_size so the last block is still captured. */
WOLFSSL_API int wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl)
{
int fl;
if (ctx == NULL || out == NULL || outl == NULL)
return BAD_FUNC_ARG;
WOLFSSL_ENTER("wolfSSL_EVP_DecryptFinal_legacy");
if (ctx->block_size == 1) {
*outl = 0;
return WOLFSSL_SUCCESS;
}
if ((ctx->bufUsed % ctx->block_size) != 0) {
*outl = 0;
/* not enough padding for decrypt */
return WOLFSSL_FAILURE;
}
/* The original behavior of CipherFinal() was like it is now,
* but checkPad would return 0 in case of a bad pad. It would
* treat the pad as 0, and leave the data in the output buffer,
* and not try to copy anything. This converts checkPad's -1 error
* code to block_size.
*/
if (ctx->lastUsed) {
PRINT_BUF(ctx->lastBlock, ctx->block_size);
if ((fl = checkPad(ctx, ctx->lastBlock)) < 0) {
fl = ctx->block_size;
}
else {
XMEMCPY(out, ctx->lastBlock, fl);
}
*outl = fl;
}
/* return error in cases where the block length is incorrect */
if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
#endif
WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx)
{
if (ctx == NULL) return BAD_FUNC_ARG;

View File

@ -348,6 +348,8 @@ WOLFSSL_API int wolfSSL_EVP_DecryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl);
WOLFSSL_API int wolfSSL_EVP_DecryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl);
WOLFSSL_API int wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl);
WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void);
WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx);