More Options

Added many more guards for algorithms that may be disabled in wolfCrypt
including DH, AES-GCM-CTR-CBC, SHA1, ECC, RSA, etc.
pull/293/head
John Safranek 2020-09-24 10:38:34 -07:00
parent 6849e6bd09
commit b63d3c4914
No known key found for this signature in database
GPG Key ID: 8CE817DE0D3CCB4A
2 changed files with 357 additions and 77 deletions

View File

@ -57,9 +57,120 @@ Flags:
use of the function if the flag isn't set. If using wolfCrypt v4.5.0 or
later, and not building with configure, set this flag.
default: off
WOLFSSH_NO_HMAC_SHA1
Set when HMAC or SHA1 are disabled. Set to disable HMAC-SHA1 support.
WOLFSSH_NO_HMAC_SHA1_96
Set when HMAC or SHA1 are disabled. Set to disable HMAC-SHA1-96 support.
WOLFSSH_NO_HMAC_SHA2_256
Set when HMAC or SHA2-256 are disabled. Set to disable HMAC-SHA2-256
support.
WOLFSSH_NO_DH_GROUP1_SHA1
Set when DH or SHA1 are disabled. Set to disable use of DH (Oakley 1) and
SHA1 support.
WOLFSSH_NO_DH_GROUP14_SHA1
Set when DH or SHA1 are disabled. Set to disable use of DH (Oakley 14) and
SHA1 support.
WOLFSSH_NO_DH_GEX_SHA256
Set when DH or SHA2-256 are disabled. Set to disable use of DH group
exchange and SHA2-256 support.
WOLFSSH_NO_ECDH_SHA2_NISTP256
Set when ECC or SHA2-256 are disabled. Set to disable use of ECDHE key
exchange with prime NISTP256.
WOLFSSH_NO_ECDH_SHA2_NISTP384
Set when ECC or SHA2-384 are disabled. Set to disable use of ECDHE key
exchange with prime NISTP384.
WOLFSSH_NO_ECDH_SHA2_NISTP521
Set when ECC or SHA2-512 are disabled. Set to disable use of ECDHE key
exchange with prime NISTP521.
WOLFSSH_NO_ECDH_SHA2_ED25519
Set when ED25519 or SHA2-256 are disabled. Set to disable use of ECDHE key
exchange with prime ED25519. (It just decodes the ID for output.)
WOLFSSH_NO_SSH_RSA_SHA1
Set when RSA or SHA1 are disabled. Set to disable use of RSA server
authentication.
WOLFSSH_NO_ECDSA_SHA2_NISTP256
Set when ECC or SHA2-256 are disabled. Set to disable use of ECDSA server
authentication with prime NISTP256.
WOLFSSH_NO_ECDSA_SHA2_NISTP384
Set when ECC or SHA2-384 are disabled. Set to disable use of ECDSA server
authentication with prime NISTP384.
WOLFSSH_NO_ECDSA_SHA2_NISTP521
Set when ECC or SHA2-512 are disabled. Set to disable use of ECDSA server
authentication with prime NISTP521.
WOLFSSH_NO_AES_CBC
Set when AES or AES-CBC are disabled. Set to disable use of AES-CBC
encryption.
WOLFSSH_NO_AES_CTR
Set when AES or AES-CTR are disabled. Set to disable use of AES-CTR
encryption.
WOLFSSH_NO_AES_GCM
Set when AES or AES-GCM are disabled. Set to disable use of AES-GCM
encryption.
WOLFSSH_NO_AEAD
Set when AES-GCM is disabled. Set to disable use of AEAD ciphers for
encryption. Setting this will force all AEAD ciphers off.
*/
#if defined(NO_HMAC) || defined(NO_SHA)
#define WOLFSSH_NO_HMAC_SHA1
#endif
#if defined(NO_HMAC) || defined(NO_SHA)
#define WOLFSSH_NO_HMAC_SHA1_96
#endif
#if defined(NO_HMAC) || defined(NO_SHA256)
#define WOLFSSH_NO_HMAC_SHA2_256
#endif
#if defined(NO_DH) || defined(NO_SHA)
#define WOLFSSH_NO_DH_GROUP1_SHA1
#endif
#if defined(NO_DH) || defined(NO_SHA)
#define WOLFSSH_NO_DH_GROUP14_SHA1
#endif
#if defined(NO_DH) || defined(NO_SHA256)
#define WOLFSSH_NO_DH_GEX_SHA256
#endif
#if !defined(HAVE_ECC) || defined(NO_SHA256)
#define WOLFSSH_NO_ECDH_SHA2_NISTP256
#endif
#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384)
#define WOLFSSH_NO_ECDH_SHA2_NISTP384
#endif
#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512)
#define WOLFSSH_NO_ECDH_SHA2_NISTP521
#endif
#if !defined(HAVE_ED25519) || defined(NO_SHA256)
#define WOLFSSH_NO_ECDH_SHA2_ED25519
#endif
#if defined(NO_RSA) || defined(NO_SHA)
#define WOLFSSH_NO_SSH_RSA_SHA1
#endif
#if !defined(HAVE_ECC) || defined(NO_SHA256)
#define WOLFSSH_NO_ECDSA_SHA2_NISTP256
#endif
#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA384)
#define WOLFSSH_NO_ECDSA_SHA2_NISTP384
#endif
#if !defined(HAVE_ECC) || !defined(WOLFSSL_SHA512)
#define WOLFSSH_NO_ECDSA_SHA2_NISTP521
#endif
#if defined(NO_AES) || !defined(HAVE_AES_CBC)
#define WOLFSSH_NO_AES_CBC
#endif
#if defined(NO_AES) || !defined(WOLFSSL_AES_COUNTER)
#define WOLFSSH_NO_AES_CTR
#endif
#if defined(NO_AES) || !defined(HAVE_AESGCM)
#define WOLFSSH_NO_AES_GCM
#endif
#if defined(WOLFSSH_NO_AES_GCM)
#define WOLFSSH_NO_AEAD
#ifndef WOLFSSH_NO_AES_GCM
#define WOLFSSH_AES_GCM
#endif
#endif
static const char sshProtoIdStr[] = "SSH-2.0-wolfSSHv"
LIBWOLFSSH_VERSION_STRING
"\r\n";
@ -937,31 +1048,67 @@ static const NameIdPair NameIdMap[] = {
{ ID_NONE, "none" },
/* Encryption IDs */
#ifndef WOLFSSH_NO_AES_CBC
{ ID_AES128_CBC, "aes128-cbc" },
#endif
#ifndef WOLFSSH_NO_AES_CTR
{ ID_AES128_CTR, "aes128-ctr" },
#endif
#ifndef WOLFSSH_NO_AES_GCM
{ ID_AES128_GCM, "aes128-gcm@openssh.com" },
#endif
/* Integrity IDs */
#ifndef WOLFSSH_NO_HMAC_SHA1
{ ID_HMAC_SHA1, "hmac-sha1" },
#endif
#ifndef WOLFSSH_NO_HMAC_SHA1_96
{ ID_HMAC_SHA1_96, "hmac-sha1-96" },
#endif
#ifndef WOLFSSH_NO_HMAC_SHA2_256
{ ID_HMAC_SHA2_256, "hmac-sha2-256" },
#endif
/* Key Exchange IDs */
#ifndef WOLFSSH_NO_DH_GROUP1_SHA1
{ ID_DH_GROUP1_SHA1, "diffie-hellman-group1-sha1" },
#endif
#ifndef WOLFSSH_NO_DH_GROUP14_SHA1
{ ID_DH_GROUP14_SHA1, "diffie-hellman-group14-sha1" },
#endif
#ifndef WOLFSSH_NO_DH_GEX_SHA256
{ ID_DH_GEX_SHA256, "diffie-hellman-group-exchange-sha256" },
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256
{ ID_ECDH_SHA2_NISTP256, "ecdh-sha2-nistp256" },
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384
{ ID_ECDH_SHA2_NISTP384, "ecdh-sha2-nistp384" },
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521
{ ID_ECDH_SHA2_NISTP521, "ecdh-sha2-nistp521" },
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_ED25519
{ ID_ECDH_SHA2_ED25519, "curve25519-sha256" },
{ ID_ECDH_SHA2_ED25519_LIBSSH, "curve25519-sha256@libssh.org" },
#endif
#ifndef WOLFSSH_NO_DH_GEX_SHA256
{ ID_DH_GROUP14_SHA256, "diffie-hellman-group14-sha256" },
#endif
/* Public Key IDs */
#ifndef WOLFSSH_NO_SSH_RSA_SHA1
{ ID_SSH_RSA, "ssh-rsa" },
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
{ ID_ECDSA_SHA2_NISTP256, "ecdsa-sha2-nistp256" },
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384
{ ID_ECDSA_SHA2_NISTP384, "ecdsa-sha2-nistp384" },
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521
{ ID_ECDSA_SHA2_NISTP521, "ecdsa-sha2-nistp521" },
#endif
/* Service IDs */
{ ID_SERVICE_USERAUTH, "ssh-userauth" },
@ -1847,27 +1994,17 @@ static int GetNameList(byte* idList, word32* idListSz,
}
static const byte cannedEncAlgo[] = {
#ifdef HAVE_AESGCM
#ifndef WOLFSSH_NO_AES_GCM
ID_AES128_GCM,
#endif
#ifdef WOLFSSL_AES_COUNTER
#ifndef WOLFSSH_NO_AES_CTR
ID_AES128_CTR,
#endif
#ifdef HAVE_AES_CBC
#ifndef WOLFSSH_NO_AES_CBC
ID_AES128_CBC,
#endif
};
#if defined(NO_HMAC) || defined(NO_SHA256)
#define WOLFSSH_NO_HMAC_SHA2_256
#endif
#if defined(NO_HMAC) || defined(NO_SHA)
#define WOLFSSH_NO_HMAC_SHA1_96
#endif
#if defined(NO_HMAC) || defined(NO_SHA)
#define WOLFSSH_NO_HMAC_SHA1
#endif
static const byte cannedMacAlgo[] = {
#ifndef WOLFSSH_NO_HMAC_SHA2_256
ID_HMAC_SHA2_256,
@ -1880,23 +2017,14 @@ static const byte cannedMacAlgo[] = {
#endif
};
static const byte cannedKeyAlgoClient[] = {ID_ECDSA_SHA2_NISTP256, ID_SSH_RSA};
#ifndef WOLFSSH_NO_SSH_RSA_SHA1
static const byte cannedKeyAlgoRsa[] = {ID_SSH_RSA};
static const word32 cannedKeyAlgoRsaSz = sizeof(cannedKeyAlgoRsa);
#endif
static const byte cannedKeyAlgoEcc256[] = {ID_ECDSA_SHA2_NISTP256};
static const byte cannedKeyAlgoEcc384[] = {ID_ECDSA_SHA2_NISTP384};
static const byte cannedKeyAlgoEcc521[] = {ID_ECDSA_SHA2_NISTP521};
#if !defined(HAVE_ECC) || defined(NO_SHA256)
#define WOLFSSH_NO_ECDH_SHA2_NISTP256
#endif
#if defined(NO_DH) || defined(NO_SHA256)
#define WOLFSSH_NO_DH_GEX_SHA256
#endif
#if defined(NO_DH) || defined(NO_SHA)
#define WOLFSSH_NO_DH_GROUP14_SHA1
#endif
#if defined(NO_DH) || defined(NO_SHA)
#define WOLFSSH_NO_DH_GROUP1_SHA1
#endif
static const byte cannedKexAlgo[] = {
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256
@ -1916,7 +2044,6 @@ static const byte cannedKexAlgo[] = {
static const word32 cannedEncAlgoSz = sizeof(cannedEncAlgo);
static const word32 cannedMacAlgoSz = sizeof(cannedMacAlgo);
static const word32 cannedKeyAlgoClientSz = sizeof(cannedKeyAlgoClient);
static const word32 cannedKeyAlgoRsaSz = sizeof(cannedKeyAlgoRsa);
static const word32 cannedKeyAlgoEcc256Sz = sizeof(cannedKeyAlgoEcc256);
static const word32 cannedKeyAlgoEcc384Sz = sizeof(cannedKeyAlgoEcc384);
static const word32 cannedKeyAlgoEcc521Sz = sizeof(cannedKeyAlgoEcc521);
@ -1960,10 +2087,18 @@ static byte MatchIdLists(int side, const byte* left, word32 leftSz,
static INLINE byte BlockSzForId(byte id)
{
switch (id) {
#ifndef WOLFSSH_NO_AES_CBC
case ID_AES128_CBC:
return AES_BLOCK_SIZE;
#endif
#ifndef WOLFSSH_NO_AES_CTR
case ID_AES128_CTR:
return AES_BLOCK_SIZE;
#endif
#ifndef WOLFSSH_NO_AES_GCM
case ID_AES128_GCM:
return AES_BLOCK_SIZE;
#endif
default:
return 0;
}
@ -1973,12 +2108,18 @@ static INLINE byte BlockSzForId(byte id)
static INLINE byte MacSzForId(byte id)
{
switch (id) {
#ifndef WOLFSSH_NO_HMAC_SHA1
case ID_HMAC_SHA1:
return WC_SHA_DIGEST_SIZE;
#endif
#ifndef WOLFSSH_NO_HMAC_SHA1_96
case ID_HMAC_SHA1_96:
return SHA1_96_SZ;
#endif
#ifndef WOLFSSH_NO_HMAC_SHA2_256
case ID_HMAC_SHA2_256:
return WC_SHA256_DIGEST_SIZE;
#endif
default:
return 0;
}
@ -1988,15 +2129,30 @@ static INLINE byte MacSzForId(byte id)
static INLINE byte KeySzForId(byte id)
{
switch (id) {
#ifndef WOLFSSH_NO_HMAC_SHA1
case ID_HMAC_SHA1:
return WC_SHA_DIGEST_SIZE;
#endif
#ifndef WOLFSSH_NO_HMAC_SHA1_96
case ID_HMAC_SHA1_96:
return WC_SHA_DIGEST_SIZE;
#endif
#ifndef WOLFSSH_NO_HMAC_SHA2_256
case ID_HMAC_SHA2_256:
return WC_SHA256_DIGEST_SIZE;
#endif
#ifndef WOLFSSH_NO_AES_CBC
case ID_AES128_CBC:
return AES_BLOCK_SIZE;
#endif
#ifndef WOLFSSH_NO_AES_CTR
case ID_AES128_CTR:
return AES_BLOCK_SIZE;
#endif
#ifndef WOLFSSH_NO_AES_GCM
case ID_AES128_GCM:
return AES_BLOCK_SIZE;
#endif
default:
return 0;
}
@ -2006,20 +2162,54 @@ static INLINE byte KeySzForId(byte id)
static INLINE enum wc_HashType HashForId(byte id)
{
switch (id) {
/* SHA1 */
#ifndef WOLFSSH_NO_DH_GROUP1_SHA1
case ID_DH_GROUP1_SHA1:
return WC_HASH_TYPE_SHA;
#endif
#ifndef WOLFSSH_NO_DH_GROUP14_SHA1
case ID_DH_GROUP14_SHA1:
return WC_HASH_TYPE_SHA;
#endif
#ifndef WOLFSSH_NO_SSH_RSA_SHA1
case ID_SSH_RSA:
return WC_HASH_TYPE_SHA;
#endif
/* SHA2-256 */
#ifndef WOLFSSH_NO_DH_GEX_SHA256
case ID_DH_GEX_SHA256:
return WC_HASH_TYPE_SHA256;
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256
case ID_ECDH_SHA2_NISTP256:
return WC_HASH_TYPE_SHA256;
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
case ID_ECDSA_SHA2_NISTP256:
return WC_HASH_TYPE_SHA256;
#endif
/* SHA2-384 */
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384
case ID_ECDH_SHA2_NISTP384:
return WC_HASH_TYPE_SHA384;
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384
case ID_ECDSA_SHA2_NISTP384:
return WC_HASH_TYPE_SHA384;
#endif
/* SHA2-512 */
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521
case ID_ECDH_SHA2_NISTP521:
return WC_HASH_TYPE_SHA512;
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521
case ID_ECDSA_SHA2_NISTP521:
return WC_HASH_TYPE_SHA512;
#endif
default:
return WC_HASH_TYPE_NONE;
}
@ -2029,15 +2219,30 @@ static INLINE enum wc_HashType HashForId(byte id)
static INLINE int wcPrimeForId(byte id)
{
switch (id) {
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256
case ID_ECDH_SHA2_NISTP256:
return ECC_SECP521R1;
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
case ID_ECDSA_SHA2_NISTP256:
return ECC_SECP256R1;
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384
case ID_ECDH_SHA2_NISTP384:
return ECC_SECP521R1;
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384
case ID_ECDSA_SHA2_NISTP384:
return ECC_SECP384R1;
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521
case ID_ECDH_SHA2_NISTP521:
return ECC_SECP521R1;
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521
case ID_ECDSA_SHA2_NISTP521:
return ECC_SECP521R1;
#endif
default:
return ECC_CURVE_INVALID;
}
@ -2045,15 +2250,30 @@ static INLINE int wcPrimeForId(byte id)
static INLINE const char *PrimeNameForId(byte id)
{
switch (id) {
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256
case ID_ECDH_SHA2_NISTP256:
return "nistp256";
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
case ID_ECDSA_SHA2_NISTP256:
return "nistp256";
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP384
case ID_ECDH_SHA2_NISTP384:
return "nistp384";
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384
case ID_ECDSA_SHA2_NISTP384:
return "nistp384";
#endif
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521
case ID_ECDH_SHA2_NISTP521:
return "nistp521";
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521
case ID_ECDSA_SHA2_NISTP521:
return "nistp521";
#endif
default:
return "unknown";
}
@ -2062,7 +2282,11 @@ static INLINE const char *PrimeNameForId(byte id)
static INLINE byte AeadModeForId(byte id)
{
#ifndef WOLFSSH_NO_AES_GCM
return (id == ID_AES128_GCM);
#else
return 0;
#endif
}
@ -2143,29 +2367,41 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
listSz = sizeof(list);
ret = GetNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
const byte *cannedKeyAlgo;
word32 cannedKeyAlgoSz;
const byte *cannedKeyAlgo = NULL;
word32 cannedKeyAlgoSz = 0;
if (side == WOLFSSH_ENDPOINT_SERVER) {
switch (ssh->ctx->useEcc) {
case ECC_SECP256R1:
cannedKeyAlgo = cannedKeyAlgoEcc256;
cannedKeyAlgoSz = cannedKeyAlgoEcc256Sz;
break;
case ECC_SECP384R1:
cannedKeyAlgo = cannedKeyAlgoEcc384;
cannedKeyAlgoSz = cannedKeyAlgoEcc384Sz;
break;
case ECC_SECP521R1:
cannedKeyAlgo = cannedKeyAlgoEcc521;
cannedKeyAlgoSz = cannedKeyAlgoEcc521Sz;
break;
default:
cannedKeyAlgo = cannedKeyAlgoRsa;
cannedKeyAlgoSz = cannedKeyAlgoRsaSz;
if (ssh->ctx->useEcc) {
switch (ssh->ctx->useEcc) {
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
case ECC_SECP256R1:
cannedKeyAlgo = cannedKeyAlgoEcc256;
cannedKeyAlgoSz = cannedKeyAlgoEcc256Sz;
break;
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384
case ECC_SECP384R1:
cannedKeyAlgo = cannedKeyAlgoEcc384;
cannedKeyAlgoSz = cannedKeyAlgoEcc384Sz;
break;
#endif
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521
case ECC_SECP521R1:
cannedKeyAlgo = cannedKeyAlgoEcc521;
cannedKeyAlgoSz = cannedKeyAlgoEcc521Sz;
break;
#endif
}
}
else {
#ifndef WOLFSSH_NO_SSH_RSA_SHA1
cannedKeyAlgo = cannedKeyAlgoRsa;
cannedKeyAlgoSz = cannedKeyAlgoRsaSz;
#endif
}
}
else {
/* XXX Does this need to be different for client? */
cannedKeyAlgo = cannedKeyAlgoClient;
cannedKeyAlgoSz = cannedKeyAlgoClientSz;
}
@ -2217,10 +2453,12 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
ssh->handshake->blockSz;
}
else {
#ifndef WOLFSSH_NO_AEAD
ssh->handshake->keys.ivSz =
ssh->handshake->peerKeys.ivSz =
AEAD_NONCE_SZ;
ssh->handshake->macSz = ssh->handshake->blockSz;
#endif
}
}
}
@ -2406,8 +2644,14 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
return ret;
}
#ifndef NO_DH
#if !defined(WOLFSSH_NO_DH_GROUP1_SHA1) || \
!defined(WOLFSSH_NO_DH_GROUP14_SHA1) || \
!defined(WOLFSSH_NO_DH_GEX_SHA256)
static const byte dhGenerator[] = { 2 };
static const word32 dhGeneratorSz = sizeof(dhGenerator);
#endif
#ifndef WOLFSSH_NO_DH_GROUP1_SHA1
static const byte dhPrimeGroup1[] = {
/* SSH DH Group 1 (Oakley Group 2, 1024-bit MODP Group, RFC 2409) */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
@ -2427,6 +2671,10 @@ static const byte dhPrimeGroup1[] = {
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
static const word32 dhPrimeGroup1Sz = sizeof(dhPrimeGroup1);
#endif
#ifndef WOLFSSH_NO_DH_GROUP14_SHA1
static const byte dhPrimeGroup14[] = {
/* SSH DH Group 14 (Oakley Group 14, 2048-bit MODP Group, RFC 3526) */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
@ -2462,9 +2710,6 @@ static const byte dhPrimeGroup14[] = {
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
static const word32 dhGeneratorSz = sizeof(dhGenerator);
static const word32 dhPrimeGroup1Sz = sizeof(dhPrimeGroup1);
static const word32 dhPrimeGroup14Sz = sizeof(dhPrimeGroup14);
#endif
@ -2552,9 +2797,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
RsaKey key;
} rsa;
#endif
#ifdef HAVE_ECC
struct {
ecc_key key;
} ecc;
#endif
} sk;
} sigKeyBlock;
word32 begin;
@ -2615,7 +2862,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
if (ret == WS_SUCCESS)
begin += pubKeySz;
#ifndef NO_DH
#ifndef WOLFSSH_NO_DH_GEX_SHA256
/* If using DH-GEX include the GEX specific values. */
if (ret == WS_SUCCESS && ssh->handshake->kexId == ID_DH_GEX_SHA256) {
byte primeGroupPad = 0, generatorPad = 0;
@ -2749,6 +2996,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
/* Load in the server's public signing key */
sigKeyBlock.useRsa = ssh->handshake->pubKeyId == ID_SSH_RSA;
ret = WS_INVALID_ALGO_ID;
if (sigKeyBlock.useRsa) {
#ifndef NO_RSA
byte* e;
@ -2786,10 +3034,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
else
ret = WS_RSA_E;
#else
(void)tmpIdx;
(void)tmpIdx;
#endif
}
else {
#ifdef HAVE_ECC
byte* q;
word32 qSz, pubKeyIdx = 0;
int primeId;
@ -2833,10 +3082,12 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
else
ret = WS_ECC_E;
}
#endif
}
/* Generate and hash in the shared secret */
if (ret == 0) {
ret = WS_INVALID_ALGO_ID;
if (!ssh->handshake->useEcc) {
#ifndef NO_DH
ret = wc_DhAgree(&ssh->handshake->privKey.dh,
@ -2848,11 +3099,12 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
#endif
}
else {
#ifdef HAVE_ECC
ecc_key key;
ret = wc_ecc_init(&key);
#ifdef HAVE_WC_ECC_SET_RNG
if (ret == WS_SUCCESS)
ret = wc_ecc_set_rng(&key, ssh->rng);
if (ret == WS_SUCCESS)
ret = wc_ecc_set_rng(&key, ssh->rng);
#endif
if (ret == 0)
ret = wc_ecc_import_x963(f, fSz, &key);
@ -2861,9 +3113,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
&key, ssh->k, &ssh->kSz);
wc_ecc_free(&key);
wc_ecc_free(&ssh->handshake->privKey.ecc);
#endif
}
}
CreateMpint(ssh->k, &ssh->kSz, &kPad);
if (ret == 0)
CreateMpint(ssh->k, &ssh->kSz, &kPad);
/* Hash in the shared secret K. */
if (ret == 0) {
@ -2956,6 +3210,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
#endif
}
else {
#ifdef HAVE_ECC
byte* r;
byte* s;
word32 rSz, sSz, asnSigSz;
@ -2987,6 +3242,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
ret = WS_ECC_E;
}
}
#endif
}
}
}
@ -2996,8 +3252,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
wc_FreeRsaKey(&sigKeyBlock.sk.rsa.key);
#endif
}
else
else {
#ifdef HAVE_ECC
wc_ecc_free(&sigKeyBlock.sk.ecc.key);
#endif
}
}
if (ret == WS_SUCCESS)
@ -3035,7 +3294,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher none");
break;
#ifdef HAVE_AES_CBC
#ifndef WOLFSSH_NO_AES128_CBC
case ID_AES128_CBC:
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-cbc");
ret = wc_AesSetKey(&ssh->decryptCipher.aes,
@ -3044,7 +3303,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
break;
#endif
#ifdef WOLFSSL_AES_COUNTER
#ifndef WOLFSSH_NO_AES128_CTR
case ID_AES128_CTR:
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-ctr");
ret = wc_AesSetKey(&ssh->decryptCipher.aes,
@ -3053,7 +3312,7 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
break;
#endif
#ifdef HAVE_AESGCM
#ifndef WOLFSSH_NO_AES128_GCM
case ID_AES128_GCM:
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-gcm");
ret = wc_AesGcmSetKey(&ssh->decryptCipher.aes,
@ -5155,6 +5414,7 @@ static int DoPacket(WOLFSSH* ssh)
}
#ifdef WOLFSSL_AES_COUNTER
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
/*
* The FIPSv2 version of wc_AesCtrEncrypt() only works if the input and
@ -5189,6 +5449,7 @@ static int DoPacket(WOLFSSH* ssh)
#else
#define AESCTRHELPER(a,b,c,d) wc_AesCtrEncrypt((a),(b),(c),(d))
#endif
#endif
static INLINE int Encrypt(WOLFSSH* ssh, byte* cipher, const byte* input,
@ -5297,6 +5558,7 @@ static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz,
ret = WS_SUCCESS;
break;
#ifndef WOLFSSH_NO_HMAC_SHA1_96
case ID_HMAC_SHA1_96:
{
Hmac hmac;
@ -5317,7 +5579,9 @@ static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz,
wc_HmacFree(&hmac);
}
break;
#endif
#ifndef WOLFSSH_NO_HMAC_SHA1
case ID_HMAC_SHA1:
{
Hmac hmac;
@ -5335,6 +5599,7 @@ static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz,
wc_HmacFree(&hmac);
}
break;
#endif
case ID_HMAC_SHA2_256:
{
@ -5439,6 +5704,7 @@ static INLINE void AeadIncrementExpIv(byte* iv)
}
#ifndef WOLFSSH_NO_AEAD
static INLINE int EncryptAead(WOLFSSH* ssh, byte* cipher,
const byte* input, word16 sz,
byte* authTag, const byte* auth,
@ -5452,7 +5718,7 @@ static INLINE int EncryptAead(WOLFSSH* ssh, byte* cipher,
WLOG(WS_LOG_DEBUG, "EncryptAead %s", IdToName(ssh->encryptId));
#ifdef HAVE_AESGCM
#ifndef WOLFSSH_NO_AES_GCM
if (ssh->encryptId == ID_AES128_GCM) {
ret = wc_AesGcmEncrypt(&ssh->encryptCipher.aes, cipher, input, sz,
ssh->keys.iv, ssh->keys.ivSz,
@ -5482,7 +5748,7 @@ static INLINE int DecryptAead(WOLFSSH* ssh, byte* plain,
WLOG(WS_LOG_DEBUG, "DecryptAead %s", IdToName(ssh->peerEncryptId));
#ifdef HAVE_AESGCM
#ifndef WOLFSSH_NO_AES_GCM
if (ssh->peerEncryptId == ID_AES128_GCM) {
ret = wc_AesGcmDecrypt(&ssh->decryptCipher.aes, plain, input, sz,
ssh->peerKeys.iv, ssh->peerKeys.ivSz,
@ -5498,6 +5764,7 @@ static INLINE int DecryptAead(WOLFSSH* ssh, byte* plain,
return ret;
}
#endif
int DoReceive(WOLFSSH* ssh)
@ -5599,6 +5866,7 @@ int DoReceive(WOLFSSH* ssh)
}
}
else {
#ifndef WOLFSSH_NO_AEAD
ret = DecryptAead(ssh,
ssh->inputBuffer.buffer +
ssh->inputBuffer.idx +
@ -5619,6 +5887,7 @@ int DoReceive(WOLFSSH* ssh)
ssh->error = ret;
return WS_FATAL_ERROR;
}
#endif
}
}
ssh->processReplyState = PROCESS_PACKET;
@ -5846,6 +6115,8 @@ static int BundlePacket(WOLFSSH* ssh)
}
else {
if (ret == WS_SUCCESS) {
ret = WS_INVALID_ALGO_ID;
#ifndef WOLFSSH_NO_AEAD
idx += paddingSz;
ret = EncryptAead(ssh,
ssh->outputBuffer.buffer +
@ -5860,6 +6131,7 @@ static int BundlePacket(WOLFSSH* ssh)
ssh->packetStartIdx,
LENGTH_SZ);
idx += ssh->macSz;
#endif
}
}
@ -5889,25 +6161,25 @@ static INLINE void CopyNameList(byte* buf, word32* idx,
}
static const char cannedEncAlgoNames[] =
#if defined(HAVE_AESGCM)
#if !defined(WOLFSSH_NO_AES_GCM)
"aes128-gcm@openssh.com"
#endif
#if defined(HAVE_AESGCM) && defined(WOLFSSL_AES_COUNTER)
#if !defined(WOLFSSH_NO_AES_GCM) && !defined(WOLFSSH_NO_AES_CTR)
","
#endif
#if defined(WOLFSSL_AES_COUNTER)
#if !defined(WOLFSSH_NO_AES_CTR)
"aes128-ctr"
#endif
#if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_COUNTER))\
&& defined(HAVE_AES_CBC)
#if (!defined(WOLFSSH_NO_AES_GCM) || !defined(WOLFSSH_NO_AES_CTR)) && \
!defined(WOLFSSH_NO_AES_CBC)
","
#endif
#if defined(HAVE_AES_CBC)
#if !defined(WOLFSSH_NO_AES_CBC)
"aes128-cbc"
#endif
;
#if !defined(HAVE_AESGCM) && !defined(WOLFSSL_AES_COUNTER)\
&& !defined(HAVE_AES_CBC)
#if defined(WOLFSSH_NO_AES_GCM) && defined(WOLFSSH_NO_AES_CTR) && \
defined(WOLFSSH_NO_AES_CBC)
#warning "You need at least one of AES-GCM, AES-CTR or AES-CBC."
#endif
@ -5921,8 +6193,8 @@ static const char cannedMacAlgoNames[] =
#if !defined(WOLFSSH_NO_HMAC_SHA1_96)
"hmac-sha1-96"
#endif
#if (!defined(WOLFSSH_NO_HMAC_SHA2_256) || !defined(WOLFSSH_NO_HMAC_SHA1_96))\
&& !defined(WOLFSSH_NO_HMAC_SHA1)
#if (!defined(WOLFSSH_NO_HMAC_SHA2_256) || !defined(WOLFSSH_NO_HMAC_SHA1_96)) \
&& !defined(WOLFSSH_NO_HMAC_SHA1)
","
#endif
#if !defined(WOLFSSH_NO_HMAC_SHA1)
@ -6794,21 +7066,25 @@ int SendNewKeys(WOLFSSH* ssh)
WLOG(WS_LOG_DEBUG, "SNK: using cipher none");
break;
#ifdef HAVE_AES_CBC
#ifndef WOLFSSH_NO_AES_CBC
case ID_AES128_CBC:
#endif
#ifdef WOLFSSL_AES_COUNTER
case ID_AES128_CTR:
#endif
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER)
WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-cbc/ctr");
WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-cbc");
ret = wc_AesSetKey(&ssh->encryptCipher.aes,
ssh->keys.encKey, ssh->keys.encKeySz,
ssh->keys.iv, AES_ENCRYPTION);
break;
#endif
#ifdef HAVE_AESGCM
#ifndef WOLFSSH_NO_AES_CTR
case ID_AES128_CTR:
WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-ctr");
ret = wc_AesSetKey(&ssh->encryptCipher.aes,
ssh->keys.encKey, ssh->keys.encKeySz,
ssh->keys.iv, AES_ENCRYPTION);
break;
#endif
#ifndef WOLFSSH_NO_AES_GCM
case ID_AES128_GCM:
WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-gcm");
ret = wc_AesGcmSetKey(&ssh->encryptCipher.aes,

View File

@ -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},