add wc_XChaCha_init(), wc_XChaCha20Poly1305_Init(), wc_XChaCha20Poly1305_encrypt_oneshot(), wc_XChaCha20Poly1305_decrypt_oneshot(), and wc_Poly1305_EncodeSizes64(). also, remove redundant arg check (typo) in wc_Poly1305Update().

This commit is contained in:
Daniel Pouzzner
2020-10-01 12:21:38 -05:00
parent e4eda3e125
commit 6142c22948
8 changed files with 524 additions and 3 deletions

View File

@ -314,6 +314,7 @@ then
enable_webserver=yes
enable_hc128=yes
enable_rabbit=yes
enable_xchacha=yes
enable_ocsp=yes
enable_ocspstapling=yes
enable_ocspstapling2=yes
@ -2998,6 +2999,23 @@ then
fi
# XCHACHA
AC_ARG_ENABLE([xchacha],
[AS_HELP_STRING([--enable-xchacha],[Enable XCHACHA (default: disabled).])],
[ ENABLED_XCHACHA=$enableval ],
[ ENABLED_XCHACHA=no]
)
if test "$ENABLED_XCHACHA" = "yes"
then
if test "$ENABLED_CHACHA" = "no"
then
AC_MSG_ERROR([XChaCha (--enable-xchacha) depends on ChaCha (--enable-chacha)])
fi
AM_CFLAGS="$AM_CFLAGS -DHAVE_XCHACHA"
fi
# Hash DRBG
AC_ARG_ENABLE([hashdrbg],
[AS_HELP_STRING([--enable-hashdrbg],[Enable Hash DRBG support (default: enabled)])],
@ -5698,6 +5716,7 @@ AM_CONDITIONAL([BUILD_SHA224],[test "x$ENABLED_SHA224" = "xyes" || test "x$ENABL
AM_CONDITIONAL([BUILD_SHA3],[test "x$ENABLED_SHA3" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_POLY1305],[test "x$ENABLED_POLY1305" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_CHACHA],[test "x$ENABLED_CHACHA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_XCHACHA],[test "x$ENABLED_XCHACHA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_INLINE],[test "x$ENABLED_INLINE" = "xyes"])
AM_CONDITIONAL([BUILD_OCSP],[test "x$ENABLED_OCSP" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_OCSP_STAPLING],[test "x$ENABLED_CERTIFICATE_STATUS_REQUEST" = "xyes"])
@ -5938,6 +5957,7 @@ echo " * SHA-512: $ENABLED_SHA512"
echo " * SHA3: $ENABLED_SHA3"
echo " * SHAKE256: $ENABLED_SHAKE256"
echo " * BLAKE2: $ENABLED_BLAKE2"
echo " * BLAKE2S: $ENABLED_BLAKE2S"
echo " * CMAC: $ENABLED_CMAC"
echo " * keygen: $ENABLED_KEYGEN"
echo " * certgen: $ENABLED_CERTGEN"
@ -5947,6 +5967,7 @@ echo " * certgencache: $ENABLED_certgencache"
echo " * HC-128: $ENABLED_HC128"
echo " * RABBIT: $ENABLED_RABBIT"
echo " * CHACHA: $ENABLED_CHACHA"
echo " * XCHACHA: $ENABLED_XCHACHA"
echo " * Hash DRBG: $ENABLED_HASHDRBG"
echo " * PWDBASED: $ENABLED_PWDBASED"
echo " * scrypt: $ENABLED_SCRYPT"

View File

@ -232,6 +232,72 @@ static WC_INLINE void wc_Chacha_wordtobyte(word32 output[CHACHA_CHUNK_WORDS],
}
}
#ifdef HAVE_XCHACHA
/*
* wc_HChacha_block - half a ChaCha block, for XChaCha
*
* see https://tools.ietf.org/html/draft-arciszewski-xchacha-03
*/
static WC_INLINE void wc_HChacha_block(ChaCha* ctx, word32 stream[CHACHA_CHUNK_WORDS/2], int nrounds) {
word32 x[CHACHA_CHUNK_WORDS];
word32 i;
for (i = 0; i < CHACHA_CHUNK_WORDS; i++) {
x[i] = ctx->X[i];
}
for (i = nrounds; i > 0; i -= 2) {
QUARTERROUND(0, 4, 8, 12)
QUARTERROUND(1, 5, 9, 13)
QUARTERROUND(2, 6, 10, 14)
QUARTERROUND(3, 7, 11, 15)
QUARTERROUND(0, 5, 10, 15)
QUARTERROUND(1, 6, 11, 12)
QUARTERROUND(2, 7, 8, 13)
QUARTERROUND(3, 4, 9, 14)
}
for (i = 0; i < CHACHA_CHUNK_WORDS/4; ++i)
stream[i] = x[i];
for (i = CHACHA_CHUNK_WORDS/4; i < CHACHA_CHUNK_WORDS/2; ++i)
stream[i] = x[i + CHACHA_CHUNK_WORDS/2];
}
/* XChaCha -- https://tools.ietf.org/html/draft-arciszewski-xchacha-03 */
int wc_XChaCha_init(ChaCha *ctx, const byte *key, word32 keySz, const byte *nonce, word32 nonceSz) {
word32 k[CHACHA_MAX_KEY_SZ];
byte iv[CHACHA_IV_BYTES];
int ret;
if (nonceSz < 24)
return BAD_FUNC_ARG;
XMEMSET(iv, 0, 4);
XMEMCPY(iv + 4, nonce + 16, 8);
if ((ret = wc_Chacha_SetKey(ctx, key, keySz)) < 0)
return ret;
if ((ret = wc_Chacha_SetIV(ctx, nonce + 4, U8TO32_LITTLE(nonce))) < 0)
return ret;
wc_HChacha_block(ctx, k, 20);
XMEMCPY(&ctx->X[4], k, 8 * sizeof(word32));
if ((ret = wc_Chacha_SetIV(ctx, iv, 0)) < 0)
return ret;
XMEMSET(k, 0, sizeof k);
XMEMSET(iv, 0, sizeof iv);
return 0;
}
#endif /* HAVE_XCHACHA */
#ifdef __cplusplus
extern "C" {
#endif
@ -301,7 +367,6 @@ static void wc_Chacha_encrypt_bytes(ChaCha* ctx, const byte* m, byte* c,
}
}
/**
* API to encrypt/decrypt a message of any size.
*/
@ -361,6 +426,18 @@ int wc_Chacha_Process(ChaCha* ctx, byte* output, const byte* input,
return 0;
}
void wc_ChaCha_purge_current_block(ChaCha* ctx) {
if (ctx->left > 0) {
#ifndef USE_INTEL_CHACHA_SPEEDUP
/* the algorithms in chacha_asm.S increment the counter for partial
* blocks, but wc_Chacha_encrypt_bytes() defers.
*/
ctx->X[CHACHA_MATRIX_CNT_IV] = PLUSONE(ctx->X[CHACHA_MATRIX_CNT_IV]);
#endif
ctx->left = 0;
}
}
#endif /* HAVE_CHACHA*/
#endif /* WOLFSSL_ARMASM */

View File

@ -293,4 +293,158 @@ int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead,
return ret;
}
#ifdef HAVE_XCHACHA
int wc_XChaCha20Poly1305_Init(
ChaChaPoly_Aead *aead,
const byte *ad, word32 ad_len,
const byte *nonce, word32 nonce_len,
const byte *key, word32 key_len,
int isEncrypt)
{
byte authKey[CHACHA20_POLY1305_AEAD_KEYSIZE];
int ret;
if ((ad == NULL) || (nonce == NULL) || (key == NULL))
return BAD_FUNC_ARG;
if ((key_len != CHACHA20_POLY1305_AEAD_KEYSIZE) ||
(nonce_len != XCHACHA20_POLY1305_AEAD_NONCE_SIZE))
return BAD_FUNC_ARG;
if ((ret = wc_XChaCha_init(&aead->chacha, key, key_len, nonce, nonce_len)) < 0)
return ret;
XMEMSET(authKey, 0, sizeof authKey);
/* Create the Poly1305 key */
if ((ret = wc_Chacha_Process(&aead->chacha, authKey, authKey,
(word32)sizeof authKey)) < 0)
return ret;
/* advance to start of the next ChaCha block. */
wc_ChaCha_purge_current_block(&aead->chacha);
/* Initialize Poly1305 context */
if ((ret = wc_Poly1305SetKey(&aead->poly, authKey,
(word32)sizeof authKey)) < 0)
return ret;
if ((ret = wc_Poly1305Update(&aead->poly, ad, (word32)ad_len)) < 0)
return ret;
if ((ret = wc_Poly1305_Pad(&aead->poly, (word32)ad_len)) < 0)
return ret;
aead->isEncrypt = (byte)isEncrypt;
aead->state = CHACHA20_POLY1305_STATE_AAD;
return 0;
}
static WC_INLINE int wc_XChaCha20Poly1305_crypt_oneshot(
byte *dst, const size_t dst_space,
const byte *src, const size_t src_len,
const byte *ad, const size_t ad_len,
const byte *nonce, const size_t nonce_len,
const byte *key, const size_t key_len,
int isEncrypt)
{
ChaChaPoly_Aead aead;
int ret;
ssize_t dst_len = isEncrypt ?
(ssize_t)src_len + POLY1305_DIGEST_SIZE :
(ssize_t)src_len - POLY1305_DIGEST_SIZE;
const byte *src_i;
byte *dst_i;
size_t src_len_rem;
if ((dst == NULL) || (src == NULL))
return BAD_FUNC_ARG;
if ((ssize_t)dst_space < dst_len)
return BUFFER_E;
if ((ret = wc_XChaCha20Poly1305_Init(&aead, ad, (word32)ad_len,
nonce, (word32)nonce_len,
key, (word32)key_len, 1)) < 0)
goto out;
/* process the input in 16k pieces to accommodate src_lens that don't fit in a word32,
* and to exploit hot cache for the input data.
*/
for (src_i = src, src_len_rem = isEncrypt ? src_len : (size_t)dst_len, dst_i = dst;
src_len_rem > 0;
) {
word32 this_src_len =
(src_len_rem > 16384) ?
16384 :
(word32)src_len_rem;
if ((ret = wc_Chacha_Process(&aead.chacha, dst_i, src_i, this_src_len)) < 0)
goto out;
if ((ret = wc_Poly1305Update(&aead.poly, isEncrypt ? dst_i : src_i, this_src_len)) < 0)
goto out;
src_len_rem -= (size_t)this_src_len;
src_i += this_src_len;
dst_i += this_src_len;
}
if (aead.poly.leftover) {
if ((ret = wc_Poly1305_Pad(&aead.poly, (word32)aead.poly.leftover)) < 0)
return ret;
}
#ifdef WORD64_AVAILABLE
ret = wc_Poly1305_EncodeSizes64(&aead.poly, ad_len, isEncrypt ? src_len : (size_t)dst_len);
#else
ret = wc_Poly1305_EncodeSizes(&aead.poly, ad_len, isEncrypt ? src_len : (size_t)dst_len);
#endif
if (ret < 0)
goto out;
if (isEncrypt)
ret = wc_Poly1305Final(&aead.poly, dst + src_len);
else {
byte outAuthTag[POLY1305_DIGEST_SIZE];
if ((ret = wc_Poly1305Final(&aead.poly, outAuthTag)) < 0)
goto out;
if (ConstantCompare(outAuthTag, src + dst_len, POLY1305_DIGEST_SIZE) != 0) {
ret = MAC_CMP_FAILED_E;
goto out;
}
}
out:
XMEMSET(&aead, 0, sizeof aead);
return ret;
}
int wc_XChaCha20Poly1305_encrypt_oneshot(
byte *dst, const size_t dst_space,
const byte *src, const size_t src_len,
const byte *ad, const size_t ad_len,
const byte *nonce, const size_t nonce_len,
const byte *key, const size_t key_len)
{
return wc_XChaCha20Poly1305_crypt_oneshot(dst, dst_space, src, src_len, ad, ad_len, nonce, nonce_len, key, key_len, 1);
}
int wc_XChaCha20Poly1305_decrypt_oneshot(
byte *dst, const size_t dst_space,
const byte *src, const size_t src_len,
const byte *ad, const size_t ad_len,
const byte *nonce, const size_t nonce_len,
const byte *key, const size_t key_len)
{
return wc_XChaCha20Poly1305_crypt_oneshot(dst, dst_space, src, src_len, ad, ad_len, nonce, nonce_len, key, key_len, 0);
}
#endif /* HAVE_XCHACHA */
#endif /* HAVE_CHACHA && HAVE_POLY1305 */

View File

@ -700,8 +700,6 @@ int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes)
}
printf("\n");
#endif
if (ctx == NULL || (m == NULL && bytes > 0))
return BAD_FUNC_ARG;
#ifdef USE_INTEL_SPEEDUP
#ifdef HAVE_INTEL_AVX2
@ -837,6 +835,30 @@ int wc_Poly1305_EncodeSizes(Poly1305* ctx, word32 aadSz, word32 dataSz)
return ret;
}
#ifdef WORD64_AVAILABLE
int wc_Poly1305_EncodeSizes64(Poly1305* ctx, word64 aadSz, word64 dataSz)
{
int ret;
word64 little64[2];
if (ctx == NULL) {
return BAD_FUNC_ARG;
}
#ifdef BIG_ENDIAN_ORDER
little64[0] = ByteReverseWord64(aadSz);
little64[1] = ByteReverseWord64(dataSz);
#else
little64[0] = aadSz;
little64[1] = dataSz;
#endif
ret = wc_Poly1305Update(ctx, (byte *)little64, sizeof(little64));
return ret;
}
#endif
/* Takes in an initialized Poly1305 struct that has a key loaded and creates
a MAC (tag) using recent TLS AEAD padding scheme.
ctx : Initialized Poly1305 struct to use

View File

@ -311,7 +311,9 @@ static int arc4_test(void);
static int hc128_test(void);
static int rabbit_test(void);
static int chacha_test(void);
static int XChaCha_test(void);
static int chacha20_poly1305_aead_test(void);
static int XChaCha20Poly1305_test(void);
static int des_test(void);
static int des3_test(void);
static int aes_test(void);
@ -857,6 +859,13 @@ initDefaultName();
test_pass("Chacha test passed!\n");
#endif
#ifdef HAVE_XCHACHA
if ( (ret = XChaCha_test()) != 0)
return err_sys("XChacha test failed!\n", ret);
else
test_pass("XChacha test passed!\n");
#endif
#ifdef HAVE_POLY1305
if ( (ret = poly1305_test()) != 0)
return err_sys("POLY1305 test failed!\n", ret);
@ -871,6 +880,13 @@ initDefaultName();
test_pass("ChaCha20-Poly1305 AEAD test passed!\n");
#endif
#if defined(HAVE_XCHACHA) && defined(HAVE_POLY1305)
if ( (ret = XChaCha20Poly1305_test()) != 0)
return err_sys("XChaCha20-Poly1305 AEAD test failed!\n", ret);
else
test_pass("XChaCha20-Poly1305 AEAD test passed!\n");
#endif
#ifndef NO_DES3
if ( (ret = des_test()) != 0)
return err_sys("DES test failed!\n", ret);
@ -10024,6 +10040,201 @@ static int idea_test(void)
}
#endif /* HAVE_IDEA */
#ifdef HAVE_XCHACHA
static int XChaCha_test(void) {
int ret = -1;
static const byte Plaintext[] = {
0x54, 0x68, 0x65, 0x20, 0x64, 0x68, 0x6f, 0x6c, 0x65, 0x20, 0x28, 0x70, 0x72, 0x6f, 0x6e, 0x6f, /* The dhole (prono */
0x75, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x22, 0x64, 0x6f, 0x6c, 0x65, 0x22, 0x29, 0x20, 0x69, 0x73, /* unced "dole") is */
0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x74, /* also known as t */
0x68, 0x65, 0x20, 0x41, 0x73, 0x69, 0x61, 0x74, 0x69, 0x63, 0x20, 0x77, 0x69, 0x6c, 0x64, 0x20, /* he Asiatic wild */
0x64, 0x6f, 0x67, 0x2c, 0x20, 0x72, 0x65, 0x64, 0x20, 0x64, 0x6f, 0x67, 0x2c, 0x20, 0x61, 0x6e, /* dog, red dog, an */
0x64, 0x20, 0x77, 0x68, 0x69, 0x73, 0x74, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x67, 0x2e, /* d whistling dog. */
0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, /* It is about the */
0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x47, 0x65, 0x72, 0x6d, 0x61, /* size of a Germa */
0x6e, 0x20, 0x73, 0x68, 0x65, 0x70, 0x68, 0x65, 0x72, 0x64, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6c, /* n shepherd but l */
0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x61, /* ooks more like a */
0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x67, 0x67, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x78, /* long-legged fox */
0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x20, 0x65, 0x6c, /* . This highly el */
0x75, 0x73, 0x69, 0x76, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65, /* usive and skille */
0x64, 0x20, 0x6a, 0x75, 0x6d, 0x70, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6c, 0x61, 0x73, /* d jumper is clas */
0x73, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x77, 0x6f, 0x6c, 0x76, /* sified with wolv */
0x65, 0x73, 0x2c, 0x20, 0x63, 0x6f, 0x79, 0x6f, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x6a, 0x61, 0x63, /* es, coyotes, jac */
0x6b, 0x61, 0x6c, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x78, 0x65, 0x73, 0x20, /* kals, and foxes */
0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x61, 0x78, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63, /* in the taxonomic */
0x20, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x20, 0x43, 0x61, 0x6e, 0x69, 0x64, 0x61, 0x65, 0x2e /* family Canidae. */
};
static const byte Key[] = {
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
};
static const byte IV[] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* @ABCDEFGHIJKLMNO */
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x58 }; /* PQRSTUVW */
static const byte Ciphertext[] = {
0x45, 0x59, 0xab, 0xba, 0x4e, 0x48, 0xc1, 0x61, 0x02, 0xe8, 0xbb, 0x2c, 0x05, 0xe6, 0x94, 0x7f,
0x50, 0xa7, 0x86, 0xde, 0x16, 0x2f, 0x9b, 0x0b, 0x7e, 0x59, 0x2a, 0x9b, 0x53, 0xd0, 0xd4, 0xe9,
0x8d, 0x8d, 0x64, 0x10, 0xd5, 0x40, 0xa1, 0xa6, 0x37, 0x5b, 0x26, 0xd8, 0x0d, 0xac, 0xe4, 0xfa,
0xb5, 0x23, 0x84, 0xc7, 0x31, 0xac, 0xbf, 0x16, 0xa5, 0x92, 0x3c, 0x0c, 0x48, 0xd3, 0x57, 0x5d,
0x4d, 0x0d, 0x2c, 0x67, 0x3b, 0x66, 0x6f, 0xaa, 0x73, 0x10, 0x61, 0x27, 0x77, 0x01, 0x09, 0x3a,
0x6b, 0xf7, 0xa1, 0x58, 0xa8, 0x86, 0x42, 0x92, 0xa4, 0x1c, 0x48, 0xe3, 0xa9, 0xb4, 0xc0, 0xda,
0xec, 0xe0, 0xf8, 0xd9, 0x8d, 0x0d, 0x7e, 0x05, 0xb3, 0x7a, 0x30, 0x7b, 0xbb, 0x66, 0x33, 0x31,
0x64, 0xec, 0x9e, 0x1b, 0x24, 0xea, 0x0d, 0x6c, 0x3f, 0xfd, 0xdc, 0xec, 0x4f, 0x68, 0xe7, 0x44,
0x30, 0x56, 0x19, 0x3a, 0x03, 0xc8, 0x10, 0xe1, 0x13, 0x44, 0xca, 0x06, 0xd8, 0xed, 0x8a, 0x2b,
0xfb, 0x1e, 0x8d, 0x48, 0xcf, 0xa6, 0xbc, 0x0e, 0xb4, 0xe2, 0x46, 0x4b, 0x74, 0x81, 0x42, 0x40,
0x7c, 0x9f, 0x43, 0x1a, 0xee, 0x76, 0x99, 0x60, 0xe1, 0x5b, 0xa8, 0xb9, 0x68, 0x90, 0x46, 0x6e,
0xf2, 0x45, 0x75, 0x99, 0x85, 0x23, 0x85, 0xc6, 0x61, 0xf7, 0x52, 0xce, 0x20, 0xf9, 0xda, 0x0c,
0x09, 0xab, 0x6b, 0x19, 0xdf, 0x74, 0xe7, 0x6a, 0x95, 0x96, 0x74, 0x46, 0xf8, 0xd0, 0xfd, 0x41,
0x5e, 0x7b, 0xee, 0x2a, 0x12, 0xa1, 0x14, 0xc2, 0x0e, 0xb5, 0x29, 0x2a, 0xe7, 0xa3, 0x49, 0xae,
0x57, 0x78, 0x20, 0xd5, 0x52, 0x0a, 0x1f, 0x3f, 0xb6, 0x2a, 0x17, 0xce, 0x6a, 0x7e, 0x68, 0xfa,
0x7c, 0x79, 0x11, 0x1d, 0x88, 0x60, 0x92, 0x0b, 0xc0, 0x48, 0xef, 0x43, 0xfe, 0x84, 0x48, 0x6c,
0xcb, 0x87, 0xc2, 0x5f, 0x0a, 0xe0, 0x45, 0xf0, 0xcc, 0xe1, 0xe7, 0x98, 0x9a, 0x9a, 0xa2, 0x20,
0xa2, 0x8b, 0xdd, 0x48, 0x27, 0xe7, 0x51, 0xa2, 0x4a, 0x6d, 0x5c, 0x62, 0xd7, 0x90, 0xa6, 0x63,
0x93, 0xb9, 0x31, 0x11, 0xc1, 0xa5, 0x5d, 0xd7, 0x42, 0x1a, 0x10, 0x18, 0x49, 0x74, 0xc7, 0xc5
};
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
struct ChaCha *chacha = (struct ChaCha *)XMALLOC(sizeof *chacha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
byte *buf1 = (byte *)XMALLOC(sizeof Plaintext, NULL, DYNAMIC_TYPE_TMP_BUFFER);
byte *buf2 = (byte *)XMALLOC(sizeof Plaintext, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if ((chacha == NULL) || (buf1 == NULL) || (buf2 == NULL))
ERROR_OUT(MEMORY_E, out);
#else
struct ChaCha chacha_buf, *chacha = &chacha_buf;
byte buf1[sizeof Plaintext];
byte buf2[sizeof Plaintext];
#endif
ret = wc_XChaCha_init(chacha, Key, sizeof Key, IV, sizeof IV);
if (ret < 0)
ERROR_OUT(-4770, out);
ret = wc_Chacha_Process(chacha, buf1, Plaintext, sizeof Plaintext);
if (ret < 0)
ERROR_OUT(-4771, out);
if (XMEMCMP(buf1, Ciphertext, sizeof Plaintext))
ERROR_OUT(-4772, out);
ret = wc_XChaCha_init(chacha, Key, sizeof Key, IV, sizeof IV);
if (ret < 0)
ERROR_OUT(-4773, out);
ret = wc_Chacha_Process(chacha, buf2, buf1, sizeof Plaintext);
if (ret < 0)
ERROR_OUT(-4774, out);
if (XMEMCMP(buf2, Plaintext, sizeof Plaintext))
ERROR_OUT(-4775, out);
out:
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
if (chacha)
XFREE(chacha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (buf1)
XFREE(buf1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (buf2)
XFREE(buf2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
#endif /* HAVE_XCHACHA */
#if defined(HAVE_XCHACHA) && defined(HAVE_POLY1305)
static int XChaCha20Poly1305_test(void) {
int ret;
static const byte Plaintext[] = {
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, /* Ladies and Gentl */
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, /* emen of the clas */
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, /* s of '99: If I c */
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, /* ould offer you o */
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, /* nly one tip for */
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, /* the future, suns */
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, /* creen would be i */
0x74, 0x2e }; /* t. */
static const byte AAD[] = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 }; /* PQRS........ */
static const byte Key[] = {
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
};
static const byte IV[] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* @ABCDEFGHIJKLMNO */
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 }; /* PQRSTUVW */
static const byte Ciphertext[] = {
0xbd, 0x6d, 0x17, 0x9d, 0x3e, 0x83, 0xd4, 0x3b, 0x95, 0x76, 0x57, 0x94, 0x93, 0xc0, 0xe9, 0x39,
0x57, 0x2a, 0x17, 0x00, 0x25, 0x2b, 0xfa, 0xcc, 0xbe, 0xd2, 0x90, 0x2c, 0x21, 0x39, 0x6c, 0xbb,
0x73, 0x1c, 0x7f, 0x1b, 0x0b, 0x4a, 0xa6, 0x44, 0x0b, 0xf3, 0xa8, 0x2f, 0x4e, 0xda, 0x7e, 0x39,
0xae, 0x64, 0xc6, 0x70, 0x8c, 0x54, 0xc2, 0x16, 0xcb, 0x96, 0xb7, 0x2e, 0x12, 0x13, 0xb4, 0x52,
0x2f, 0x8c, 0x9b, 0xa4, 0x0d, 0xb5, 0xd9, 0x45, 0xb1, 0x1b, 0x69, 0xb9, 0x82, 0xc1, 0xbb, 0x9e,
0x3f, 0x3f, 0xac, 0x2b, 0xc3, 0x69, 0x48, 0x8f, 0x76, 0xb2, 0x38, 0x35, 0x65, 0xd3, 0xff, 0xf9,
0x21, 0xf9, 0x66, 0x4c, 0x97, 0x63, 0x7d, 0xa9, 0x76, 0x88, 0x12, 0xf6, 0x15, 0xc6, 0x8b, 0x13,
0xb5, 0x2e };
static const byte Tag[] = {
0xc0, 0x87, 0x59, 0x24, 0xc1, 0xc7, 0x98, 0x79, 0x47, 0xde, 0xaf, 0xd8, 0x78, 0x0a, 0xcf, 0x49
};
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
byte *buf1 = (byte *)XMALLOC(sizeof Ciphertext + sizeof Tag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
byte *buf2 = (byte *)XMALLOC(sizeof Plaintext, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#else
byte buf1[sizeof Ciphertext + sizeof Tag];
byte buf2[sizeof Plaintext];
#endif
ret = wc_XChaCha20Poly1305_encrypt_oneshot(buf1, sizeof Ciphertext + sizeof Tag,
Plaintext, sizeof Plaintext,
AAD, sizeof AAD,
IV, sizeof IV,
Key, sizeof Key);
if (ret < 0) {
printf("wc_XChaCha20Poly1305_encrypt_oneshot failed: %s\n",wc_GetErrorString(ret));
ERROR_OUT(-4760, out);
}
if (XMEMCMP(buf1, Ciphertext, sizeof Plaintext))
ERROR_OUT(-4761, out);
if (XMEMCMP(buf1 + sizeof Plaintext, Tag, CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE))
ERROR_OUT(-4762, out);
ret = wc_XChaCha20Poly1305_decrypt_oneshot(buf2, sizeof Plaintext,
buf1, sizeof Plaintext + sizeof Tag,
AAD, sizeof AAD,
IV, sizeof IV,
Key, sizeof Key);
if (ret < 0) {
printf("wc_XChaCha20Poly1305_decrypt_oneshot failed: %s\n",wc_GetErrorString(ret));
ERROR_OUT(-4763, out);
}
if (XMEMCMP(buf2, Plaintext, sizeof Plaintext))
ERROR_OUT(-4764, out);
out:
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
XFREE(buf1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(buf2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
#endif /* defined(HAVE_XCHACHA) && defined(HAVE_POLY1305) */
#ifndef WC_NO_RNG
static int _rng_test(WC_RNG* rng, int errorOffset)

View File

@ -92,8 +92,16 @@ WOLFSSL_API int wc_Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter);
WOLFSSL_API int wc_Chacha_Process(ChaCha* ctx, byte* cipher, const byte* plain,
word32 msglen);
WOLFSSL_LOCAL void wc_ChaCha_purge_current_block(ChaCha* ctx);
WOLFSSL_API int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz);
#ifdef HAVE_XCHACHA
WOLFSSL_API int wc_XChaCha_init(ChaCha *ctx, const byte *key, word32 keySz,
const byte *nonce, word32 nonceSz);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -48,6 +48,7 @@ or Authenticated Encryption with Additional Data (AEAD) algorithm.
#define CHACHA20_POLY1305_AEAD_IV_SIZE 12
#define CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE 16
#define CHACHA20_POLY1305_MAX 4294967295U
#define XCHACHA20_POLY1305_AEAD_NONCE_SIZE 24
enum {
CHACHA20_POLY_1305_ENC_TYPE = 8, /* cipher unique type */
@ -123,6 +124,30 @@ WOLFSSL_API int wc_ChaCha20Poly1305_UpdateData(ChaChaPoly_Aead* aead,
WOLFSSL_API int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead,
byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);
#ifdef HAVE_XCHACHA
WOLFSSL_API int wc_XChaCha20Poly1305_Init(
ChaChaPoly_Aead* aead,
const byte *ad, word32 ad_len,
const byte *inKey, word32 inKeySz,
const byte *inIV, word32 inIVSz,
int isEncrypt);
WOLFSSL_API int wc_XChaCha20Poly1305_encrypt_oneshot(
byte *dst, const size_t dst_space,
const byte *src, const size_t src_len,
const byte *ad, const size_t ad_len,
const byte *nonce, const size_t nonce_len,
const byte *key, const size_t key_len);
WOLFSSL_API int wc_XChaCha20Poly1305_decrypt_oneshot(
byte *dst, const size_t dst_space,
const byte *src, const size_t src_len,
const byte *ad, const size_t ad_len,
const byte *nonce, const size_t nonce_len,
const byte *key, const size_t key_len);
#endif /* HAVE_XCHACHA */
#ifdef __cplusplus
} /* extern "C" */

View File

@ -116,6 +116,9 @@ WOLFSSL_API int wc_Poly1305Final(Poly1305* poly1305, byte* tag);
/* AEAD Functions */
WOLFSSL_API int wc_Poly1305_Pad(Poly1305* ctx, word32 lenToPad);
WOLFSSL_API int wc_Poly1305_EncodeSizes(Poly1305* ctx, word32 aadSz, word32 dataSz);
#ifdef WORD64_AVAILABLE
WOLFSSL_API int wc_Poly1305_EncodeSizes64(Poly1305* ctx, word64 aadSz, word64 dataSz);
#endif
WOLFSSL_API int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz,
byte* input, word32 sz, byte* tag, word32 tagSz);