From 39f30e25a407f50d474bdf2e94513eb7afb1c27c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 4 Sep 2020 15:28:25 -0700 Subject: [PATCH 1/2] Optional RSA 1. If RSA is disabled in the wolfCrypt build, the RSA related code in wolfSSH shall be disabled. 2. Examples will force themselves to use ECC if RSA is disabled. --- examples/client/client.c | 4 +++ examples/echoserver/echoserver.c | 6 ++++ examples/server/server.c | 5 +++ examples/sftpclient/sftpclient.c | 5 +++ src/agent.c | 6 ++++ src/internal.c | 62 +++++++++++++++++++++++++++----- src/keygen.c | 9 +++++ src/ssh.c | 9 +++-- tests/api.c | 7 +++- 9 files changed, 102 insertions(+), 11 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index c1e5752..e63baa9 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -869,6 +869,10 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) if (username == NULL) err_sys("client requires a username parameter."); +#ifdef NO_RSA + userEcc = 1; +#endif + #ifdef SINGLE_THREADED if (keepOpen) err_sys("Threading needed for terminal session\n"); diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index c57a17c..fb4d598 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -1602,6 +1602,12 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) } #endif +#ifdef NO_RSA + /* If wolfCrypt isn't built with RSA, force ECC on. */ + userEcc = 1; + peerEcc = 1; +#endif + if (wolfSSH_Init() != WS_SUCCESS) { fprintf(stderr, "Couldn't initialize wolfSSH.\n"); exit(EXIT_FAILURE); diff --git a/examples/server/server.c b/examples/server/server.c index e0bf1bd..20ee2b6 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -660,6 +660,11 @@ THREAD_RETURN WOLFSSH_THREAD server_test(void* args) } myoptind = 0; /* reset for test cases */ +#ifdef NO_RSA + /* If wolfCrypt isn't built with RSA, force ECC on. */ + useEcc = 1; +#endif + if (wolfSSH_Init() != WS_SUCCESS) { fprintf(stderr, "Couldn't initialize wolfSSH.\n"); exit(EXIT_FAILURE); diff --git a/examples/sftpclient/sftpclient.c b/examples/sftpclient/sftpclient.c index 9c90075..c980f04 100644 --- a/examples/sftpclient/sftpclient.c +++ b/examples/sftpclient/sftpclient.c @@ -1329,6 +1329,11 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args) if (username == NULL) err_sys("client requires a username parameter."); +#ifdef NO_RSA + userEcc = 1; + /* peerEcc = 1; */ +#endif + if (autopilot != AUTOPILOT_OFF) { if (apLocal == NULL || apRemote == NULL) { err_sys("Options -G and -g require both -l and -r."); diff --git a/src/agent.c b/src/agent.c index 28e4d80..59a6774 100644 --- a/src/agent.c +++ b/src/agent.c @@ -379,6 +379,7 @@ static int PostUnlock(WOLFSSH_AGENT_CTX* agent, } +#ifndef NO_RSA static int PostAddRsaId(WOLFSSH_AGENT_CTX* agent, byte keyType, byte* key, word32 keySz, word32 nSz, word32 eSz, word32 dSz, @@ -457,6 +458,7 @@ static int PostAddRsaId(WOLFSSH_AGENT_CTX* agent, WLOG_LEAVE(ret); return ret; } +#endif static int PostAddEcdsaId(WOLFSSH_AGENT_CTX* agent, @@ -667,6 +669,7 @@ static int PostSignRequest(WOLFSSH_AGENT_CTX* agent, int sigSz = sizeof(sig); if (cur->keyType == ID_SSH_RSA) { +#ifndef NO_RSA WOLFSSH_AGENT_KEY_RSA* key; RsaKey rsa; byte encSig[MAX_ENCODED_SIG_SZ]; @@ -708,6 +711,7 @@ static int PostSignRequest(WOLFSSH_AGENT_CTX* agent, wc_FreeRsaKey(&rsa); if (ret != 0) ret = WS_RSA_E; +#endif } else if (cur->keyType == ID_ECDSA_SHA2_NISTP256) { WOLFSSH_AGENT_KEY_ECDSA* key; @@ -942,6 +946,7 @@ static int DoAddIdentity(WOLFSSH_AGENT_CTX* agent, begin += sz; if (keyType == ID_SSH_RSA) { +#ifndef NO_RSA byte* key; byte* scratch; word32 keySz, nSz, eSz, dSz, iqmpSz, pSz, qSz, commentSz; @@ -983,6 +988,7 @@ static int DoAddIdentity(WOLFSSH_AGENT_CTX* agent, ret = PostAddRsaId(agent, keyType, key, keySz, nSz, eSz, dSz, iqmpSz, pSz, qSz, commentSz); } +#endif } else if (keyType == ID_ECDSA_SHA2_NISTP256 || keyType == ID_ECDSA_SHA2_NISTP384 || diff --git a/src/internal.c b/src/internal.c index 6dac8a7..8f11a9d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -679,12 +679,15 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx, if (type == BUFTYPE_PRIVKEY && format != WOLFSSH_FORMAT_RAW) { /* Check RSA key */ union { +#ifndef NO_RSA RsaKey rsa; +#endif ecc_key ecc; } key; word32 scratch = 0; int ret; +#ifndef NO_RSA if (wc_InitRsaKey(&key.rsa, NULL) < 0) return WS_RSA_E; @@ -692,6 +695,7 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx, wc_FreeRsaKey(&key.rsa); if (ret < 0) { +#endif /* Couldn't decode as RSA key. Try decoding as ECC key. */ scratch = 0; if (wc_ecc_init_ex(&key.ecc, ctx->heap, INVALID_DEVID) != 0) @@ -714,7 +718,9 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx, if (ret != 0) return WS_BAD_FILE_E; +#ifndef NO_RSA } +#endif } return WS_SUCCESS; @@ -2534,9 +2540,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) byte useRsa; word32 keySz; union { +#ifndef NO_RSA struct { RsaKey key; } rsa; +#endif struct { ecc_key key; } ecc; @@ -2733,6 +2741,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) sigKeyBlock.useRsa = ssh->handshake->pubKeyId == ID_SSH_RSA; if (sigKeyBlock.useRsa) { +#ifndef NO_RSA byte* e; word32 eSz; byte* n; @@ -2767,6 +2776,9 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) sigKeyBlock.keySz = sizeof(sigKeyBlock.sk.rsa.key); else ret = WS_RSA_E; +#else + (void)tmpIdx; +#endif } else { byte* q; @@ -2901,6 +2913,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) } if (ret == WS_SUCCESS) { if (sigKeyBlock.useRsa) { +#ifndef NO_RSA sig = sig + begin; /* In the fuzz, sigSz ends up 1 and it has issues. */ sigSz = scratch; @@ -2929,6 +2942,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) ret = WS_RSA_E; } } +#endif } else { byte* r; @@ -2966,8 +2980,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) } } - if (sigKeyBlock.useRsa) + if (sigKeyBlock.useRsa) { +#ifndef NO_RSA wc_FreeRsaKey(&sigKeyBlock.sk.rsa.key); +#endif + } else wc_ecc_free(&sigKeyBlock.sk.ecc.key); } @@ -3558,7 +3575,7 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData, return ret; } - +#ifndef NO_RSA /* Utility for DoUserAuthRequestPublicKey() */ /* returns negative for error, positive is size of digest. */ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk, @@ -3678,6 +3695,7 @@ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk, WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestRsa(), ret = %d", ret); return ret; } +#endif /* Utility for DoUserAuthRequestPublicKey() */ @@ -3962,9 +3980,12 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, } if (ret == WS_SUCCESS) { - if (pkTypeId == ID_SSH_RSA) + if (pkTypeId == ID_SSH_RSA) { +#ifndef NO_RSA ret = DoUserAuthRequestRsa(ssh, pk, hashId, digest, digestSz); +#endif + } else if (pkTypeId == ID_ECDSA_SHA2_NISTP256 || pkTypeId == ID_ECDSA_SHA2_NISTP384 || pkTypeId == ID_ECDSA_SHA2_NISTP521) @@ -6056,6 +6077,7 @@ int SendKexDhReply(WOLFSSH* ssh) const char *name; word32 nameSz; union { +#ifndef NO_RSA struct { RsaKey key; byte e[257]; @@ -6065,6 +6087,7 @@ int SendKexDhReply(WOLFSSH* ssh) word32 nSz; byte nPad; } rsa; +#endif struct { ecc_key key; word32 keyBlobSz; @@ -6134,6 +6157,7 @@ int SendKexDhReply(WOLFSSH* ssh) * either be RSA or ECDSA public key blob. */ if (ret == WS_SUCCESS) { if (sigKeyBlock.useRsa) { +#ifndef NO_RSA /* Decode the user-configured RSA private key. */ sigKeyBlock.sk.rsa.eSz = sizeof(sigKeyBlock.sk.rsa.e); sigKeyBlock.sk.rsa.nSz = sizeof(sigKeyBlock.sk.rsa.n); @@ -6223,6 +6247,7 @@ int SendKexDhReply(WOLFSSH* ssh) enmhashId, sigKeyBlock.sk.rsa.n, sigKeyBlock.sk.rsa.nSz); +#endif } else { sigKeyBlock.sk.ecc.primeName = @@ -6511,6 +6536,7 @@ int SendKexDhReply(WOLFSSH* ssh) if (ret == WS_SUCCESS) { if (sigKeyBlock.useRsa) { +#ifndef NO_RSA byte encSig[MAX_ENCODED_SIG_SZ]; word32 encSigSz; @@ -6530,6 +6556,7 @@ int SendKexDhReply(WOLFSSH* ssh) ret = WS_RSA_E; } } +#endif } else { WLOG(WS_LOG_INFO, "Signing hash with ECDSA."); @@ -6573,10 +6600,14 @@ int SendKexDhReply(WOLFSSH* ssh) } } - if (sigKeyBlock.useRsa) + if (sigKeyBlock.useRsa) { +#ifndef NO_RSA wc_FreeRsaKey(&sigKeyBlock.sk.rsa.key); - else +#endif + } + else { wc_ecc_free(&sigKeyBlock.sk.ecc.key); + } sigBlockSz = (LENGTH_SZ * 2) + sigKeyBlock.nameSz + sigSz; @@ -6605,6 +6636,7 @@ int SendKexDhReply(WOLFSSH* ssh) WMEMCPY(output + idx, sigKeyBlock.name, sigKeyBlock.nameSz); idx += sigKeyBlock.nameSz; if (sigKeyBlock.useRsa) { +#ifndef NO_RSA c32toa(sigKeyBlock.sk.rsa.eSz + sigKeyBlock.sk.rsa.ePad, output + idx); idx += LENGTH_SZ; @@ -6617,6 +6649,7 @@ int SendKexDhReply(WOLFSSH* ssh) if (sigKeyBlock.sk.rsa.nPad) output[idx++] = 0; WMEMCPY(output + idx, sigKeyBlock.sk.rsa.n, sigKeyBlock.sk.rsa.nSz); idx += sigKeyBlock.sk.rsa.nSz; +#endif } else { c32toa(sigKeyBlock.sk.ecc.primeNameSz, output + idx); @@ -7282,6 +7315,7 @@ typedef struct WS_KeySignature { const char *name; word32 nameSz; union { +#ifndef NO_RSA struct { RsaKey key; byte e[256]; @@ -7291,6 +7325,7 @@ typedef struct WS_KeySignature { word32 nSz; byte nPad; } rsa; +#endif struct { ecc_key key; word32 keyBlobSz; @@ -7352,6 +7387,7 @@ static int BuildUserAuthRequestPassword(WOLFSSH* ssh, } +#ifndef NO_RSA static int PrepareUserAuthRequestRsa(WOLFSSH* ssh, word32* payloadSz, const WS_UserAuthData* authData, WS_KeySignature* keySig) { @@ -7504,6 +7540,7 @@ static int BuildUserAuthRequestRsa(WOLFSSH* ssh, return ret; } +#endif static int PrepareUserAuthRequestEcc(WOLFSSH* ssh, word32* payloadSz, @@ -7725,8 +7762,11 @@ static int PrepareUserAuthRequestPublicKey(WOLFSSH* ssh, word32* payloadSz, authData->sf.publicKey.publicKeySz; } - if (keySig->keySigId == ID_SSH_RSA) + if (keySig->keySigId == ID_SSH_RSA) { +#ifndef NO_RSA ret = PrepareUserAuthRequestRsa(ssh, payloadSz, authData, keySig); +#endif + } else if (keySig->keySigId == ID_ECDSA_SHA2_NISTP256 || keySig->keySigId == ID_ECDSA_SHA2_NISTP384 || keySig->keySigId == ID_ECDSA_SHA2_NISTP521) @@ -7766,9 +7806,12 @@ static int BuildUserAuthRequestPublicKey(WOLFSSH* ssh, begin += pk->publicKeySz; if (pk->hasSignature) { - if (keySig->keySigId == ID_SSH_RSA) + if (keySig->keySigId == ID_SSH_RSA) { +#ifndef NO_RSA ret = BuildUserAuthRequestRsa(ssh, output, &begin, authData, sigStart, sigStartIdx, keySig); +#endif + } else if (keySig->keySigId == ID_ECDSA_SHA2_NISTP256 || keySig->keySigId == ID_ECDSA_SHA2_NISTP384 || keySig->keySigId == ID_ECDSA_SHA2_NISTP521) @@ -7789,8 +7832,11 @@ static int BuildUserAuthRequestPublicKey(WOLFSSH* ssh, static void CleanupUserAuthRequestPublicKey(WS_KeySignature* keySig) { if (keySig != NULL) { - if (keySig->keySigId == ID_SSH_RSA) + if (keySig->keySigId == ID_SSH_RSA) { +#ifndef NO_RSA wc_FreeRsaKey(&keySig->ks.rsa.key); +#endif + } else wc_ecc_free(&keySig->ks.ecc.key); } diff --git a/src/keygen.c b/src/keygen.c index 589bc24..9beaf77 100644 --- a/src/keygen.c +++ b/src/keygen.c @@ -57,6 +57,8 @@ int wolfSSH_MakeRsaKey(byte* out, word32 outSz, word32 size, word32 e) { +#ifndef NO_RSA + int ret = WS_SUCCESS; WC_RNG rng; @@ -105,6 +107,13 @@ int wolfSSH_MakeRsaKey(byte* out, word32 outSz, WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_MakeRsaKey(), ret = %d", ret); return ret; +#else + (void)out; + (void)outSz; + (void)size; + (void)e; + return WS_NOT_COMPILED; +#endif } diff --git a/src/ssh.c b/src/ssh.c index 985d24a..eee08c3 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -1441,7 +1441,9 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format, else if (format == WOLFSSH_FORMAT_ASN1) { byte* newKey; union { - RsaKey rsa; + #ifndef NO_RSA + RsaKey rsa; + #endif ecc_key ecc; } testKey; word32 scratch = 0; @@ -1459,7 +1461,7 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format, } *outSz = inSz; WMEMCPY(newKey, in, inSz); - +#ifndef NO_RSA /* TODO: This is copied and modified from a function in src/internal.c. This and that code should be combined into a single function. */ if (wc_InitRsaKey(&testKey.rsa, heap) < 0) @@ -1474,6 +1476,7 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format, *outTypeSz = (word32)WSTRLEN((const char*)*outType); } else { +#endif /* Couldn't decode as RSA testKey. Try decoding as ECC testKey. */ scratch = 0; if (wc_ecc_init_ex(&testKey.ecc, heap, INVALID_DEVID) != 0) @@ -1489,7 +1492,9 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format, } else return WS_BAD_FILE_E; +#ifndef NO_RSA } +#endif } else ret = WS_ERROR; diff --git a/tests/api.c b/tests/api.c index 39ed412..3e6b63d 100644 --- a/tests/api.c +++ b/tests/api.c @@ -570,9 +570,10 @@ static void test_wolfSSH_CTX_UsePrivateKey_buffer(void) AssertNotNull(ctx->privateKey); AssertIntNE(0, ctx->privateKeySz); AssertIntEQ(ECC_SECP256R1, ctx->useEcc); + +#ifndef NO_RSA lastKey = ctx->privateKey; lastKeySz = ctx->privateKeySz; - AssertIntEQ(WS_SUCCESS, wolfSSH_CTX_UsePrivateKey_buffer(ctx, rsaKey, rsaKeySz, TEST_GOOD_FORMAT_ASN1)); @@ -581,6 +582,10 @@ static void test_wolfSSH_CTX_UsePrivateKey_buffer(void) AssertIntEQ(0, ctx->useEcc); AssertIntEQ(0, (lastKey == ctx->privateKey)); AssertIntNE(lastKeySz, ctx->privateKeySz); +#else + (void)lastKey; + (void)lastKeySz; +#endif wolfSSH_CTX_free(ctx); FreeBins(eccKey, rsaKey, NULL, NULL); From 9fced1fe7dd9adc0e9b36265eb790e2bbaaf8075 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Sun, 6 Sep 2020 22:45:26 -0700 Subject: [PATCH 2/2] Optional DH 1. If DH is disabled in the wolfCrypt build, the DH related code in wolfSSH shall be disabled. --- src/internal.c | 43 ++++++++++++++++++++++++++++++++++++++----- src/ssh.c | 5 ++++- wolfssh/internal.h | 4 ++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/internal.c b/src/internal.c index 8f11a9d..942c7b9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -33,7 +33,9 @@ #include #include #include -#include +#ifndef NO_DH + #include +#endif #include #include #include @@ -365,9 +367,11 @@ static HandshakeInfo* HandshakeInfoNew(void* heap) newHs->macId = ID_NONE; newHs->blockSz = MIN_BLOCK_SZ; newHs->hashId = WC_HASH_TYPE_NONE; +#ifndef NO_DH newHs->dhGexMinSz = WOLFSSH_DEFAULT_GEXDH_MIN; newHs->dhGexPreferredSz = WOLFSSH_DEFAULT_GEXDH_PREFERRED; newHs->dhGexMaxSz = WOLFSSH_DEFAULT_GEXDH_MAX; +#endif } return newHs; @@ -381,8 +385,10 @@ static void HandshakeInfoFree(HandshakeInfo* hs, void* heap) WLOG(WS_LOG_DEBUG, "Entering HandshakeInfoFree()"); if (hs) { WFREE(hs->kexInit, heap, DYNTYPE_STRING); +#ifndef NO_DH WFREE(hs->primeGroup, heap, DYNTYPE_MPINT); WFREE(hs->generator, heap, DYNTYPE_MPINT); +#endif ForceZero(hs, sizeof(HandshakeInfo)); WFREE(hs, heap, DYNTYPE_HS); } @@ -2400,7 +2406,7 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) return ret; } - +#ifndef NO_DH static const byte dhGenerator[] = { 2 }; static const byte dhPrimeGroup1[] = { /* SSH DH Group 1 (Oakley Group 2, 1024-bit MODP Group, RFC 2409) */ @@ -2460,6 +2466,7 @@ static const byte dhPrimeGroup14[] = { static const word32 dhGeneratorSz = sizeof(dhGenerator); static const word32 dhPrimeGroup1Sz = sizeof(dhPrimeGroup1); static const word32 dhPrimeGroup14Sz = sizeof(dhPrimeGroup14); +#endif static int DoKexDhInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) @@ -2608,6 +2615,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) if (ret == WS_SUCCESS) begin += pubKeySz; +#ifndef NO_DH /* 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; @@ -2688,6 +2696,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) ssh->handshake->generator, ssh->handshake->generatorSz); } +#endif /* Hash in the size of the client's DH e-value (ECDH Q-value). */ if (ret == 0) { @@ -2829,12 +2838,14 @@ 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 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); +#endif } else { ecc_key key; @@ -3075,6 +3086,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) } +#ifndef NO_DH static int DoKexDhGexRequest(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { @@ -3163,6 +3175,7 @@ static int DoKexDhGexGroup(WOLFSSH* ssh, return ret; } +#endif static int DoIgnore(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) @@ -4884,7 +4897,7 @@ static int DoPacket(WOLFSSH* ssh) byte padSz; byte msg; word32 payloadIdx = 0; - int ret; + int ret = WS_SUCCESS; WLOG(WS_LOG_DEBUG, "DoPacket sequence number: %d", ssh->peerSeq); @@ -4963,8 +4976,10 @@ static int DoPacket(WOLFSSH* ssh) } if (ssh->handshake->kexId == ID_DH_GEX_SHA256) { +#ifndef NO_DH WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_GROUP"); ret = DoKexDhGexGroup(ssh, buf + idx, payloadSz, &payloadIdx); +#endif } else { WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_REPLY"); @@ -4972,10 +4987,12 @@ static int DoPacket(WOLFSSH* ssh) } break; +#ifndef NO_DH case MSGID_KEXDH_GEX_REQUEST: WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_REQUEST"); ret = DoKexDhGexRequest(ssh, buf + idx, payloadSz, &payloadIdx); break; +#endif case MSGID_KEXDH_GEX_INIT: WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_INIT"); @@ -5908,8 +5925,9 @@ static const char cannedKexAlgoNames[] = "," #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, " @@ -6060,10 +6078,12 @@ 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; +#endif byte useEcc = 0; byte f[257]; @@ -6126,6 +6146,7 @@ int SendKexDhReply(WOLFSSH* ssh) sigKeyBlock.nameSz = (word32)strlen(sigKeyBlock.name); switch (ssh->handshake->kexId) { +#ifndef NO_DH case ID_DH_GROUP1_SHA1: primeGroup = dhPrimeGroup1; primeGroupSz = dhPrimeGroup1Sz; @@ -6138,6 +6159,7 @@ int SendKexDhReply(WOLFSSH* ssh) case ID_DH_GEX_SHA256: msgId = MSGID_KEXDH_GEX_REPLY; break; +#endif case ID_ECDH_SHA2_NISTP256: case ID_ECDH_SHA2_NISTP384: @@ -6320,7 +6342,7 @@ int SendKexDhReply(WOLFSSH* ssh) sigKeyBlock.sk.ecc.q, sigKeyBlock.sk.ecc.qSz); } - +#ifndef NO_DH /* If using DH-GEX include the GEX specific values. */ if (ssh->handshake->kexId == ID_DH_GEX_SHA256) { byte primeGroupPad = 0, generatorPad = 0; @@ -6395,6 +6417,7 @@ int SendKexDhReply(WOLFSSH* ssh) enmhashId, generator, generatorSz); } +#endif /* Hash in the size of the client's DH e-value (ECDH Q-value). */ if (ret == 0) { @@ -6411,6 +6434,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 DhKey privKey; byte y[MAX_KEX_KEY_SZ]; word32 ySz = sizeof(y); @@ -6427,6 +6451,7 @@ int SendKexDhReply(WOLFSSH* ssh) ssh->handshake->e, ssh->handshake->eSz); ForceZero(y, ySz); wc_FreeDhKey(&privKey); +#endif } else { ecc_key pubKey; @@ -6773,6 +6798,7 @@ int SendNewKeys(WOLFSSH* ssh) } +#ifndef NO_DH int SendKexDhGexRequest(WOLFSSH* ssh) { byte* output; @@ -6888,6 +6914,7 @@ int SendKexDhGexGroup(WOLFSSH* ssh) WLOG(WS_LOG_DEBUG, "Leaving SendKexDhGexGroup(), ret = %d", ret); return ret; } +#endif int SendKexDhInit(WOLFSSH* ssh) @@ -6895,10 +6922,12 @@ 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; +#endif int ret = WS_SUCCESS; byte msgId = MSGID_KEXDH_INIT; byte e[MAX_KEX_KEY_SZ+1]; /* plus 1 in case of padding. */ @@ -6908,6 +6937,7 @@ int SendKexDhInit(WOLFSSH* ssh) WLOG(WS_LOG_DEBUG, "Entering SendKexDhInit()"); switch (ssh->handshake->kexId) { +#ifndef NO_DH case ID_DH_GROUP1_SHA1: primeGroup = dhPrimeGroup1; primeGroupSz = dhPrimeGroup1Sz; @@ -6924,6 +6954,7 @@ int SendKexDhInit(WOLFSSH* ssh) generatorSz = ssh->handshake->generatorSz; msgId = MSGID_KEXDH_GEX_INIT; break; +#endif case ID_ECDH_SHA2_NISTP256: case ID_ECDH_SHA2_NISTP384: @@ -6940,6 +6971,7 @@ int SendKexDhInit(WOLFSSH* ssh) if (ret == WS_SUCCESS) { if (!ssh->handshake->useEcc) { +#ifndef NO_DH DhKey* privKey = &ssh->handshake->privKey.dh; ret = wc_InitDhKey(privKey); @@ -6951,6 +6983,7 @@ int SendKexDhInit(WOLFSSH* ssh) ssh->handshake->x, &ssh->handshake->xSz, e, &eSz); +#endif } else { ecc_key* privKey = &ssh->handshake->privKey.ecc; diff --git a/src/ssh.c b/src/ssh.c index eee08c3..2a032ef 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -722,8 +722,11 @@ int wolfSSH_connect(WOLFSSH* ssh) return WS_FATAL_ERROR; } - if (ssh->handshake->kexId == ID_DH_GEX_SHA256) + if (ssh->handshake->kexId == ID_DH_GEX_SHA256) { +#ifndef NO_DH ssh->error = SendKexDhGexRequest(ssh); +#endif + } else ssh->error = SendKexDhInit(ssh); if (ssh->error < WS_SUCCESS) { diff --git a/wolfssh/internal.h b/wolfssh/internal.h index 795ce34..7ee3f2d 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -270,6 +270,7 @@ typedef struct HandshakeInfo { byte* kexInit; word32 kexInitSz; +#ifndef NO_DH word32 dhGexMinSz; word32 dhGexPreferredSz; word32 dhGexMaxSz; @@ -277,10 +278,13 @@ typedef struct HandshakeInfo { word32 primeGroupSz; byte* generator; word32 generatorSz; +#endif byte useEcc; union { +#ifndef NO_DH DhKey dh; +#endif ecc_key ecc; } privKey; } HandshakeInfo;