diff --git a/src/ssl.c b/src/ssl.c index 0aa2dc6f3..5c3fc20b8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -14064,7 +14064,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) Des myDes; byte lastblock[DES_BLOCK_SIZE]; int lb_sz; - long blk; + long idx = length; + long blk; WOLFSSL_ENTER("DES_ncbc_encrypt"); @@ -14072,23 +14073,33 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, !enc); lb_sz = length%DES_BLOCK_SIZE; blk = length/DES_BLOCK_SIZE; + idx -= sizeof(DES_cblock); + if (lb_sz) { + idx += DES_BLOCK_SIZE - lb_sz; + } if (enc){ - wc_Des_CbcEncrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE); - if(lb_sz){ + wc_Des_CbcEncrypt(&myDes, output, input, + (word32)blk * DES_BLOCK_SIZE); + if (lb_sz){ XMEMSET(lastblock, 0, DES_BLOCK_SIZE); XMEMCPY(lastblock, input+length-lb_sz, lb_sz); - wc_Des_CbcEncrypt(&myDes, output+blk*DES_BLOCK_SIZE, + wc_Des_CbcEncrypt(&myDes, output + blk * DES_BLOCK_SIZE, lastblock, (word32)DES_BLOCK_SIZE); } + XMEMCPY(ivec, output + idx, sizeof(DES_cblock)); } else { - wc_Des_CbcDecrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE); - if(lb_sz){ - wc_Des_CbcDecrypt(&myDes, lastblock, input+length-lb_sz, (word32)DES_BLOCK_SIZE); + WOLFSSL_DES_cblock tmp; + XMEMCPY(tmp, input + idx, sizeof(DES_cblock)); + wc_Des_CbcDecrypt(&myDes, output, input, + (word32)blk * DES_BLOCK_SIZE); + if (lb_sz){ + wc_Des_CbcDecrypt(&myDes, lastblock, input + length - lb_sz, + (word32)DES_BLOCK_SIZE); XMEMCPY(output+length-lb_sz, lastblock, lb_sz); } + XMEMCPY(ivec, tmp, sizeof(WOLFSSL_DES_cblock)); } - XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock)); } #endif /* NO_DES3 */ diff --git a/tests/api.c b/tests/api.c index 4fd5c2903..ab9079ea4 100644 --- a/tests/api.c +++ b/tests/api.c @@ -19111,6 +19111,53 @@ static void test_wolfSSL_X509_check_ca(void){ #endif } +static void test_wolfSSL_DES_ncbc(void){ +#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) + const_DES_cblock myDes; + DES_cblock iv = {1}; + DES_key_schedule key = {0}; + unsigned char msg[] = "hello wolfssl"; + unsigned char out[DES_BLOCK_SIZE * 2] = {0}; + unsigned char pln[DES_BLOCK_SIZE * 2] = {0}; + + unsigned char exp[] = {0x31, 0x98, 0x2F, 0x3A, 0x55, 0xBF, 0xD8, 0xC4}; + unsigned char exp2[] = {0xC7, 0x45, 0x8B, 0x28, 0x10, 0x53, 0xE0, 0x58}; + + printf(testingFmt, "wolfSSL_DES_ncbc()"); + + /* partial block test */ + DES_set_key(&key, &myDes); + DES_ncbc_encrypt(msg, out, 3, &myDes, &iv, DES_ENCRYPT); + AssertIntEQ(XMEMCMP(exp, out, DES_BLOCK_SIZE), 0); + AssertIntEQ(XMEMCMP(exp, iv, DES_BLOCK_SIZE), 0); + + DES_set_key(&key, &myDes); + XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); + *((byte*)&iv) = 1; + DES_ncbc_encrypt(out, pln, 3, &myDes, &iv, DES_DECRYPT); + AssertIntEQ(XMEMCMP(msg, pln, 3), 0); + AssertIntEQ(XMEMCMP(exp, iv, DES_BLOCK_SIZE), 0); + + /* full block test */ + DES_set_key(&key, &myDes); + XMEMSET(pln, 0, DES_BLOCK_SIZE); + XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); + *((byte*)&iv) = 1; + DES_ncbc_encrypt(msg, out, 8, &myDes, &iv, DES_ENCRYPT); + AssertIntEQ(XMEMCMP(exp2, out, DES_BLOCK_SIZE), 0); + AssertIntEQ(XMEMCMP(exp2, iv, DES_BLOCK_SIZE), 0); + + DES_set_key(&key, &myDes); + XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); + *((byte*)&iv) = 1; + DES_ncbc_encrypt(out, pln, 8, &myDes, &iv, DES_DECRYPT); + AssertIntEQ(XMEMCMP(msg, pln, 8), 0); + AssertIntEQ(XMEMCMP(exp2, iv, DES_BLOCK_SIZE), 0); + + printf(resultFmt, passed); +#endif +} + static void test_no_op_functions(void) { #if defined(OPENSSL_EXTRA) @@ -20442,6 +20489,7 @@ void ApiTest(void) test_wolfSSL_ASN1_TIME_to_generalizedtime(); test_wolfSSL_i2c_ASN1_INTEGER(); test_wolfSSL_X509_check_ca(); + test_wolfSSL_DES_ncbc(); #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) AssertIntEQ(test_wolfSSL_CTX_use_certificate_ASN1(), WOLFSSL_SUCCESS);