From 2c907637bc0156bc30248c586cf4870f78ef8f84 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 22 Sep 2017 00:21:58 +0000 Subject: [PATCH] Add a new COP_F_CIPHER_FIRST flag for struct crypt_op. This requests that the cipher be performed before rather than after the HMAC when both are specified for a single operation. Reviewed by: cem Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D11757 --- share/man/man4/crypto.4 | 16 ++++++++++++++-- sys/opencrypto/cryptodev.c | 24 ++++++++++++++---------- sys/opencrypto/cryptodev.h | 3 ++- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/share/man/man4/crypto.4 b/share/man/man4/crypto.4 index 31edb7f0dbb0..e29b02789263 100644 --- a/share/man/man4/crypto.4 +++ b/share/man/man4/crypto.4 @@ -60,7 +60,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 15, 2015 +.Dd September 21, 2017 .Dt CRYPTO 4 .Os .Sh NAME @@ -127,7 +127,9 @@ Asymmetric operations do not use sessions. .It Submit requests, synchronously with .Dv CIOCCRYPT -(symmetric) +(symmetric), +.Dv CIOCCRYPTAEAD +(symmetric), or .Dv CIOCKEY (asymmetric). @@ -279,6 +281,16 @@ supplies the length of the input buffer; the fields .Fa cr_op-\*[Gt]iv supply the addresses of the input buffer, output buffer, one-way hash, and initialization vector, respectively. +If a session is using both a privacy algorithm and a hash algorithm, +the request will generate a hash of the input buffer before +generating the output buffer by default. +If the +.Dv COP_F_CIPHER_FIRST +flag is included in the +.Fa cr_op-\*[Gt]flags +field, +then the request will generate a hash of the output buffer after +executing the privacy algorithm. .It Dv CIOCCRYPTAEAD Fa struct crypt_aead *cr_aead .Bd -literal struct crypt_aead { diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c index 20ce0cbb6cb7..78d5deb05721 100644 --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -731,18 +731,22 @@ cryptodev_op( goto bail; } - if (cse->thash) { - crda = crp->crp_desc; - if (cse->txform) - crde = crda->crd_next; - } else { - if (cse->txform) + if (cse->thash && cse->txform) { + if (cop->flags & COP_F_CIPHER_FIRST) { crde = crp->crp_desc; - else { - SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); - error = EINVAL; - goto bail; + crda = crde->crd_next; + } else { + crda = crp->crp_desc; + crde = crda->crd_next; } + } else if (cse->thash) { + crda = crp->crp_desc; + } else if (cse->txform) { + crde = crp->crp_desc; + } else { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); + error = EINVAL; + goto bail; } if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h index ca584694b7c5..b9a7634298d5 100644 --- a/sys/opencrypto/cryptodev.h +++ b/sys/opencrypto/cryptodev.h @@ -238,7 +238,8 @@ struct crypt_op { #define COP_ENCRYPT 1 #define COP_DECRYPT 2 u_int16_t flags; -#define COP_F_BATCH 0x0008 /* Batch op if possible */ +#define COP_F_CIPHER_FIRST 0x0001 /* Cipher before MAC. */ +#define COP_F_BATCH 0x0008 /* Batch op if possible */ u_int len; c_caddr_t src; /* become iov[] inside kernel */ caddr_t dst;