1/* This file is in the public domain. */ 2 3#include <sys/cdefs.h> 4__FBSDID("$FreeBSD$"); 5 6#include <crypto/chacha20/chacha.h> 7#include <opencrypto/xform_enc.h> 8 9static int 10chacha20_xform_setkey(u_int8_t **sched, u_int8_t *key, int len) 11{ 12 struct chacha_ctx *ctx; 13 14 if (len != CHACHA_MINKEYLEN && len != 32) 15 return (EINVAL); 16 17 ctx = malloc(sizeof(*ctx), M_CRYPTO_DATA, M_NOWAIT | M_ZERO); 18 *sched = (void *)ctx; 19 if (ctx == NULL) 20 return (ENOMEM); 21 22 chacha_keysetup(ctx, key, len * 8); 23 return (0); 24} 25 26static void 27chacha20_xform_reinit(caddr_t key, u_int8_t *iv) 28{ 29 struct chacha_ctx *ctx; 30 31 ctx = (void *)key; 32 chacha_ivsetup(ctx, iv + 8, iv); 33} 34 35static void 36chacha20_xform_zerokey(u_int8_t **sched) 37{ 38 struct chacha_ctx *ctx; 39 40 ctx = (void *)*sched; 41 explicit_bzero(ctx, sizeof(*ctx)); 42 free(ctx, M_CRYPTO_DATA); 43 *sched = NULL; 44} 45 46static void 47chacha20_xform_crypt(caddr_t cctx, u_int8_t *bytes) 48{ 49 struct chacha_ctx *ctx; 50 51 ctx = (void *)cctx; 52 chacha_encrypt_bytes(ctx, bytes, bytes, 1); 53} 54 55static void 56chacha20_xform_crypt_multi(void *vctx, uint8_t *bytes, size_t len) 57{ 58 struct chacha_ctx *ctx; 59 60 ctx = vctx; 61 chacha_encrypt_bytes(ctx, bytes, bytes, len); 62} 63 64struct enc_xform enc_xform_chacha20 = { 65 .type = CRYPTO_CHACHA20, 66 .name = "chacha20", 67 .blocksize = 1, 68 .ivsize = CHACHA_NONCELEN + CHACHA_CTRLEN, 69 .minkey = CHACHA_MINKEYLEN, 70 .maxkey = 32, 71 .encrypt = chacha20_xform_crypt, 72 .decrypt = chacha20_xform_crypt, 73 .setkey = chacha20_xform_setkey, 74 .zerokey = chacha20_xform_zerokey, 75 .reinit = chacha20_xform_reinit, 76 .encrypt_multi = chacha20_xform_crypt_multi, 77 .decrypt_multi = chacha20_xform_crypt_multi, 78}; 79