Skip to content

Commit

Permalink
Add DH Group 16 and HMAC-SHA2-512
Browse files Browse the repository at this point in the history
This adds the `diffie-hellman-group16-sha512` key exchange and
`hmac-sha2-512` mac support.

Echoserver can now take `-x` for key exchange and `-m` for mac setting,
so that this can be used in the test suite.
  • Loading branch information
LinuxJedi committed Feb 4, 2025
1 parent 759bcbd commit 17c8b69
Show file tree
Hide file tree
Showing 7 changed files with 582 additions and 5 deletions.
29 changes: 27 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,8 @@ 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;
ES_HEAP_HINT* heap = NULL;
int multipleConnections = 1;
int userEcc = 0;
Expand All @@ -2378,7 +2383,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:";
myoptind = 0;
while ((ch = mygetopt(argc, argv, optlist)) != -1) {
switch (ch) {
Expand Down Expand Up @@ -2466,6 +2471,14 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
userAuthWouldBlock = atoi(myoptarg);
break;

case 'x':
kexList = myoptarg;
break;

case 'm':
macList = myoptarg;
break;

default:
ShowUsage();
serverArgs->return_code = MY_EX_USAGE;
Expand Down Expand Up @@ -2524,6 +2537,18 @@ 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");
}
}

WMEMSET(&pwMapList, 0, sizeof(pwMapList));
if (serverArgs->user_auth == NULL)
wolfSSH_SetUserAuth(ctx, wsUserAuth);
Expand Down
159 changes: 159 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 @@ -10077,6 +10211,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 +10352,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 +11644,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 +12219,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
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

0 comments on commit 17c8b69

Please sign in to comment.