diff --git a/examples/client/client.c b/examples/client/client.c index 8ec2ac7a28f..23574d8f38a 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1281,6 +1281,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (ssl == NULL) err_sys("unable to get SSL object"); + #ifdef OPENSSL_EXTRA + wolfSSL_KeepArrays(ssl); + #endif + #ifdef HAVE_SUPPORTED_CURVES /* add curves to supported curves extension */ if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP256R1) != SSL_SUCCESS) { @@ -1428,6 +1432,36 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif showPeer(ssl); +#ifdef OPENSSL_EXTRA + { + byte* rnd; + byte* pt; + int size; + + /* get size of buffer then print */ + size = wolfSSL_get_client_random(NULL, NULL, 0); + if (size < 0) { + err_sys("error getting client random buffer size"); + } + + rnd = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (rnd == NULL) { + err_sys("error creating client random buffer"); + } + + size = wolfSSL_get_client_random(ssl, rnd, size); + if (size < 0) { + XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER); + err_sys("error getting client random buffer"); + } + + printf("Client Random : "); + for (pt = rnd; pt < rnd + size; pt++) printf("%02X", *pt); + printf("\n"); + XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + if (doSTARTTLS) { if (XSTRNCMP(starttlsProt, "smtp", 4) == 0) { if (SMTP_Shutdown(ssl, wc_shutdown) != SSL_SUCCESS) { diff --git a/src/ssl.c b/src/ssl.c index 4401c20a35c..8ac38b8f39e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5630,6 +5630,44 @@ int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file) +#if !defined(NO_WOLFSSL_CLIENT) +/* Return the amount of random bytes copied over or error case. + * ssl : ssl struct after handshake + * out : buffer to hold random bytes + * outSz : either 0 (return max buffer sz) or size of out buffer + * + * NOTE: wolfSSL_KeepArrays(ssl) must be called to retain handshake information. + */ +int wolfSSL_get_client_random(WOLFSSL* ssl, unsigned char* out, int outSz) +{ + int size; + + /* return max size of buffer */ + if (outSz == 0) { + return RAN_LEN; + } + + if (ssl == NULL || out == NULL || outSz < 0) { + return BAD_FUNC_ARG; + } + + if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) { + WOLFSSL_MSG("Arrays struct not saved after handshake"); + return BAD_FUNC_ARG; + } + + if (outSz > RAN_LEN) { + size = RAN_LEN; + } + else { + size = outSz; + } + + XMEMCPY(out, ssl->arrays->clientRandom, size); + return size; +} +#endif /* !defined(NO_WOLFSSL_CLIENT) */ + #ifdef HAVE_ECC /* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */ @@ -13272,6 +13310,132 @@ long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx) } #ifndef NO_DES3 +void wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, + WOLFSSL_DES_key_schedule* key) +{ +#ifdef WOLFSSL_CHECK_DESKEY + wolfSSL_DES_set_key_checked(myDes, key); +#else + wolfSSL_DES_set_key_unchecked(myDes, key); +#endif +} + + + +/* return true in fail case (1) */ +static int DES_check(word32 mask, word32 mask2, unsigned char* key) +{ + word32 value[2]; + + /* sanity check on length made in wolfSSL_DES_set_key_checked */ + value[0] = mask; + value[1] = mask2; + return (XMEMCMP(value, key, sizeof(value)) == 0)? 1: 0; +} + + +/* check that the key is odd parity and is not a weak key */ +void wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, + WOLFSSL_DES_key_schedule* key) +{ + if (myDes == NULL || key == NULL) { + WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked"); + } + else { + word32 i, mask, mask2; + word32 sz = sizeof(WOLFSSL_DES_key_schedule); + + /* sanity check before call to DES_check */ + if (sz != (sizeof(word32) * 2)) { + WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size"); + return; + } + + /* check odd parity */ + for (i = 0; i < sz; i++) { + unsigned char c = *((unsigned char*)key + 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("Odd parity test fail"); + return; + } + } + + /* check is not weak. Weak key list from Nist + "Recommendation for the Triple + Data Encryption Algorithm + (TDEA) Block Cipher" */ + mask = 0x01010101; mask2 = 0x01010101; + if (DES_check(mask, mask2, *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE; + if (DES_check(mask, mask2, *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1; + if (DES_check(mask, mask2, *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E; + if (DES_check(mask, mask2, *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + /* semi-weak *key check (list from same Nist paper) */ + mask = 0x011F011F; mask2 = 0x010E010E; + if (DES_check(mask, mask2, *key) || + DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + mask = 0x01E001E0; mask2 = 0x01F101F1; + if (DES_check(mask, mask2, *key) || + DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + mask = 0x01FE01FE; mask2 = 0x01FE01FE; + if (DES_check(mask, mask2, *key) || + DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + mask = 0x1FE01FE0; mask2 = 0x0EF10EF1; + if (DES_check(mask, mask2, *key) || + DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + mask = 0x1FFE1FFE; mask2 = 0x0EFE0EFE; + if (DES_check(mask, mask2, *key) || + DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { + WOLFSSL_MSG("Weak key found"); + return; + } + + /* passed tests, now copy over key */ + XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock)); + } +} + void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes, WOLFSSL_DES_key_schedule* key) diff --git a/tests/api.c b/tests/api.c index 67428715b2c..26eea679423 100644 --- a/tests/api.c +++ b/tests/api.c @@ -46,7 +46,10 @@ #ifdef OPENSSL_EXTRA #include #include +#ifndef NO_DES3 + #include #endif +#endif /* OPENSSL_EXTRA */ /* enable testing buffer load functions */ #ifndef USE_CERT_BUFFERS_2048 @@ -2195,6 +2198,53 @@ static int test_wolfSSL_UseOCSPStaplingV2(void) } /*END test_wolfSSL_UseOCSPStaplingV2*/ +/*----------------------------------------------------------------------------* + | Compatibility Tests + *----------------------------------------------------------------------------*/ + + +static void test_wolfSSL_DES(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_DES3) + const_DES_cblock myDes; + DES_key_schedule key; + word32 i; + + printf(testingFmt, "wolfSSL_DES()"); + + DES_check_key(1); + DES_set_key(&myDes, &key); + + /* check, check of odd parity */ + XMEMSET(key, 4, sizeof(DES_key_schedule)); key[0] = 3; /*set even parity*/ + XMEMSET(myDes, 5, sizeof(const_DES_cblock)); + DES_set_key_checked(&myDes, &key); + AssertIntNE(key[0], myDes[0]); /* should not have copied over key */ + + /* set odd parity for success case */ + key[0] = 4; + DES_set_key_checked(&myDes, &key); + for (i = 0; i < sizeof(DES_key_schedule); i++) { + AssertIntEQ(key[i], myDes[i]); + } + + /* check weak key */ + XMEMSET(key, 1, sizeof(DES_key_schedule)); + XMEMSET(myDes, 5, sizeof(const_DES_cblock)); + DES_set_key_checked(&myDes, &key); + AssertIntNE(key[0], myDes[0]); /* should not have copied over key */ + + /* now do unchecked copy of a weak key over */ + DES_set_key_unchecked(&myDes, &key); + /* compare arrays, should be the same */ + for (i = 0; i < sizeof(DES_key_schedule); i++) { + AssertIntEQ(key[i], myDes[i]); + } + + printf(resultFmt, passed); + #endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ +} + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -2239,6 +2289,9 @@ void ApiTest(void) AssertIntEQ(test_wolfSSL_UseOCSPStapling(), SSL_SUCCESS); AssertIntEQ(test_wolfSSL_UseOCSPStaplingV2(), SSL_SUCCESS); + /* compatibility tests */ + test_wolfSSL_DES(); + AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS); printf(" End API Tests\n"); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 9a15b3af173..54bbb9dfb40 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6322,6 +6322,14 @@ int openssl_test(void) (void)e; (void)f; + /* test malloc / free , 10 is an arbitrary amount of memory chosen */ + { + byte* p; + p = (byte*)CRYPTO_malloc(10, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XMEMSET(p, 0, 10); + CRYPTO_free(p, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + } + #ifndef NO_MD5 a.input = "1234567890123456789012345678901234567890123456789012345678" diff --git a/wolfssl/openssl/des.h b/wolfssl/openssl/des.h index 14b843b0bfb..0425511963f 100644 --- a/wolfssl/openssl/des.h +++ b/wolfssl/openssl/des.h @@ -53,6 +53,10 @@ enum { }; +WOLFSSL_API void wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, + WOLFSSL_DES_key_schedule* key); +WOLFSSL_API void wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, + WOLFSSL_DES_key_schedule* key); WOLFSSL_API void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock*, WOLFSSL_DES_key_schedule*); WOLFSSL_API int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key, @@ -81,6 +85,9 @@ typedef WOLFSSL_DES_cblock DES_cblock; typedef WOLFSSL_const_DES_cblock const_DES_cblock; typedef WOLFSSL_DES_key_schedule DES_key_schedule; +#define DES_check_key(x) /* Define WOLFSSL_CHECK_DESKEY to check key */ +#define DES_set_key wolfSSL_DES_set_key +#define DES_set_key_checked wolfSSL_DES_set_key_checked #define DES_set_key_unchecked wolfSSL_DES_set_key_unchecked #define DES_key_sched wolfSSL_DES_key_sched #define DES_cbc_encrypt wolfSSL_DES_cbc_encrypt diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 756321b9363..22592f7d7db 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -90,6 +90,11 @@ typedef WOLFSSL_X509_REVOKED X509_REVOKED; typedef WOLFSSL_X509_OBJECT X509_OBJECT; typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; +#define CRYPTO_free XFREE +#define CRYPTO_malloc XMALLOC + +#define SSL_get_client_random(ssl,out,outSz) \ + wolfSSL_get_client_random((ssl),(out),(outSz)) #define SSL_get_cipher_list(ctx,i) wolfSSL_get_cipher_list((i)) #define SSL_get_cipher_name(ctx) wolfSSL_get_cipher((ctx)) #define SSL_get_shared_ciphers(ctx,buf,len) \ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c29371ad73a..30ff6491201 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1797,7 +1797,12 @@ WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time, #ifdef OPENSSL_EXTRA - /*lighttp compatibility */ +WOLFSSL_API int wolfSSL_get_client_random(WOLFSSL* ssl, unsigned char* out, + int outSz); + + +/*lighttp compatibility */ + #include struct WOLFSSL_X509_NAME_ENTRY { WOLFSSL_ASN1_OBJECT* object; /* not defined yet */