diff --git a/cipher.c b/cipher.c index c7ed14b..276e13f 100644 --- a/cipher.c +++ b/cipher.c @@ -21,10 +21,9 @@ int -lc_cipher_encrypt_init(struct lc_cipher_ctx *ctx, const uint8_t *key, - size_t keylen, const uint8_t *iv, size_t ivlen) +lc_cipher_encrypt_init(struct lc_cipher_ctx *ctx, const void *initparams) { - return ctx->impl->encrypt_init(ctx->arg, key, keylen, iv, ivlen); + return ctx->impl->encrypt_init(ctx->arg, initparams); } int @@ -43,17 +42,15 @@ lc_cipher_encrypt_final(struct lc_cipher_ctx *ctx, uint8_t *out, int lc_cipher_encrypt(const struct lc_cipher_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 *in, size_t inlen) + size_t *outlen, const void *initparams, const uint8_t *in, size_t inlen) { - return impl->encrypt(out, outlen, key, keylen, iv, ivlen, in, inlen); + return impl->encrypt(out, outlen, initparams, in, inlen); } int -lc_cipher_decrypt_init(struct lc_cipher_ctx *ctx, const uint8_t *key, - size_t keylen, const uint8_t *iv, size_t ivlen) +lc_cipher_decrypt_init(struct lc_cipher_ctx *ctx, const void *initparams) { - return ctx->impl->decrypt_init(ctx->arg, key, keylen, iv, ivlen); + return ctx->impl->decrypt_init(ctx->arg, initparams); } int @@ -72,10 +69,9 @@ lc_cipher_decrypt_final(struct lc_cipher_ctx *ctx, uint8_t *out, int lc_cipher_decrypt(const struct lc_cipher_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 *in, size_t inlen) + size_t *outlen, const void *initparams, const uint8_t *in, size_t inlen) { - return impl->decrypt(out, outlen, key, keylen, iv, ivlen, in, inlen); + return impl->decrypt(out, outlen, initparams, in, inlen); } struct lc_cipher_ctx * diff --git a/cipher.h b/cipher.h index 27a4e00..c941ff4 100644 --- a/cipher.h +++ b/cipher.h @@ -19,21 +19,19 @@ struct lc_cipher_impl { - int (*encrypt_init)(void *, const uint8_t *, size_t, + int (*encrypt_init)(void *, const void *); + int (*encrypt_update)(void *, uint8_t *, size_t *, const uint8_t *, size_t); - int (*encrypt_update)(void *, uint8_t *, size_t *, const uint8_t *, - size_t); int (*encrypt_final)(void *, uint8_t *, size_t *); - int (*encrypt)(uint8_t *, size_t *, const uint8_t *, size_t, - const uint8_t *, size_t, const uint8_t *, size_t); - - int (*decrypt_init)(void *, const uint8_t *, size_t, - const uint8_t *, size_t); - int (*decrypt_update)(void *, uint8_t *, size_t *, const uint8_t *, + int (*encrypt)(uint8_t *, size_t *, const void *, const uint8_t *, size_t); + + int (*decrypt_init)(void *, const void *); + int (*decrypt_update)(void *, uint8_t *, size_t *, + const uint8_t *, size_t); int (*decrypt_final)(void *, uint8_t *, size_t *); - int (*decrypt)(uint8_t *, size_t *, const uint8_t *, size_t, - const uint8_t *, size_t, const uint8_t *, size_t); + int (*decrypt)(uint8_t *, size_t *, const void *, const uint8_t *, + size_t); void *(*ctx_new)(void); void (*ctx_free)(void *); diff --git a/cipher_chacha20.c b/cipher_chacha20.c index e9423e6..872949e 100644 --- a/cipher_chacha20.c +++ b/cipher_chacha20.c @@ -19,57 +19,49 @@ #include "lilcrypto.h" #include "cipher.h" -#include "cipher_chacha20.h" #include "impl_chacha20.h" #include "util.h" -int -chacha20_common_init_from(void *arg, const uint8_t *key, size_t keylen, - const uint8_t *iv, size_t ivlen, uint32_t counter) -{ - struct chacha20_ctx *ctx = arg; - size_t i; +/* + * Implements ChaCha20 according to RFC 8439, XChaCha20 according to + * draft-irtf-cfrg-xchacha-03. + */ - if (keylen != LC_CHACHA20_KEYLEN || ivlen != LC_CHACHA20_NONCELEN) - return 0; + +static int +chacha20_common_init(void *arg, const void *initparams) +{ + const struct lc_chacha20_params *params = initparams; + struct chacha20_ctx *ctx = arg; + size_t i; for (i = 0; i < CHACHA20_CHUNK_WORDS; i++) ctx->s[i] = 0; for (i = 0; i < CHACHA20_KEY_WORDS; i++) - ctx->k[i] = load32le(&key[i * 4]); - ctx->n[0] = counter; + ctx->k[i] = load32le(¶ms->key[i * 4]); + ctx->n[0] = params->counter; for (i = 1; i < CHACHA20_NONCE_WORDS; i++) - ctx->n[i] = load32le(&iv[(i - 1) * 4]); + ctx->n[i] = load32le(¶ms->nonce[(i - 1) * 4]); ctx->mlen = 0; return 1; } -int -chacha20_common_init(void *arg, const uint8_t *key, size_t keylen, - const uint8_t *iv, size_t ivlen) +static int +xchacha20_common_init(void *arg, const void *initparams) { - return chacha20_common_init_from(arg, key, keylen, iv, ivlen, 0); -} - -int -xchacha20_common_init_from(void *arg, const uint8_t *key, size_t keylen, - const uint8_t *iv, size_t ivlen, uint64_t counter) -{ - struct chacha20_ctx *ctx = arg; - size_t i; - - if (keylen != LC_XCHACHA20_KEYLEN || ivlen != LC_XCHACHA20_NONCELEN) - return 0; + const struct lc_xchacha20_params *params = initparams; + struct chacha20_ctx *ctx = arg; + size_t i; for (i = 0; i < CHACHA20_CHUNK_WORDS; i++) ctx->s[i] = 0; for (i = 0; i < CHACHA20_KEY_WORDS; i++) - ctx->k[i] = load32le(&key[i * 4]); + ctx->k[i] = load32le(¶ms->key[i * 4]); for (i = 0; i < CHACHA20_NONCE_WORDS; i++) - ctx->n[i] = load32le(&iv[i * 4]); + ctx->n[i] = load32le(¶ms->nonce[i * 4]); ctx->mlen = 0; hchacha20_block(ctx); @@ -82,22 +74,15 @@ xchacha20_common_init_from(void *arg, const uint8_t *key, size_t keylen, ctx->k[5] = ctx->s[13]; ctx->k[6] = ctx->s[14]; ctx->k[7] = ctx->s[15]; - ctx->n[0] = counter; - ctx->n[1] = counter >> 32; - ctx->n[2] = load32le(&iv[16]); - ctx->n[3] = load32le(&iv[20]); + ctx->n[0] = params->counter; + ctx->n[1] = 0; + ctx->n[2] = load32le(¶ms->nonce[16]); + ctx->n[3] = load32le(¶ms->nonce[20]); return 1; } -int -xchacha20_common_init(void *arg, const uint8_t *key, size_t keylen, - const uint8_t *iv, size_t ivlen) -{ - return xchacha20_common_init_from(arg, key, keylen, iv, ivlen, 0); -} - -int +static int chacha20_common_update(void *arg, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { @@ -159,7 +144,7 @@ chacha20_common_update(void *arg, uint8_t *out, size_t *outlen, return 1; } -int +static int chacha20_common_final(void *arg, uint8_t *out, size_t *outlen) { struct chacha20_ctx *ctx = arg; @@ -192,10 +177,9 @@ chacha20_common_final(void *arg, uint8_t *out, size_t *outlen) return 1; } -int -chacha20_common(uint8_t *out, size_t *outlen, const uint8_t *key, - size_t keylen, const uint8_t *iv, size_t ivlen, const uint8_t *in, - size_t inlen) +static int +chacha20_common(uint8_t *out, size_t *outlen, const void *initparams, + const uint8_t *in, size_t inlen) { struct chacha20_ctx ctx; size_t l0, l1; @@ -212,7 +196,7 @@ chacha20_common(uint8_t *out, size_t *outlen, const uint8_t *key, return 1; } - rc = chacha20_common_init(&ctx, key, keylen, iv, ivlen) && + rc = chacha20_common_init(&ctx, initparams) && chacha20_common_update(&ctx, out, &l0, in, inlen) && chacha20_common_final(&ctx, out + l0, &l1); diff --git a/cipher_chacha20.h b/cipher_chacha20.h deleted file mode 100644 index 423e058..0000000 --- a/cipher_chacha20.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2024 Lucas Gabriel Vuotto - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include - - -int chacha20_common_init_from(void *, const uint8_t *, size_t, - const uint8_t *, size_t, uint32_t); -int chacha20_common_init(void *, const uint8_t *, size_t, const uint8_t *, - size_t); -int xchacha20_common_init_from(void *, const uint8_t *, size_t, - const uint8_t *, size_t, uint64_t); -int xchacha20_common_init(void *, const uint8_t *, size_t, const uint8_t *, - size_t); -int chacha20_common_update(void *, uint8_t *, size_t *, const uint8_t *, - size_t); -int chacha20_common_final(void *, uint8_t *, size_t *); -int chacha20_common(uint8_t *, size_t *, const uint8_t *, size_t, - const uint8_t *, size_t, const uint8_t *, size_t); diff --git a/lilcrypto.h b/lilcrypto.h index b651aa8..502f7d6 100644 --- a/lilcrypto.h +++ b/lilcrypto.h @@ -147,22 +147,18 @@ struct lc_cipher_ctx; struct lc_cipher_impl; -int lc_cipher_encrypt_init(struct lc_cipher_ctx *, const uint8_t *, size_t, - const uint8_t *, size_t); +int lc_cipher_encrypt_init(struct lc_cipher_ctx *, const void *); int lc_cipher_encrypt_update(struct lc_cipher_ctx *, uint8_t *, size_t *, const uint8_t *, size_t); int lc_cipher_encrypt_final(struct lc_cipher_ctx *, uint8_t *, size_t *); int lc_cipher_encrypt(const struct lc_cipher_impl *, uint8_t *, size_t *, - const uint8_t *, size_t, const uint8_t *, size_t, const uint8_t *, - size_t); -int lc_cipher_decrypt_init(struct lc_cipher_ctx *, const uint8_t *, size_t, - const uint8_t *, size_t); + const void *, const uint8_t *, size_t); +int lc_cipher_decrypt_init(struct lc_cipher_ctx *, const void *); int lc_cipher_decrypt_update(struct lc_cipher_ctx *, uint8_t *, size_t *, const uint8_t *, size_t); int lc_cipher_decrypt_final(struct lc_cipher_ctx *, uint8_t *, size_t *); int lc_cipher_decrypt(const struct lc_cipher_impl *, 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); struct lc_cipher_ctx *lc_cipher_ctx_new(const struct lc_cipher_impl *); void lc_cipher_ctx_free(struct lc_cipher_ctx *);