Author: jhb
Date: Mon Mar 11 21:35:56 2019
New Revision: 345027
URL: https://svnweb.freebsd.org/changeset/base/345027

Log:
  MFC 323891,323892: Support EtA requests via /dev/crypto.
  
  323891:
  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.
  
  323892:
  Support AEAD requests with non-GCM algorithms.
  
  In particular, support chaining an AES cipher with an HMAC for a request
  including AAD.  This permits submitting requests from userland to encrypt
  objects like IPSec packets using these algorithms.
  
  In the non-GCM case, the authentication crypto descriptor covers both the
  AAD and the ciphertext.  The GCM case remains unchanged.  This matches
  the requests created internally in IPSec.  For the non-GCM case, the
  COP_F_CIPHER_FIRST is also supported since the ordering matters.
  
  Note that while this can be used to simulate IPSec requests from userland,
  this ioctl cannot currently be used to perform TLS requests using AES-CBC
  and MAC-before-encrypt.
  
  Sponsored by: Chelsio Communications

Modified:
  stable/11/share/man/man4/crypto.4
  stable/11/sys/opencrypto/cryptodev.c
  stable/11/sys/opencrypto/cryptodev.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/share/man/man4/crypto.4
==============================================================================
--- stable/11/share/man/man4/crypto.4   Mon Mar 11 21:00:58 2019        
(r345026)
+++ stable/11/share/man/man4/crypto.4   Mon Mar 11 21:35:56 2019        
(r345027)
@@ -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 {

Modified: stable/11/sys/opencrypto/cryptodev.c
==============================================================================
--- stable/11/sys/opencrypto/cryptodev.c        Mon Mar 11 21:00:58 2019        
(r345026)
+++ stable/11/sys/opencrypto/cryptodev.c        Mon Mar 11 21:35:56 2019        
(r345027)
@@ -755,18 +755,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,
@@ -941,8 +945,13 @@ cryptodev_aead(
                goto bail;
        }
 
-       crda = crp->crp_desc;
-       crde = crda->crd_next;
+       if (caead->flags & COP_F_CIPHER_FIRST) {
+               crde = crp->crp_desc;
+               crda = crde->crd_next;
+       } else {
+               crda = crp->crp_desc;
+               crde = crda->crd_next;
+       }
 
        if ((error = copyin(caead->aad, cse->uio.uio_iov[0].iov_base,
            caead->aadlen))) {
@@ -956,8 +965,16 @@ cryptodev_aead(
                goto bail;
        }
 
+       /*
+        * For GCM, crd_len covers only the AAD.  For other ciphers
+        * chained with an HMAC, crd_len covers both the AAD and the
+        * cipher text.
+        */
        crda->crd_skip = 0;
-       crda->crd_len = caead->aadlen;
+       if (cse->cipher == CRYPTO_AES_NIST_GCM_16)
+               crda->crd_len = caead->aadlen;
+       else
+               crda->crd_len = caead->aadlen + caead->len;
        crda->crd_inject = caead->aadlen + caead->len;
 
        crda->crd_alg = cse->mac;

Modified: stable/11/sys/opencrypto/cryptodev.h
==============================================================================
--- stable/11/sys/opencrypto/cryptodev.h        Mon Mar 11 21:00:58 2019        
(r345026)
+++ stable/11/sys/opencrypto/cryptodev.h        Mon Mar 11 21:35:56 2019        
(r345027)
@@ -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;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to