git: 16676123fc85 - main - cryptodev: Permit explicit IV/nonce and MAC/tag lengths.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Wed, 06 Oct 2021 21:10:26 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=16676123fc85233334983e0071cb446357abec8d

commit 16676123fc85233334983e0071cb446357abec8d
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2021-10-06 21:08:46 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2021-10-06 21:08:46 +0000

    cryptodev: Permit explicit IV/nonce and MAC/tag lengths.
    
    Add 'ivlen' and 'maclen' fields to the structure used for CIOGSESSION2
    to specify the explicit IV/nonce and MAC/tag lengths for crypto
    sessions.  If these fields are zero, the default lengths are used.
    
    This permits selecting an alternate nonce length for AEAD ciphers such
    as AES-CCM which support multiple nonce leengths.  It also supports
    truncated MACs as input to AEAD or ETA requests.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D32107
---
 share/man/man4/crypto.4    | 24 ++++++++++++++++++++----
 sys/opencrypto/cryptodev.c | 29 +++++++++++++++++++++++++++--
 sys/opencrypto/cryptodev.h |  9 +++++++--
 3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/share/man/man4/crypto.4 b/share/man/man4/crypto.4
index 56fd4f484c3b..5617bacd904a 100644
--- a/share/man/man4/crypto.4
+++ b/share/man/man4/crypto.4
@@ -1,13 +1,16 @@
 .\"	$NetBSD: crypto.4,v 1.24 2014/01/27 21:23:59 pgoyette Exp $
 .\"
 .\" Copyright (c) 2008 The NetBSD Foundation, Inc.
-.\" Copyright (c) 2014 The FreeBSD Foundation
+.\" Copyright (c) 2014-2021 The FreeBSD Foundation
 .\" All rights reserved.
 .\"
 .\" Portions of this documentation were written by John-Mark Gurney
 .\" under sponsorship of the FreeBSD Foundation and
 .\" Rubicon Communications, LLC (Netgate).
 .\"
+.\" Portions of this documentation were written by Ararat River
+.\" Consulting, LLC under sponsorship of the FreeBSD Foundation.
+.\"
 .\" This code is derived from software contributed to The NetBSD Foundation
 .\" by Coyote Point Systems, Inc.
 .\"
@@ -60,7 +63,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 12, 2021
+.Dd October 6, 2021
 .Dt CRYPTO 4
 .Os
 .Sh NAME
@@ -251,14 +254,27 @@ struct session2_op {
 
     uint32_t ses;	/* returns: ses # */
     int	crid;		/* driver id + flags (rw) */
-    int	pad[4];		/* for future expansion */
+    int ivlen;		/* length of nonce/IV */
+    int maclen;		/* length of MAC/tag */
+    int	pad[2];		/* for future expansion */
 };
 
 .Ed
-This request is similar to CIOGSESSION except that
+This request is similar to CIOGSESSION but adds additional fields.
+.Pp
 .Fa sessp-\*[Gt]crid
 requests either a specific crypto device or a class of devices (software vs
 hardware).
+.Pp
+.Fa sessp-\*[Gt]ivlen
+specifies the length of the IV or nonce supplied with each request.
+If this field is set to zero, the default IV or nonce length is used.
+.Pp
+.Fa sessp-\*[Gt]maclen
+specifies the length of the MAC or authentication tag supplied or computed by
+each request.
+If this field is set to zero, the full MAC is used.
+.Pp
 The
 .Fa sessp-\*[Gt]pad
 field must be initialized to zero.
diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c
index 9a4db6f453bc..6614c8f60676 100644
--- a/sys/opencrypto/cryptodev.c
+++ b/sys/opencrypto/cryptodev.c
@@ -103,7 +103,9 @@ struct session2_op32 {
 	uint32_t	mackey;
 	uint32_t	ses;
 	int		crid;
-	int		pad[4];
+	int		ivlen;
+	int		maclen;
+	int		pad[2];
 };
 
 struct crypt_op32 {
@@ -156,6 +158,8 @@ session2_op_from_32(const struct session2_op32 *from, struct session2_op *to)
 
 	session_op_from_32((const struct session_op32 *)from, to);
 	CP(*from, *to, crid);
+	CP(*from, *to, ivlen);
+	CP(*from, *to, maclen);
 }
 
 static void
@@ -597,6 +601,25 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
 			csp.csp_ivlen = AES_CCM_IV_LEN;
 	}
 
+	if (sop->ivlen != 0) {
+		if (csp.csp_ivlen == 0) {
+			CRYPTDEB("does not support an IV");
+			error = EINVAL;
+			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+			goto bail;
+		}
+		csp.csp_ivlen = sop->ivlen;
+	}
+	if (sop->maclen != 0) {
+		if (!(thash != NULL || csp.csp_mode == CSP_MODE_AEAD)) {
+			CRYPTDEB("does not support a MAC");
+			error = EINVAL;
+			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+			goto bail;
+		}
+		csp.csp_auth_mlen = sop->maclen;
+	}
+
 	crid = sop->crid;
 	error = checkforsoftware(&crid);
 	if (error) {
@@ -618,7 +641,9 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
 	cse->mackey = mackey;
 	cse->cses = cses;
 	cse->txform = txform;
-	if (thash != NULL)
+	if (sop->maclen != 0)
+		cse->hashsize = sop->maclen;
+	else if (thash != NULL)
 		cse->hashsize = thash->hashsize;
 	else if (csp.csp_cipher_alg == CRYPTO_AES_NIST_GCM_16)
 		cse->hashsize = AES_GMAC_HASH_LEN;
diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h
index 79dec8c44f51..b3c79a48f632 100644
--- a/sys/opencrypto/cryptodev.h
+++ b/sys/opencrypto/cryptodev.h
@@ -23,13 +23,16 @@
  * PURPOSE.
  *
  * Copyright (c) 2001 Theo de Raadt
- * 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.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -241,7 +244,9 @@ struct session2_op {
 
   	uint32_t	ses;		/* returns: session # */ 
 	int		crid;		/* driver id + flags (rw) */
-	int		pad[4];		/* for future expansion */
+	int		ivlen;		/* length of nonce/IV */
+	int		maclen;		/* length of MAC/tag */
+	int		pad[2];		/* for future expansion */
 };
 
 struct crypt_op {