Changeset View
Changeset View
Standalone View
Standalone View
head/sys/crypto/chacha20/chacha-sw.c
/* This file is in the public domain. */ | /* This file is in the public domain. */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <crypto/chacha20/chacha.h> | #include <crypto/chacha20/chacha.h> | ||||
#include <opencrypto/xform_enc.h> | #include <opencrypto/xform_enc.h> | ||||
static int | static int | ||||
chacha20_xform_setkey(u_int8_t **sched, const u_int8_t *key, int len) | chacha20_xform_setkey(void *ctx, const uint8_t *key, int len) | ||||
{ | { | ||||
struct chacha_ctx *ctx; | |||||
if (len != CHACHA_MINKEYLEN && len != 32) | if (len != CHACHA_MINKEYLEN && len != 32) | ||||
return (EINVAL); | return (EINVAL); | ||||
ctx = malloc(sizeof(*ctx), M_CRYPTO_DATA, M_NOWAIT | M_ZERO); | |||||
*sched = (void *)ctx; | |||||
if (ctx == NULL) | |||||
return (ENOMEM); | |||||
chacha_keysetup(ctx, key, len * 8); | chacha_keysetup(ctx, key, len * 8); | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
chacha20_xform_reinit(caddr_t key, const u_int8_t *iv) | chacha20_xform_reinit(void *ctx, const u_int8_t *iv) | ||||
{ | { | ||||
struct chacha_ctx *ctx; | |||||
ctx = (void *)key; | |||||
chacha_ivsetup(ctx, iv + 8, iv); | chacha_ivsetup(ctx, iv + 8, iv); | ||||
} | } | ||||
static void | static void | ||||
chacha20_xform_zerokey(u_int8_t **sched) | chacha20_xform_crypt(void *ctx, const uint8_t *in, uint8_t *out) | ||||
{ | { | ||||
struct chacha_ctx *ctx; | |||||
ctx = (void *)*sched; | chacha_encrypt_bytes(ctx, in, out, 1); | ||||
explicit_bzero(ctx, sizeof(*ctx)); | |||||
free(ctx, M_CRYPTO_DATA); | |||||
*sched = NULL; | |||||
} | } | ||||
static void | static void | ||||
chacha20_xform_crypt(caddr_t cctx, u_int8_t *bytes) | chacha20_xform_crypt_multi(void *ctx, const uint8_t *in, uint8_t *out, | ||||
size_t len) | |||||
{ | { | ||||
struct chacha_ctx *ctx; | |||||
ctx = (void *)cctx; | chacha_encrypt_bytes(ctx, in, out, len); | ||||
chacha_encrypt_bytes(ctx, bytes, bytes, 1); | |||||
} | } | ||||
static void | |||||
chacha20_xform_crypt_multi(void *vctx, uint8_t *bytes, size_t len) | |||||
{ | |||||
struct chacha_ctx *ctx; | |||||
ctx = vctx; | |||||
chacha_encrypt_bytes(ctx, bytes, bytes, len); | |||||
} | |||||
struct enc_xform enc_xform_chacha20 = { | struct enc_xform enc_xform_chacha20 = { | ||||
.type = CRYPTO_CHACHA20, | .type = CRYPTO_CHACHA20, | ||||
.name = "chacha20", | .name = "chacha20", | ||||
.ctxsize = sizeof(struct chacha_ctx), | |||||
.blocksize = 1, | .blocksize = 1, | ||||
.ivsize = CHACHA_NONCELEN + CHACHA_CTRLEN, | .ivsize = CHACHA_NONCELEN + CHACHA_CTRLEN, | ||||
.minkey = CHACHA_MINKEYLEN, | .minkey = CHACHA_MINKEYLEN, | ||||
.maxkey = 32, | .maxkey = 32, | ||||
.encrypt = chacha20_xform_crypt, | .encrypt = chacha20_xform_crypt, | ||||
.decrypt = chacha20_xform_crypt, | .decrypt = chacha20_xform_crypt, | ||||
.setkey = chacha20_xform_setkey, | .setkey = chacha20_xform_setkey, | ||||
.zerokey = chacha20_xform_zerokey, | |||||
.reinit = chacha20_xform_reinit, | .reinit = chacha20_xform_reinit, | ||||
.encrypt_multi = chacha20_xform_crypt_multi, | .encrypt_multi = chacha20_xform_crypt_multi, | ||||
.decrypt_multi = chacha20_xform_crypt_multi, | .decrypt_multi = chacha20_xform_crypt_multi, | ||||
}; | }; |