From nobody Wed Oct 06 21:10:24 2021 X-Original-To: dev-commits-src-main@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 4DEBF12D3D93; Wed, 6 Oct 2021 21:10:25 +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 4HPnD04Rdgz3HMj; Wed, 6 Oct 2021 21:10:24 +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 51C8726F62; Wed, 6 Oct 2021 21:10:24 +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 196LAOkP058746; Wed, 6 Oct 2021 21:10:24 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 196LAOV3058745; Wed, 6 Oct 2021 21:10:24 GMT (envelope-from git) Date: Wed, 6 Oct 2021 21:10:24 GMT Message-Id: <202110062110.196LAOV3058745@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: 1833d6042c9a - main - crypto: Permit variable-sized IVs for ciphers with a reinit hook. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@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: 1833d6042c9a0116e8a1198256fd8fbc99cb11ad Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=1833d6042c9a0116e8a1198256fd8fbc99cb11ad commit 1833d6042c9a0116e8a1198256fd8fbc99cb11ad Author: John Baldwin AuthorDate: 2021-10-06 21:08:46 +0000 Commit: John Baldwin CommitDate: 2021-10-06 21:08:46 +0000 crypto: Permit variable-sized IVs for ciphers with a reinit hook. Add a 'len' argument to the reinit hook in 'struct enc_xform' to permit support for AEAD ciphers such as AES-CCM and Chacha20-Poly1305 which support different nonce lengths. Reviewed by: markj Sponsored by: Chelsio Communications, The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32105 --- sys/crypto/chacha20/chacha-sw.c | 5 +++-- sys/dev/cxgbe/crypto/t4_crypto.c | 10 +++++++--- sys/opencrypto/cryptosoft.c | 20 +++++++++++--------- sys/opencrypto/xform_aes_icm.c | 22 ++++++++++++++-------- sys/opencrypto/xform_aes_xts.c | 7 +++++-- sys/opencrypto/xform_chacha20_poly1305.c | 5 ++++- sys/opencrypto/xform_enc.h | 2 +- 7 files changed, 45 insertions(+), 26 deletions(-) diff --git a/sys/crypto/chacha20/chacha-sw.c b/sys/crypto/chacha20/chacha-sw.c index b1bf0a106bfd..8041a3fee8a5 100644 --- a/sys/crypto/chacha20/chacha-sw.c +++ b/sys/crypto/chacha20/chacha-sw.c @@ -18,9 +18,10 @@ chacha20_xform_setkey(void *ctx, const uint8_t *key, int len) } static void -chacha20_xform_reinit(void *ctx, const uint8_t *iv) +chacha20_xform_reinit(void *ctx, const uint8_t *iv, size_t ivlen) { - + KASSERT(ivlen == CHACHA_NONCELEN + CHACHA_CTRLEN, + ("%s: invalid IV length", __func__)); chacha_ivsetup(ctx, iv + 8, iv); } diff --git a/sys/dev/cxgbe/crypto/t4_crypto.c b/sys/dev/cxgbe/crypto/t4_crypto.c index 490c984a9751..845bc3c29e38 100644 --- a/sys/dev/cxgbe/crypto/t4_crypto.c +++ b/sys/dev/cxgbe/crypto/t4_crypto.c @@ -1,8 +1,12 @@ /*- * Copyright (c) 2017 Chelsio Communications, Inc. + * Copyright (c) 2021 The FreeBSD Foundation * All rights reserved. * Written by: John Baldwin * + * 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: @@ -1458,7 +1462,7 @@ ccr_gcm_soft(struct ccr_session *s, struct cryptop *crp) } } - exf->reinit(kschedule, iv); + exf->reinit(kschedule, iv, sizeof(iv)); /* Do encryption with MAC */ for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) { @@ -1935,7 +1939,7 @@ ccr_ccm_soft(struct ccr_session *s, struct cryptop *crp) if (error) goto out; - exf->reinit(kschedule, iv); + exf->reinit(kschedule, iv, sizeof(iv)); /* Do encryption/decryption with MAC */ for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) { @@ -1970,7 +1974,7 @@ ccr_ccm_soft(struct ccr_session *s, struct cryptop *crp) error = 0; /* Tag matches, decrypt data. */ - exf->reinit(kschedule, iv); + exf->reinit(kschedule, iv, sizeof(iv)); for (i = 0; i < crp->crp_payload_length; i += sizeof(block)) { len = imin(crp->crp_payload_length - i, diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index ef927f117bcc..04a2b004799a 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -9,13 +9,16 @@ * supported the development of this code. * * Copyright (c) 2000, 2001 Angelos D. Keromytis - * 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. + * * Permission to use, copy, and modify this software with or without fee * is hereby granted, provided that this entire notice is included in * all source code copies of any software which is or includes a copy or @@ -106,7 +109,7 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp) const struct enc_xform *exf; struct swcr_encdec *sw; size_t inlen, outlen; - int i, blks, ivlen, resid; + int i, blks, resid; struct crypto_buffer_cursor cc_in, cc_out; const unsigned char *inblk; unsigned char *outblk; @@ -117,7 +120,7 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp) sw = &ses->swcr_encdec; exf = sw->sw_exf; - ivlen = exf->ivsize; + csp = crypto_get_params(crp->crp_session); if (exf->native_blocksize == 0) { /* Check for non-padded data */ @@ -133,7 +136,6 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp) return (EINVAL); if (crp->crp_cipher_key != NULL) { - csp = crypto_get_params(crp->crp_session); error = exf->setkey(sw->sw_kschedule, crp->crp_cipher_key, csp->csp_cipher_klen); if (error) @@ -147,7 +149,7 @@ swcr_encdec(struct swcr_session *ses, struct cryptop *crp) * xforms that provide a reinit method perform all IV * handling themselves. */ - exf->reinit(sw->sw_kschedule, iv); + exf->reinit(sw->sw_kschedule, iv, csp->csp_ivlen); } ivp = iv; @@ -534,7 +536,7 @@ swcr_gcm(struct swcr_session *ses, struct cryptop *crp) if (crp->crp_cipher_key != NULL) exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, crypto_get_params(crp->crp_session)->csp_cipher_klen); - exf->reinit(swe->sw_kschedule, iv); + exf->reinit(swe->sw_kschedule, iv, ivlen); /* Do encryption with MAC */ crypto_cursor_init(&cc_in, &crp->crp_buf); @@ -753,7 +755,7 @@ swcr_ccm(struct swcr_session *ses, struct cryptop *crp) if (crp->crp_cipher_key != NULL) exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, crypto_get_params(crp->crp_session)->csp_cipher_klen); - exf->reinit(swe->sw_kschedule, iv); + exf->reinit(swe->sw_kschedule, iv, ivlen); /* Do encryption/decryption with MAC */ crypto_cursor_init(&cc_in, &crp->crp_buf); @@ -824,7 +826,7 @@ swcr_ccm(struct swcr_session *ses, struct cryptop *crp) } /* tag matches, decrypt data */ - exf->reinit(swe->sw_kschedule, iv); + exf->reinit(swe->sw_kschedule, iv, ivlen); crypto_cursor_init(&cc_in, &crp->crp_buf); crypto_cursor_advance(&cc_in, crp->crp_payload_start); for (resid = crp->crp_payload_length; resid > blksz; @@ -915,7 +917,7 @@ swcr_chacha20_poly1305(struct swcr_session *ses, struct cryptop *crp) if (crp->crp_cipher_key != NULL) exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, csp->csp_cipher_klen); - exf->reinit(swe->sw_kschedule, crp->crp_iv); + exf->reinit(swe->sw_kschedule, crp->crp_iv, csp->csp_ivlen); /* Do encryption with MAC */ crypto_cursor_init(&cc_in, &crp->crp_buf); diff --git a/sys/opencrypto/xform_aes_icm.c b/sys/opencrypto/xform_aes_icm.c index 618b812ceebf..860dceda5232 100644 --- a/sys/opencrypto/xform_aes_icm.c +++ b/sys/opencrypto/xform_aes_icm.c @@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$"); static int aes_icm_setkey(void *, const uint8_t *, int); static void aes_icm_crypt(void *, const uint8_t *, uint8_t *); static void aes_icm_crypt_last(void *, const uint8_t *, uint8_t *, size_t); -static void aes_icm_reinit(void *, const uint8_t *); -static void aes_gcm_reinit(void *, const uint8_t *); -static void aes_ccm_reinit(void *, const uint8_t *); +static void aes_icm_reinit(void *, const uint8_t *, size_t); +static void aes_gcm_reinit(void *, const uint8_t *, size_t); +static void aes_ccm_reinit(void *, const uint8_t *, size_t); /* Encryption instances */ const struct enc_xform enc_xform_aes_icm = { @@ -114,20 +114,24 @@ const struct enc_xform enc_xform_ccm = { * Encryption wrapper routines. */ static void -aes_icm_reinit(void *key, const uint8_t *iv) +aes_icm_reinit(void *key, const uint8_t *iv, size_t ivlen) { struct aes_icm_ctx *ctx; ctx = key; - bcopy(iv, ctx->ac_block, AESICM_BLOCKSIZE); + KASSERT(ivlen <= sizeof(ctx->ac_block), + ("%s: ivlen too large", __func__)); + bcopy(iv, ctx->ac_block, ivlen); } static void -aes_gcm_reinit(void *key, const uint8_t *iv) +aes_gcm_reinit(void *key, const uint8_t *iv, size_t ivlen) { struct aes_icm_ctx *ctx; - aes_icm_reinit(key, iv); + KASSERT(ivlen == AES_GCM_IV_LEN, + ("%s: invalid IV length", __func__)); + aes_icm_reinit(key, iv, ivlen); ctx = key; /* GCM starts with 2 as counter 1 is used for final xor of tag. */ @@ -136,10 +140,12 @@ aes_gcm_reinit(void *key, const uint8_t *iv) } static void -aes_ccm_reinit(void *key, const uint8_t *iv) +aes_ccm_reinit(void *key, const uint8_t *iv, size_t ivlen) { struct aes_icm_ctx *ctx; + KASSERT(ivlen == AES_CCM_IV_LEN, + ("%s: invalid IV length", __func__)); ctx = key; /* CCM has flags, then the IV, then the counter, which starts at 1 */ diff --git a/sys/opencrypto/xform_aes_xts.c b/sys/opencrypto/xform_aes_xts.c index 457535621511..7a79d4685d21 100644 --- a/sys/opencrypto/xform_aes_xts.c +++ b/sys/opencrypto/xform_aes_xts.c @@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$"); static int aes_xts_setkey(void *, const uint8_t *, int); static void aes_xts_encrypt(void *, const uint8_t *, uint8_t *); static void aes_xts_decrypt(void *, const uint8_t *, uint8_t *); -static void aes_xts_reinit(void *, const uint8_t *); +static void aes_xts_reinit(void *, const uint8_t *, size_t); /* Encryption instances */ const struct enc_xform enc_xform_aes_xts = { @@ -77,12 +77,15 @@ const struct enc_xform enc_xform_aes_xts = { * Encryption wrapper routines. */ static void -aes_xts_reinit(void *key, const uint8_t *iv) +aes_xts_reinit(void *key, const uint8_t *iv, size_t ivlen) { struct aes_xts_ctx *ctx = key; uint64_t blocknum; u_int i; + KASSERT(ivlen == sizeof(blocknum), + ("%s: invalid IV length", __func__)); + /* * Prepare tweak as E_k2(IV). IV is specified as LE representation * of a 64-bit block number which we allow to be passed in directly. diff --git a/sys/opencrypto/xform_chacha20_poly1305.c b/sys/opencrypto/xform_chacha20_poly1305.c index 543c16bcc4e0..51ae11c923e7 100644 --- a/sys/opencrypto/xform_chacha20_poly1305.c +++ b/sys/opencrypto/xform_chacha20_poly1305.c @@ -50,10 +50,13 @@ chacha20_poly1305_setkey(void *vctx, const uint8_t *key, int len) } static void -chacha20_poly1305_reinit(void *vctx, const uint8_t *iv) +chacha20_poly1305_reinit(void *vctx, const uint8_t *iv, size_t ivlen) { struct chacha20_poly1305_cipher_ctx *ctx = vctx; + KASSERT(ivlen == sizeof(ctx->nonce), + ("%s: invalid nonce length", __func__)); + /* Block 0 is used for the poly1305 key. */ memcpy(ctx->nonce, iv, sizeof(ctx->nonce)); ctx->ic = 1; diff --git a/sys/opencrypto/xform_enc.h b/sys/opencrypto/xform_enc.h index 6f95b49986c5..baf423dd1079 100644 --- a/sys/opencrypto/xform_enc.h +++ b/sys/opencrypto/xform_enc.h @@ -62,7 +62,7 @@ struct enc_xform { void (*encrypt) (void *, const uint8_t *, uint8_t *); void (*decrypt) (void *, const uint8_t *, uint8_t *); int (*setkey) (void *, const uint8_t *, int len); - void (*reinit) (void *, const uint8_t *); + void (*reinit) (void *, const uint8_t *, size_t); /* * For stream ciphers, encrypt/decrypt the final partial block