From b63d3c491487f47009d629b470cb4add6b2ca3b0 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 24 Sep 2020 10:38:34 -0700 Subject: [PATCH 1/7] 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}, From 4d5ce88cc9a185a6ae75d982b229097038956edf Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 13 Oct 2020 17:41:15 -0700 Subject: [PATCH 2/7] More Options Wrapped more items with guards to disable them if not usable. --- examples/echoserver/echoserver.c | 9 +- src/internal.c | 159 +++++++++++++++++++------------ tests/api.c | 24 ++++- 3 files changed, 127 insertions(+), 65 deletions(-) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 823053d..8bc6712 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -1105,6 +1105,12 @@ static int load_file(const char* fileName, byte* buf, word32 bufSz) } #endif /* NO_FILESYSTEM */ +#ifdef HAVE_ECC521 + #define ECC_PATH "./keys/server-key-ecc-521.der" +#else + #define ECC_PATH "./keys/server-key-ecc.der" +#endif + /* returns buffer size on success */ static int load_key(byte isEcc, byte* buf, word32 bufSz) { @@ -1112,8 +1118,7 @@ static int load_key(byte isEcc, byte* buf, word32 bufSz) #ifndef NO_FILESYSTEM const char* bufName; - bufName = isEcc ? "./keys/server-key-ecc.der" : - "./keys/server-key-rsa.der" ; + bufName = isEcc ? ECC_PATH : "./keys/server-key-rsa.der" ; sz = load_file(bufName, buf, bufSz); #else /* using buffers instead */ diff --git a/src/internal.c b/src/internal.c index 3950f32..dbfba06 100644 --- a/src/internal.c +++ b/src/internal.c @@ -130,13 +130,13 @@ Flags: #if defined(NO_DH) || defined(NO_SHA256) #define WOLFSSH_NO_DH_GEX_SHA256 #endif -#if !defined(HAVE_ECC) || defined(NO_SHA256) +#if !defined(HAVE_ECC) || defined(NO_SHA256) || defined(NO_ECC256) #define WOLFSSH_NO_ECDH_SHA2_NISTP256 #endif -#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) || !defined(HAVE_ECC384) #define WOLFSSH_NO_ECDH_SHA2_NISTP384 #endif -#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) || !defined(HAVE_ECC521) #define WOLFSSH_NO_ECDH_SHA2_NISTP521 #endif #if !defined(HAVE_ED25519) || defined(NO_SHA256) @@ -145,13 +145,13 @@ Flags: #if defined(NO_RSA) || defined(NO_SHA) #define WOLFSSH_NO_SSH_RSA_SHA1 #endif -#if !defined(HAVE_ECC) || defined(NO_SHA256) +#if !defined(HAVE_ECC) || defined(NO_SHA256) || defined(NO_ECC256) #define WOLFSSH_NO_ECDSA_SHA2_NISTP256 #endif -#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) || !defined(HAVE_ECC384) #define WOLFSSH_NO_ECDSA_SHA2_NISTP384 #endif -#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) || !defined(HAVE_ECC521) #define WOLFSSH_NO_ECDSA_SHA2_NISTP521 #endif #if defined(NO_AES) || !defined(HAVE_AES_CBC) @@ -1995,7 +1995,7 @@ static int GetNameList(byte* idList, word32* idListSz, static const byte cannedEncAlgo[] = { #ifndef WOLFSSH_NO_AES_GCM - ID_AES128_GCM, + ID_AES128_GCM, #endif #ifndef WOLFSSH_NO_AES_CTR ID_AES128_CTR, @@ -2016,17 +2016,47 @@ static const byte cannedMacAlgo[] = { ID_HMAC_SHA1, #endif }; -static const byte cannedKeyAlgoClient[] = {ID_ECDSA_SHA2_NISTP256, ID_SSH_RSA}; + +static const byte cannedKeyAlgoClient[] = { +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 + ID_ECDSA_SHA2_NISTP521, +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 + ID_ECDSA_SHA2_NISTP384, +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 + ID_ECDSA_SHA2_NISTP256, +#endif +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 + ID_SSH_RSA, +#endif +}; + #ifndef WOLFSSH_NO_SSH_RSA_SHA1 static const byte cannedKeyAlgoRsa[] = {ID_SSH_RSA}; static const word32 cannedKeyAlgoRsaSz = sizeof(cannedKeyAlgoRsa); #endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 static const byte cannedKeyAlgoEcc256[] = {ID_ECDSA_SHA2_NISTP256}; +static const word32 cannedKeyAlgoEcc256Sz = sizeof(cannedKeyAlgoEcc256); +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 static const byte cannedKeyAlgoEcc384[] = {ID_ECDSA_SHA2_NISTP384}; +static const word32 cannedKeyAlgoEcc384Sz = sizeof(cannedKeyAlgoEcc384); +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 static const byte cannedKeyAlgoEcc521[] = {ID_ECDSA_SHA2_NISTP521}; +static const word32 cannedKeyAlgoEcc521Sz = sizeof(cannedKeyAlgoEcc521); +#endif static const byte cannedKexAlgo[] = { +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521 + ID_ECDH_SHA2_NISTP521, +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384 + ID_ECDH_SHA2_NISTP384, +#endif #ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 ID_ECDH_SHA2_NISTP256, #endif @@ -2044,9 +2074,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 cannedKeyAlgoEcc256Sz = sizeof(cannedKeyAlgoEcc256); -static const word32 cannedKeyAlgoEcc384Sz = sizeof(cannedKeyAlgoEcc384); -static const word32 cannedKeyAlgoEcc521Sz = sizeof(cannedKeyAlgoEcc521); static const word32 cannedKexAlgoSz = sizeof(cannedKexAlgo); @@ -6162,92 +6189,100 @@ static INLINE void CopyNameList(byte* buf, word32* idx, static const char cannedEncAlgoNames[] = #if !defined(WOLFSSH_NO_AES_GCM) - "aes128-gcm@openssh.com" -#endif -#if !defined(WOLFSSH_NO_AES_GCM) && !defined(WOLFSSH_NO_AES_CTR) - "," + "aes128-gcm@openssh.com," #endif #if !defined(WOLFSSH_NO_AES_CTR) - "aes128-ctr" -#endif -#if (!defined(WOLFSSH_NO_AES_GCM) || !defined(WOLFSSH_NO_AES_CTR)) && \ - !defined(WOLFSSH_NO_AES_CBC) - "," + "aes128-ctr," #endif #if !defined(WOLFSSH_NO_AES_CBC) - "aes128-cbc" + "aes128-cbc," #endif - ; + ""; #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." +#warning "You need at least one encryption algorithm." #endif static const char cannedMacAlgoNames[] = #if !defined(WOLFSSH_NO_HMAC_SHA2_256) - "hmac-sha2-256" -#endif -#if !defined(WOLFSSH_NO_HMAC_SHA2_256) && !defined(WOLFSSH_NO_HMAC_SHA1_96) - "," + "hmac-sha2-256," #endif #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) - "," + "hmac-sha1-96," #endif #if !defined(WOLFSSH_NO_HMAC_SHA1) - "hmac-sha1" + "hmac-sha1," #endif - ; -#if defined(WOLFSSH_NO_HMAC_SHA2_256) && defined(WOLFSSH_NO_HMAC_SHA1_96)\ - && defined(WOLFSSH_NO_HMAC_SHA1) - #warning "You need at least one of HMAC-SHA2-256, HMAC-SHA1-96 or HMAC-SHA1" + ""; +#if defined(WOLFSSH_NO_HMAC_SHA2_256) && \ + defined(WOLFSSH_NO_HMAC_SHA1_96) && \ + defined(WOLFSSH_NO_HMAC_SHA1) + #warning "You need at least one MAC algorithm." +#endif + +static const char cannedKeyAlgoClientNames[] = +#ifndef WOLFSSL_NO_ECDSA_SHA2_NISTP521 + "ecdsa-sha2-nistp521," +#endif +#ifndef WOLFSSL_NO_ECDSA_SHA2_NISTP384 + "ecdsa-sha2-nistp384," +#endif +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 + "ecdsa-sha2-nistp256," +#endif +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 + "ssh-rsa," +#endif + ""; +#if defined(WOLFSSH_NO_ECDSA_SHA2_NISTP256) && \ + defined(WOLFSSH_NO_ECDSA_SHA2_NISTP384) && \ + defined(WOLFSSH_NO_ECDSA_SHA2_NISTP521) && \ + defined(WOLFSSH_NO_SSH_RSA_SHA2) + #warning "You need at least one signing algorithm." #endif -static const char cannedKeyAlgoClientNames[] = "ecdsa-sha2-nistp256,ssh-rsa"; static const char cannedKeyAlgoRsaNames[] = "ssh-rsa"; static const char cannedKeyAlgoEcc256Names[] = "ecdsa-sha2-nistp256"; static const char cannedKeyAlgoEcc384Names[] = "ecdsa-sha2-nistp384"; static const char cannedKeyAlgoEcc521Names[] = "ecdsa-sha2-nistp521"; + static const char cannedKexAlgoNames[] = -#if !defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) - "ecdh-sha2-nistp256" +#if !defined(WOLFSSH_NO_ECDH_SHA2_NISTP521) + "ecdh-sha2-nistp521," #endif -#if !defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) && !defined(WOLFSSH_NO_DH_GEX_SHA256) - "," +#if !defined(WOLFSSH_NO_ECDH_SHA2_NISTP384) + "ecdh-sha2-nistp384," +#endif +#if !defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) + "ecdh-sha2-nistp256," #endif #if !defined(WOLFSSH_NO_DH_GEX_SHA256) - "diffie-hellman-group-exchange-sha256" -#endif -#if (!defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) || !defined(WOLFSSH_NO_DH_GEX_SHA256))\ - && !defined(WOLFSSH_NO_DH_GROUP14_SHA1) - "," + "diffie-hellman-group-exchange-sha256," #endif #if !defined(WOLFSSH_NO_DH_GROUP14_SHA1) - "diffie-hellman-group14-sha1" -#endif -#if (!defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) || !defined(WOLFSSH_NO_DH_GEX_SHA256) \ - || !defined(WOLFSSH_NO_DH_GROUP14_SHA1)) && !defined(WOLFSSH_NO_DH_GROUP1_SHA1) - "," + "diffie-hellman-group14-sha1," #endif #if !defined(WOLFSSH_NO_DH_GROUP1_SHA1) - "diffie-hellman-group1-sha1" + "diffie-hellman-group1-sha1," #endif - ; /* This is a little awkward. */ -#if defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) && defined(WOLFSSH_NO_DH_GEX_SHA256)\ - && defined(WOLFSSH_NO_DH_GROUP14_SHA1) && defined(WOLFSSH_NO_DH_GROUP1_SHA1) - #warning "You need at least one of ECDH-SHA2-NISTP256, DH-GEX-SHA256, " - "DH-GROUP14-SHA1 or DH-GROUP1-SHA1" + ""; + +#if defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) && \ + defined(WOLFSSH_NO_DH_GEX_SHA256) && \ + defined(WOLFSSH_NO_DH_GROUP14_SHA1) && \ + defined(WOLFSSH_NO_DH_GROUP1_SHA1) && \ + defined(WOLFSSH_NO_ECDH_SHA2_NISTP521) && \ + defined(WOLFSSH_NO_ECDH_SHA2_NISTP384) + #warning "You need at least one key exchange algorithm." #endif static const char cannedNoneNames[] = "none"; -static const word32 cannedEncAlgoNamesSz = sizeof(cannedEncAlgoNames) - 1; -static const word32 cannedMacAlgoNamesSz = sizeof(cannedMacAlgoNames) - 1; +/* -1 for the null, some are -1 for the comma */ +static const word32 cannedEncAlgoNamesSz = sizeof(cannedEncAlgoNames) - 2; +static const word32 cannedMacAlgoNamesSz = sizeof(cannedMacAlgoNames) - 2; static const word32 cannedKeyAlgoClientNamesSz = - sizeof(cannedKeyAlgoClientNames) - 1; + sizeof(cannedKeyAlgoClientNames) - 2; static const word32 cannedKeyAlgoRsaNamesSz = sizeof(cannedKeyAlgoRsaNames) - 1; static const word32 cannedKeyAlgoEcc256NamesSz = sizeof(cannedKeyAlgoEcc256Names) - 1; @@ -6255,7 +6290,7 @@ static const word32 cannedKeyAlgoEcc384NamesSz = sizeof(cannedKeyAlgoEcc384Names) - 1; static const word32 cannedKeyAlgoEcc521NamesSz = sizeof(cannedKeyAlgoEcc521Names) - 1; -static const word32 cannedKexAlgoNamesSz = sizeof(cannedKexAlgoNames) - 1; +static const word32 cannedKexAlgoNamesSz = sizeof(cannedKexAlgoNames) - 2; static const word32 cannedNoneNamesSz = sizeof(cannedNoneNames) - 1; diff --git a/tests/api.c b/tests/api.c index 3e6b63d..6fe21c5 100644 --- a/tests/api.c +++ b/tests/api.c @@ -462,11 +462,33 @@ enum WS_TestFormatTypes { }; +#ifndef NO_ECC256 static const char serverKeyEccDer[] = "307702010104206109990b79d25f285a0f5d15cca15654f92b3987212da77d85" "7bb87f38c66dd5a00a06082a8648ce3d030107a144034200048113ffa42bb79c" "45747a834c61f33fad26cf22cda9a3bca561b47ce662d4c2f755439a31fb8011" "20b5124b24f578d7fd22ef4635f005586b5f63c8da1bc4f569"; +static const int serverKeyEccCurveId = ECC_SECP256R1; +#elif defined(HAVE_ECC384) +static const char serverKeyEccDer[] = + "3081a402010104303eadd2bbbf05a7be3a3f7c28151289de5bb3644d7011761d" + "b56f2a0362fba64f98e64ff986dc4fb8efdb2d6b8da57142a00706052b810400" + "22a1640362000438d62be418ff573fd0e020d48876c4e1121dfb2d6ebee4895d" + "7724316d46a23105873f2986d5c712803a6f471ab86850eb063e108961349cf8" + "b4c6a4cf5e97bd7e51e975e3e9217261506eb9cf3c493d3eb88d467b5f27ebab" + "2161c00066febd"; +static const int serverKeyEccCurveId = ECC_SECP384R1; +#elif defined(HAVE_ECC521) +static const char serverKeyEccDer[] = + "3081dc0201010442004ca4d86428d9400e7b2df3912eb996c195895043af92e8" + "6de70ae4df46f22a291a6bb2748aae82580df6c39f49b3ed82f1789ece1b657d" + "45438cff156534354575a00706052b81040023a18189038186000401f8d0a7c3" + "c58d841957969f213a94f3da550edf76d8dd171531f35bb069c8bc300d6f6b37" + "d18046a9717f2c6f59519c827095b29a6313306218c235769400d0f96d000a19" + "3ba346652beb409a9a45c597a3ed932dd5aaae96bf2f317e5a7ac7458b3c6cdb" + "aa90c355382cdfcdca7377d92eb20a5e8c74237ca5a345b19e3f1a2290b154"; +static const int serverKeyEccCurveId = ECC_SECP521R1; +#endif static const char serverKeyRsaDer[] = "308204a30201000282010100da5dad2514761559f340fd3cb86230b36dc0f9ec" @@ -569,7 +591,7 @@ static void test_wolfSSH_CTX_UsePrivateKey_buffer(void) TEST_GOOD_FORMAT_ASN1)); AssertNotNull(ctx->privateKey); AssertIntNE(0, ctx->privateKeySz); - AssertIntEQ(ECC_SECP256R1, ctx->useEcc); + AssertIntEQ(serverKeyEccCurveId, ctx->useEcc); #ifndef NO_RSA lastKey = ctx->privateKey; From 740d47d0b7f9fe74eb5927bec829150a23ddde79 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 14 Oct 2020 14:28:26 -0700 Subject: [PATCH 3/7] More Options 1. Wrapped the user keys in client.c with guards. 2. Added the ECC-521 key for hansel. 3. Touched up the loads of the keys with guards. --- examples/client/client.c | 58 +++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 275019b..cd52f8d 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -188,6 +188,7 @@ static word32 userPrivateKeyTypeSz = 0; static byte isPrivate = 0; +#ifndef NO_RSA static const char* hanselPublicRsa = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho" "MNiisWSgUs5HdHcACuHYPi2W6Z1PBFmBWT9odOrGRjoZXJfDDoPi+j8SSfDGsc/hsCmc3G" @@ -195,7 +196,6 @@ static const char* hanselPublicRsa = "nEhBaIPUJO2C/M0pFnnbZxKgJlX7t1Doy7h5eXxviymOIvaCZKU+x5OopfzM/wFkey0EPW" "NmzI5y/+pzU5afsdeEWdiQDIQc80H6Pz8fsoFPvYSG+s4/wz0duu7yeeV1Ypoho65Zr+pE" "nIf7dO0B8EblgWt+ud+JI8wrAhfE4x hansel"; - static const byte hanselPrivateRsa[] = { 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0x3f, 0x76, 0x45, 0xa3, 0x03, 0xac, 0x38, 0xd5, 0xc7, 0x0f, 0x93, @@ -298,15 +298,16 @@ static const byte hanselPrivateRsa[] = { 0x7c, 0x97, 0x0b, 0x27, 0x2f, 0xae, 0xfc, 0xc3, 0x93, 0xaf, 0x1a, 0x75, 0xec, 0x18, 0xdb }; - static const unsigned int hanselPrivateRsaSz = 1191; +#endif -const char* hanselPublicEcc = +#ifdef HAVE_ECC +#ifndef NO_ECC256 +static const char* hanselPublicEcc = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA" "BBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25" "qUzgDtH7oyaQROUnNvk= hansel"; - static const byte hanselPrivateEcc[] = { 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x03, 0x6e, 0x17, 0xd3, 0xb9, 0xb8, 0xab, 0xc8, 0xf9, 0x1f, 0xf1, 0x2d, 0x44, 0x4c, 0x3b, 0x12, 0xb1, @@ -320,8 +321,39 @@ static const byte hanselPrivateEcc[] = { 0x4c, 0xe0, 0x0e, 0xd1, 0xfb, 0xa3, 0x26, 0x90, 0x44, 0xe5, 0x27, 0x36, 0xf9 }; - static const unsigned int hanselPrivateEccSz = 121; +#elif defined(HAVE_ECC521) +static const char* hanselPublicEcc = + "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAA" + "CFBAET/BOzBb9Jx9b52VIHFP4g/uk5KceDpz2M+/Ln9WiDjsMfb4NgNCAB+EMNJUX/TNBL" + "FFmqr7c6+zUH+QAo2qstvQDsReyFkETRB2vZD//nCZfcAe0RMtKZmgtQLKXzSlimUjXBM4" + "/zE5lwE05aXADp88h8nuaT/X4bll9cWJlH0fUykA== hansel"; +static const byte hanselPrivateEcc[] = { + 0x30, 0x81, 0xdc, 0x02, 0x01, 0x01, 0x04, 0x42, 0x01, 0x79, 0x40, 0xb8, + 0x33, 0xe5, 0x53, 0x5b, 0x9e, 0xfd, 0xed, 0xbe, 0x7c, 0x68, 0xe4, 0xb6, + 0xc3, 0x50, 0x00, 0x0d, 0x39, 0x64, 0x05, 0xf6, 0x5a, 0x5d, 0x41, 0xab, + 0xb3, 0xd9, 0xa7, 0xcb, 0x1c, 0x7d, 0x34, 0x46, 0x5c, 0x2d, 0x56, 0x26, + 0xa0, 0x6a, 0xc7, 0x3d, 0x4f, 0x78, 0x58, 0x14, 0x66, 0x6c, 0xfc, 0x86, + 0x3c, 0x8b, 0x5b, 0x54, 0x29, 0x89, 0x93, 0x48, 0xd9, 0x54, 0x8b, 0xbe, + 0x9d, 0x91, 0xa0, 0x07, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, 0xa1, + 0x81, 0x89, 0x03, 0x81, 0x86, 0x00, 0x04, 0x01, 0x13, 0xfc, 0x13, 0xb3, + 0x05, 0xbf, 0x49, 0xc7, 0xd6, 0xf9, 0xd9, 0x52, 0x07, 0x14, 0xfe, 0x20, + 0xfe, 0xe9, 0x39, 0x29, 0xc7, 0x83, 0xa7, 0x3d, 0x8c, 0xfb, 0xf2, 0xe7, + 0xf5, 0x68, 0x83, 0x8e, 0xc3, 0x1f, 0x6f, 0x83, 0x60, 0x34, 0x20, 0x01, + 0xf8, 0x43, 0x0d, 0x25, 0x45, 0xff, 0x4c, 0xd0, 0x4b, 0x14, 0x59, 0xaa, + 0xaf, 0xb7, 0x3a, 0xfb, 0x35, 0x07, 0xf9, 0x00, 0x28, 0xda, 0xab, 0x2d, + 0xbd, 0x00, 0xec, 0x45, 0xec, 0x85, 0x90, 0x44, 0xd1, 0x07, 0x6b, 0xd9, + 0x0f, 0xff, 0xe7, 0x09, 0x97, 0xdc, 0x01, 0xed, 0x11, 0x32, 0xd2, 0x99, + 0x9a, 0x0b, 0x50, 0x2c, 0xa5, 0xf3, 0x4a, 0x58, 0xa6, 0x52, 0x35, 0xc1, + 0x33, 0x8f, 0xf3, 0x13, 0x99, 0x70, 0x13, 0x4e, 0x5a, 0x5c, 0x00, 0xe9, + 0xf3, 0xc8, 0x7c, 0x9e, 0xe6, 0x93, 0xfd, 0x7e, 0x1b, 0x96, 0x5f, 0x5c, + 0x58, 0x99, 0x47, 0xd1, 0xf5, 0x32, 0x90 +}; +static const unsigned int hanselPrivateEccSz = 223; +#else + #error "Enable an ECC Curve or disable ECC." +#endif +#endif static int wsUserAuth(byte authType, @@ -766,7 +798,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) SOCKADDR_IN_T clientAddr; socklen_t clientAddrSz = sizeof(clientAddr); char rxBuf[80]; - int ret; + int ret = 0; int ch; int userEcc = 0; word16 port = wolfSshPort; @@ -885,17 +917,20 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) if (privKeyName == NULL) { if (userEcc) { + #ifdef HAVE_ECC ret = wolfSSH_ReadKey_buffer(hanselPrivateEcc, hanselPrivateEccSz, WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz, &userPrivateKeyType, &userPrivateKeyTypeSz, NULL); - isPrivate = 1; + #endif } else { + #ifndef NO_RSA ret = wolfSSH_ReadKey_buffer(hanselPrivateRsa, hanselPrivateRsaSz, WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz, &userPrivateKeyType, &userPrivateKeyTypeSz, NULL); - isPrivate = 1; + #endif } + isPrivate = 1; if (ret != 0) err_sys("Couldn't load private key buffer."); } else { @@ -916,19 +951,22 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) userPublicKeySz = sizeof(userPublicKey); if (userEcc) { + #ifdef HAVE_ECC ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicEcc, (word32)strlen(hanselPublicEcc), WOLFSSH_FORMAT_SSH, &p, &userPublicKeySz, &userPublicKeyType, &userPublicKeyTypeSz, NULL); - isPrivate = 1; + #endif } else { + #ifndef NO_RSA ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicRsa, (word32)strlen(hanselPublicRsa), WOLFSSH_FORMAT_SSH, &p, &userPublicKeySz, &userPublicKeyType, &userPublicKeyTypeSz, NULL); - isPrivate = 1; + #endif } + isPrivate = 1; if (ret != 0) err_sys("Couldn't load public key buffer."); } else { From 91ca3ee43bb6ca245860a3448ecd1d0492d86a17 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 14 Oct 2020 15:23:04 -0700 Subject: [PATCH 4/7] Fix a mix up between two prime names in a lookup table. --- src/internal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index dbfba06..dfd89d5 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2248,7 +2248,7 @@ static INLINE int wcPrimeForId(byte id) switch (id) { #ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 case ID_ECDH_SHA2_NISTP256: - return ECC_SECP521R1; + return ECC_SECP256R1; #endif #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 case ID_ECDSA_SHA2_NISTP256: @@ -2256,7 +2256,7 @@ static INLINE int wcPrimeForId(byte id) #endif #ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384 case ID_ECDH_SHA2_NISTP384: - return ECC_SECP521R1; + return ECC_SECP384R1; #endif #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 case ID_ECDSA_SHA2_NISTP384: From b9ccb6f4fbff1508e9ac2d2b55ddcf94007cbf0e Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 14 Oct 2020 16:44:50 -0700 Subject: [PATCH 5/7] Fix a couple dead stores. --- src/internal.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/internal.c b/src/internal.c index dfd89d5..131e338 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3023,7 +3023,6 @@ 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; @@ -3061,7 +3060,8 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) else ret = WS_RSA_E; #else - (void)tmpIdx; + (void)tmpIdx; + ret = WS_INVALID_ALGO_ID; #endif } else { @@ -3109,12 +3109,13 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) else ret = WS_ECC_E; } +#else + ret = WS_INVALID_ALGO_ID; #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, @@ -3123,6 +3124,8 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) f, fSz); ForceZero(ssh->handshake->x, ssh->handshake->xSz); wc_FreeDhKey(&ssh->handshake->privKey.dh); +#else + ret = WS_INVALID_ALGO_ID; #endif } else { @@ -3140,6 +3143,8 @@ 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); +#else + ret = WS_INVALID_ALGO_ID; #endif } } @@ -6142,7 +6147,6 @@ static int BundlePacket(WOLFSSH* ssh) } else { if (ret == WS_SUCCESS) { - ret = WS_INVALID_ALGO_ID; #ifndef WOLFSSH_NO_AEAD idx += paddingSz; ret = EncryptAead(ssh, @@ -6158,6 +6162,8 @@ static int BundlePacket(WOLFSSH* ssh) ssh->packetStartIdx, LENGTH_SZ); idx += ssh->macSz; +#else + ret = WS_INVALID_ALGO_ID; #endif } } From 28f5d750c9846255312e2301494ad31ddd6ea67c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 15 Oct 2020 08:48:02 -0700 Subject: [PATCH 6/7] More Options 1. Fix the key offerings in the echoserver and client with ifdef guards. 2. Fix a couple guards that weren't copy-pasted correctly. --- examples/echoserver/echoserver.c | 43 ++++++++++++++++++++++++++------ src/internal.c | 4 +-- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 8bc6712..d476958 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -1220,6 +1220,8 @@ static const char samplePasswordBuffer[] = "jack:fetchapail\n"; +#ifdef HAVE_ECC +#ifndef NO_ECC256 static const char samplePublicKeyEccBuffer[] = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA" "BBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25" @@ -1227,8 +1229,22 @@ static const char samplePublicKeyEccBuffer[] = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA" "BBBKAtH8cqaDbtJFjtviLobHBmjCtG56DMkP6A4M2H9zX2/YCg1h9bYS7WHd9UQDwXO1Hh" "IZzRYecXh7SG9P4GhRY= gretel\n"; +#elif defined(HAVE_ECC521) +static const char samplePublicKeyEccBuffer[] = + "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAA" + "CFBAET/BOzBb9Jx9b52VIHFP4g/uk5KceDpz2M+/Ln9WiDjsMfb4NgNCAB+EMNJUX/TNBL" + "FFmqr7c6+zUH+QAo2qstvQDsReyFkETRB2vZD//nCZfcAe0RMtKZmgtQLKXzSlimUjXBM4" + "/zE5lwE05aXADp88h8nuaT/X4bll9cWJlH0fUykA== hansel\n" + "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAA" + "CFBAD3gANmzvkxOBN8MYwRBYO6B//7TTCtA2vwG/W5bqiVVxznXWj0xiFrgayApvH7FDpL" + "HiJ8+c1vUsRVEa8PY5QPsgFow+xv0P2WSrRkn4/UUquftPs1ZHPhdr06LjS19ObvWM8xFZ" + "YU6n0i28UWCUR5qE+BCTzZDWYT8V24YD8UhpaYIw== gretel\n"; +#else + #error "Enable an ECC Curve or disable ECC." +#endif +#endif - +#ifndef NO_RSA static const char samplePublicKeyRsaBuffer[] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho" "MNiisWSgUs5HdHcACuHYPi2W6Z1PBFmBWT9odOrGRjoZXJfDDoPi+j8SSfDGsc/hsCmc3G" @@ -1242,6 +1258,7 @@ static const char samplePublicKeyRsaBuffer[] = "uNZl/30Mczs73N3MBzi6J1oPo7sFlqzB6ecBjK2Kpjus4Y1rYFphJnUxtKvB0s+hoaadru" "biE57dK6BrH5iZwVLTQKux31uCJLPhiktI3iLbdlGZEctJkTasfVSsUizwVIyRjhVKmbdI" "RGwkU38D043AR1h0mUoGCPIKuqcFMf gretel\n"; +#endif static const char sampleNoneBuffer[] = "holmes\n" @@ -1642,7 +1659,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) #endif { - const char* bufName; + const char* bufName = NULL; byte buf[SCRATCH_BUFFER_SZ]; word32 bufSz; @@ -1662,12 +1679,22 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) buf[bufSz] = 0; LoadPasswordBuffer(buf, bufSz, &pwMapList); - bufName = userEcc ? samplePublicKeyEccBuffer : - samplePublicKeyRsaBuffer; - bufSz = (word32)strlen(bufName); - memcpy(buf, bufName, bufSz); - buf[bufSz] = 0; - LoadPublicKeyBuffer(buf, bufSz, &pwMapList); + if (userEcc) { + #ifdef HAVE_ECC + bufName = samplePublicKeyEccBuffer; + #endif + } + else { + #ifndef NO_RSA + bufName = samplePublicKeyRsaBuffer; + #endif + } + if (bufName != NULL) { + bufSz = (word32)strlen(bufName); + memcpy(buf, bufName, bufSz); + buf[bufSz] = 0; + LoadPublicKeyBuffer(buf, bufSz, &pwMapList); + } bufSz = (word32)strlen(sampleNoneBuffer); memcpy(buf, sampleNoneBuffer, bufSz); diff --git a/src/internal.c b/src/internal.c index 131e338..03ee8b5 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6227,10 +6227,10 @@ static const char cannedMacAlgoNames[] = #endif static const char cannedKeyAlgoClientNames[] = -#ifndef WOLFSSL_NO_ECDSA_SHA2_NISTP521 +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 "ecdsa-sha2-nistp521," #endif -#ifndef WOLFSSL_NO_ECDSA_SHA2_NISTP384 +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 "ecdsa-sha2-nistp384," #endif #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 From 22c67b26ce41fd39a7f014fc697a15218d91bdfd Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 15 Oct 2020 13:51:10 -0700 Subject: [PATCH 7/7] More Options 1. Moved the options checking to internal.h so other sources can use it. 2. Added some additional option checks and groups. 3. Added some guard checksto the key exchange. --- src/internal.c | 186 +++++++++++++++++++++------------------------ wolfssh/internal.h | 115 ++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+), 101 deletions(-) diff --git a/src/internal.c b/src/internal.c index 03ee8b5..cdd5dfb 100644 --- a/src/internal.c +++ b/src/internal.c @@ -33,7 +33,7 @@ #include #include #include -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH #include #endif #include @@ -109,68 +109,13 @@ Flags: 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. + WOLFSSH_NO_DH + Set when all DH algorithms are disabled. Set to disable use of all DH + algorithms for key agreement. Setting this will force all DH key agreement + algorithms 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) || defined(NO_ECC256) - #define WOLFSSH_NO_ECDH_SHA2_NISTP256 -#endif -#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) || !defined(HAVE_ECC384) - #define WOLFSSH_NO_ECDH_SHA2_NISTP384 -#endif -#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) || !defined(HAVE_ECC521) - #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) || defined(NO_ECC256) - #define WOLFSSH_NO_ECDSA_SHA2_NISTP256 -#endif -#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) || !defined(HAVE_ECC384) - #define WOLFSSH_NO_ECDSA_SHA2_NISTP384 -#endif -#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) || !defined(HAVE_ECC521) - #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"; @@ -478,7 +423,7 @@ static HandshakeInfo* HandshakeInfoNew(void* heap) newHs->macId = ID_NONE; newHs->blockSz = MIN_BLOCK_SZ; newHs->hashId = WC_HASH_TYPE_NONE; -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GEX_SHA256 newHs->dhGexMinSz = WOLFSSH_DEFAULT_GEXDH_MIN; newHs->dhGexPreferredSz = WOLFSSH_DEFAULT_GEXDH_PREFERRED; newHs->dhGexMaxSz = WOLFSSH_DEFAULT_GEXDH_MAX; @@ -496,7 +441,7 @@ static void HandshakeInfoFree(HandshakeInfo* hs, void* heap) WLOG(WS_LOG_DEBUG, "Entering HandshakeInfoFree()"); if (hs) { WFREE(hs->kexInit, heap, DYNTYPE_STRING); -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH WFREE(hs->primeGroup, heap, DYNTYPE_MPINT); WFREE(hs->generator, heap, DYNTYPE_MPINT); #endif @@ -2701,7 +2646,8 @@ static const byte dhPrimeGroup1[] = { static const word32 dhPrimeGroup1Sz = sizeof(dhPrimeGroup1); #endif -#ifndef WOLFSSH_NO_DH_GROUP14_SHA1 +#if !defined(WOLFSSH_NO_DH_GROUP14_SHA1) || \ + !defined(WOLFSSH_NO_DH_GEX_SHA256) 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, @@ -3117,7 +3063,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) /* Generate and hash in the shared secret */ if (ret == 0) { if (!ssh->handshake->useEcc) { -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH ret = wc_DhAgree(&ssh->handshake->privKey.dh, ssh->k, &ssh->kSz, ssh->handshake->x, ssh->handshake->xSz, @@ -3326,7 +3272,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) WLOG(WS_LOG_DEBUG, "DNK: peer using cipher none"); break; -#ifndef WOLFSSH_NO_AES128_CBC +#ifndef WOLFSSH_NO_AES_CBC case ID_AES128_CBC: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-cbc"); ret = wc_AesSetKey(&ssh->decryptCipher.aes, @@ -3335,7 +3281,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) break; #endif -#ifndef WOLFSSH_NO_AES128_CTR +#ifndef WOLFSSH_NO_AES_CTR case ID_AES128_CTR: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-ctr"); ret = wc_AesSetKey(&ssh->decryptCipher.aes, @@ -3344,7 +3290,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) break; #endif -#ifndef WOLFSSH_NO_AES128_GCM +#ifndef WOLFSSH_NO_AES_GCM case ID_AES128_GCM: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-gcm"); ret = wc_AesGcmSetKey(&ssh->decryptCipher.aes, @@ -3377,7 +3323,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) } -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GEX_SHA256 static int DoKexDhGexRequest(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { @@ -5299,7 +5245,7 @@ static int DoPacket(WOLFSSH* ssh) } if (ssh->handshake->kexId == ID_DH_GEX_SHA256) { -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GEX_SHA256 WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_GROUP"); ret = DoKexDhGexGroup(ssh, buf + idx, payloadSz, &payloadIdx); #endif @@ -5310,7 +5256,7 @@ static int DoPacket(WOLFSSH* ssh) } break; -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GEX_SHA256 case MSGID_KEXDH_GEX_REQUEST: WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_REQUEST"); ret = DoKexDhGexRequest(ssh, buf + idx, payloadSz, &payloadIdx); @@ -5446,7 +5392,7 @@ static int DoPacket(WOLFSSH* ssh) } -#ifdef WOLFSSL_AES_COUNTER +#ifndef WOLFSSH_NO_AES_CTR #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2) /* * The FIPSv2 version of wc_AesCtrEncrypt() only works if the input and @@ -6243,7 +6189,7 @@ static const char cannedKeyAlgoClientNames[] = #if defined(WOLFSSH_NO_ECDSA_SHA2_NISTP256) && \ defined(WOLFSSH_NO_ECDSA_SHA2_NISTP384) && \ defined(WOLFSSH_NO_ECDSA_SHA2_NISTP521) && \ - defined(WOLFSSH_NO_SSH_RSA_SHA2) + defined(WOLFSSH_NO_SSH_RSA_SHA1) #warning "You need at least one signing algorithm." #endif @@ -6427,11 +6373,11 @@ int SendKexInit(WOLFSSH* ssh) int SendKexDhReply(WOLFSSH* ssh) { /* This function and DoKexDhReply() are unwieldy and in need of refactoring. */ -#ifndef NO_DH - const byte* primeGroup = dhPrimeGroup14; - word32 primeGroupSz = dhPrimeGroup14Sz; - const byte* generator = dhGenerator; - word32 generatorSz = dhGeneratorSz; +#ifndef WOLFSSH_NO_DH + const byte* primeGroup = NULL; + word32 primeGroupSz = 0; + const byte* generator = NULL; + word32 generatorSz = 0; #endif byte useEcc = 0; @@ -6495,28 +6441,49 @@ int SendKexDhReply(WOLFSSH* ssh) sigKeyBlock.nameSz = (word32)strlen(sigKeyBlock.name); switch (ssh->handshake->kexId) { -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GROUP1_SHA1 case ID_DH_GROUP1_SHA1: primeGroup = dhPrimeGroup1; primeGroupSz = dhPrimeGroup1Sz; + generator = dhGenerator; + generatorSz = dhGeneratorSz; break; - +#endif +#ifndef WOLFSSH_NO_DH_GROUP14_SHA1 case ID_DH_GROUP14_SHA1: - /* This is the default case. */ + primeGroup = dhPrimeGroup14; + primeGroupSz = dhPrimeGroup14Sz; + generator = dhGenerator; + generatorSz = dhGeneratorSz; break; - +#endif +#ifndef WOLFSSH_NO_DH_GEX_SHA256 case ID_DH_GEX_SHA256: + primeGroup = dhPrimeGroup14; + primeGroupSz = dhPrimeGroup14Sz; + generator = dhGenerator; + generatorSz = dhGeneratorSz; msgId = MSGID_KEXDH_GEX_REPLY; break; #endif - +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 case ID_ECDH_SHA2_NISTP256: + useEcc = 1; + msgId = MSGID_KEXDH_REPLY; + break; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384 case ID_ECDH_SHA2_NISTP384: + useEcc = 1; + msgId = MSGID_KEXDH_REPLY; + break; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521 case ID_ECDH_SHA2_NISTP521: useEcc = 1; msgId = MSGID_KEXDH_REPLY; break; - +#endif default: ret = WS_INVALID_ALGO_ID; } @@ -6691,7 +6658,7 @@ int SendKexDhReply(WOLFSSH* ssh) sigKeyBlock.sk.ecc.q, sigKeyBlock.sk.ecc.qSz); } -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GEX_SHA256 /* If using DH-GEX include the GEX specific values. */ if (ssh->handshake->kexId == ID_DH_GEX_SHA256) { byte primeGroupPad = 0, generatorPad = 0; @@ -6783,7 +6750,7 @@ int SendKexDhReply(WOLFSSH* ssh) /* Or make the server's ECDH private value, and the shared secret K. */ if (ret == 0) { if (!useEcc) { -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH DhKey privKey; byte y[MAX_KEX_KEY_SZ]; word32 ySz = sizeof(y); @@ -6910,7 +6877,7 @@ int SendKexDhReply(WOLFSSH* ssh) if (ret == WS_SUCCESS) { if (sigKeyBlock.useRsa) { -#ifndef NO_RSA +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 byte encSig[MAX_ENCODED_SIG_SZ]; word32 encSigSz; @@ -6975,7 +6942,7 @@ int SendKexDhReply(WOLFSSH* ssh) } if (sigKeyBlock.useRsa) { -#ifndef NO_RSA +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 wc_FreeRsaKey(&sigKeyBlock.sk.rsa.key); #endif } @@ -7010,7 +6977,7 @@ int SendKexDhReply(WOLFSSH* ssh) WMEMCPY(output + idx, sigKeyBlock.name, sigKeyBlock.nameSz); idx += sigKeyBlock.nameSz; if (sigKeyBlock.useRsa) { -#ifndef NO_RSA +#ifndef WOLFSSH_NO_SSH_RSA_SHA1 c32toa(sigKeyBlock.sk.rsa.eSz + sigKeyBlock.sk.rsa.ePad, output + idx); idx += LENGTH_SZ; @@ -7151,7 +7118,7 @@ int SendNewKeys(WOLFSSH* ssh) } -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GEX_SHA256 int SendKexDhGexRequest(WOLFSSH* ssh) { byte* output; @@ -7275,11 +7242,11 @@ int SendKexDhInit(WOLFSSH* ssh) byte* output; word32 idx = 0; word32 payloadSz; -#ifndef NO_DH - const byte* primeGroup = dhPrimeGroup14; - word32 primeGroupSz = dhPrimeGroup14Sz; - const byte* generator = dhGenerator; - word32 generatorSz = dhGeneratorSz; +#ifndef WOLFSSH_NO_DH + const byte* primeGroup = NULL; + word32 primeGroupSz = 0; + const byte* generator = NULL; + word32 generatorSz = 0; #endif int ret = WS_SUCCESS; byte msgId = MSGID_KEXDH_INIT; @@ -7290,16 +7257,23 @@ int SendKexDhInit(WOLFSSH* ssh) WLOG(WS_LOG_DEBUG, "Entering SendKexDhInit()"); switch (ssh->handshake->kexId) { -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GROUP1_SHA1 case ID_DH_GROUP1_SHA1: primeGroup = dhPrimeGroup1; primeGroupSz = dhPrimeGroup1Sz; + generator = dhGenerator; + generatorSz = dhGeneratorSz; break; - +#endif +#ifndef WOLFSSH_NO_DH_GROUP14_SHA1 case ID_DH_GROUP14_SHA1: - /* This is the default case. */ + primeGroup = dhPrimeGroup14; + primeGroupSz = dhPrimeGroup14Sz; + generator = dhGenerator; + generatorSz = dhGeneratorSz; break; - +#endif +#ifndef WOLFSSH_NO_DH_GEX_SHA256 case ID_DH_GEX_SHA256: primeGroup = ssh->handshake->primeGroup; primeGroupSz = ssh->handshake->primeGroupSz; @@ -7308,14 +7282,24 @@ int SendKexDhInit(WOLFSSH* ssh) msgId = MSGID_KEXDH_GEX_INIT; break; #endif - +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256 case ID_ECDH_SHA2_NISTP256: + ssh->handshake->useEcc = 1; + msgId = MSGID_KEXECDH_INIT; + break; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384 case ID_ECDH_SHA2_NISTP384: + ssh->handshake->useEcc = 1; + msgId = MSGID_KEXECDH_INIT; + break; +#endif +#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521 case ID_ECDH_SHA2_NISTP521: ssh->handshake->useEcc = 1; msgId = MSGID_KEXECDH_INIT; break; - +#endif default: WLOG(WS_LOG_DEBUG, "Invalid algo: %u", ssh->handshake->kexId); ret = WS_INVALID_ALGO_ID; @@ -7324,7 +7308,7 @@ int SendKexDhInit(WOLFSSH* ssh) if (ret == WS_SUCCESS) { if (!ssh->handshake->useEcc) { -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH DhKey* privKey = &ssh->handshake->privKey.dh; ret = wc_InitDhKey(privKey); diff --git a/wolfssh/internal.h b/wolfssh/internal.h index ca92680..28c896d 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -62,6 +62,121 @@ extern "C" { #endif +/* Check options set by wolfSSL and set wolfSSH options as appropriate. If + * the derived options and any override options leave wolfSSH without + * at least one algorithm to use, throw an error. */ + +#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(WOLFSSH_NO_HMAC_SHA1) && \ + defined(WOLFSSH_NO_HMAC_SHA1_96) && \ + defined(WOLFSSH_NO_HMAC_SHA2_256) + #error "You need at least one MAC algorithm." +#endif + + +#ifdef WOLFSSH_NO_DH + #undef WOLFSSH_NO_DH_GROUP1_SHA1 + #define WOLFSSH_NO_DH_GROUP1_SHA1 + #undef WOLFSSH_NO_DH_GROUP14_SHA1 + #define WOLFSSH_NO_DH_GROUP14_SHA1 + #undef WOLFSSH_NO_DH_GEX_SHA256 + #define WOLFSSH_NO_DH_GEX_SHA256 +#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) || defined(NO_ECC256) + #define WOLFSSH_NO_ECDH_SHA2_NISTP256 +#endif +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) || !defined(HAVE_ECC384) + #define WOLFSSH_NO_ECDH_SHA2_NISTP384 +#endif +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) || !defined(HAVE_ECC521) + #define WOLFSSH_NO_ECDH_SHA2_NISTP521 +#endif +#if !defined(HAVE_ED25519) || defined(NO_SHA256) || 1 + /* ED25519 isn't supported yet. Force disabled. */ + #define WOLFSSH_NO_ECDH_SHA2_ED25519 +#endif + +#if defined(WOLFSSH_NO_DH_GROUP1_SHA1) && \ + defined(WOLFSSH_NO_DH_GROUP14_SHA1) && \ + defined(WOLFSSH_NO_DH_GEX_SHA256) && \ + defined(WOLFSSH_NO_ECDH_SHA2_NISTP256) && \ + defined(WOLFSSH_NO_ECDH_SHA2_NISTP384) && \ + defined(WOLFSSH_NO_ECDH_SHA2_NISTP521) && \ + defined(WOLFSSH_NO_ECDH_SHA2_ED25519) + #error "You need at least one key agreement algorithm." +#endif + +#if defined(WOLFSSH_NO_DH_GROUP1_SHA1) && \ + defined(WOLFSSH_NO_DH_GROUP14_SHA1) && \ + defined(WOLFSSH_NO_DH_GEX_SHA256) + #define WOLFSSH_NO_DH +#endif + + +#if defined(NO_RSA) || defined(NO_SHA) + #define WOLFSSH_NO_SSH_RSA_SHA1 +#endif +#if !defined(HAVE_ECC) || defined(NO_SHA256) || defined(NO_ECC256) + #define WOLFSSH_NO_ECDSA_SHA2_NISTP256 +#endif +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384) || !defined(HAVE_ECC384) + #define WOLFSSH_NO_ECDSA_SHA2_NISTP384 +#endif +#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512) || !defined(HAVE_ECC521) + #define WOLFSSH_NO_ECDSA_SHA2_NISTP521 +#endif +#if defined(WOLFSSH_NO_SHA_RSA_SHA1) && \ + defined(WOLFSSH_NO_ECDSA_SHA2_NISTP256) && \ + defined(WOLFSSH_NO_ECDSA_SHA2_NISTP384) && \ + defined(WOLFSSH_NO_ECDSA_SHA2_NISTP521) + #error "You need at least one signing algorithm." +#endif + + +#ifdef WOLFSSH_NO_AEAD + #undef WOLFSSH_NO_AES_GCM + #define WOLFSSH_NO_AES_GCM +#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_CBC) && \ + defined(WOLFSSH_NO_AES_CTR) && \ + defined(WOLFSSH_NO_AES_GCM) + #error "You need at least one encryption algorithm." +#endif + +#if defined(WOLFSSH_NO_AES_GCM) + #define WOLFSSH_NO_AEAD +#endif + + WOLFSSH_LOCAL const char* GetErrorString(int);