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 { diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 823053d..d476958 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 */ @@ -1215,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" @@ -1222,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" @@ -1237,6 +1258,7 @@ static const char samplePublicKeyRsaBuffer[] = "uNZl/30Mczs73N3MBzi6J1oPo7sFlqzB6ecBjK2Kpjus4Y1rYFphJnUxtKvB0s+hoaadru" "biE57dK6BrH5iZwVLTQKux31uCJLPhiktI3iLbdlGZEctJkTasfVSsUizwVIyRjhVKmbdI" "RGwkU38D043AR1h0mUoGCPIKuqcFMf gretel\n"; +#endif static const char sampleNoneBuffer[] = "holmes\n" @@ -1637,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; @@ -1657,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 1e76ad6..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 @@ -57,6 +57,62 @@ 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. + 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. */ @@ -367,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; @@ -385,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 @@ -937,31 +993,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 +1939,17 @@ static int GetNameList(byte* idList, word32* idListSz, } static const byte cannedEncAlgo[] = { -#ifdef HAVE_AESGCM - ID_AES128_GCM, +#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, @@ -1879,26 +1961,47 @@ static const byte cannedMacAlgo[] = { ID_HMAC_SHA1, #endif }; -static const byte cannedKeyAlgoClient[] = {ID_ECDSA_SHA2_NISTP256, ID_SSH_RSA}; -static const byte cannedKeyAlgoRsa[] = {ID_SSH_RSA}; -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 +static const byte cannedKeyAlgoClient[] = { +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521 + ID_ECDSA_SHA2_NISTP521, #endif -#if defined(NO_DH) || defined(NO_SHA256) - #define WOLFSSH_NO_DH_GEX_SHA256 +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384 + ID_ECDSA_SHA2_NISTP384, #endif -#if defined(NO_DH) || defined(NO_SHA) - #define WOLFSSH_NO_DH_GROUP14_SHA1 +#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256 + ID_ECDSA_SHA2_NISTP256, #endif -#if defined(NO_DH) || defined(NO_SHA) - #define WOLFSSH_NO_DH_GROUP1_SHA1 +#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 @@ -1916,10 +2019,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); static const word32 cannedKexAlgoSz = sizeof(cannedKexAlgo); @@ -1960,10 +2059,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 +2080,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 +2101,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 +2134,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 +2191,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_SECP256R1; +#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_SECP384R1; +#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 +2222,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 +2254,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 +2339,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 +2425,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 +2616,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 +2643,11 @@ 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 + +#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, @@ -2462,9 +2683,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 +2770,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 +2835,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; @@ -2786,10 +3006,12 @@ 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 { +#ifdef HAVE_ECC byte* q; word32 qSz, pubKeyIdx = 0; int primeId; @@ -2833,26 +3055,32 @@ 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) { 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, f, fSz); ForceZero(ssh->handshake->x, ssh->handshake->xSz); wc_FreeDhKey(&ssh->handshake->privKey.dh); +#else + ret = WS_INVALID_ALGO_ID; #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 +3089,13 @@ 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 } } - 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 +3188,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 +3220,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) ret = WS_ECC_E; } } +#endif } } } @@ -2996,8 +3230,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 +3272,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_AES_CBC case ID_AES128_CBC: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-cbc"); ret = wc_AesSetKey(&ssh->decryptCipher.aes, @@ -3044,7 +3281,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) break; #endif -#ifdef WOLFSSL_AES_COUNTER +#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, @@ -3053,7 +3290,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) break; #endif -#ifdef HAVE_AESGCM +#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, @@ -3086,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) { @@ -5008,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 @@ -5019,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); @@ -5155,6 +5392,7 @@ static int DoPacket(WOLFSSH* ssh) } +#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 @@ -5189,6 +5427,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 +5536,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 +5557,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 +5577,7 @@ static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz, wc_HmacFree(&hmac); } break; +#endif case ID_HMAC_SHA2_256: { @@ -5439,6 +5682,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 +5696,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 +5726,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 +5742,7 @@ static INLINE int DecryptAead(WOLFSSH* ssh, byte* plain, return ret; } +#endif int DoReceive(WOLFSSH* ssh) @@ -5599,6 +5844,7 @@ int DoReceive(WOLFSSH* ssh) } } else { +#ifndef WOLFSSH_NO_AEAD ret = DecryptAead(ssh, ssh->inputBuffer.buffer + ssh->inputBuffer.idx + @@ -5619,6 +5865,7 @@ int DoReceive(WOLFSSH* ssh) ssh->error = ret; return WS_FATAL_ERROR; } +#endif } } ssh->processReplyState = PROCESS_PACKET; @@ -5846,6 +6093,7 @@ static int BundlePacket(WOLFSSH* ssh) } else { if (ret == WS_SUCCESS) { +#ifndef WOLFSSH_NO_AEAD idx += paddingSz; ret = EncryptAead(ssh, ssh->outputBuffer.buffer + @@ -5860,6 +6108,9 @@ static int BundlePacket(WOLFSSH* ssh) ssh->packetStartIdx, LENGTH_SZ); idx += ssh->macSz; +#else + ret = WS_INVALID_ALGO_ID; +#endif } } @@ -5889,93 +6140,101 @@ static INLINE void CopyNameList(byte* buf, word32* idx, } static const char cannedEncAlgoNames[] = -#if defined(HAVE_AESGCM) - "aes128-gcm@openssh.com" +#if !defined(WOLFSSH_NO_AES_GCM) + "aes128-gcm@openssh.com," #endif -#if defined(HAVE_AESGCM) && defined(WOLFSSL_AES_COUNTER) - "," +#if !defined(WOLFSSH_NO_AES_CTR) + "aes128-ctr," #endif -#if defined(WOLFSSL_AES_COUNTER) - "aes128-ctr" +#if !defined(WOLFSSH_NO_AES_CBC) + "aes128-cbc," #endif -#if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_COUNTER))\ - && defined(HAVE_AES_CBC) - "," -#endif -#if defined(HAVE_AES_CBC) - "aes128-cbc" -#endif - ; -#if !defined(HAVE_AESGCM) && !defined(WOLFSSL_AES_COUNTER)\ - && !defined(HAVE_AES_CBC) -#warning "You need at least one of AES-GCM, AES-CTR or AES-CBC." + ""; +#if defined(WOLFSSH_NO_AES_GCM) && defined(WOLFSSH_NO_AES_CTR) && \ + defined(WOLFSSH_NO_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 WOLFSSH_NO_ECDSA_SHA2_NISTP521 + "ecdsa-sha2-nistp521," +#endif +#ifndef WOLFSSH_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_SHA1) + #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; @@ -5983,7 +6242,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; @@ -6114,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; @@ -6182,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; } @@ -6378,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; @@ -6470,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); @@ -6597,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; @@ -6662,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 } @@ -6697,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; @@ -6794,21 +7074,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, @@ -6834,7 +7118,7 @@ int SendNewKeys(WOLFSSH* ssh) } -#ifndef NO_DH +#ifndef WOLFSSH_NO_DH_GEX_SHA256 int SendKexDhGexRequest(WOLFSSH* ssh) { byte* output; @@ -6958,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; @@ -6973,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; @@ -6991,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; @@ -7007,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/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; 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}, 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);