aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2021-02-18 17:21:56 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2021-02-18 17:26:00 +0000
commitfc8fc743d89388c0c5b97a491428fab2b36beac8 (patch)
tree5c9add4ab60f162925be8186ab6f786ba3be07de /sys
parentcd6114d1a65cda09410e91ed4dc220df825a8ba2 (diff)
downloadsrc-fc8fc743d89388c0c5b97a491428fab2b36beac8.tar.gz
src-fc8fc743d89388c0c5b97a491428fab2b36beac8.zip
Add an OCF algorithm for ChaCha20-Poly1305 AEAD.
Note that this algorithm implements the mode defined in RFC 8439. Reviewed by: cem Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D27836
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files1
-rw-r--r--sys/modules/crypto/Makefile1
-rw-r--r--sys/opencrypto/crypto.c12
-rw-r--r--sys/opencrypto/cryptodev.c11
-rw-r--r--sys/opencrypto/cryptodev.h5
-rw-r--r--sys/opencrypto/xform_chacha20_poly1305.c41
-rw-r--r--sys/opencrypto/xform_enc.h1
7 files changed, 65 insertions, 7 deletions
diff --git a/sys/conf/files b/sys/conf/files
index f1a76b0575d9..8705287e89f1 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4925,6 +4925,7 @@ opencrypto/gfmult.c optional crypto | ipsec | ipsec_support
opencrypto/rmd160.c optional crypto | ipsec | ipsec_support
opencrypto/xform.c optional crypto | ipsec | ipsec_support
opencrypto/xform_cbc_mac.c optional crypto
+opencrypto/xform_chacha20_poly1305.c optional crypto
opencrypto/xform_poly1305.c optional crypto \
compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium"
contrib/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \
diff --git a/sys/modules/crypto/Makefile b/sys/modules/crypto/Makefile
index 01ade43a0e51..89af6ab8fc61 100644
--- a/sys/modules/crypto/Makefile
+++ b/sys/modules/crypto/Makefile
@@ -67,6 +67,7 @@ SRCS += randombytes.c
CFLAGS.randombytes.c += -I${LIBSODIUM_INC} -I${LIBSODIUM_COMPAT}
SRCS += utils.c
CFLAGS.utils.c += -I${LIBSODIUM_INC} -I${LIBSODIUM_COMPAT}
+SRCS += xform_chacha20_poly1305.c
SRCS += opt_param.h cryptodev_if.h bus_if.h device_if.h
SRCS += opt_compat.h
diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c
index 3b489739f067..1c9d79af8c91 100644
--- a/sys/opencrypto/crypto.c
+++ b/sys/opencrypto/crypto.c
@@ -600,6 +600,8 @@ crypto_cipher(const struct crypto_session_params *csp)
return (&enc_xform_chacha20);
case CRYPTO_AES_CCM_16:
return (&enc_xform_ccm);
+ case CRYPTO_CHACHA20_POLY1305:
+ return (&enc_xform_chacha20_poly1305);
default:
return (NULL);
}
@@ -691,6 +693,7 @@ static enum alg_type {
[CRYPTO_POLY1305] = ALG_KEYED_DIGEST,
[CRYPTO_AES_CCM_CBC_MAC] = ALG_KEYED_DIGEST,
[CRYPTO_AES_CCM_16] = ALG_AEAD,
+ [CRYPTO_CHACHA20_POLY1305] = ALG_AEAD,
};
static enum alg_type
@@ -835,6 +838,7 @@ check_csp(const struct crypto_session_params *csp)
switch (csp->csp_cipher_alg) {
case CRYPTO_AES_NIST_GCM_16:
case CRYPTO_AES_CCM_16:
+ case CRYPTO_CHACHA20_POLY1305:
if (csp->csp_auth_mlen > 16)
return (false);
break;
@@ -1308,12 +1312,8 @@ crp_sanity(struct cryptop *crp)
crp->crp_op ==
(CRYPTO_OP_DECRYPT | CRYPTO_OP_VERIFY_DIGEST),
("invalid AEAD op %x", crp->crp_op));
- if (csp->csp_cipher_alg == CRYPTO_AES_NIST_GCM_16)
- KASSERT(crp->crp_flags & CRYPTO_F_IV_SEPARATE,
- ("GCM without a separate IV"));
- if (csp->csp_cipher_alg == CRYPTO_AES_CCM_16)
- KASSERT(crp->crp_flags & CRYPTO_F_IV_SEPARATE,
- ("CCM without a separate IV"));
+ KASSERT(crp->crp_flags & CRYPTO_F_IV_SEPARATE,
+ ("AEAD without a separate IV"));
break;
case CSP_MODE_ETA:
KASSERT(crp->crp_op ==
diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c
index 9bb95bcb21f0..ed7e3cfd0354 100644
--- a/sys/opencrypto/cryptodev.c
+++ b/sys/opencrypto/cryptodev.c
@@ -428,6 +428,9 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
case CRYPTO_AES_CCM_16:
txform = &enc_xform_ccm;
break;
+ case CRYPTO_CHACHA20_POLY1305:
+ txform = &enc_xform_chacha20_poly1305;
+ break;
default:
CRYPTDEB("invalid cipher");
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
@@ -586,6 +589,12 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
return (EINVAL);
}
csp.csp_mode = CSP_MODE_AEAD;
+ } else if (sop->cipher == CRYPTO_CHACHA20_POLY1305) {
+ if (sop->mac != 0) {
+ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+ return (EINVAL);
+ }
+ csp.csp_mode = CSP_MODE_AEAD;
} else if (txform != NULL && thash != NULL)
csp.csp_mode = CSP_MODE_ETA;
else if (txform != NULL)
@@ -679,6 +688,8 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
cse->hashsize = AES_GMAC_HASH_LEN;
else if (csp.csp_cipher_alg == CRYPTO_AES_CCM_16)
cse->hashsize = AES_CBC_MAC_HASH_LEN;
+ else if (csp.csp_cipher_alg == CRYPTO_CHACHA20_POLY1305)
+ cse->hashsize = POLY1305_HASH_LEN;
cse->ivsize = csp.csp_ivlen;
mtx_lock(&fcr->lock);
diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h
index 659599cb7d60..bd9e65eb9428 100644
--- a/sys/opencrypto/cryptodev.h
+++ b/sys/opencrypto/cryptodev.h
@@ -124,6 +124,7 @@
#define AES_CCM_IV_LEN 12
#define AES_XTS_IV_LEN 8
#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */
+#define CHACHA20_POLY1305_IV_LEN 12
/* Min and Max Encryption Key Sizes */
#define NULL_MIN_KEY 0
@@ -136,6 +137,7 @@
#define AES_XTS_MAX_KEY (2 * AES_MAX_KEY)
#define CAMELLIA_MIN_KEY 16
#define CAMELLIA_MAX_KEY 32
+#define CHACHA20_POLY1305_KEY 32
/* Maximum hash algorithm result length */
#define AALG_MAX_RESULT_LEN 64 /* Keep this updated */
@@ -184,7 +186,8 @@
#define CRYPTO_POLY1305 38
#define CRYPTO_AES_CCM_CBC_MAC 39 /* auth side */
#define CRYPTO_AES_CCM_16 40 /* cipher side */
-#define CRYPTO_ALGORITHM_MAX 40 /* Keep updated - see below */
+#define CRYPTO_CHACHA20_POLY1305 41 /* combined AEAD cipher per RFC 8439 */
+#define CRYPTO_ALGORITHM_MAX 41 /* Keep updated - see below */
#define CRYPTO_ALGO_VALID(x) ((x) >= CRYPTO_ALGORITHM_MIN && \
(x) <= CRYPTO_ALGORITHM_MAX)
diff --git a/sys/opencrypto/xform_chacha20_poly1305.c b/sys/opencrypto/xform_chacha20_poly1305.c
new file mode 100644
index 000000000000..e568e76cad51
--- /dev/null
+++ b/sys/opencrypto/xform_chacha20_poly1305.c
@@ -0,0 +1,41 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Netflix Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <crypto/chacha20/chacha.h>
+#include <opencrypto/xform_enc.h>
+
+struct enc_xform enc_xform_chacha20_poly1305 = {
+ .type = CRYPTO_CHACHA20_POLY1305,
+ .name = "ChaCha20-Poly1305",
+ .ctxsize = sizeof(struct chacha_ctx),
+ .blocksize = 1,
+ .native_blocksize = CHACHA_BLOCKLEN,
+ .ivsize = CHACHA20_POLY1305_IV_LEN,
+ .minkey = CHACHA20_POLY1305_KEY,
+ .maxkey = CHACHA20_POLY1305_KEY,
+};
+
diff --git a/sys/opencrypto/xform_enc.h b/sys/opencrypto/xform_enc.h
index b44f1ff0c270..e8325f20917b 100644
--- a/sys/opencrypto/xform_enc.h
+++ b/sys/opencrypto/xform_enc.h
@@ -81,6 +81,7 @@ extern struct enc_xform enc_xform_aes_nist_gmac;
extern struct enc_xform enc_xform_aes_xts;
extern struct enc_xform enc_xform_camellia;
extern struct enc_xform enc_xform_chacha20;
+extern struct enc_xform enc_xform_chacha20_poly1305;
extern struct enc_xform enc_xform_ccm;
struct aes_icm_ctx {