forked from wolfSSL/wolfssl
add functions for using an hpke context multiple times
This commit is contained in:
@ -875,49 +875,63 @@ static int wc_HpkeSetupBaseSender(Hpke* hpke, HpkeBaseContext* context,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* give SetupBaseSender a more intuitive and wolfCrypt friendly name */
|
||||
int wc_HpkeInitSealContext(Hpke* hpke, HpkeBaseContext* context,
|
||||
void* ephemeralKey, void* receiverKey, byte* info, word32 infoSz)
|
||||
{
|
||||
if (hpke == NULL || context == NULL || ephemeralKey == NULL ||
|
||||
receiverKey == NULL || (info == NULL && infoSz > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* zero out all fields */
|
||||
XMEMSET(context, 0, sizeof(HpkeBaseContext));
|
||||
|
||||
return wc_HpkeSetupBaseSender(hpke, context, ephemeralKey, receiverKey,
|
||||
info, infoSz);
|
||||
}
|
||||
|
||||
/* encrypt a message using an hpke base context, return 0 or error */
|
||||
static int wc_HpkeContextSealBase(Hpke* hpke, HpkeBaseContext* context,
|
||||
int wc_HpkeContextSealBase(Hpke* hpke, HpkeBaseContext* context,
|
||||
byte* aad, word32 aadSz, byte* plaintext, word32 ptSz, byte* out)
|
||||
{
|
||||
int ret;
|
||||
byte nonce[HPKE_Nn_MAX];
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
Aes aes_key[1];
|
||||
Aes aes[1];
|
||||
#else
|
||||
Aes* aes_key;
|
||||
Aes* aes;
|
||||
#endif
|
||||
|
||||
if (hpke == NULL) {
|
||||
if (hpke == NULL || context == NULL || (aad == NULL && aadSz > 0) ||
|
||||
plaintext == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
aes_key = (Aes*)XMALLOC(sizeof(Aes), hpke->heap, DYNAMIC_TYPE_AES);
|
||||
if (aes_key == NULL) {
|
||||
aes = (Aes*)XMALLOC(sizeof(Aes), hpke->heap, DYNAMIC_TYPE_AES);
|
||||
if (aes == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = wc_AesInit(aes_key, hpke->heap, INVALID_DEVID);
|
||||
ret = wc_AesInit(aes, hpke->heap, INVALID_DEVID);
|
||||
if (ret == 0) {
|
||||
/* compute nonce */
|
||||
ret = wc_HpkeContextComputeNonce(hpke, context, nonce);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmSetKey(aes_key, context->key, hpke->Nk);
|
||||
ret = wc_AesGcmSetKey(aes, context->key, hpke->Nk);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(aes_key, out, plaintext, ptSz, nonce,
|
||||
ret = wc_AesGcmEncrypt(aes, out, plaintext, ptSz, nonce,
|
||||
hpke->Nn, out + ptSz, hpke->Nt, aad, aadSz);
|
||||
}
|
||||
/* increment sequence for non one shot */
|
||||
if (ret == 0) {
|
||||
context->seq++;
|
||||
}
|
||||
wc_AesFree(aes_key);
|
||||
wc_AesFree(aes);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(aes_key, hpke->heap, DYNAMIC_TYPE_AES);
|
||||
XFREE(aes, hpke->heap, DYNAMIC_TYPE_AES);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1111,49 +1125,60 @@ static int wc_HpkeSetupBaseReceiver(Hpke* hpke, HpkeBaseContext* context,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* give SetupBaseReceiver a more intuitive and wolfCrypt friendly name */
|
||||
int wc_HpkeInitOpenContext(Hpke* hpke, HpkeBaseContext* context,
|
||||
void* receiverKey, const byte* pubKey, word16 pubKeySz, byte* info,
|
||||
word32 infoSz)
|
||||
{
|
||||
if (hpke == NULL || context == NULL || receiverKey == NULL || pubKey == NULL
|
||||
|| (info == NULL && infoSz > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
return wc_HpkeSetupBaseReceiver(hpke, context, receiverKey, pubKey,
|
||||
pubKeySz, info, infoSz);
|
||||
}
|
||||
|
||||
/* decrypt a message using a setup hpke context, return 0 or error */
|
||||
static int wc_HpkeContextOpenBase(Hpke* hpke, HpkeBaseContext* context,
|
||||
byte* aad, word32 aadSz, byte* ciphertext, word32 ctSz, byte* out)
|
||||
int wc_HpkeContextOpenBase(Hpke* hpke, HpkeBaseContext* context, byte* aad,
|
||||
word32 aadSz, byte* ciphertext, word32 ctSz, byte* out)
|
||||
{
|
||||
int ret;
|
||||
byte nonce[HPKE_Nn_MAX];
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
Aes aes_key[1];
|
||||
Aes aes[1];
|
||||
#else
|
||||
Aes* aes_key;
|
||||
Aes* aes;
|
||||
#endif
|
||||
|
||||
if (hpke == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMSET(nonce, 0, sizeof(nonce));
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
aes_key = (Aes*)XMALLOC(sizeof(Aes), hpke->heap, DYNAMIC_TYPE_AES);
|
||||
if (aes_key == NULL) {
|
||||
aes = (Aes*)XMALLOC(sizeof(Aes), hpke->heap, DYNAMIC_TYPE_AES);
|
||||
if (aes == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* compute nonce */
|
||||
ret = wc_HpkeContextComputeNonce(hpke, context, nonce);
|
||||
if (ret == 0)
|
||||
ret = wc_AesInit(aes_key, hpke->heap, INVALID_DEVID);
|
||||
ret = wc_AesInit(aes, hpke->heap, INVALID_DEVID);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmSetKey(aes_key, context->key, hpke->Nk);
|
||||
ret = wc_AesGcmSetKey(aes, context->key, hpke->Nk);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmDecrypt(aes_key, out, ciphertext, ctSz, nonce,
|
||||
ret = wc_AesGcmDecrypt(aes, out, ciphertext, ctSz, nonce,
|
||||
hpke->Nn, ciphertext + ctSz, hpke->Nt, aad, aadSz);
|
||||
}
|
||||
/* increment sequence for non one shot */
|
||||
if (ret == 0) {
|
||||
context->seq++;
|
||||
}
|
||||
wc_AesFree(aes_key);
|
||||
wc_AesFree(aes);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(aes_key, hpke->heap, DYNAMIC_TYPE_AES);
|
||||
XFREE(aes, hpke->heap, DYNAMIC_TYPE_AES);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -25309,6 +25309,106 @@ static wc_test_ret_t hpke_test_single(Hpke* hpke)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static wc_test_ret_t hpke_test_multi(Hpke* hpke)
|
||||
{
|
||||
wc_test_ret_t ret = 0;
|
||||
int rngRet = 0;
|
||||
WC_RNG rng[1];
|
||||
const char* start_text = "this is a test";
|
||||
const char* info_text = "info";
|
||||
const char* aad_text = "aad";
|
||||
byte ciphertexts[2][MAX_HPKE_LABEL_SZ];
|
||||
byte plaintext[MAX_HPKE_LABEL_SZ];
|
||||
void* receiverKey = NULL;
|
||||
void* ephemeralKey = NULL;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
HpkeBaseContext* context = NULL;
|
||||
byte *pubKey = NULL; /* public key */
|
||||
word16 pubKeySz = (word16)HPKE_Npk_MAX;
|
||||
#else
|
||||
HpkeBaseContext context[1];
|
||||
byte pubKey[HPKE_Npk_MAX]; /* public key */
|
||||
word16 pubKeySz = (word16)sizeof(pubKey);
|
||||
#endif
|
||||
rngRet = ret = wc_InitRng(rng);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
pubKey = (byte *)XMALLOC(pubKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (pubKey == NULL)
|
||||
ret = MEMORY_E;
|
||||
if (ret == 0) {
|
||||
context = (HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext), HEAP_HINT,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (context == NULL)
|
||||
ret = MEMORY_E;
|
||||
#endif
|
||||
/* generate the keys */
|
||||
if (ret == 0)
|
||||
ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng);
|
||||
if (ret == 0)
|
||||
ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, rng);
|
||||
/* setup seal context */
|
||||
if (ret == 0) {
|
||||
ret = wc_HpkeInitSealContext(hpke, context, ephemeralKey, receiverKey,
|
||||
(byte*)info_text, (word32)XSTRLEN(info_text));
|
||||
}
|
||||
/* seal message 0 */
|
||||
if (ret == 0) {
|
||||
ret = wc_HpkeContextSealBase(hpke, context,
|
||||
(byte*)aad_text, (word32)XSTRLEN(aad_text),
|
||||
(byte*)start_text, (word32)XSTRLEN(start_text),
|
||||
ciphertexts[context->seq]);
|
||||
}
|
||||
/* seal message 1 */
|
||||
if (ret == 0) {
|
||||
ret = wc_HpkeContextSealBase(hpke, context,
|
||||
(byte*)aad_text, (word32)XSTRLEN(aad_text),
|
||||
(byte*)start_text, (word32)XSTRLEN(start_text),
|
||||
ciphertexts[context->seq]);
|
||||
}
|
||||
/* export ephemeral key */
|
||||
if (ret == 0)
|
||||
ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, pubKey, &pubKeySz);
|
||||
/* setup open context */
|
||||
if (ret == 0) {
|
||||
ret = wc_HpkeInitOpenContext(hpke, context, receiverKey, pubKey,
|
||||
pubKeySz, (byte*)info_text, (word32)XSTRLEN(info_text));
|
||||
}
|
||||
/* open message 0 */
|
||||
if (ret == 0) {
|
||||
ret = wc_HpkeContextOpenBase(hpke, context, (byte*)aad_text,
|
||||
(word32)XSTRLEN(aad_text), ciphertexts[context->seq],
|
||||
(word32)XSTRLEN(start_text), plaintext);
|
||||
}
|
||||
/* check message 0 */
|
||||
if (ret == 0)
|
||||
ret = XMEMCMP(plaintext, start_text, XSTRLEN(start_text));
|
||||
/* open message 1 */
|
||||
if (ret == 0) {
|
||||
ret = wc_HpkeContextOpenBase(hpke, context, (byte*)aad_text,
|
||||
(word32)XSTRLEN(aad_text), ciphertexts[context->seq],
|
||||
(word32)XSTRLEN(start_text), plaintext);
|
||||
}
|
||||
/* check message 1 */
|
||||
if (ret == 0)
|
||||
ret = XMEMCMP(plaintext, start_text, XSTRLEN(start_text));
|
||||
if (ephemeralKey != NULL)
|
||||
wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap);
|
||||
if (receiverKey != NULL)
|
||||
wc_HpkeFreeKey(hpke, hpke->kem, receiverKey, hpke->heap);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (pubKey != NULL)
|
||||
XFREE(pubKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (context != NULL)
|
||||
XFREE(context, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
if (rngRet == 0)
|
||||
wc_FreeRng(rng);
|
||||
return ret;
|
||||
}
|
||||
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void)
|
||||
{
|
||||
wc_test_ret_t ret = 0;
|
||||
@ -25319,14 +25419,15 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void)
|
||||
/* p256 */
|
||||
ret = wc_HpkeInit(hpke, DHKEM_P256_HKDF_SHA256, HKDF_SHA256,
|
||||
HPKE_AES_128_GCM, NULL);
|
||||
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
ret = hpke_test_single(hpke);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = hpke_test_multi(hpke);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_SHA384) && \
|
||||
@ -25334,12 +25435,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void)
|
||||
/* p384 */
|
||||
ret = wc_HpkeInit(hpke, DHKEM_P384_HKDF_SHA384, HKDF_SHA384,
|
||||
HPKE_AES_128_GCM, NULL);
|
||||
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
ret = hpke_test_single(hpke);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = hpke_test_multi(hpke);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
@ -25349,12 +25450,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void)
|
||||
/* p521 */
|
||||
ret = wc_HpkeInit(hpke, DHKEM_P521_HKDF_SHA512, HKDF_SHA512,
|
||||
HPKE_AES_128_GCM, NULL);
|
||||
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
ret = hpke_test_single(hpke);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = hpke_test_multi(hpke);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
@ -25364,12 +25465,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void)
|
||||
/* test with curve25519 and aes256 */
|
||||
ret = wc_HpkeInit(hpke, DHKEM_X25519_HKDF_SHA256, HKDF_SHA256,
|
||||
HPKE_AES_256_GCM, NULL);
|
||||
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
ret = hpke_test_single(hpke);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = hpke_test_multi(hpke);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
@ -120,9 +120,18 @@ WOLFSSL_API int wc_HpkeDeserializePublicKey(Hpke* hpke, void** key,
|
||||
const byte* in, word16 inSz);
|
||||
WOLFSSL_API void wc_HpkeFreeKey(Hpke* hpke, word16 kem, void* keypair,
|
||||
void* heap);
|
||||
WOLFSSL_API int wc_HpkeInitSealContext(Hpke* hpke, HpkeBaseContext* context,
|
||||
void* ephemeralKey, void* receiverKey, byte* info, word32 infoSz);
|
||||
WOLFSSL_API int wc_HpkeContextSealBase(Hpke* hpke, HpkeBaseContext* context,
|
||||
byte* aad, word32 aadSz, byte* plaintext, word32 ptSz, byte* out);
|
||||
WOLFSSL_API int wc_HpkeSealBase(Hpke* hpke, void* ephemeralKey,
|
||||
void* receiverKey, byte* info, word32 infoSz, byte* aad, word32 aadSz,
|
||||
byte* plaintext, word32 ptSz, byte* ciphertext);
|
||||
WOLFSSL_API int wc_HpkeInitOpenContext(Hpke* hpke, HpkeBaseContext* context,
|
||||
void* receiverKey, const byte* pubKey, word16 pubKeySz, byte* info,
|
||||
word32 infoSz);
|
||||
WOLFSSL_API int wc_HpkeContextOpenBase(Hpke* hpke, HpkeBaseContext* context,
|
||||
byte* aad, word32 aadSz, byte* ciphertext, word32 ctSz, byte* out);
|
||||
WOLFSSL_API int wc_HpkeOpenBase(Hpke* hpke, void* receiverKey,
|
||||
const byte* pubKey, word16 pubKeySz, byte* info, word32 infoSz, byte* aad,
|
||||
word32 aadSz, byte* ciphertext, word32 ctSz, byte* plaintext);
|
||||
|
Reference in New Issue
Block a user