xref: /OK3568_Linux_fs/kernel/net/sctp/auth.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /* SCTP kernel implementation
3*4882a593Smuzhiyun  * (C) Copyright 2007 Hewlett-Packard Development Company, L.P.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This file is part of the SCTP kernel implementation
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Please send any bug reports or fixes you make to the
8*4882a593Smuzhiyun  * email address(es):
9*4882a593Smuzhiyun  *    lksctp developers <linux-sctp@vger.kernel.org>
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * Written or modified by:
12*4882a593Smuzhiyun  *   Vlad Yasevich     <vladislav.yasevich@hp.com>
13*4882a593Smuzhiyun  */
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #include <crypto/hash.h>
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/types.h>
18*4882a593Smuzhiyun #include <linux/scatterlist.h>
19*4882a593Smuzhiyun #include <net/sctp/sctp.h>
20*4882a593Smuzhiyun #include <net/sctp/auth.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun static struct sctp_hmac sctp_hmac_list[SCTP_AUTH_NUM_HMACS] = {
23*4882a593Smuzhiyun 	{
24*4882a593Smuzhiyun 		/* id 0 is reserved.  as all 0 */
25*4882a593Smuzhiyun 		.hmac_id = SCTP_AUTH_HMAC_ID_RESERVED_0,
26*4882a593Smuzhiyun 	},
27*4882a593Smuzhiyun 	{
28*4882a593Smuzhiyun 		.hmac_id = SCTP_AUTH_HMAC_ID_SHA1,
29*4882a593Smuzhiyun 		.hmac_name = "hmac(sha1)",
30*4882a593Smuzhiyun 		.hmac_len = SCTP_SHA1_SIG_SIZE,
31*4882a593Smuzhiyun 	},
32*4882a593Smuzhiyun 	{
33*4882a593Smuzhiyun 		/* id 2 is reserved as well */
34*4882a593Smuzhiyun 		.hmac_id = SCTP_AUTH_HMAC_ID_RESERVED_2,
35*4882a593Smuzhiyun 	},
36*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_CRYPTO_SHA256)
37*4882a593Smuzhiyun 	{
38*4882a593Smuzhiyun 		.hmac_id = SCTP_AUTH_HMAC_ID_SHA256,
39*4882a593Smuzhiyun 		.hmac_name = "hmac(sha256)",
40*4882a593Smuzhiyun 		.hmac_len = SCTP_SHA256_SIG_SIZE,
41*4882a593Smuzhiyun 	}
42*4882a593Smuzhiyun #endif
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 
sctp_auth_key_put(struct sctp_auth_bytes * key)46*4882a593Smuzhiyun void sctp_auth_key_put(struct sctp_auth_bytes *key)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	if (!key)
49*4882a593Smuzhiyun 		return;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	if (refcount_dec_and_test(&key->refcnt)) {
52*4882a593Smuzhiyun 		kfree_sensitive(key);
53*4882a593Smuzhiyun 		SCTP_DBG_OBJCNT_DEC(keys);
54*4882a593Smuzhiyun 	}
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* Create a new key structure of a given length */
sctp_auth_create_key(__u32 key_len,gfp_t gfp)58*4882a593Smuzhiyun static struct sctp_auth_bytes *sctp_auth_create_key(__u32 key_len, gfp_t gfp)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	struct sctp_auth_bytes *key;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	/* Verify that we are not going to overflow INT_MAX */
63*4882a593Smuzhiyun 	if (key_len > (INT_MAX - sizeof(struct sctp_auth_bytes)))
64*4882a593Smuzhiyun 		return NULL;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	/* Allocate the shared key */
67*4882a593Smuzhiyun 	key = kmalloc(sizeof(struct sctp_auth_bytes) + key_len, gfp);
68*4882a593Smuzhiyun 	if (!key)
69*4882a593Smuzhiyun 		return NULL;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	key->len = key_len;
72*4882a593Smuzhiyun 	refcount_set(&key->refcnt, 1);
73*4882a593Smuzhiyun 	SCTP_DBG_OBJCNT_INC(keys);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	return key;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* Create a new shared key container with a give key id */
sctp_auth_shkey_create(__u16 key_id,gfp_t gfp)79*4882a593Smuzhiyun struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	struct sctp_shared_key *new;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	/* Allocate the shared key container */
84*4882a593Smuzhiyun 	new = kzalloc(sizeof(struct sctp_shared_key), gfp);
85*4882a593Smuzhiyun 	if (!new)
86*4882a593Smuzhiyun 		return NULL;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	INIT_LIST_HEAD(&new->key_list);
89*4882a593Smuzhiyun 	refcount_set(&new->refcnt, 1);
90*4882a593Smuzhiyun 	new->key_id = key_id;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	return new;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun /* Free the shared key structure */
sctp_auth_shkey_destroy(struct sctp_shared_key * sh_key)96*4882a593Smuzhiyun static void sctp_auth_shkey_destroy(struct sctp_shared_key *sh_key)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	BUG_ON(!list_empty(&sh_key->key_list));
99*4882a593Smuzhiyun 	sctp_auth_key_put(sh_key->key);
100*4882a593Smuzhiyun 	sh_key->key = NULL;
101*4882a593Smuzhiyun 	kfree(sh_key);
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
sctp_auth_shkey_release(struct sctp_shared_key * sh_key)104*4882a593Smuzhiyun void sctp_auth_shkey_release(struct sctp_shared_key *sh_key)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun 	if (refcount_dec_and_test(&sh_key->refcnt))
107*4882a593Smuzhiyun 		sctp_auth_shkey_destroy(sh_key);
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
sctp_auth_shkey_hold(struct sctp_shared_key * sh_key)110*4882a593Smuzhiyun void sctp_auth_shkey_hold(struct sctp_shared_key *sh_key)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun 	refcount_inc(&sh_key->refcnt);
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun /* Destroy the entire key list.  This is done during the
116*4882a593Smuzhiyun  * associon and endpoint free process.
117*4882a593Smuzhiyun  */
sctp_auth_destroy_keys(struct list_head * keys)118*4882a593Smuzhiyun void sctp_auth_destroy_keys(struct list_head *keys)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	struct sctp_shared_key *ep_key;
121*4882a593Smuzhiyun 	struct sctp_shared_key *tmp;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	if (list_empty(keys))
124*4882a593Smuzhiyun 		return;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	key_for_each_safe(ep_key, tmp, keys) {
127*4882a593Smuzhiyun 		list_del_init(&ep_key->key_list);
128*4882a593Smuzhiyun 		sctp_auth_shkey_release(ep_key);
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /* Compare two byte vectors as numbers.  Return values
133*4882a593Smuzhiyun  * are:
134*4882a593Smuzhiyun  * 	  0 - vectors are equal
135*4882a593Smuzhiyun  * 	< 0 - vector 1 is smaller than vector2
136*4882a593Smuzhiyun  * 	> 0 - vector 1 is greater than vector2
137*4882a593Smuzhiyun  *
138*4882a593Smuzhiyun  * Algorithm is:
139*4882a593Smuzhiyun  * 	This is performed by selecting the numerically smaller key vector...
140*4882a593Smuzhiyun  *	If the key vectors are equal as numbers but differ in length ...
141*4882a593Smuzhiyun  *	the shorter vector is considered smaller
142*4882a593Smuzhiyun  *
143*4882a593Smuzhiyun  * Examples (with small values):
144*4882a593Smuzhiyun  * 	000123456789 > 123456789 (first number is longer)
145*4882a593Smuzhiyun  * 	000123456789 < 234567891 (second number is larger numerically)
146*4882a593Smuzhiyun  * 	123456789 > 2345678 	 (first number is both larger & longer)
147*4882a593Smuzhiyun  */
sctp_auth_compare_vectors(struct sctp_auth_bytes * vector1,struct sctp_auth_bytes * vector2)148*4882a593Smuzhiyun static int sctp_auth_compare_vectors(struct sctp_auth_bytes *vector1,
149*4882a593Smuzhiyun 			      struct sctp_auth_bytes *vector2)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun 	int diff;
152*4882a593Smuzhiyun 	int i;
153*4882a593Smuzhiyun 	const __u8 *longer;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	diff = vector1->len - vector2->len;
156*4882a593Smuzhiyun 	if (diff) {
157*4882a593Smuzhiyun 		longer = (diff > 0) ? vector1->data : vector2->data;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 		/* Check to see if the longer number is
160*4882a593Smuzhiyun 		 * lead-zero padded.  If it is not, it
161*4882a593Smuzhiyun 		 * is automatically larger numerically.
162*4882a593Smuzhiyun 		 */
163*4882a593Smuzhiyun 		for (i = 0; i < abs(diff); i++) {
164*4882a593Smuzhiyun 			if (longer[i] != 0)
165*4882a593Smuzhiyun 				return diff;
166*4882a593Smuzhiyun 		}
167*4882a593Smuzhiyun 	}
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	/* lengths are the same, compare numbers */
170*4882a593Smuzhiyun 	return memcmp(vector1->data, vector2->data, vector1->len);
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun /*
174*4882a593Smuzhiyun  * Create a key vector as described in SCTP-AUTH, Section 6.1
175*4882a593Smuzhiyun  *    The RANDOM parameter, the CHUNKS parameter and the HMAC-ALGO
176*4882a593Smuzhiyun  *    parameter sent by each endpoint are concatenated as byte vectors.
177*4882a593Smuzhiyun  *    These parameters include the parameter type, parameter length, and
178*4882a593Smuzhiyun  *    the parameter value, but padding is omitted; all padding MUST be
179*4882a593Smuzhiyun  *    removed from this concatenation before proceeding with further
180*4882a593Smuzhiyun  *    computation of keys.  Parameters which were not sent are simply
181*4882a593Smuzhiyun  *    omitted from the concatenation process.  The resulting two vectors
182*4882a593Smuzhiyun  *    are called the two key vectors.
183*4882a593Smuzhiyun  */
sctp_auth_make_key_vector(struct sctp_random_param * random,struct sctp_chunks_param * chunks,struct sctp_hmac_algo_param * hmacs,gfp_t gfp)184*4882a593Smuzhiyun static struct sctp_auth_bytes *sctp_auth_make_key_vector(
185*4882a593Smuzhiyun 			struct sctp_random_param *random,
186*4882a593Smuzhiyun 			struct sctp_chunks_param *chunks,
187*4882a593Smuzhiyun 			struct sctp_hmac_algo_param *hmacs,
188*4882a593Smuzhiyun 			gfp_t gfp)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	struct sctp_auth_bytes *new;
191*4882a593Smuzhiyun 	__u32	len;
192*4882a593Smuzhiyun 	__u32	offset = 0;
193*4882a593Smuzhiyun 	__u16	random_len, hmacs_len, chunks_len = 0;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	random_len = ntohs(random->param_hdr.length);
196*4882a593Smuzhiyun 	hmacs_len = ntohs(hmacs->param_hdr.length);
197*4882a593Smuzhiyun 	if (chunks)
198*4882a593Smuzhiyun 		chunks_len = ntohs(chunks->param_hdr.length);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	len = random_len + hmacs_len + chunks_len;
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	new = sctp_auth_create_key(len, gfp);
203*4882a593Smuzhiyun 	if (!new)
204*4882a593Smuzhiyun 		return NULL;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	memcpy(new->data, random, random_len);
207*4882a593Smuzhiyun 	offset += random_len;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	if (chunks) {
210*4882a593Smuzhiyun 		memcpy(new->data + offset, chunks, chunks_len);
211*4882a593Smuzhiyun 		offset += chunks_len;
212*4882a593Smuzhiyun 	}
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	memcpy(new->data + offset, hmacs, hmacs_len);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	return new;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun /* Make a key vector based on our local parameters */
sctp_auth_make_local_vector(const struct sctp_association * asoc,gfp_t gfp)221*4882a593Smuzhiyun static struct sctp_auth_bytes *sctp_auth_make_local_vector(
222*4882a593Smuzhiyun 				    const struct sctp_association *asoc,
223*4882a593Smuzhiyun 				    gfp_t gfp)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	return sctp_auth_make_key_vector(
226*4882a593Smuzhiyun 			(struct sctp_random_param *)asoc->c.auth_random,
227*4882a593Smuzhiyun 			(struct sctp_chunks_param *)asoc->c.auth_chunks,
228*4882a593Smuzhiyun 			(struct sctp_hmac_algo_param *)asoc->c.auth_hmacs, gfp);
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun /* Make a key vector based on peer's parameters */
sctp_auth_make_peer_vector(const struct sctp_association * asoc,gfp_t gfp)232*4882a593Smuzhiyun static struct sctp_auth_bytes *sctp_auth_make_peer_vector(
233*4882a593Smuzhiyun 				    const struct sctp_association *asoc,
234*4882a593Smuzhiyun 				    gfp_t gfp)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun 	return sctp_auth_make_key_vector(asoc->peer.peer_random,
237*4882a593Smuzhiyun 					 asoc->peer.peer_chunks,
238*4882a593Smuzhiyun 					 asoc->peer.peer_hmacs,
239*4882a593Smuzhiyun 					 gfp);
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun /* Set the value of the association shared key base on the parameters
244*4882a593Smuzhiyun  * given.  The algorithm is:
245*4882a593Smuzhiyun  *    From the endpoint pair shared keys and the key vectors the
246*4882a593Smuzhiyun  *    association shared keys are computed.  This is performed by selecting
247*4882a593Smuzhiyun  *    the numerically smaller key vector and concatenating it to the
248*4882a593Smuzhiyun  *    endpoint pair shared key, and then concatenating the numerically
249*4882a593Smuzhiyun  *    larger key vector to that.  The result of the concatenation is the
250*4882a593Smuzhiyun  *    association shared key.
251*4882a593Smuzhiyun  */
sctp_auth_asoc_set_secret(struct sctp_shared_key * ep_key,struct sctp_auth_bytes * first_vector,struct sctp_auth_bytes * last_vector,gfp_t gfp)252*4882a593Smuzhiyun static struct sctp_auth_bytes *sctp_auth_asoc_set_secret(
253*4882a593Smuzhiyun 			struct sctp_shared_key *ep_key,
254*4882a593Smuzhiyun 			struct sctp_auth_bytes *first_vector,
255*4882a593Smuzhiyun 			struct sctp_auth_bytes *last_vector,
256*4882a593Smuzhiyun 			gfp_t gfp)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	struct sctp_auth_bytes *secret;
259*4882a593Smuzhiyun 	__u32 offset = 0;
260*4882a593Smuzhiyun 	__u32 auth_len;
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	auth_len = first_vector->len + last_vector->len;
263*4882a593Smuzhiyun 	if (ep_key->key)
264*4882a593Smuzhiyun 		auth_len += ep_key->key->len;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	secret = sctp_auth_create_key(auth_len, gfp);
267*4882a593Smuzhiyun 	if (!secret)
268*4882a593Smuzhiyun 		return NULL;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	if (ep_key->key) {
271*4882a593Smuzhiyun 		memcpy(secret->data, ep_key->key->data, ep_key->key->len);
272*4882a593Smuzhiyun 		offset += ep_key->key->len;
273*4882a593Smuzhiyun 	}
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	memcpy(secret->data + offset, first_vector->data, first_vector->len);
276*4882a593Smuzhiyun 	offset += first_vector->len;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	memcpy(secret->data + offset, last_vector->data, last_vector->len);
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	return secret;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun /* Create an association shared key.  Follow the algorithm
284*4882a593Smuzhiyun  * described in SCTP-AUTH, Section 6.1
285*4882a593Smuzhiyun  */
sctp_auth_asoc_create_secret(const struct sctp_association * asoc,struct sctp_shared_key * ep_key,gfp_t gfp)286*4882a593Smuzhiyun static struct sctp_auth_bytes *sctp_auth_asoc_create_secret(
287*4882a593Smuzhiyun 				 const struct sctp_association *asoc,
288*4882a593Smuzhiyun 				 struct sctp_shared_key *ep_key,
289*4882a593Smuzhiyun 				 gfp_t gfp)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	struct sctp_auth_bytes *local_key_vector;
292*4882a593Smuzhiyun 	struct sctp_auth_bytes *peer_key_vector;
293*4882a593Smuzhiyun 	struct sctp_auth_bytes	*first_vector,
294*4882a593Smuzhiyun 				*last_vector;
295*4882a593Smuzhiyun 	struct sctp_auth_bytes	*secret = NULL;
296*4882a593Smuzhiyun 	int	cmp;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	/* Now we need to build the key vectors
300*4882a593Smuzhiyun 	 * SCTP-AUTH , Section 6.1
301*4882a593Smuzhiyun 	 *    The RANDOM parameter, the CHUNKS parameter and the HMAC-ALGO
302*4882a593Smuzhiyun 	 *    parameter sent by each endpoint are concatenated as byte vectors.
303*4882a593Smuzhiyun 	 *    These parameters include the parameter type, parameter length, and
304*4882a593Smuzhiyun 	 *    the parameter value, but padding is omitted; all padding MUST be
305*4882a593Smuzhiyun 	 *    removed from this concatenation before proceeding with further
306*4882a593Smuzhiyun 	 *    computation of keys.  Parameters which were not sent are simply
307*4882a593Smuzhiyun 	 *    omitted from the concatenation process.  The resulting two vectors
308*4882a593Smuzhiyun 	 *    are called the two key vectors.
309*4882a593Smuzhiyun 	 */
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	local_key_vector = sctp_auth_make_local_vector(asoc, gfp);
312*4882a593Smuzhiyun 	peer_key_vector = sctp_auth_make_peer_vector(asoc, gfp);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	if (!peer_key_vector || !local_key_vector)
315*4882a593Smuzhiyun 		goto out;
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	/* Figure out the order in which the key_vectors will be
318*4882a593Smuzhiyun 	 * added to the endpoint shared key.
319*4882a593Smuzhiyun 	 * SCTP-AUTH, Section 6.1:
320*4882a593Smuzhiyun 	 *   This is performed by selecting the numerically smaller key
321*4882a593Smuzhiyun 	 *   vector and concatenating it to the endpoint pair shared
322*4882a593Smuzhiyun 	 *   key, and then concatenating the numerically larger key
323*4882a593Smuzhiyun 	 *   vector to that.  If the key vectors are equal as numbers
324*4882a593Smuzhiyun 	 *   but differ in length, then the concatenation order is the
325*4882a593Smuzhiyun 	 *   endpoint shared key, followed by the shorter key vector,
326*4882a593Smuzhiyun 	 *   followed by the longer key vector.  Otherwise, the key
327*4882a593Smuzhiyun 	 *   vectors are identical, and may be concatenated to the
328*4882a593Smuzhiyun 	 *   endpoint pair key in any order.
329*4882a593Smuzhiyun 	 */
330*4882a593Smuzhiyun 	cmp = sctp_auth_compare_vectors(local_key_vector,
331*4882a593Smuzhiyun 					peer_key_vector);
332*4882a593Smuzhiyun 	if (cmp < 0) {
333*4882a593Smuzhiyun 		first_vector = local_key_vector;
334*4882a593Smuzhiyun 		last_vector = peer_key_vector;
335*4882a593Smuzhiyun 	} else {
336*4882a593Smuzhiyun 		first_vector = peer_key_vector;
337*4882a593Smuzhiyun 		last_vector = local_key_vector;
338*4882a593Smuzhiyun 	}
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	secret = sctp_auth_asoc_set_secret(ep_key, first_vector, last_vector,
341*4882a593Smuzhiyun 					    gfp);
342*4882a593Smuzhiyun out:
343*4882a593Smuzhiyun 	sctp_auth_key_put(local_key_vector);
344*4882a593Smuzhiyun 	sctp_auth_key_put(peer_key_vector);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	return secret;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun /*
350*4882a593Smuzhiyun  * Populate the association overlay list with the list
351*4882a593Smuzhiyun  * from the endpoint.
352*4882a593Smuzhiyun  */
sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint * ep,struct sctp_association * asoc,gfp_t gfp)353*4882a593Smuzhiyun int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep,
354*4882a593Smuzhiyun 				struct sctp_association *asoc,
355*4882a593Smuzhiyun 				gfp_t gfp)
356*4882a593Smuzhiyun {
357*4882a593Smuzhiyun 	struct sctp_shared_key *sh_key;
358*4882a593Smuzhiyun 	struct sctp_shared_key *new;
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	BUG_ON(!list_empty(&asoc->endpoint_shared_keys));
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	key_for_each(sh_key, &ep->endpoint_shared_keys) {
363*4882a593Smuzhiyun 		new = sctp_auth_shkey_create(sh_key->key_id, gfp);
364*4882a593Smuzhiyun 		if (!new)
365*4882a593Smuzhiyun 			goto nomem;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 		new->key = sh_key->key;
368*4882a593Smuzhiyun 		sctp_auth_key_hold(new->key);
369*4882a593Smuzhiyun 		list_add(&new->key_list, &asoc->endpoint_shared_keys);
370*4882a593Smuzhiyun 	}
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	return 0;
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun nomem:
375*4882a593Smuzhiyun 	sctp_auth_destroy_keys(&asoc->endpoint_shared_keys);
376*4882a593Smuzhiyun 	return -ENOMEM;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun /* Public interface to create the association shared key.
381*4882a593Smuzhiyun  * See code above for the algorithm.
382*4882a593Smuzhiyun  */
sctp_auth_asoc_init_active_key(struct sctp_association * asoc,gfp_t gfp)383*4882a593Smuzhiyun int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun 	struct sctp_auth_bytes	*secret;
386*4882a593Smuzhiyun 	struct sctp_shared_key *ep_key;
387*4882a593Smuzhiyun 	struct sctp_chunk *chunk;
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	/* If we don't support AUTH, or peer is not capable
390*4882a593Smuzhiyun 	 * we don't need to do anything.
391*4882a593Smuzhiyun 	 */
392*4882a593Smuzhiyun 	if (!asoc->peer.auth_capable)
393*4882a593Smuzhiyun 		return 0;
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	/* If the key_id is non-zero and we couldn't find an
396*4882a593Smuzhiyun 	 * endpoint pair shared key, we can't compute the
397*4882a593Smuzhiyun 	 * secret.
398*4882a593Smuzhiyun 	 * For key_id 0, endpoint pair shared key is a NULL key.
399*4882a593Smuzhiyun 	 */
400*4882a593Smuzhiyun 	ep_key = sctp_auth_get_shkey(asoc, asoc->active_key_id);
401*4882a593Smuzhiyun 	BUG_ON(!ep_key);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	secret = sctp_auth_asoc_create_secret(asoc, ep_key, gfp);
404*4882a593Smuzhiyun 	if (!secret)
405*4882a593Smuzhiyun 		return -ENOMEM;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	sctp_auth_key_put(asoc->asoc_shared_key);
408*4882a593Smuzhiyun 	asoc->asoc_shared_key = secret;
409*4882a593Smuzhiyun 	asoc->shkey = ep_key;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	/* Update send queue in case any chunk already in there now
412*4882a593Smuzhiyun 	 * needs authenticating
413*4882a593Smuzhiyun 	 */
414*4882a593Smuzhiyun 	list_for_each_entry(chunk, &asoc->outqueue.out_chunk_list, list) {
415*4882a593Smuzhiyun 		if (sctp_auth_send_cid(chunk->chunk_hdr->type, asoc)) {
416*4882a593Smuzhiyun 			chunk->auth = 1;
417*4882a593Smuzhiyun 			if (!chunk->shkey) {
418*4882a593Smuzhiyun 				chunk->shkey = asoc->shkey;
419*4882a593Smuzhiyun 				sctp_auth_shkey_hold(chunk->shkey);
420*4882a593Smuzhiyun 			}
421*4882a593Smuzhiyun 		}
422*4882a593Smuzhiyun 	}
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	return 0;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun /* Find the endpoint pair shared key based on the key_id */
sctp_auth_get_shkey(const struct sctp_association * asoc,__u16 key_id)429*4882a593Smuzhiyun struct sctp_shared_key *sctp_auth_get_shkey(
430*4882a593Smuzhiyun 				const struct sctp_association *asoc,
431*4882a593Smuzhiyun 				__u16 key_id)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun 	struct sctp_shared_key *key;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	/* First search associations set of endpoint pair shared keys */
436*4882a593Smuzhiyun 	key_for_each(key, &asoc->endpoint_shared_keys) {
437*4882a593Smuzhiyun 		if (key->key_id == key_id) {
438*4882a593Smuzhiyun 			if (!key->deactivated)
439*4882a593Smuzhiyun 				return key;
440*4882a593Smuzhiyun 			break;
441*4882a593Smuzhiyun 		}
442*4882a593Smuzhiyun 	}
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 	return NULL;
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun /*
448*4882a593Smuzhiyun  * Initialize all the possible digest transforms that we can use.  Right
449*4882a593Smuzhiyun  * now, the supported digests are SHA1 and SHA256.  We do this here once
450*4882a593Smuzhiyun  * because of the restrictiong that transforms may only be allocated in
451*4882a593Smuzhiyun  * user context.  This forces us to pre-allocated all possible transforms
452*4882a593Smuzhiyun  * at the endpoint init time.
453*4882a593Smuzhiyun  */
sctp_auth_init_hmacs(struct sctp_endpoint * ep,gfp_t gfp)454*4882a593Smuzhiyun int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)
455*4882a593Smuzhiyun {
456*4882a593Smuzhiyun 	struct crypto_shash *tfm = NULL;
457*4882a593Smuzhiyun 	__u16   id;
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	/* If the transforms are already allocated, we are done */
460*4882a593Smuzhiyun 	if (ep->auth_hmacs)
461*4882a593Smuzhiyun 		return 0;
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	/* Allocated the array of pointers to transorms */
464*4882a593Smuzhiyun 	ep->auth_hmacs = kcalloc(SCTP_AUTH_NUM_HMACS,
465*4882a593Smuzhiyun 				 sizeof(struct crypto_shash *),
466*4882a593Smuzhiyun 				 gfp);
467*4882a593Smuzhiyun 	if (!ep->auth_hmacs)
468*4882a593Smuzhiyun 		return -ENOMEM;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	for (id = 0; id < SCTP_AUTH_NUM_HMACS; id++) {
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 		/* See is we support the id.  Supported IDs have name and
473*4882a593Smuzhiyun 		 * length fields set, so that we can allocated and use
474*4882a593Smuzhiyun 		 * them.  We can safely just check for name, for without the
475*4882a593Smuzhiyun 		 * name, we can't allocate the TFM.
476*4882a593Smuzhiyun 		 */
477*4882a593Smuzhiyun 		if (!sctp_hmac_list[id].hmac_name)
478*4882a593Smuzhiyun 			continue;
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 		/* If this TFM has been allocated, we are all set */
481*4882a593Smuzhiyun 		if (ep->auth_hmacs[id])
482*4882a593Smuzhiyun 			continue;
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 		/* Allocate the ID */
485*4882a593Smuzhiyun 		tfm = crypto_alloc_shash(sctp_hmac_list[id].hmac_name, 0, 0);
486*4882a593Smuzhiyun 		if (IS_ERR(tfm))
487*4882a593Smuzhiyun 			goto out_err;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 		ep->auth_hmacs[id] = tfm;
490*4882a593Smuzhiyun 	}
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	return 0;
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun out_err:
495*4882a593Smuzhiyun 	/* Clean up any successful allocations */
496*4882a593Smuzhiyun 	sctp_auth_destroy_hmacs(ep->auth_hmacs);
497*4882a593Smuzhiyun 	ep->auth_hmacs = NULL;
498*4882a593Smuzhiyun 	return -ENOMEM;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun /* Destroy the hmac tfm array */
sctp_auth_destroy_hmacs(struct crypto_shash * auth_hmacs[])502*4882a593Smuzhiyun void sctp_auth_destroy_hmacs(struct crypto_shash *auth_hmacs[])
503*4882a593Smuzhiyun {
504*4882a593Smuzhiyun 	int i;
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 	if (!auth_hmacs)
507*4882a593Smuzhiyun 		return;
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	for (i = 0; i < SCTP_AUTH_NUM_HMACS; i++) {
510*4882a593Smuzhiyun 		crypto_free_shash(auth_hmacs[i]);
511*4882a593Smuzhiyun 	}
512*4882a593Smuzhiyun 	kfree(auth_hmacs);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 
sctp_auth_get_hmac(__u16 hmac_id)516*4882a593Smuzhiyun struct sctp_hmac *sctp_auth_get_hmac(__u16 hmac_id)
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun 	return &sctp_hmac_list[hmac_id];
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun /* Get an hmac description information that we can use to build
522*4882a593Smuzhiyun  * the AUTH chunk
523*4882a593Smuzhiyun  */
sctp_auth_asoc_get_hmac(const struct sctp_association * asoc)524*4882a593Smuzhiyun struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc)
525*4882a593Smuzhiyun {
526*4882a593Smuzhiyun 	struct sctp_hmac_algo_param *hmacs;
527*4882a593Smuzhiyun 	__u16 n_elt;
528*4882a593Smuzhiyun 	__u16 id = 0;
529*4882a593Smuzhiyun 	int i;
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	/* If we have a default entry, use it */
532*4882a593Smuzhiyun 	if (asoc->default_hmac_id)
533*4882a593Smuzhiyun 		return &sctp_hmac_list[asoc->default_hmac_id];
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	/* Since we do not have a default entry, find the first entry
536*4882a593Smuzhiyun 	 * we support and return that.  Do not cache that id.
537*4882a593Smuzhiyun 	 */
538*4882a593Smuzhiyun 	hmacs = asoc->peer.peer_hmacs;
539*4882a593Smuzhiyun 	if (!hmacs)
540*4882a593Smuzhiyun 		return NULL;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	n_elt = (ntohs(hmacs->param_hdr.length) -
543*4882a593Smuzhiyun 		 sizeof(struct sctp_paramhdr)) >> 1;
544*4882a593Smuzhiyun 	for (i = 0; i < n_elt; i++) {
545*4882a593Smuzhiyun 		id = ntohs(hmacs->hmac_ids[i]);
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 		/* Check the id is in the supported range. And
548*4882a593Smuzhiyun 		 * see if we support the id.  Supported IDs have name and
549*4882a593Smuzhiyun 		 * length fields set, so that we can allocate and use
550*4882a593Smuzhiyun 		 * them.  We can safely just check for name, for without the
551*4882a593Smuzhiyun 		 * name, we can't allocate the TFM.
552*4882a593Smuzhiyun 		 */
553*4882a593Smuzhiyun 		if (id > SCTP_AUTH_HMAC_ID_MAX ||
554*4882a593Smuzhiyun 		    !sctp_hmac_list[id].hmac_name) {
555*4882a593Smuzhiyun 			id = 0;
556*4882a593Smuzhiyun 			continue;
557*4882a593Smuzhiyun 		}
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 		break;
560*4882a593Smuzhiyun 	}
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	if (id == 0)
563*4882a593Smuzhiyun 		return NULL;
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	return &sctp_hmac_list[id];
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun 
__sctp_auth_find_hmacid(__be16 * hmacs,int n_elts,__be16 hmac_id)568*4882a593Smuzhiyun static int __sctp_auth_find_hmacid(__be16 *hmacs, int n_elts, __be16 hmac_id)
569*4882a593Smuzhiyun {
570*4882a593Smuzhiyun 	int  found = 0;
571*4882a593Smuzhiyun 	int  i;
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	for (i = 0; i < n_elts; i++) {
574*4882a593Smuzhiyun 		if (hmac_id == hmacs[i]) {
575*4882a593Smuzhiyun 			found = 1;
576*4882a593Smuzhiyun 			break;
577*4882a593Smuzhiyun 		}
578*4882a593Smuzhiyun 	}
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	return found;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun /* See if the HMAC_ID is one that we claim as supported */
sctp_auth_asoc_verify_hmac_id(const struct sctp_association * asoc,__be16 hmac_id)584*4882a593Smuzhiyun int sctp_auth_asoc_verify_hmac_id(const struct sctp_association *asoc,
585*4882a593Smuzhiyun 				    __be16 hmac_id)
586*4882a593Smuzhiyun {
587*4882a593Smuzhiyun 	struct sctp_hmac_algo_param *hmacs;
588*4882a593Smuzhiyun 	__u16 n_elt;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	if (!asoc)
591*4882a593Smuzhiyun 		return 0;
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	hmacs = (struct sctp_hmac_algo_param *)asoc->c.auth_hmacs;
594*4882a593Smuzhiyun 	n_elt = (ntohs(hmacs->param_hdr.length) -
595*4882a593Smuzhiyun 		 sizeof(struct sctp_paramhdr)) >> 1;
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	return __sctp_auth_find_hmacid(hmacs->hmac_ids, n_elt, hmac_id);
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun /* Cache the default HMAC id.  This to follow this text from SCTP-AUTH:
602*4882a593Smuzhiyun  * Section 6.1:
603*4882a593Smuzhiyun  *   The receiver of a HMAC-ALGO parameter SHOULD use the first listed
604*4882a593Smuzhiyun  *   algorithm it supports.
605*4882a593Smuzhiyun  */
sctp_auth_asoc_set_default_hmac(struct sctp_association * asoc,struct sctp_hmac_algo_param * hmacs)606*4882a593Smuzhiyun void sctp_auth_asoc_set_default_hmac(struct sctp_association *asoc,
607*4882a593Smuzhiyun 				     struct sctp_hmac_algo_param *hmacs)
608*4882a593Smuzhiyun {
609*4882a593Smuzhiyun 	struct sctp_endpoint *ep;
610*4882a593Smuzhiyun 	__u16   id;
611*4882a593Smuzhiyun 	int	i;
612*4882a593Smuzhiyun 	int	n_params;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	/* if the default id is already set, use it */
615*4882a593Smuzhiyun 	if (asoc->default_hmac_id)
616*4882a593Smuzhiyun 		return;
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	n_params = (ntohs(hmacs->param_hdr.length) -
619*4882a593Smuzhiyun 		    sizeof(struct sctp_paramhdr)) >> 1;
620*4882a593Smuzhiyun 	ep = asoc->ep;
621*4882a593Smuzhiyun 	for (i = 0; i < n_params; i++) {
622*4882a593Smuzhiyun 		id = ntohs(hmacs->hmac_ids[i]);
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun 		/* Check the id is in the supported range */
625*4882a593Smuzhiyun 		if (id > SCTP_AUTH_HMAC_ID_MAX)
626*4882a593Smuzhiyun 			continue;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 		/* If this TFM has been allocated, use this id */
629*4882a593Smuzhiyun 		if (ep->auth_hmacs[id]) {
630*4882a593Smuzhiyun 			asoc->default_hmac_id = id;
631*4882a593Smuzhiyun 			break;
632*4882a593Smuzhiyun 		}
633*4882a593Smuzhiyun 	}
634*4882a593Smuzhiyun }
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun /* Check to see if the given chunk is supposed to be authenticated */
__sctp_auth_cid(enum sctp_cid chunk,struct sctp_chunks_param * param)638*4882a593Smuzhiyun static int __sctp_auth_cid(enum sctp_cid chunk, struct sctp_chunks_param *param)
639*4882a593Smuzhiyun {
640*4882a593Smuzhiyun 	unsigned short len;
641*4882a593Smuzhiyun 	int found = 0;
642*4882a593Smuzhiyun 	int i;
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	if (!param || param->param_hdr.length == 0)
645*4882a593Smuzhiyun 		return 0;
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	len = ntohs(param->param_hdr.length) - sizeof(struct sctp_paramhdr);
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 	/* SCTP-AUTH, Section 3.2
650*4882a593Smuzhiyun 	 *    The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE and AUTH
651*4882a593Smuzhiyun 	 *    chunks MUST NOT be listed in the CHUNKS parameter.  However, if
652*4882a593Smuzhiyun 	 *    a CHUNKS parameter is received then the types for INIT, INIT-ACK,
653*4882a593Smuzhiyun 	 *    SHUTDOWN-COMPLETE and AUTH chunks MUST be ignored.
654*4882a593Smuzhiyun 	 */
655*4882a593Smuzhiyun 	for (i = 0; !found && i < len; i++) {
656*4882a593Smuzhiyun 		switch (param->chunks[i]) {
657*4882a593Smuzhiyun 		case SCTP_CID_INIT:
658*4882a593Smuzhiyun 		case SCTP_CID_INIT_ACK:
659*4882a593Smuzhiyun 		case SCTP_CID_SHUTDOWN_COMPLETE:
660*4882a593Smuzhiyun 		case SCTP_CID_AUTH:
661*4882a593Smuzhiyun 			break;
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 		default:
664*4882a593Smuzhiyun 			if (param->chunks[i] == chunk)
665*4882a593Smuzhiyun 				found = 1;
666*4882a593Smuzhiyun 			break;
667*4882a593Smuzhiyun 		}
668*4882a593Smuzhiyun 	}
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	return found;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun /* Check if peer requested that this chunk is authenticated */
sctp_auth_send_cid(enum sctp_cid chunk,const struct sctp_association * asoc)674*4882a593Smuzhiyun int sctp_auth_send_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
675*4882a593Smuzhiyun {
676*4882a593Smuzhiyun 	if (!asoc)
677*4882a593Smuzhiyun 		return 0;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 	if (!asoc->peer.auth_capable)
680*4882a593Smuzhiyun 		return 0;
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 	return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun /* Check if we requested that peer authenticate this chunk. */
sctp_auth_recv_cid(enum sctp_cid chunk,const struct sctp_association * asoc)686*4882a593Smuzhiyun int sctp_auth_recv_cid(enum sctp_cid chunk, const struct sctp_association *asoc)
687*4882a593Smuzhiyun {
688*4882a593Smuzhiyun 	if (!asoc)
689*4882a593Smuzhiyun 		return 0;
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	if (!asoc->peer.auth_capable)
692*4882a593Smuzhiyun 		return 0;
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	return __sctp_auth_cid(chunk,
695*4882a593Smuzhiyun 			      (struct sctp_chunks_param *)asoc->c.auth_chunks);
696*4882a593Smuzhiyun }
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun /* SCTP-AUTH: Section 6.2:
699*4882a593Smuzhiyun  *    The sender MUST calculate the MAC as described in RFC2104 [2] using
700*4882a593Smuzhiyun  *    the hash function H as described by the MAC Identifier and the shared
701*4882a593Smuzhiyun  *    association key K based on the endpoint pair shared key described by
702*4882a593Smuzhiyun  *    the shared key identifier.  The 'data' used for the computation of
703*4882a593Smuzhiyun  *    the AUTH-chunk is given by the AUTH chunk with its HMAC field set to
704*4882a593Smuzhiyun  *    zero (as shown in Figure 6) followed by all chunks that are placed
705*4882a593Smuzhiyun  *    after the AUTH chunk in the SCTP packet.
706*4882a593Smuzhiyun  */
sctp_auth_calculate_hmac(const struct sctp_association * asoc,struct sk_buff * skb,struct sctp_auth_chunk * auth,struct sctp_shared_key * ep_key,gfp_t gfp)707*4882a593Smuzhiyun void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
708*4882a593Smuzhiyun 			      struct sk_buff *skb, struct sctp_auth_chunk *auth,
709*4882a593Smuzhiyun 			      struct sctp_shared_key *ep_key, gfp_t gfp)
710*4882a593Smuzhiyun {
711*4882a593Smuzhiyun 	struct sctp_auth_bytes *asoc_key;
712*4882a593Smuzhiyun 	struct crypto_shash *tfm;
713*4882a593Smuzhiyun 	__u16 key_id, hmac_id;
714*4882a593Smuzhiyun 	unsigned char *end;
715*4882a593Smuzhiyun 	int free_key = 0;
716*4882a593Smuzhiyun 	__u8 *digest;
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	/* Extract the info we need:
719*4882a593Smuzhiyun 	 * - hmac id
720*4882a593Smuzhiyun 	 * - key id
721*4882a593Smuzhiyun 	 */
722*4882a593Smuzhiyun 	key_id = ntohs(auth->auth_hdr.shkey_id);
723*4882a593Smuzhiyun 	hmac_id = ntohs(auth->auth_hdr.hmac_id);
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 	if (key_id == asoc->active_key_id)
726*4882a593Smuzhiyun 		asoc_key = asoc->asoc_shared_key;
727*4882a593Smuzhiyun 	else {
728*4882a593Smuzhiyun 		/* ep_key can't be NULL here */
729*4882a593Smuzhiyun 		asoc_key = sctp_auth_asoc_create_secret(asoc, ep_key, gfp);
730*4882a593Smuzhiyun 		if (!asoc_key)
731*4882a593Smuzhiyun 			return;
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 		free_key = 1;
734*4882a593Smuzhiyun 	}
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun 	/* set up scatter list */
737*4882a593Smuzhiyun 	end = skb_tail_pointer(skb);
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun 	tfm = asoc->ep->auth_hmacs[hmac_id];
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun 	digest = auth->auth_hdr.hmac;
742*4882a593Smuzhiyun 	if (crypto_shash_setkey(tfm, &asoc_key->data[0], asoc_key->len))
743*4882a593Smuzhiyun 		goto free;
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	crypto_shash_tfm_digest(tfm, (u8 *)auth, end - (unsigned char *)auth,
746*4882a593Smuzhiyun 				digest);
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun free:
749*4882a593Smuzhiyun 	if (free_key)
750*4882a593Smuzhiyun 		sctp_auth_key_put(asoc_key);
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun /* API Helpers */
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun /* Add a chunk to the endpoint authenticated chunk list */
sctp_auth_ep_add_chunkid(struct sctp_endpoint * ep,__u8 chunk_id)756*4882a593Smuzhiyun int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id)
757*4882a593Smuzhiyun {
758*4882a593Smuzhiyun 	struct sctp_chunks_param *p = ep->auth_chunk_list;
759*4882a593Smuzhiyun 	__u16 nchunks;
760*4882a593Smuzhiyun 	__u16 param_len;
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	/* If this chunk is already specified, we are done */
763*4882a593Smuzhiyun 	if (__sctp_auth_cid(chunk_id, p))
764*4882a593Smuzhiyun 		return 0;
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 	/* Check if we can add this chunk to the array */
767*4882a593Smuzhiyun 	param_len = ntohs(p->param_hdr.length);
768*4882a593Smuzhiyun 	nchunks = param_len - sizeof(struct sctp_paramhdr);
769*4882a593Smuzhiyun 	if (nchunks == SCTP_NUM_CHUNK_TYPES)
770*4882a593Smuzhiyun 		return -EINVAL;
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun 	p->chunks[nchunks] = chunk_id;
773*4882a593Smuzhiyun 	p->param_hdr.length = htons(param_len + 1);
774*4882a593Smuzhiyun 	return 0;
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun /* Add hmac identifires to the endpoint list of supported hmac ids */
sctp_auth_ep_set_hmacs(struct sctp_endpoint * ep,struct sctp_hmacalgo * hmacs)778*4882a593Smuzhiyun int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
779*4882a593Smuzhiyun 			   struct sctp_hmacalgo *hmacs)
780*4882a593Smuzhiyun {
781*4882a593Smuzhiyun 	int has_sha1 = 0;
782*4882a593Smuzhiyun 	__u16 id;
783*4882a593Smuzhiyun 	int i;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	/* Scan the list looking for unsupported id.  Also make sure that
786*4882a593Smuzhiyun 	 * SHA1 is specified.
787*4882a593Smuzhiyun 	 */
788*4882a593Smuzhiyun 	for (i = 0; i < hmacs->shmac_num_idents; i++) {
789*4882a593Smuzhiyun 		id = hmacs->shmac_idents[i];
790*4882a593Smuzhiyun 
791*4882a593Smuzhiyun 		if (id > SCTP_AUTH_HMAC_ID_MAX)
792*4882a593Smuzhiyun 			return -EOPNOTSUPP;
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 		if (SCTP_AUTH_HMAC_ID_SHA1 == id)
795*4882a593Smuzhiyun 			has_sha1 = 1;
796*4882a593Smuzhiyun 
797*4882a593Smuzhiyun 		if (!sctp_hmac_list[id].hmac_name)
798*4882a593Smuzhiyun 			return -EOPNOTSUPP;
799*4882a593Smuzhiyun 	}
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	if (!has_sha1)
802*4882a593Smuzhiyun 		return -EINVAL;
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun 	for (i = 0; i < hmacs->shmac_num_idents; i++)
805*4882a593Smuzhiyun 		ep->auth_hmacs_list->hmac_ids[i] =
806*4882a593Smuzhiyun 				htons(hmacs->shmac_idents[i]);
807*4882a593Smuzhiyun 	ep->auth_hmacs_list->param_hdr.length =
808*4882a593Smuzhiyun 			htons(sizeof(struct sctp_paramhdr) +
809*4882a593Smuzhiyun 			hmacs->shmac_num_idents * sizeof(__u16));
810*4882a593Smuzhiyun 	return 0;
811*4882a593Smuzhiyun }
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun /* Set a new shared key on either endpoint or association.  If the
814*4882a593Smuzhiyun  * key with a same ID already exists, replace the key (remove the
815*4882a593Smuzhiyun  * old key and add a new one).
816*4882a593Smuzhiyun  */
sctp_auth_set_key(struct sctp_endpoint * ep,struct sctp_association * asoc,struct sctp_authkey * auth_key)817*4882a593Smuzhiyun int sctp_auth_set_key(struct sctp_endpoint *ep,
818*4882a593Smuzhiyun 		      struct sctp_association *asoc,
819*4882a593Smuzhiyun 		      struct sctp_authkey *auth_key)
820*4882a593Smuzhiyun {
821*4882a593Smuzhiyun 	struct sctp_shared_key *cur_key, *shkey;
822*4882a593Smuzhiyun 	struct sctp_auth_bytes *key;
823*4882a593Smuzhiyun 	struct list_head *sh_keys;
824*4882a593Smuzhiyun 	int replace = 0;
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun 	/* Try to find the given key id to see if
827*4882a593Smuzhiyun 	 * we are doing a replace, or adding a new key
828*4882a593Smuzhiyun 	 */
829*4882a593Smuzhiyun 	if (asoc) {
830*4882a593Smuzhiyun 		if (!asoc->peer.auth_capable)
831*4882a593Smuzhiyun 			return -EACCES;
832*4882a593Smuzhiyun 		sh_keys = &asoc->endpoint_shared_keys;
833*4882a593Smuzhiyun 	} else {
834*4882a593Smuzhiyun 		if (!ep->auth_enable)
835*4882a593Smuzhiyun 			return -EACCES;
836*4882a593Smuzhiyun 		sh_keys = &ep->endpoint_shared_keys;
837*4882a593Smuzhiyun 	}
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun 	key_for_each(shkey, sh_keys) {
840*4882a593Smuzhiyun 		if (shkey->key_id == auth_key->sca_keynumber) {
841*4882a593Smuzhiyun 			replace = 1;
842*4882a593Smuzhiyun 			break;
843*4882a593Smuzhiyun 		}
844*4882a593Smuzhiyun 	}
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun 	cur_key = sctp_auth_shkey_create(auth_key->sca_keynumber, GFP_KERNEL);
847*4882a593Smuzhiyun 	if (!cur_key)
848*4882a593Smuzhiyun 		return -ENOMEM;
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 	/* Create a new key data based on the info passed in */
851*4882a593Smuzhiyun 	key = sctp_auth_create_key(auth_key->sca_keylength, GFP_KERNEL);
852*4882a593Smuzhiyun 	if (!key) {
853*4882a593Smuzhiyun 		kfree(cur_key);
854*4882a593Smuzhiyun 		return -ENOMEM;
855*4882a593Smuzhiyun 	}
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun 	memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength);
858*4882a593Smuzhiyun 	cur_key->key = key;
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	if (!replace) {
861*4882a593Smuzhiyun 		list_add(&cur_key->key_list, sh_keys);
862*4882a593Smuzhiyun 		return 0;
863*4882a593Smuzhiyun 	}
864*4882a593Smuzhiyun 
865*4882a593Smuzhiyun 	list_del_init(&shkey->key_list);
866*4882a593Smuzhiyun 	list_add(&cur_key->key_list, sh_keys);
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun 	if (asoc && asoc->active_key_id == auth_key->sca_keynumber &&
869*4882a593Smuzhiyun 	    sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL)) {
870*4882a593Smuzhiyun 		list_del_init(&cur_key->key_list);
871*4882a593Smuzhiyun 		sctp_auth_shkey_release(cur_key);
872*4882a593Smuzhiyun 		list_add(&shkey->key_list, sh_keys);
873*4882a593Smuzhiyun 		return -ENOMEM;
874*4882a593Smuzhiyun 	}
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 	sctp_auth_shkey_release(shkey);
877*4882a593Smuzhiyun 	return 0;
878*4882a593Smuzhiyun }
879*4882a593Smuzhiyun 
sctp_auth_set_active_key(struct sctp_endpoint * ep,struct sctp_association * asoc,__u16 key_id)880*4882a593Smuzhiyun int sctp_auth_set_active_key(struct sctp_endpoint *ep,
881*4882a593Smuzhiyun 			     struct sctp_association *asoc,
882*4882a593Smuzhiyun 			     __u16  key_id)
883*4882a593Smuzhiyun {
884*4882a593Smuzhiyun 	struct sctp_shared_key *key;
885*4882a593Smuzhiyun 	struct list_head *sh_keys;
886*4882a593Smuzhiyun 	int found = 0;
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 	/* The key identifier MUST correst to an existing key */
889*4882a593Smuzhiyun 	if (asoc) {
890*4882a593Smuzhiyun 		if (!asoc->peer.auth_capable)
891*4882a593Smuzhiyun 			return -EACCES;
892*4882a593Smuzhiyun 		sh_keys = &asoc->endpoint_shared_keys;
893*4882a593Smuzhiyun 	} else {
894*4882a593Smuzhiyun 		if (!ep->auth_enable)
895*4882a593Smuzhiyun 			return -EACCES;
896*4882a593Smuzhiyun 		sh_keys = &ep->endpoint_shared_keys;
897*4882a593Smuzhiyun 	}
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun 	key_for_each(key, sh_keys) {
900*4882a593Smuzhiyun 		if (key->key_id == key_id) {
901*4882a593Smuzhiyun 			found = 1;
902*4882a593Smuzhiyun 			break;
903*4882a593Smuzhiyun 		}
904*4882a593Smuzhiyun 	}
905*4882a593Smuzhiyun 
906*4882a593Smuzhiyun 	if (!found || key->deactivated)
907*4882a593Smuzhiyun 		return -EINVAL;
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun 	if (asoc) {
910*4882a593Smuzhiyun 		__u16  active_key_id = asoc->active_key_id;
911*4882a593Smuzhiyun 
912*4882a593Smuzhiyun 		asoc->active_key_id = key_id;
913*4882a593Smuzhiyun 		if (sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL)) {
914*4882a593Smuzhiyun 			asoc->active_key_id = active_key_id;
915*4882a593Smuzhiyun 			return -ENOMEM;
916*4882a593Smuzhiyun 		}
917*4882a593Smuzhiyun 	} else
918*4882a593Smuzhiyun 		ep->active_key_id = key_id;
919*4882a593Smuzhiyun 
920*4882a593Smuzhiyun 	return 0;
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun 
sctp_auth_del_key_id(struct sctp_endpoint * ep,struct sctp_association * asoc,__u16 key_id)923*4882a593Smuzhiyun int sctp_auth_del_key_id(struct sctp_endpoint *ep,
924*4882a593Smuzhiyun 			 struct sctp_association *asoc,
925*4882a593Smuzhiyun 			 __u16  key_id)
926*4882a593Smuzhiyun {
927*4882a593Smuzhiyun 	struct sctp_shared_key *key;
928*4882a593Smuzhiyun 	struct list_head *sh_keys;
929*4882a593Smuzhiyun 	int found = 0;
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun 	/* The key identifier MUST NOT be the current active key
932*4882a593Smuzhiyun 	 * The key identifier MUST correst to an existing key
933*4882a593Smuzhiyun 	 */
934*4882a593Smuzhiyun 	if (asoc) {
935*4882a593Smuzhiyun 		if (!asoc->peer.auth_capable)
936*4882a593Smuzhiyun 			return -EACCES;
937*4882a593Smuzhiyun 		if (asoc->active_key_id == key_id)
938*4882a593Smuzhiyun 			return -EINVAL;
939*4882a593Smuzhiyun 
940*4882a593Smuzhiyun 		sh_keys = &asoc->endpoint_shared_keys;
941*4882a593Smuzhiyun 	} else {
942*4882a593Smuzhiyun 		if (!ep->auth_enable)
943*4882a593Smuzhiyun 			return -EACCES;
944*4882a593Smuzhiyun 		if (ep->active_key_id == key_id)
945*4882a593Smuzhiyun 			return -EINVAL;
946*4882a593Smuzhiyun 
947*4882a593Smuzhiyun 		sh_keys = &ep->endpoint_shared_keys;
948*4882a593Smuzhiyun 	}
949*4882a593Smuzhiyun 
950*4882a593Smuzhiyun 	key_for_each(key, sh_keys) {
951*4882a593Smuzhiyun 		if (key->key_id == key_id) {
952*4882a593Smuzhiyun 			found = 1;
953*4882a593Smuzhiyun 			break;
954*4882a593Smuzhiyun 		}
955*4882a593Smuzhiyun 	}
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun 	if (!found)
958*4882a593Smuzhiyun 		return -EINVAL;
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	/* Delete the shared key */
961*4882a593Smuzhiyun 	list_del_init(&key->key_list);
962*4882a593Smuzhiyun 	sctp_auth_shkey_release(key);
963*4882a593Smuzhiyun 
964*4882a593Smuzhiyun 	return 0;
965*4882a593Smuzhiyun }
966*4882a593Smuzhiyun 
sctp_auth_deact_key_id(struct sctp_endpoint * ep,struct sctp_association * asoc,__u16 key_id)967*4882a593Smuzhiyun int sctp_auth_deact_key_id(struct sctp_endpoint *ep,
968*4882a593Smuzhiyun 			   struct sctp_association *asoc, __u16  key_id)
969*4882a593Smuzhiyun {
970*4882a593Smuzhiyun 	struct sctp_shared_key *key;
971*4882a593Smuzhiyun 	struct list_head *sh_keys;
972*4882a593Smuzhiyun 	int found = 0;
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun 	/* The key identifier MUST NOT be the current active key
975*4882a593Smuzhiyun 	 * The key identifier MUST correst to an existing key
976*4882a593Smuzhiyun 	 */
977*4882a593Smuzhiyun 	if (asoc) {
978*4882a593Smuzhiyun 		if (!asoc->peer.auth_capable)
979*4882a593Smuzhiyun 			return -EACCES;
980*4882a593Smuzhiyun 		if (asoc->active_key_id == key_id)
981*4882a593Smuzhiyun 			return -EINVAL;
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun 		sh_keys = &asoc->endpoint_shared_keys;
984*4882a593Smuzhiyun 	} else {
985*4882a593Smuzhiyun 		if (!ep->auth_enable)
986*4882a593Smuzhiyun 			return -EACCES;
987*4882a593Smuzhiyun 		if (ep->active_key_id == key_id)
988*4882a593Smuzhiyun 			return -EINVAL;
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun 		sh_keys = &ep->endpoint_shared_keys;
991*4882a593Smuzhiyun 	}
992*4882a593Smuzhiyun 
993*4882a593Smuzhiyun 	key_for_each(key, sh_keys) {
994*4882a593Smuzhiyun 		if (key->key_id == key_id) {
995*4882a593Smuzhiyun 			found = 1;
996*4882a593Smuzhiyun 			break;
997*4882a593Smuzhiyun 		}
998*4882a593Smuzhiyun 	}
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	if (!found)
1001*4882a593Smuzhiyun 		return -EINVAL;
1002*4882a593Smuzhiyun 
1003*4882a593Smuzhiyun 	/* refcnt == 1 and !list_empty mean it's not being used anywhere
1004*4882a593Smuzhiyun 	 * and deactivated will be set, so it's time to notify userland
1005*4882a593Smuzhiyun 	 * that this shkey can be freed.
1006*4882a593Smuzhiyun 	 */
1007*4882a593Smuzhiyun 	if (asoc && !list_empty(&key->key_list) &&
1008*4882a593Smuzhiyun 	    refcount_read(&key->refcnt) == 1) {
1009*4882a593Smuzhiyun 		struct sctp_ulpevent *ev;
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 		ev = sctp_ulpevent_make_authkey(asoc, key->key_id,
1012*4882a593Smuzhiyun 						SCTP_AUTH_FREE_KEY, GFP_KERNEL);
1013*4882a593Smuzhiyun 		if (ev)
1014*4882a593Smuzhiyun 			asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
1015*4882a593Smuzhiyun 	}
1016*4882a593Smuzhiyun 
1017*4882a593Smuzhiyun 	key->deactivated = 1;
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 	return 0;
1020*4882a593Smuzhiyun }
1021*4882a593Smuzhiyun 
sctp_auth_init(struct sctp_endpoint * ep,gfp_t gfp)1022*4882a593Smuzhiyun int sctp_auth_init(struct sctp_endpoint *ep, gfp_t gfp)
1023*4882a593Smuzhiyun {
1024*4882a593Smuzhiyun 	int err = -ENOMEM;
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 	/* Allocate space for HMACS and CHUNKS authentication
1027*4882a593Smuzhiyun 	 * variables.  There are arrays that we encode directly
1028*4882a593Smuzhiyun 	 * into parameters to make the rest of the operations easier.
1029*4882a593Smuzhiyun 	 */
1030*4882a593Smuzhiyun 	if (!ep->auth_hmacs_list) {
1031*4882a593Smuzhiyun 		struct sctp_hmac_algo_param *auth_hmacs;
1032*4882a593Smuzhiyun 
1033*4882a593Smuzhiyun 		auth_hmacs = kzalloc(struct_size(auth_hmacs, hmac_ids,
1034*4882a593Smuzhiyun 						 SCTP_AUTH_NUM_HMACS), gfp);
1035*4882a593Smuzhiyun 		if (!auth_hmacs)
1036*4882a593Smuzhiyun 			goto nomem;
1037*4882a593Smuzhiyun 		/* Initialize the HMACS parameter.
1038*4882a593Smuzhiyun 		 * SCTP-AUTH: Section 3.3
1039*4882a593Smuzhiyun 		 *    Every endpoint supporting SCTP chunk authentication MUST
1040*4882a593Smuzhiyun 		 *    support the HMAC based on the SHA-1 algorithm.
1041*4882a593Smuzhiyun 		 */
1042*4882a593Smuzhiyun 		auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO;
1043*4882a593Smuzhiyun 		auth_hmacs->param_hdr.length =
1044*4882a593Smuzhiyun 				htons(sizeof(struct sctp_paramhdr) + 2);
1045*4882a593Smuzhiyun 		auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1);
1046*4882a593Smuzhiyun 		ep->auth_hmacs_list = auth_hmacs;
1047*4882a593Smuzhiyun 	}
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun 	if (!ep->auth_chunk_list) {
1050*4882a593Smuzhiyun 		struct sctp_chunks_param *auth_chunks;
1051*4882a593Smuzhiyun 
1052*4882a593Smuzhiyun 		auth_chunks = kzalloc(sizeof(*auth_chunks) +
1053*4882a593Smuzhiyun 				      SCTP_NUM_CHUNK_TYPES, gfp);
1054*4882a593Smuzhiyun 		if (!auth_chunks)
1055*4882a593Smuzhiyun 			goto nomem;
1056*4882a593Smuzhiyun 		/* Initialize the CHUNKS parameter */
1057*4882a593Smuzhiyun 		auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
1058*4882a593Smuzhiyun 		auth_chunks->param_hdr.length =
1059*4882a593Smuzhiyun 				htons(sizeof(struct sctp_paramhdr));
1060*4882a593Smuzhiyun 		ep->auth_chunk_list = auth_chunks;
1061*4882a593Smuzhiyun 	}
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 	/* Allocate and initialize transorms arrays for supported
1064*4882a593Smuzhiyun 	 * HMACs.
1065*4882a593Smuzhiyun 	 */
1066*4882a593Smuzhiyun 	err = sctp_auth_init_hmacs(ep, gfp);
1067*4882a593Smuzhiyun 	if (err)
1068*4882a593Smuzhiyun 		goto nomem;
1069*4882a593Smuzhiyun 
1070*4882a593Smuzhiyun 	return 0;
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun nomem:
1073*4882a593Smuzhiyun 	/* Free all allocations */
1074*4882a593Smuzhiyun 	kfree(ep->auth_hmacs_list);
1075*4882a593Smuzhiyun 	kfree(ep->auth_chunk_list);
1076*4882a593Smuzhiyun 	ep->auth_hmacs_list = NULL;
1077*4882a593Smuzhiyun 	ep->auth_chunk_list = NULL;
1078*4882a593Smuzhiyun 	return err;
1079*4882a593Smuzhiyun }
1080*4882a593Smuzhiyun 
sctp_auth_free(struct sctp_endpoint * ep)1081*4882a593Smuzhiyun void sctp_auth_free(struct sctp_endpoint *ep)
1082*4882a593Smuzhiyun {
1083*4882a593Smuzhiyun 	kfree(ep->auth_hmacs_list);
1084*4882a593Smuzhiyun 	kfree(ep->auth_chunk_list);
1085*4882a593Smuzhiyun 	ep->auth_hmacs_list = NULL;
1086*4882a593Smuzhiyun 	ep->auth_chunk_list = NULL;
1087*4882a593Smuzhiyun 	sctp_auth_destroy_hmacs(ep->auth_hmacs);
1088*4882a593Smuzhiyun 	ep->auth_hmacs = NULL;
1089*4882a593Smuzhiyun }
1090