Merge pull request #941 from SparkiDev/ed25519

ED25519 with certificates and TLS
This commit is contained in:
toddouska 2017-06-12 10:47:21 -07:00 committed by GitHub
commit 7cc455259e
37 changed files with 2373 additions and 408 deletions

Binary file not shown.

View File

@ -0,0 +1,4 @@
-----BEGIN EDDSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEIE3EyZVR/gbofvUgIsCeuA3yZ9E7DbTQxW7HMDYQhbxl
oSIEIEEH7HUMaHISPASCB24Wb0BBbaSPCPLinadDwiQomH6s
-----END EDDSA 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 EDDSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEIBGdNYxa3ommO8aYO1oGaGSRQBqDYB0sKOdR3bqejqIQ
oSIEIDY9UZ60w5FgsDoJuIdapQUPW1PlZBc+cLkNZhKk5fFR
-----END EDDSA 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 EDDSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEIFwOftlJ9QL4yEBIBh9UmTRwCu+A6puPK9OFmVk0A19P
oSIEIKZgKbt92EfL1B7QbQ9XANgqH1BqQrxd5bgZZbLfJK9Q
-----END EDDSA 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 EDDSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEINjpdrI/H/eIdfXd+HrGSTBu6Z/LnR4rwBjvu3WJ5ndn
oSIEIBowiBhHL5faBPSk471sDBa5SMHRQteOkoSgdCpDng4p
-----END EDDSA 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

@ -55,6 +55,23 @@ EXTRA_DIST += \
certs/server-ecc.der \
certs/server-ecc-rsa.der \
certs/server-cert-chain.der
EXTRA_DIST += \
certs/ed25519/ca-ed25519.der \
certs/ed25519/ca-ed25519-key.der \
certs/ed25519/ca-ed25519-key.pem \
certs/ed25519/ca-ed25519.pem \
certs/ed25519/client-ed25519.der \
certs/ed25519/client-ed25519-key.der \
certs/ed25519/client-ed25519-key.pem \
certs/ed25519/client-ed25519.pem \
certs/ed25519/root-ed25519.der \
certs/ed25519/root-ed25519-key.der \
certs/ed25519/root-ed25519-key.pem \
certs/ed25519/root-ed25519.pem \
certs/ed25519/server-ed25519.der \
certs/ed25519/server-ed25519-key.der \
certs/ed25519/server-ed25519-key.pem \
certs/ed25519/server-ed25519.pem
dist_doc_DATA+= certs/taoCert.txt

View File

@ -156,7 +156,7 @@ static void ShowVersions(void)
/* Measures average time to create, connect and disconnect a connection (TPS).
Benchmark = number of connections. */
static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession)
int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519)
{
/* time passed in number of connects give average */
int times = benchmark;
@ -171,6 +171,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
#endif
(void)resumeSession;
(void)useX25519;
while (loops--) {
#ifndef NO_SESSION_CACHE
@ -190,6 +191,16 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
#ifndef NO_SESSION_CACHE
if (benchResume)
wolfSSL_set_session(ssl, benchSession);
#endif
#ifdef WOLFSSL_TLS13
#ifdef HAVE_CURVE25519
else if (useX25519) {
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519)
!= SSL_SUCCESS) {
err_sys("unable to use curve secp256r1");
}
}
#endif
#endif
if (wolfSSL_set_fd(ssl, sockfd) != SSL_SUCCESS) {
err_sys("error in setting fd");
@ -247,7 +258,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
/* Measures throughput in kbps. Throughput = number of bytes */
static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
int dtlsUDP, int dtlsSCTP, int throughput)
int dtlsUDP, int dtlsSCTP, int throughput, int useX25519)
{
double start, conn_time = 0, tx_time = 0, rx_time = 0;
SOCKET_T sockfd;
@ -264,6 +275,18 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
err_sys("error in setting fd");
}
(void)useX25519;
#ifdef WOLFSSL_TLS13
#ifdef HAVE_CURVE25519
if (useX25519) {
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519)
!= SSL_SUCCESS) {
err_sys("unable to use curve secp256r1");
}
}
#endif
#endif
do {
err = 0; /* reset error */
ret = wolfSSL_connect(ssl);
@ -735,9 +758,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
int useOcsp = 0;
char* ocspUrl = NULL;
#endif
#ifdef HAVE_CURVE25519
int useX25519 = 0;
#endif
#ifdef HAVE_WNR
const char* wnrConfigFile = wnrConfig;
@ -771,6 +792,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
(void)alpnList;
(void)alpn_opt;
(void)updateKeysIVs;
(void)useX25519;
StackTrap();
@ -1479,7 +1501,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
if (benchmark) {
((func_args*)args)->return_code =
ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP,
benchmark, resumeSession);
benchmark, resumeSession, useX25519);
wolfSSL_CTX_free(ctx);
exit(EXIT_SUCCESS);
}
@ -1487,7 +1509,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
if(throughput) {
((func_args*)args)->return_code =
ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP,
throughput);
throughput, useX25519);
wolfSSL_CTX_free(ctx);
exit(EXIT_SUCCESS);
}

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;

223
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");
@ -4026,16 +4035,28 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
switch (type) {
case CA_TYPE: /* same as below */
case TRUSTED_PEER_TYPE:
case CERT_TYPE: header=BEGIN_CERT; footer=END_CERT; break;
case CRL_TYPE: header=BEGIN_X509_CRL; footer=END_X509_CRL; break;
case DH_PARAM_TYPE: header=BEGIN_DH_PARAM; footer=END_DH_PARAM; break;
case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM; footer=END_DSA_PARAM; break;
case CERTREQ_TYPE: header=BEGIN_CERT_REQ; footer=END_CERT_REQ; break;
case DSA_TYPE: header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV; break;
case ECC_TYPE: header=BEGIN_EC_PRIV; footer=END_EC_PRIV; break;
case RSA_TYPE: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; break;
case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY; footer=END_PUB_KEY; break;
default: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV; break;
case CERT_TYPE: header=BEGIN_CERT; footer=END_CERT;
break;
case CRL_TYPE: header=BEGIN_X509_CRL; footer=END_X509_CRL;
break;
case DH_PARAM_TYPE: header=BEGIN_DH_PARAM; footer=END_DH_PARAM;
break;
case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM; footer=END_DSA_PARAM;
break;
case CERTREQ_TYPE: header=BEGIN_CERT_REQ; footer=END_CERT_REQ;
break;
case DSA_TYPE: header=BEGIN_DSA_PRIV; footer=END_DSA_PRIV;
break;
case ECC_TYPE: header=BEGIN_EC_PRIV; footer=END_EC_PRIV;
break;
case RSA_TYPE: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV;
break;
case ED25519_TYPE: header=BEGIN_EDDSA_PRIV; footer=END_EDDSA_PRIV;
break;
case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY; footer=END_PUB_KEY;
break;
default: header=BEGIN_RSA_PRIV; footer=END_RSA_PRIV;
break;
}
/* find header */
@ -4052,6 +4073,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
header = BEGIN_EC_PRIV; footer = END_EC_PRIV;
} else if (header == BEGIN_EC_PRIV) {
header = BEGIN_DSA_PRIV; footer = END_DSA_PRIV;
} else if (header == BEGIN_DSA_PRIV) {
header = BEGIN_EDDSA_PRIV; footer = END_EDDSA_PRIV;
} else
break;
}
@ -4375,6 +4398,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 +4598,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,52 +4662,96 @@ 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;
}
}
else
eccKey = 0;
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 */
/* check for minimum 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;
if (ssl) {
ssl->options.haveStaticECC = 1;
}
else if (ctx) {
ctx->haveStaticECC = 1;
}
wc_ed25519_free(&key);
ed25519Key = 1;
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
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 +4798,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 +4817,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 +4832,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 +4862,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 +4880,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 +22125,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 +22197,6 @@ void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
return NULL;
}
#endif
#endif /* HAVE_ECC */
#ifndef NO_RSA
@ -22365,6 +22515,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,12 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
}
/* Check for public key of required type. */
#ifdef HAVE_ED25519
if (args->sigAlgo == ed25519_sa_algo &&
!ssl->peerEd25519KeyPresent) {
WOLFSSL_MSG("Oops, peer sent ED25519 key but not in verify");
}
#endif
if (args->sigAlgo == ecc_dsa_sa_algo &&
!ssl->peerEccDsaKeyPresent) {
WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
@ -4191,6 +4233,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 +4293,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

File diff suppressed because it is too large Load Diff

View File

@ -210,7 +210,7 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
res will be 1 on successful verify and 0 on unsuccessful
return 0 and res of 1 on success
*/
int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
word32 msglen, int* res, ed25519_key* key)
{
byte rcheck[ED25519_KEY_SIZE];
@ -407,6 +407,25 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
}
/*
For importing a private key.
*/
int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
ed25519_key* key)
{
/* sanity check on arguments */
if (priv == NULL || key == NULL)
return BAD_FUNC_ARG;
/* key size check */
if (privSz < ED25519_KEY_SIZE)
return BAD_FUNC_ARG;
XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
return 0;
}
/*
For importing a private key and its associated public key.
*/
@ -508,6 +527,14 @@ int wc_ed25519_export_key(ed25519_key* key,
#endif /* HAVE_ED25519_KEY_EXPORT */
/* check the private and public keys match */
int wc_ed25519_check_key(ed25519_key* key)
{
/* TODO: Perform check of private and public key */
(void)key;
return 0;
}
/* returns the private key size (secret only) in bytes */
int wc_ed25519_size(ed25519_key* key)

View File

@ -5716,6 +5716,14 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out)
static const char* eccCaKeyPubFile = CERT_ROOT "ecc-keyPub.der";
#endif
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
#ifdef WOLFSSL_TEST_CERT
static const char* serverEd25519Cert =
CERT_ROOT "ed25519/server-ed25519.der";
static const char* caEd25519Cert =
CERT_ROOT "ed25519/ca-ed25519.der";
#endif
#endif
#endif /* !USE_CERT_BUFFER_* */
#ifndef NO_WRITE_TEMP_FILES
@ -11445,6 +11453,213 @@ int curve25519_test(void)
#ifdef HAVE_ED25519
#ifdef WOLFSSL_TEST_CERT
static int ed25519_test_cert(void)
{
DecodedCert cert[2];
DecodedCert* serverCert = NULL;
DecodedCert* caCert = NULL;
#ifdef HAVE_ED25519_VERIFY
ed25519_key key;
ed25519_key* pubKey = NULL;
int verify;
#endif /* HAVE_ED25519_VERIFY */
int ret;
byte* tmp;
int bytes;
FILE* file;
tmp = XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (tmp == NULL) {
ret = -7200;
goto done;
}
#ifdef USE_CERT_BUFFERS_256
XMEMCPY(tmp, ca_ed25519_cert, sizeof_ca_ed25519_cert);
bytes = sizeof_ca_ed25519_cert;
#elif !defined(NO_FILESYSTEM)
file = fopen(caEd25519Cert, "rb");
if (file == NULL) {
ret = -7201;
goto done;
}
bytes = fread(tmp, 1, FOURK_BUF, file);
fclose(file);
#else
/* No certificate to use. */
ret = -7202;
goto done;
#endif
InitDecodedCert(&cert[0], tmp, (word32)bytes, 0);
caCert = &cert[0];
ret = ParseCert(caCert, CERT_TYPE, NO_VERIFY, NULL);
if (ret != 0) {
ret = -7203;
goto done;
}
#ifdef USE_CERT_BUFFERS_256
XMEMCPY(tmp, server_ed25519_cert, sizeof_server_ed25519_cert);
bytes = sizeof_server_ed25519_cert;
#elif !defined(NO_FILESYSTEM)
file = fopen(serverEd25519Cert, "rb");
if (file == NULL) {
ret = -7204;
goto done;
}
bytes = fread(tmp, 1, FOURK_BUF, file);
fclose(file);
#else
/* No certificate to use. */
ret = -7205;
goto done;
#endif
InitDecodedCert(&cert[1], tmp, (word32)bytes, 0);
serverCert = &cert[1];
ret = ParseCert(serverCert, CERT_TYPE, NO_VERIFY, NULL);
if (ret != 0) {
ret = -7206;
goto done;
}
#ifdef HAVE_ED25519_VERIFY
ret = wc_ed25519_init(&key);
if (ret < 0) {
ret = -7207;
goto done;
}
pubKey = &key;
ret = wc_ed25519_import_public(caCert->publicKey, caCert->pubKeySize,
pubKey);
if (ret < 0) {
ret = -7208;
goto done;
}
if (wc_ed25519_verify_msg(serverCert->signature, serverCert->sigLength,
serverCert->source + serverCert->certBegin,
serverCert->sigIndex - serverCert->certBegin,
&verify, pubKey) < 0 || verify != 1) {
ret = -7209;
goto done;
}
#endif /* HAVE_ED25519_VERIFY */
done:
if (tmp != NULL)
XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#ifdef HAVE_ED25519_VERIFY
wc_ed25519_free(pubKey);
#endif /* HAVE_ED25519_VERIFY */
if (caCert != NULL)
FreeDecodedCert(caCert);
if (serverCert != NULL)
FreeDecodedCert(serverCert);
return ret;
}
#ifdef WOLFSSL_CERT_GEN
static const CertName defaultName = {
"US", CTC_PRINTABLE,
"Montana", CTC_UTF8,
"Bozeman", CTC_UTF8,
"Test", CTC_UTF8,
"wolfSSL", CTC_UTF8,
"ED25519", CTC_UTF8,
"www.wolfssl.com", CTC_UTF8,
"info@wolfssl.com"
};
#ifdef WOLFSSL_CERT_EXT
static const char leafKeyUsage[] = "digitalSignature,nonRepudiation";
#endif
static int ed25519_test_make_cert(void)
{
WC_RNG rng;
Cert cert;
DecodedCert decode;
ed25519_key key;
ed25519_key* privKey = NULL;
int ret = 0;
byte* tmp = NULL;
wc_InitCert(&cert);
#ifndef HAVE_FIPS
ret = wc_InitRng_ex(&rng, HEAP_HINT, devId);
#else
ret = wc_InitRng(&rng);
#endif
if (ret != 0)
return -7220;
wc_ed25519_init(&key);
privKey = &key;
wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, privKey);
cert.daysValid = 365 * 2;
cert.selfSigned = 1;
XMEMCPY(&cert.issuer, &defaultName, sizeof(CertName));
XMEMCPY(&cert.subject, &defaultName, sizeof(CertName));
cert.isCA = 0;
#ifdef WOLFSSL_CERT_EXT
ret = wc_SetKeyUsage(&cert, leafKeyUsage);
if (ret < 0) {
ret = -7221;
goto done;
}
ret = wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED25519_TYPE, privKey);
if (ret < 0) {
ret = -7222;
goto done;
}
ret = wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED25519_TYPE, privKey);
if (ret < 0) {
ret = -7223;
goto done;
}
#endif
tmp = XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (tmp == NULL) {
ret = -7224;
goto done;
}
cert.sigType = CTC_ED25519;
ret = wc_MakeCert_ex(&cert, tmp, FOURK_BUF, ED25519_TYPE, privKey, &rng);
if (ret < 0) {
ret = -7225;
goto done;
}
ret = wc_SignCert_ex(cert.bodySz, cert.sigType, tmp, FOURK_BUF,
ED25519_TYPE, privKey, &rng);
if (ret < 0) {
ret = -7226;
goto done;
}
InitDecodedCert(&decode, tmp, ret, HEAP_HINT);
ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0);
FreeDecodedCert(&decode);
if (ret != 0) {
ret = -7227;
goto done;
}
done:
if (tmp != NULL)
XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
wc_ed25519_free(privKey);
wc_FreeRng(&rng);
return ret;
}
#endif /* WOLFSSL_CERT_GEN */
#endif /* WOLFSSL_TEST_CERT */
int ed25519_test(void)
{
WC_RNG rng;
@ -11874,6 +12089,17 @@ int ed25519_test(void)
(void)keySz;
(void)sigSz;
#ifdef WOLFSSL_TEST_CERT
ret = ed25519_test_cert();
if (ret < 0)
return ret;
#ifdef WOLFSSL_CERT_GEN
ret = ed25519_test_make_cert();
if (ret < 0)
return ret;
#endif /* WOLFSSL_CERT_GEN */
#endif /* WOLFSSL_TEST_CERT */
return 0;
}
#endif /* HAVE_ED25519 */

View File

@ -2183,5 +2183,158 @@ static const unsigned char dh_g[] =
0x02,
};
#ifdef HAVE_ED25519
/*
* Subject: /C=US/ST=Montana/L=Bozeman/SN=Leaf/O=wolfSSL/OU=ED25519/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
* Issuer: /C=US/ST=Montana/L=Bozeman/SN=CA/O=wolfSSL/OU=ED25519/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
*/
static const unsigned char server_ed25519_pkey[44] = {
0x30, 0x2A, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03,
0x21, 0x00, 0x1A, 0x30, 0x88, 0x18, 0x47, 0x2F, 0x97, 0xDA,
0x04, 0xF4, 0xA4, 0xE3, 0xBD, 0x6C, 0x0C, 0x16, 0xB9, 0x48,
0xC1, 0xD1, 0x42, 0xD7, 0x8E, 0x92, 0x84, 0xA0, 0x74, 0x2A,
0x43, 0x9E, 0x0E, 0x29
};
static const int sizeof_server_ed25519_pkey = sizeof(server_ed25519_pkey);
static const unsigned char server_ed25519_cert[591] = {
0x30, 0x82, 0x02, 0x4B, 0x30, 0x82, 0x01, 0xFD, 0xA0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x08, 0x01, 0xD0, 0x92, 0x10, 0x6A,
0x5A, 0x46, 0x57, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70,
0x30, 0x81, 0x9D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E,
0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E,
0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D,
0x61, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x04, 0x0C, 0x02, 0x43, 0x41, 0x31, 0x10, 0x30, 0x0E, 0x06,
0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66,
0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55,
0x04, 0x0B, 0x0C, 0x07, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31,
0x39, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03,
0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66,
0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30,
0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77,
0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D,
0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x37, 0x30, 0x35,
0x32, 0x38, 0x32, 0x33, 0x32, 0x36, 0x32, 0x39, 0x5A, 0x18,
0x0F, 0x32, 0x30, 0x31, 0x39, 0x30, 0x35, 0x32, 0x39, 0x32,
0x33, 0x32, 0x36, 0x32, 0x39, 0x5A, 0x30, 0x81, 0x9F, 0x31,
0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04,
0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61,
0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C,
0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x0D,
0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C, 0x04, 0x4C,
0x65, 0x61, 0x66, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55,
0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53,
0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B,
0x0C, 0x07, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x31,
0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F,
0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73,
0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06,
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01,
0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C,
0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x2A,
0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03, 0x21, 0x00,
0x1A, 0x30, 0x88, 0x18, 0x47, 0x2F, 0x97, 0xDA, 0x04, 0xF4,
0xA4, 0xE3, 0xBD, 0x6C, 0x0C, 0x16, 0xB9, 0x48, 0xC1, 0xD1,
0x42, 0xD7, 0x8E, 0x92, 0x84, 0xA0, 0x74, 0x2A, 0x43, 0x9E,
0x0E, 0x29, 0xA3, 0x53, 0x30, 0x51, 0x30, 0x1D, 0x06, 0x03,
0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xF6, 0xB2, 0x84,
0x1A, 0x95, 0xB4, 0x70, 0x32, 0x53, 0xFE, 0xD9, 0xEB, 0x9B,
0x29, 0x80, 0x4B, 0xD6, 0xB5, 0xF1, 0xC0, 0x30, 0x1F, 0x06,
0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
0x92, 0xD5, 0x0B, 0xDA, 0xF1, 0x04, 0x8B, 0xB9, 0xA1, 0x8B,
0x03, 0x02, 0x9F, 0x58, 0x00, 0x35, 0x36, 0x07, 0x7A, 0xC9,
0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF,
0x04, 0x05, 0x03, 0x02, 0x06, 0xC0, 0x00, 0x30, 0x05, 0x06,
0x03, 0x2B, 0x65, 0x70, 0x03, 0x41, 0x00, 0x12, 0x56, 0x77,
0x0C, 0x96, 0x42, 0x98, 0xDA, 0xC9, 0x15, 0x6C, 0x4E, 0x48,
0x95, 0x05, 0x1D, 0xD0, 0x78, 0x32, 0xF8, 0x86, 0x46, 0x9A,
0x46, 0x9B, 0x64, 0x8B, 0x31, 0xB0, 0x19, 0x6B, 0x77, 0x99,
0x8B, 0xFF, 0xFC, 0x02, 0x36, 0x05, 0x0B, 0x69, 0x37, 0x87,
0x62, 0x75, 0xDA, 0x50, 0x2C, 0x2D, 0x5D, 0x52, 0x94, 0x3F,
0x00, 0x9D, 0x18, 0x45, 0x6F, 0x37, 0x12, 0x8E, 0xF4, 0xE4,
0x00
};
static const int sizeof_server_ed25519_cert = sizeof(server_ed25519_cert);
static const unsigned char ca_ed25519_pkey[44] = {
0x30, 0x2A, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03,
0x21, 0x00, 0x41, 0x07, 0xEC, 0x75, 0x0C, 0x68, 0x72, 0x12,
0x3C, 0x04, 0x82, 0x07, 0x6E, 0x16, 0x6F, 0x40, 0x41, 0x6D,
0xA4, 0x8F, 0x08, 0xF2, 0xE2, 0x9D, 0xA7, 0x43, 0xC2, 0x24,
0x28, 0x98, 0x7E, 0xAC
};
static const int sizeof_ca_ed25519_pkey = sizeof(ca_ed25519_pkey);
static const unsigned char ca_ed25519_cert[605] = {
0x30, 0x82, 0x02, 0x59, 0x30, 0x82, 0x02, 0x0B, 0xA0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x08, 0x01, 0xF6, 0xE1, 0x3E, 0xBC,
0x79, 0xA1, 0x85, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70,
0x30, 0x81, 0x9F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E,
0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E,
0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D,
0x61, 0x6E, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04,
0x04, 0x0C, 0x04, 0x52, 0x6F, 0x6F, 0x74, 0x31, 0x10, 0x30,
0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F,
0x6C, 0x66, 0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06,
0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x45, 0x44, 0x32, 0x35,
0x35, 0x31, 0x39, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55,
0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F,
0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31,
0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F,
0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63,
0x6F, 0x6D, 0x30, 0x22, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x37,
0x30, 0x35, 0x32, 0x38, 0x32, 0x33, 0x32, 0x36, 0x32, 0x39,
0x5A, 0x18, 0x0F, 0x32, 0x30, 0x31, 0x39, 0x30, 0x35, 0x32,
0x39, 0x32, 0x33, 0x32, 0x36, 0x32, 0x39, 0x5A, 0x30, 0x81,
0x9D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61,
0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04,
0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E,
0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C,
0x02, 0x43, 0x41, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55,
0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, 0x66, 0x53, 0x53,
0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B,
0x0C, 0x07, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x31,
0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F,
0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73,
0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06,
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01,
0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C,
0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x2A,
0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03, 0x21, 0x00,
0x41, 0x07, 0xEC, 0x75, 0x0C, 0x68, 0x72, 0x12, 0x3C, 0x04,
0x82, 0x07, 0x6E, 0x16, 0x6F, 0x40, 0x41, 0x6D, 0xA4, 0x8F,
0x08, 0xF2, 0xE2, 0x9D, 0xA7, 0x43, 0xC2, 0x24, 0x28, 0x98,
0x7E, 0xAC, 0xA3, 0x61, 0x30, 0x5F, 0x30, 0x0C, 0x06, 0x03,
0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF,
0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04,
0x14, 0x92, 0xD5, 0x0B, 0xDA, 0xF1, 0x04, 0x8B, 0xB9, 0xA1,
0x8B, 0x03, 0x02, 0x9F, 0x58, 0x00, 0x35, 0x36, 0x07, 0x7A,
0xC9, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18,
0x30, 0x16, 0x80, 0x14, 0x86, 0xC0, 0x27, 0xE9, 0x9E, 0xFA,
0x85, 0xC1, 0xFD, 0xE3, 0x6F, 0xFC, 0x54, 0x59, 0x72, 0x37,
0xC7, 0x33, 0x92, 0xBB, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D,
0x0F, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x03, 0x02, 0x01, 0xC6,
0x00, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03, 0x41,
0x00, 0x22, 0x1B, 0x06, 0x17, 0xC0, 0x11, 0x74, 0x1F, 0x64,
0xD1, 0xA3, 0xF6, 0x7B, 0x06, 0x00, 0x1A, 0x0B, 0x50, 0x8E,
0xEB, 0xB1, 0x63, 0x92, 0x45, 0xBA, 0xDC, 0xE2, 0xC1, 0x68,
0x14, 0x23, 0x0C, 0x6E, 0x2C, 0x95, 0x3C, 0xB1, 0x1C, 0x19,
0x27, 0x98, 0x50, 0x3E, 0x55, 0x51, 0xCC, 0xC4, 0x49, 0x58,
0xAF, 0xB9, 0x46, 0x4F, 0xED, 0x9C, 0x57, 0x38, 0x04, 0x29,
0xD4, 0xA9, 0x12, 0xFE, 0x08
};
static const int sizeof_ca_ed25519_cert = sizeof(ca_ed25519_cert);
#endif
#endif /* WOLFSSL_CERTS_TEST_H */

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

@ -239,10 +239,11 @@ enum Block_Sum {
enum Key_Sum {
DSAk = 515,
RSAk = 645,
NTRUk = 274,
ECDSAk = 518
DSAk = 515,
RSAk = 645,
NTRUk = 274,
ECDSAk = 518,
ED25519k = 256
};
@ -286,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,
@ -434,10 +436,13 @@ struct SignatureCtx {
#endif
union {
#ifndef NO_RSA
struct RsaKey* rsa;
struct RsaKey* rsa;
#endif
#ifdef HAVE_ECC
struct ecc_key* ecc;
struct ecc_key* ecc;
#endif
#ifdef HAVE_ED25519
struct ed25519_key* ed25519;
#endif
void* ptr;
} key;
@ -655,6 +660,8 @@ extern const char* BEGIN_DSA_PRIV;
extern const char* END_DSA_PRIV;
extern const char* BEGIN_PUB_KEY;
extern const char* END_PUB_KEY;
extern const char* BEGIN_EDDSA_PRIV;
extern const char* END_EDDSA_PRIV;
#ifdef NO_SHA
#define SIGNER_DIGEST_SIZE SHA256_DIGEST_SIZE
@ -814,7 +821,8 @@ enum cert_enums {
EMAIL_JOINT_LEN = 9,
RSA_KEY = 10,
NTRU_KEY = 11,
ECC_KEY = 12
ECC_KEY = 12,
ED25519_KEY = 13
};
#ifndef WOLFSSL_PEMCERT_TODER_DEFINED

View File

@ -35,6 +35,10 @@
typedef struct ecc_key ecc_key;
#define WC_ECCKEY_TYPE_DEFINED
#endif
#ifndef WC_ED25519KEY_TYPE_DEFINED
typedef struct ed25519_key ed25519_key;
#define WC_ED25519KEY_TYPE_DEFINED
#endif
#ifndef WC_RSAKEY_TYPE_DEFINED
typedef struct RsaKey RsaKey;
#define WC_RSAKEY_TYPE_DEFINED
@ -61,7 +65,9 @@ enum CertType {
PUBLICKEY_TYPE,
RSA_PUBLICKEY_TYPE,
ECC_PUBLICKEY_TYPE,
TRUSTED_PEER_TYPE
TRUSTED_PEER_TYPE,
EDDSA_PRIVATEKEY_TYPE,
ED25519_TYPE
};
@ -79,7 +85,8 @@ enum Ctc_SigType {
CTC_SHA384wRSA = 656,
CTC_SHA384wECDSA = 525,
CTC_SHA512wRSA = 657,
CTC_SHA512wECDSA = 526
CTC_SHA512wECDSA = 526,
CTC_ED25519 = 256
};
enum Ctc_Encoding {
@ -174,14 +181,21 @@ typedef struct Cert {
keyType = RSA_KEY (default)
*/
WOLFSSL_API void wc_InitCert(Cert*);
WOLFSSL_API int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz,
int keyType, void* key, WC_RNG* rng);
WOLFSSL_API int wc_MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,
ecc_key*, WC_RNG*);
ecc_key*, WC_RNG*);
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_API int wc_MakeCertReq_ex(Cert*, byte* derBuffer, word32 derSz,
int, void*);
WOLFSSL_API int wc_MakeCertReq(Cert*, byte* derBuffer, word32 derSz,
RsaKey*, ecc_key*);
#endif
WOLFSSL_API int wc_SignCert_ex(int requestSz, int sType, byte* buffer,
word32 buffSz, int keyType, void* key,
WC_RNG* rng);
WOLFSSL_API int wc_SignCert(int requestSz, int sigType, byte* derBuffer,
word32 derSz, RsaKey*, ecc_key*, WC_RNG*);
word32 derSz, RsaKey*, ecc_key*, WC_RNG*);
WOLFSSL_API int wc_MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,
WC_RNG*);
WOLFSSL_API int wc_SetIssuer(Cert*, const char*);
@ -195,10 +209,14 @@ WOLFSSL_API int wc_SetAltNamesBuffer(Cert*, const byte*, int);
WOLFSSL_API int wc_SetDatesBuffer(Cert*, const byte*, int);
#ifdef WOLFSSL_CERT_EXT
WOLFSSL_API int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType,
void* key);
WOLFSSL_API int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey,
ecc_key *eckey);
WOLFSSL_API int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz);
WOLFSSL_API int wc_SetAuthKeyId(Cert *cert, const char* file);
WOLFSSL_API int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType,
void* key);
WOLFSSL_API int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey,
ecc_key *eckey);
WOLFSSL_API int wc_SetSubjectKeyId(Cert *cert, const char* file);
@ -267,6 +285,24 @@ WOLFSSL_API int wc_SetKeyUsage(Cert *cert, const char *value);
#endif
#endif
#ifdef HAVE_ED25519
/* private key helpers */
WOLFSSL_API int wc_Ed25519PrivateKeyDecode(const byte*, word32*,
ed25519_key*, word32);
WOLFSSL_API int wc_Ed25519KeyToDer(ed25519_key* key, byte* output,
word32 inLen);
WOLFSSL_API int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output,
word32 inLen);
/* public key helper */
WOLFSSL_API int wc_Ed25519PublicKeyDecode(const byte*, word32*,
ed25519_key*, word32);
#if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
WOLFSSL_API int wc_Ed25519PublicKeyToDer(ed25519_key*, byte* output,
word32 inLen, int with_AlgCurve);
#endif
#endif
/* DER encode signature */
WOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest,
word32 digSz, int hashOID);

View File

@ -54,8 +54,14 @@
/* both private and public key */
#define ED25519_PRV_KEY_SIZE (ED25519_PUB_KEY_SIZE+ED25519_KEY_SIZE)
#ifndef WC_ED25519KEY_TYPE_DEFINED
typedef struct ed25519_key ed25519_key;
#define WC_ED25519KEY_TYPE_DEFINED
#endif
/* An ED25519 Key */
typedef struct {
struct ed25519_key {
byte p[ED25519_PUB_KEY_SIZE]; /* compressed public key */
byte k[ED25519_PRV_KEY_SIZE]; /* private key : 32 secret -- 32 public */
#ifdef FREESCALE_LTC_ECC
@ -63,7 +69,7 @@ typedef struct {
byte pointX[ED25519_KEY_SIZE]; /* recovered X coordinate */
byte pointY[ED25519_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */
#endif
} ed25519_key;
};
WOLFSSL_API
@ -72,7 +78,7 @@ WOLFSSL_API
int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
word32 *outlen, ed25519_key* key);
WOLFSSL_API
int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
word32 msglen, int* stat, ed25519_key* key);
WOLFSSL_API
int wc_ed25519_init(ed25519_key* key);
@ -81,6 +87,9 @@ void wc_ed25519_free(ed25519_key* key);
WOLFSSL_API
int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key);
WOLFSSL_API
int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
ed25519_key* key);
WOLFSSL_API
int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ed25519_key* key);
WOLFSSL_API
@ -94,6 +103,8 @@ int wc_ed25519_export_key(ed25519_key* key,
byte* priv, word32 *privSz,
byte* pub, word32 *pubSz);
int wc_ed25519_check_key(ed25519_key* key);
/* size helper */
WOLFSSL_API
int wc_ed25519_size(ed25519_key* key);

View File

@ -416,6 +416,7 @@
DYNAMIC_TYPE_ASYNC_NUMA = 67,
DYNAMIC_TYPE_ASYNC_NUMA64 = 68,
DYNAMIC_TYPE_CURVE25519 = 69,
DYNAMIC_TYPE_ED25519 = 70,
};
/* max error buffer string size */