From 4baf494ddd5d2d25732951f56a76f1b66f701c32 Mon Sep 17 00:00:00 2001 From: Takashi Kojo Date: Sat, 26 Nov 2016 17:56:40 +0900 Subject: [PATCH] add EVP_CipherUpdate/Final --- src/ssl.c | 3 +- wolfcrypt/src/evp.c | 77 +++++++++++++++++++++--------------- wolfcrypt/test/test.c | 92 +++++++++++++++++++++++++++++++++++++++++-- wolfssl/openssl/evp.h | 4 +- 4 files changed, 138 insertions(+), 38 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 0cbfa8f31..3d5136e89 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -10730,7 +10730,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return 0; /* failure */ } ctx->bufUsed = 0; - ctx->finUsed = 0; + ctx->lastUsed = 0; + ctx->flags = 0; #ifndef NO_AES /* printf("cipherType=%d\n", ctx->cipherType); */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 390153d50..d41d1e9c4 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -64,7 +64,7 @@ WOLFSSL_API int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx, return wolfSSL_EVP_DigestInit(ctx, type); } -#ifdef DEBUG_WOLFSSL +#ifdef DEBUG_WOLFSSL_EVP #define PRINT_BUF(b, sz) { int i; for(i=0; i<(sz); i++){printf("%02x(%c),", (b)[i], (b)[i]); if((i+1)%8==0)printf("\n");}} #else #define PRINT_BUF(b, sz) @@ -73,8 +73,7 @@ WOLFSSL_API int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx, static int fillBuff(WOLFSSL_EVP_CIPHER_CTX *ctx, const unsigned char *in, int sz) { int fill; - WOLFSSL_ENTER("fillBuff"); - /* printf("ctx->bufUsed=%d, sz=%d\n",ctx->bufUsed, sz); */ + if (sz > 0) { if ((sz+ctx->bufUsed) > ctx->block_size) { fill = ctx->block_size - ctx->bufUsed; @@ -83,7 +82,6 @@ static int fillBuff(WOLFSSL_EVP_CIPHER_CTX *ctx, const unsigned char *in, int sz } XMEMCPY(&(ctx->buf[ctx->bufUsed]), in, fill); ctx->bufUsed += fill; - /* printf("Result: ctx->bufUsed=%d\n",ctx->bufUsed); */ return fill; } else return 0; } @@ -92,7 +90,6 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, int inl) { - WOLFSSL_ENTER("evpCipherBlock"); switch (ctx->cipherType) { #if !defined(NO_AES) && defined(HAVE_AES_CBC) case AES_128_CBC_TYPE: @@ -152,8 +149,6 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, default: return 0; } - ctx->finUsed = 1; - XMEMCPY(ctx->fin, (const byte *)&out[inl-ctx->block_size], ctx->block_size); (void)in; return 1; } @@ -173,12 +168,25 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, inl -= fill; in += fill; } - if (ctx->bufUsed == ctx->block_size) { - /* the buff is full, flash out */ - if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) - return 0; + if((ctx->enc == 0)&& (ctx->lastUsed == 1)){ + PRINT_BUF(ctx->lastBlock, ctx->block_size); + XMEMCPY(out, ctx->lastBlock, ctx->block_size); *outl+= ctx->block_size; out += ctx->block_size; + } + if ((ctx->bufUsed == ctx->block_size) || (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING)){ + /* the buff is full, flash out */ + PRINT_BUF(ctx->buf, ctx->block_size); + if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) + return 0; + PRINT_BUF(out, ctx->block_size); + if(ctx->enc == 0){ + ctx->lastUsed = 1; + XMEMCPY(ctx->lastBlock, out, ctx->block_size); + } else { + *outl+= ctx->block_size; + out += ctx->block_size; + } ctx->bufUsed = 0; } @@ -187,10 +195,17 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, /* process blocks */ if (evpCipherBlock(ctx, out, ctx->buf, blocks) == 0) return 0; + PRINT_BUF(ctx->buf, ctx->block_size); + PRINT_BUF(out, ctx->block_size); inl -= ctx->block_size * blocks; - *outl+= ctx->block_size * blocks; in += ctx->block_size * blocks; - out += ctx->block_size * blocks; + if(ctx->enc == 0){ + ctx->lastUsed = 1; + XMEMCPY(ctx->lastBlock, &out[ctx->block_size * (blocks-1)], ctx->block_size); + *outl+= ctx->block_size * (blocks-1); + } else { + *outl+= ctx->block_size * blocks; + } } if (inl > 0) { /* put fraction into buff */ @@ -206,22 +221,22 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, static void padBlock(WOLFSSL_EVP_CIPHER_CTX *ctx) { int i; - WOLFSSL_ENTER("paddBlock"); for (i = ctx->bufUsed; i < ctx->block_size; i++) ctx->buf[i] = (byte)(ctx->block_size - ctx->bufUsed); } -static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx) +static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff) { int i; int n; - WOLFSSL_ENTER("checkPad"); - n = ctx->buf[ctx->block_size-1]; + n = buff[ctx->block_size-1]; + if (n > ctx->block_size) return FALSE; - for (i = n; i < ctx->block_size; i++) - if (ctx->buf[i] != n) - return -1; - return n; + for (i = 0; i < n; i++){ + if (buff[ctx->block_size-i-1] != n) + return FALSE; + } + return ctx->block_size - n; } WOLFSSL_API int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, @@ -234,24 +249,22 @@ WOLFSSL_API int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, *outl = 0; return 1; } - if (ctx->bufUsed > 0) { - if (ctx->enc) { + if (ctx->enc) { + if (ctx->bufUsed > 0) { padBlock(ctx); - /* printf("Enc: block_size=%d\n", ctx->block_size); */ PRINT_BUF(ctx->buf, ctx->block_size); if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) return 0; + PRINT_BUF(out, ctx->block_size); *outl = ctx->block_size; } - else { - if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) - return 0; - /* printf("Dec: block_size=%d\n", ctx->block_size); */ - PRINT_BUF(ctx->buf, ctx->block_size); - if ((fl = checkPad(ctx)) >= 0) { - XMEMCPY(out, ctx->buf, fl); + } else { + if (ctx->lastUsed){ + PRINT_BUF(ctx->lastBlock, ctx->block_size); + if ((fl = checkPad(ctx, ctx->lastBlock)) >= 0) { + XMEMCPY(out, ctx->lastBlock, fl); *outl = fl; - } else return 0; + } else return 0; } } return 1; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 9deae33f0..c0d79b45a 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6982,6 +6982,7 @@ int openssl_test(void) #ifdef WOLFSSL_AES_DIRECT /* enable HAVE_AES_DECRYPT for AES_encrypt/decrypt */ +{ /* Test: AES_encrypt/decrypt/set Key */ AES_KEY enc; @@ -7028,6 +7029,7 @@ int openssl_test(void) if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) return OPENSSL_TEST_ERROR-61; +} #endif @@ -7194,7 +7196,6 @@ int openssl_test(void) if (EVP_CipherInit(&en, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) return -3316; - printf("EVP_Cipher\n"); if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr192Plain, AES_BLOCK_SIZE) == 0) return -3317; EVP_CIPHER_CTX_init(&de); @@ -7230,11 +7231,96 @@ int openssl_test(void) return -3326; if (XMEMCMP(ctr256Cipher, cipherBuff, sizeof(ctr256Cipher))) return -3327; - } - #endif /* HAVE_AES_COUNTER */ +{ + /* EVP_CipherUpdate test */ + + + const byte cbcPlain[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, + 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 + }; + + byte key[] = "0123456789abcdef "; /* align */ + byte iv[] = "1234567890abcdef "; /* align */ + + byte cipher[AES_BLOCK_SIZE * 4]; + byte plain [AES_BLOCK_SIZE * 4]; + EVP_CIPHER_CTX en; + EVP_CIPHER_CTX de; + int outlen ; + int total = 0; + + EVP_CIPHER_CTX_init(&en); + if (EVP_CipherInit(&en, EVP_aes_128_cbc(), + (unsigned char*)key, (unsigned char*)iv, 1) == 0) + return -3401; + if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 9) == 0) + return -3402; + if(outlen != 0) + return -3403; + total += outlen; + + if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[9] , 9) == 0) + return -3404; + if(outlen != 16) + return -3405; + total += outlen; + + if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) + return -3406; + if(outlen != 16) + return -3407; + total += outlen; + if(total != 32) + return 3408; + + total = 0; + EVP_CIPHER_CTX_init(&de); + if (EVP_CipherInit(&de, EVP_aes_128_cbc(), + (unsigned char*)key, (unsigned char*)iv, 0) == 0) + return -3420; + + if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 6) == 0) + return -3421; + if(outlen != 0) + return -3422; + total += outlen; + + if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6], 12) == 0) + return -3423; + if(outlen != 0) + total += outlen; + + if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6+12], 14) == 0) + return -3423; + if(outlen != 16) + return -3424; + total += outlen; + + if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) + return -3425; + if(outlen != 2) + return -3426; + total += outlen; + + if(total != 18) + return 3427; + + if (XMEMCMP(plain, cbcPlain, 18)) + return -3428; + + } + return 0; } diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 1de39e318..282a49b81 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -169,8 +169,8 @@ typedef struct WOLFSSL_EVP_CIPHER_CTX { WOLFSSL_Cipher cipher; ALIGN16 byte buf[WOLFSSL_EVP_BUF_SIZE]; int bufUsed; - ALIGN16 byte fin[WOLFSSL_EVP_BUF_SIZE]; - int finUsed; + ALIGN16 byte lastBlock[WOLFSSL_EVP_BUF_SIZE]; + int lastUsed; } WOLFSSL_EVP_CIPHER_CTX; typedef int WOLFSSL_ENGINE ;