diff --git a/src/ssl.c b/src/ssl.c index 3d07c0f1e..c35bedc59 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -14089,19 +14089,80 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key, WOLFSSL_DES_key_schedule* schedule) { - WOLFSSL_ENTER("DES_key_sched"); + WOLFSSL_ENTER("wolfSSL_DES_key_sched"); if (key == NULL || schedule == NULL) { WOLFSSL_MSG("Null argument passed in"); } else { - XMEMCPY(schedule, key, sizeof(const_DES_cblock)); + XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock)); } return 0; } + /* intended to behave similar to Kerberos mit_des_cbc_cksum + * return the last 4 bytes of cipher text */ + WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in, + WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc, + WOLFSSL_const_DES_cblock* iv) + { + WOLFSSL_DES_LONG ret; + unsigned char* tmp; + unsigned char* data = (unsigned char*)in; + long dataSz = length; + byte dynamicFlag = 0; /* when padding the buffer created needs free'd */ + + WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum"); + + if (in == NULL || out == NULL || sc == NULL || iv == NULL) { + WOLFSSL_MSG("Bad argument passed in"); + return 0; + } + + /* if input length is not a multiple of DES_BLOCK_SIZE pad with 0s */ + if (dataSz % DES_BLOCK_SIZE) { + dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE); + data = (unsigned char*)XMALLOC(dataSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (data == NULL) { + WOLFSSL_MSG("Issue creating temporary buffer"); + return 0; + } + dynamicFlag = 1; /* set to free buffer at end */ + XMEMCPY(data, in, length); + XMEMSET(data + length, 0, dataSz - length); /* padding */ + } + + tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { + WOLFSSL_MSG("Issue creating temporary buffer"); + if (dynamicFlag == 1) { + XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + return 0; + } + + wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc, + (WOLFSSL_DES_cblock*)iv, 1); + XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE), + DES_BLOCK_SIZE); + + ret = (((*((unsigned char*)out + 4) & 0xFF) << 24)| + ((*((unsigned char*)out + 5) & 0xFF) << 16)| + ((*((unsigned char*)out + 6) & 0xFF) << 8) | + (*((unsigned char*)out + 7) & 0xFF)); + + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (dynamicFlag == 1) { + XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + return ret; + } + + void wolfSSL_DES_cbc_encrypt(const unsigned char* input, unsigned char* output, long length, WOLFSSL_DES_key_schedule* schedule, @@ -18555,8 +18616,25 @@ void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes, void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes) { - (void)myDes; - WOLFSSL_STUB("wolfSSL_DES_set_odd_parity"); + word32 i; + word32 sz = sizeof(WOLFSSL_DES_cblock); + + WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity"); + + for (i = 0; i < sz; i++) { + unsigned char c = *((unsigned char*)myDes + i); + if (((c & 0x01) ^ + ((c >> 1) & 0x01) ^ + ((c >> 2) & 0x01) ^ + ((c >> 3) & 0x01) ^ + ((c >> 4) & 0x01) ^ + ((c >> 5) & 0x01) ^ + ((c >> 6) & 0x01) ^ + ((c >> 7) & 0x01)) != 1) { + WOLFSSL_MSG("Setting odd parity bit"); + *((unsigned char*)myDes + i) = *((unsigned char*)myDes + i) | 0x80; + } + } } diff --git a/tests/api.c b/tests/api.c index 59e8bd1e3..8d868b630 100644 --- a/tests/api.c +++ b/tests/api.c @@ -13431,8 +13431,11 @@ static void test_wolfSSL_DES(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_DES3) const_DES_cblock myDes; + DES_cblock iv; DES_key_schedule key; word32 i; + DES_LONG dl; + unsigned char msg[] = "hello wolfssl"; printf(testingFmt, "wolfSSL_DES()"); @@ -13446,7 +13449,7 @@ static void test_wolfSSL_DES(void) AssertIntNE(key[0], myDes[0]); /* should not have copied over key */ /* set odd parity for success case */ - myDes[0] = 4; + DES_set_odd_parity(&myDes); AssertIntEQ(DES_set_key_checked(&myDes, &key), 0); for (i = 0; i < sizeof(DES_key_schedule); i++) { AssertIntEQ(key[i], myDes[i]); @@ -13477,6 +13480,13 @@ static void test_wolfSSL_DES(void) AssertIntEQ(key[i], myDes[i]); } + /* DES_cbc_cksum should return the last 4 of the last 8 bytes after + * DES_cbc_encrypt on the input */ + XMEMSET(iv, 0, sizeof(DES_cblock)); + XMEMSET(myDes, 5, sizeof(DES_key_schedule)); + AssertIntGT((dl = DES_cbc_cksum(msg, &key, sizeof(msg), &myDes, &iv)), 0); + AssertIntEQ(dl, 480052723); + printf(resultFmt, passed); #endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ } diff --git a/wolfssl/openssl/des.h b/wolfssl/openssl/des.h index 74ee7538e..6d172467e 100644 --- a/wolfssl/openssl/des.h +++ b/wolfssl/openssl/des.h @@ -45,6 +45,7 @@ typedef unsigned char WOLFSSL_DES_cblock[8]; typedef /* const */ WOLFSSL_DES_cblock WOLFSSL_const_DES_cblock; typedef WOLFSSL_DES_cblock WOLFSSL_DES_key_schedule; +typedef unsigned int WOLFSSL_DES_LONG; enum { @@ -54,6 +55,9 @@ enum { WOLFSSL_API int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key); +WOLFSSL_API WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in, + WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc, + WOLFSSL_const_DES_cblock* iv); WOLFSSL_API int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, WOLFSSL_DES_key_schedule* key); WOLFSSL_API int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, @@ -85,6 +89,7 @@ WOLFSSL_API void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock*, WOLFSSL_DES_cblock typedef WOLFSSL_DES_cblock DES_cblock; typedef WOLFSSL_const_DES_cblock const_DES_cblock; typedef WOLFSSL_DES_key_schedule DES_key_schedule; +typedef WOLFSSL_DES_LONG DES_LONG; #define DES_check_key(x) /* Define WOLFSSL_CHECK_DESKEY to check key */ #define DES_is_weak_key wolfSSL_DES_is_weak_key @@ -97,6 +102,7 @@ typedef WOLFSSL_DES_key_schedule DES_key_schedule; #define DES_set_odd_parity wolfSSL_DES_set_odd_parity #define DES_ecb_encrypt wolfSSL_DES_ecb_encrypt #define DES_ede3_cbc_encrypt wolfSSL_DES_ede3_cbc_encrypt +#define DES_cbc_cksum wolfSSL_DES_cbc_cksum #ifdef __cplusplus } /* extern "C" */