forked from wolfSSL/wolfssl
updates to EVP_CipherUpdate for handling storage of last block
This commit is contained in:
@@ -369,21 +369,24 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
|
||||||
WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
||||||
unsigned char *out, int *outl,
|
unsigned char *out, int *outl,
|
||||||
const unsigned char *in, int inl)
|
const unsigned char *in, int inl)
|
||||||
{
|
{
|
||||||
int blocks;
|
int blocks;
|
||||||
int fill;
|
int fill;
|
||||||
int copied;
|
|
||||||
|
|
||||||
if ((ctx == NULL) || (inl < 0) ||
|
|
||||||
(outl == NULL)|| (in == NULL)) return BAD_FUNC_ARG;
|
|
||||||
WOLFSSL_ENTER("wolfSSL_EVP_CipherUpdate");
|
WOLFSSL_ENTER("wolfSSL_EVP_CipherUpdate");
|
||||||
printf("wolfSSL_EVP_CipherUpdate\n");
|
if ((ctx == NULL) || (inl < 0) || (outl == NULL)|| (in == NULL)) {
|
||||||
|
WOLFSSL_MSG("Bad argument");
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
*outl = 0;
|
*outl = 0;
|
||||||
if (inl == 0) return WOLFSSL_SUCCESS;
|
if (inl == 0) {
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
#if !defined(NO_AES) && defined(HAVE_AESGCM)
|
||||||
switch (ctx->cipherType) {
|
switch (ctx->cipherType) {
|
||||||
@@ -398,49 +401,64 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
}
|
}
|
||||||
#endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */
|
#endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */
|
||||||
|
|
||||||
if (out == NULL)
|
if (out == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->bufUsed > 0) { /* concatinate them if there is anything */
|
|
||||||
printf("head fillBuff inl=%d, ctx->bufUsed=%d\n", inl, ctx->bufUsed);
|
if (ctx->bufUsed > 0) { /* concatenate them if there is anything */
|
||||||
fill = fillBuff(ctx, in, inl);
|
fill = fillBuff(ctx, in, inl);
|
||||||
inl -= fill;
|
inl -= fill;
|
||||||
in += fill;
|
in += fill;
|
||||||
printf("head fillBuff inl=%d, ctx->bufUsed=%d\n", inl, ctx->bufUsed);
|
|
||||||
}
|
}
|
||||||
if ((ctx->enc == 0) && (ctx->lastUsed == 1) && (inl > 0/*ctx->block_size*/)) {
|
|
||||||
PRINT_BUF(ctx->lastBlock, ctx->block_size);
|
/* check if the buff is full, and if so flash it out */
|
||||||
|
if (ctx->bufUsed == ctx->block_size) {
|
||||||
|
byte* output = out;
|
||||||
|
|
||||||
|
/* During decryption we save the last block to check padding on Final.
|
||||||
|
* Update the last block stored if one has already been stored */
|
||||||
|
if ((ctx->enc == 0)) {
|
||||||
|
if (ctx->lastUsed == 1) {
|
||||||
XMEMCPY(out, ctx->lastBlock, ctx->block_size);
|
XMEMCPY(out, ctx->lastBlock, ctx->block_size);
|
||||||
*outl+= ctx->block_size;
|
*outl+= ctx->block_size;
|
||||||
out += ctx->block_size;
|
out += ctx->block_size;
|
||||||
ctx->lastUsed = 0;
|
|
||||||
copied = 1;
|
|
||||||
printf("Copied out last block - 1\n");
|
|
||||||
}
|
}
|
||||||
if (ctx->bufUsed == ctx->block_size /* && inl/ctx->block_size != 0*/) {
|
output = ctx->lastBlock; /* redirect output to last block buffer */
|
||||||
/* the buff is full, flash out */
|
ctx->lastUsed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
PRINT_BUF(ctx->buf, ctx->block_size);
|
PRINT_BUF(ctx->buf, ctx->block_size);
|
||||||
if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0)
|
if (evpCipherBlock(ctx, output, ctx->buf, ctx->block_size) == 0) {
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
PRINT_BUF(out, ctx->block_size);
|
PRINT_BUF(out, ctx->block_size);
|
||||||
|
ctx->bufUsed = 0;
|
||||||
|
|
||||||
|
/* if doing encryption update the new output block, decryption will
|
||||||
|
* always have the last block saved for when Final is called */
|
||||||
|
if ((ctx->enc != 0)) {
|
||||||
*outl+= ctx->block_size;
|
*outl+= ctx->block_size;
|
||||||
out += ctx->block_size;
|
out += ctx->block_size;
|
||||||
ctx->bufUsed = 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks = inl / ctx->block_size;
|
blocks = inl / ctx->block_size;
|
||||||
if (blocks > 0) {
|
if (blocks > 0) {
|
||||||
if ((ctx->enc == 0) && (ctx->lastUsed == 1) && (copied == 0)) {
|
/* During decryption we save the last block to check padding on Final.
|
||||||
|
* Update the last block stored if one has already been stored */
|
||||||
|
if ((ctx->enc == 0) && (ctx->lastUsed == 1)) {
|
||||||
PRINT_BUF(ctx->lastBlock, ctx->block_size);
|
PRINT_BUF(ctx->lastBlock, ctx->block_size);
|
||||||
XMEMCPY(out, ctx->lastBlock, ctx->block_size);
|
XMEMCPY(out, ctx->lastBlock, ctx->block_size);
|
||||||
*outl += ctx->block_size;
|
*outl += ctx->block_size;
|
||||||
out += ctx->block_size;
|
out += ctx->block_size;
|
||||||
ctx->lastUsed = 0;
|
ctx->lastUsed = 0;
|
||||||
printf("Copied out last block - 2\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process blocks */
|
/* process blocks */
|
||||||
if (evpCipherBlock(ctx, out, in, blocks * ctx->block_size) == 0)
|
if (evpCipherBlock(ctx, out, in, blocks * ctx->block_size) == 0) {
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
PRINT_BUF(in, ctx->block_size*blocks);
|
PRINT_BUF(in, ctx->block_size*blocks);
|
||||||
PRINT_BUF(out,ctx->block_size*blocks);
|
PRINT_BUF(out,ctx->block_size*blocks);
|
||||||
inl -= ctx->block_size * blocks;
|
inl -= ctx->block_size * blocks;
|
||||||
@@ -449,29 +467,30 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
if ((ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) ||
|
if ((ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) ||
|
||||||
(ctx->block_size == 1)) {
|
(ctx->block_size == 1)) {
|
||||||
ctx->lastUsed = 0;
|
ctx->lastUsed = 0;
|
||||||
*outl+= ctx->block_size * blocks;
|
*outl += ctx->block_size * blocks;
|
||||||
} else {
|
} else {
|
||||||
if (inl == 0) {
|
/* in the case of decryption and padding, store the last block
|
||||||
|
* here in order to verify the padding when Final is called */
|
||||||
|
if (inl == 0) { /* if not 0 then we know leftovers are checked*/
|
||||||
ctx->lastUsed = 1;
|
ctx->lastUsed = 1;
|
||||||
blocks = blocks - 1; /* save last block to check padding in
|
blocks = blocks - 1; /* save last block to check padding in
|
||||||
* EVP_CipherFinal call */
|
* EVP_CipherFinal call */
|
||||||
XMEMCPY(ctx->lastBlock, &out[ctx->block_size * blocks],
|
XMEMCPY(ctx->lastBlock, &out[ctx->block_size * blocks],
|
||||||
ctx->block_size);
|
ctx->block_size);
|
||||||
printf("Saved last block\n");
|
|
||||||
}
|
}
|
||||||
*outl+= ctx->block_size * blocks;
|
*outl += ctx->block_size * blocks;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*outl+= ctx->block_size * blocks;
|
*outl += ctx->block_size * blocks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (inl > 0) {
|
if (inl > 0) {
|
||||||
/* put fraction into buff */
|
/* put fraction into buff */
|
||||||
fillBuff(ctx, in, inl);
|
fillBuff(ctx, in, inl);
|
||||||
printf("tailing fillBuff inl=%d\n", inl);
|
|
||||||
/* no increase of outl */
|
/* no increase of outl */
|
||||||
}
|
}
|
||||||
printf("Returning outl=%d, ctx->lastUsed= %d, ctx->bufUsed=%d\n", *outl, ctx->lastUsed, ctx->bufUsed);
|
|
||||||
(void)out; /* silence warning in case not read */
|
(void)out; /* silence warning in case not read */
|
||||||
|
|
||||||
return WOLFSSL_SUCCESS;
|
return WOLFSSL_SUCCESS;
|
||||||
@@ -527,7 +546,6 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
*outl = 0;
|
*outl = 0;
|
||||||
}
|
}
|
||||||
else if (ctx->enc) {
|
else if (ctx->enc) {
|
||||||
printf("EVP_CipherFinal(ctx->enc)\n");
|
|
||||||
if (ctx->block_size == 1) {
|
if (ctx->block_size == 1) {
|
||||||
*outl = 0;
|
*outl = 0;
|
||||||
}
|
}
|
||||||
@@ -560,7 +578,6 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
|||||||
if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
|
if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {
|
||||||
/* return error in cases where the block length is incorrect */
|
/* return error in cases where the block length is incorrect */
|
||||||
ret = WOLFSSL_FAILURE;
|
ret = WOLFSSL_FAILURE;
|
||||||
printf("EVP_CipherFinal(ctx->lastUsed == 0 && ctx->bufUsed == 0) fl=%d\n", fl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Reference in New Issue
Block a user