mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
Merge pull request #2221 from SparkiDev/rfc8032
Support Ed25519ctx and Ed25519ph sign/verify algorithms
This commit is contained in:
@ -45,6 +45,12 @@
|
|||||||
#include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
|
#include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_ED25519_SIGN) || defined(HAVE_ED25519_VERIFY)
|
||||||
|
#define ED25519CTX_SIZE 32
|
||||||
|
|
||||||
|
static const byte ed25519Ctx[ED25519CTX_SIZE] =
|
||||||
|
"SigEd25519 no Ed25519 collisions";
|
||||||
|
#endif
|
||||||
|
|
||||||
int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
|
int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
|
||||||
word32 pubKeySz)
|
word32 pubKeySz)
|
||||||
@ -117,16 +123,20 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
|
|||||||
|
|
||||||
#ifdef HAVE_ED25519_SIGN
|
#ifdef HAVE_ED25519_SIGN
|
||||||
/*
|
/*
|
||||||
in contains the message to sign
|
in contains the message to sign
|
||||||
inlen is the length of the message to sign
|
inLen is the length of the message to sign
|
||||||
out is the buffer to write the signature
|
out is the buffer to write the signature
|
||||||
outLen [in/out] input size of out buf
|
outLen [in/out] input size of out buf
|
||||||
output gets set as the final length of out
|
output gets set as the final length of out
|
||||||
key is the ed25519 key to use when signing
|
key is the ed25519 key to use when signing
|
||||||
|
type one of Ed25519, Ed25519ctx or Ed25519ph
|
||||||
|
context extra signing data
|
||||||
|
contextLen length of extra signing data
|
||||||
return 0 on success
|
return 0 on success
|
||||||
*/
|
*/
|
||||||
int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
|
static int ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
|
||||||
word32 *outLen, ed25519_key* key)
|
word32 *outLen, ed25519_key* key, byte type,
|
||||||
|
const byte* context, byte contextLen)
|
||||||
{
|
{
|
||||||
#ifdef FREESCALE_LTC_ECC
|
#ifdef FREESCALE_LTC_ECC
|
||||||
byte tempBuf[ED25519_PRV_KEY_SIZE];
|
byte tempBuf[ED25519_PRV_KEY_SIZE];
|
||||||
@ -140,8 +150,10 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* sanity check on arguments */
|
/* sanity check on arguments */
|
||||||
if (in == NULL || out == NULL || outLen == NULL || key == NULL)
|
if (in == NULL || out == NULL || outLen == NULL || key == NULL ||
|
||||||
|
(context == NULL && contextLen != 0)) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
if (!key->pubKeySet)
|
if (!key->pubKeySet)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
@ -166,9 +178,19 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
|
|||||||
ret = wc_InitSha512(&sha);
|
ret = wc_InitSha512(&sha);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = wc_Sha512Update(&sha, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
|
if (type == Ed25519ctx || type == Ed25519ph) {
|
||||||
|
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, &type, sizeof(type));
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
|
||||||
|
if (ret == 0 && context != NULL)
|
||||||
|
ret = wc_Sha512Update(&sha, context, contextLen);
|
||||||
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_Sha512Update(&sha, in, inlen);
|
ret = wc_Sha512Update(&sha, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, in, inLen);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_Sha512Final(&sha, nonce);
|
ret = wc_Sha512Final(&sha, nonce);
|
||||||
wc_Sha512Free(&sha);
|
wc_Sha512Free(&sha);
|
||||||
@ -180,7 +202,8 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
|
|||||||
ltcPoint.X = &tempBuf[0];
|
ltcPoint.X = &tempBuf[0];
|
||||||
ltcPoint.Y = &tempBuf[32];
|
ltcPoint.Y = &tempBuf[32];
|
||||||
LTC_PKHA_sc_reduce(nonce);
|
LTC_PKHA_sc_reduce(nonce);
|
||||||
LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce, ED25519_KEY_SIZE, <cPoint, kLTC_Ed25519 /* result on Ed25519 */);
|
LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce,
|
||||||
|
ED25519_KEY_SIZE, <cPoint, kLTC_Ed25519 /* result on Ed25519 */);
|
||||||
LTC_PKHA_Ed25519_Compress(<cPoint, out);
|
LTC_PKHA_Ed25519_Compress(<cPoint, out);
|
||||||
#else
|
#else
|
||||||
sc_reduce(nonce);
|
sc_reduce(nonce);
|
||||||
@ -196,11 +219,21 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
|
|||||||
ret = wc_InitSha512(&sha);
|
ret = wc_InitSha512(&sha);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = wc_Sha512Update(&sha, out, ED25519_SIG_SIZE/2);
|
if (type == Ed25519ctx || type == Ed25519ph) {
|
||||||
|
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, &type, sizeof(type));
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
|
||||||
|
if (ret == 0 && context != NULL)
|
||||||
|
ret = wc_Sha512Update(&sha, context, contextLen);
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, out, ED25519_SIG_SIZE/2);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
|
ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_Sha512Update(&sha, in, inlen);
|
ret = wc_Sha512Update(&sha, in, inLen);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_Sha512Final(&sha, hram);
|
ret = wc_Sha512Final(&sha, hram);
|
||||||
wc_Sha512Free(&sha);
|
wc_Sha512Free(&sha);
|
||||||
@ -218,20 +251,100 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
in contains the message to sign
|
||||||
|
inLen is the length of the message to sign
|
||||||
|
out is the buffer to write the signature
|
||||||
|
outLen [in/out] input size of out buf
|
||||||
|
output gets set as the final length of out
|
||||||
|
key is the ed25519 key to use when signing
|
||||||
|
return 0 on success
|
||||||
|
*/
|
||||||
|
int wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
|
||||||
|
word32 *outLen, ed25519_key* key)
|
||||||
|
{
|
||||||
|
return ed25519_sign_msg(in, inLen, out, outLen, key, Ed25519, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
in contains the message to sign
|
||||||
|
inLen is the length of the message to sign
|
||||||
|
out is the buffer to write the signature
|
||||||
|
outLen [in/out] input size of out buf
|
||||||
|
output gets set as the final length of out
|
||||||
|
key is the ed25519 key to use when signing
|
||||||
|
context extra signing data
|
||||||
|
contextLen length of extra signing data
|
||||||
|
return 0 on success
|
||||||
|
*/
|
||||||
|
int wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out,
|
||||||
|
word32 *outLen, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen)
|
||||||
|
{
|
||||||
|
return ed25519_sign_msg(in, inLen, out, outLen, key, Ed25519ctx, context,
|
||||||
|
contextLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
hash contains the SHA-512 hash of the message to sign
|
||||||
|
hashLen is the length of the SHA-512 hash of the message to sign
|
||||||
|
out is the buffer to write the signature
|
||||||
|
outLen [in/out] input size of out buf
|
||||||
|
output gets set as the final length of out
|
||||||
|
key is the ed25519 key to use when signing
|
||||||
|
context extra signing data
|
||||||
|
contextLen length of extra signing data
|
||||||
|
return 0 on success
|
||||||
|
*/
|
||||||
|
int wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
|
||||||
|
word32 *outLen, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen)
|
||||||
|
{
|
||||||
|
return ed25519_sign_msg(hash, hashLen, out, outLen, key, Ed25519ph, context,
|
||||||
|
contextLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
in contains the message to sign
|
||||||
|
inLen is the length of the message to sign
|
||||||
|
out is the buffer to write the signature
|
||||||
|
outLen [in/out] input size of out buf
|
||||||
|
output gets set as the final length of out
|
||||||
|
key is the ed25519 key to use when signing
|
||||||
|
context extra signing data
|
||||||
|
contextLen length of extra signing data
|
||||||
|
return 0 on success
|
||||||
|
*/
|
||||||
|
int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
|
||||||
|
word32 *outLen, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
byte hash[WC_SHA512_DIGEST_SIZE];
|
||||||
|
|
||||||
|
ret = wc_Sha512Hash(in, inLen, hash);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return wc_ed25519ph_sign_hash(hash, sizeof(hash), out, outLen, key, context,
|
||||||
|
contextLen);
|
||||||
|
}
|
||||||
#endif /* HAVE_ED25519_SIGN */
|
#endif /* HAVE_ED25519_SIGN */
|
||||||
|
|
||||||
#ifdef HAVE_ED25519_VERIFY
|
#ifdef HAVE_ED25519_VERIFY
|
||||||
|
|
||||||
/*
|
/*
|
||||||
sig is array of bytes containing the signature
|
sig is array of bytes containing the signature
|
||||||
siglen is the length of sig byte array
|
sigLen is the length of sig byte array
|
||||||
msg the array of bytes containing the message
|
msg the array of bytes containing the message
|
||||||
msglen length of msg array
|
msgLen length of msg array
|
||||||
res will be 1 on successful verify and 0 on unsuccessful
|
res will be 1 on successful verify and 0 on unsuccessful
|
||||||
|
key Ed25519 public key
|
||||||
return 0 and res of 1 on success
|
return 0 and res of 1 on success
|
||||||
*/
|
*/
|
||||||
int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
|
static int ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
||||||
word32 msglen, int* res, ed25519_key* key)
|
word32 msgLen, int* res, ed25519_key* key,
|
||||||
|
byte type, const byte* context, byte contextLen)
|
||||||
{
|
{
|
||||||
byte rcheck[ED25519_KEY_SIZE];
|
byte rcheck[ED25519_KEY_SIZE];
|
||||||
byte h[WC_SHA512_DIGEST_SIZE];
|
byte h[WC_SHA512_DIGEST_SIZE];
|
||||||
@ -243,14 +356,16 @@ int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
|
|||||||
wc_Sha512 sha;
|
wc_Sha512 sha;
|
||||||
|
|
||||||
/* sanity check on arguments */
|
/* sanity check on arguments */
|
||||||
if (sig == NULL || msg == NULL || res == NULL || key == NULL)
|
if (sig == NULL || msg == NULL || res == NULL || key == NULL ||
|
||||||
|
(context == NULL && contextLen != 0)) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
/* set verification failed by default */
|
/* set verification failed by default */
|
||||||
*res = 0;
|
*res = 0;
|
||||||
|
|
||||||
/* check on basics needed to verify signature */
|
/* check on basics needed to verify signature */
|
||||||
if (siglen < ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
|
if (sigLen < ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* uncompress A (public key), test if valid, and negate it */
|
/* uncompress A (public key), test if valid, and negate it */
|
||||||
@ -263,11 +378,21 @@ int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
|
|||||||
ret = wc_InitSha512(&sha);
|
ret = wc_InitSha512(&sha);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = wc_Sha512Update(&sha, sig, ED25519_SIG_SIZE/2);
|
if (type == Ed25519ctx || type == Ed25519ph) {
|
||||||
|
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, &type, sizeof(type));
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
|
||||||
|
if (ret == 0 && context != NULL)
|
||||||
|
ret = wc_Sha512Update(&sha, context, contextLen);
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Update(&sha, sig, ED25519_SIG_SIZE/2);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
|
ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_Sha512Update(&sha, msg, msglen);
|
ret = wc_Sha512Update(&sha, msg, msgLen);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_Sha512Final(&sha, h);
|
ret = wc_Sha512Final(&sha, h);
|
||||||
wc_Sha512Free(&sha);
|
wc_Sha512Free(&sha);
|
||||||
@ -302,6 +427,85 @@ int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sig is array of bytes containing the signature
|
||||||
|
sigLen is the length of sig byte array
|
||||||
|
msg the array of bytes containing the message
|
||||||
|
msgLen length of msg array
|
||||||
|
res will be 1 on successful verify and 0 on unsuccessful
|
||||||
|
key Ed25519 public key
|
||||||
|
return 0 and res of 1 on success
|
||||||
|
*/
|
||||||
|
int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
||||||
|
word32 msgLen, int* res, ed25519_key* key)
|
||||||
|
{
|
||||||
|
return ed25519_verify_msg(sig, sigLen, msg, msgLen, res, key, Ed25519, NULL,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sig is array of bytes containing the signature
|
||||||
|
sigLen is the length of sig byte array
|
||||||
|
msg the array of bytes containing the message
|
||||||
|
msgLen length of msg array
|
||||||
|
res will be 1 on successful verify and 0 on unsuccessful
|
||||||
|
key Ed25519 public key
|
||||||
|
context extra sigining data
|
||||||
|
contextLen length of extra sigining data
|
||||||
|
return 0 and res of 1 on success
|
||||||
|
*/
|
||||||
|
int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
||||||
|
word32 msgLen, int* res, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen)
|
||||||
|
{
|
||||||
|
return ed25519_verify_msg(sig, sigLen, msg, msgLen, res, key, Ed25519ctx,
|
||||||
|
context, contextLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sig is array of bytes containing the signature
|
||||||
|
sigLen is the length of sig byte array
|
||||||
|
hash the array of bytes containing the SHA-512 hash of the message
|
||||||
|
hashLen length of hash array
|
||||||
|
res will be 1 on successful verify and 0 on unsuccessful
|
||||||
|
key Ed25519 public key
|
||||||
|
context extra sigining data
|
||||||
|
contextLen length of extra sigining data
|
||||||
|
return 0 and res of 1 on success
|
||||||
|
*/
|
||||||
|
int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
|
||||||
|
word32 hashLen, int* res, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen)
|
||||||
|
{
|
||||||
|
return ed25519_verify_msg(sig, sigLen, hash, hashLen, res, key, Ed25519ph,
|
||||||
|
context, contextLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sig is array of bytes containing the signature
|
||||||
|
sigLen is the length of sig byte array
|
||||||
|
msg the array of bytes containing the message
|
||||||
|
msgLen length of msg array
|
||||||
|
res will be 1 on successful verify and 0 on unsuccessful
|
||||||
|
key Ed25519 public key
|
||||||
|
context extra sigining data
|
||||||
|
contextLen length of extra sigining data
|
||||||
|
return 0 and res of 1 on success
|
||||||
|
*/
|
||||||
|
int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
||||||
|
word32 msgLen, int* res, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
byte hash[WC_SHA512_DIGEST_SIZE];
|
||||||
|
|
||||||
|
ret = wc_Sha512Hash(msg, msgLen, hash);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return wc_ed25519ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key,
|
||||||
|
context, contextLen);
|
||||||
|
}
|
||||||
#endif /* HAVE_ED25519_VERIFY */
|
#endif /* HAVE_ED25519_VERIFY */
|
||||||
|
|
||||||
|
|
||||||
|
@ -18458,6 +18458,248 @@ done:
|
|||||||
}
|
}
|
||||||
#endif /* WOLFSSL_TEST_CERT */
|
#endif /* WOLFSSL_TEST_CERT */
|
||||||
|
|
||||||
|
#if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_EXPORT) && \
|
||||||
|
defined(HAVE_ED25519_KEY_IMPORT)
|
||||||
|
static int ed25519ctx_test(void)
|
||||||
|
{
|
||||||
|
byte out[ED25519_SIG_SIZE];
|
||||||
|
word32 outlen;
|
||||||
|
#ifdef HAVE_ED25519_VERIFY
|
||||||
|
int verify;
|
||||||
|
#endif /* HAVE_ED25519_VERIFY */
|
||||||
|
ed25519_key key;
|
||||||
|
|
||||||
|
static const byte sKeyCtx[] = {
|
||||||
|
0x03,0x05,0x33,0x4e,0x38,0x1a,0xf7,0x8f,
|
||||||
|
0x14,0x1c,0xb6,0x66,0xf6,0x19,0x9f,0x57,
|
||||||
|
0xbc,0x34,0x95,0x33,0x5a,0x25,0x6a,0x95,
|
||||||
|
0xbd,0x2a,0x55,0xbf,0x54,0x66,0x63,0xf6
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte pKeyCtx[] = {
|
||||||
|
0xdf,0xc9,0x42,0x5e,0x4f,0x96,0x8f,0x7f,
|
||||||
|
0x0c,0x29,0xf0,0x25,0x9c,0xf5,0xf9,0xae,
|
||||||
|
0xd6,0x85,0x1c,0x2b,0xb4,0xad,0x8b,0xfb,
|
||||||
|
0x86,0x0c,0xfe,0xe0,0xab,0x24,0x82,0x92
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte sigCtx1[] = {
|
||||||
|
0x55,0xa4,0xcc,0x2f,0x70,0xa5,0x4e,0x04,
|
||||||
|
0x28,0x8c,0x5f,0x4c,0xd1,0xe4,0x5a,0x7b,
|
||||||
|
0xb5,0x20,0xb3,0x62,0x92,0x91,0x18,0x76,
|
||||||
|
0xca,0xda,0x73,0x23,0x19,0x8d,0xd8,0x7a,
|
||||||
|
0x8b,0x36,0x95,0x0b,0x95,0x13,0x00,0x22,
|
||||||
|
0x90,0x7a,0x7f,0xb7,0xc4,0xe9,0xb2,0xd5,
|
||||||
|
0xf6,0xcc,0xa6,0x85,0xa5,0x87,0xb4,0xb2,
|
||||||
|
0x1f,0x4b,0x88,0x8e,0x4e,0x7e,0xdb,0x0d
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte sigCtx2[] = {
|
||||||
|
0xcc,0x5e,0x63,0xa2,0x7e,0x94,0xaf,0xd3,
|
||||||
|
0x41,0x83,0x38,0xd2,0x48,0x6f,0xa9,0x2a,
|
||||||
|
0xf9,0x91,0x7c,0x2d,0x98,0x9e,0x06,0xe5,
|
||||||
|
0x02,0x77,0x72,0x1c,0x34,0x38,0x18,0xb4,
|
||||||
|
0x21,0x96,0xbc,0x29,0x2e,0x68,0xf3,0x4d,
|
||||||
|
0x85,0x9b,0xbe,0xad,0x17,0x9f,0x54,0x54,
|
||||||
|
0x2d,0x4b,0x04,0xdc,0xfb,0xfa,0x4a,0x68,
|
||||||
|
0x4e,0x39,0x50,0xfb,0x1c,0xcd,0x8d,0x0d
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte msgCtx[] = {
|
||||||
|
0xf7,0x26,0x93,0x6d,0x19,0xc8,0x00,0x49,
|
||||||
|
0x4e,0x3f,0xda,0xff,0x20,0xb2,0x76,0xa8
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte contextCtx[] = {
|
||||||
|
0x66,0x6f,0x6f
|
||||||
|
};
|
||||||
|
|
||||||
|
outlen = sizeof(out);
|
||||||
|
XMEMSET(out, 0, sizeof(out));
|
||||||
|
|
||||||
|
if (wc_ed25519_import_private_key(sKeyCtx, ED25519_KEY_SIZE, pKeyCtx,
|
||||||
|
sizeof(pKeyCtx), &key) != 0)
|
||||||
|
return -9020;
|
||||||
|
|
||||||
|
if (wc_ed25519ctx_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key,
|
||||||
|
contextCtx, sizeof(contextCtx)) != 0)
|
||||||
|
return -9021;
|
||||||
|
|
||||||
|
if (XMEMCMP(out, sigCtx1, 64))
|
||||||
|
return -9022;
|
||||||
|
|
||||||
|
#if defined(HAVE_ED25519_VERIFY)
|
||||||
|
/* test verify on good msg */
|
||||||
|
if (wc_ed25519ctx_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify,
|
||||||
|
&key, contextCtx, sizeof(contextCtx)) != 0 ||
|
||||||
|
verify != 1)
|
||||||
|
return -9023;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (wc_ed25519ctx_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key, NULL,
|
||||||
|
0) != 0)
|
||||||
|
return -9025;
|
||||||
|
|
||||||
|
if (XMEMCMP(out, sigCtx2, 64))
|
||||||
|
return -9026;
|
||||||
|
|
||||||
|
#if defined(HAVE_ED25519_VERIFY)
|
||||||
|
/* test verify on good msg */
|
||||||
|
if (wc_ed25519ctx_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify,
|
||||||
|
&key, NULL, 0) != 0 || verify != 1)
|
||||||
|
return -9027;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wc_ed25519_free(&key);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ed25519ph_test(void)
|
||||||
|
{
|
||||||
|
byte out[ED25519_SIG_SIZE];
|
||||||
|
word32 outlen;
|
||||||
|
#ifdef HAVE_ED25519_VERIFY
|
||||||
|
int verify;
|
||||||
|
#endif /* HAVE_ED25519_VERIFY */
|
||||||
|
ed25519_key key;
|
||||||
|
|
||||||
|
static const byte sKeyPh[] = {
|
||||||
|
0x83,0x3f,0xe6,0x24,0x09,0x23,0x7b,0x9d,
|
||||||
|
0x62,0xec,0x77,0x58,0x75,0x20,0x91,0x1e,
|
||||||
|
0x9a,0x75,0x9c,0xec,0x1d,0x19,0x75,0x5b,
|
||||||
|
0x7d,0xa9,0x01,0xb9,0x6d,0xca,0x3d,0x42
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte pKeyPh[] = {
|
||||||
|
0xec,0x17,0x2b,0x93,0xad,0x5e,0x56,0x3b,
|
||||||
|
0xf4,0x93,0x2c,0x70,0xe1,0x24,0x50,0x34,
|
||||||
|
0xc3,0x54,0x67,0xef,0x2e,0xfd,0x4d,0x64,
|
||||||
|
0xeb,0xf8,0x19,0x68,0x34,0x67,0xe2,0xbf
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte sigPh1[] = {
|
||||||
|
0x98,0xa7,0x02,0x22,0xf0,0xb8,0x12,0x1a,
|
||||||
|
0xa9,0xd3,0x0f,0x81,0x3d,0x68,0x3f,0x80,
|
||||||
|
0x9e,0x46,0x2b,0x46,0x9c,0x7f,0xf8,0x76,
|
||||||
|
0x39,0x49,0x9b,0xb9,0x4e,0x6d,0xae,0x41,
|
||||||
|
0x31,0xf8,0x50,0x42,0x46,0x3c,0x2a,0x35,
|
||||||
|
0x5a,0x20,0x03,0xd0,0x62,0xad,0xf5,0xaa,
|
||||||
|
0xa1,0x0b,0x8c,0x61,0xe6,0x36,0x06,0x2a,
|
||||||
|
0xaa,0xd1,0x1c,0x2a,0x26,0x08,0x34,0x06
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte sigPh2[] = {
|
||||||
|
0xe0,0x39,0x70,0x2b,0x4c,0x25,0x95,0xa6,
|
||||||
|
0xa5,0x41,0xac,0x85,0x09,0x23,0x6e,0x29,
|
||||||
|
0x90,0x47,0x47,0x95,0x33,0x0c,0x9b,0x34,
|
||||||
|
0xa7,0x5f,0x58,0xa6,0x60,0x12,0x9e,0x08,
|
||||||
|
0xfd,0x73,0x69,0x43,0xfb,0x19,0x43,0xa5,
|
||||||
|
0x57,0x20,0xb9,0xe0,0x95,0x7b,0x1e,0xd6,
|
||||||
|
0x73,0x48,0x16,0x61,0x9f,0x13,0x88,0xf4,
|
||||||
|
0x3f,0x73,0xe6,0xe3,0xba,0xa8,0x1c,0x0e
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte msgPh[] = {
|
||||||
|
0x61,0x62,0x63
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SHA-512 hash of msgPh */
|
||||||
|
static const byte hashPh[] = {
|
||||||
|
0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,
|
||||||
|
0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31,
|
||||||
|
0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,
|
||||||
|
0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a,
|
||||||
|
0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,
|
||||||
|
0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd,
|
||||||
|
0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,
|
||||||
|
0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f
|
||||||
|
};
|
||||||
|
|
||||||
|
static const byte contextPh2[] = {
|
||||||
|
0x66,0x6f,0x6f
|
||||||
|
};
|
||||||
|
|
||||||
|
outlen = sizeof(out);
|
||||||
|
XMEMSET(out, 0, sizeof(out));
|
||||||
|
|
||||||
|
if (wc_ed25519_import_private_key(sKeyPh, ED25519_KEY_SIZE, pKeyPh,
|
||||||
|
sizeof(pKeyPh), &key) != 0) {
|
||||||
|
return -9030;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wc_ed25519ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, NULL,
|
||||||
|
0) != 0) {
|
||||||
|
return -9031;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XMEMCMP(out, sigPh1, 64))
|
||||||
|
return -9032;
|
||||||
|
|
||||||
|
#if defined(HAVE_ED25519_VERIFY)
|
||||||
|
/* test verify on good msg */
|
||||||
|
if (wc_ed25519ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify,
|
||||||
|
&key, NULL, 0) != 0 ||
|
||||||
|
verify != 1) {
|
||||||
|
return -9033;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (wc_ed25519ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key,
|
||||||
|
contextPh2, sizeof(contextPh2)) != 0) {
|
||||||
|
return -9035;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XMEMCMP(out, sigPh2, 64))
|
||||||
|
return -9036;
|
||||||
|
|
||||||
|
#if defined(HAVE_ED25519_VERIFY)
|
||||||
|
/* test verify on good msg */
|
||||||
|
if (wc_ed25519ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify,
|
||||||
|
&key, contextPh2, sizeof(contextPh2)) != 0 ||
|
||||||
|
verify != 1) {
|
||||||
|
return -9037;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (wc_ed25519ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, NULL,
|
||||||
|
0) != 0) {
|
||||||
|
return -9041;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XMEMCMP(out, sigPh1, 64))
|
||||||
|
return -9042;
|
||||||
|
|
||||||
|
#if defined(HAVE_ED25519_VERIFY)
|
||||||
|
if (wc_ed25519ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify,
|
||||||
|
&key, NULL, 0) != 0 ||
|
||||||
|
verify != 1) {
|
||||||
|
return -9043;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (wc_ed25519ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key,
|
||||||
|
contextPh2, sizeof(contextPh2)) != 0) {
|
||||||
|
return -9045;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XMEMCMP(out, sigPh2, 64))
|
||||||
|
return -9046;
|
||||||
|
|
||||||
|
#if defined(HAVE_ED25519_VERIFY)
|
||||||
|
if (wc_ed25519ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify,
|
||||||
|
&key, contextPh2, sizeof(contextPh2)) != 0 ||
|
||||||
|
verify != 1) {
|
||||||
|
return -9047;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wc_ed25519_free(&key);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_KEY_IMPORT */
|
||||||
|
|
||||||
int ed25519_test(void)
|
int ed25519_test(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -18916,6 +19158,14 @@ int ed25519_test(void)
|
|||||||
#endif /* HAVE_ED25519_VERIFY */
|
#endif /* HAVE_ED25519_VERIFY */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = ed25519ctx_test();
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = ed25519ph_test();
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifndef NO_ASN
|
#ifndef NO_ASN
|
||||||
/* Try ASN.1 encoded private-only key and public key. */
|
/* Try ASN.1 encoded private-only key and public key. */
|
||||||
idx = 0;
|
idx = 0;
|
||||||
|
@ -63,6 +63,12 @@
|
|||||||
#define ED25519_PRV_KEY_SIZE (ED25519_PUB_KEY_SIZE+ED25519_KEY_SIZE)
|
#define ED25519_PRV_KEY_SIZE (ED25519_PUB_KEY_SIZE+ED25519_KEY_SIZE)
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Ed25519 = -1,
|
||||||
|
Ed25519ctx = 0,
|
||||||
|
Ed25519ph = 1,
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef WC_ED25519KEY_TYPE_DEFINED
|
#ifndef WC_ED25519KEY_TYPE_DEFINED
|
||||||
typedef struct ed25519_key ed25519_key;
|
typedef struct ed25519_key ed25519_key;
|
||||||
#define WC_ED25519KEY_TYPE_DEFINED
|
#define WC_ED25519KEY_TYPE_DEFINED
|
||||||
@ -90,11 +96,35 @@ int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
|
|||||||
WOLFSSL_API
|
WOLFSSL_API
|
||||||
int wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key);
|
int wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key);
|
||||||
WOLFSSL_API
|
WOLFSSL_API
|
||||||
int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
|
int wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
|
||||||
word32 *outlen, ed25519_key* key);
|
word32 *outLen, ed25519_key* key);
|
||||||
WOLFSSL_API
|
WOLFSSL_API
|
||||||
int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
|
int wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out,
|
||||||
word32 msglen, int* stat, ed25519_key* key);
|
word32 *outLen, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen);
|
||||||
|
WOLFSSL_API
|
||||||
|
int wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
|
||||||
|
word32 *outLen, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen);
|
||||||
|
WOLFSSL_API
|
||||||
|
int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
|
||||||
|
word32 *outLen, ed25519_key* key, const byte* context,
|
||||||
|
byte contextLen);
|
||||||
|
WOLFSSL_API
|
||||||
|
int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
||||||
|
word32 msgLen, int* stat, ed25519_key* key);
|
||||||
|
WOLFSSL_API
|
||||||
|
int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
||||||
|
word32 msgLen, int* stat, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen);
|
||||||
|
WOLFSSL_API
|
||||||
|
int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
|
||||||
|
word32 hashLen, int* stat, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen);
|
||||||
|
WOLFSSL_API
|
||||||
|
int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
||||||
|
word32 msgLen, int* stat, ed25519_key* key,
|
||||||
|
const byte* context, byte contextLen);
|
||||||
WOLFSSL_API
|
WOLFSSL_API
|
||||||
int wc_ed25519_init(ed25519_key* key);
|
int wc_ed25519_init(ed25519_key* key);
|
||||||
WOLFSSL_API
|
WOLFSSL_API
|
||||||
|
Reference in New Issue
Block a user