-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
172 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -143,6 +143,9 @@ | |
algorithms off. | ||
WOLFSSH_KEY_QUANTITY_REQ | ||
Number of keys required to be in an OpenSSH-style key wrapper. | ||
WOLFSSH_NO_CURVE25519_SHA256 | ||
Set when Curve25519 or SHA2-256 are disabled in wolfSSL. Set to disable use | ||
of Curve25519 key exchange. | ||
*/ | ||
|
||
static const char sshProtoIdStr[] = "SSH-2.0-wolfSSHv" | ||
|
@@ -2011,6 +2014,11 @@ static const NameIdPair NameIdMap[] = { | |
{ ID_ECDH_NISTP256_KYBER_LEVEL1_SHA256, | ||
"[email protected]" }, | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
/* See RFC 8731 */ | ||
{ ID_CURVE25519_SHA256, "curve25519-sha256" }, | ||
#endif | ||
|
||
{ ID_EXTINFO_S, "ext-info-s" }, | ||
{ ID_EXTINFO_C, "ext-info-c" }, | ||
|
||
|
@@ -3072,6 +3080,9 @@ static const byte cannedKexAlgo[] = { | |
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
ID_ECDH_NISTP256_KYBER_LEVEL1_SHA256, | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
ID_CURVE25519_SHA256, | ||
#endif | ||
#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP521 | ||
ID_ECDH_SHA2_NISTP521, | ||
#endif | ||
|
@@ -3266,6 +3277,10 @@ static INLINE enum wc_HashType HashForId(byte id) | |
case ID_ECDH_NISTP256_KYBER_LEVEL1_SHA256: | ||
return WC_HASH_TYPE_SHA256; | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
case ID_CURVE25519_SHA256: | ||
return WC_HASH_TYPE_SHA256; | ||
#endif | ||
#ifndef WOLFSSH_NO_RSA_SHA2_256 | ||
case ID_RSA_SHA2_256: | ||
return WC_HASH_TYPE_SHA256; | ||
|
@@ -4518,6 +4533,9 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) | |
if (!ssh->handshake->useEcc | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
&& !ssh->handshake->useEccKyber | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
&& !ssh->handshake->useCurve25519 | ||
#endif | ||
) { | ||
#ifndef WOLFSSH_NO_DH | ||
|
@@ -4562,6 +4580,37 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) | |
ret = WS_INVALID_ALGO_ID; | ||
#endif | ||
} | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
else if (ssh->handshake->useCurve25519) { | ||
curve25519_key pub; | ||
ret = wc_curve25519_init(&pub); | ||
|
||
if (ret == 0) | ||
ret = wc_curve25519_check_public(f, fSz, | ||
EC25519_LITTLE_ENDIAN); | ||
|
||
if (ret == 0) { | ||
ret = wc_curve25519_import_public_ex(f, fSz, &pub, | ||
EC25519_LITTLE_ENDIAN); | ||
} | ||
|
||
if (ret == 0) { | ||
PRIVATE_KEY_UNLOCK(); | ||
ret = wc_curve25519_shared_secret_ex( | ||
&ssh->handshake->privKey.curve25519, &pub, | ||
ssh->k, &ssh->kSz, EC25519_LITTLE_ENDIAN); | ||
PRIVATE_KEY_LOCK(); | ||
} | ||
|
||
wc_curve25519_free(&pub); | ||
wc_curve25519_free(&ssh->handshake->privKey.curve25519); | ||
|
||
if (ret != 0) { | ||
WLOG(WS_LOG_ERROR, | ||
"Gen curve25519 shared secret failed, %d", ret); | ||
} | ||
} | ||
#endif /* !WOLFSSH_NO_CURVE25519_SHA256 */ | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
else if (ssh->handshake->useEccKyber) { | ||
/* This is a a hybrid of ECDHE and a post-quantum KEM. In this | ||
|
@@ -4804,8 +4853,8 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) | |
|
||
if (ret == WS_SUCCESS) { | ||
int useKeyPadding = 1; | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
useKeyPadding = !ssh->handshake->useEccKyber; | ||
#if !defined(WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256) | ||
doKeyPadding = !ssh->handshake->useEccKyber; | ||
#endif | ||
ret = GenerateKeys(ssh, hashId, useKeyPadding); | ||
} | ||
|
@@ -8919,6 +8968,9 @@ static const char cannedKeyAlgoNames[] = "rsa-sha2-256,ecdsa-sha2-nistp256"; | |
|
||
#if 0 | ||
static const char cannedKexAlgoNames[] = | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
"curve25519-sha256," | ||
#endif | ||
#if !defined(WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256) | ||
"[email protected]," | ||
#endif | ||
|
@@ -9773,6 +9825,9 @@ int SendKexDhReply(WOLFSSH* ssh) | |
byte useEccKyber = 0; | ||
byte sharedSecretHashSz = 0; | ||
byte *sharedSecretHash = NULL; | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
byte useCurve25519 = 0; | ||
#endif | ||
byte fPad = 0; | ||
byte kPad = 0; | ||
|
@@ -9856,6 +9911,12 @@ int SendKexDhReply(WOLFSSH* ssh) | |
msgId = MSGID_KEXDH_REPLY; | ||
break; | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
case ID_CURVE25519_SHA256: | ||
useCurve25519 = 1; | ||
msgId = MSGID_KEXDH_REPLY; | ||
break; | ||
#endif | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
case ID_ECDH_NISTP256_KYBER_LEVEL1_SHA256: | ||
useEccKyber = 1; /* Only support level 1 for now. */ | ||
|
@@ -9899,6 +9960,9 @@ int SendKexDhReply(WOLFSSH* ssh) | |
if (!useEcc | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
&& !useEccKyber | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
&& !useCurve25519 | ||
#endif | ||
) { | ||
#ifndef WOLFSSH_NO_DH | ||
|
@@ -10014,6 +10078,61 @@ int SendKexDhReply(WOLFSSH* ssh) | |
#endif | ||
#endif /* !defined(WOLFSSH_NO_ECDH) */ | ||
} | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
if (useCurve25519) { | ||
#ifdef WOLFSSH_SMALL_STACK | ||
pubKey = (curve25519_key*)WMALLOC(sizeof(curve25519_key), | ||
heap, DYNTYPE_PUBKEY); | ||
privKey = (curve25519_key*)WMALLOC(sizeof(curve25519_key), | ||
heap, DYNTYPE_PRIVKEY); | ||
if (pubKey == NULL || privKey == NULL) { | ||
ret = WS_MEMORY_E; | ||
} | ||
#else | ||
curve25519_key pubKey[1], privKey[1]; | ||
#endif | ||
|
||
if (ret == 0) | ||
ret = wc_curve25519_init_ex(pubKey, heap, | ||
INVALID_DEVID); | ||
if (ret == 0) | ||
ret = wc_curve25519_init_ex(privKey, heap, | ||
INVALID_DEVID); | ||
if (ret == 0) | ||
ret = wc_curve25519_check_public(ssh->handshake->e, | ||
ssh->handshake->eSz, EC25519_LITTLE_ENDIAN); | ||
if (ret == 0) | ||
ret = wc_curve25519_import_public_ex( | ||
ssh->handshake->e, ssh->handshake->eSz, | ||
pubKey, EC25519_LITTLE_ENDIAN); | ||
|
||
if (ret == 0) | ||
ret = wc_curve25519_make_key(ssh->rng, | ||
CURVE25519_KEYSIZE, privKey); | ||
|
||
if (ret == 0) { | ||
PRIVATE_KEY_UNLOCK(); | ||
ret = wc_curve25519_export_public_ex(privKey, | ||
f_ptr, &fSz, EC25519_LITTLE_ENDIAN); | ||
PRIVATE_KEY_LOCK(); | ||
} | ||
|
||
if (ret == 0) { | ||
PRIVATE_KEY_UNLOCK(); | ||
ret = wc_curve25519_shared_secret_ex(privKey, pubKey, | ||
ssh->k, &ssh->kSz, EC25519_LITTLE_ENDIAN); | ||
PRIVATE_KEY_LOCK(); | ||
} | ||
wc_curve25519_free(privKey); | ||
wc_curve25519_free(pubKey); | ||
#ifdef WOLFSSH_SMALL_STACK | ||
WFREE(pubKey, heap, DYNTYPE_PUBKEY); | ||
WFREE(privKey, heap, DYNTYPE_PRIVKEY); | ||
pubKey = NULL; | ||
privKey = NULL; | ||
#endif | ||
} | ||
#endif /* ! WOLFSSH_NO_CURVE25519_SHA256 */ | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
else if (useEccKyber) { | ||
/* This is a hybrid KEM. In this case, I need to generate my ECC | ||
|
@@ -10161,6 +10280,9 @@ int SendKexDhReply(WOLFSSH* ssh) | |
if (ret == 0 | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
&& !useEccKyber | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
&& !useCurve25519 | ||
#endif | ||
) { | ||
ret = CreateMpint(f_ptr, &fSz, &fPad); | ||
|
@@ -10378,8 +10500,8 @@ int SendKexDhReply(WOLFSSH* ssh) | |
|
||
if (ret == WS_SUCCESS) { | ||
int doKeyPadding = 1; | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
doKeyPadding = !useEccKyber; | ||
#if !defined(WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256) | ||
doKeyPadding = !ssh->handshake->useEccKyber; | ||
#endif | ||
ret = GenerateKeys(ssh, hashId, doKeyPadding); | ||
} | ||
|
@@ -10793,6 +10915,12 @@ int SendKexDhInit(WOLFSSH* ssh) | |
msgId = MSGID_KEXECDH_INIT; | ||
break; | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
case ID_CURVE25519_SHA256: | ||
ssh->handshake->useCurve25519 = 1; | ||
msgId = MSGID_KEXECDH_INIT; | ||
break; | ||
#endif | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
case ID_ECDH_NISTP256_KYBER_LEVEL1_SHA256: | ||
/* Only support level 1 for now. */ | ||
|
@@ -10811,6 +10939,9 @@ int SendKexDhInit(WOLFSSH* ssh) | |
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
&& !ssh->handshake->useEccKyber | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
&& !ssh->handshake->useCurve25519 | ||
#endif | ||
) { | ||
#ifndef WOLFSSH_NO_DH | ||
DhKey* privKey = &ssh->handshake->privKey.dh; | ||
|
@@ -10826,6 +10957,23 @@ int SendKexDhInit(WOLFSSH* ssh) | |
e, &eSz); | ||
#endif | ||
} | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
else if (ssh->handshake->useCurve25519) { | ||
curve25519_key* privKey = &ssh->handshake->privKey.curve25519; | ||
if (ret == 0) | ||
ret = wc_curve25519_init_ex(privKey, ssh->ctx->heap, | ||
INVALID_DEVID); | ||
if (ret == 0) | ||
ret = wc_curve25519_make_key(ssh->rng, CURVE25519_KEYSIZE, | ||
privKey); | ||
if (ret == 0) { | ||
PRIVATE_KEY_UNLOCK(); | ||
ret = wc_curve25519_export_public_ex(privKey, e, &eSz, | ||
EC25519_LITTLE_ENDIAN); | ||
PRIVATE_KEY_LOCK(); | ||
} | ||
} | ||
#endif /* ! WOLFSSH_NO_CURVE25519_SHA256 */ | ||
else if (ssh->handshake->useEcc | ||
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
|| ssh->handshake->useEccKyber | ||
|
@@ -10897,6 +11045,10 @@ int SendKexDhInit(WOLFSSH* ssh) | |
#ifndef WOLFSSH_NO_ECDH_NISTP256_KYBER_LEVEL1_SHA256 | ||
&& !ssh->handshake->useEccKyber | ||
#endif | ||
#ifndef WOLFSSH_NO_CURVE25519_SHA256 | ||
&& !ssh->handshake->useCurve25519 | ||
#endif | ||
|
||
) { | ||
ret = CreateMpint(e, &eSz, &ePad); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters