Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DH Group 16 and HMAC-SHA2-512 #767

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions examples/echoserver/echoserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -2315,7 +2315,10 @@ static void ShowUsage(void)
#ifdef WOLFSSH_CERTS
printf(" -a <file> load in a root CA certificate file\n");
#endif
printf(" -k set the list of key algos to use\n");
printf(" -k <list> set the comma separated list of key algos to use\n");
printf(" -x <list> set the comma separated list of key exchange algos "
"to use\n");
printf(" -m <list> set the comma separated list of mac algos to use\n");
printf(" -b <num> test user auth would block\n");
}

Expand Down Expand Up @@ -2356,6 +2359,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
word32 threadCount = 0;
const char* keyList = NULL;
const char* kexList = NULL;
const char* macList = NULL;
const char* cipherList = NULL;
ES_HEAP_HINT* heap = NULL;
int multipleConnections = 1;
int userEcc = 0;
Expand All @@ -2378,7 +2384,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
serverArgs->return_code = EXIT_SUCCESS;

if (argc > 0) {
const char* optlist = "?1a:d:efEp:R:Ni:j:I:J:K:P:k:b:";
const char* optlist = "?1a:d:efEp:R:Ni:j:I:J:K:P:k:b:x:m:c:";
myoptind = 0;
while ((ch = mygetopt(argc, argv, optlist)) != -1) {
switch (ch) {
Expand Down Expand Up @@ -2466,6 +2472,18 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
userAuthWouldBlock = atoi(myoptarg);
break;

case 'x':
kexList = myoptarg;
break;

case 'm':
macList = myoptarg;
break;

case 'c':
cipherList = myoptarg;
break;

default:
ShowUsage();
serverArgs->return_code = MY_EX_USAGE;
Expand Down Expand Up @@ -2524,6 +2542,24 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
}
}

if (kexList) {
if (wolfSSH_CTX_SetAlgoListKex(ctx, kexList) != WS_SUCCESS) {
ES_ERROR("Error setting kex list.\n");
}
}

if (macList) {
if (wolfSSH_CTX_SetAlgoListMac(ctx, macList) != WS_SUCCESS) {
ES_ERROR("Error setting mac list.\n");
}
}

if (cipherList) {
if (wolfSSH_CTX_SetAlgoListCipher(ctx, cipherList) != WS_SUCCESS) {
ES_ERROR("Error setting cipher list.\n");
}
}

WMEMSET(&pwMapList, 0, sizeof(pwMapList));
if (serverArgs->user_auth == NULL)
wolfSSH_SetUserAuth(ctx, wsUserAuth);
Expand Down
161 changes: 161 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
WOLFSSH_NO_HMAC_SHA2_256
Set when HMAC or SHA2-256 are disabled. Set to disable HMAC-SHA2-256
support.
WOLFSSH_NO_HMAC_SHA2_512
Set when HMAC or SHA2-512 are disabled. Set to disable HMAC-SHA2-512
support.
WOLFSSH_NO_DH_GROUP1_SHA1
Set when DH or SHA1 are disabled. Set to disable use of DH (Oakley 1) and
SHA1 support.
Expand All @@ -102,6 +105,9 @@
WOLFSSH_NO_DH_GROUP14_SHA256
Set when DH or SHA256 are disabled. Set to disable use of DH (Oakley 14)
and SHA256 support.
WOLFSSH_NO_DH_GROUP16_SHA512
Set when DH or SHA512 are disabled. Set to disable use of DH (Oakley 16)
and SHA512 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.
Expand Down Expand Up @@ -690,6 +696,9 @@ static const char cannedKexAlgoNames[] =
#if !defined(WOLFSSH_NO_DH_GROUP14_SHA256)
"diffie-hellman-group14-sha256,"
#endif
#if !defined(WOLFSSH_NO_DH_GROUP16_SHA512)
"diffie-hellman-group16-sha512,"
#endif
#if !defined(WOLFSSH_NO_DH_GEX_SHA256)
"diffie-hellman-group-exchange-sha256,"
#endif
Expand Down Expand Up @@ -797,6 +806,9 @@ static const char cannedMacAlgoNames[] =
#if !defined(WOLFSSH_NO_HMAC_SHA2_256)
"hmac-sha2-256,"
#endif
#if !defined(WOLFSSH_NO_HMAC_SHA2_512)
"hmac-sha2-512,"
#endif
#if defined(WOLFSSH_NO_SHA1_SOFT_DISABLE)
#if !defined(WOLFSSH_NO_HMAC_SHA1_96)
"hmac-sha1-96,"
Expand Down Expand Up @@ -2445,6 +2457,9 @@ static const NameIdPair NameIdMap[] = {
#ifndef WOLFSSH_NO_HMAC_SHA2_256
{ ID_HMAC_SHA2_256, TYPE_MAC, "hmac-sha2-256" },
#endif
#ifndef WOLFSSH_NO_HMAC_SHA2_512
{ ID_HMAC_SHA2_512, TYPE_MAC, "hmac-sha2-512" },
#endif

/* Key Exchange IDs */
#ifndef WOLFSSH_NO_DH_GROUP1_SHA1
Expand All @@ -2456,6 +2471,9 @@ static const NameIdPair NameIdMap[] = {
#ifndef WOLFSSH_NO_DH_GROUP14_SHA256
{ ID_DH_GROUP14_SHA256, TYPE_KEX, "diffie-hellman-group14-sha256" },
#endif
#ifndef WOLFSSH_NO_DH_GROUP16_SHA512
{ ID_DH_GROUP16_SHA512, TYPE_KEX, "diffie-hellman-group16-sha512" },
#endif
#ifndef WOLFSSH_NO_DH_GEX_SHA256
{ ID_DH_GEX_SHA256, TYPE_KEX, "diffie-hellman-group-exchange-sha256" },
#endif
Expand Down Expand Up @@ -3625,6 +3643,10 @@ static INLINE byte MacSzForId(byte id)
#ifndef WOLFSSH_NO_HMAC_SHA2_256
case ID_HMAC_SHA2_256:
return WC_SHA256_DIGEST_SIZE;
#endif
#ifndef WOLFSSH_NO_HMAC_SHA2_512
case ID_HMAC_SHA2_512:
return WC_SHA512_DIGEST_SIZE;
#endif
default:
return 0;
Expand All @@ -3647,6 +3669,10 @@ static INLINE byte KeySzForId(byte id)
case ID_HMAC_SHA2_256:
return WC_SHA256_DIGEST_SIZE;
#endif
#ifndef WOLFSSH_NO_HMAC_SHA2_512
case ID_HMAC_SHA2_512:
return WC_SHA512_DIGEST_SIZE;
#endif
#ifndef WOLFSSH_NO_AES_CBC
case ID_AES128_CBC:
return AES_128_KEY_SIZE;
Expand Down Expand Up @@ -3759,6 +3785,10 @@ enum wc_HashType HashForId(byte id)
#endif
return WC_HASH_TYPE_SHA512;
#endif
#ifndef WOLFSSH_NO_DH_GROUP16_SHA512
case ID_DH_GROUP16_SHA512:
return WC_HASH_TYPE_SHA512;
#endif
#ifndef WOLFSSH_NO_RSA_SHA2_512
case ID_RSA_SHA2_512:
return WC_HASH_TYPE_SHA512;
Expand Down Expand Up @@ -4349,6 +4379,76 @@ static const byte dhPrimeGroup14[] = {
static const word32 dhPrimeGroup14Sz = (word32)sizeof(dhPrimeGroup14);
#endif

#ifndef WOLFSSH_NO_DH_GROUP16_SHA512
static const byte dhPrimeGroup16[] = {
/* SSH DH Group 16 (Oakley Group 16, 4096-bit MODP Group, RFC 3526) */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
static const word32 dhPrimeGroup16Sz = (word32)sizeof(dhPrimeGroup16);
#endif

static int DoKexDhInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
{
Expand Down Expand Up @@ -9249,6 +9349,27 @@ static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz,
}
break;

#ifndef WOLFSSH_NO_HMAC_SHA2_512
case ID_HMAC_SHA2_512:
{
Hmac hmac;

ret = wc_HmacInit(&hmac, ssh->ctx->heap, INVALID_DEVID);
if (ret == WS_SUCCESS)
ret = wc_HmacSetKey(&hmac, WC_SHA512,
ssh->keys.macKey,
ssh->keys.macKeySz);
if (ret == WS_SUCCESS)
ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq));
if (ret == WS_SUCCESS)
ret = wc_HmacUpdate(&hmac, in, inSz);
if (ret == WS_SUCCESS)
ret = wc_HmacFinal(&hmac, mac);
wc_HmacFree(&hmac);
}
break;
#endif

default:
WLOG(WS_LOG_DEBUG, "Invalid Mac ID");
ret = WS_FATAL_ERROR;
Expand Down Expand Up @@ -9311,6 +9432,19 @@ static INLINE int VerifyMac(WOLFSSH* ssh, const byte* in, word32 inSz,
ret = WS_VERIFY_MAC_E;
break;

case ID_HMAC_SHA2_512:
ret = wc_HmacSetKey(&hmac, WC_SHA512, ssh->peerKeys.macKey,
ssh->peerKeys.macKeySz);
if (ret == WS_SUCCESS)
ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq));
if (ret == WS_SUCCESS)
ret = wc_HmacUpdate(&hmac, in, inSz);
if (ret == WS_SUCCESS)
ret = wc_HmacFinal(&hmac, checkMac);
if (ConstantCompare(checkMac, mac, ssh->peerMacSz) != 0)
ret = WS_VERIFY_MAC_E;
break;

default:
ret = WS_INVALID_ALGO_ID;
}
Expand Down Expand Up @@ -9450,6 +9584,8 @@ int DoReceive(WOLFSSH* ssh)
/* Peek at the packet_length field. */
ato32(ssh->inputBuffer.buffer + ssh->inputBuffer.idx, &ssh->curSz);
if (ssh->curSz > MAX_PACKET_SZ - (word32)peerMacSz - UINT32_SZ) {
WLOG(WS_LOG_DEBUG, "Packet length overflow: size = %u",
ssh->curSz);
ssh->error = WS_OVERFLOW_E;
return WS_FATAL_ERROR;
}
Expand Down Expand Up @@ -10077,6 +10213,8 @@ struct wolfSSH_sigKeyBlockFull {
/* Size of Kyber public key (bigger than ciphertext) and some extra for the
* ECC hybrid component. */
#define KEX_F_SIZE 1024
#elif !defined(WOLFSSH_NO_DH_GROUP16_SHA512)
#define KEX_F_SIZE (512 + 1)
#else
#define KEX_F_SIZE (256 + 1)
#endif
Expand Down Expand Up @@ -10216,6 +10354,14 @@ static int GetDHPrimeGroup(int kexId, const byte** primeGroup,
*generatorSz = dhGeneratorSz;
break;
#endif
#ifndef WOLFSSH_NO_DH_GROUP16_SHA512
case ID_DH_GROUP16_SHA512:
*primeGroup = dhPrimeGroup16;
*primeGroupSz = dhPrimeGroup16Sz;
*generator = dhGenerator;
*generatorSz = dhGeneratorSz;
break;
#endif
#ifndef WOLFSSH_NO_DH_GEX_SHA256
case ID_DH_GEX_SHA256:
*primeGroup = dhPrimeGroup14;
Expand Down Expand Up @@ -11500,6 +11646,12 @@ int SendKexDhReply(WOLFSSH* ssh)
msgId = MSGID_KEXDH_REPLY;
break;
#endif
#ifndef WOLFSSH_NO_DH_GROUP16_SHA512
case ID_DH_GROUP16_SHA512:
useDh = 1;
msgId = MSGID_KEXDH_REPLY;
break;
#endif
#ifndef WOLFSSH_NO_DH_GEX_SHA256
case ID_DH_GEX_SHA256:
useDh = 1;
Expand Down Expand Up @@ -12069,6 +12221,15 @@ int SendKexDhInit(WOLFSSH* ssh)
generatorSz = dhGeneratorSz;
break;
#endif
#ifndef WOLFSSH_NO_DH_GROUP16_SHA512
case ID_DH_GROUP16_SHA512:
ssh->handshake->useDh = 1;
primeGroup = dhPrimeGroup16;
primeGroupSz = dhPrimeGroup16Sz;
generator = dhGenerator;
generatorSz = dhGeneratorSz;
break;
#endif
#ifndef WOLFSSH_NO_DH_GEX_SHA256
case ID_DH_GEX_SHA256:
ssh->handshake->useDh = 1;
Expand Down
2 changes: 1 addition & 1 deletion src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ int wsEmbedSend(WOLFSSH* ssh, void* data, word32 sz, void* ctx)
return WS_CBIO_ERR_CONN_CLOSE;
}
else {
WLOG(WS_LOG_DEBUG," General error");
WLOG(WS_LOG_DEBUG," General error %d", err);
return WS_CBIO_ERR_GENERAL;
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -2921,6 +2921,9 @@ static const char* MacNameForId(byte macid, byte cipherid)

case ID_HMAC_SHA2_256:
return "HMAC-SHA-256";

case ID_HMAC_SHA2_512:
return "HMAC-SHA-512";
}
}
else {
Expand Down Expand Up @@ -3010,6 +3013,11 @@ size_t wolfSSH_GetText(WOLFSSH *ssh, WS_Text id, char *str, size_t strSz)
ssh->primeGroupSz*8, 14);
break;

case ID_DH_GROUP16_SHA512:
ret = WSNPRINTF(str, strSz, standard_dh_format,
ssh->primeGroupSz*8, 16);
break;

case ID_DH_GEX_SHA256:
ret = WSNPRINTF(str, strSz,
"%d-bit Diffie-Hellman with server-supplied group",
Expand Down
Loading