From b63d3c491487f47009d629b470cb4add6b2ca3b0 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 24 Sep 2020 10:38:34 -0700 Subject: [PATCH] More Options Added many more guards for algorithms that may be disabled in wolfCrypt including DH, AES-GCM-CTR-CBC, SHA1, ECC, RSA, etc. --- src/internal.c | 430 ++++++++++++++++++++++++++++++++++++++++--------- tests/unit.c | 4 + 2 files changed, 357 insertions(+), 77 deletions(-) diff --git a/src/internal.c b/src/internal.c index 1e76ad6..3950f32 100644 --- a/src/internal.c +++ b/src/internal.c @@ -57,9 +57,120 @@ Flags: use of the function if the flag isn't set. If using wolfCrypt v4.5.0 or later, and not building with configure, set this flag. default: off + WOLFSSH_NO_HMAC_SHA1 + Set when HMAC or SHA1 are disabled. Set to disable HMAC-SHA1 support. + WOLFSSH_NO_HMAC_SHA1_96 + Set when HMAC or SHA1 are disabled. Set to disable HMAC-SHA1-96 support. + WOLFSSH_NO_HMAC_SHA2_256 + Set when HMAC or SHA2-256 are disabled. Set to disable HMAC-SHA2-256 + support. + WOLFSSH_NO_DH_GROUP1_SHA1 + Set when DH or SHA1 are disabled. Set to disable use of DH (Oakley 1) and + SHA1 support. + WOLFSSH_NO_DH_GROUP14_SHA1 + Set when DH or SHA1 are disabled. Set to disable use of DH (Oakley 14) and + SHA1 support. + WOLFSSH_NO_DH_GEX_SHA256 + Set when DH or SHA2-256 are disabled. Set to disable use of DH group + exchange and SHA2-256 support. + WOLFSSH_NO_ECDH_SHA2_NISTP256 + Set when ECC or SHA2-256 are disabled. Set to disable use of ECDHE key + exchange with prime NISTP256. + WOLFSSH_NO_ECDH_SHA2_NISTP384 + Set when ECC or SHA2-384 are disabled. Set to disable use of ECDHE key + exchange with prime NISTP384. + WOLFSSH_NO_ECDH_SHA2_NISTP521 + Set when ECC or SHA2-512 are disabled. Set to disable use of ECDHE key + exchange with prime NISTP521. + WOLFSSH_NO_ECDH_SHA2_ED25519 + Set when ED25519 or SHA2-256 are disabled. Set to disable use of ECDHE key + exchange with prime ED25519. (It just decodes the ID for output.) + WOLFSSH_NO_SSH_RSA_SHA1 + Set when RSA or SHA1 are disabled. Set to disable use of RSA server + authentication. + WOLFSSH_NO_ECDSA_SHA2_NISTP256 + Set when ECC or SHA2-256 are disabled. Set to disable use of ECDSA server + authentication with prime NISTP256. + WOLFSSH_NO_ECDSA_SHA2_NISTP384 + Set when ECC or SHA2-384 are disabled. Set to disable use of ECDSA server + authentication with prime NISTP384. + WOLFSSH_NO_ECDSA_SHA2_NISTP521 + Set when ECC or SHA2-512 are disabled. Set to disable use of ECDSA server + authentication with prime NISTP521. + WOLFSSH_NO_AES_CBC + Set when AES or AES-CBC are disabled. Set to disable use of AES-CBC + encryption. + WOLFSSH_NO_AES_CTR + Set when AES or AES-CTR are disabled. Set to disable use of AES-CTR + encryption. + WOLFSSH_NO_AES_GCM + Set when AES or AES-GCM are disabled. Set to disable use of AES-GCM + encryption. + WOLFSSH_NO_AEAD + Set when AES-GCM is disabled. Set to disable use of AEAD ciphers for + encryption. Setting this will force all AEAD ciphers off. */ +#if defined(NO_HMAC) || defined(NO_SHA) + #define WOLFSSH_NO_HMAC_SHA1 +#endif +#if defined(NO_HMAC) || defined(NO_SHA) + #define WOLFSSH_NO_HMAC_SHA1_96 +#endif +#if defined(NO_HMAC) || defined(NO_SHA256) + #define WOLFSSH_NO_HMAC_SHA2_256 +#endif +#if defined(NO_DH) || defined(NO_SHA) + #define WOLFSSH_NO_DH_GROUP1_SHA1 +#endif +#if defined(NO_DH) || defined(NO_SHA) + #define WOLFSSH_NO_DH_GROUP14_SHA1 +#endif +#if defined(NO_DH) || defined(NO_SHA256) + #define WOLFSSH_NO_DH_GEX_SHA256 +#endif +#if !defined(HAVE_ECC) || defined(NO_SHA256) + #define WOLFSSH_NO_ECDH_SHA2_NISTP256 +#endif +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) + #define WOLFSSH_NO_ECDH_SHA2_NISTP384 +#endif +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) + #define WOLFSSH_NO_ECDH_SHA2_NISTP521 +#endif +#if !defined(HAVE_ED25519) || defined(NO_SHA256) + #define WOLFSSH_NO_ECDH_SHA2_ED25519 +#endif +#if defined(NO_RSA) || defined(NO_SHA) + #define WOLFSSH_NO_SSH_RSA_SHA1 +#endif +#if !defined(HAVE_ECC) || defined(NO_SHA256) + #define WOLFSSH_NO_ECDSA_SHA2_NISTP256 +#endif +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) + #define WOLFSSH_NO_ECDSA_SHA2_NISTP384 +#endif +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) + #define WOLFSSH_NO_ECDSA_SHA2_NISTP521 +#endif +#if defined(NO_AES) || !defined(HAVE_AES_CBC) + #define WOLFSSH_NO_AES_CBC +#endif +#if defined(NO_AES) || !defined(WOLFSSL_AES_COUNTER) + #define WOLFSSH_NO_AES_CTR +#endif +#if defined(NO_AES) || !defined(HAVE_AESGCM) + #define WOLFSSH_NO_AES_GCM +#endif +#if defined(WOLFSSH_NO_AES_GCM) + #define WOLFSSH_NO_AEAD + #ifndef WOLFSSH_NO_AES_GCM + #define WOLFSSH_AES_GCM + #endif +#endif + + static const char sshProtoIdStr[] = "SSH-2.0-wolfSSHv" LIBWOLFSSH_VERSION_STRING "\r\n"; @@ -937,31 +1048,67 @@ static const NameIdPair NameIdMap[] = { { ID_NONE, "none" }, /* Encryption IDs */ +#ifndef WOLFSSH_NO_AES_CBC { ID_AES128_CBC, "aes128-cbc" }, +#endif +#ifndef WOLFSSH_NO_AES_CTR { ID_AES128_CTR, "aes128-ctr" }, +#endif +#ifndef WOLFSSH_NO_AES_GCM { ID_AES128_GCM, "aes128-gcm@openssh.com" }, +#endif /* Integrity IDs */ +#ifndef WOLFSSH_NO_HMAC_SHA1 { ID_HMAC_SHA1, "hmac-sha1" }, +#endif +#ifndef WOLFSSH_NO_HMAC_SHA1_96 { ID_HMAC_SHA1_96, "hmac-sha1-96" }, +#endif +#ifndef WOLFSSH_NO_HMAC_SHA2_256 { ID_HMAC_SHA2_256, "hmac-sha2-256" }, +#endif /* Key Exchange IDs */ +#ifndef WOLFSSH_NO_DH_GROUP1_SHA1 { ID_DH_GROUP1_SHA1, "diffie-hellman-group1-sha1" }, +#endif +#ifndef WOLFSSH_NO_DH_GROUP14_SHA1 { ID_DH_GROUP14_SHA1, "diffie-hellman-group14-sha1" }, +#endif +#ifndef WOLFSSH_NO_DH_GEX_SHA256 { ID_DH_GEX_SHA256, "diffie-hellman-group-exchange-sha256" }, +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 { ID_ECDH_SHA2_NISTP256, "ecdh-sha2-nistp256" }, +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384 { ID_ECDH_SHA2_NISTP384, "ecdh-sha2-nistp384" }, +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521 { ID_ECDH_SHA2_NISTP521, "ecdh-sha2-nistp521" }, +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_ED25519 { ID_ECDH_SHA2_ED25519, "curve25519-sha256" }, { ID_ECDH_SHA2_ED25519_LIBSSH, "curve25519-sha256@libssh.org" }, +#endif +#ifndef WOLFSSH_NO_DH_GEX_SHA256 { ID_DH_GROUP14_SHA256, "diffie-hellman-group14-sha256" }, +#endif /* Public Key IDs */ +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 { ID_SSH_RSA, "ssh-rsa" }, +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 { ID_ECDSA_SHA2_NISTP256, "ecdsa-sha2-nistp256" }, +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 { ID_ECDSA_SHA2_NISTP384, "ecdsa-sha2-nistp384" }, +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 { ID_ECDSA_SHA2_NISTP521, "ecdsa-sha2-nistp521" }, +#endif /* Service IDs */ { ID_SERVICE_USERAUTH, "ssh-userauth" }, @@ -1847,27 +1994,17 @@ static int GetNameList(byte* idList, word32* idListSz, } static const byte cannedEncAlgo[] = { -#ifdef HAVE_AESGCM +#ifndef WOLFSSH_NO_AES_GCM ID_AES128_GCM, #endif -#ifdef WOLFSSL_AES_COUNTER +#ifndef WOLFSSH_NO_AES_CTR ID_AES128_CTR, #endif -#ifdef HAVE_AES_CBC +#ifndef WOLFSSH_NO_AES_CBC ID_AES128_CBC, #endif }; -#if defined(NO_HMAC) || defined(NO_SHA256) - #define WOLFSSH_NO_HMAC_SHA2_256 -#endif -#if defined(NO_HMAC) || defined(NO_SHA) -#define WOLFSSH_NO_HMAC_SHA1_96 -#endif -#if defined(NO_HMAC) || defined(NO_SHA) - #define WOLFSSH_NO_HMAC_SHA1 -#endif - static const byte cannedMacAlgo[] = { #ifndef WOLFSSH_NO_HMAC_SHA2_256 ID_HMAC_SHA2_256, @@ -1880,23 +2017,14 @@ static const byte cannedMacAlgo[] = { #endif }; static const byte cannedKeyAlgoClient[] = {ID_ECDSA_SHA2_NISTP256, ID_SSH_RSA}; +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 static const byte cannedKeyAlgoRsa[] = {ID_SSH_RSA}; +static const word32 cannedKeyAlgoRsaSz = sizeof(cannedKeyAlgoRsa); +#endif static const byte cannedKeyAlgoEcc256[] = {ID_ECDSA_SHA2_NISTP256}; static const byte cannedKeyAlgoEcc384[] = {ID_ECDSA_SHA2_NISTP384}; static const byte cannedKeyAlgoEcc521[] = {ID_ECDSA_SHA2_NISTP521}; -#if !defined(HAVE_ECC) || defined(NO_SHA256) - #define WOLFSSH_NO_ECDH_SHA2_NISTP256 -#endif -#if defined(NO_DH) || defined(NO_SHA256) - #define WOLFSSH_NO_DH_GEX_SHA256 -#endif -#if defined(NO_DH) || defined(NO_SHA) - #define WOLFSSH_NO_DH_GROUP14_SHA1 -#endif -#if defined(NO_DH) || defined(NO_SHA) - #define WOLFSSH_NO_DH_GROUP1_SHA1 -#endif static const byte cannedKexAlgo[] = { #ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 @@ -1916,7 +2044,6 @@ static const byte cannedKexAlgo[] = { static const word32 cannedEncAlgoSz = sizeof(cannedEncAlgo); static const word32 cannedMacAlgoSz = sizeof(cannedMacAlgo); static const word32 cannedKeyAlgoClientSz = sizeof(cannedKeyAlgoClient); -static const word32 cannedKeyAlgoRsaSz = sizeof(cannedKeyAlgoRsa); static const word32 cannedKeyAlgoEcc256Sz = sizeof(cannedKeyAlgoEcc256); static const word32 cannedKeyAlgoEcc384Sz = sizeof(cannedKeyAlgoEcc384); static const word32 cannedKeyAlgoEcc521Sz = sizeof(cannedKeyAlgoEcc521); @@ -1960,10 +2087,18 @@ static byte MatchIdLists(int side, const byte* left, word32 leftSz, static INLINE byte BlockSzForId(byte id) { switch (id) { +#ifndef WOLFSSH_NO_AES_CBC case ID_AES128_CBC: + return AES_BLOCK_SIZE; +#endif +#ifndef WOLFSSH_NO_AES_CTR case ID_AES128_CTR: + return AES_BLOCK_SIZE; +#endif +#ifndef WOLFSSH_NO_AES_GCM case ID_AES128_GCM: return AES_BLOCK_SIZE; +#endif default: return 0; } @@ -1973,12 +2108,18 @@ static INLINE byte BlockSzForId(byte id) static INLINE byte MacSzForId(byte id) { switch (id) { +#ifndef WOLFSSH_NO_HMAC_SHA1 case ID_HMAC_SHA1: return WC_SHA_DIGEST_SIZE; +#endif +#ifndef WOLFSSH_NO_HMAC_SHA1_96 case ID_HMAC_SHA1_96: return SHA1_96_SZ; +#endif +#ifndef WOLFSSH_NO_HMAC_SHA2_256 case ID_HMAC_SHA2_256: return WC_SHA256_DIGEST_SIZE; +#endif default: return 0; } @@ -1988,15 +2129,30 @@ static INLINE byte MacSzForId(byte id) static INLINE byte KeySzForId(byte id) { switch (id) { +#ifndef WOLFSSH_NO_HMAC_SHA1 case ID_HMAC_SHA1: + return WC_SHA_DIGEST_SIZE; +#endif +#ifndef WOLFSSH_NO_HMAC_SHA1_96 case ID_HMAC_SHA1_96: return WC_SHA_DIGEST_SIZE; +#endif +#ifndef WOLFSSH_NO_HMAC_SHA2_256 case ID_HMAC_SHA2_256: return WC_SHA256_DIGEST_SIZE; +#endif +#ifndef WOLFSSH_NO_AES_CBC case ID_AES128_CBC: + return AES_BLOCK_SIZE; +#endif +#ifndef WOLFSSH_NO_AES_CTR case ID_AES128_CTR: + return AES_BLOCK_SIZE; +#endif +#ifndef WOLFSSH_NO_AES_GCM case ID_AES128_GCM: return AES_BLOCK_SIZE; +#endif default: return 0; } @@ -2006,20 +2162,54 @@ static INLINE byte KeySzForId(byte id) static INLINE enum wc_HashType HashForId(byte id) { switch (id) { + + /* SHA1 */ +#ifndef WOLFSSH_NO_DH_GROUP1_SHA1 case ID_DH_GROUP1_SHA1: + return WC_HASH_TYPE_SHA; +#endif +#ifndef WOLFSSH_NO_DH_GROUP14_SHA1 case ID_DH_GROUP14_SHA1: + return WC_HASH_TYPE_SHA; +#endif +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 case ID_SSH_RSA: return WC_HASH_TYPE_SHA; +#endif + + /* SHA2-256 */ +#ifndef WOLFSSH_NO_DH_GEX_SHA256 case ID_DH_GEX_SHA256: + return WC_HASH_TYPE_SHA256; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 case ID_ECDH_SHA2_NISTP256: + return WC_HASH_TYPE_SHA256; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 case ID_ECDSA_SHA2_NISTP256: return WC_HASH_TYPE_SHA256; +#endif + + /* SHA2-384 */ +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384 case ID_ECDH_SHA2_NISTP384: + return WC_HASH_TYPE_SHA384; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 case ID_ECDSA_SHA2_NISTP384: return WC_HASH_TYPE_SHA384; +#endif + + /* SHA2-512 */ +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521 case ID_ECDH_SHA2_NISTP521: + return WC_HASH_TYPE_SHA512; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 case ID_ECDSA_SHA2_NISTP521: return WC_HASH_TYPE_SHA512; +#endif default: return WC_HASH_TYPE_NONE; } @@ -2029,15 +2219,30 @@ static INLINE enum wc_HashType HashForId(byte id) static INLINE int wcPrimeForId(byte id) { switch (id) { +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 case ID_ECDH_SHA2_NISTP256: + return ECC_SECP521R1; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 case ID_ECDSA_SHA2_NISTP256: return ECC_SECP256R1; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384 case ID_ECDH_SHA2_NISTP384: + return ECC_SECP521R1; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 case ID_ECDSA_SHA2_NISTP384: return ECC_SECP384R1; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521 case ID_ECDH_SHA2_NISTP521: + return ECC_SECP521R1; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 case ID_ECDSA_SHA2_NISTP521: return ECC_SECP521R1; +#endif default: return ECC_CURVE_INVALID; } @@ -2045,15 +2250,30 @@ static INLINE int wcPrimeForId(byte id) static INLINE const char *PrimeNameForId(byte id) { switch (id) { +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 case ID_ECDH_SHA2_NISTP256: + return "nistp256"; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 case ID_ECDSA_SHA2_NISTP256: return "nistp256"; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384 case ID_ECDH_SHA2_NISTP384: + return "nistp384"; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 case ID_ECDSA_SHA2_NISTP384: return "nistp384"; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521 case ID_ECDH_SHA2_NISTP521: + return "nistp521"; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 case ID_ECDSA_SHA2_NISTP521: return "nistp521"; +#endif default: return "unknown"; } @@ -2062,7 +2282,11 @@ static INLINE const char *PrimeNameForId(byte id) static INLINE byte AeadModeForId(byte id) { +#ifndef WOLFSSH_NO_AES_GCM return (id == ID_AES128_GCM); +#else + return 0; +#endif } @@ -2143,29 +2367,41 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) listSz = sizeof(list); ret = GetNameList(list, &listSz, buf, len, &begin); if (ret == WS_SUCCESS) { - const byte *cannedKeyAlgo; - word32 cannedKeyAlgoSz; + const byte *cannedKeyAlgo = NULL; + word32 cannedKeyAlgoSz = 0; if (side == WOLFSSH_ENDPOINT_SERVER) { - switch (ssh->ctx->useEcc) { - case ECC_SECP256R1: - cannedKeyAlgo = cannedKeyAlgoEcc256; - cannedKeyAlgoSz = cannedKeyAlgoEcc256Sz; - break; - case ECC_SECP384R1: - cannedKeyAlgo = cannedKeyAlgoEcc384; - cannedKeyAlgoSz = cannedKeyAlgoEcc384Sz; - break; - case ECC_SECP521R1: - cannedKeyAlgo = cannedKeyAlgoEcc521; - cannedKeyAlgoSz = cannedKeyAlgoEcc521Sz; - break; - default: - cannedKeyAlgo = cannedKeyAlgoRsa; - cannedKeyAlgoSz = cannedKeyAlgoRsaSz; + if (ssh->ctx->useEcc) { + switch (ssh->ctx->useEcc) { +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 + case ECC_SECP256R1: + cannedKeyAlgo = cannedKeyAlgoEcc256; + cannedKeyAlgoSz = cannedKeyAlgoEcc256Sz; + break; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 + case ECC_SECP384R1: + cannedKeyAlgo = cannedKeyAlgoEcc384; + cannedKeyAlgoSz = cannedKeyAlgoEcc384Sz; + break; +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 + case ECC_SECP521R1: + cannedKeyAlgo = cannedKeyAlgoEcc521; + cannedKeyAlgoSz = cannedKeyAlgoEcc521Sz; + break; +#endif + } + } + else { +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 + cannedKeyAlgo = cannedKeyAlgoRsa; + cannedKeyAlgoSz = cannedKeyAlgoRsaSz; +#endif } } else { + /* XXX Does this need to be different for client? */ cannedKeyAlgo = cannedKeyAlgoClient; cannedKeyAlgoSz = cannedKeyAlgoClientSz; } @@ -2217,10 +2453,12 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) ssh->handshake->blockSz; } else { +#ifndef WOLFSSH_NO_AEAD ssh->handshake->keys.ivSz = ssh->handshake->peerKeys.ivSz = AEAD_NONCE_SZ; ssh->handshake->macSz = ssh->handshake->blockSz; +#endif } } } @@ -2406,8 +2644,14 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) return ret; } -#ifndef NO_DH +#if !defined(WOLFSSH_NO_DH_GROUP1_SHA1) || \ + !defined(WOLFSSH_NO_DH_GROUP14_SHA1) || \ + !defined(WOLFSSH_NO_DH_GEX_SHA256) static const byte dhGenerator[] = { 2 }; +static const word32 dhGeneratorSz = sizeof(dhGenerator); +#endif + +#ifndef WOLFSSH_NO_DH_GROUP1_SHA1 static const byte dhPrimeGroup1[] = { /* SSH DH Group 1 (Oakley Group 2, 1024-bit MODP Group, RFC 2409) */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -2427,6 +2671,10 @@ static const byte dhPrimeGroup1[] = { 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const word32 dhPrimeGroup1Sz = sizeof(dhPrimeGroup1); +#endif + +#ifndef WOLFSSH_NO_DH_GROUP14_SHA1 static const byte dhPrimeGroup14[] = { /* SSH DH Group 14 (Oakley Group 14, 2048-bit MODP Group, RFC 3526) */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -2462,9 +2710,6 @@ static const byte dhPrimeGroup14[] = { 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - -static const word32 dhGeneratorSz = sizeof(dhGenerator); -static const word32 dhPrimeGroup1Sz = sizeof(dhPrimeGroup1); static const word32 dhPrimeGroup14Sz = sizeof(dhPrimeGroup14); #endif @@ -2552,9 +2797,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) RsaKey key; } rsa; #endif +#ifdef HAVE_ECC struct { ecc_key key; } ecc; +#endif } sk; } sigKeyBlock; word32 begin; @@ -2615,7 +2862,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) if (ret == WS_SUCCESS) begin += pubKeySz; -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GEX_SHA256 /* If using DH-GEX include the GEX specific values. */ if (ret == WS_SUCCESS && ssh->handshake->kexId == ID_DH_GEX_SHA256) { byte primeGroupPad = 0, generatorPad = 0; @@ -2749,6 +2996,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) /* Load in the server's public signing key */ sigKeyBlock.useRsa = ssh->handshake->pubKeyId == ID_SSH_RSA; + ret = WS_INVALID_ALGO_ID; if (sigKeyBlock.useRsa) { #ifndef NO_RSA byte* e; @@ -2786,10 +3034,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) else ret = WS_RSA_E; #else - (void)tmpIdx; + (void)tmpIdx; #endif } else { +#ifdef HAVE_ECC byte* q; word32 qSz, pubKeyIdx = 0; int primeId; @@ -2833,10 +3082,12 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) else ret = WS_ECC_E; } +#endif } /* Generate and hash in the shared secret */ if (ret == 0) { + ret = WS_INVALID_ALGO_ID; if (!ssh->handshake->useEcc) { #ifndef NO_DH ret = wc_DhAgree(&ssh->handshake->privKey.dh, @@ -2848,11 +3099,12 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) #endif } else { +#ifdef HAVE_ECC ecc_key key; ret = wc_ecc_init(&key); #ifdef HAVE_WC_ECC_SET_RNG - if (ret == WS_SUCCESS) - ret = wc_ecc_set_rng(&key, ssh->rng); + if (ret == WS_SUCCESS) + ret = wc_ecc_set_rng(&key, ssh->rng); #endif if (ret == 0) ret = wc_ecc_import_x963(f, fSz, &key); @@ -2861,9 +3113,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) &key, ssh->k, &ssh->kSz); wc_ecc_free(&key); wc_ecc_free(&ssh->handshake->privKey.ecc); +#endif } } - CreateMpint(ssh->k, &ssh->kSz, &kPad); + if (ret == 0) + CreateMpint(ssh->k, &ssh->kSz, &kPad); /* Hash in the shared secret K. */ if (ret == 0) { @@ -2956,6 +3210,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) #endif } else { +#ifdef HAVE_ECC byte* r; byte* s; word32 rSz, sSz, asnSigSz; @@ -2987,6 +3242,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) ret = WS_ECC_E; } } +#endif } } } @@ -2996,8 +3252,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) wc_FreeRsaKey(&sigKeyBlock.sk.rsa.key); #endif } - else + else { +#ifdef HAVE_ECC wc_ecc_free(&sigKeyBlock.sk.ecc.key); +#endif + } } if (ret == WS_SUCCESS) @@ -3035,7 +3294,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) WLOG(WS_LOG_DEBUG, "DNK: peer using cipher none"); break; -#ifdef HAVE_AES_CBC +#ifndef WOLFSSH_NO_AES128_CBC case ID_AES128_CBC: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-cbc"); ret = wc_AesSetKey(&ssh->decryptCipher.aes, @@ -3044,7 +3303,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) break; #endif -#ifdef WOLFSSL_AES_COUNTER +#ifndef WOLFSSH_NO_AES128_CTR case ID_AES128_CTR: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-ctr"); ret = wc_AesSetKey(&ssh->decryptCipher.aes, @@ -3053,7 +3312,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) break; #endif -#ifdef HAVE_AESGCM +#ifndef WOLFSSH_NO_AES128_GCM case ID_AES128_GCM: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-gcm"); ret = wc_AesGcmSetKey(&ssh->decryptCipher.aes, @@ -5155,6 +5414,7 @@ static int DoPacket(WOLFSSH* ssh) } +#ifdef WOLFSSL_AES_COUNTER #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2) /* * The FIPSv2 version of wc_AesCtrEncrypt() only works if the input and @@ -5189,6 +5449,7 @@ static int DoPacket(WOLFSSH* ssh) #else #define AESCTRHELPER(a,b,c,d) wc_AesCtrEncrypt((a),(b),(c),(d)) #endif +#endif static INLINE int Encrypt(WOLFSSH* ssh, byte* cipher, const byte* input, @@ -5297,6 +5558,7 @@ static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz, ret = WS_SUCCESS; break; +#ifndef WOLFSSH_NO_HMAC_SHA1_96 case ID_HMAC_SHA1_96: { Hmac hmac; @@ -5317,7 +5579,9 @@ static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz, wc_HmacFree(&hmac); } break; +#endif +#ifndef WOLFSSH_NO_HMAC_SHA1 case ID_HMAC_SHA1: { Hmac hmac; @@ -5335,6 +5599,7 @@ static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz, wc_HmacFree(&hmac); } break; +#endif case ID_HMAC_SHA2_256: { @@ -5439,6 +5704,7 @@ static INLINE void AeadIncrementExpIv(byte* iv) } +#ifndef WOLFSSH_NO_AEAD static INLINE int EncryptAead(WOLFSSH* ssh, byte* cipher, const byte* input, word16 sz, byte* authTag, const byte* auth, @@ -5452,7 +5718,7 @@ static INLINE int EncryptAead(WOLFSSH* ssh, byte* cipher, WLOG(WS_LOG_DEBUG, "EncryptAead %s", IdToName(ssh->encryptId)); -#ifdef HAVE_AESGCM +#ifndef WOLFSSH_NO_AES_GCM if (ssh->encryptId == ID_AES128_GCM) { ret = wc_AesGcmEncrypt(&ssh->encryptCipher.aes, cipher, input, sz, ssh->keys.iv, ssh->keys.ivSz, @@ -5482,7 +5748,7 @@ static INLINE int DecryptAead(WOLFSSH* ssh, byte* plain, WLOG(WS_LOG_DEBUG, "DecryptAead %s", IdToName(ssh->peerEncryptId)); -#ifdef HAVE_AESGCM +#ifndef WOLFSSH_NO_AES_GCM if (ssh->peerEncryptId == ID_AES128_GCM) { ret = wc_AesGcmDecrypt(&ssh->decryptCipher.aes, plain, input, sz, ssh->peerKeys.iv, ssh->peerKeys.ivSz, @@ -5498,6 +5764,7 @@ static INLINE int DecryptAead(WOLFSSH* ssh, byte* plain, return ret; } +#endif int DoReceive(WOLFSSH* ssh) @@ -5599,6 +5866,7 @@ int DoReceive(WOLFSSH* ssh) } } else { +#ifndef WOLFSSH_NO_AEAD ret = DecryptAead(ssh, ssh->inputBuffer.buffer + ssh->inputBuffer.idx + @@ -5619,6 +5887,7 @@ int DoReceive(WOLFSSH* ssh) ssh->error = ret; return WS_FATAL_ERROR; } +#endif } } ssh->processReplyState = PROCESS_PACKET; @@ -5846,6 +6115,8 @@ static int BundlePacket(WOLFSSH* ssh) } else { if (ret == WS_SUCCESS) { + ret = WS_INVALID_ALGO_ID; +#ifndef WOLFSSH_NO_AEAD idx += paddingSz; ret = EncryptAead(ssh, ssh->outputBuffer.buffer + @@ -5860,6 +6131,7 @@ static int BundlePacket(WOLFSSH* ssh) ssh->packetStartIdx, LENGTH_SZ); idx += ssh->macSz; +#endif } } @@ -5889,25 +6161,25 @@ static INLINE void CopyNameList(byte* buf, word32* idx, } static const char cannedEncAlgoNames[] = -#if defined(HAVE_AESGCM) +#if !defined(WOLFSSH_NO_AES_GCM) "aes128-gcm@openssh.com" #endif -#if defined(HAVE_AESGCM) && defined(WOLFSSL_AES_COUNTER) +#if !defined(WOLFSSH_NO_AES_GCM) && !defined(WOLFSSH_NO_AES_CTR) "," #endif -#if defined(WOLFSSL_AES_COUNTER) +#if !defined(WOLFSSH_NO_AES_CTR) "aes128-ctr" #endif -#if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_COUNTER))\ - && defined(HAVE_AES_CBC) +#if (!defined(WOLFSSH_NO_AES_GCM) || !defined(WOLFSSH_NO_AES_CTR)) && \ + !defined(WOLFSSH_NO_AES_CBC) "," #endif -#if defined(HAVE_AES_CBC) +#if !defined(WOLFSSH_NO_AES_CBC) "aes128-cbc" #endif ; -#if !defined(HAVE_AESGCM) && !defined(WOLFSSL_AES_COUNTER)\ - && !defined(HAVE_AES_CBC) +#if defined(WOLFSSH_NO_AES_GCM) && defined(WOLFSSH_NO_AES_CTR) && \ + defined(WOLFSSH_NO_AES_CBC) #warning "You need at least one of AES-GCM, AES-CTR or AES-CBC." #endif @@ -5921,8 +6193,8 @@ static const char cannedMacAlgoNames[] = #if !defined(WOLFSSH_NO_HMAC_SHA1_96) "hmac-sha1-96" #endif -#if (!defined(WOLFSSH_NO_HMAC_SHA2_256) || !defined(WOLFSSH_NO_HMAC_SHA1_96))\ - && !defined(WOLFSSH_NO_HMAC_SHA1) +#if (!defined(WOLFSSH_NO_HMAC_SHA2_256) || !defined(WOLFSSH_NO_HMAC_SHA1_96)) \ + && !defined(WOLFSSH_NO_HMAC_SHA1) "," #endif #if !defined(WOLFSSH_NO_HMAC_SHA1) @@ -6794,21 +7066,25 @@ int SendNewKeys(WOLFSSH* ssh) WLOG(WS_LOG_DEBUG, "SNK: using cipher none"); break; -#ifdef HAVE_AES_CBC +#ifndef WOLFSSH_NO_AES_CBC case ID_AES128_CBC: -#endif -#ifdef WOLFSSL_AES_COUNTER - case ID_AES128_CTR: -#endif -#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) - WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-cbc/ctr"); + WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-cbc"); ret = wc_AesSetKey(&ssh->encryptCipher.aes, ssh->keys.encKey, ssh->keys.encKeySz, ssh->keys.iv, AES_ENCRYPTION); break; #endif -#ifdef HAVE_AESGCM +#ifndef WOLFSSH_NO_AES_CTR + case ID_AES128_CTR: + WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-ctr"); + ret = wc_AesSetKey(&ssh->encryptCipher.aes, + ssh->keys.encKey, ssh->keys.encKeySz, + ssh->keys.iv, AES_ENCRYPTION); + break; +#endif + +#ifndef WOLFSSH_NO_AES_GCM case ID_AES128_GCM: WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-gcm"); ret = wc_AesGcmSetKey(&ssh->encryptCipher.aes, diff --git a/tests/unit.c b/tests/unit.c index 58cf177..c8f9db9 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -208,6 +208,7 @@ typedef struct { } KdfTestVector; +#ifndef NO_SHA /** Test Vector Set #1: SHA-1 **/ const char kdfTvSet1k[] = "35618FD3AABF980A5F766408961600D4933C60DD7B22D69EEB4D7A987C938F6F" @@ -245,6 +246,7 @@ const char kdfTvSet2c[] = "CB6D56EC5B9AFECD326D544DA2D22DED"; const char kdfTvSet2d[] = "F712F6451F1BD6CE9BAA597AC87C5A24"; const char kdfTvSet2e[] = "E42FC62C76B76B37818F78292D3C2226D0264760"; const char kdfTvSet2f[] = "D14BE4DD0093A3E759580233C80BB8399CE4C4E7"; +#endif /** Test Vector Set #3: SHA-256 **/ const char kdfTvSet3k[] = @@ -296,6 +298,7 @@ const char kdfTvSet4f[] = #define HASH_SHA256 WC_HASH_TYPE_SHA256 static const KdfTestVector kdfTestVectors[] = { +#ifndef NO_SHA {HASH_SHA, 'A', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sid, kdfTvSet1a}, {HASH_SHA, 'B', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sid, kdfTvSet1b}, {HASH_SHA, 'C', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sid, kdfTvSet1c}, @@ -308,6 +311,7 @@ static const KdfTestVector kdfTestVectors[] = { {HASH_SHA, 'D', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sid, kdfTvSet2d}, {HASH_SHA, 'E', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sid, kdfTvSet2e}, {HASH_SHA, 'F', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sid, kdfTvSet2f}, +#endif {HASH_SHA256, 'A', kdfTvSet3k, kdfTvSet3h, kdfTvSet3sid, kdfTvSet3a}, {HASH_SHA256, 'B', kdfTvSet3k, kdfTvSet3h, kdfTvSet3sid, kdfTvSet3b}, {HASH_SHA256, 'C', kdfTvSet3k, kdfTvSet3h, kdfTvSet3sid, kdfTvSet3c},