From patchwork Fri Nov 14 10:40:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 4596 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:6d04:b0:7b1:439f:bdf with SMTP id e4csp1430384may; Fri, 14 Nov 2025 02:41:01 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCW06HWxIFTrW/h+jaLUkdKld0H8ICt6khHbkIBv9Qr+E52Mvk3hP5KFN3qtYCIqjFGeyCqW2rJu0G8=@openvpn.net X-Google-Smtp-Source: AGHT+IEL5/wD9HlurbqwU8ep2PAajz4kHZnG5/EhxOZ21CrTXp6wdYsxoZzuUiUIyHOwV5LAVIfM X-Received: by 2002:a05:6830:8316:b0:7c2:91cd:2776 with SMTP id 46e09a7af769-7c7382b329amr3721615a34.17.1763116860942; Fri, 14 Nov 2025 02:41:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1763116860; cv=none; d=google.com; s=arc-20240605; b=jhOF8g5bsQNfJL2JlFgTDx7UANhSefROSyei55NL7yFQJQt4PzvlsI6UvfN0cRtM9p MEbSKHQBTG2a5wccMTFjDEyi/IECJeLib2dR16IQPfR0W+72PRR9Mwq4pLNbHFnckaye C+OB+C2kT6dtakZPV8LBnp3u9fT0tHmEPKMNhCOuJ1Vhot6L2jY31xgkP6Bw1RT9e8mX 6DvizUTgikNcsTn8VVrELHgYiFZi/kjAuk54KFLl7YKm7vtts0f3Y65Nt9dnR/9xVZjQ z+6Gk8y1CVt+68hDEm9UChR4bcLy+DTuLPQ7rjhrABR/2sFB9ZiTdXPBYVQrIz6rMwqN CAqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:cc:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:message-id:date:to:from:dkim-signature:dkim-signature :dkim-signature:dkim-signature; bh=M5fNwPYaFjwMBSnqsRnIFhJJJe0IAnpSBQxCQArvYtU=; fh=BRD5nlWz8Dao7r6wQQa6hXD4f3uQGq0bfdeuHf+OsGo=; b=e7t9ovsxVpBh0uVnACUPOnapl8AcuFlDnoWT7tasR6+mdqKzGjNZDdhM7OwNK0DrE2 fMrwBikKC7FGWyccWcDkBcv4FTugo/8f0eHiLqKReyDnTn8Gzzzwf3YHTXlc4xjChXhw kEzyczYs3sXtLSVLH7rl0fElHM/f4/6bius4se3eN2QlB4FsWrfE+ifVgOxnKPVMV5yS 8Mr4FUq4Ig6c5kw5L0j8nAKvBRmmV231loafgkHryWYjW6leRu2z7EUCeesHxn88LNq2 vn6wa1xS0g/CTwJ+B18KpsSq2JCBfj+pZzwfnc4E/5+kiOTcmAnVlWAHmuz770Bc+1Jg 6fZw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=GR3EcT1u; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=T2jU0iIq; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=MoKNOTrp; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=google header.b="YEd/sFE4"; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dara=neutral header.i=@openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 46e09a7af769-7c73a38b9besi1920014a34.186.2025.11.14.02.41.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Nov 2025 02:41:00 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=GR3EcT1u; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=T2jU0iIq; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=MoKNOTrp; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=google header.b="YEd/sFE4"; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dara=neutral header.i=@openvpn.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type:Cc: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:Message-ID:Date:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Owner; bh=M5fNwPYaFjwMBSnqsRnIFhJJJe0IAnpSBQxCQArvYtU=; b=GR3EcT1uMaQ6TSG2oyXYb49yw6 /YOrA2Lg579irvydWallnJ6U1+8LAby3ofu7wSh1D5TjNUy6VEQpGtlT5b0clz/bAwdw9YY/0IWaz OJMDWfZE9kJGvuGcGvbKrxVvZBxLb1m4lZG6MGL5DPfUUtTUUPBKvtzByJD5cwjJF3lo=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1vJrEg-000432-3H; Fri, 14 Nov 2025 10:40:58 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1vJrEe-00042l-W7 for openvpn-devel@lists.sourceforge.net; Fri, 14 Nov 2025 10:40:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-ID: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=pwE8na1Qvp1aeodu1JAY4dZOt/FRLwLu7b8vuCKLm+4=; b=T2jU0iIqhAOEZE+uKkukl8i++Z YutfYixPc2/jIuaYrvxc6r2b6WJcFA3TOMy/avnHq5ikfVnHkmTjp6qa+LP/5GCyroWMVpqfKWXNl dqx4ee+ij0IFdgZwpyIbP48g8HT2YIMpUDcGZdRpILSyvHwZHwiFznNfsbqVKWczlGdw=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-ID:Date:Subject:Cc:To:From :Sender:Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=pwE8na1Qvp1aeodu1JAY4dZOt/FRLwLu7b8vuCKLm+4=; b=M oKNOTrpLf16jMNc9flBRHaX29ZpCxjKEIokJzs9WIQwmRXJlyGGf/082LpTHhT/AfCnNRFAXDDIOE 5sg3dRq3Lm6TonhArSWJIvFOwewgok2vra7UEIjl7c1PDAo5oE1hcHkpnXiWGO7CvhZ9nZSLN+6Ta WYrc2zdfvZP1n4XM=; Received: from mail-ed1-f41.google.com ([209.85.208.41]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1vJrEe-0002Zv-SN for openvpn-devel@lists.sourceforge.net; Fri, 14 Nov 2025 10:40:57 +0000 Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-640b0639dabso3175197a12.3 for ; Fri, 14 Nov 2025 02:40:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=google; t=1763116850; x=1763721650; darn=lists.sourceforge.net; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=pwE8na1Qvp1aeodu1JAY4dZOt/FRLwLu7b8vuCKLm+4=; b=YEd/sFE4zjXagX427j5P7psTgIzT/d5mLsDweALvZCX713mN2B2X+18C8whkH2O2pC Il/k7q4Pucx7gAQ0BmVQ/FoagYrmTIQI4ATDvycqtGAXCukLUNVUdK2YjLspfsBhE4M0 /dIg/fi4Ww6Gh7DOGy8wIQdzcOW6qY2aGKd8U6AY2XZk5sXkUgmoeb0g632lnTLtFKg+ uPaOiI7+M2zpJAH8Ik9xM3FIoZ1lEX9ZozWp3PqOvlK9hlyismhdfCZZ1NxtoEM5lGEN 2kd0UjY6T58VEPJS61fWtxZKOqtKV3kfHv9WTEujEhlBNwa1C99x7Jsn0RHfY9nZjexZ DMsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763116850; x=1763721650; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=pwE8na1Qvp1aeodu1JAY4dZOt/FRLwLu7b8vuCKLm+4=; b=d57Ep9Pdl1zQJNRKV2xqKGOYfFTNS9wLBrB8tugcXGrkOWdaOaSQWZEgzJF+75kXQk bTv2ZhPECVW53k4nNZUQ+wbdzg3Mso2m/FGx4IWtssB6TTRCPbS3zaKHyK+NsvePiaU1 SlQde7yh3FuXPfLtzsWijZG1m8MZFfKZ320z6OgYnk9NIUyT5camIpNtUbYOSIUi8Fuu bLM5GpPVj8oTbqTsOiAijhPAaWkHNqArrrEJXbZYrTQLGSYBw8mFy2vTMI+XfudfNixD SsUbDcvP6F3EgohpBxiyt0Uuez5gHchvC1cm7xXeU50JXBgiVi7ZGJnhZIp7riDo7aJ/ we8g== X-Gm-Message-State: AOJu0Yy8LlmGKqImgCNwePKAXRReeCRxqoeYTyYL6V1PCQRj3N5v6TG/ GR45u0oRXiGOLsU8yhDFHC5FdRytCWA/doBGtPGol6aB95LAZDann6lzJw040u3CiAcFMfvWyD6 9dpjuabI= X-Gm-Gg: ASbGncvyC1+TQqIbBkha5oqj9dcrtiQ/5r5YOA8oJzl3urpSnl2uilPDQYIL7eBJsqj khF+pxWhuQ8zB8IHp9xprwaKo3ON4MLSzNFS3k7EagqJ69wgLiLAkI+70MY9xcdHvlXIm5m0LZP 9wNgMn1E5KkTp915Sn+MZPayACHQoHd5Q3ed7e4PSpjdFad5YaU1TQHfbRDQAk6QZ6LBiV93xuO bRsZvQ+vzgBlOpoo+cmwQ0XmHZQ2ApAasrseMeHRHTVbpxcyURte2fqFxGU2JXYckjqZumy4qOx BEO4jfZx+GTKiOIvHTqdfJsLYFXY3Nx9h3l2dHQgsQaFEe10tF1GvU92bXlFYpUOLbQkBMeWznR hC4E5RKoOX+BRbVx/9j6MvoF8xLtY57b9TBJd6EMlQjkZR9EAJzLNErojJpa8WGRkGgEQZoA= X-Received: by 2002:a05:6402:3513:b0:640:9cdc:aba7 with SMTP id 4fb4d7f45d1cf-64350e9fef7mr2318479a12.26.1763116849899; Fri, 14 Nov 2025 02:40:49 -0800 (PST) Received: from fedora ([2a01:e11:600c:d1a0:3dc8:57d2:efb7:51a8]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6433a4ce83dsm3364903a12.34.2025.11.14.02.40.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Nov 2025 02:40:49 -0800 (PST) From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Fri, 14 Nov 2025 11:40:29 +0100 Message-ID: <20251114104029.239065-1-ralf@mandelbit.com> X-Mailer: git-send-email 2.51.1 MIME-Version: 1.0 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Currently ovpn uses three separate dynamically allocated structures to set up cryptographic operations for both encryption and decryption. This adds overhead to performance-critical paths and contribu [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.208.41 listed in wl.mailspike.net] X-Headers-End: 1vJrEe-0002Zv-SN Subject: [Openvpn-devel] [PATCH ovpn v3] ovpn: consolidate crypto allocations in one chunk X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli , Sabrina Dubroca Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1848762026092934769?= X-GMAIL-MSGID: =?utf-8?q?1848762026092934769?= Currently ovpn uses three separate dynamically allocated structures to set up cryptographic operations for both encryption and decryption. This adds overhead to performance-critical paths and contribute to memory fragmentation. This commit consolidates those allocations into a single temporary blob, similar to what esp_alloc_tmp() does. The resulting performance gain is +7.7% and +4.3% for UDP when using AES and ChaChaPoly respectively, and +4.3% for TCP. Signed-off-by: Ralf Lici Signed-off-by: Antonio Quartulli --- Changes since v2: - Replaced manual multiplication with array_size() helper - Made ovpn_aead_crypto_tmp_size() less generic by asserting that IV size equals OVPN_NONCE_SIZE Changes since v1: - Fixed typo in commit message - Adjusted ovpn_aead_crypto_tmp_size comment to follow kdoc style - Stored allocated blob in the skb control block immediately after allocation to prevent leakage on failure - Removed 'inline' from function declarations in crypto_aead.c drivers/net/ovpn/crypto_aead.c | 160 +++++++++++++++++++++++++-------- drivers/net/ovpn/io.c | 8 +- drivers/net/ovpn/skb.h | 13 ++- 3 files changed, 135 insertions(+), 46 deletions(-) diff --git a/drivers/net/ovpn/crypto_aead.c b/drivers/net/ovpn/crypto_aead.c index cb6cdf8ec317..cd723140c8d0 100644 --- a/drivers/net/ovpn/crypto_aead.c +++ b/drivers/net/ovpn/crypto_aead.c @@ -36,6 +36,104 @@ static int ovpn_aead_encap_overhead(const struct ovpn_crypto_key_slot *ks) crypto_aead_authsize(ks->encrypt); /* Auth Tag */ } +/** + * ovpn_aead_crypto_tmp_size - compute the size of a temporary object containing + * an AEAD request structure with extra space for SG + * and IV. + * @tfm: the AEAD cipher handle + * @nfrags: the number of fragments in the skb + * + * This function calculates the size of a contiguous memory block that includes + * the initialization vector (IV), the AEAD request, and an array of scatterlist + * entries. For alignment considerations, the IV is placed first, followed by + * the request, and then the scatterlist. + * Additional alignment is applied according to the requirements of the + * underlying structures. + * + * Return: the size of the temporary memory that needs to be allocated + */ +static unsigned int ovpn_aead_crypto_tmp_size(struct crypto_aead *tfm, + const unsigned int nfrags) +{ + unsigned int len = OVPN_NONCE_SIZE; + + DEBUG_NET_WARN_ON_ONCE(OVPN_NONCE_SIZE != crypto_aead_ivsize(tfm)); + + /* min size for a buffer of ivsize, aligned to alignmask */ + len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1); + /* round up to the next multiple of the crypto ctx alignment */ + len = ALIGN(len, crypto_tfm_ctx_alignment()); + + /* reserve space for the AEAD request */ + len += sizeof(struct aead_request) + crypto_aead_reqsize(tfm); + /* round up to the next multiple of the scatterlist alignment */ + len = ALIGN(len, __alignof__(struct scatterlist)); + + /* add enough space for nfrags + 2 scatterlist entries */ + len += array_size(sizeof(struct scatterlist), nfrags + 2); + return len; +} + +/** + * ovpn_aead_crypto_tmp_iv - retrieve the pointer to the IV within a temporary + * buffer allocated using ovpn_aead_crypto_tmp_size + * @aead: the AEAD cipher handle + * @tmp: a pointer to the beginning of the temporary buffer + * + * This function retrieves a pointer to the initialization vector (IV) in the + * temporary buffer. If the AEAD cipher specifies an IV size, the pointer is + * adjusted using the AEAD's alignment mask to ensure proper alignment. + * + * Returns: a pointer to the IV within the temporary buffer + */ +static u8 *ovpn_aead_crypto_tmp_iv(struct crypto_aead *aead, void *tmp) +{ + return likely(crypto_aead_ivsize(aead)) ? + PTR_ALIGN((u8 *)tmp, crypto_aead_alignmask(aead) + 1) : + tmp; +} + +/** + * ovpn_aead_crypto_tmp_req - retrieve the pointer to the AEAD request structure + * within a temporary buffer allocated using + * ovpn_aead_crypto_tmp_size + * @aead: the AEAD cipher handle + * @iv: a pointer to the initialization vector in the temporary buffer + * + * This function computes the location of the AEAD request structure that + * immediately follows the IV in the temporary buffer and it ensures the request + * is aligned to the crypto transform context alignment. + * + * Returns: a pointer to the AEAD request structure + */ +static struct aead_request *ovpn_aead_crypto_tmp_req(struct crypto_aead *aead, + const u8 *iv) +{ + return (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead), + crypto_tfm_ctx_alignment()); +} + +/** + * ovpn_aead_crypto_req_sg - locate the scatterlist following the AEAD request + * within a temporary buffer allocated using + * ovpn_aead_crypto_tmp_size + * @aead: the AEAD cipher handle + * @req: a pointer to the AEAD request structure in the temporary buffer + * + * This function computes the starting address of the scatterlist that is + * allocated immediately after the AEAD request structure. It aligns the pointer + * based on the alignment requirements of the scatterlist structure. + * + * Returns: a pointer to the scatterlist + */ +static struct scatterlist *ovpn_aead_crypto_req_sg(struct crypto_aead *aead, + struct aead_request *req) +{ + return (void *)ALIGN((unsigned long)(req + 1) + + crypto_aead_reqsize(aead), + __alignof__(struct scatterlist)); +} + int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, struct sk_buff *skb) { @@ -45,6 +143,7 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, struct scatterlist *sg; int nfrags, ret; u32 pktid, op; + void *tmp; u8 *iv; ovpn_skb_cb(skb)->peer = peer; @@ -71,13 +170,17 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, if (unlikely(nfrags + 2 > (MAX_SKB_FRAGS + 2))) return -ENOSPC; - /* sg may be required by async crypto */ - ovpn_skb_cb(skb)->sg = kmalloc(sizeof(*ovpn_skb_cb(skb)->sg) * - (nfrags + 2), GFP_ATOMIC); - if (unlikely(!ovpn_skb_cb(skb)->sg)) + /* allocate temporary memory for iv, sg and req */ + tmp = kmalloc(ovpn_aead_crypto_tmp_size(ks->encrypt, nfrags), + GFP_ATOMIC); + if (unlikely(!tmp)) return -ENOMEM; - sg = ovpn_skb_cb(skb)->sg; + ovpn_skb_cb(skb)->crypto_tmp = tmp; + + iv = ovpn_aead_crypto_tmp_iv(ks->encrypt, tmp); + req = ovpn_aead_crypto_tmp_req(ks->encrypt, iv); + sg = ovpn_aead_crypto_req_sg(ks->encrypt, req); /* sg table: * 0: op, wire nonce (AD, len=OVPN_OP_SIZE_V2+OVPN_NONCE_WIRE_SIZE), @@ -105,13 +208,6 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, if (unlikely(ret < 0)) return ret; - /* iv may be required by async crypto */ - ovpn_skb_cb(skb)->iv = kmalloc(OVPN_NONCE_SIZE, GFP_ATOMIC); - if (unlikely(!ovpn_skb_cb(skb)->iv)) - return -ENOMEM; - - iv = ovpn_skb_cb(skb)->iv; - /* concat 4 bytes packet id and 8 bytes nonce tail into 12 bytes * nonce */ @@ -130,12 +226,6 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, /* AEAD Additional data */ sg_set_buf(sg, skb->data, OVPN_AAD_SIZE); - req = aead_request_alloc(ks->encrypt, GFP_ATOMIC); - if (unlikely(!req)) - return -ENOMEM; - - ovpn_skb_cb(skb)->req = req; - /* setup async crypto operation */ aead_request_set_tfm(req, ks->encrypt); aead_request_set_callback(req, 0, ovpn_encrypt_post, skb); @@ -156,6 +246,7 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, struct aead_request *req; struct sk_buff *trailer; struct scatterlist *sg; + void *tmp; u8 *iv; payload_offset = OVPN_AAD_SIZE + tag_size; @@ -184,13 +275,17 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, if (unlikely(nfrags + 2 > (MAX_SKB_FRAGS + 2))) return -ENOSPC; - /* sg may be required by async crypto */ - ovpn_skb_cb(skb)->sg = kmalloc(sizeof(*ovpn_skb_cb(skb)->sg) * - (nfrags + 2), GFP_ATOMIC); - if (unlikely(!ovpn_skb_cb(skb)->sg)) + /* allocate temporary memory for iv, sg and req */ + tmp = kmalloc(ovpn_aead_crypto_tmp_size(ks->decrypt, nfrags), + GFP_ATOMIC); + if (unlikely(!tmp)) return -ENOMEM; - sg = ovpn_skb_cb(skb)->sg; + ovpn_skb_cb(skb)->crypto_tmp = tmp; + + iv = ovpn_aead_crypto_tmp_iv(ks->decrypt, tmp); + req = ovpn_aead_crypto_tmp_req(ks->decrypt, iv); + sg = ovpn_aead_crypto_req_sg(ks->decrypt, req); /* sg table: * 0: op, wire nonce (AD, len=OVPN_OPCODE_SIZE+OVPN_NONCE_WIRE_SIZE), @@ -213,24 +308,11 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks, /* append auth_tag onto scatterlist */ sg_set_buf(sg + ret + 1, skb->data + OVPN_AAD_SIZE, tag_size); - /* iv may be required by async crypto */ - ovpn_skb_cb(skb)->iv = kmalloc(OVPN_NONCE_SIZE, GFP_ATOMIC); - if (unlikely(!ovpn_skb_cb(skb)->iv)) - return -ENOMEM; - - iv = ovpn_skb_cb(skb)->iv; - /* copy nonce into IV buffer */ memcpy(iv, skb->data + OVPN_OPCODE_SIZE, OVPN_NONCE_WIRE_SIZE); memcpy(iv + OVPN_NONCE_WIRE_SIZE, ks->nonce_tail_recv, OVPN_NONCE_TAIL_SIZE); - req = aead_request_alloc(ks->decrypt, GFP_ATOMIC); - if (unlikely(!req)) - return -ENOMEM; - - ovpn_skb_cb(skb)->req = req; - /* setup async crypto operation */ aead_request_set_tfm(req, ks->decrypt); aead_request_set_callback(req, 0, ovpn_decrypt_post, skb); @@ -273,7 +355,11 @@ static struct crypto_aead *ovpn_aead_init(const char *title, goto error; } - /* basic AEAD assumption */ + /* basic AEAD assumption + * all current algorithms use OVPN_NONCE_SIZE. + * ovpn_aead_crypto_tmp_size and ovpn_aead_encrypt/decrypt + * expect this. + */ if (crypto_aead_ivsize(aead) != OVPN_NONCE_SIZE) { pr_err("%s IV size must be %d\n", title, OVPN_NONCE_SIZE); ret = -EINVAL; diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c index 3e9e7f8444b3..2721ee8268b2 100644 --- a/drivers/net/ovpn/io.c +++ b/drivers/net/ovpn/io.c @@ -119,9 +119,7 @@ void ovpn_decrypt_post(void *data, int ret) peer = ovpn_skb_cb(skb)->peer; /* crypto is done, cleanup skb CB and its members */ - kfree(ovpn_skb_cb(skb)->iv); - kfree(ovpn_skb_cb(skb)->sg); - aead_request_free(ovpn_skb_cb(skb)->req); + kfree(ovpn_skb_cb(skb)->crypto_tmp); if (unlikely(ret < 0)) goto drop; @@ -248,9 +246,7 @@ void ovpn_encrypt_post(void *data, int ret) peer = ovpn_skb_cb(skb)->peer; /* crypto is done, cleanup skb CB and its members */ - kfree(ovpn_skb_cb(skb)->iv); - kfree(ovpn_skb_cb(skb)->sg); - aead_request_free(ovpn_skb_cb(skb)->req); + kfree(ovpn_skb_cb(skb)->crypto_tmp); if (unlikely(ret == -ERANGE)) { /* we ran out of IVs and we must kill the key as it can't be diff --git a/drivers/net/ovpn/skb.h b/drivers/net/ovpn/skb.h index 64430880f1da..4fb7ea025426 100644 --- a/drivers/net/ovpn/skb.h +++ b/drivers/net/ovpn/skb.h @@ -18,12 +18,19 @@ #include #include +/** + * struct ovpn_cb - ovpn skb control block + * @peer: the peer this skb was received from/sent to + * @ks: the crypto key slot used to encrypt/decrypt this skb + * @crypto_tmp: pointer to temporary memory used for crypto operations + * containing the IV, the scatter gather list and the aead request + * @payload_offset: offset in the skb where the payload starts + * @nosignal: whether this skb should be sent with the MSG_NOSIGNAL flag (TCP) + */ struct ovpn_cb { struct ovpn_peer *peer; struct ovpn_crypto_key_slot *ks; - struct aead_request *req; - struct scatterlist *sg; - u8 *iv; + void *crypto_tmp; unsigned int payload_offset; bool nosignal; };