mirror of
https://git.FreeBSD.org/src.git
synced 2024-10-19 02:29:40 +00:00
crypto: Permit variable-sized IVs for ciphers with a reinit hook.
Add a 'len' argument to the reinit hook in 'struct enc_xform' to permit support for AEAD ciphers such as AES-CCM and Chacha20-Poly1305 which support different nonce lengths. Reviewed by: markj Sponsored by: Chelsio Communications, The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32105
This commit is contained in:
parent
cb128893b9
commit
1833d6042c
@ -18,9 +18,10 @@ chacha20_xform_setkey(void *ctx, const uint8_t *key, int len)
|
||||
}
|
||||
|
||||
static void
|
||||
chacha20_xform_reinit(void *ctx, const uint8_t *iv)
|
||||
chacha20_xform_reinit(void *ctx, const uint8_t *iv, size_t ivlen)
|
||||
{
|
||||
|
||||
KASSERT(ivlen == CHACHA_NONCELEN + CHACHA_CTRLEN,
|
||||
("%s: invalid IV length", __func__));
|
||||
chacha_ivsetup(ctx, iv + 8, iv);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,12 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Chelsio Communications, Inc.
|
||||
* Copyright (c) 2021 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
* Written by: John Baldwin <jhb@FreeBSD.org>
|
||||
*
|
||||
* Portions of this software were developed by Ararat River
|
||||
* Consulting, LLC under sponsorship of the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -1458,7 +1462,7 @@ ccr_gcm_soft(struct ccr_session *s, struct cryptop *crp)
|
||||
}
|
||||
}
|
||||
|
||||
exf->reinit(kschedule, iv);
|
||||
exf->reinit(kschedule, iv, sizeof(iv));
|
||||
|
||||
/* Do encryption with MAC */
|
||||
for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) {
|
||||
@ -1935,7 +1939,7 @@ ccr_ccm_soft(struct ccr_session *s, struct cryptop *crp)
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
exf->reinit(kschedule, iv);
|
||||
exf->reinit(kschedule, iv, sizeof(iv));
|
||||
|
||||
/* Do encryption/decryption with MAC */
|
||||
for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) {
|
||||
@ -1970,7 +1974,7 @@ ccr_ccm_soft(struct ccr_session *s, struct cryptop *crp)
|
||||
error = 0;
|
||||
|
||||
/* Tag matches, decrypt data. */
|
||||
exf->reinit(kschedule, iv);
|
||||
exf->reinit(kschedule, iv, sizeof(iv));
|
||||
for (i = 0; i < crp->crp_payload_length;
|
||||
i += sizeof(block)) {
|
||||
len = imin(crp->crp_payload_length - i,
|
||||
|
@ -9,13 +9,16 @@
|
||||
* supported the development of this code.
|
||||
*
|
||||
* Copyright (c) 2000, 2001 Angelos D. Keromytis
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* Copyright (c) 2014-2021 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by John-Mark Gurney
|
||||
* under sponsorship of the FreeBSD Foundation and
|
||||
* Rubicon Communications, LLC (Netgate).
|
||||
*
|
||||
* Portions of this software were developed by Ararat River
|
||||
* Consulting, LLC under sponsorship of the FreeBSD Foundation.
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all source code copies of any software which is or includes a copy or
|
||||
@ -106,7 +109,7 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp)
|
||||
const struct enc_xform *exf;
|
||||
struct swcr_encdec *sw;
|
||||
size_t inlen, outlen;
|
||||
int i, blks, ivlen, resid;
|
||||
int i, blks, resid;
|
||||
struct crypto_buffer_cursor cc_in, cc_out;
|
||||
const unsigned char *inblk;
|
||||
unsigned char *outblk;
|
||||
@ -117,7 +120,7 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp)
|
||||
|
||||
sw = &ses->swcr_encdec;
|
||||
exf = sw->sw_exf;
|
||||
ivlen = exf->ivsize;
|
||||
csp = crypto_get_params(crp->crp_session);
|
||||
|
||||
if (exf->native_blocksize == 0) {
|
||||
/* Check for non-padded data */
|
||||
@ -133,7 +136,6 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp)
|
||||
return (EINVAL);
|
||||
|
||||
if (crp->crp_cipher_key != NULL) {
|
||||
csp = crypto_get_params(crp->crp_session);
|
||||
error = exf->setkey(sw->sw_kschedule,
|
||||
crp->crp_cipher_key, csp->csp_cipher_klen);
|
||||
if (error)
|
||||
@ -147,7 +149,7 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp)
|
||||
* xforms that provide a reinit method perform all IV
|
||||
* handling themselves.
|
||||
*/
|
||||
exf->reinit(sw->sw_kschedule, iv);
|
||||
exf->reinit(sw->sw_kschedule, iv, csp->csp_ivlen);
|
||||
}
|
||||
|
||||
ivp = iv;
|
||||
@ -534,7 +536,7 @@ swcr_gcm(struct swcr_session *ses, struct cryptop *crp)
|
||||
if (crp->crp_cipher_key != NULL)
|
||||
exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
|
||||
crypto_get_params(crp->crp_session)->csp_cipher_klen);
|
||||
exf->reinit(swe->sw_kschedule, iv);
|
||||
exf->reinit(swe->sw_kschedule, iv, ivlen);
|
||||
|
||||
/* Do encryption with MAC */
|
||||
crypto_cursor_init(&cc_in, &crp->crp_buf);
|
||||
@ -753,7 +755,7 @@ swcr_ccm(struct swcr_session *ses, struct cryptop *crp)
|
||||
if (crp->crp_cipher_key != NULL)
|
||||
exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
|
||||
crypto_get_params(crp->crp_session)->csp_cipher_klen);
|
||||
exf->reinit(swe->sw_kschedule, iv);
|
||||
exf->reinit(swe->sw_kschedule, iv, ivlen);
|
||||
|
||||
/* Do encryption/decryption with MAC */
|
||||
crypto_cursor_init(&cc_in, &crp->crp_buf);
|
||||
@ -824,7 +826,7 @@ swcr_ccm(struct swcr_session *ses, struct cryptop *crp)
|
||||
}
|
||||
|
||||
/* tag matches, decrypt data */
|
||||
exf->reinit(swe->sw_kschedule, iv);
|
||||
exf->reinit(swe->sw_kschedule, iv, ivlen);
|
||||
crypto_cursor_init(&cc_in, &crp->crp_buf);
|
||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start);
|
||||
for (resid = crp->crp_payload_length; resid > blksz;
|
||||
@ -915,7 +917,7 @@ swcr_chacha20_poly1305(struct swcr_session *ses, struct cryptop *crp)
|
||||
if (crp->crp_cipher_key != NULL)
|
||||
exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
|
||||
csp->csp_cipher_klen);
|
||||
exf->reinit(swe->sw_kschedule, crp->crp_iv);
|
||||
exf->reinit(swe->sw_kschedule, crp->crp_iv, csp->csp_ivlen);
|
||||
|
||||
/* Do encryption with MAC */
|
||||
crypto_cursor_init(&cc_in, &crp->crp_buf);
|
||||
|
@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$");
|
||||
static int aes_icm_setkey(void *, const uint8_t *, int);
|
||||
static void aes_icm_crypt(void *, const uint8_t *, uint8_t *);
|
||||
static void aes_icm_crypt_last(void *, const uint8_t *, uint8_t *, size_t);
|
||||
static void aes_icm_reinit(void *, const uint8_t *);
|
||||
static void aes_gcm_reinit(void *, const uint8_t *);
|
||||
static void aes_ccm_reinit(void *, const uint8_t *);
|
||||
static void aes_icm_reinit(void *, const uint8_t *, size_t);
|
||||
static void aes_gcm_reinit(void *, const uint8_t *, size_t);
|
||||
static void aes_ccm_reinit(void *, const uint8_t *, size_t);
|
||||
|
||||
/* Encryption instances */
|
||||
const struct enc_xform enc_xform_aes_icm = {
|
||||
@ -114,20 +114,24 @@ const struct enc_xform enc_xform_ccm = {
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
aes_icm_reinit(void *key, const uint8_t *iv)
|
||||
aes_icm_reinit(void *key, const uint8_t *iv, size_t ivlen)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
ctx = key;
|
||||
bcopy(iv, ctx->ac_block, AESICM_BLOCKSIZE);
|
||||
KASSERT(ivlen <= sizeof(ctx->ac_block),
|
||||
("%s: ivlen too large", __func__));
|
||||
bcopy(iv, ctx->ac_block, ivlen);
|
||||
}
|
||||
|
||||
static void
|
||||
aes_gcm_reinit(void *key, const uint8_t *iv)
|
||||
aes_gcm_reinit(void *key, const uint8_t *iv, size_t ivlen)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
aes_icm_reinit(key, iv);
|
||||
KASSERT(ivlen == AES_GCM_IV_LEN,
|
||||
("%s: invalid IV length", __func__));
|
||||
aes_icm_reinit(key, iv, ivlen);
|
||||
|
||||
ctx = key;
|
||||
/* GCM starts with 2 as counter 1 is used for final xor of tag. */
|
||||
@ -136,10 +140,12 @@ aes_gcm_reinit(void *key, const uint8_t *iv)
|
||||
}
|
||||
|
||||
static void
|
||||
aes_ccm_reinit(void *key, const uint8_t *iv)
|
||||
aes_ccm_reinit(void *key, const uint8_t *iv, size_t ivlen)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
KASSERT(ivlen == AES_CCM_IV_LEN,
|
||||
("%s: invalid IV length", __func__));
|
||||
ctx = key;
|
||||
|
||||
/* CCM has flags, then the IV, then the counter, which starts at 1 */
|
||||
|
@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$");
|
||||
static int aes_xts_setkey(void *, const uint8_t *, int);
|
||||
static void aes_xts_encrypt(void *, const uint8_t *, uint8_t *);
|
||||
static void aes_xts_decrypt(void *, const uint8_t *, uint8_t *);
|
||||
static void aes_xts_reinit(void *, const uint8_t *);
|
||||
static void aes_xts_reinit(void *, const uint8_t *, size_t);
|
||||
|
||||
/* Encryption instances */
|
||||
const struct enc_xform enc_xform_aes_xts = {
|
||||
@ -77,12 +77,15 @@ const struct enc_xform enc_xform_aes_xts = {
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
static void
|
||||
aes_xts_reinit(void *key, const uint8_t *iv)
|
||||
aes_xts_reinit(void *key, const uint8_t *iv, size_t ivlen)
|
||||
{
|
||||
struct aes_xts_ctx *ctx = key;
|
||||
uint64_t blocknum;
|
||||
u_int i;
|
||||
|
||||
KASSERT(ivlen == sizeof(blocknum),
|
||||
("%s: invalid IV length", __func__));
|
||||
|
||||
/*
|
||||
* Prepare tweak as E_k2(IV). IV is specified as LE representation
|
||||
* of a 64-bit block number which we allow to be passed in directly.
|
||||
|
@ -50,10 +50,13 @@ chacha20_poly1305_setkey(void *vctx, const uint8_t *key, int len)
|
||||
}
|
||||
|
||||
static void
|
||||
chacha20_poly1305_reinit(void *vctx, const uint8_t *iv)
|
||||
chacha20_poly1305_reinit(void *vctx, const uint8_t *iv, size_t ivlen)
|
||||
{
|
||||
struct chacha20_poly1305_cipher_ctx *ctx = vctx;
|
||||
|
||||
KASSERT(ivlen == sizeof(ctx->nonce),
|
||||
("%s: invalid nonce length", __func__));
|
||||
|
||||
/* Block 0 is used for the poly1305 key. */
|
||||
memcpy(ctx->nonce, iv, sizeof(ctx->nonce));
|
||||
ctx->ic = 1;
|
||||
|
@ -62,7 +62,7 @@ struct enc_xform {
|
||||
void (*encrypt) (void *, const uint8_t *, uint8_t *);
|
||||
void (*decrypt) (void *, const uint8_t *, uint8_t *);
|
||||
int (*setkey) (void *, const uint8_t *, int len);
|
||||
void (*reinit) (void *, const uint8_t *);
|
||||
void (*reinit) (void *, const uint8_t *, size_t);
|
||||
|
||||
/*
|
||||
* For stream ciphers, encrypt/decrypt the final partial block
|
||||
|
Loading…
Reference in New Issue
Block a user