Retire the CRYPTO_F_IV_GENERATE flag.

The sole in-tree user of this flag has been retired, so remove this
complexity from all drivers.  While here, add a helper routine drivers
can use to read the current request's IV into a local buffer.  Use
this routine to replace duplicated code in nearly all drivers.

Reviewed by:	cem
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D24450
This commit is contained in:
jhb 2020-04-20 22:24:49 +00:00
parent 6c8988f849
commit 5ddc1a3518
19 changed files with 46 additions and 177 deletions

View File

@ -904,6 +904,7 @@ MLINKS+=crypto_driver.9 crypto_apply.9 \
crypto_driver.9 crypto_done.9 \
crypto_driver.9 crypto_get_driverid.9 \
crypto_driver.9 crypto_get_driver_session.9 \
crypto_driver.9 crypto_read_iv.9 \
crypto_driver.9 crypto_unblock.9 \
crypto_driver.9 crypto_unregister_all.9 \
crypto_driver.9 CRYPTODEV_FREESESSION.9 \

View File

@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd March 27, 2020
.Dd April 20, 2020
.Dt CRYPTO_DRIVER 9
.Os
.Sh NAME
@ -62,6 +62,8 @@
.Fn crypto_get_driverid "device_t dev" "size_t session_size" "int flags"
.Ft void *
.Fn crypto_get_driver_session "crypto_session_t crypto_session"
.Ft void
.Fn crypto_read_iv "struct cryptop *crp" "void *iv"
.Ft int
.Fn crypto_unblock "uint32_t driverid" "int what"
.Ft int
@ -261,6 +263,12 @@ The bytes are written starting at an offset of
.Fa off
bytes in the request's data buffer.
.Pp
.Fn crypto_read_iv
copies the IV or nonce for
.Fa crp
into the the local buffer pointed to by
.Fa iv .
.Pp
A driver calls
.Fn crypto_done
to mark the request

View File

@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd March 27, 2020
.Dd April 20, 2020
.Dt CRYPTO_REQUEST 9
.Os
.Sh NAME
@ -226,16 +226,6 @@ and
.Fa crp_digest_start
should be left as zero.
.Pp
An encryption request using an IV stored in the IV region may set
.Dv CRYPTO_F_IV_GENERATE
in
.Fa crp_flags
to request that the driver generate a random IV.
Note that
.Dv CRYPTO_F_IV_GENERATE
cannot be used with decryption operations or in combination with
.Dv CRYPTO_F_IV_SEPARATE .
.Pp
Requests that store part, but not all, of the IV in the data buffer should
store the partial IV in the data buffer and pass the full IV separately in
.Fa crp_iv .

View File

@ -704,14 +704,7 @@ aesni_cipher_crypt(struct aesni_session *ses, struct cryptop *crp,
aesni_cipher_setup_common(ses, csp, crp->crp_cipher_key,
csp->csp_cipher_klen);
/* Setup iv */
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(iv, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen, iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(iv, crp->crp_iv, csp->csp_ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen, iv);
crypto_read_iv(crp, iv);
switch (csp->csp_cipher_alg) {
case CRYPTO_AES_CBC:

View File

@ -335,14 +335,7 @@ armv8_crypto_cipher_process(struct armv8_crypto_session *ses,
panic("armv8: new cipher key");
}
/* Setup iv */
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(iv, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen, iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(iv, crp->crp_iv, csp->csp_ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen, iv);
crypto_read_iv(crp, iv);
/* Do work */
switch (csp->csp_cipher_alg) {

View File

@ -1353,13 +1353,7 @@ ccp_collect_iv(struct cryptop *crp, const struct crypto_session_params *csp,
char *iv)
{
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(iv, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen, iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(iv, crp->crp_iv, csp->csp_ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen, iv);
crypto_read_iv(crp, iv);
/*
* If the input IV is 12 bytes, append an explicit counter of 1.

View File

@ -209,13 +209,7 @@ padlock_cipher_process(struct padlock_session *ses, struct cryptop *crp,
cw->cw_filler2 = 0;
cw->cw_filler3 = 0;
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(iv, AES_BLOCK_LEN, 0);
crypto_copyback(crp, crp->crp_iv_start, AES_BLOCK_LEN, iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(iv, crp->crp_iv, AES_BLOCK_LEN);
else
crypto_copydata(crp, crp->crp_iv_start, AES_BLOCK_LEN, iv);
crypto_read_iv(crp, iv);
if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
cw->cw_direction = PADLOCK_DIRECTION_ENCRYPT;

View File

@ -1791,17 +1791,8 @@ cesa_process(device_t dev, struct cryptop *crp, int hint)
CESA_LOCK(sc, sessions);
cesa_sync_desc(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
if (csp->csp_cipher_alg != 0) {
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(cr->cr_csd->csd_iv, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen,
cr->cr_csd->csd_iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(cr->cr_csd->csd_iv, crp->crp_iv, csp->csp_ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen,
cr->cr_csd->csd_iv);
}
if (csp->csp_cipher_alg != 0)
crypto_read_iv(crp, cr->cr_csd->csd_iv);
if (crp->crp_cipher_key != NULL) {
memcpy(cs->cs_key, crp->crp_cipher_key,

View File

@ -665,19 +665,7 @@ ccr_blkcipher(struct ccr_softc *sc, struct ccr_session *s, struct cryptop *crp)
crwr = wrtod(wr);
memset(crwr, 0, wr_len);
/*
* Read the existing IV from the request or generate a random
* one if none is provided.
*/
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(iv, s->blkcipher.iv_len, 0);
crypto_copyback(crp, crp->crp_iv_start, s->blkcipher.iv_len,
iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(iv, crp->crp_iv, s->blkcipher.iv_len);
else
crypto_copydata(crp, crp->crp_iv_start, s->blkcipher.iv_len,
iv);
crypto_read_iv(crp, iv);
/* Zero the remainder of the IV for AES-XTS. */
memset(iv + s->blkcipher.iv_len, 0, iv_len - s->blkcipher.iv_len);
@ -968,19 +956,7 @@ ccr_eta(struct ccr_softc *sc, struct ccr_session *s, struct cryptop *crp)
crwr = wrtod(wr);
memset(crwr, 0, wr_len);
/*
* Read the existing IV from the request or generate a random
* one if none is provided.
*/
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(iv, s->blkcipher.iv_len, 0);
crypto_copyback(crp, crp->crp_iv_start, s->blkcipher.iv_len,
iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(iv, crp->crp_iv, s->blkcipher.iv_len);
else
crypto_copydata(crp, crp->crp_iv_start, s->blkcipher.iv_len,
iv);
crypto_read_iv(crp, iv);
/* Zero the remainder of the IV for AES-XTS. */
memset(iv + s->blkcipher.iv_len, 0, iv_len - s->blkcipher.iv_len);

View File

@ -659,13 +659,7 @@ glxsb_crypto_encdec(struct cryptop *crp, struct glxsb_session *ses,
else
control = SB_CTL_DEC;
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(op_iv, sizeof(op_iv), 0);
crypto_copyback(crp, crp->crp_iv_start, sizeof(op_iv), op_iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(op_iv, crp->crp_iv, sizeof(op_iv));
else
crypto_copydata(crp, crp->crp_iv_start, sizeof(op_iv), op_iv);
crypto_read_iv(crp, op_iv);
offset = 0;
tlen = crp->crp_payload_length;

View File

@ -2431,7 +2431,7 @@ hifn_process(device_t dev, struct cryptop *crp, int hint)
struct hifn_softc *sc = device_get_softc(dev);
struct hifn_command *cmd = NULL;
const void *mackey;
int err, ivlen, keylen;
int err, keylen;
struct hifn_session *ses;
ses = crypto_get_driver_session(crp->crp_session);
@ -2485,18 +2485,8 @@ hifn_process(device_t dev, struct cryptop *crp, int hint)
err = EINVAL;
goto errout;
}
if (csp->csp_cipher_alg != CRYPTO_ARC4) {
ivlen = csp->csp_ivlen;
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(cmd->iv, ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, ivlen,
cmd->iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(cmd->iv, crp->crp_iv, ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, ivlen,
cmd->iv);
}
if (csp->csp_cipher_alg != CRYPTO_ARC4)
crypto_read_iv(crp, cmd->iv);
if (crp->crp_cipher_key != NULL)
cmd->ck = crp->crp_cipher_key;

View File

@ -894,16 +894,7 @@ safe_process(device_t dev, struct cryptop *crp, int hint)
* in the state record and set the hash/crypt offset to
* copy both the header+IV.
*/
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(re->re_sastate.sa_saved_iv, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen,
re->re_sastate.sa_saved_iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(re->re_sastate.sa_saved_iv, crp->crp_iv,
csp->csp_ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen,
re->re_sastate.sa_saved_iv);
crypto_read_iv(crp, re->re_sastate.sa_saved_iv);
cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {

View File

@ -1285,18 +1285,8 @@ sec_process(device_t dev, struct cryptop *crp, int hint)
desc->sd_error = 0;
desc->sd_crp = crp;
if (csp->csp_cipher_alg != 0) {
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(desc->sd_desc->shd_iv, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen,
desc->sd_desc->shd_iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(desc->sd_desc->shd_iv, crp->crp_iv,
csp->csp_ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen,
desc->sd_desc->shd_iv);
}
if (csp->csp_cipher_alg != 0)
crypto_read_iv(crp, desc->sd_desc->shd_iv);
if (crp->crp_cipher_key != NULL)
memcpy(ses->ss_key, crp->crp_cipher_key, csp->csp_cipher_klen);

View File

@ -1043,15 +1043,7 @@ ubsec_process(device_t dev, struct cryptop *crp, int hint)
ctx.pc_flags |= htole16(UBS_PKTCTX_ENC_3DES);
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(ctx.pc_iv, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start,
csp->csp_ivlen, ctx.pc_iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(ctx.pc_iv, crp->crp_iv, csp->csp_ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen,
ctx.pc_iv);
crypto_read_iv(crp, ctx.pc_iv);
if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
ctx.pc_flags |= htole16(UBS_PKTCTX_INBOUND);

View File

@ -365,12 +365,7 @@ cryptocteon_process(device_t dev, struct cryptop *crp, int hint)
}
if (csp->csp_cipher_alg != 0) {
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(iv_data, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen,
iv_data);
ivp = iv_data;
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
ivp = crp->crp_iv;
else {
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen,

View File

@ -470,11 +470,7 @@ xlp_copyiv(struct xlp_sec_softc *sc, struct xlp_sec_command *cmd,
crp = cmd->crp;
if (csp->csp_cipher_alg != CRYPTO_ARC4) {
if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(cmd->iv, csp->csp_ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen,
cmd->iv);
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(cmd->iv, crp->crp_iv, csp->csp_ivlen);
}
}

View File

@ -1280,14 +1280,6 @@ crp_sanity(struct cryptop *crp)
("invalid ETA op %x", crp->crp_op));
break;
}
KASSERT((crp->crp_flags & CRYPTO_F_IV_GENERATE) == 0 ||
crp->crp_op == CRYPTO_OP_ENCRYPT ||
crp->crp_op == (CRYPTO_OP_ENCRYPT | CRYPTO_OP_COMPUTE_DIGEST),
("IV_GENERATE set for non-encryption operation %x", crp->crp_op));
KASSERT((crp->crp_flags &
(CRYPTO_F_IV_SEPARATE | CRYPTO_F_IV_GENERATE)) !=
(CRYPTO_F_IV_SEPARATE | CRYPTO_F_IV_GENERATE),
("crp with both IV_SEPARATE and IV_GENERATE set"));
KASSERT(crp->crp_buf_type >= CRYPTO_BUF_CONTIG &&
crp->crp_buf_type <= CRYPTO_BUF_MBUF,
("invalid crp buffer type %d", crp->crp_buf_type));
@ -1305,9 +1297,8 @@ crp_sanity(struct cryptop *crp)
("AAD region in request not supporting AAD"));
}
if (csp->csp_ivlen == 0) {
KASSERT((crp->crp_flags &
(CRYPTO_F_IV_SEPARATE | CRYPTO_F_IV_GENERATE)) == 0,
("IV_GENERATE or IV_SEPARATE set when IV isn't used"));
KASSERT((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0,
("IV_SEPARATE set when IV isn't used"));
KASSERT(crp->crp_iv_start == 0,
("crp_iv_start set when IV isn't used"));
} else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE) {
@ -1361,8 +1352,6 @@ crypto_dispatch(struct cryptop *crp)
crp_sanity(crp);
#endif
/* TODO: Handle CRYPTO_F_IV_GENERATE so drivers don't have to. */
cryptostats.cs_ops++;
#ifdef CRYPTO_TIMING

View File

@ -454,7 +454,6 @@ struct cryptop {
* if CRYPTO_F_ASYNC flags is set
*/
#define CRYPTO_F_IV_SEPARATE 0x0200 /* Use crp_iv[] as IV. */
#define CRYPTO_F_IV_GENERATE 0x0400 /* Generate a random IV and store. */
int crp_op;
@ -611,5 +610,17 @@ int crypto_apply(struct cryptop *crp, int off, int len,
void *crypto_contiguous_subsegment(struct cryptop *crp, size_t skip,
size_t len);
static __inline void
crypto_read_iv(struct cryptop *crp, void *iv)
{
const struct crypto_session_params *csp;
csp = crypto_get_params(crp->crp_session);
if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
memcpy(iv, crp->crp_iv, csp->csp_ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen, iv);
}
#endif /* _KERNEL */
#endif /* _CRYPTO_CRYPTO_H_ */

View File

@ -133,14 +133,7 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp)
(crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
return (EINVAL);
/* IV explicitly provided ? */
if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
bcopy(crp->crp_iv, iv, ivlen);
else if (crp->crp_flags & CRYPTO_F_IV_GENERATE) {
arc4rand(iv, ivlen, 0);
crypto_copyback(crp, crp->crp_iv_start, ivlen, iv);
} else
crypto_copydata(crp, crp->crp_iv_start, ivlen, iv);
crypto_read_iv(crp, iv);
if (crp->crp_cipher_key != NULL) {
if (sw->sw_kschedule)
@ -510,15 +503,9 @@ swcr_gmac(struct swcr_session *ses, struct cryptop *crp)
bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
blksz = axf->blocksize;
if (crp->crp_flags & CRYPTO_F_IV_GENERATE)
return (EINVAL);
/* Initialize the IV */
ivlen = AES_GCM_IV_LEN;
if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
bcopy(crp->crp_iv, iv, ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, ivlen, iv);
crypto_read_iv(crp, iv);
axf->Reinit(&ctx, iv, ivlen);
for (i = 0; i < crp->crp_payload_length; i += blksz) {
@ -669,15 +656,9 @@ swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp)
bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
blksz = axf->blocksize;
if (crp->crp_flags & CRYPTO_F_IV_GENERATE)
return (EINVAL);
/* Initialize the IV */
ivlen = AES_CCM_IV_LEN;
if (crp->crp_flags & CRYPTO_F_IV_SEPARATE)
bcopy(crp->crp_iv, iv, ivlen);
else
crypto_copydata(crp, crp->crp_iv_start, ivlen, iv);
crypto_read_iv(crp, iv);
/*
* AES CCM-CBC-MAC needs to know the length of both the auth