From nobody Tue Jan 11 22:38:08 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id B2C81194C0CD; Tue, 11 Jan 2022 22:38:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JYQZS3S2gz4m1X; Tue, 11 Jan 2022 22:38:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 56FA721BD0; Tue, 11 Jan 2022 22:38:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 20BMc8tW075807; Tue, 11 Jan 2022 22:38:08 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 20BMc882075806; Tue, 11 Jan 2022 22:38:08 GMT (envelope-from git) Date: Tue, 11 Jan 2022 22:38:08 GMT Message-Id: <202201112238.20BMc882075806@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: 8f35841f1f35 - main - crypto: Add support for the XChaCha20-Poly1305 AEAD cipher. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 8f35841f1f35cce332e94f0a3a69f51e2eb5e762 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1641940688; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+6PYMWxm/4/wRvhZAniL1XC8kjWyAOMYHqsQ+Wqyy5k=; b=rIEld0tFvssoksx2aahBQNKnRHDbt9nI2K8QOK4kph30IR1xVkfge/Y8xSd/h99A18gRPV KAH/Iep/F2lidS0yye0zYJUr78SB8/RB8IL2Fn2CZFauIo0dki4ogjOkDC7069q5n0dOb/ 1MkcYLyyx2joZ+rnyMIDqjzT+Z/S0XapepZ3Djy/+oob6npmx/0Zl3kWv3NiF8S9VippQB f81Iff+VH6OMBl1NY3nupFDabjSoKXOBQUh4FrOsYOhu1I4QC14rj53f74q4qEgiirUvDN E7DFx5CcWTCZn6mrdbK20Wj/gWPt/sj6vhDFjfbnOGSbIeka3OPBeN9xrvZSzw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1641940688; a=rsa-sha256; cv=none; b=Le1HItV+3d5wm9tb/wRGwcyvGpJmFVk4DHB/VfHdjZPFXzHW72StBHpgvfIDdUeMA8eW3d wUHvlbY2A6ZNz08Kc1adGUnzxov6lVqnjvBASFbF9Xf5Ua3u+lN5agoL86K5YpKR3L9z2Z TwTe/DsWwpc6fDJ1JxLXmx7f6/0cLCimnM4Hh4VMk7kAmz5JvsYMyQz9YZlYdTdhZtKsN9 El2H7rHFA+nTiXsve4zr6LAfAjGxElQRqK42adgKTL3H8Dxa7WQvepEzRl8qofmrZwCgIJ wH5S8XW9bPgwpd86+KuEdca92V+QYupPPGQkDGgkmpZ9GRXqAWEzg4Fel+utSA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=8f35841f1f35cce332e94f0a3a69f51e2eb5e762 commit 8f35841f1f35cce332e94f0a3a69f51e2eb5e762 Author: John Baldwin AuthorDate: 2022-01-11 22:16:05 +0000 Commit: John Baldwin CommitDate: 2022-01-11 22:16:41 +0000 crypto: Add support for the XChaCha20-Poly1305 AEAD cipher. This cipher is a wrapper around the ChaCha20-Poly1305 AEAD cipher which accepts a larger nonce. Part of the nonce is used along with the key as an input to HChaCha20 to generate a derived key used for ChaCha20-Poly1305. This cipher is used by WireGuard. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33523 --- share/man/man7/crypto.7 | 5 ++- sys/opencrypto/crypto.c | 9 +++++ sys/opencrypto/cryptodev.h | 5 ++- sys/opencrypto/cryptosoft.c | 6 ++++ sys/opencrypto/xform_chacha20_poly1305.c | 62 ++++++++++++++++++++++++++++++++ sys/opencrypto/xform_enc.h | 1 + 6 files changed, 86 insertions(+), 2 deletions(-) diff --git a/share/man/man7/crypto.7 b/share/man/man7/crypto.7 index c7af22af4deb..01ff339fa31f 100644 --- a/share/man/man7/crypto.7 +++ b/share/man/man7/crypto.7 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 6, 2021 +.Dd January 11, 2022 .Dt CRYPTO 7 .Os .Sh NAME @@ -170,6 +170,9 @@ AES Counter with CBC-MAC .It Dv CRYPTO_CHACHA20_POLY1305 Ta 12, 8 Ta 32 Ta 16 Ta ChaCha20-Poly1305 .El +.It Dv CRYPTO_XCHACHA20_POLY1305 Ta 24 Ta 32 Ta 16 Ta +XChaCha20-Poly1305 +.El .Sh SEE ALSO .Xr crypto 4 , .Xr crypto 9 diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c index acc7b8d2ecb8..0b2c250a7af2 100644 --- a/sys/opencrypto/crypto.c +++ b/sys/opencrypto/crypto.c @@ -579,6 +579,8 @@ crypto_cipher(const struct crypto_session_params *csp) return (&enc_xform_ccm); case CRYPTO_CHACHA20_POLY1305: return (&enc_xform_chacha20_poly1305); + case CRYPTO_XCHACHA20_POLY1305: + return (&enc_xform_xchacha20_poly1305); default: return (NULL); } @@ -671,6 +673,7 @@ static enum alg_type { [CRYPTO_AES_CCM_CBC_MAC] = ALG_KEYED_DIGEST, [CRYPTO_AES_CCM_16] = ALG_AEAD, [CRYPTO_CHACHA20_POLY1305] = ALG_AEAD, + [CRYPTO_XCHACHA20_POLY1305] = ALG_AEAD, }; static enum alg_type @@ -865,6 +868,12 @@ check_csp(const struct crypto_session_params *csp) if (csp->csp_auth_mlen > POLY1305_HASH_LEN) return (false); break; + case CRYPTO_XCHACHA20_POLY1305: + if (csp->csp_ivlen != XCHACHA20_POLY1305_IV_LEN) + return (false); + if (csp->csp_auth_mlen > POLY1305_HASH_LEN) + return (false); + break; } break; case CSP_MODE_ETA: diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h index ed396ed86912..b2eb01566f4f 100644 --- a/sys/opencrypto/cryptodev.h +++ b/sys/opencrypto/cryptodev.h @@ -129,6 +129,7 @@ #define AES_XTS_IV_LEN 8 #define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */ #define CHACHA20_POLY1305_IV_LEN 12 +#define XCHACHA20_POLY1305_IV_LEN 24 /* Min and Max Encryption Key Sizes */ #define NULL_MIN_KEY 0 @@ -142,6 +143,7 @@ #define CAMELLIA_MIN_KEY 16 #define CAMELLIA_MAX_KEY 32 #define CHACHA20_POLY1305_KEY 32 +#define XCHACHA20_POLY1305_KEY 32 /* Maximum hash algorithm result length */ #define AALG_MAX_RESULT_LEN 64 /* Keep this updated */ @@ -191,7 +193,8 @@ #define CRYPTO_AES_CCM_CBC_MAC 39 /* auth side */ #define CRYPTO_AES_CCM_16 40 /* cipher side */ #define CRYPTO_CHACHA20_POLY1305 41 /* combined AEAD cipher per RFC 8439 */ -#define CRYPTO_ALGORITHM_MAX 41 /* Keep updated - see below */ +#define CRYPTO_XCHACHA20_POLY1305 42 +#define CRYPTO_ALGORITHM_MAX 42 /* Keep updated - see below */ #define CRYPTO_ALGO_VALID(x) ((x) >= CRYPTO_ALGORITHM_MIN && \ (x) <= CRYPTO_ALGORITHM_MAX) diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index 43fefae99c40..65eb29bdfd91 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -1330,6 +1330,7 @@ swcr_probesession(device_t dev, const struct crypto_session_params *csp) case CRYPTO_AES_NIST_GCM_16: case CRYPTO_AES_CCM_16: case CRYPTO_CHACHA20_POLY1305: + case CRYPTO_XCHACHA20_POLY1305: return (EINVAL); default: if (!swcr_cipher_supported(csp)) @@ -1355,6 +1356,7 @@ swcr_probesession(device_t dev, const struct crypto_session_params *csp) } break; case CRYPTO_CHACHA20_POLY1305: + case CRYPTO_XCHACHA20_POLY1305: break; default: return (EINVAL); @@ -1366,6 +1368,7 @@ swcr_probesession(device_t dev, const struct crypto_session_params *csp) case CRYPTO_AES_NIST_GCM_16: case CRYPTO_AES_CCM_16: case CRYPTO_CHACHA20_POLY1305: + case CRYPTO_XCHACHA20_POLY1305: return (EINVAL); } switch (csp->csp_auth_alg) { @@ -1422,6 +1425,7 @@ swcr_newsession(device_t dev, crypto_session_t cses, case CRYPTO_AES_NIST_GCM_16: case CRYPTO_AES_CCM_16: case CRYPTO_CHACHA20_POLY1305: + case CRYPTO_XCHACHA20_POLY1305: panic("bad cipher algo"); #endif default: @@ -1446,6 +1450,7 @@ swcr_newsession(device_t dev, crypto_session_t cses, ses->swcr_process = swcr_ccm; break; case CRYPTO_CHACHA20_POLY1305: + case CRYPTO_XCHACHA20_POLY1305: error = swcr_setup_aead(ses, csp); if (error == 0) ses->swcr_process = swcr_chacha20_poly1305; @@ -1462,6 +1467,7 @@ swcr_newsession(device_t dev, crypto_session_t cses, case CRYPTO_AES_NIST_GCM_16: case CRYPTO_AES_CCM_16: case CRYPTO_CHACHA20_POLY1305: + case CRYPTO_XCHACHA20_POLY1305: panic("bad eta cipher algo"); } switch (csp->csp_auth_alg) { diff --git a/sys/opencrypto/xform_chacha20_poly1305.c b/sys/opencrypto/xform_chacha20_poly1305.c index cb1fc4cea88d..eec82681bd2c 100644 --- a/sys/opencrypto/xform_chacha20_poly1305.c +++ b/sys/opencrypto/xform_chacha20_poly1305.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -39,6 +40,12 @@ struct chacha20_poly1305_ctx { char nonce[CHACHA20_POLY1305_IV_LEN]; }; +struct xchacha20_poly1305_ctx { + struct chacha20_poly1305_ctx base_ctx; /* must be first */ + const void *key; + char derived_key[CHACHA20_POLY1305_KEY]; +}; + static int chacha20_poly1305_setkey(void *vctx, const uint8_t *key, int len) { @@ -144,3 +151,58 @@ const struct enc_xform enc_xform_chacha20_poly1305 = { .update = chacha20_poly1305_update, .final = chacha20_poly1305_final, }; + +static int +xchacha20_poly1305_setkey(void *vctx, const uint8_t *key, int len) +{ + struct xchacha20_poly1305_ctx *ctx = vctx; + + if (len != XCHACHA20_POLY1305_KEY) + return (EINVAL); + + ctx->key = key; + ctx->base_ctx.key = ctx->derived_key; + return (0); +} + +static void +xchacha20_poly1305_reinit(void *vctx, const uint8_t *iv, size_t ivlen) +{ + struct xchacha20_poly1305_ctx *ctx = vctx; + char nonce[CHACHA20_POLY1305_IV_LEN]; + + KASSERT(ivlen == XCHACHA20_POLY1305_IV_LEN, + ("%s: invalid nonce length", __func__)); + + /* + * Use HChaCha20 to derive the internal key used for + * ChaCha20-Poly1305. + */ + crypto_core_hchacha20(ctx->derived_key, iv, ctx->key, NULL); + + memset(nonce, 0, 4); + memcpy(nonce + 4, iv + crypto_core_hchacha20_INPUTBYTES, + sizeof(nonce) - 4); + chacha20_poly1305_reinit(&ctx->base_ctx, nonce, sizeof(nonce)); + explicit_bzero(nonce, sizeof(nonce)); +} + +const struct enc_xform enc_xform_xchacha20_poly1305 = { + .type = CRYPTO_XCHACHA20_POLY1305, + .name = "XChaCha20-Poly1305", + .ctxsize = sizeof(struct xchacha20_poly1305_ctx), + .blocksize = 1, + .native_blocksize = CHACHA20_NATIVE_BLOCK_LEN, + .ivsize = XCHACHA20_POLY1305_IV_LEN, + .minkey = XCHACHA20_POLY1305_KEY, + .maxkey = XCHACHA20_POLY1305_KEY, + .macsize = POLY1305_HASH_LEN, + .encrypt = chacha20_poly1305_crypt, + .decrypt = chacha20_poly1305_crypt, + .setkey = xchacha20_poly1305_setkey, + .reinit = xchacha20_poly1305_reinit, + .encrypt_last = chacha20_poly1305_crypt_last, + .decrypt_last = chacha20_poly1305_crypt_last, + .update = chacha20_poly1305_update, + .final = chacha20_poly1305_final, +}; diff --git a/sys/opencrypto/xform_enc.h b/sys/opencrypto/xform_enc.h index c998e06d4944..9364ff36431c 100644 --- a/sys/opencrypto/xform_enc.h +++ b/sys/opencrypto/xform_enc.h @@ -89,6 +89,7 @@ extern const struct enc_xform enc_xform_aes_xts; extern const struct enc_xform enc_xform_camellia; extern const struct enc_xform enc_xform_chacha20; extern const struct enc_xform enc_xform_chacha20_poly1305; +extern const struct enc_xform enc_xform_xchacha20_poly1305; extern const struct enc_xform enc_xform_ccm; struct aes_icm_ctx {