From f8f7f69f48d21b1811bd84695438982360dd2363 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 26 Nov 2012 18:40:43 -0800 Subject: [PATCH] compile option to leave out MD5 and SSL code --- configure.ac | 2 +- ctaocrypt/src/asn.c | 9 +- ctaocrypt/src/hmac.c | 315 +++++++++++++++++++++++++-------------- cyassl/ctaocrypt/asn.h | 2 +- cyassl/ctaocrypt/hmac.h | 12 +- cyassl/ctaocrypt/md5.h | 3 +- cyassl/internal.h | 19 ++- examples/client/client.c | 2 + examples/server/server.c | 2 + src/crl.c | 3 +- src/include.am | 2 +- src/internal.c | 70 +++++++-- src/keys.c | 12 +- src/tls.c | 123 +++++++++++---- tests/api.c | 2 + tests/hash.c | 6 + tests/include.am | 3 +- tests/suites.c | 12 +- tests/test-leanpsk.conf | 20 +++ testsuite/testsuite.c | 22 +-- 20 files changed, 445 insertions(+), 196 deletions(-) create mode 100644 tests/test-leanpsk.conf diff --git a/configure.ac b/configure.ac index 11df99e88..a2a316266 100644 --- a/configure.ac +++ b/configure.ac @@ -217,7 +217,7 @@ AC_ARG_ENABLE(leanpsk, if test "$ENABLED_LEANPSK" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DCYASSL_LEANPSK -DHAVE_NULL_CIPHER -DNO_AES -DNO_FILESYSTEM -DNO_RSA -DNO_DSA -DNO_DH -DNO_CERTS -DNO_PWDBASED -DNO_DES3 -DNO_MD4 -DNO_ERROR_STRINGS" + AM_CFLAGS="$AM_CFLAGS -DCYASSL_LEANPSK -DHAVE_NULL_CIPHER -DNO_AES -DNO_FILESYSTEM -DNO_RSA -DNO_DSA -DNO_DH -DNO_CERTS -DNO_PWDBASED -DNO_DES3 -DNO_MD4 -DNO_MD5 -DNO_ERROR_STRINGS -DNO_OLD_TLS" ENABLED_SLOWMATH="no" fi diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 1bc83b473..19c196cd7 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4941,15 +4941,16 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) { int version, len; word32 oid, idx = 0; - Md5 md5; + Sha sha; Signer* ca; CYASSL_MSG("ParseCRL"); /* raw crl hash */ - InitMd5(&md5); - Md5Update(&md5, buff, sz); - Md5Final(&md5, dcrl->crlHash); + /* hash here if needed for optimized comparisons + * InitSha(&sha); + * ShaUpdate(&sha, buff, sz); + * ShaFinal(&sha, dcrl->crlHash); */ if (GetSequence(buff, &idx, &len, sz) < 0) return ASN_PARSE_E; diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index 880581e8c..42335def6 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -37,18 +37,32 @@ static int InitHmac(Hmac* hmac, int type) if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384)) return BAD_FUNC_ARG; - if (type == MD5) - InitMd5(&hmac->hash.md5); - else if (type == SHA) - InitSha(&hmac->hash.sha); -#ifndef NO_SHA256 - else if (type == SHA256) - InitSha256(&hmac->hash.sha256); -#endif -#ifdef CYASSL_SHA384 - else if (type == SHA384) - InitSha384(&hmac->hash.sha384); -#endif + switch (type) { + #ifndef NO_MD5 + case MD5: + InitMd5(&hmac->hash.md5); + break; + #endif + + case SHA: + InitSha(&hmac->hash.sha); + break; + + #ifndef NO_SHA256 + case SHA256: + InitSha256(&hmac->hash.sha256); + break; + #endif + + #ifdef CYASSL_SHA384 + case SHA384: + InitSha384(&hmac->hash.sha384); + break; + #endif + + default: + break; + } return 0; } @@ -58,57 +72,75 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) { byte* ip = (byte*) hmac->ipad; byte* op = (byte*) hmac->opad; - word32 i, hmac_block_size = MD5_BLOCK_SIZE; + word32 i, hmac_block_size = SHA_BLOCK_SIZE; InitHmac(hmac, type); - if (hmac->macType == MD5) { - if (length <= MD5_BLOCK_SIZE) { - XMEMCPY(ip, key, length); + switch (hmac->macType) { + #ifndef NO_MD5 + case MD5: + { + hmac_block_size = MD5_BLOCK_SIZE; + if (length <= MD5_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { + Md5Update(&hmac->hash.md5, key, length); + Md5Final(&hmac->hash.md5, ip); + length = MD5_DIGEST_SIZE; + } } - else { - Md5Update(&hmac->hash.md5, key, length); - Md5Final(&hmac->hash.md5, ip); - length = MD5_DIGEST_SIZE; + break; + #endif + + case SHA: + { + if (length <= SHA_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { + ShaUpdate(&hmac->hash.sha, key, length); + ShaFinal(&hmac->hash.sha, ip); + length = SHA_DIGEST_SIZE; + } } + break; + + #ifndef NO_SHA256 + case SHA256: + { + hmac_block_size = SHA256_BLOCK_SIZE; + if (length <= SHA256_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { + Sha256Update(&hmac->hash.sha256, key, length); + Sha256Final(&hmac->hash.sha256, ip); + length = SHA256_DIGEST_SIZE; + } + } + break; + #endif + + #ifdef CYASSL_SHA384 + case SHA384: + { + hmac_block_size = SHA384_BLOCK_SIZE; + if (length <= SHA384_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { + Sha384Update(&hmac->hash.sha384, key, length); + Sha384Final(&hmac->hash.sha384, ip); + length = SHA384_DIGEST_SIZE; + } + } + break; + #endif + + default: + break; } - else if (hmac->macType == SHA) { - hmac_block_size = SHA_BLOCK_SIZE; - if (length <= SHA_BLOCK_SIZE) { - XMEMCPY(ip, key, length); - } - else { - ShaUpdate(&hmac->hash.sha, key, length); - ShaFinal(&hmac->hash.sha, ip); - length = SHA_DIGEST_SIZE; - } - } -#ifndef NO_SHA256 - else if (hmac->macType == SHA256) { - hmac_block_size = SHA256_BLOCK_SIZE; - if (length <= SHA256_BLOCK_SIZE) { - XMEMCPY(ip, key, length); - } - else { - Sha256Update(&hmac->hash.sha256, key, length); - Sha256Final(&hmac->hash.sha256, ip); - length = SHA256_DIGEST_SIZE; - } - } -#endif -#ifdef CYASSL_SHA384 - else if (hmac->macType == SHA384) { - hmac_block_size = SHA384_BLOCK_SIZE; - if (length <= SHA384_BLOCK_SIZE) { - XMEMCPY(ip, key, length); - } - else { - Sha384Update(&hmac->hash.sha384, key, length); - Sha384Final(&hmac->hash.sha384, ip); - length = SHA384_DIGEST_SIZE; - } - } -#endif XMEMSET(ip + length, 0, hmac_block_size - length); for(i = 0; i < hmac_block_size; i++) { @@ -120,18 +152,34 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) static void HmacKeyInnerHash(Hmac* hmac) { - if (hmac->macType == MD5) - Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); - else if (hmac->macType == SHA) - ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE); -#ifndef NO_SHA256 - else if (hmac->macType == SHA256) - Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, SHA256_BLOCK_SIZE); -#endif -#ifdef CYASSL_SHA384 - else if (hmac->macType == SHA384) - Sha384Update(&hmac->hash.sha384, (byte*) hmac->ipad, SHA384_BLOCK_SIZE); -#endif + switch (hmac->macType) { + #ifndef NO_MD5 + case MD5: + Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); + break; + #endif + + case SHA: + ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE); + break; + + #ifndef NO_SHA256 + case SHA256: + Sha256Update(&hmac->hash.sha256, + (byte*) hmac->ipad, SHA256_BLOCK_SIZE); + break; + #endif + + #ifdef CYASSL_SHA384 + case SHA384: + Sha384Update(&hmac->hash.sha384, + (byte*) hmac->ipad, SHA384_BLOCK_SIZE); + break; + #endif + + default: + break; + } hmac->innerHashKeyed = 1; } @@ -142,18 +190,32 @@ void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) if (!hmac->innerHashKeyed) HmacKeyInnerHash(hmac); - if (hmac->macType == MD5) - Md5Update(&hmac->hash.md5, msg, length); - else if (hmac->macType == SHA) - ShaUpdate(&hmac->hash.sha, msg, length); -#ifndef NO_SHA256 - else if (hmac->macType == SHA256) - Sha256Update(&hmac->hash.sha256, msg, length); -#endif -#ifdef CYASSL_SHA384 - else if (hmac->macType == SHA384) - Sha384Update(&hmac->hash.sha384, msg, length); -#endif + switch (hmac->macType) { + #ifndef NO_MD5 + case MD5: + Md5Update(&hmac->hash.md5, msg, length); + break; + #endif + + case SHA: + ShaUpdate(&hmac->hash.sha, msg, length); + break; + + #ifndef NO_SHA256 + case SHA256: + Sha256Update(&hmac->hash.sha256, msg, length); + break; + #endif + + #ifdef CYASSL_SHA384 + case SHA384: + Sha384Update(&hmac->hash.sha384, msg, length); + break; + #endif + + default: + break; + } } @@ -163,44 +225,65 @@ void HmacFinal(Hmac* hmac, byte* hash) if (!hmac->innerHashKeyed) HmacKeyInnerHash(hmac); - if (hmac->macType == MD5) { - Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); + switch (hmac->macType) { + #ifndef NO_MD5 + case MD5: + { + Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); - Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); - Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE); + Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); + Md5Update(&hmac->hash.md5, + (byte*) hmac->innerHash, MD5_DIGEST_SIZE); - Md5Final(&hmac->hash.md5, hash); + Md5Final(&hmac->hash.md5, hash); + } + break; + #endif + + case SHA: + { + ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); + + ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE); + ShaUpdate(&hmac->hash.sha, + (byte*) hmac->innerHash, SHA_DIGEST_SIZE); + + ShaFinal(&hmac->hash.sha, hash); + } + break; + + #ifndef NO_SHA256 + case SHA256: + { + Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); + + Sha256Update(&hmac->hash.sha256, + (byte*) hmac->opad, SHA256_BLOCK_SIZE); + Sha256Update(&hmac->hash.sha256, + (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); + + Sha256Final(&hmac->hash.sha256, hash); + } + break; + #endif + + #ifdef CYASSL_SHA384 + case SHA384: + { + Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); + + Sha384Update(&hmac->hash.sha384, + (byte*) hmac->opad, SHA384_BLOCK_SIZE); + Sha384Update(&hmac->hash.sha384, + (byte*) hmac->innerHash, SHA384_DIGEST_SIZE); + + Sha384Final(&hmac->hash.sha384, hash); + } + #endif + + default: + break; } - else if (hmac->macType == SHA) { - ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); - - ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE); - ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE); - - ShaFinal(&hmac->hash.sha, hash); - } -#ifndef NO_SHA256 - else if (hmac->macType == SHA256) { - Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); - - Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, SHA256_BLOCK_SIZE); - Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash, - SHA256_DIGEST_SIZE); - - Sha256Final(&hmac->hash.sha256, hash); - } -#endif -#ifdef CYASSL_SHA384 - else if (hmac->macType == SHA384) { - Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); - - Sha384Update(&hmac->hash.sha384, (byte*) hmac->opad, SHA384_BLOCK_SIZE); - Sha384Update(&hmac->hash.sha384, (byte*) hmac->innerHash, - SHA384_DIGEST_SIZE); - - Sha384Final(&hmac->hash.sha384, hash); - } -#endif hmac->innerHashKeyed = 0; } diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index 189de08d2..eab0dd2e3 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -462,7 +462,7 @@ struct DecodedCRL { word32 signatureOID; /* sum of algorithm object id */ byte* signature; /* pointer into raw source, not owned */ byte issuerHash[SHA_DIGEST_SIZE]; /* issuer hash */ - byte crlHash[MD5_DIGEST_SIZE]; /* raw crl data hash */ + byte crlHash[SHA_DIGEST_SIZE]; /* raw crl data hash */ byte lastDate[MAX_DATE_SIZE]; /* last date updated */ byte nextDate[MAX_DATE_SIZE]; /* next update date */ byte lastDateFormat; /* format of last date */ diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index ee11669d0..0be5b9ccf 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -25,7 +25,10 @@ #ifndef CTAO_CRYPT_HMAC_H #define CTAO_CRYPT_HMAC_H -#include +#ifndef NO_MD5 + #include +#endif + #include #ifndef NO_SHA256 @@ -44,6 +47,9 @@ enum { IPAD = 0x36, OPAD = 0x5C, +#ifdef NO_MD5 + MD5 = 0, +#endif #if defined(CYASSL_SHA384) INNER_HASH_SIZE = SHA384_DIGEST_SIZE, HMAC_BLOCK_SIZE = SHA384_BLOCK_SIZE @@ -62,7 +68,9 @@ enum { /* hash union */ typedef union { - Md5 md5; + #ifndef NO_MD5 + Md5 md5; + #endif Sha sha; #ifndef NO_SHA256 Sha256 sha256; diff --git a/cyassl/ctaocrypt/md5.h b/cyassl/ctaocrypt/md5.h index 2e6a46ddd..246ec3997 100644 --- a/cyassl/ctaocrypt/md5.h +++ b/cyassl/ctaocrypt/md5.h @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#ifndef NO_MD5 #ifndef CTAO_CRYPT_MD5_H #define CTAO_CRYPT_MD5_H @@ -59,4 +60,4 @@ CYASSL_API void Md5Final(Md5*, byte*); #endif #endif /* CTAO_CRYPT_MD5_H */ - +#endif /* NO_MD5 */ diff --git a/cyassl/internal.h b/cyassl/internal.h index dfe4c7804..b8693ac2c 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -374,7 +374,11 @@ enum Misc { SECRET_LEN = 48, /* pre RSA and all master */ ENCRYPT_LEN = 512, /* allow 4096 bit static buffer */ SIZEOF_SENDER = 4, /* clnt or srvr */ +#ifndef NO_MD5 FINISHED_SZ = MD5_DIGEST_SIZE + SHA_DIGEST_SIZE, +#else + FINISHED_SZ = 36, +#endif MAX_RECORD_SIZE = 16384, /* 2^14, max size by standard */ MAX_MSG_EXTRA = 70, /* max added to msg, mac + pad from */ /* RECORD_HEADER_SZ + BLOCK_SZ (pad) + SHA_256 @@ -781,7 +785,8 @@ typedef struct CRL_Entry CRL_Entry; struct CRL_Entry { CRL_Entry* next; /* next entry */ byte issuerHash[SHA_DIGEST_SIZE]; /* issuer hash */ - byte crlHash[MD5_DIGEST_SIZE]; /* raw crl data hash */ + /* byte crlHash[SHA_DIGEST_SIZE]; raw crl data hash */ + /* restore the hash here if needed for optimized comparisons */ byte lastDate[MAX_DATE_SIZE]; /* last date updated */ byte nextDate[MAX_DATE_SIZE]; /* next update date */ byte lastDateFormat; /* last date format */ @@ -1069,8 +1074,12 @@ CYASSL_LOCAL void FreeCiphers(CYASSL* ssl); /* hashes type */ typedef struct Hashes { - byte md5[MD5_DIGEST_SIZE]; - byte sha[SHA_DIGEST_SIZE]; + #ifndef NO_MD5 + byte md5[MD5_DIGEST_SIZE]; + byte sha[SHA_DIGEST_SIZE]; + #else + byte hash[FINISHED_SZ]; + #endif } Hashes; @@ -1308,8 +1317,10 @@ struct CYASSL { void* IOCB_ReadCtx; void* IOCB_WriteCtx; RNG* rng; - Md5 hashMd5; /* md5 hash of handshake msgs */ Sha hashSha; /* sha hash of handshake msgs */ +#ifndef NO_MD5 + Md5 hashMd5; /* md5 hash of handshake msgs */ +#endif #ifndef NO_SHA256 Sha256 hashSha256; /* sha256 hash of handshake msgs */ #endif diff --git a/examples/client/client.c b/examples/client/client.c index 70d562024..236a45837 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -237,6 +237,7 @@ void client_test(void* args) myoptind = 0; /* reset for test cases */ switch (version) { +#ifndef NO_OLD_TLS case 0: method = CyaSSLv3_client_method(); break; @@ -248,6 +249,7 @@ void client_test(void* args) case 2: method = CyaTLSv1_1_client_method(); break; +#endif case 3: method = CyaTLSv1_2_client_method(); diff --git a/examples/server/server.c b/examples/server/server.c index 56b2d4711..984263485 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -205,6 +205,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) myoptind = 0; /* reset for test cases */ switch (version) { +#ifndef NO_OLD_TLS case 0: method = SSLv3_server_method(); break; @@ -216,6 +217,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) case 2: method = TLSv1_1_server_method(); break; +#endif case 3: method = TLSv1_2_server_method(); diff --git a/src/crl.c b/src/crl.c index b546af9cd..8cf8893ed 100644 --- a/src/crl.c +++ b/src/crl.c @@ -58,7 +58,8 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl) CYASSL_ENTER("InitCRL_Entry"); XMEMCPY(crle->issuerHash, dcrl->issuerHash, SHA_DIGEST_SIZE); - XMEMCPY(crle->crlHash, dcrl->crlHash, MD5_DIGEST_SIZE); + /* XMEMCPY(crle->crlHash, dcrl->crlHash, SHA_DIGEST_SIZE); + * copy the hash here if needed for optimized comparisons */ XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE); XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE); crle->lastDateFormat = dcrl->lastDateFormat; diff --git a/src/include.am b/src/include.am index 126d978e1..b8853cf44 100644 --- a/src/include.am +++ b/src/include.am @@ -10,7 +10,6 @@ src_libcyassl_la_SOURCES = \ src/ssl.c \ src/tls.c \ ctaocrypt/src/coding.c \ - ctaocrypt/src/md5.c \ ctaocrypt/src/hmac.c \ ctaocrypt/src/random.c \ ctaocrypt/src/sha.c \ @@ -28,6 +27,7 @@ if !BUILD_LEANPSK src_libcyassl_la_SOURCES += ctaocrypt/src/rsa.c \ ctaocrypt/src/des3.c \ ctaocrypt/src/md4.c \ + ctaocrypt/src/md5.c \ ctaocrypt/src/asn.c \ ctaocrypt/src/dh.c \ ctaocrypt/src/dsa.c \ diff --git a/src/internal.c b/src/internal.c index c0e843f92..36b5b0eb5 100644 --- a/src/internal.c +++ b/src/internal.c @@ -90,10 +90,12 @@ typedef enum { runProcessingOneMessage } processReply; +#ifndef NO_MD5 static void Hmac(CYASSL* ssl, byte* digest, const byte* buffer, word32 sz, int content, int verify); static void BuildCertHashes(CYASSL* ssl, Hashes* hashes); +#endif #ifndef min @@ -1019,7 +1021,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->IOCB_ReadCtx = &ssl->rfd; /* prevent invalid pointer access if not */ ssl->IOCB_WriteCtx = &ssl->wfd; /* correctly set */ +#ifndef NO_MD5 InitMd5(&ssl->hashMd5); +#endif InitSha(&ssl->hashSha); #ifndef NO_SHA256 InitSha256(&ssl->hashSha256); @@ -1088,7 +1092,11 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->options.resuming = 0; ssl->options.haveSessionId = 0; - ssl->hmac = Hmac; /* default to SSLv3 */ + #ifndef NO_OLD_TLS + ssl->hmac = Hmac; /* default to SSLv3 */ + #else + ssl->hmac = TLS_hmac; + #endif ssl->heap = ctx->heap; /* defaults to self */ ssl->options.tls = 0; ssl->options.tls1_1 = 0; @@ -1578,8 +1586,11 @@ static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz) } #endif - Md5Update(&ssl->hashMd5, adj, sz); ShaUpdate(&ssl->hashSha, adj, sz); +#ifndef NO_MD5 + Md5Update(&ssl->hashMd5, adj, sz); +#endif + if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 Sha256Update(&ssl->hashSha256, adj, sz); @@ -1604,8 +1615,11 @@ static void HashInput(CYASSL* ssl, const byte* input, int sz) } #endif - Md5Update(&ssl->hashMd5, adj, sz); ShaUpdate(&ssl->hashSha, adj, sz); +#ifndef NO_MD5 + Md5Update(&ssl->hashMd5, adj, sz); +#endif + if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 Sha256Update(&ssl->hashSha256, adj, sz); @@ -2024,6 +2038,7 @@ static int GetDtlsHandShakeHeader(CYASSL* ssl, const byte* input, #endif +#ifndef NO_MD5 /* fill with MD5 pad size since biggest required */ static const byte PAD1[PAD_MD5] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, @@ -2080,12 +2095,15 @@ static void BuildSHA(CYASSL* ssl, Hashes* hashes, const byte* sender) ShaFinal(&ssl->hashSha, hashes->sha); } +#endif static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) { /* store current states, building requires get_digest which resets state */ +#ifndef NO_MD5 Md5 md5 = ssl->hashMd5; +#endif Sha sha = ssl->hashSha; #ifndef NO_SHA256 Sha256 sha256; @@ -2107,13 +2125,17 @@ static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) if (ssl->options.tls) BuildTlsFinished(ssl, hashes, sender); +#ifndef NO_MD5 else { BuildMD5(ssl, hashes, sender); BuildSHA(ssl, hashes, sender); } +#endif /* restore */ +#ifndef NO_MD5 ssl->hashMd5 = md5; +#endif ssl->hashSha = sha; if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 @@ -3545,7 +3567,7 @@ static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify) return ssl->keys.server_write_MAC_secret; } - +#ifndef NO_OLD_TLS static void Hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, int content, int verify) { @@ -3665,7 +3687,7 @@ static void BuildCertHashes(CYASSL* ssl, Hashes* hashes) ssl->hashSha256 = sha256; #endif } - +#endif /* Build SSL Message, encrypted */ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, @@ -5416,10 +5438,14 @@ int SetCipherList(Suites* s, const char* list) int ret; XMEMCPY(ssl->arrays->masterSecret, ssl->session.masterSecret, SECRET_LEN); - if (ssl->options.tls) + #ifndef NO_OLD_TLS + if (ssl->options.tls) + ret = DeriveTlsKeys(ssl); + else + ret = DeriveKeys(ssl); + #else ret = DeriveTlsKeys(ssl); - else - ret = DeriveKeys(ssl); + #endif ssl->options.serverState = SERVER_HELLODONE_COMPLETE; return ret; } @@ -7117,7 +7143,9 @@ int SetCipherList(Suites* s, const char* list) #endif /* manually hash input since different format */ +#ifndef NO_MD5 Md5Update(&ssl->hashMd5, input + idx, sz); +#endif ShaUpdate(&ssl->hashSha, input + idx, sz); #ifndef NO_SHA256 if (IsAtLeastTLSv1_2(ssl)) @@ -7236,10 +7264,14 @@ int SetCipherList(Suites* s, const char* list) } RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN); - if (ssl->options.tls) + #ifndef NO_OLD_TLS + if (ssl->options.tls) + ret = DeriveTlsKeys(ssl); + else + ret = DeriveKeys(ssl); + #else ret = DeriveTlsKeys(ssl); - else - ret = DeriveKeys(ssl); + #endif ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; return ret; @@ -7405,10 +7437,14 @@ int SetCipherList(Suites* s, const char* list) } RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN); - if (ssl->options.tls) + #ifndef NO_OLD_TLS + if (ssl->options.tls) + ret = DeriveTlsKeys(ssl); + else + ret = DeriveKeys(ssl); + #else ret = DeriveTlsKeys(ssl); - else - ret = DeriveKeys(ssl); + #endif ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; return ret; @@ -7800,8 +7836,10 @@ int SetCipherList(Suites* s, const char* list) if (ret == 0) { ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; - if (ssl->options.verifyPeer) - BuildCertHashes(ssl, &ssl->certHashes); + #ifndef NO_CERTS + if (ssl->options.verifyPeer) + BuildCertHashes(ssl, &ssl->certHashes); + #endif } return ret; diff --git a/src/keys.c b/src/keys.c index 3d264dda9..cb5f845a4 100644 --- a/src/keys.c +++ b/src/keys.c @@ -970,7 +970,7 @@ enum KeyStuff { }; - +#ifndef NO_OLD_TLS /* true or false, zero for error */ static int SetPrefix(byte* sha_input, int idx) { @@ -1002,6 +1002,7 @@ static int SetPrefix(byte* sha_input, int idx) } return 1; } +#endif static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, @@ -1212,7 +1213,7 @@ int StoreKeys(CYASSL* ssl, const byte* keyData) ssl->options.side, ssl->heap, ssl->rng); } - +#ifndef NO_OLD_TLS int DeriveKeys(CYASSL* ssl) { int length = 2 * ssl->specs.hash_size + @@ -1344,15 +1345,20 @@ static int MakeSslMasterSecret(CYASSL* ssl) return ret; } +#endif /* Master wrapper, doesn't use SSL stack space in TLS mode */ int MakeMasterSecret(CYASSL* ssl) { -#ifndef NO_TLS +#ifdef NO_OLD_TLS + return MakeTlsMasterSecret(ssl); +#elif !defined(NO_TLS) if (ssl->options.tls) return MakeTlsMasterSecret(ssl); #endif +#ifndef NO_OLD_TLS return MakeSslMasterSecret(ssl); +#endif } diff --git a/src/tls.c b/src/tls.c index 005bf51bf..5b12f0b00 100644 --- a/src/tls.c +++ b/src/tls.c @@ -43,16 +43,6 @@ #endif /* min */ -/* calculate XOR for TLSv1 PRF */ -static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) -{ - word32 i; - - for (i = 0; i < digLen; i++) - digest[i] = md5[i] ^ sha[i]; -} - - #ifdef CYASSL_SHA384 #define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE #else @@ -63,7 +53,7 @@ static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) static void p_hash(byte* result, word32 resLen, const byte* secret, word32 secLen, const byte* seed, word32 seedLen, int hash) { - word32 len = MD5_DIGEST_SIZE; + word32 len = SHA_DIGEST_SIZE; word32 times; word32 lastLen; word32 lastTime; @@ -74,23 +64,39 @@ static void p_hash(byte* result, word32 resLen, const byte* secret, Hmac hmac; - if (hash == md5_mac) { - hash = MD5; + switch (hash) { + #ifndef NO_MD5 + case md5_mac: + { + len = MD5_DIGEST_SIZE; + hash = MD5; + } + break; + #endif + #ifndef NO_SHA256 + case sha256_mac: + { + len = SHA256_DIGEST_SIZE; + hash = SHA256; + } + break; + #endif + #ifdef CYASSL_SHA384 + case sha384_mac: + { + len = SHA384_DIGEST_SIZE; + hash = SHA384; + } + break; + #endif + case sha_mac: + default: + { + len = SHA_DIGEST_SIZE; + hash = SHA; + } + break; } - else if (hash == sha_mac) { - len = SHA_DIGEST_SIZE; - hash = SHA; - } else if (hash == sha256_mac) { - len = SHA256_DIGEST_SIZE; - hash = SHA256; - } -#ifdef CYASSL_SHA384 - else if (hash == sha384_mac) - { - len = SHA384_DIGEST_SIZE; - hash = SHA384; - } -#endif times = resLen / len; lastLen = resLen % len; @@ -119,6 +125,18 @@ static void p_hash(byte* result, word32 resLen, const byte* secret, +#ifndef NO_MD5 + +/* calculate XOR for TLSv1 PRF */ +static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) +{ + word32 i; + + for (i = 0; i < digLen; i++) + digest[i] = md5[i] ^ sha[i]; +} + + /* compute TLSv1 PRF (pseudo random function using HMAC) */ static void doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, const byte* label, word32 labLen, const byte* seed, word32 seedLen) @@ -151,6 +169,8 @@ static void doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, get_xor(digest, digLen, md5_result, sha_result); } +#endif + /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack use */ @@ -174,8 +194,10 @@ static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen, hash_type); } +#ifndef NO_MD5 else doPRF(digest, digLen, secret, secLen, label, labLen, seed, seedLen); +#endif } @@ -192,8 +214,11 @@ void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) byte handshake_hash[HSHASH_SZ]; word32 hashSz = FINISHED_SZ; +#ifndef NO_MD5 Md5Final(&ssl->hashMd5, handshake_hash); ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); +#endif + if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 if (ssl->specs.mac_algorithm <= sha256_mac) { @@ -214,9 +239,15 @@ void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) else side = tls_server; +#ifndef NO_MD5 PRF(hashes->md5, TLS_FINISHED_SZ, ssl->arrays->masterSecret, SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); +#else + PRF(hashes->hash, TLS_FINISHED_SZ, ssl->arrays->masterSecret, SECRET_LEN, + side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl), + ssl->specs.mac_algorithm); +#endif } @@ -378,12 +409,28 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, #endif c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]); - if (ssl->specs.mac_algorithm == md5_mac) - type = MD5; - else if (ssl->specs.mac_algorithm == sha_mac) - type = SHA; - else - type = SHA256; + switch (ssl->specs.mac_algorithm) { + #ifndef NO_MD5 + case md5_mac: + { + type = MD5; + } + break; + #endif + #ifndef NO_SHA256 + case sha256_mac: + { + type = SHA256; + } + break; + #endif + case sha_mac: + default: + { + type = SHA; + } + break; + } HmacSetKey(&hmac, type, GetMacSecret(ssl, verify), ssl->specs.hash_size); HmacUpdate(&hmac, seq, SEQ_SZ); /* seq_num */ @@ -399,6 +446,8 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, #ifndef NO_CYASSL_CLIENT +#ifndef NO_OLD_TLS + CYASSL_METHOD* CyaTLSv1_client_method(void) { CYASSL_METHOD* method = @@ -420,6 +469,7 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, return method; } +#endif /* !NO_OLD_TLS */ #ifndef NO_SHA256 /* can't use without SHA256 */ @@ -447,7 +497,9 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, #else InitSSL_Method(method, MakeTLSv1_1()); #endif +#ifndef NO_OLD_TLS method->downgrade = 1; +#endif } return method; } @@ -459,6 +511,8 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, #ifndef NO_CYASSL_SERVER +#ifndef NO_OLD_TLS + CYASSL_METHOD* CyaTLSv1_server_method(void) { CYASSL_METHOD* method = @@ -484,6 +538,7 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, return method; } +#endif /* !NO_OLD_TLS */ #ifndef NO_SHA256 /* can't use without SHA256 */ @@ -514,7 +569,9 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, InitSSL_Method(method, MakeTLSv1_1()); #endif method->side = SERVER_END; +#ifndef NO_OLD_TLS method->downgrade = 1; +#endif /* !NO_OLD_TLS */ } return method; } diff --git a/tests/api.c b/tests/api.c index b930e6559..b0e822742 100644 --- a/tests/api.c +++ b/tests/api.c @@ -147,12 +147,14 @@ int test_method2(CYASSL_METHOD *method, const char *name) int test_CyaSSL_Method_Allocators(void) { +#ifndef NO_OLD_TLS test_method(CyaSSLv3_server_method(), "CyaSSLv3_server_method()"); test_method(CyaSSLv3_client_method(), "CyaSSLv3_client_method()"); test_method(CyaTLSv1_server_method(), "CyaTLSv1_server_method()"); test_method(CyaTLSv1_client_method(), "CyaTLSv1_client_method()"); test_method(CyaTLSv1_1_server_method(), "CyaTLSv1_1_server_method()"); test_method(CyaTLSv1_1_client_method(), "CyaTLSv1_1_client_method()"); +#endif /* NO_OLD_TLS */ test_method(CyaTLSv1_2_server_method(), "CyaTLSv1_2_server_method()"); test_method(CyaTLSv1_2_client_method(), "CyaTLSv1_2_client_method()"); test_method(CyaSSLv23_client_method(), "CyaSSLv23_client_method()"); diff --git a/tests/hash.c b/tests/hash.c index 9931ef81b..1baa5ca59 100644 --- a/tests/hash.c +++ b/tests/hash.c @@ -68,11 +68,13 @@ int HashTest(void) printf( " MD4 test passed!\n"); #endif +#ifndef NO_MD5 if ( (ret = md5_test()) ) { printf( " MD5 test failed!\n"); return ret; } else printf( " MD5 test passed!\n"); +#endif if ( (ret = sha_test()) ) { printf( " SHA test failed!\n"); @@ -224,6 +226,8 @@ int md4_test(void) #endif /* NO_MD4 */ +#ifndef NO_MD5 + int md5_test(void) { Md5 md5; @@ -284,6 +288,8 @@ int md5_test(void) return 0; } +#endif /* NO_MD5 */ + int sha_test(void) { Sha sha; diff --git a/tests/include.am b/tests/include.am index 59e1bb83b..139ba6305 100644 --- a/tests/include.am +++ b/tests/include.am @@ -28,4 +28,5 @@ EXTRA_DIST += tests/test.conf \ tests/test-dtls.conf \ tests/test-rabbit.conf \ tests/test-null.conf \ - tests/test-psk-null.conf + tests/test-psk-null.conf \ + tests/test-leanpsk.conf diff --git a/tests/suites.c b/tests/suites.c index e06a76147..3bcb23e21 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -295,7 +295,7 @@ int SuiteTest(void) } #endif -#if !defined(NO_PSK) && defined(HAVE_NULL_CIPHER) +#if !defined(NO_PSK) && defined(HAVE_NULL_CIPHER) && !defined(NO_OLD_TLS) strcpy(argv0[1], "tests/test-psk-null.conf"); printf("starting psk extra null cipher suite tests\n"); test_harness(&args); @@ -305,6 +305,16 @@ int SuiteTest(void) } #endif +#ifdef CYASSL_LEANPSK + strcpy(argv0[1], "tests/test-leanpsk.conf"); + printf("starting lean-psk cipher suite tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + exit(EXIT_FAILURE); + } +#endif + #ifdef HAVE_NTRU /* add ntru extra suites */ strcpy(argv0[1], "tests/test-ntru.conf"); diff --git a/tests/test-leanpsk.conf b/tests/test-leanpsk.conf new file mode 100644 index 000000000..b319ae19a --- /dev/null +++ b/tests/test-leanpsk.conf @@ -0,0 +1,20 @@ +# server TLSv1.2 PSK-NULL +-s +-v 3 +-l PSK-NULL-SHA + +# client TLSv1.2 PSK-NULL +-s +-v 3 +-l PSK-NULL-SHA + +# server TLSv1.2 PSK-NULL-SHA256 +-s +-v 3 +-l PSK-NULL-SHA256 + +# client TLSv1.2 PSK-NULL-SHA256 +-s +-v 3 +-l PSK-NULL-SHA256 + diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index a4b305904..956a3d1f3 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include "ctaocrypt/test/test.h" @@ -132,8 +132,8 @@ int main(int argc, char** argv) /* validate output equals input */ { - byte input[MD5_DIGEST_SIZE]; - byte output[MD5_DIGEST_SIZE]; + byte input[SHA_DIGEST_SIZE]; + byte output[SHA_DIGEST_SIZE]; file_test("input", input); file_test("output", output); @@ -211,23 +211,23 @@ void file_test(const char* file, byte* check) { FILE* f; int i = 0, j; - Md5 md5; + Sha sha; byte buf[1024]; - byte md5sum[MD5_DIGEST_SIZE]; + byte shasum[SHA_DIGEST_SIZE]; - InitMd5(&md5); + InitSha(&sha); if( !( f = fopen( file, "rb" ) )) { printf("Can't open %s\n", file); return; } while( ( i = (int)fread(buf, 1, sizeof(buf), f )) > 0 ) - Md5Update(&md5, buf, i); + ShaUpdate(&sha, buf, i); - Md5Final(&md5, md5sum); - memcpy(check, md5sum, sizeof(md5sum)); + ShaFinal(&sha, shasum); + memcpy(check, shasum, sizeof(shasum)); - for(j = 0; j < MD5_DIGEST_SIZE; ++j ) - printf( "%02x", md5sum[j] ); + for(j = 0; j < SHA_DIGEST_SIZE; ++j ) + printf( "%02x", shasum[j] ); printf(" %s\n", file);