723d87648e
Add a 'native_blocksize' member to 'struct enc_xform' that ciphers can use if they support a partial final block. This is particular useful for stream ciphers, but can also apply to other ciphers. cryptosoft will only pass in native blocks to the encrypt and decrypt hooks. For the final partial block, 'struct enc_xform' now has new encrypt_last/decrypt_last hooks which accept the length of the final block. The multi_block methods are also retired. Mark AES-ICM (AES-CTR) as a stream cipher. This has some interesting effects on IPsec in that FreeBSD can now properly receive all packets sent by Linux when using AES-CTR, but FreeBSD can no longer interoperate with OpenBSD and older verisons of FreeBSD which assume AES-CTR packets have a payload padded to a 16-byte boundary. Kornel has offered to work on a patch to add a compatiblity sysctl to enforce additional padding for AES-CTR in esp_output to permit compatibility with OpenBSD and older versions of FreeBSD. AES-XTS continues to use a block size of a single AES block length. It is possible to adjust it to support partial final blocks by implementing cipher text stealing via encrypt_last/decrypt_last hooks, but I have not done so. Reviewed by: cem (earlier version) Tested by: Kornel Dulęba <mindal@semihalf.com> (AES-CTR with IPsec) Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D24906
58 lines
1.2 KiB
C
58 lines
1.2 KiB
C
/* This file is in the public domain. */
|
|
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
#include <crypto/chacha20/chacha.h>
|
|
#include <opencrypto/xform_enc.h>
|
|
|
|
static int
|
|
chacha20_xform_setkey(void *ctx, const uint8_t *key, int len)
|
|
{
|
|
|
|
if (len != CHACHA_MINKEYLEN && len != 32)
|
|
return (EINVAL);
|
|
|
|
chacha_keysetup(ctx, key, len * 8);
|
|
return (0);
|
|
}
|
|
|
|
static void
|
|
chacha20_xform_reinit(void *ctx, const u_int8_t *iv)
|
|
{
|
|
|
|
chacha_ivsetup(ctx, iv + 8, iv);
|
|
}
|
|
|
|
static void
|
|
chacha20_xform_crypt(void *ctx, const uint8_t *in, uint8_t *out)
|
|
{
|
|
|
|
chacha_encrypt_bytes(ctx, in, out, CHACHA_BLOCKLEN);
|
|
}
|
|
|
|
static void
|
|
chacha20_xform_crypt_last(void *ctx, const uint8_t *in, uint8_t *out,
|
|
size_t len)
|
|
{
|
|
|
|
chacha_encrypt_bytes(ctx, in, out, len);
|
|
}
|
|
|
|
struct enc_xform enc_xform_chacha20 = {
|
|
.type = CRYPTO_CHACHA20,
|
|
.name = "chacha20",
|
|
.ctxsize = sizeof(struct chacha_ctx),
|
|
.blocksize = 1,
|
|
.native_blocksize = CHACHA_BLOCKLEN,
|
|
.ivsize = CHACHA_NONCELEN + CHACHA_CTRLEN,
|
|
.minkey = CHACHA_MINKEYLEN,
|
|
.maxkey = 32,
|
|
.encrypt = chacha20_xform_crypt,
|
|
.decrypt = chacha20_xform_crypt,
|
|
.setkey = chacha20_xform_setkey,
|
|
.reinit = chacha20_xform_reinit,
|
|
.encrypt_last = chacha20_xform_crypt_last,
|
|
.decrypt_last = chacha20_xform_crypt_last,
|
|
};
|