mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Merge pull request #5308 from SparkiDev/ecies_gen_iv
ECIES: Google Pay generates IV and places it before msg
This commit is contained in:
@ -3041,7 +3041,7 @@ fi
|
||||
|
||||
# ECC encrypt
|
||||
AC_ARG_ENABLE([eccencrypt],
|
||||
[AS_HELP_STRING([--enable-eccencrypt],[Enable ECC encrypt (default: disabled). yes = SEC1 standard, iso18033 = ISO 18033 standard, old = original wolfSSL algorithm])],
|
||||
[AS_HELP_STRING([--enable-eccencrypt],[Enable ECC encrypt (default: disabled). yes = SEC1 standard, geniv = Generate IV, iso18033 = ISO 18033 standard, old = original wolfSSL algorithm])],
|
||||
[ ENABLED_ECC_ENCRYPT=$enableval ],
|
||||
[ ENABLED_ECC_ENCRYPT=no ]
|
||||
)
|
||||
@ -3065,6 +3065,10 @@ then
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ECIES_ISO18033"
|
||||
fi
|
||||
if test "$ENABLED_ECC_ENCRYPT" = "geniv"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ECIES_GEN_IV"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Elliptic Curve-Based Certificateless Signatures for Identity-Based Encryption (ECCSI)
|
||||
|
@ -1664,6 +1664,7 @@ int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo,
|
||||
|
||||
\sa wc_ecc_ctx_new
|
||||
\sa wc_ecc_ctx_set_peer_salt
|
||||
\sa wc_ecc_ctx_set_kdf_salt
|
||||
*/
|
||||
|
||||
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx*);
|
||||
@ -1702,10 +1703,46 @@ const byte* wc_ecc_ctx_get_own_salt(ecEncCtx*);
|
||||
\endcode
|
||||
|
||||
\sa wc_ecc_ctx_get_own_salt
|
||||
\sa wc_ecc_ctx_set_kdf_salt
|
||||
*/
|
||||
|
||||
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt);
|
||||
|
||||
/*!
|
||||
\ingroup ECC
|
||||
|
||||
\brief This function sets the salt pointer and length to use with KDF
|
||||
into the ecEncCtx object.
|
||||
|
||||
\return 0 Returned upon successfully setting the salt for the
|
||||
ecEncCtx object.
|
||||
\return BAD_FUNC_ARG Returned if the given ecEncCtx object is NULL
|
||||
or if the given salt is NULL and length is not NULL.
|
||||
|
||||
\param ctx pointer to the ecEncCtx for which to set the salt
|
||||
\param salt pointer to salt buffer
|
||||
\param len length salt in bytes
|
||||
|
||||
_Example_
|
||||
\code
|
||||
ecEncCtx* srvCtx;
|
||||
WC_WC_RNG rng;
|
||||
byte cliSalt[] = { fixed salt data };
|
||||
word32 cliSaltLen = (word32)sizeof(cliSalt);
|
||||
int ret;
|
||||
|
||||
wc_InitRng(&rng);
|
||||
cliCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng);
|
||||
|
||||
ret = wc_ecc_ctx_set_kdf_salt(&cliCtx, cliSalt, cliSaltLen);
|
||||
\endcode
|
||||
|
||||
\sa wc_ecc_ctx_get_own_salt
|
||||
\sa wc_ecc_ctx_get_peer_salt
|
||||
*/
|
||||
|
||||
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 len);
|
||||
|
||||
/*!
|
||||
\ingroup ECC
|
||||
|
||||
|
@ -25573,6 +25573,9 @@ static int test_wc_ecc_encryptDecrypt (void)
|
||||
word32 msgSz = (word32)XSTRLEN("EccBlock Size 16");
|
||||
#ifdef WOLFSSL_ECIES_OLD
|
||||
byte out[(sizeof("EccBlock Size 16") - 1) + WC_SHA256_DIGEST_SIZE];
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
byte out[KEY20 * 2 + 1 + AES_BLOCK_SIZE +
|
||||
(sizeof("EccBlock Size 16") - 1) + WC_SHA256_DIGEST_SIZE];
|
||||
#else
|
||||
byte out[KEY20 * 2 + 1 + (sizeof("EccBlock Size 16") - 1) + WC_SHA256_DIGEST_SIZE];
|
||||
#endif
|
||||
|
@ -12452,6 +12452,31 @@ int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the salt pointer into context.
|
||||
*
|
||||
* @param [in, out] ctx ECIES context object.
|
||||
* @param [in] salt Salt to use with KDF.
|
||||
* @param [in] len Length of salt in bytes.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
|
||||
*/
|
||||
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 len)
|
||||
{
|
||||
if (ctx == NULL || (salt == NULL && len != 0))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ctx->kdfSalt = salt;
|
||||
ctx->kdfSaltSz = len;
|
||||
|
||||
if (ctx->protocol == REQ_RESP_CLIENT) {
|
||||
ctx->srvSt = ecSRV_SALT_SET;
|
||||
}
|
||||
else if (ctx->protocol == REQ_RESP_SERVER) {
|
||||
ctx->srvSt = ecSRV_SALT_SET;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
|
||||
{
|
||||
@ -12569,12 +12594,12 @@ static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
case ecAES_128_CTR:
|
||||
*encKeySz = KEY_SIZE_128;
|
||||
*ivSz = IV_SIZE_128;
|
||||
*ivSz = 12;
|
||||
*blockSz = 1;
|
||||
break;
|
||||
case ecAES_256_CTR:
|
||||
*encKeySz = KEY_SIZE_256;
|
||||
*ivSz = IV_SIZE_128;
|
||||
*ivSz = 12;
|
||||
*blockSz = 1;
|
||||
break;
|
||||
#endif
|
||||
@ -12612,7 +12637,9 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
int ret = 0;
|
||||
word32 blockSz = 0;
|
||||
#ifndef WOLFSSL_ECIES_OLD
|
||||
#ifndef WOLFSSL_ECIES_GEN_IV
|
||||
byte iv[ECC_MAX_IV_SIZE];
|
||||
#endif
|
||||
word32 pubKeySz = 0;
|
||||
#endif
|
||||
word32 digestSz = 0;
|
||||
@ -12692,6 +12719,9 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
#ifdef WOLFSSL_ECIES_OLD
|
||||
if (*outSz < (msgSz + digestSz))
|
||||
return BUFFER_E;
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
if (*outSz < (pubKeySz + ivSz + msgSz + digestSz))
|
||||
return BUFFER_E;
|
||||
#else
|
||||
if (*outSz < (pubKeySz + msgSz + digestSz))
|
||||
return BUFFER_E;
|
||||
@ -12773,13 +12803,21 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
encKey = keys + offset;
|
||||
encIv = encKey + encKeySz;
|
||||
macKey = encKey + encKeySz + ivSz;
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
encKey = keys + offset;
|
||||
encIv = out;
|
||||
out += ivSz;
|
||||
macKey = encKey + encKeySz;
|
||||
ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
|
||||
#else
|
||||
XMEMSET(iv, 0, ivSz);
|
||||
encKey = keys + offset;
|
||||
encIv = iv;
|
||||
macKey = encKey + encKeySz;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
switch (ctx->encAlgo) {
|
||||
case ecAES_128_CBC:
|
||||
case ecAES_256_CBC:
|
||||
@ -12821,19 +12859,26 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
case ecAES_256_CTR:
|
||||
{
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte ctr_iv[AES_BLOCK_SIZE];
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
Aes aes[1];
|
||||
#else
|
||||
Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
|
||||
DYNAMIC_TYPE_AES);
|
||||
if (aes == NULL) {
|
||||
ret = MEMORY_E;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
Aes aes[1];
|
||||
#endif
|
||||
|
||||
/* Include 4 byte counter starting at all zeros. */
|
||||
XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
|
||||
XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
|
||||
AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
|
||||
|
||||
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
|
||||
ret = wc_AesSetKey(aes, encKey, encKeySz, ctr_iv,
|
||||
AES_ENCRYPTION);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
|
||||
@ -12877,8 +12922,14 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
if (ret == 0) {
|
||||
ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
|
||||
WC_SHA256_DIGEST_SIZE);
|
||||
if (ret == 0)
|
||||
if (ret == 0) {
|
||||
#if !defined(WOLFSSL_ECIES_GEN_IV)
|
||||
ret = wc_HmacUpdate(hmac, out, msgSz);
|
||||
#else
|
||||
/* IV is before encrypted message. */
|
||||
ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
|
||||
#endif
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
|
||||
if (ret == 0)
|
||||
@ -12900,6 +12951,8 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
if (ret == 0) {
|
||||
#ifdef WOLFSSL_ECIES_OLD
|
||||
*outSz = msgSz + digestSz;
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
*outSz = pubKeySz + ivSz + msgSz + digestSz;
|
||||
#else
|
||||
*outSz = pubKeySz + msgSz + digestSz;
|
||||
#endif
|
||||
@ -12934,7 +12987,9 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
int ret = 0;
|
||||
word32 blockSz = 0;
|
||||
#ifndef WOLFSSL_ECIES_OLD
|
||||
#ifndef WOLFSSL_ECIES_GEN_IV
|
||||
byte iv[ECC_MAX_IV_SIZE];
|
||||
#endif
|
||||
word32 pubKeySz = 0;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ecc_key* peerKey = NULL;
|
||||
@ -12965,7 +13020,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
int ivSz = 0;
|
||||
int offset = 0; /* in case using msg exchange */
|
||||
byte* encKey = NULL;
|
||||
byte* encIv = NULL;
|
||||
const byte* encIv = NULL;
|
||||
byte* macKey = NULL;
|
||||
|
||||
|
||||
@ -13022,6 +13077,14 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
|
||||
if (*outSz < (msgSz - digestSz))
|
||||
return BUFFER_E;
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
|
||||
return BAD_PADDING_E;
|
||||
|
||||
if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
|
||||
return BAD_FUNC_ARG;
|
||||
if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
|
||||
return BUFFER_E;
|
||||
#else
|
||||
if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
|
||||
return BAD_PADDING_E;
|
||||
@ -13133,6 +13196,12 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
encKey = keys + offset;
|
||||
encIv = encKey + encKeySz;
|
||||
macKey = encKey + encKeySz + ivSz;
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
encKey = keys + offset;
|
||||
encIv = msg;
|
||||
msg += ivSz;
|
||||
msgSz -= ivSz;
|
||||
macKey = encKey + encKeySz;
|
||||
#else
|
||||
XMEMSET(iv, 0, ivSz);
|
||||
encKey = keys + offset;
|
||||
@ -13159,7 +13228,12 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
|
||||
WC_SHA256_DIGEST_SIZE);
|
||||
if (ret == 0)
|
||||
#if !defined(WOLFSSL_ECIES_GEN_IV)
|
||||
ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
|
||||
#else
|
||||
/* IV is before encrypted message. */
|
||||
ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
|
||||
#endif
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
|
||||
|
||||
@ -13236,7 +13310,12 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
#endif
|
||||
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesSetKey(aes, encKey, encKeySz, encIv,
|
||||
byte ctr_iv[AES_BLOCK_SIZE];
|
||||
/* Make a 16 byte IV from the bytes passed in. */
|
||||
XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
|
||||
XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
|
||||
AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
|
||||
ret = wc_AesSetKey(aes, encKey, encKeySz, ctr_iv,
|
||||
AES_ENCRYPTION);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
|
||||
|
@ -25213,6 +25213,34 @@ static int ecc_encrypt_kat(WC_RNG *rng)
|
||||
0xf4, 0x95, 0xd4, 0xcf, 0x30, 0xd6, 0xa2, 0xc5,
|
||||
0x35, 0x96, 0x6a, 0xd4, 0x36, 0x15, 0xa9, 0xbd,
|
||||
0x7f
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
/* EC P-256 point */
|
||||
0x04,
|
||||
/* X */
|
||||
0x50, 0xf2, 0x93, 0xa2, 0x48, 0xa9, 0xc0, 0x5a,
|
||||
0x9a, 0xa7, 0x70, 0x34, 0xb7, 0x7f, 0x4c, 0x3a,
|
||||
0xad, 0xfc, 0xd8, 0xb6, 0x76, 0x0a, 0xe3, 0xc1,
|
||||
0x87, 0x17, 0x07, 0x2d, 0x8d, 0xa3, 0x63, 0xa0,
|
||||
/* Y */
|
||||
0xc1, 0x27, 0xb2, 0x97, 0x9b, 0x84, 0xe7, 0xcd,
|
||||
0x20, 0x65, 0x8d, 0x2b, 0x6a, 0x93, 0x75, 0xaa,
|
||||
0x8b, 0xe1, 0x3a, 0x7b, 0x24, 0x1a, 0xbe, 0xe8,
|
||||
0x36, 0xd2, 0xe6, 0x34, 0x8a, 0x7a, 0xb3, 0x28,
|
||||
/* IV */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Encrypted Msg */
|
||||
0xe5, 0x17, 0xaf, 0x0d, 0x65, 0x4d, 0x3d, 0x50,
|
||||
0x96, 0x05, 0xc9, 0x63, 0x2c, 0xef, 0x1c, 0x1f,
|
||||
0x78, 0xc9, 0x90, 0x7a, 0x14, 0x00, 0xfc, 0x44,
|
||||
0x71, 0x6d, 0x57, 0x8c, 0xdf, 0x23, 0xca, 0x65,
|
||||
0xcf, 0x93, 0x06, 0xb6, 0x9a, 0xf4, 0x61, 0xbd,
|
||||
0x44, 0x1a, 0xeb, 0x52, 0x68, 0x0f, 0xd1, 0xde,
|
||||
/* HMAC */
|
||||
0x5a, 0x22, 0xc1, 0x5d, 0x99, 0x66, 0x3f, 0x24,
|
||||
0x35, 0x96, 0xac, 0xf7, 0xf6, 0x28, 0x45, 0x16,
|
||||
0x52, 0x19, 0x0d, 0xe4, 0xb2, 0xca, 0x5b, 0x28,
|
||||
0x4e, 0xbb, 0xf3, 0x98, 0x57, 0xd7, 0x3b, 0xe2
|
||||
#else
|
||||
0x04, 0x50, 0xf2, 0x93, 0xa2, 0x48, 0xa9, 0xc0,
|
||||
0x5a, 0x9a, 0xa7, 0x70, 0x34, 0xb7, 0x7f, 0x4c,
|
||||
@ -25357,6 +25385,8 @@ static int ecc_encrypt_e2e_test(WC_RNG* rng, ecc_key* userA, ecc_key* userB,
|
||||
byte plain[48];
|
||||
#ifdef WOLFSSL_ECIES_OLD
|
||||
byte out[80];
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
byte out[1 + ECC_KEYGEN_SIZE * 2 + 16 + 80];
|
||||
#else
|
||||
byte out[1 + ECC_KEYGEN_SIZE * 2 + 80];
|
||||
#endif
|
||||
@ -25372,6 +25402,8 @@ static int ecc_encrypt_e2e_test(WC_RNG* rng, ecc_key* userA, ecc_key* userB,
|
||||
byte plain2[48];
|
||||
#ifdef WOLFSSL_ECIES_OLD
|
||||
byte out2[80];
|
||||
#elif defined(WOLFSSL_ECIES_GEN_IV)
|
||||
byte out2[1 + ECC_KEYGEN_SIZE * 2 + 16 + 80];
|
||||
#else
|
||||
byte out2[1 + ECC_KEYGEN_SIZE * 2 + 80];
|
||||
#endif
|
||||
|
@ -850,6 +850,10 @@ enum ecFlags {
|
||||
REQ_RESP_SERVER = 2
|
||||
};
|
||||
|
||||
#ifndef WOLFSSL_ECIES_GEN_IV_SIZE
|
||||
#define WOLFSSL_ECIES_GEN_IV_SIZE 12
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct ecEncCtx ecEncCtx;
|
||||
|
||||
@ -870,6 +874,8 @@ const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz);
|
||||
|
||||
WOLFSSL_API
|
||||
|
Reference in New Issue
Block a user