Commit 2f3dd6ec authored by Eric Biggers's avatar Eric Biggers Committed by Jakub Kicinski
Browse files

sctp: Convert cookie authentication to use HMAC-SHA256



Convert SCTP cookies to use HMAC-SHA256, instead of the previous choice
of the legacy algorithms HMAC-MD5 and HMAC-SHA1.  Simplify and optimize
the code by using the HMAC-SHA256 library instead of crypto_shash, and
by preparing the HMAC key when it is generated instead of per-operation.

This doesn't break compatibility, since the cookie format is an
implementation detail, not part of the SCTP protocol itself.

Note that the cookie size doesn't change either.  The HMAC field was
already 32 bytes, even though previously at most 20 bytes were actually
compared.  32 bytes exactly fits an untruncated HMAC-SHA256 value.  So,
although we could safely truncate the MAC to something slightly shorter,
for now just keep the cookie size the same.

I also considered SipHash, but that would generate only 8-byte MACs.  An
8-byte MAC *might* suffice here.  However, there's quite a lot of
information in the SCTP cookies: more than in TCP SYN cookies.  So
absent an analysis that occasional forgeries of all that information is
okay in SCTP, I errored on the side of caution.

Remove HMAC-MD5 and HMAC-SHA1 as options, since the new HMAC-SHA256
option is just better.  It's faster as well as more secure.  For
example, benchmarking on x86_64, cookie authentication is now nearly 3x
as fast as the previous default choice and implementation of HMAC-MD5.

Also just make the kernel always support cookie authentication if SCTP
is supported at all, rather than making it optional in the build.  (It
was sort of optional before, but it didn't really work properly.  E.g.,
a kernel with CONFIG_SCTP_COOKIE_HMAC_MD5=n still supported HMAC-MD5
cookie authentication if CONFIG_CRYPTO_HMAC and CONFIG_CRYPTO_MD5
happened to be enabled in the kconfig for other reasons.)

Acked-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarEric Biggers <ebiggers@kernel.org>
Link: https://patch.msgid.link/20250818205426.30222-5-ebiggers@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent bf40785f
Loading
Loading
Loading
Loading
+4 −7
Original line number Diff line number Diff line
@@ -3508,16 +3508,13 @@ cookie_hmac_alg - STRING
	a listening sctp socket to a connecting client in the INIT-ACK chunk.
	Valid values are:

	* md5
	* sha1
	* sha256
	* none

	Ability to assign md5 or sha1 as the selected alg is predicated on the
	configuration of those algorithms at build time (CONFIG_CRYPTO_MD5 and
	CONFIG_CRYPTO_SHA1).
	md5 and sha1 are also accepted for backwards compatibility, but cause
	sha256 to be selected.

	Default: Dependent on configuration.  MD5 if available, else SHA1 if
	available, else none.
	Default: sha256

rcvbuf_policy - INTEGER
	Determines if the receive buffer is attributed to the socket or to
+2 −2
Original line number Diff line number Diff line
@@ -75,8 +75,8 @@ struct netns_sctp {
	/* Whether Cookie Preservative is enabled(1) or not(0) */
	int cookie_preserve_enable;

	/* The namespace default hmac alg */
	char *sctp_hmac_alg;
	/* Whether cookie authentication is enabled(1) or not(0) */
	int cookie_auth_enable;

	/* Valid.Cookie.Life	    - 60  seconds  */
	unsigned int valid_cookie_life;
+2 −3
Original line number Diff line number Diff line
@@ -296,9 +296,8 @@ enum { SCTP_MAX_GABS = 16 };
					 */
#define SCTP_DEFAULT_MINSEGMENT 512	/* MTU size ... if no mtu disc */

#define SCTP_SECRET_SIZE 32		/* Number of octets in a 256 bits. */

#define SCTP_SIGNATURE_SIZE 20	        /* size of a SLA-1 signature */
#define SCTP_COOKIE_KEY_SIZE 32	/* size of cookie HMAC key */
#define SCTP_COOKIE_MAC_SIZE 32	/* size of HMAC field in cookies */

#define SCTP_COOKIE_MULTIPLE 32 /* Pad out our cookie to make our hash
				 * functions simpler to write.
+7 −23
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#ifndef __sctp_structs_h__
#define __sctp_structs_h__

#include <crypto/sha2.h>
#include <linux/ktime.h>
#include <linux/generic-radix-tree.h>
#include <linux/rhashtable-types.h>
@@ -68,7 +69,6 @@ struct sctp_outq;
struct sctp_bind_addr;
struct sctp_ulpq;
struct sctp_ep_common;
struct crypto_shash;
struct sctp_stream;


@@ -155,10 +155,6 @@ struct sctp_sock {
	/* PF_ family specific functions.  */
	struct sctp_pf *pf;

	/* Access to HMAC transform. */
	struct crypto_shash *hmac;
	char *sctp_hmac_alg;

	/* What is our base endpointer? */
	struct sctp_endpoint *ep;

@@ -227,7 +223,8 @@ struct sctp_sock {
		frag_interleave:1,
		recvrcvinfo:1,
		recvnxtinfo:1,
		data_ready_signalled:1;
		data_ready_signalled:1,
		cookie_auth_enable:1;

	atomic_t pd_mode;

@@ -335,7 +332,7 @@ struct sctp_cookie {

/* The format of our cookie that we send to our peer. */
struct sctp_signed_cookie {
	__u8 signature[SCTP_SECRET_SIZE];
	__u8 mac[SCTP_COOKIE_MAC_SIZE];
	__u32 __pad;		/* force sctp_cookie alignment to 64 bits */
	struct sctp_cookie c;
} __packed;
@@ -1307,21 +1304,8 @@ struct sctp_endpoint {
	/* This is really a list of struct sctp_association entries. */
	struct list_head asocs;

	/* Secret Key: A secret key used by this endpoint to compute
	 *	      the MAC.	This SHOULD be a cryptographic quality
	 *	      random number with a sufficient length.
	 *	      Discussion in [RFC1750] can be helpful in
	 *	      selection of the key.
	 */
	__u8 secret_key[SCTP_SECRET_SIZE];

 	/* digest:  This is a digest of the sctp cookie.  This field is
 	 * 	    only used on the receive path when we try to validate
 	 * 	    that the cookie has not been tampered with.  We put
 	 * 	    this here so we pre-allocate this once and can re-use
 	 * 	    on every receive.
 	 */
 	__u8 *digest;
	/* Cookie authentication key used by this endpoint */
	struct hmac_sha256_key cookie_auth_key;

	/* sendbuf acct. policy.	*/
	__u32 sndbuf_policy;
+10 −33
Original line number Diff line number Diff line
@@ -49,48 +49,25 @@ config SCTP_DBG_OBJCNT
	  'cat /proc/net/sctp/sctp_dbg_objcnt'

	  If unsure, say N

choice
	prompt "Default SCTP cookie HMAC encoding"
	default SCTP_DEFAULT_COOKIE_HMAC_MD5
	prompt "Default SCTP cookie authentication method"
	default SCTP_DEFAULT_COOKIE_HMAC_SHA256
	help
	  This option sets the default sctp cookie hmac algorithm
	  when in doubt select 'md5'
	  This option sets the default SCTP cookie authentication method, for
	  when a method hasn't been explicitly selected via the
	  net.sctp.cookie_hmac_alg sysctl.

config SCTP_DEFAULT_COOKIE_HMAC_MD5
	bool "Enable optional MD5 hmac cookie generation"
	help
	  Enable optional MD5 hmac based SCTP cookie generation
	select SCTP_COOKIE_HMAC_MD5
	  If unsure, choose the default (HMAC-SHA256).

config SCTP_DEFAULT_COOKIE_HMAC_SHA1
	bool "Enable optional SHA1 hmac cookie generation"
	help
	  Enable optional SHA1 hmac based SCTP cookie generation
	select SCTP_COOKIE_HMAC_SHA1
config SCTP_DEFAULT_COOKIE_HMAC_SHA256
	bool "HMAC-SHA256"

config SCTP_DEFAULT_COOKIE_HMAC_NONE
	bool "Use no hmac alg in SCTP cookie generation"
	help
	  Use no hmac algorithm in SCTP cookie generation
	bool "None"

endchoice

config SCTP_COOKIE_HMAC_MD5
	bool "Enable optional MD5 hmac cookie generation"
	help
	  Enable optional MD5 hmac based SCTP cookie generation
	select CRYPTO
	select CRYPTO_HMAC
	select CRYPTO_MD5

config SCTP_COOKIE_HMAC_SHA1
	bool "Enable optional SHA1 hmac cookie generation"
	help
	  Enable optional SHA1 hmac based SCTP cookie generation
	select CRYPTO
	select CRYPTO_HMAC
	select CRYPTO_SHA1

config INET_SCTP_DIAG
	depends on INET_DIAG
	def_tristate INET_DIAG
Loading