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