1 /* This file is in the public domain. */ 2 3 #include <sys/cdefs.h> 4 #include <crypto/chacha20/chacha.h> 5 #include <opencrypto/xform_enc.h> 6 7 static int 8 chacha20_xform_setkey(void *ctx, const uint8_t *key, int len) 9 { 10 11 if (len != CHACHA_MINKEYLEN && len != 32) 12 return (EINVAL); 13 14 chacha_keysetup(ctx, key, len * 8); 15 return (0); 16 } 17 18 static void 19 chacha20_xform_reinit(void *ctx, const uint8_t *iv, size_t ivlen) 20 { 21 KASSERT(ivlen == CHACHA_NONCELEN + CHACHA_CTRLEN, 22 ("%s: invalid IV length", __func__)); 23 chacha_ivsetup(ctx, iv + 8, iv); 24 } 25 26 static void 27 chacha20_xform_crypt(void *ctx, const uint8_t *in, uint8_t *out) 28 { 29 30 chacha_encrypt_bytes(ctx, in, out, CHACHA_BLOCKLEN); 31 } 32 33 static void 34 chacha20_xform_crypt_multi(void *ctx, const uint8_t *in, uint8_t *out, 35 size_t len) 36 { 37 KASSERT(len % CHACHA_BLOCKLEN == 0, ("%s: invalid length", __func__)); 38 chacha_encrypt_bytes(ctx, in, out, len); 39 } 40 41 static void 42 chacha20_xform_crypt_last(void *ctx, const uint8_t *in, uint8_t *out, 43 size_t len) 44 { 45 46 chacha_encrypt_bytes(ctx, in, out, len); 47 } 48 49 const struct enc_xform enc_xform_chacha20 = { 50 .type = CRYPTO_CHACHA20, 51 .name = "chacha20", 52 .ctxsize = sizeof(struct chacha_ctx), 53 .blocksize = 1, 54 .native_blocksize = CHACHA_BLOCKLEN, 55 .ivsize = CHACHA_NONCELEN + CHACHA_CTRLEN, 56 .minkey = CHACHA_MINKEYLEN, 57 .maxkey = 32, 58 .setkey = chacha20_xform_setkey, 59 .reinit = chacha20_xform_reinit, 60 .encrypt = chacha20_xform_crypt, 61 .decrypt = chacha20_xform_crypt, 62 .encrypt_multi = chacha20_xform_crypt_multi, 63 .decrypt_multi = chacha20_xform_crypt_multi, 64 .encrypt_last = chacha20_xform_crypt_last, 65 .decrypt_last = chacha20_xform_crypt_last, 66 }; 67