diff --git a/aead.c b/aead.c index bd9e828..7597bf6 100644 --- a/aead.c +++ b/aead.c @@ -20,18 +20,16 @@ int lc_aead_seal(const struct lc_aead_impl *impl, uint8_t *out, size_t *outlen, - const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen) + const void *argparams, const uint8_t *aad, size_t aadlen, + const uint8_t *in, size_t inlen) { - return impl->seal(out, outlen, key, keylen, iv, ivlen, aad, aadlen, in, - inlen); + return impl->seal(out, outlen, argparams, aad, aadlen, in, inlen); } int lc_aead_open(const struct lc_aead_impl *impl, uint8_t *out, size_t *outlen, - const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen) + const void *argparams, const uint8_t *aad, size_t aadlen, + const uint8_t *in, size_t inlen) { - return impl->open(out, outlen, key, keylen, iv, ivlen, aad, aadlen, in, - inlen); + return impl->open(out, outlen, argparams, aad, aadlen, in, inlen); } diff --git a/aead.h b/aead.h index e9fffcb..a0eea5a 100644 --- a/aead.h +++ b/aead.h @@ -19,10 +19,8 @@ struct lc_aead_impl { - int (*seal)(uint8_t *, size_t *, const uint8_t *, size_t, - const uint8_t *, size_t, const uint8_t *, size_t, - const uint8_t *, size_t); - int (*open)(uint8_t *, size_t *, const uint8_t *, size_t, - const uint8_t *, size_t, const uint8_t *, size_t, - const uint8_t *, size_t); + int (*seal)(uint8_t *, size_t *, const void *, const uint8_t *, + size_t, const uint8_t *, size_t); + int (*open)(uint8_t *, size_t *, const void *, const uint8_t *, + size_t, const uint8_t *, size_t); }; diff --git a/aead_chacha20_poly1305.c b/aead_chacha20_poly1305.c index 9367c3c..22e3e66 100644 --- a/aead_chacha20_poly1305.c +++ b/aead_chacha20_poly1305.c @@ -16,10 +16,7 @@ #include "lilcrypto.h" #include "aead.h" -#include "auth_poly1305.h" -#include "cipher_chacha20.h" #include "impl_chacha20.h" -#include "impl_poly1305.h" #include "util.h" @@ -31,99 +28,230 @@ static const uint8_t zeropad[16]; +static int +aead_poly1305_keysetup(struct lc_cipher_ctx *cctx, + uint8_t akey[LC_POLY1305_KEYLEN], const void *initparams) +{ + size_t i, olen, akeylen; + + for (i = 0; i < LC_POLY1305_KEYLEN; i++) + akey[i] = 0; + if (!lc_cipher_encrypt_init(cctx, initparams) || + !lc_cipher_encrypt_update(cctx, akey, &olen, akey, + LC_POLY1305_KEYLEN)) + return 0; + akeylen = olen; + if (!lc_cipher_encrypt_final(cctx, akey + olen, &olen)) + return 0; + akeylen += olen; + + return akeylen == LC_POLY1305_KEYLEN; +} static int -chacha20_poly1305_seal(uint8_t *out, size_t *outlen, const uint8_t *key, - size_t keylen, const uint8_t *iv, size_t ivlen, const uint8_t *aad, - size_t aadlen, const uint8_t *in, size_t inlen) +aead_poly1305_anycrypt(struct lc_cipher_ctx *cctx, uint8_t *out, + size_t *outlen, const void *initparams, const uint8_t *in, size_t inlen) { - struct chacha20_ctx cctx; - struct poly1305_ctx pctx; - uint8_t poly1305_key[LC_POLY1305_KEYLEN]; - uint8_t buf[sizeof(uint64_t) * 2]; - size_t i, olen; + size_t olen; - if (inlen > UINT64_MAX || aadlen > UINT64_MAX || - inlen > SIZE_MAX - LC_POLY1305_TAGLEN || - inlen > SIZE_MAX - CHACHA20_CHUNK + 1 || - (inlen + CHACHA20_CHUNK - 1) / CHACHA20_CHUNK > - CHACHA20_CTRMAX - 1) { - if (out == NULL) - *outlen = 0; + if (!lc_cipher_encrypt_init(cctx, initparams) || + !lc_cipher_encrypt_update(cctx, out, &olen, in, inlen)) + return 0; + *outlen = olen; + if (!lc_cipher_encrypt_final(cctx, out + olen, &olen)) + return 0; + *outlen += olen; + + return *outlen == inlen; +} + +static int +chacha20_poly1305_seal(uint8_t *out, size_t *outlen, const void *initparams, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen) +{ + const struct lc_chacha20_poly1305_params *params = initparams; + struct lc_cipher_ctx *cctx = NULL; + struct lc_auth_ctx *actx = NULL; + struct lc_chacha20_params cparams; + struct lc_poly1305_params aparams; + uint8_t buf[sizeof(uint64_t) * 2]; + size_t i, olen; + int ret = 0; + + *outlen = 0; + /* inlen and aadlen are capped by design; enough space of tag. */ + if (inlen > UINT64_MAX || aadlen > UINT64_MAX || + inlen > SIZE_MAX - LC_POLY1305_TAGLEN) + return 0; + /* Counter 0 is used for deriving Poly1305 key. */ + if (inlen > SIZE_MAX - (CHACHA20_CHUNK - 1) || + (inlen + CHACHA20_CHUNK - 1) / CHACHA20_CHUNK > + CHACHA20_CTRMAX - 1) return 0; - } if (out == NULL) { *outlen = inlen + LC_POLY1305_TAGLEN; return 1; } - *outlen = 0; + cctx = lc_cipher_ctx_new(lc_cipher_impl_chacha20()); + if (cctx == NULL) + goto cleanup; + actx = lc_auth_ctx_new(lc_auth_impl_poly1305()); + if (actx == NULL) + goto cleanup; - for (i = 0; i < LC_POLY1305_KEYLEN; i++) - poly1305_key[i] = 0; - if (!chacha20_common_init(&cctx, key, keylen, iv, ivlen) || - !chacha20_common_update(&cctx, poly1305_key, &olen, poly1305_key, - LC_POLY1305_KEYLEN)) - return 0; - if (!chacha20_common_final(&cctx, poly1305_key + olen, &olen)) - return 0; + for (i = 0; i < sizeof(params->key); i++) + cparams.key[i] = params->key[i]; + for (i = 0; i < sizeof(params->nonce); i++) + cparams.nonce[i] = params->nonce[i]; - if (!poly1305_init(&pctx, poly1305_key, LC_POLY1305_KEYLEN) || - !poly1305_update(&pctx, aad, aadlen)) - return 0; + cparams.counter = 0; + if (!aead_poly1305_keysetup(cctx, aparams.key, &cparams)) + goto cleanup; + + if (!lc_auth_init(actx, &aparams) || + !lc_auth_update(actx, aad, aadlen)) + goto cleanup; if (aadlen % 16 != 0) - if (!poly1305_update(&pctx, zeropad, 16 - (aadlen % 16))) - return 0; + if (!lc_auth_update(actx, zeropad, 16 - (aadlen % 16))) + goto cleanup; - if (!chacha20_common_init_from(&cctx, key, keylen, iv, ivlen, 1)) - return 0; - if (!chacha20_common_update(&cctx, out, &olen, in, inlen)) - return 0; - *outlen = olen; - if (!chacha20_common_final(&cctx, out + olen, &olen)) - return 0; - if (!poly1305_update(&pctx, out, inlen)) - return 0; + cparams.counter = 1; + if (!aead_poly1305_anycrypt(cctx, out, outlen, &cparams, in, inlen)) + goto cleanup; + + if (!lc_auth_update(actx, out, inlen)) + goto cleanup; if (inlen % 16 != 0) - if (!poly1305_update(&pctx, zeropad, 16 - (inlen % 16))) - return 0; + if (!lc_auth_update(actx, zeropad, 16 - (inlen % 16))) + goto cleanup; store64le(&buf[0], aadlen); store64le(&buf[sizeof(uint64_t)], inlen); - if (!poly1305_update(&pctx, buf, sizeof(buf)) || - !poly1305_final(&pctx, out + inlen, &olen)) - return 0; + if (!lc_auth_update(actx, buf, sizeof(buf)) || + !lc_auth_final(actx, out + inlen, &olen)) + goto cleanup; + *outlen += olen; + if (*outlen != inlen + LC_POLY1305_TAGLEN) + goto cleanup; + ret = 1; + cleanup: lc_scrub(buf, sizeof(buf)); - lc_scrub(poly1305_key, sizeof(poly1305_key)); + lc_scrub(&aparams, sizeof(aparams)); + lc_scrub(&cparams, sizeof(cparams)); + lc_auth_ctx_free(actx); + lc_cipher_ctx_free(cctx); - *outlen = inlen + LC_POLY1305_TAGLEN; - - return 1; + return ret; } static int -chacha20_poly1305_open(uint8_t *out, size_t *outlen, const uint8_t *key, - size_t keylen, const uint8_t *iv, size_t ivlen, const uint8_t *aad, - size_t aadlen, const uint8_t *in, size_t inlen) +xchacha20_poly1305_seal(uint8_t *out, size_t *outlen, const void *initparams, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen) { - const uint8_t *tagp; - struct chacha20_ctx cctx; - struct poly1305_ctx pctx; - uint8_t poly1305_key[LC_POLY1305_KEYLEN]; - uint8_t tag[LC_POLY1305_TAGLEN]; - uint8_t buf[sizeof(uint64_t) * 2]; - size_t i, olen, ctlen; + const struct lc_xchacha20_poly1305_params *params = initparams; + struct lc_cipher_ctx *cctx = NULL; + struct lc_auth_ctx *actx = NULL; + struct lc_xchacha20_params cparams; + struct lc_poly1305_params aparams; + uint8_t buf[sizeof(uint64_t) * 2]; + size_t i, olen; + int ret = 0; + *outlen = 0; + /* inlen and aadlen are capped by design; enough space of tag. */ + if (inlen > UINT64_MAX || aadlen > UINT64_MAX || + inlen > SIZE_MAX - LC_POLY1305_TAGLEN) + return 0; + /* Counter 0 is used for deriving Poly1305 key. */ + if (inlen > SIZE_MAX - (CHACHA20_CHUNK - 1) || + (inlen + CHACHA20_CHUNK - 1) / CHACHA20_CHUNK > + CHACHA20_CTRMAX - 1) + return 0; + + if (out == NULL) { + *outlen = inlen + LC_POLY1305_TAGLEN; + return 1; + } + + cctx = lc_cipher_ctx_new(lc_cipher_impl_xchacha20()); + if (cctx == NULL) + goto cleanup; + actx = lc_auth_ctx_new(lc_auth_impl_poly1305()); + if (actx == NULL) + goto cleanup; + + for (i = 0; i < sizeof(params->key); i++) + cparams.key[i] = params->key[i]; + for (i = 0; i < sizeof(params->nonce); i++) + cparams.nonce[i] = params->nonce[i]; + + cparams.counter = 0; + if (!aead_poly1305_keysetup(cctx, aparams.key, &cparams)) + goto cleanup; + + if (!lc_auth_init(actx, &aparams) || + !lc_auth_update(actx, aad, aadlen)) + goto cleanup; + if (aadlen % 16 != 0) + if (!lc_auth_update(actx, zeropad, 16 - (aadlen % 16))) + goto cleanup; + + cparams.counter = 1; + if (!aead_poly1305_anycrypt(cctx, out, outlen, &cparams, in, inlen)) + goto cleanup; + + if (!lc_auth_update(actx, out, inlen)) + goto cleanup; + if (inlen % 16 != 0) + if (!lc_auth_update(actx, zeropad, 16 - (inlen % 16))) + goto cleanup; + + store64le(&buf[0], aadlen); + store64le(&buf[sizeof(uint64_t)], inlen); + if (!lc_auth_update(actx, buf, sizeof(buf)) || + !lc_auth_final(actx, out + inlen, &olen)) + goto cleanup; + *outlen += olen; + if (*outlen != inlen + LC_POLY1305_TAGLEN) + goto cleanup; + ret = 1; + + cleanup: + lc_scrub(buf, sizeof(buf)); + lc_scrub(&aparams, sizeof(aparams)); + lc_scrub(&cparams, sizeof(cparams)); + lc_auth_ctx_free(actx); + lc_cipher_ctx_free(cctx); + + return ret; +} + +static int +chacha20_poly1305_open(uint8_t *out, size_t *outlen, const void *initparams, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen) +{ + const struct lc_chacha20_poly1305_params *params = initparams; + struct lc_cipher_ctx *cctx = NULL; + struct lc_auth_ctx *actx = NULL; + struct lc_chacha20_params cparams; + struct lc_poly1305_params aparams; + uint8_t tag[LC_POLY1305_TAGLEN]; + uint8_t buf[sizeof(uint64_t) * 2]; + size_t i, olen, ctlen; + int ret = 0; + + *outlen = 0; + /* inlen includes the tag; inlen and aadlen are capped by design. */ if (inlen < LC_POLY1305_TAGLEN || - inlen > UINT64_MAX || aadlen > UINT64_MAX || - inlen > SIZE_MAX - LC_POLY1305_TAGLEN || - inlen > SIZE_MAX - CHACHA20_CHUNK + 1 || + inlen > UINT64_MAX || aadlen > UINT64_MAX) + return 0; + /* Counter 0 is used for deriving Poly1305 key. */ + if (inlen > SIZE_MAX - (CHACHA20_CHUNK - 1) || (inlen + CHACHA20_CHUNK - 1) / CHACHA20_CHUNK > CHACHA20_CTRMAX - 1) { - if (out == NULL) - *outlen = 0; return 0; } @@ -132,148 +260,85 @@ chacha20_poly1305_open(uint8_t *out, size_t *outlen, const uint8_t *key, return 1; } - *outlen = 0; - ctlen = inlen - LC_POLY1305_TAGLEN; - tagp = in + ctlen; + cctx = lc_cipher_ctx_new(lc_cipher_impl_chacha20()); + if (cctx == NULL) + goto cleanup; + actx = lc_auth_ctx_new(lc_auth_impl_poly1305()); + if (actx == NULL) + goto cleanup; - for (i = 0; i < LC_POLY1305_KEYLEN; i++) - poly1305_key[i] = 0; - if (!chacha20_common_init(&cctx, key, keylen, iv, ivlen) || - !chacha20_common_update(&cctx, poly1305_key, &olen, poly1305_key, - LC_POLY1305_KEYLEN)) - return 0; - if (!chacha20_common_final(&cctx, poly1305_key + olen, &olen)) - return 0; + for (i = 0; i < sizeof(params->key); i++) + cparams.key[i] = params->key[i]; + for (i = 0; i < sizeof(params->nonce); i++) + cparams.nonce[i] = params->nonce[i]; - if (!poly1305_init(&pctx, poly1305_key, LC_POLY1305_KEYLEN) || - !poly1305_update(&pctx, aad, aadlen)) - return 0; + cparams.counter = 0; + if (!aead_poly1305_keysetup(cctx, aparams.key, &cparams)) + goto cleanup; + + if (!lc_auth_init(actx, &aparams) || + !lc_auth_update(actx, aad, aadlen)) + goto cleanup; if (aadlen % 16 != 0) - if (!poly1305_update(&pctx, zeropad, 16 - (aadlen % 16))) - return 0; + if (!lc_auth_update(actx, zeropad, 16 - (aadlen % 16))) + goto cleanup; - if (!poly1305_update(&pctx, in, ctlen)) - return 0; + ctlen = inlen - LC_POLY1305_TAGLEN; + if (!lc_auth_update(actx, in, ctlen)) + goto cleanup; if (ctlen % 16 != 0) - if (!poly1305_update(&pctx, zeropad, 16 - (ctlen % 16))) - return 0; + if (!lc_auth_update(actx, zeropad, 16 - (ctlen % 16))) + goto cleanup; store64le(&buf[0], aadlen); store64le(&buf[sizeof(uint64_t)], ctlen); - if (!poly1305_update(&pctx, buf, sizeof(buf)) || - !poly1305_final(&pctx, tag, &olen)) - return 0; + if (!lc_auth_update(actx, buf, sizeof(buf)) || + !lc_auth_final(actx, tag, &olen)) + goto cleanup; + if (olen != LC_POLY1305_TAGLEN) + goto cleanup; + if (!lc_ct_cmp(tag, in + ctlen, LC_POLY1305_TAGLEN)) + goto cleanup; - if (!lc_ct_cmp(tag, tagp, LC_POLY1305_TAGLEN)) - return 0; + cparams.counter = 1; + if (!aead_poly1305_anycrypt(cctx, out, outlen, &cparams, in, ctlen)) + goto cleanup; + ret = 1; + cleanup: lc_scrub(buf, sizeof(buf)); - lc_scrub(poly1305_key, sizeof(poly1305_key)); + lc_scrub(&aparams, sizeof(aparams)); + lc_scrub(&cparams, sizeof(cparams)); + lc_scrub(tag, sizeof(tag)); + lc_auth_ctx_free(actx); + lc_cipher_ctx_free(cctx); - if (!chacha20_common_init_from(&cctx, key, keylen, iv, ivlen, 1)) - return 0; - if (!chacha20_common_update(&cctx, out, &olen, in, ctlen)) - return 0; - *outlen = olen; - if (!chacha20_common_final(&cctx, out + olen, &olen)) - return 0; - *outlen += olen; - - return 1; + return ret; } static int -xchacha20_poly1305_seal(uint8_t *out, size_t *outlen, const uint8_t *key, - size_t keylen, const uint8_t *iv, size_t ivlen, const uint8_t *aad, - size_t aadlen, const uint8_t *in, size_t inlen) +xchacha20_poly1305_open(uint8_t *out, size_t *outlen, const void *initparams, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen) { - struct chacha20_ctx cctx; - struct poly1305_ctx pctx; - uint8_t poly1305_key[LC_POLY1305_KEYLEN]; - uint8_t buf[sizeof(uint64_t) * 2]; - size_t i, olen; - - if (inlen > UINT64_MAX || aadlen > UINT64_MAX || - inlen > SIZE_MAX - LC_POLY1305_TAGLEN || - inlen > SIZE_MAX - CHACHA20_CHUNK + 1 || - (inlen + CHACHA20_CHUNK - 1) / CHACHA20_CHUNK > - CHACHA20_CTRMAX - 1) { - if (out == NULL) - *outlen = 0; - return 0; - } - - if (out == NULL) { - *outlen = inlen + LC_POLY1305_TAGLEN; - return 1; - } + const struct lc_xchacha20_poly1305_params *params = initparams; + struct lc_cipher_ctx *cctx = NULL; + struct lc_auth_ctx *actx = NULL; + struct lc_xchacha20_params cparams; + struct lc_poly1305_params aparams; + uint8_t tag[LC_POLY1305_TAGLEN]; + uint8_t buf[sizeof(uint64_t) * 2]; + size_t i, olen, ctlen; + int ret = 0; *outlen = 0; - - for (i = 0; i < LC_POLY1305_KEYLEN; i++) - poly1305_key[i] = 0; - if (!xchacha20_common_init(&cctx, key, keylen, iv, ivlen) || - !chacha20_common_update(&cctx, poly1305_key, &olen, poly1305_key, - LC_POLY1305_KEYLEN)) - return 0; - if (!chacha20_common_final(&cctx, poly1305_key + olen, &olen)) - return 0; - - if (!poly1305_init(&pctx, poly1305_key, LC_POLY1305_KEYLEN) || - !poly1305_update(&pctx, aad, aadlen)) - return 0; - if (aadlen % 16 != 0) - if (!poly1305_update(&pctx, zeropad, 16 - (aadlen % 16))) - return 0; - - if (!xchacha20_common_init_from(&cctx, key, keylen, iv, ivlen, 1)) - return 0; - if (!chacha20_common_update(&cctx, out, &olen, in, inlen)) - return 0; - *outlen = olen; - if (!chacha20_common_final(&cctx, out + olen, &olen)) - return 0; - if (!poly1305_update(&pctx, out, inlen)) - return 0; - if (inlen % 16 != 0) - if (!poly1305_update(&pctx, zeropad, 16 - (inlen % 16))) - return 0; - - store64le(&buf[0], aadlen); - store64le(&buf[sizeof(uint64_t)], inlen); - if (!poly1305_update(&pctx, buf, sizeof(buf)) || - !poly1305_final(&pctx, out + inlen, &olen)) - return 0; - - lc_scrub(buf, sizeof(buf)); - lc_scrub(poly1305_key, sizeof(poly1305_key)); - - *outlen = inlen + LC_POLY1305_TAGLEN; - - return 1; -} - -static int -xchacha20_poly1305_open(uint8_t *out, size_t *outlen, const uint8_t *key, - size_t keylen, const uint8_t *iv, size_t ivlen, const uint8_t *aad, - size_t aadlen, const uint8_t *in, size_t inlen) -{ - const uint8_t *tagp; - struct chacha20_ctx cctx; - struct poly1305_ctx pctx; - uint8_t poly1305_key[LC_POLY1305_KEYLEN]; - uint8_t tag[LC_POLY1305_TAGLEN]; - uint8_t buf[sizeof(uint64_t) * 2]; - size_t i, olen, ctlen; - + /* inlen includes the tag; inlen and aadlen are capped by design. */ if (inlen < LC_POLY1305_TAGLEN || - inlen > UINT64_MAX || aadlen > UINT64_MAX || - inlen > SIZE_MAX - LC_POLY1305_TAGLEN || - inlen > SIZE_MAX - CHACHA20_CHUNK + 1 || + inlen > UINT64_MAX || aadlen > UINT64_MAX) + return 0; + /* Counter 0 is used for deriving Poly1305 key. */ + if (inlen > SIZE_MAX - (CHACHA20_CHUNK - 1) || (inlen + CHACHA20_CHUNK - 1) / CHACHA20_CHUNK > CHACHA20_CTRMAX - 1) { - if (out == NULL) - *outlen = 0; return 0; } @@ -282,54 +347,60 @@ xchacha20_poly1305_open(uint8_t *out, size_t *outlen, const uint8_t *key, return 1; } - *outlen = 0; - ctlen = inlen - LC_POLY1305_TAGLEN; - tagp = in + ctlen; + cctx = lc_cipher_ctx_new(lc_cipher_impl_xchacha20()); + if (cctx == NULL) + goto cleanup; + actx = lc_auth_ctx_new(lc_auth_impl_poly1305()); + if (actx == NULL) + goto cleanup; - for (i = 0; i < LC_POLY1305_KEYLEN; i++) - poly1305_key[i] = 0; - if (!xchacha20_common_init(&cctx, key, keylen, iv, ivlen) || - !chacha20_common_update(&cctx, poly1305_key, &olen, poly1305_key, - LC_POLY1305_KEYLEN)) - return 0; - if (!chacha20_common_final(&cctx, poly1305_key + olen, &olen)) - return 0; + for (i = 0; i < sizeof(params->key); i++) + cparams.key[i] = params->key[i]; + for (i = 0; i < sizeof(params->nonce); i++) + cparams.nonce[i] = params->nonce[i]; - if (!poly1305_init(&pctx, poly1305_key, LC_POLY1305_KEYLEN) || - !poly1305_update(&pctx, aad, aadlen)) - return 0; + cparams.counter = 0; + if (!aead_poly1305_keysetup(cctx, aparams.key, &cparams)) + goto cleanup; + + if (!lc_auth_init(actx, &aparams) || + !lc_auth_update(actx, aad, aadlen)) + goto cleanup; if (aadlen % 16 != 0) - if (!poly1305_update(&pctx, zeropad, 16 - (aadlen % 16))) - return 0; + if (!lc_auth_update(actx, zeropad, 16 - (aadlen % 16))) + goto cleanup; - if (!poly1305_update(&pctx, in, ctlen)) - return 0; + ctlen = inlen - LC_POLY1305_TAGLEN; + if (!lc_auth_update(actx, in, ctlen)) + goto cleanup; if (ctlen % 16 != 0) - if (!poly1305_update(&pctx, zeropad, 16 - (ctlen % 16))) - return 0; + if (!lc_auth_update(actx, zeropad, 16 - (ctlen % 16))) + goto cleanup; store64le(&buf[0], aadlen); store64le(&buf[sizeof(uint64_t)], ctlen); - if (!poly1305_update(&pctx, buf, sizeof(buf)) || - !poly1305_final(&pctx, tag, &olen)) - return 0; + if (!lc_auth_update(actx, buf, sizeof(buf)) || + !lc_auth_final(actx, tag, &olen)) + goto cleanup; + if (olen != LC_POLY1305_TAGLEN) + goto cleanup; + if (!lc_ct_cmp(tag, in + ctlen, LC_POLY1305_TAGLEN)) + goto cleanup; - if (!lc_ct_cmp(tag, tagp, LC_POLY1305_TAGLEN)) - return 0; + cparams.counter = 1; + if (!aead_poly1305_anycrypt(cctx, out, outlen, &cparams, in, ctlen)) + goto cleanup; + ret = 1; + cleanup: lc_scrub(buf, sizeof(buf)); - lc_scrub(poly1305_key, sizeof(poly1305_key)); + lc_scrub(&aparams, sizeof(aparams)); + lc_scrub(&cparams, sizeof(cparams)); + lc_scrub(tag, sizeof(tag)); + lc_auth_ctx_free(actx); + lc_cipher_ctx_free(cctx); - if (!xchacha20_common_init_from(&cctx, key, keylen, iv, ivlen, 1)) - return 0; - if (!chacha20_common_update(&cctx, out, &olen, in, ctlen)) - return 0; - *outlen = olen; - if (!chacha20_common_final(&cctx, out + olen, &olen)) - return 0; - *outlen += olen; - - return 1; + return ret; } diff --git a/lilcrypto.h b/lilcrypto.h index c18c19a..603bcb9 100644 --- a/lilcrypto.h +++ b/lilcrypto.h @@ -175,11 +175,9 @@ struct lc_aead_impl; int lc_aead_seal(const struct lc_aead_impl *, uint8_t *, size_t *, - const uint8_t *, size_t, const uint8_t *, size_t, const uint8_t *, - size_t, const uint8_t *, size_t); + const void *, const uint8_t *, size_t, const uint8_t *, size_t); int lc_aead_open(const struct lc_aead_impl *, uint8_t *, size_t *, - const uint8_t *, size_t, const uint8_t *, size_t, const uint8_t *, - size_t, const uint8_t *, size_t); + const void *, const uint8_t *, size_t, const uint8_t *, size_t); const struct lc_aead_impl *lc_aead_impl_chacha20_poly1305(void); const struct lc_aead_impl *lc_aead_impl_xchacha20_poly1305(void);