ED25519 TLS support

This commit is contained in:
Sean Parkinson
2017-05-30 16:04:24 +10:00
parent 4beda52dcd
commit 613d30bcae
29 changed files with 1091 additions and 154 deletions

Binary file not shown.

View File

@@ -0,0 +1,4 @@
-----BEGIN RSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEIE3EyZVR/gbofvUgIsCeuA3yZ9E7DbTQxW7HMDYQhbxl
oSIEIEEH7HUMaHISPASCB24Wb0BBbaSPCPLinadDwiQomH6s
-----END RSA PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICWTCCAgugAwIBAgIIAfbhPrx5oYUwBQYDK2VwMIGfMQswCQYDVQQGEwJVUzEQ
MA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjENMAsGA1UEBAwEUm9v
dDEQMA4GA1UECgwHd29sZlNTTDEQMA4GA1UECwwHRUQyNTUxOTEYMBYGA1UEAwwP
d3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29t
MCIYDzIwMTcwNTI4MjMyNjI5WhgPMjAxOTA1MjkyMzI2MjlaMIGdMQswCQYDVQQG
EwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjELMAkGA1UE
BAwCQ0ExEDAOBgNVBAoMB3dvbGZTU0wxEDAOBgNVBAsMB0VEMjU1MTkxGDAWBgNV
BAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3Ns
LmNvbTAqMAUGAytlcAMhAEEH7HUMaHISPASCB24Wb0BBbaSPCPLinadDwiQomH6s
o2EwXzAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBSS1Qva8QSLuaGLAwKfWAA1Ngd6
yTAfBgNVHSMEGDAWgBSGwCfpnvqFwf3jb/xUWXI3xzOSuzAPBgNVHQ8BAf8EBQMC
AcYAMAUGAytlcANBACIbBhfAEXQfZNGj9nsGABoLUI7rsWOSRbrc4sFoFCMMbiyV
PLEcGSeYUD5VUczESVivuUZP7ZxXOAQp1KkS/gg=
-----END CERTIFICATE-----

Binary file not shown.

View File

@@ -0,0 +1,4 @@
-----BEGIN RSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEIBGdNYxa3ommO8aYO1oGaGSRQBqDYB0sKOdR3bqejqIQ
oSIEIDY9UZ60w5FgsDoJuIdapQUPW1PlZBc+cLkNZhKk5fFR
-----END RSA PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICUTCCAgOgAwIBAgIIAckQps/YSE8wBQYDK2VwMIGhMQswCQYDVQQGEwJVUzEQ
MA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEPMA0GA1UEBAwGY2xp
ZW50MRAwDgYDVQQKDAd3b2xmU1NMMRAwDgYDVQQLDAdFRDI1NTE5MRgwFgYDVQQD
DA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5j
b20wIhgPMjAxNzA1MjgyMzI2MjlaGA8yMDE5MDUyOTIzMjYyOVowgaExCzAJBgNV
BAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMQ8wDQYD
VQQEDAZjbGllbnQxEDAOBgNVBAoMB3dvbGZTU0wxEDAOBgNVBAsMB0VEMjU1MTkx
GDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3
b2xmc3NsLmNvbTAqMAUGAytlcAMhADY9UZ60w5FgsDoJuIdapQUPW1PlZBc+cLkN
ZhKk5fFRo1MwUTAdBgNVHQ4EFgQUppdwk1xpkyuWMh6Heza6k5opV/EwHwYDVR0j
BBgwFoAUppdwk1xpkyuWMh6Heza6k5opV/EwDwYDVR0PAQH/BAUDAgbAADAFBgMr
ZXADQQCUo3bb4Zv2vjs09vniOoogAIHBlj4tOdodJ/vVfSFRGfo5MTbFOa4RmAvZ
kz+W324RkBsIl8R8ksENe87bJwAP
-----END CERTIFICATE-----

Binary file not shown.

View File

@@ -0,0 +1,4 @@
-----BEGIN RSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEIFwOftlJ9QL4yEBIBh9UmTRwCu+A6puPK9OFmVk0A19P
oSIEIKZgKbt92EfL1B7QbQ9XANgqH1BqQrxd5bgZZbLfJK9Q
-----END RSA PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICWzCCAg2gAwIBAgIIAcUx7uhNOB4wBQYDK2VwMIGfMQswCQYDVQQGEwJVUzEQ
MA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjENMAsGA1UEBAwEUm9v
dDEQMA4GA1UECgwHd29sZlNTTDEQMA4GA1UECwwHRUQyNTUxOTEYMBYGA1UEAwwP
d3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29t
MCIYDzIwMTcwNTI4MjMyNjI5WhgPMjAxOTA1MjkyMzI2MjlaMIGfMQswCQYDVQQG
EwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjENMAsGA1UE
BAwEUm9vdDEQMA4GA1UECgwHd29sZlNTTDEQMA4GA1UECwwHRUQyNTUxOTEYMBYG
A1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZz
c2wuY29tMCowBQYDK2VwAyEApmApu33YR8vUHtBtD1cA2CofUGpCvF3luBllst8k
r1CjYTBfMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFIbAJ+me+oXB/eNv/FRZcjfH
M5K7MB8GA1UdIwQYMBaAFIbAJ+me+oXB/eNv/FRZcjfHM5K7MA8GA1UdDwEB/wQF
AwIBxgAwBQYDK2VwA0EAGj129Ed4mXezQYuGBMzeglOtvFvz3UqPLBGTRI49gqqw
2/VnVoX532VvhensyCrk3/tRluh1wMnenEQlncm/CQ==
-----END CERTIFICATE-----

Binary file not shown.

View File

@@ -0,0 +1,4 @@
-----BEGIN RSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEINjpdrI/H/eIdfXd+HrGSTBu6Z/LnR4rwBjvu3WJ5ndn
oSIEIBowiBhHL5faBPSk471sDBa5SMHRQteOkoSgdCpDng4p
-----END RSA PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIICSzCCAf2gAwIBAgIIAdCSEGpaRlcwBQYDK2VwMIGdMQswCQYDVQQGEwJVUzEQ
MA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjELMAkGA1UEBAwCQ0Ex
EDAOBgNVBAoMB3dvbGZTU0wxEDAOBgNVBAsMB0VEMjU1MTkxGDAWBgNVBAMMD3d3
dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTAi
GA8yMDE3MDUyODIzMjYyOVoYDzIwMTkwNTI5MjMyNjI5WjCBnzELMAkGA1UEBhMC
VVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xDTALBgNVBAQM
BExlYWYxEDAOBgNVBAoMB3dvbGZTU0wxEDAOBgNVBAsMB0VEMjU1MTkxGDAWBgNV
BAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3Ns
LmNvbTAqMAUGAytlcAMhABowiBhHL5faBPSk471sDBa5SMHRQteOkoSgdCpDng4p
o1MwUTAdBgNVHQ4EFgQU9rKEGpW0cDJT/tnrmymAS9a18cAwHwYDVR0jBBgwFoAU
ktUL2vEEi7mhiwMCn1gANTYHeskwDwYDVR0PAQH/BAUDAgbAADAFBgMrZXADQQAS
VncMlkKY2skVbE5IlQUd0Hgy+IZGmkabZIsxsBlrd5mL//wCNgULaTeHYnXaUCwt
XVKUPwCdGEVvNxKO9OQA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICWTCCAgugAwIBAgIIAfbhPrx5oYUwBQYDK2VwMIGfMQswCQYDVQQGEwJVUzEQ
MA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjENMAsGA1UEBAwEUm9v
dDEQMA4GA1UECgwHd29sZlNTTDEQMA4GA1UECwwHRUQyNTUxOTEYMBYGA1UEAwwP
d3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29t
MCIYDzIwMTcwNTI4MjMyNjI5WhgPMjAxOTA1MjkyMzI2MjlaMIGdMQswCQYDVQQG
EwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjELMAkGA1UE
BAwCQ0ExEDAOBgNVBAoMB3dvbGZTU0wxEDAOBgNVBAsMB0VEMjU1MTkxGDAWBgNV
BAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3Ns
LmNvbTAqMAUGAytlcAMhAEEH7HUMaHISPASCB24Wb0BBbaSPCPLinadDwiQomH6s
o2EwXzAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBSS1Qva8QSLuaGLAwKfWAA1Ngd6
yTAfBgNVHSMEGDAWgBSGwCfpnvqFwf3jb/xUWXI3xzOSuzAPBgNVHQ8BAf8EBQMC
AcYAMAUGAytlcANBACIbBhfAEXQfZNGj9nsGABoLUI7rsWOSRbrc4sFoFCMMbiyV
PLEcGSeYUD5VUczESVivuUZP7ZxXOAQp1KkS/gg=
-----END CERTIFICATE-----

View File

@@ -1723,6 +1723,10 @@ static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
suites->hashSigAlgo[idx++] = sha_mac;
suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
#endif
#ifdef HAVE_ED25519
suites->hashSigAlgo[idx++] = ED25519_SA_MAJOR;
suites->hashSigAlgo[idx++] = ED25519_SA_MINOR;
#endif
}
if (haveRSAsig) {
@@ -2652,17 +2656,24 @@ void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA,
static INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType)
{
switch (input[0]) {
case NEW_SA_MAJOR:
#ifdef WC_RSA_PSS
case rsa_pss_sa_algo:
/* PSS signatures: 0x080[4-6] */
if (input[1] <= sha512_mac) {
*hsType = input[0];
*hashAlgo = input[1];
}
break;
/* PSS signatures: 0x080[4-6] */
if (input[1] <= sha512_mac) {
*hsType = input[0];
*hashAlgo = input[1];
}
#endif
/* ED25519: 0x0807 */
/* ED448: 0x0808 */
#ifdef HAVE_ED25519
/* ED25519: 0x0807 */
if (input[1] == ED25519_SA_MINOR) {
*hsType = ed25519_sa_algo;
/* Hash performed as part of sign/verify operation. */
*hashAlgo = sha512_mac;
}
#endif
/* ED448: 0x0808 */
break;
default:
*hashAlgo = input[0];
*hsType = input[1];
@@ -2828,6 +2839,12 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
output[0] = hashAlgo;
output[1] = ecc_dsa_sa_algo;
break;
#ifdef HAVE_ED25519
case ed25519_sa_algo:
output[0] = ED25519_SA_MAJOR;
output[1] = ED25519_SA_MINOR;
break;
#endif
#endif
#ifndef NO_RSA
case rsa_sa_algo:
@@ -2842,7 +2859,6 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
break;
#endif
#endif
/* ED25519: 0x0807 */
/* ED448: 0x0808 */
}
}
@@ -3420,6 +3436,108 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer)
return ret;
}
#ifdef HAVE_ED25519
/* Sign the data using EdDSA and key using X25519.
*
* ssl SSL object.
* in Data or message to sign.
* inSz Length of the data.
* out Buffer to hold signature.
* outSz On entry, size of the buffer. On exit, the size of the signature.
* key The private X25519 key data.
* keySz The length of the private key data in bytes.
* ctx The callback context.
* returns 0 on succes, otherwise the valus is an error.
*/
int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
word32* outSz, ed25519_key* key, byte* keyBuf, word32 keySz,
void* ctx)
{
int ret;
(void)ssl;
(void)keyBuf;
(void)keySz;
(void)ctx;
WOLFSSL_ENTER("Ed25519Sign");
#if defined(HAVE_PK_CALLBACKS)
if (ssl->ctx->Ed25519SignCb) {
ret = ssl->ctx->Ed25519SignCb(ssl, in, inSz, out, outSz, keyBuf,
keySz, ctx);
}
else
#endif /* HAVE_PK_CALLBACKS */
{
ret = wc_ed25519_sign_msg(in, inSz, out, outSz, key);
}
/* Handle async pending response */
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_PENDING_E) {
ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
}
#endif /* WOLFSSL_ASYNC_CRYPT */
WOLFSSL_LEAVE("Ed25519Sign", ret);
return ret;
}
/* Verify the data using EdDSA and key using X25519.
*
* ssl SSL object.
* in Signature data.
* inSz Length of the signature data in bytes.
* msg Message to verify.
* outSz Length of message in bytes.
* key The public X25519 key data.
* keySz The length of the private key data in bytes.
* ctx The callback context.
* returns 0 on succes, otherwise the valus is an error.
*/
int Ed25519Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg,
word32 msgSz, ed25519_key* key, byte* keyBuf, word32 keySz,
void* ctx)
{
int ret;
(void)ssl;
(void)keyBuf;
(void)keySz;
(void)ctx;
WOLFSSL_ENTER("Ed25519Verify");
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->Ed25519VerifyCb) {
ret = ssl->ctx->Ed25519VerifyCb(ssl, in, inSz, msg, msgSz, keyBuf,
keySz, &ssl->eccVerifyRes, ctx);
}
else
#endif /* HAVE_PK_CALLBACKS */
{
ret = wc_ed25519_verify_msg(in, inSz, msg, msgSz,
&ssl->eccVerifyRes, key);
}
/* Handle async pending response */
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_PENDING_E) {
ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
}
else
#endif /* WOLFSSL_ASYNC_CRYPT */
{
ret = (ret != 0 || ssl->eccVerifyRes == 0) ? VERIFY_SIGN_ERROR : 0;
}
WOLFSSL_LEAVE("Ed25519Verify", ret);
return ret;
}
#endif /* HAVE_ED25519 */
#ifdef HAVE_CURVE25519
#ifdef HAVE_PK_CALLBACKS
@@ -4179,6 +4297,11 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey)
wc_ecc_free((ecc_key*)*pKey);
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case DYNAMIC_TYPE_ED25519:
wc_ed25519_free((ed25519_key*)*pKey);
break;
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_CURVE25519
case DYNAMIC_TYPE_CURVE25519:
wc_curve25519_free((curve25519_key*)*pKey);
@@ -4216,26 +4339,31 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
/* Determine size */
switch (type) {
#ifndef NO_RSA
#ifndef NO_RSA
case DYNAMIC_TYPE_RSA:
sz = sizeof(RsaKey);
break;
#endif /* ! NO_RSA */
#ifdef HAVE_ECC
#endif /* ! NO_RSA */
#ifdef HAVE_ECC
case DYNAMIC_TYPE_ECC:
sz = sizeof(ecc_key);
break;
#endif /* HAVE_ECC */
#ifdef HAVE_CURVE25519
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case DYNAMIC_TYPE_ED25519:
sz = sizeof(ed25519_key);
break;
#endif /* HAVE_ED25519 */
#ifdef HAVE_CURVE25519
case DYNAMIC_TYPE_CURVE25519:
sz = sizeof(curve25519_key);
break;
#endif /* HAVE_CURVE25519 */
#ifndef NO_DH
#endif /* HAVE_CURVE25519 */
#ifndef NO_DH
case DYNAMIC_TYPE_DH:
sz = sizeof(DhKey);
break;
#endif /* !NO_DH */
#endif /* !NO_DH */
default:
return BAD_FUNC_ARG;
}
@@ -4262,6 +4390,12 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
ret = wc_ecc_init_ex((ecc_key*)*pKey, ssl->heap, ssl->devId);
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case DYNAMIC_TYPE_ED25519:
wc_ed25519_init((ed25519_key*)*pKey);
ret = 0;
break;
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_CURVE25519
case DYNAMIC_TYPE_CURVE25519:
wc_curve25519_init((curve25519_key*)*pKey);
@@ -4303,6 +4437,12 @@ static int ReuseKey(WOLFSSL* ssl, int type, void* pKey)
ret = wc_ecc_init_ex((ecc_key*)pKey, ssl->heap, ssl->devId);
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case DYNAMIC_TYPE_ED25519:
wc_ed25519_free((ed25519_key*)pKey);
wc_ed25519_init((ed25519_key*)pKey);
break;
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_CURVE25519
case DYNAMIC_TYPE_CURVE25519:
wc_curve25519_free((curve25519_key*)pKey);
@@ -4447,6 +4587,10 @@ void SSL_ResourceFree(WOLFSSL* ssl)
ssl->peerX25519KeyPresent = 0;
#endif
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
FreeKey(ssl, DYNAMIC_TYPE_ED25519, (void**)&ssl->peerEd25519Key);
ssl->peerEd25519KeyPresent = 0;
#endif
#ifdef HAVE_PK_CALLBACKS
#ifdef HAVE_ECC
XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
@@ -7640,6 +7784,17 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz
}
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ED25519k:
if (ssl->options.minEccKeySz < 0 ||
ED25519_KEY_SIZE <
(word16)ssl->options.minEccKeySz) {
WOLFSSL_MSG(
"ECC key size in cert chain error");
ret = ECC_KEY_SIZE_E;
}
break;
#endif /* HAVE_ED25519 */
default:
WOLFSSL_MSG("Key size not checked");
/* key not being checked for size if not in
@@ -8098,7 +8253,6 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz
else {
ssl->peerEccDsaKeyPresent = 1;
#ifdef HAVE_PK_CALLBACKS
#ifdef HAVE_ECC
ssl->buffers.peerEccDsaKey.buffer =
(byte*)XMALLOC(args->dCert->pubKeySize,
ssl->heap, DYNAMIC_TYPE_ECC);
@@ -8112,7 +8266,6 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz
ssl->buffers.peerEccDsaKey.length =
args->dCert->pubKeySize;
}
#endif /* HAVE_ECC */
#endif /*HAVE_PK_CALLBACKS */
}
@@ -8126,6 +8279,56 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz
}
break;
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ED25519k:
{
int keyRet = 0;
if (ssl->peerEd25519Key == NULL) {
/* alloc/init on demand */
keyRet = AllocKey(ssl, DYNAMIC_TYPE_ECC,
(void**)&ssl->peerEd25519Key);
} else if (ssl->peerEd25519KeyPresent) {
keyRet = ReuseKey(ssl, DYNAMIC_TYPE_ECC,
ssl->peerEd25519Key);
ssl->peerEd25519KeyPresent = 0;
}
if (keyRet != 0 ||
wc_ed25519_import_public(args->dCert->publicKey,
args->dCert->pubKeySize,
ssl->peerEd25519Key)
!= 0) {
ret = PEER_KEY_ERROR;
}
else {
ssl->peerEd25519KeyPresent = 1;
#ifdef HAVE_PK_CALLBACKS
ssl->buffers.peerEd25519Key.buffer =
(byte*)XMALLOC(args->dCert->pubKeySize,
ssl->heap, DYNAMIC_TYPE_ECC);
if (ssl->buffers.peerEd25519Key.buffer == NULL) {
ERROR_OUT(MEMORY_ERROR, exit_ppc);
}
else {
XMEMCPY(ssl->buffers.peerEd25519Key.buffer,
args->dCert->publicKey,
args->dCert->pubKeySize);
ssl->buffers.peerEd25519Key.length =
args->dCert->pubKeySize;
}
#endif /*HAVE_PK_CALLBACKS */
}
/* check size of peer ECC key */
if (ret == 0 && ssl->peerEd25519KeyPresent &&
!ssl->options.verifyNone &&
ED25519_KEY_SIZE < ssl->options.minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("Peer ECC key is too small");
}
break;
}
#endif /* HAVE_ECC */
default:
break;
@@ -15177,6 +15380,17 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
byte hashAlgo = 0, sigAlgo = 0;
DecodeSigAlg(&hashSigAlgo[i], &hashAlgo, &sigAlgo);
#ifdef HAVE_ECC
if (ssl->pkCurveOID == ECC_ED25519_OID && sigAlgo != ed25519_sa_algo)
continue;
if (sigAlgo == ed25519_sa_algo &&
ssl->specs.sig_algo == ecc_dsa_sa_algo) {
ssl->suites->sigAlgo = sigAlgo;
ssl->suites->hashAlgo = sha512_mac;
break;
}
#endif
if (sigAlgo == ssl->specs.sig_algo || (sigAlgo == rsa_pss_sa_algo &&
ssl->specs.sig_algo == rsa_sa_algo)) {
if (hashAlgo == sha_mac) {
@@ -16756,15 +16970,6 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
}
ssl->buffers.sig.length = SEED_LEN + verifySz;
/* buffer for hash */
ssl->buffers.digest.length = wc_HashGetDigestSize(hashType);
ssl->buffers.digest.buffer = (byte*)XMALLOC(
ssl->buffers.digest.length, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (ssl->buffers.digest.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_dske);
}
/* build message to hash */
XMEMCPY(ssl->buffers.sig.buffer,
ssl->arrays->clientRandom, RAN_LEN);
@@ -16773,12 +16978,25 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN * 2],
input + args->begin, verifySz); /* message */
/* Perform hash */
ret = wc_Hash(hashType,
ssl->buffers.sig.buffer, ssl->buffers.sig.length,
ssl->buffers.digest.buffer, ssl->buffers.digest.length);
if (ret != 0) {
goto exit_dske;
if (args->sigAlgo != ed25519_sa_algo) {
/* buffer for hash */
ssl->buffers.digest.length =
wc_HashGetDigestSize(hashType);
ssl->buffers.digest.buffer = (byte*)XMALLOC(
ssl->buffers.digest.length, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (ssl->buffers.digest.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_dske);
}
/* Perform hash */
ret = wc_Hash(hashType, ssl->buffers.sig.buffer,
ssl->buffers.sig.length,
ssl->buffers.digest.buffer,
ssl->buffers.digest.length);
if (ret != 0) {
goto exit_dske;
}
}
switch (args->sigAlgo)
@@ -16805,6 +17023,15 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
break;
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ed25519_sa_algo:
{
if (!ssl->peerEd25519KeyPresent) {
ERROR_OUT(NO_PEER_KEY, exit_dske);
}
break;
}
#endif /* HAVE_ECC */
default:
ret = ALGO_ID_E;
@@ -16908,6 +17135,26 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
break;
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ed25519_sa_algo:
{
ret = Ed25519Verify(ssl,
args->verifySig, args->verifySigSz,
ssl->buffers.sig.buffer,
ssl->buffers.sig.length,
ssl->peerEd25519Key,
#ifdef HAVE_PK_CALLBACKS
ssl->buffers.peerEccDsaKey.buffer,
ssl->buffers.peerEccDsaKey.length,
ssl->Ed25519VerifyCtx
#else
NULL, 0, NULL
#endif
);
break;
}
#endif /* HAVE_ECC */
default:
ret = ALGO_ID_E;
@@ -17016,6 +17263,11 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
case ecc_dsa_sa_algo:
/* Nothing to do in this algo */
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ed25519_sa_algo:
/* Nothing to do in this algo */
break;
#endif /* HAVE_ECC */
default:
ret = ALGO_ID_E;
@@ -18582,22 +18834,61 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
(ecc_key*)ssl->hsKey,
ssl->buffers.key->length);
if (ret == 0) {
WOLFSSL_MSG("Using ECC private key");
/* Check it meets the minimum ECC key size requirements. */
keySz = wc_ecc_size((ecc_key*)ssl->hsKey);
if (keySz < ssl->options.minEccKeySz) {
WOLFSSL_MSG("ECC key size too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
}
/* Return the maximum signature length. */
*length = wc_ecc_sig_size((ecc_key*)ssl->hsKey);
goto exit_dpk;
}
#endif
#ifdef HAVE_ED25519
#if !defined(NO_RSA) || defined(HAVE_ECC)
FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey);
#endif
ssl->hsType = DYNAMIC_TYPE_ED25519;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ret != 0) {
WOLFSSL_MSG("Bad client cert type");
goto exit_dpk;
}
WOLFSSL_MSG("Using ECC private key");
#ifdef HAVE_ECC
WOLFSSL_MSG("Trying ED25519 private key, ECC didn't work");
#elif !defined(NO_RSA)
WOLFSSL_MSG("Trying ED25519 private key, RSA didn't work");
#else
WOLFSSL_MSG("Trying ED25519 private key");
#endif
/* Check it meets the minimum ECC key size requirements. */
keySz = wc_ecc_size((ecc_key*)ssl->hsKey);
if (keySz < ssl->options.minEccKeySz) {
WOLFSSL_MSG("ECC key size too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
/* Set start of data to beginning of buffer. */
idx = 0;
/* Decode the key assuming it is an ED25519 private key. */
ret = wc_Ed25519PrivateKeyDecode(ssl->buffers.key->buffer, &idx,
(ed25519_key*)ssl->hsKey,
ssl->buffers.key->length);
if (ret == 0) {
WOLFSSL_MSG("Using ED25519 private key");
/* Check it meets the minimum ECC key size requirements. */
if (ED25519_KEY_SIZE < ssl->options.minEccKeySz) {
WOLFSSL_MSG("ED25519 key size too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
}
/* Return the maximum signature length. */
*length = ED25519_SIG_SIZE;
goto exit_dpk;
}
/* Return the maximum signature length. */
*length = wc_ecc_sig_size((ecc_key*)ssl->hsKey);
#endif
exit_dpk:
@@ -18755,6 +19046,8 @@ int SendCertificateVerify(WOLFSSL* ssl)
}
else if (ssl->hsType == DYNAMIC_TYPE_ECC)
args->sigAlgo = ecc_dsa_sa_algo;
else if (ssl->hsType == DYNAMIC_TYPE_ED25519)
args->sigAlgo = ed25519_sa_algo;
if (IsAtLeastTLSv1_2(ssl)) {
EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo,
@@ -18821,6 +19114,24 @@ int SendCertificateVerify(WOLFSSL* ssl)
);
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
ed25519_key* key = (ed25519_key*)ssl->hsKey;
ret = Ed25519Sign(ssl,
ssl->buffers.digest.buffer, ssl->buffers.digest.length,
ssl->buffers.sig.buffer, &ssl->buffers.sig.length,
key,
#if defined(HAVE_PK_CALLBACKS)
ssl->buffers.key->buffer,
ssl->buffers.key->length,
ssl->Ed25519SignCtx
#else
NULL, 0, NULL
#endif
);
}
#endif /* HAVE_ECC */
#ifndef NO_RSA
if (ssl->hsType == DYNAMIC_TYPE_RSA) {
RsaKey* key = (RsaKey*)ssl->hsKey;
@@ -18867,6 +19178,16 @@ int SendCertificateVerify(WOLFSSL* ssl)
ssl->buffers.sig.buffer, ssl->buffers.sig.length);
}
#endif /* HAVE_ECC */
#ifdef HAVE_ECC
if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
args->length = ssl->buffers.sig.length;
/* prepend hdr */
c16toa((word16)ssl->buffers.sig.length, args->verify +
args->extraSz);
XMEMCPY(args->verify + args->extraSz + VERIFY_HEADER,
ssl->buffers.sig.buffer, ssl->buffers.sig.length);
}
#endif /* HAVE_ECC */
#ifndef NO_RSA
if (ssl->hsType == DYNAMIC_TYPE_RSA) {
RsaKey* key = (RsaKey*)ssl->hsKey;
@@ -19991,6 +20312,38 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
break;
}
#ifdef HAVE_ED25519
case ed25519_sa_algo:
{
word32 i = 0;
ssl->hsType = DYNAMIC_TYPE_ED25519;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ret != 0) {
goto exit_sske;
}
ret = wc_Ed25519PrivateKeyDecode(
ssl->buffers.key->buffer,
&i,
(ed25519_key*)ssl->hsKey,
ssl->buffers.key->length);
if (ret != 0) {
goto exit_sske;
}
/* worst case estimate */
args->tmpSigSz = ED25519_SIG_SIZE;
/* check the minimum ECC key size */
if (ED25519_KEY_SIZE <
ssl->options.minEccKeySz) {
WOLFSSL_MSG("Ed25519 key size too small");
ret = ECC_KEY_SIZE_E;
goto exit_sske;
}
break;
}
#endif
default:
ERROR_OUT(ALGO_ID_E, exit_sske); /* unsupported type */
} /* switch(ssl->specs.sig_algo) */
@@ -20091,20 +20444,24 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
XMEMCPY(args->sigDataBuf+RAN_LEN+RAN_LEN,
args->output + preSigIdx, preSigSz);
ssl->buffers.sig.length = wc_HashGetDigestSize(hashType);
ssl->buffers.sig.buffer = (byte*)XMALLOC(
if (ssl->suites->sigAlgo != ed25519_sa_algo) {
ssl->buffers.sig.length =
wc_HashGetDigestSize(hashType);
ssl->buffers.sig.buffer = (byte*)XMALLOC(
ssl->buffers.sig.length,
ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ssl->buffers.sig.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
if (ssl->buffers.sig.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
/* Perform hash */
ret = wc_Hash(hashType,
args->sigDataBuf, args->sigDataSz,
ssl->buffers.sig.buffer, ssl->buffers.sig.length);
if (ret != 0) {
goto exit_sske;
/* Perform hash */
ret = wc_Hash(hashType, args->sigDataBuf,
args->sigDataSz,
ssl->buffers.sig.buffer,
ssl->buffers.sig.length);
if (ret != 0) {
goto exit_sske;
}
}
args->sigSz = args->tmpSigSz;
@@ -20151,6 +20508,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
break;
#endif
#endif /* !NO_RSA */
#ifdef HAVE_ED25519
case ed25519_sa_algo:
#endif
case ecc_dsa_sa_algo:
{
break;
@@ -20321,20 +20681,24 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
XMEMCPY(args->sigDataBuf+RAN_LEN+RAN_LEN,
args->output + preSigIdx, preSigSz);
ssl->buffers.sig.length = wc_HashGetDigestSize(hashType);
ssl->buffers.sig.buffer = (byte*)XMALLOC(
if (ssl->suites->sigAlgo != ed25519_sa_algo) {
ssl->buffers.sig.length =
wc_HashGetDigestSize(hashType);
ssl->buffers.sig.buffer = (byte*)XMALLOC(
ssl->buffers.sig.length, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (ssl->buffers.sig.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
if (ssl->buffers.sig.buffer == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
/* Perform hash */
ret = wc_Hash(hashType,
args->sigDataBuf, args->sigDataSz,
ssl->buffers.sig.buffer, ssl->buffers.sig.length);
if (ret != 0) {
goto exit_sske;
/* Perform hash */
ret = wc_Hash(hashType, args->sigDataBuf,
args->sigDataSz,
ssl->buffers.sig.buffer,
ssl->buffers.sig.length);
if (ret != 0) {
goto exit_sske;
}
}
args->sigSz = args->tmpSigSz;
@@ -20458,6 +20822,27 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
);
break;
}
#ifdef HAVE_ED25519
case ed25519_sa_algo:
{
ed25519_key* key = (ed25519_key*)ssl->hsKey;
ret = Ed25519Sign(ssl,
args->sigDataBuf, args->sigDataSz,
args->output + LENGTH_SZ + args->idx,
&args->sigSz,
key,
#if defined(HAVE_PK_CALLBACKS)
ssl->buffers.key->buffer,
ssl->buffers.key->length,
ssl->Ed25519SignCtx
#else
NULL, 0, NULL
#endif
);
break;
}
#endif
} /* switch(ssl->specs.sig_algo) */
break;
}
@@ -20589,6 +20974,19 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->sendSz += args->sigSz - args->tmpSigSz;
break;
}
#ifdef HAVE_ED25519
case ed25519_sa_algo:
{
/* Now that we know the real sig size, write it. */
c16toa((word16)args->sigSz,
args->output + args->idx);
/* And adjust length and sendSz from estimates */
args->length += args->sigSz - args->tmpSigSz;
args->sendSz += args->sigSz - args->tmpSigSz;
break;
}
#endif
default:
ERROR_OUT(ALGO_ID_E, exit_sske); /* unsupported type */
} /* switch(ssl->specs.sig_algo) */
@@ -21714,6 +22112,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
else if (ssl->peerEccDsaKeyPresent)
args->sigAlgo = ecc_dsa_sa_algo;
#endif
#ifdef HAVE_ED25519
else if (ssl->peerEd25519KeyPresent)
args->sigAlgo = ed25519_sa_algo;
#endif
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
ERROR_OUT(BUFFER_ERROR, exit_dcv);
@@ -21754,6 +22156,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (ssl->peerEd25519KeyPresent) {
WOLFSSL_MSG("Doing ED25519 peer cert verify");
if (IsAtLeastTLSv1_2(ssl) &&
args->sigAlgo != ed25519_sa_algo) {
WOLFSSL_MSG(
"Oops, peer sent ED25519 key but not in verify");
}
}
#endif /* HAVE_ED25519 */
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_DO;

179
src/ssl.c
View File

@@ -3635,6 +3635,15 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
}
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ED25519k:
if (cm->minEccKeySz < 0 ||
ED25519_KEY_SIZE < (word16)cm->minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("\tCA ECC key size error");
}
break;
#endif /* HAVE_ED25519 */
default:
WOLFSSL_MSG("\tNo key size check done on CA");
@@ -4375,6 +4384,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
DerBuffer* der = NULL; /* holds DER or RAW (for NTRU) */
int ret = 0;
int eccKey = 0;
int ed25519Key = 0;
int rsaKey = 0;
int resetSuites = 0;
void* heap = ctx ? ctx->heap : ((ssl) ? ssl->heap : NULL);
@@ -4574,7 +4584,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
#ifndef NO_RSA
if (!eccKey) {
if (!eccKey && !ed25519Key) {
/* make sure RSA key can be used */
word32 idx = 0;
#ifdef WOLFSSL_SMALL_STACK
@@ -4638,40 +4648,83 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
}
#endif
#ifdef HAVE_ECC
if (!rsaKey) {
if (!rsaKey && !ed25519Key) {
/* make sure ECC key can be used */
word32 idx = 0;
ecc_key key;
ret = wc_ecc_init_ex(&key, heap, devId);
if (wc_ecc_init_ex(&key, heap, devId) == 0) {
if (wc_EccPrivateKeyDecode(der->buffer, &idx, &key,
der->length) == 0) {
/* check for minimum ECC key size and then free */
if (ssl) {
if (wc_ecc_size(&key) < ssl->options.minEccKeySz) {
wc_ecc_free(&key);
WOLFSSL_MSG("ECC private key too small");
return ECC_KEY_SIZE_E;
}
}
else if (ctx) {
if (wc_ecc_size(&key) < ctx->minEccKeySz) {
wc_ecc_free(&key);
WOLFSSL_MSG("ECC private key too small");
return ECC_KEY_SIZE_E;
}
}
eccKey = 1;
if (ssl) {
ssl->options.haveStaticECC = 1;
}
else if (ctx) {
ctx->haveStaticECC = 1;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
resetSuites = 1;
}
}
wc_ecc_free(&key);
}
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (!rsaKey && !eccKey) {
/* make sure Ed25519 key can be used */
word32 idx = 0;
ed25519_key key;
ret = wc_ed25519_init(&key);
if (ret != 0) {
return ret;
}
if (wc_EccPrivateKeyDecode(der->buffer, &idx, &key,
der->length) != 0) {
wc_ecc_free(&key);
if (wc_Ed25519PrivateKeyDecode(der->buffer, &idx, &key,
der->length) != 0) {
wc_ed25519_free(&key);
return SSL_BAD_FILE;
}
/* check for minimum ECC key size and then free */
if (ssl) {
if (wc_ecc_size(&key) < ssl->options.minEccKeySz) {
wc_ecc_free(&key);
WOLFSSL_MSG("ECC private key too small");
if (ED25519_KEY_SIZE < ssl->options.minEccKeySz) {
wc_ed25519_free(&key);
WOLFSSL_MSG("ED25519 private key too small");
return ECC_KEY_SIZE_E;
}
}
else if (ctx) {
if (wc_ecc_size(&key) < ctx->minEccKeySz) {
wc_ecc_free(&key);
WOLFSSL_MSG("ECC private key too small");
if (ED25519_KEY_SIZE < ctx->minEccKeySz) {
wc_ed25519_free(&key);
WOLFSSL_MSG("ED25519 private key too small");
return ECC_KEY_SIZE_E;
}
}
wc_ecc_free(&key);
eccKey = 1;
wc_ed25519_free(&key);
ed25519Key = 1;
if (ssl) {
ssl->options.haveStaticECC = 1;
}
@@ -4683,7 +4736,12 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
resetSuites = 1;
}
}
#endif /* HAVE_ECC */
#endif
if (!rsaKey && !eccKey && !ed25519Key)
return SSL_BAD_FILE;
(void)ed25519Key;
}
else if (type == CERT_TYPE) {
#ifdef WOLFSSL_SMALL_STACK
@@ -4730,6 +4788,13 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
else if (ctx)
ctx->haveECDSAsig = 1;
break;
case CTC_ED25519:
WOLFSSL_MSG("ED25519 cert signature");
if (ssl)
ssl->options.haveECDSAsig = 1;
else if (ctx)
ctx->haveECDSAsig = 1;
break;
default:
WOLFSSL_MSG("Not ECDSA cert signature");
break;
@@ -4742,6 +4807,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
if (cert->keyOID == ECDSAk) {
ssl->options.haveECC = 1;
}
#ifdef HAVE_ED25519
else if (cert->keyOID == ED25519k) {
ssl->options.haveECC = 1;
}
#endif
#else
ssl->options.haveECC = ssl->options.haveECDSAsig;
#endif
@@ -4752,6 +4822,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
if (cert->keyOID == ECDSAk) {
ctx->haveECC = 1;
}
#ifdef HAVE_ED25519
else if (cert->keyOID == ED25519k) {
ctx->haveECC = 1;
}
#endif
#else
ctx->haveECC = ctx->haveECDSAsig;
#endif
@@ -4777,7 +4852,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
}
}
break;
#endif /* !NO_RSA */
#endif /* !NO_RSA */
#ifdef HAVE_ECC
case ECDSAk:
if (ssl && !ssl->options.verifyNone) {
@@ -4795,7 +4870,25 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
}
}
break;
#endif /* HAVE_ECC */
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ED25519k:
if (ssl && !ssl->options.verifyNone) {
if (ssl->options.minEccKeySz < 0 ||
ED25519_KEY_SIZE < (word16)ssl->options.minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("Certificate Ed key size error");
}
}
else if (ctx && !ctx->verifyNone) {
if (ctx->minEccKeySz < 0 ||
ED25519_KEY_SIZE < (word16)ctx->minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("Certificate ECC key size error");
}
}
break;
#endif /* HAVE_ED25519 */
default:
WOLFSSL_MSG("No key size check done on certificate");
@@ -22022,6 +22115,54 @@ void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
return NULL;
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
void wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX* ctx, CallbackEd25519Sign cb)
{
if (ctx)
ctx->Ed25519SignCb = cb;
}
void wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx)
{
if (ssl)
ssl->Ed25519SignCtx = ctx;
}
void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl)
{
if (ssl)
return ssl->Ed25519SignCtx;
return NULL;
}
void wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX* ctx, CallbackEd25519Verify cb)
{
if (ctx)
ctx->Ed25519VerifyCb = cb;
}
void wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx)
{
if (ssl)
ssl->Ed25519VerifyCtx = ctx;
}
void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl)
{
if (ssl)
return ssl->Ed25519VerifyCtx;
return NULL;
}
#endif
#ifdef HAVE_CURVE25519
void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX* ctx,
@@ -22046,7 +22187,6 @@ void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
return NULL;
}
#endif
#endif /* HAVE_ECC */
#ifndef NO_RSA
@@ -22365,6 +22505,9 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
case RSAk:
ctx->haveRSA = 1;
break;
#ifdef HAVE_ED25519
case ED25519k:
#endif
case ECDSAk:
ctx->haveECC = 1;
ctx->pkCurveOID = x->pkCurveOID;

112
src/tls.c
View File

@@ -2985,6 +2985,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
: NULL;
EllipticCurve* curve = NULL;
word32 oid = 0;
word32 pkOid = 0;
word32 defOid = 0;
word32 defSz = 80; /* Maximum known curve size is 66. */
word32 nextOid = 0;
@@ -3009,19 +3010,19 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
#if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP160R1:
oid = ECC_SECP160R1_OID;
pkOid = oid = ECC_SECP160R1_OID;
octets = 20;
break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_SECPR2
case WOLFSSL_ECC_SECP160R2:
oid = ECC_SECP160R2_OID;
pkOid = oid = ECC_SECP160R2_OID;
octets = 20;
break;
#endif /* HAVE_ECC_SECPR2 */
#ifdef HAVE_ECC_KOBLITZ
case WOLFSSL_ECC_SECP160K1:
oid = ECC_SECP160K1_OID;
pkOid = oid = ECC_SECP160K1_OID;
octets = 20;
break;
#endif /* HAVE_ECC_KOBLITZ */
@@ -3029,13 +3030,13 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP192R1:
oid = ECC_SECP192R1_OID;
pkOid = oid = ECC_SECP192R1_OID;
octets = 24;
break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_KOBLITZ
case WOLFSSL_ECC_SECP192K1:
oid = ECC_SECP192K1_OID;
pkOid = oid = ECC_SECP192K1_OID;
octets = 24;
break;
#endif /* HAVE_ECC_KOBLITZ */
@@ -3043,13 +3044,13 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP224R1:
oid = ECC_SECP224R1_OID;
pkOid = oid = ECC_SECP224R1_OID;
octets = 28;
break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_KOBLITZ
case WOLFSSL_ECC_SECP224K1:
oid = ECC_SECP224K1_OID;
pkOid = oid = ECC_SECP224K1_OID;
octets = 28;
break;
#endif /* HAVE_ECC_KOBLITZ */
@@ -3057,25 +3058,30 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP256R1:
oid = ECC_SECP256R1_OID;
pkOid = oid = ECC_SECP256R1_OID;
octets = 32;
break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_CURVE25519
case WOLFSSL_ECC_X25519:
oid = ECC_X25519_OID;
#ifdef HAVE_ED25519
pkOid = ECC_ED25519_OID;
#else
pkOid = ECC_X25519_OID;
#endif
octets = 32;
break;
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_ECC_KOBLITZ
case WOLFSSL_ECC_SECP256K1:
oid = ECC_SECP256K1_OID;
pkOid = oid = ECC_SECP256K1_OID;
octets = 32;
break;
#endif /* HAVE_ECC_KOBLITZ */
#ifdef HAVE_ECC_BRAINPOOL
case WOLFSSL_ECC_BRAINPOOLP256R1:
oid = ECC_BRAINPOOLP256R1_OID;
pkOid = oid = ECC_BRAINPOOLP256R1_OID;
octets = 32;
break;
#endif /* HAVE_ECC_BRAINPOOL */
@@ -3083,13 +3089,13 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP384R1:
oid = ECC_SECP384R1_OID;
pkOid = oid = ECC_SECP384R1_OID;
octets = 48;
break;
#endif /* !NO_ECC_SECP */
#ifdef HAVE_ECC_BRAINPOOL
case WOLFSSL_ECC_BRAINPOOLP384R1:
oid = ECC_BRAINPOOLP384R1_OID;
pkOid = oid = ECC_BRAINPOOLP384R1_OID;
octets = 48;
break;
#endif /* HAVE_ECC_BRAINPOOL */
@@ -3097,7 +3103,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
#ifdef HAVE_ECC_BRAINPOOL
case WOLFSSL_ECC_BRAINPOOLP512R1:
oid = ECC_BRAINPOOLP512R1_OID;
pkOid = oid = ECC_BRAINPOOLP512R1_OID;
octets = 64;
break;
#endif /* HAVE_ECC_BRAINPOOL */
@@ -3105,7 +3111,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP521R1:
oid = ECC_SECP521R1_OID;
pkOid = oid = ECC_SECP521R1_OID;
octets = 66;
break;
#endif /* !NO_ECC_SECP */
@@ -3139,7 +3145,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
sig |= ssl->pkCurveOID == oid;
sig |= ssl->pkCurveOID == pkOid;
key |= ssl->ecdhCurveOID == oid;
ephmSuite = 1;
break;
@@ -3158,7 +3164,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
defOid = 0;
defSz = 80;
}
sig |= ssl->pkCurveOID == oid;
sig |= ssl->pkCurveOID == pkOid;
key |= ssl->pkCurveOID == oid;
break;
#endif /* WOLFSSL_STATIC_DH */
@@ -3192,7 +3198,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
defSz = 80;
}
sig = 1;
key |= ssl->pkCurveOID == oid;
key |= ssl->pkCurveOID == pkOid;
break;
#endif /* WOLFSSL_STATIC_DH */
#endif
@@ -3214,7 +3220,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
/* ECDHE_ECDSA */
case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
sig |= ssl->pkCurveOID == oid;
sig |= ssl->pkCurveOID == pkOid;
key |= ssl->ecdhCurveOID == oid;
ephmSuite = 1;
break;
@@ -6969,9 +6975,9 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
WOLFSSL_ECC_SECP256R1, ssl->heap);
if (ret != SSL_SUCCESS) return ret;
#endif
#ifdef HAVE_CURVE25519
#if defined(HAVE_CURVE25519)
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_ECC_X25519, ssl->heap);
WOLFSSL_ECC_X25519, ssl->heap);
if (ret != SSL_SUCCESS) return ret;
#endif
#ifdef HAVE_ECC_KOBLITZ
@@ -7028,38 +7034,40 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
ssl->heap)) != 0)
return ret;
/* Add FFDHE supported groups. */
#ifdef HAVE_FFDHE_2048
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_2048, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
#ifdef HAVE_FFDHE_3072
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_3072, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
#ifdef HAVE_FFDHE_4096
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_4096, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
#ifdef HAVE_FFDHE_6144
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_6144, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
#ifdef HAVE_FFDHE_8192
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_8192, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
ret = 0;
if (!ssl->options.userCurves && !ssl->ctx->userCurves) {
/* Add FFDHE supported groups. */
#ifdef HAVE_FFDHE_2048
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_2048, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
#ifdef HAVE_FFDHE_3072
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_3072, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
#ifdef HAVE_FFDHE_4096
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_4096, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
#ifdef HAVE_FFDHE_6144
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_6144, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
#ifdef HAVE_FFDHE_8192
ret = TLSX_UseSupportedCurve(&ssl->extensions,
WOLFSSL_FFDHE_8192, ssl->heap);
if (ret != SSL_SUCCESS)
return ret;
#endif
ret = 0;
}
if (TLSX_Find(ssl->extensions, TLSX_KEY_SHARE) == NULL) {
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \

View File

@@ -3087,6 +3087,13 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
output[0] = hashAlgo;
output[1] = ecc_dsa_sa_algo;
break;
#ifdef HAVE_ED25519
/* ED25519: 0x0807 */
case ed25519_sa_algo:
output[0] = ED25519_SA_MAJOR;
output[1] = ED25519_SA_MINOR;
break;
#endif
#endif
#ifndef NO_RSA
case rsa_sa_algo:
@@ -3101,7 +3108,6 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
break;
#endif
#endif
/* ED25519: 0x0807 */
/* ED448: 0x0808 */
}
}
@@ -3115,17 +3121,24 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
static INLINE void DecodeSigAlg(byte* input, byte* hashAlgo, byte* hsType)
{
switch (input[0]) {
case NEW_SA_MAJOR:
#ifdef WC_RSA_PSS
case 0x08:
/* PSS signatures: 0x080[4-6] */
if (input[1] <= 0x06) {
*hsType = input[0];
*hashAlgo = input[1];
}
break;
/* PSS signatures: 0x080[4-6] */
if (input[1] <= sha512_mac) {
*hsType = input[0];
*hashAlgo = input[1];
}
#endif
/* ED25519: 0x0807 */
/* ED448: 0x0808 */
#ifdef HAVE_ED25519
/* ED25519: 0x0807 */
if (input[1] == ED25519_SA_MINOR) {
*hsType = ed25519_sa_algo;
/* Hash performed as part of sign/verify operation. */
*hashAlgo = sha512_mac;
}
#endif
/* ED448: 0x0808 */
break;
default:
*hashAlgo = input[0];
*hsType = input[1];
@@ -3825,6 +3838,8 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
}
else if (ssl->hsType == DYNAMIC_TYPE_ECC)
args->sigAlgo = ecc_dsa_sa_algo;
else if (ssl->hsType == DYNAMIC_TYPE_ED25519)
args->sigAlgo = ed25519_sa_algo;
EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, args->verify);
/* Create the data to be signed. */
@@ -3869,6 +3884,12 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
ret = 0;
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
/* Nothing to do */
sig->length = ED25519_SIG_SIZE;
}
#endif /* HAVE_ECC */
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_DO;
@@ -3892,6 +3913,21 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
args->length = sig->length;
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
ret = Ed25519Sign(ssl, args->sigData, args->sigDataSz,
args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
&sig->length, (ed25519_key*)ssl->hsKey,
#if defined(HAVE_PK_CALLBACKS)
ssl->buffers.key->buffer, ssl->buffers.key->length,
ssl->Ed25519SignCtx
#else
NULL, 0, NULL
#endif
);
args->length = sig->length;
}
#endif
#ifndef NO_RSA
if (ssl->hsType == DYNAMIC_TYPE_RSA) {
/* restore verify pointer */
@@ -4154,6 +4190,10 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
}
/* Check for public key of required type. */
if (args->sigAlgo == ed25519_sa_algo &&
!ssl->peerEd25519KeyPresent) {
WOLFSSL_MSG("Oops, peer sent ED25519 key but not in verify");
}
if (args->sigAlgo == ecc_dsa_sa_algo &&
!ssl->peerEccDsaKeyPresent) {
WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
@@ -4191,6 +4231,20 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
ret = 0;
}
#endif
#ifdef HAVE_ED25519
if (ssl->peerEd25519KeyPresent) {
WOLFSSL_MSG("Doing ED25519 peer cert verify");
args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (args->sigData == NULL) {
ERROR_OUT(MEMORY_E, exit_dcv);
}
CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
ret = 0;
}
#endif
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_DO;
@@ -4237,6 +4291,23 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
);
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (ssl->peerEd25519KeyPresent) {
WOLFSSL_MSG("Doing ED25519 peer cert verify");
ret = Ed25519Verify(ssl, input + args->idx, args->sz,
args->sigData, args->sigDataSz,
ssl->peerEd25519Key,
#ifdef HAVE_PK_CALLBACKS
ssl->buffers.peerEd25519Key.buffer,
ssl->buffers.peerEd25519Key.length,
ssl->Ed25519VerifyCtx
#else
NULL, 0, NULL
#endif
);
}
#endif
/* Check for error */
if (ret != 0) {

View File

@@ -574,6 +574,16 @@ int SuiteTest(void)
exit(EXIT_FAILURE);
}
#endif
#if defined(HAVE_CURVE25519) && defined(HAVE_ED25519)
/* add ED25519 certificate cipher suite tests */
strcpy(argv0[1], "tests/test-ed25519.conf");
printf("starting ED25519 extra cipher suite tests\n");
test_harness(&args);
if (args.return_code != 0) {
printf("error from script %d\n", args.return_code);
exit(EXIT_FAILURE);
}
#endif
#ifdef WOLFSSL_DTLS
/* add dtls extra suites */
strcpy(argv0[1], "tests/test-dtls.conf");

56
tests/test-ed25519.conf Normal file
View File

@@ -0,0 +1,56 @@
# server TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256
-v 3
-l ECDHE-ECDSA-AES128-GCM-SHA256
-c ./certs/ed25519/server-ed25519.pem
-k ./certs/ed25519/server-ed25519-key.pem
# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256
-v 3
-l ECDHE-ECDSA-AES128-GCM-SHA256
-A ./certs/ed25519/root-ed25519.pem
-C
# Enable when CRL for ED25519 certificates available.
# server TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256
#-v 3
#-l ECDHE-ECDSA-AES128-GCM-SHA256
#-c ./certs/ed25519/server-ed25519.pem
#-k ./certs/ed25519/server-ed25519-key.pem
#-A ./certs/ed25519/client-ed25519.pem
# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256
#-v 3
#-l ECDHE-ECDSA-AES128-GCM-SHA256
#-c ./certs/ed25519/client-ed25519.pem
#-k ./certs/ed25519/client-ed25519-key.pem
#-A ./certs/ed25519/root-ed25519.pem
#-C
# server TLSv1.3 TLS13-AES128-GCM-SHA256
-v 4
-l TLS13-AES128-GCM-SHA256
-c ./certs/ed25519/server-ed25519.pem
-k ./certs/ed25519/server-ed25519-key.pem
# client TLSv1.3 TLS13-AES128-GCM-SHA256
-v 4
-l TLS13-AES128-GCM-SHA256
-A ./certs/ed25519/root-ed25519.pem
-C
# Enable when CRL for ED25519 certificates available.
# server TLSv1.3 TLS13-AES128-GCM-SHA256
#-v 4
#-l TLS13-AES128-GCM-SHA256
#-c ./certs/ed25519/server-ed25519.pem
#-k ./certs/ed25519/server-ed25519-key.pem
#-A ./certs/ed25519/client-ed25519.pem
# client TLSv1.3 TLS13-AES128-GCM-SHA256
#-v 4
#-l TLS13-AES128-GCM-SHA256
#-c ./certs/ed25519/client-ed25519.pem
#-k ./certs/ed25519/client-ed25519-key.pem
#-A ./certs/ed25519/root-ed25519.pem
#-C

View File

@@ -93,3 +93,15 @@
-l TLS13-AES128-CCM-8-SHA256
-A ./certs/server-ecc.pem
# server TLSv1.3 TLS13-AES128-GCM-SHA256
-v 4
-l TLS13-AES128-GCM-SHA256
-c ./certs/server-ecc.pem
-k ./certs/ecc-key.pem
# client TLSv1.3 TLS13-AES128-GCM-SHA256
-v 4
-l TLS13-AES128-GCM-SHA256
-A ./certs/server-ecc.pem
-t

View File

@@ -2178,3 +2178,15 @@
-l ECDHE-RSA-AES128-SHA256
-j
# server TLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305
-v 3
-l ECDHE-ECDSA-CHACHA20-POLY1305
-c ./certs/server-ecc.pem
-k ./certs/ecc-key.pem
# client TLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305
-v 3
-l ECDHE-ECDSA-CHACHA20-POLY1305
-A ./certs/server-ecc.pem
-t

View File

@@ -2502,7 +2502,7 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (*algoID != RSAk && *algoId != ECDSAk) {
if (*algoID != RSAk && *algoID != ECDSAk) {
if (wc_ed25519_init(&ed25519) == 0) {
if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, &ed25519, keySz)
== 0) {
@@ -3448,6 +3448,8 @@ static int GetKey(DecodedCert* cert)
{
int ret;
cert->pkCurveOID = ED25519k;
ret = CheckBitString(cert->source, &cert->srcIdx, &length,
cert->maxIdx, 1, NULL);
if (ret != 0)
@@ -4637,7 +4639,7 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
WOLFSSL_MSG("Hash for Signature has unsupported type");
}
return 0;
return ret;
}
/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
@@ -10228,6 +10230,15 @@ int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
return BAD_FUNC_ARG;
if (GetOctetString(input, inOutIdx, &privSz, inSz) >= 0) {
priv = input + *inOutIdx;
*inOutIdx += privSz;
if (*inOutIdx != inSz)
return ASN_PARSE_E;
return wc_ed25519_import_private_only(priv, privSz, key);
}
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
endKeyIdx = *inOutIdx + length;

View File

@@ -72,6 +72,9 @@
#ifdef HAVE_ECC
#include <wolfssl/wolfcrypt/ecc.h>
#endif
#ifdef HAVE_ED25519
#include <wolfssl/wolfcrypt/ed25519.h>
#endif
#ifdef HAVE_CURVE25519
#include <wolfssl/wolfcrypt/curve25519.h>
#endif
@@ -909,7 +912,7 @@ enum Misc {
ECC_BYTE = 0xC0, /* ECC first cipher suite byte */
QSH_BYTE = 0xD0, /* Quantum-safe Handshake cipher suite */
CHACHA_BYTE = 0xCC, /* ChaCha first cipher suite */
TLS13_BYTE = 0x13, /* TLS v.13 first byte of cipher suite */
TLS13_BYTE = 0x13, /* TLS v1.3 first byte of cipher suite */
SEND_CERT = 1,
SEND_BLANK_CERT = 2,
@@ -1093,6 +1096,12 @@ enum Misc {
ECDHE_SIZE = 32, /* ECHDE server size defaults to 256 bit */
MAX_EXPORT_ECC_SZ = 256, /* Export ANS X9.62 max future size */
NEW_SA_MAJOR = 8, /* Most signicant byte used with new sig algos */
ED25519_SA_MAJOR = 8, /* Most significant byte for ED25519 */
ED25519_SA_MINOR = 7, /* Least significant byte for ED25519 */
ED448_SA_MAJOR = 8, /* Most significant byte for ED448 */
ED448_SA_MINOR = 8, /* Least significant byte for ED448 */
#ifdef HAVE_QSH
/* qsh handshake sends 600+ size keys over hello extensions */
MAX_HELLO_SZ = 2048, /* max client or server hello */
@@ -2263,6 +2272,12 @@ struct WOLFSSL_CTX {
CallbackEccSign EccSignCb; /* User EccSign Callback handler */
CallbackEccVerify EccVerifyCb; /* User EccVerify Callback handler */
CallbackEccSharedSecret EccSharedSecretCb; /* User EccVerify Callback handler */
#ifdef HAVE_ED25519
/* User Ed25519Sign Callback handler */
CallbackEd25519Sign Ed25519SignCb;
/* User Ed25519Verify Callback handler */
CallbackEd25519Verify Ed25519VerifyCb;
#endif
#ifdef HAVE_CURVE25519
/* User EccSharedSecret Callback handler */
CallbackX25519SharedSecret X25519SharedSecretCb;
@@ -2374,7 +2389,8 @@ enum SignatureAlgorithm {
rsa_sa_algo = 1,
dsa_sa_algo = 2,
ecc_dsa_sa_algo = 3,
rsa_pss_sa_algo = 8
rsa_pss_sa_algo = 8,
ed25519_sa_algo = 9
};
@@ -2637,6 +2653,9 @@ typedef struct Buffers {
#ifdef HAVE_ECC
buffer peerEccDsaKey; /* we own for Ecc Verify Callbacks */
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
buffer peerEd25519Key; /* for Ed25519 Verify Callbacks */
#endif /* HAVE_ED25519 */
#ifndef NO_RSA
buffer peerRsaKey; /* we own for Rsa Verify Callbacks */
#endif /* NO_RSA */
@@ -3134,6 +3153,10 @@ struct WOLFSSL {
byte peerEccKeyPresent;
byte peerEccDsaKeyPresent;
byte eccTempKeyPresent;
#ifdef HAVE_ED25519
ed25519_key* peerEd25519Key;
byte peerEd25519KeyPresent;
#endif
#ifdef HAVE_CURVE25519
curve25519_key* peerX25519Key;
byte peerX25519KeyPresent;
@@ -3241,6 +3264,10 @@ struct WOLFSSL {
void* EccSignCtx; /* Ecc Sign Callback Context */
void* EccVerifyCtx; /* Ecc Verify Callback Context */
void* EccSharedSecretCtx; /* Ecc Pms Callback Context */
#ifdef HAVE_ED25519
void* Ed25519SignCtx; /* ED25519 Sign Callback Context */
void* Ed25519VerifyCtx; /* ED25519 Verify Callback Context */
#endif
#ifdef HAVE_CURVE25519
void* X25519SharedSecretCtx; /* X25519 Pms Callback Context */
#endif
@@ -3472,6 +3499,15 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl);
ecc_key* pub_key, byte* pubKeyDer, word32* pubKeySz, byte* out,
word32* outlen, int side, void* ctx);
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
WOLFSSL_LOCAL int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, ed25519_key* key, byte* keyBuf,
word32 keySz, void* ctx);
WOLFSSL_LOCAL int Ed25519Verify(WOLFSSL* ssl, const byte* in,
word32 inSz, const byte* msg, word32 msgSz, ed25519_key* key,
byte* keyBuf, word32 keySz, void* ctx);
#endif /* HAVE_ED25519 */
#ifdef WOLFSSL_TRUST_PEER_CERT

View File

@@ -1506,6 +1506,27 @@ WOLFSSL_API void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX*, CallbackEccShar
WOLFSSL_API void wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx);
WOLFSSL_API void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl);
struct ed25519_key;
typedef int (*CallbackEd25519Sign)(WOLFSSL* ssl,
const unsigned char* in, unsigned int inSz,
unsigned char* out, unsigned int* outSz,
const unsigned char* keyDer, unsigned int keySz,
void* ctx);
WOLFSSL_API void wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX*,
CallbackEd25519Sign);
WOLFSSL_API void wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx);
WOLFSSL_API void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl);
typedef int (*CallbackEd25519Verify)(WOLFSSL* ssl,
const unsigned char* sig, unsigned int sigSz,
const unsigned char* msg, unsigned int msgSz,
const unsigned char* keyDer, unsigned int keySz,
int* result, void* ctx);
WOLFSSL_API void wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX*,
CallbackEd25519Verify);
WOLFSSL_API void wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx);
WOLFSSL_API void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl);
struct curve25519_key;
typedef int (*CallbackX25519SharedSecret)(WOLFSSL* ssl,
struct curve25519_key* otherKey,

View File

@@ -24,6 +24,9 @@
#ifdef HAVE_ECC
#include <wolfssl/wolfcrypt/ecc.h>
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
#include <wolfssl/wolfcrypt/ed25519.h>
#endif /* HAVE_ED25519 */
#ifdef HAVE_CURVE25519
#include <wolfssl/wolfcrypt/curve25519.h>
#endif /* HAVE_ECC */
@@ -1828,6 +1831,52 @@ static INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey,
return ret;
}
#ifdef HAVE_ED25519
static INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
{
int ret;
word32 idx = 0;
ed25519_key myKey;
(void)ssl;
(void)ctx;
ret = wc_ed25519_init(&myKey);
if (ret == 0) {
ret = wc_Ed25519PrivateKeyDecode(key, &idx, &myKey, keySz);
if (ret == 0)
ret = wc_ed25519_sign_msg(in, inSz, out, outSz, &myKey);
wc_ed25519_free(&myKey);
}
return ret;
}
static INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
const byte* msg, word32 msgSz, const byte* key, word32 keySz,
int* result, void* ctx)
{
int ret;
ed25519_key myKey;
(void)ssl;
(void)ctx;
ret = wc_ed25519_init(&myKey);
if (ret == 0) {
ret = wc_ed25519_import_public(key, keySz, &myKey);
if (ret == 0) {
ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, result, &myKey);
}
wc_ed25519_free(&myKey);
}
return ret;
}
#endif /* HAVE_ED25519 */
#ifdef HAVE_CURVE25519
static INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey,
unsigned char* pubKeyDer, unsigned int* pubKeySz,
@@ -2121,10 +2170,14 @@ static INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret);
#ifdef HAVE_CURVE25519
wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret);
#endif
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign);
wolfSSL_CTX_SetEd25519VerifyCb(ctx, myEd25519Verify);
#endif
#ifdef HAVE_CURVE25519
wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret);
#endif
#ifndef NO_RSA
wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);

View File

@@ -287,6 +287,7 @@ enum Ecc_Sum {
ECC_SECP256K1_OID = 186,
ECC_BRAINPOOLP256R1_OID = 104,
ECC_X25519_OID = 365,
ECC_ED25519_OID = 256,
ECC_BRAINPOOLP320R1_OID = 106,
ECC_SECP384R1_OID = 210,
ECC_BRAINPOOLP384R1_OID = 108,