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 9 static int 10 chacha20_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 26 static void 27 chacha20_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 35 static void 36 chacha20_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 46 static void 47 chacha20_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 55 static void 56 chacha20_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 64 struct 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