diff --git a/share/man/man7/crypto.7 b/share/man/man7/crypto.7 --- a/share/man/man7/crypto.7 +++ b/share/man/man7/crypto.7 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 20, 2021 +.Dd February 18, 2021 .Dt CRYPTO 7 .Os .Sh NAME @@ -161,6 +161,8 @@ AES Galois/Counter Mode .It Dv CRYPTO_AES_CCM_16 Ta 12 Ta 16, 24, 32 Ta 16 Ta AES Counter with CBC-MAC +.It Dv CRYPTO_CHACHA20_POLY1305 Ta 12 Ta 32 Ta 16 Ta +ChaCha20-Poly1305 .El .Sh SEE ALSO .Xr crypto 4 , diff --git a/sys/conf/files b/sys/conf/files --- a/sys/conf/files +++ b/sys/conf/files @@ -4925,6 +4925,7 @@ 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 --- a/sys/modules/crypto/Makefile +++ b/sys/modules/crypto/Makefile @@ -67,6 +67,7 @@ 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 --- a/sys/opencrypto/crypto.c +++ b/sys/opencrypto/crypto.c @@ -600,6 +600,8 @@ 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 @@ [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 @@ 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->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.h b/sys/opencrypto/cryptodev.h --- 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/cryptodev.c b/sys/opencrypto/cryptodev.c --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -428,6 +428,9 @@ 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 @@ 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->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/xform_chacha20_poly1305.c b/sys/opencrypto/xform_chacha20_poly1305.c new file mode 100644 --- /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 +#include + +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 --- a/sys/opencrypto/xform_enc.h +++ b/sys/opencrypto/xform_enc.h @@ -81,6 +81,7 @@ 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 {