mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #4802 from SparkiDev/ecies_compressed
ECIES: allow compressed public keyspull/4805/head
commit
77a64d0087
|
@ -1539,6 +1539,7 @@ int wc_ecc_sig_size(ecc_key* key);
|
|||
\endcode
|
||||
|
||||
\sa wc_ecc_encrypt
|
||||
\sa wc_ecc_encrypt_ex
|
||||
\sa wc_ecc_decrypt
|
||||
*/
|
||||
WOLFSSL_API
|
||||
|
@ -1759,12 +1760,77 @@ int wc_ecc_ctx_set_info(ecEncCtx*, const byte* info, int sz);
|
|||
}
|
||||
\endcode
|
||||
|
||||
\sa wc_ecc_encrypt_ex
|
||||
\sa wc_ecc_decrypt
|
||||
*/
|
||||
WOLFSSL_API
|
||||
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx);
|
||||
|
||||
/*!
|
||||
\ingroup ECC
|
||||
|
||||
\brief This function encrypts the given input message from msg
|
||||
to out. This function takes an optional ctx object as parameter.
|
||||
When supplied, encryption proceeds based on the ecEncCtx's
|
||||
encAlgo, kdfAlgo, and macAlgo. If ctx is not supplied, processing
|
||||
completes with the default algorithms, ecAES_128_CBC,
|
||||
ecHKDF_SHA256 and ecHMAC_SHA256. This function requires that
|
||||
the messages are padded according to the encryption type specified by ctx.
|
||||
|
||||
\return 0 Returned upon successfully encrypting the input message
|
||||
\return BAD_FUNC_ARG Returned if privKey, pubKey, msg, msgSz, out,
|
||||
or outSz are NULL, or the ctx object specifies an unsupported
|
||||
encryption type
|
||||
\return BAD_ENC_STATE_E Returned if the ctx object given is in a
|
||||
state that is not appropriate for encryption
|
||||
\return BUFFER_E Returned if the supplied output buffer is too
|
||||
small to store the encrypted ciphertext
|
||||
\return MEMORY_E Returned if there is an error allocating memory
|
||||
for the shared secret key
|
||||
|
||||
\param privKey pointer to the ecc_key object containing the
|
||||
private key to use for encryption
|
||||
\param pubKey pointer to the ecc_key object containing the public
|
||||
key of the peer with whom one wishes to communicate
|
||||
\param msg pointer to the buffer holding the message to encrypt
|
||||
\param msgSz size of the buffer to encrypt
|
||||
\param out pointer to the buffer in which to store the encrypted
|
||||
ciphertext
|
||||
\param outSz pointer to a word32 object containing the available
|
||||
size in the out buffer. Upon successfully encrypting the message,
|
||||
holds the number of bytes written to the output buffer
|
||||
\param ctx Optional: pointer to an ecEncCtx object specifying different
|
||||
encryption algorithms to use
|
||||
\param compressed Public key field is to be output in compressed format.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
byte msg[] = { initialize with msg to encrypt. Ensure padded to block size };
|
||||
byte out[sizeof(msg)];
|
||||
word32 outSz = sizeof(out);
|
||||
int ret;
|
||||
ecc_key cli, serv;
|
||||
// initialize cli with private key
|
||||
// initialize serv with received public key
|
||||
|
||||
ecEncCtx* cliCtx, servCtx;
|
||||
// initialize cliCtx and servCtx
|
||||
// exchange salts
|
||||
ret = wc_ecc_encrypt_ex(&cli, &serv, msg, sizeof(msg), out, &outSz, cliCtx,
|
||||
1);
|
||||
if(ret != 0) {
|
||||
// error encrypting message
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa wc_ecc_encrypt
|
||||
\sa wc_ecc_decrypt
|
||||
*/
|
||||
WOLFSSL_API
|
||||
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed);
|
||||
|
||||
/*!
|
||||
\ingroup ECC
|
||||
|
||||
|
@ -1822,6 +1888,7 @@ int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
|||
\endcode
|
||||
|
||||
\sa wc_ecc_encrypt
|
||||
\sa wc_ecc_encrypt_ex
|
||||
*/
|
||||
WOLFSSL_API
|
||||
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
|
|
|
@ -11928,8 +11928,8 @@ static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
|
|||
ctx holds non default algos and inputs
|
||||
msgSz should be the right size for encAlgo, i.e., already padded
|
||||
return 0 on success */
|
||||
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
|
||||
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 blockSz = 0;
|
||||
|
@ -11979,7 +11979,12 @@ int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
|||
return ret;
|
||||
|
||||
#ifndef WOLFSSL_ECIES_OLD
|
||||
pubKeySz = 1 + wc_ecc_size(privKey) * 2;
|
||||
if (!compressed) {
|
||||
pubKeySz = 1 + wc_ecc_size(privKey) * 2;
|
||||
}
|
||||
else {
|
||||
pubKeySz = 1 + wc_ecc_size(privKey);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ctx->protocol == REQ_RESP_SERVER) {
|
||||
|
@ -12027,7 +12032,7 @@ int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
|||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
ret = wc_ecc_export_x963(privKey, out, &pubKeySz);
|
||||
ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
out += pubKeySz;
|
||||
|
@ -12191,6 +12196,15 @@ int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* ecc encrypt with shared secret run through kdf
|
||||
ctx holds non default algos and inputs
|
||||
msgSz should be the right size for encAlgo, i.e., already padded
|
||||
return 0 on success */
|
||||
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
|
||||
{
|
||||
return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
|
||||
}
|
||||
|
||||
/* ecc decrypt with shared secret run through kdf
|
||||
ctx holds non default algos and inputs
|
||||
|
@ -12257,6 +12271,11 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
|||
ret = ecc_public_key_size(privKey, &pubKeySz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#ifdef HAVE_COMP_KEY
|
||||
if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
|
||||
pubKeySz = (pubKeySz / 2) + 1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (ctx->protocol == REQ_RESP_CLIENT) {
|
||||
|
|
|
@ -24642,6 +24642,66 @@ WOLFSSL_TEST_SUBROUTINE int ecc_encrypt_test(void)
|
|||
ret = -10412; goto done;
|
||||
}
|
||||
|
||||
#ifdef HAVE_COMP_KEY
|
||||
/* Create new client and server contexts. */
|
||||
wc_ecc_ctx_free(srvCtx);
|
||||
wc_ecc_ctx_free(cliCtx);
|
||||
/* let's verify message exchange works, A is client, B is server */
|
||||
cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng);
|
||||
srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng);
|
||||
if (cliCtx == NULL || srvCtx == NULL) {
|
||||
ret = -10416; goto done;
|
||||
}
|
||||
|
||||
/* get salt to send to peer */
|
||||
tmpSalt = wc_ecc_ctx_get_own_salt(cliCtx);
|
||||
if (tmpSalt == NULL) {
|
||||
ret = -10417; goto done;
|
||||
}
|
||||
XMEMCPY(cliSalt, tmpSalt, EXCHANGE_SALT_SZ);
|
||||
|
||||
tmpSalt = wc_ecc_ctx_get_own_salt(srvCtx);
|
||||
if (tmpSalt == NULL) {
|
||||
ret = -10418; goto done;
|
||||
}
|
||||
XMEMCPY(srvSalt, tmpSalt, EXCHANGE_SALT_SZ);
|
||||
|
||||
/* in actual use, we'd get the peer's salt over the transport */
|
||||
ret = wc_ecc_ctx_set_peer_salt(cliCtx, srvSalt);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
ret = wc_ecc_ctx_set_peer_salt(srvCtx, cliSalt);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
|
||||
ret = wc_ecc_ctx_set_info(cliCtx, (byte*)"wolfSSL MSGE", 11);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
ret = wc_ecc_ctx_set_info(srvCtx, (byte*)"wolfSSL MSGE", 11);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
|
||||
/* get encrypted msg (request) to send to B - compressed public key */
|
||||
outSz = sizeof(out);
|
||||
ret = wc_ecc_encrypt_ex(userA, userB, msg, sizeof(msg), out, &outSz, cliCtx,
|
||||
1);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
|
||||
#ifndef WOLFSSL_ECIES_OLD
|
||||
wc_ecc_free(tmpKey);
|
||||
#endif
|
||||
/* B decrypts msg (request) from A - out has a compressed public key */
|
||||
plainSz = sizeof(plain);
|
||||
ret = wc_ecc_decrypt(userB, tmpKey, out, outSz, plain, &plainSz, srvCtx);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
|
||||
if (XMEMCMP(plain, msg, sizeof(msg)) != 0) {
|
||||
ret = -10419; goto done;
|
||||
}
|
||||
#endif /* HAVE_COMP_KEY */
|
||||
|
||||
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
|
||||
ret = ecc_encrypt_kat(&rng);
|
||||
#endif
|
||||
|
|
|
@ -869,10 +869,13 @@ int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz);
|
|||
|
||||
WOLFSSL_API
|
||||
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx);
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx);
|
||||
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx);
|
||||
|
||||
#endif /* HAVE_ECC_ENCRYPT */
|
||||
|
||||
|
|
Loading…
Reference in New Issue