]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet/sctp_auth.c
sysctl(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / sys / netinet / sctp_auth.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
5  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6  * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * a) Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  *
14  * b) Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the distribution.
17  *
18  * c) Neither the name of Cisco Systems, Inc. nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include <netinet/sctp_os.h>
39 #include <netinet/sctp.h>
40 #include <netinet/sctp_header.h>
41 #include <netinet/sctp_pcb.h>
42 #include <netinet/sctp_var.h>
43 #include <netinet/sctp_sysctl.h>
44 #include <netinet/sctputil.h>
45 #include <netinet/sctp_indata.h>
46 #include <netinet/sctp_output.h>
47 #include <netinet/sctp_auth.h>
48
49 #ifdef SCTP_DEBUG
50 #define SCTP_AUTH_DEBUG         (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_AUTH1)
51 #define SCTP_AUTH_DEBUG2        (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_AUTH2)
52 #endif                          /* SCTP_DEBUG */
53
54 void
55 sctp_clear_chunklist(sctp_auth_chklist_t *chklist)
56 {
57         memset(chklist, 0, sizeof(*chklist));
58         /* chklist->num_chunks = 0; */
59 }
60
61 sctp_auth_chklist_t *
62 sctp_alloc_chunklist(void)
63 {
64         sctp_auth_chklist_t *chklist;
65
66         SCTP_MALLOC(chklist, sctp_auth_chklist_t *, sizeof(*chklist),
67             SCTP_M_AUTH_CL);
68         if (chklist == NULL) {
69                 SCTPDBG(SCTP_DEBUG_AUTH1, "sctp_alloc_chunklist: failed to get memory!\n");
70         } else {
71                 sctp_clear_chunklist(chklist);
72         }
73         return (chklist);
74 }
75
76 void
77 sctp_free_chunklist(sctp_auth_chklist_t *list)
78 {
79         if (list != NULL)
80                 SCTP_FREE(list, SCTP_M_AUTH_CL);
81 }
82
83 sctp_auth_chklist_t *
84 sctp_copy_chunklist(sctp_auth_chklist_t *list)
85 {
86         sctp_auth_chklist_t *new_list;
87
88         if (list == NULL)
89                 return (NULL);
90
91         /* get a new list */
92         new_list = sctp_alloc_chunklist();
93         if (new_list == NULL)
94                 return (NULL);
95         /* copy it */
96         memcpy(new_list, list, sizeof(*new_list));
97
98         return (new_list);
99 }
100
101 /*
102  * add a chunk to the required chunks list
103  */
104 int
105 sctp_auth_add_chunk(uint8_t chunk, sctp_auth_chklist_t *list)
106 {
107         if (list == NULL)
108                 return (-1);
109
110         /* is chunk restricted? */
111         if ((chunk == SCTP_INITIATION) ||
112             (chunk == SCTP_INITIATION_ACK) ||
113             (chunk == SCTP_SHUTDOWN_COMPLETE) ||
114             (chunk == SCTP_AUTHENTICATION)) {
115                 return (-1);
116         }
117         if (list->chunks[chunk] == 0) {
118                 list->chunks[chunk] = 1;
119                 list->num_chunks++;
120                 SCTPDBG(SCTP_DEBUG_AUTH1,
121                     "SCTP: added chunk %u (0x%02x) to Auth list\n",
122                     chunk, chunk);
123         }
124         return (0);
125 }
126
127 /*
128  * delete a chunk from the required chunks list
129  */
130 int
131 sctp_auth_delete_chunk(uint8_t chunk, sctp_auth_chklist_t *list)
132 {
133         if (list == NULL)
134                 return (-1);
135
136         if (list->chunks[chunk] == 1) {
137                 list->chunks[chunk] = 0;
138                 list->num_chunks--;
139                 SCTPDBG(SCTP_DEBUG_AUTH1,
140                     "SCTP: deleted chunk %u (0x%02x) from Auth list\n",
141                     chunk, chunk);
142         }
143         return (0);
144 }
145
146 size_t
147 sctp_auth_get_chklist_size(const sctp_auth_chklist_t *list)
148 {
149         if (list == NULL)
150                 return (0);
151         else
152                 return (list->num_chunks);
153 }
154
155 /*
156  * return the current number and list of required chunks caller must
157  * guarantee ptr has space for up to 256 bytes
158  */
159 int
160 sctp_serialize_auth_chunks(const sctp_auth_chklist_t *list, uint8_t *ptr)
161 {
162         int i, count = 0;
163
164         if (list == NULL)
165                 return (0);
166
167         for (i = 0; i < 256; i++) {
168                 if (list->chunks[i] != 0) {
169                         *ptr++ = i;
170                         count++;
171                 }
172         }
173         return (count);
174 }
175
176 int
177 sctp_pack_auth_chunks(const sctp_auth_chklist_t *list, uint8_t *ptr)
178 {
179         int i, size = 0;
180
181         if (list == NULL)
182                 return (0);
183
184         if (list->num_chunks <= 32) {
185                 /* just list them, one byte each */
186                 for (i = 0; i < 256; i++) {
187                         if (list->chunks[i] != 0) {
188                                 *ptr++ = i;
189                                 size++;
190                         }
191                 }
192         } else {
193                 int index, offset;
194
195                 /* pack into a 32 byte bitfield */
196                 for (i = 0; i < 256; i++) {
197                         if (list->chunks[i] != 0) {
198                                 index = i / 8;
199                                 offset = i % 8;
200                                 ptr[index] |= (1 << offset);
201                         }
202                 }
203                 size = 32;
204         }
205         return (size);
206 }
207
208 int
209 sctp_unpack_auth_chunks(const uint8_t *ptr, uint8_t num_chunks,
210     sctp_auth_chklist_t *list)
211 {
212         int i;
213         int size;
214
215         if (list == NULL)
216                 return (0);
217
218         if (num_chunks <= 32) {
219                 /* just pull them, one byte each */
220                 for (i = 0; i < num_chunks; i++) {
221                         (void)sctp_auth_add_chunk(*ptr++, list);
222                 }
223                 size = num_chunks;
224         } else {
225                 int index, offset;
226
227                 /* unpack from a 32 byte bitfield */
228                 for (index = 0; index < 32; index++) {
229                         for (offset = 0; offset < 8; offset++) {
230                                 if (ptr[index] & (1 << offset)) {
231                                         (void)sctp_auth_add_chunk((index * 8) + offset, list);
232                                 }
233                         }
234                 }
235                 size = 32;
236         }
237         return (size);
238 }
239
240 /*
241  * allocate structure space for a key of length keylen
242  */
243 sctp_key_t *
244 sctp_alloc_key(uint32_t keylen)
245 {
246         sctp_key_t *new_key;
247
248         SCTP_MALLOC(new_key, sctp_key_t *, sizeof(*new_key) + keylen,
249             SCTP_M_AUTH_KY);
250         if (new_key == NULL) {
251                 /* out of memory */
252                 return (NULL);
253         }
254         new_key->keylen = keylen;
255         return (new_key);
256 }
257
258 void
259 sctp_free_key(sctp_key_t *key)
260 {
261         if (key != NULL)
262                 SCTP_FREE(key, SCTP_M_AUTH_KY);
263 }
264
265 void
266 sctp_print_key(sctp_key_t *key, const char *str)
267 {
268         uint32_t i;
269
270         if (key == NULL) {
271                 SCTP_PRINTF("%s: [Null key]\n", str);
272                 return;
273         }
274         SCTP_PRINTF("%s: len %u, ", str, key->keylen);
275         if (key->keylen) {
276                 for (i = 0; i < key->keylen; i++)
277                         SCTP_PRINTF("%02x", key->key[i]);
278                 SCTP_PRINTF("\n");
279         } else {
280                 SCTP_PRINTF("[Null key]\n");
281         }
282 }
283
284 void
285 sctp_show_key(sctp_key_t *key, const char *str)
286 {
287         uint32_t i;
288
289         if (key == NULL) {
290                 SCTP_PRINTF("%s: [Null key]\n", str);
291                 return;
292         }
293         SCTP_PRINTF("%s: len %u, ", str, key->keylen);
294         if (key->keylen) {
295                 for (i = 0; i < key->keylen; i++)
296                         SCTP_PRINTF("%02x", key->key[i]);
297                 SCTP_PRINTF("\n");
298         } else {
299                 SCTP_PRINTF("[Null key]\n");
300         }
301 }
302
303 static uint32_t
304 sctp_get_keylen(sctp_key_t *key)
305 {
306         if (key != NULL)
307                 return (key->keylen);
308         else
309                 return (0);
310 }
311
312 /*
313  * generate a new random key of length 'keylen'
314  */
315 sctp_key_t *
316 sctp_generate_random_key(uint32_t keylen)
317 {
318         sctp_key_t *new_key;
319
320         new_key = sctp_alloc_key(keylen);
321         if (new_key == NULL) {
322                 /* out of memory */
323                 return (NULL);
324         }
325         SCTP_READ_RANDOM(new_key->key, keylen);
326         new_key->keylen = keylen;
327         return (new_key);
328 }
329
330 sctp_key_t *
331 sctp_set_key(uint8_t *key, uint32_t keylen)
332 {
333         sctp_key_t *new_key;
334
335         new_key = sctp_alloc_key(keylen);
336         if (new_key == NULL) {
337                 /* out of memory */
338                 return (NULL);
339         }
340         memcpy(new_key->key, key, keylen);
341         return (new_key);
342 }
343
344 /*-
345  * given two keys of variable size, compute which key is "larger/smaller"
346  * returns:  1 if key1 > key2
347  *          -1 if key1 < key2
348  *           0 if key1 = key2
349  */
350 static int
351 sctp_compare_key(sctp_key_t *key1, sctp_key_t *key2)
352 {
353         uint32_t maxlen;
354         uint32_t i;
355         uint32_t key1len, key2len;
356         uint8_t *key_1, *key_2;
357         uint8_t val1, val2;
358
359         /* sanity/length check */
360         key1len = sctp_get_keylen(key1);
361         key2len = sctp_get_keylen(key2);
362         if ((key1len == 0) && (key2len == 0))
363                 return (0);
364         else if (key1len == 0)
365                 return (-1);
366         else if (key2len == 0)
367                 return (1);
368
369         if (key1len < key2len) {
370                 maxlen = key2len;
371         } else {
372                 maxlen = key1len;
373         }
374         key_1 = key1->key;
375         key_2 = key2->key;
376         /* check for numeric equality */
377         for (i = 0; i < maxlen; i++) {
378                 /* left-pad with zeros */
379                 val1 = (i < (maxlen - key1len)) ? 0 : *(key_1++);
380                 val2 = (i < (maxlen - key2len)) ? 0 : *(key_2++);
381                 if (val1 > val2) {
382                         return (1);
383                 } else if (val1 < val2) {
384                         return (-1);
385                 }
386         }
387         /* keys are equal value, so check lengths */
388         if (key1len == key2len)
389                 return (0);
390         else if (key1len < key2len)
391                 return (-1);
392         else
393                 return (1);
394 }
395
396 /*
397  * generate the concatenated keying material based on the two keys and the
398  * shared key (if available). draft-ietf-tsvwg-auth specifies the specific
399  * order for concatenation
400  */
401 sctp_key_t *
402 sctp_compute_hashkey(sctp_key_t *key1, sctp_key_t *key2, sctp_key_t *shared)
403 {
404         uint32_t keylen;
405         sctp_key_t *new_key;
406         uint8_t *key_ptr;
407
408         keylen = sctp_get_keylen(key1) + sctp_get_keylen(key2) +
409             sctp_get_keylen(shared);
410
411         if (keylen > 0) {
412                 /* get space for the new key */
413                 new_key = sctp_alloc_key(keylen);
414                 if (new_key == NULL) {
415                         /* out of memory */
416                         return (NULL);
417                 }
418                 new_key->keylen = keylen;
419                 key_ptr = new_key->key;
420         } else {
421                 /* all keys empty/null?! */
422                 return (NULL);
423         }
424
425         /* concatenate the keys */
426         if (sctp_compare_key(key1, key2) <= 0) {
427                 /* key is shared + key1 + key2 */
428                 if (sctp_get_keylen(shared)) {
429                         memcpy(key_ptr, shared->key, shared->keylen);
430                         key_ptr += shared->keylen;
431                 }
432                 if (sctp_get_keylen(key1)) {
433                         memcpy(key_ptr, key1->key, key1->keylen);
434                         key_ptr += key1->keylen;
435                 }
436                 if (sctp_get_keylen(key2)) {
437                         memcpy(key_ptr, key2->key, key2->keylen);
438                 }
439         } else {
440                 /* key is shared + key2 + key1 */
441                 if (sctp_get_keylen(shared)) {
442                         memcpy(key_ptr, shared->key, shared->keylen);
443                         key_ptr += shared->keylen;
444                 }
445                 if (sctp_get_keylen(key2)) {
446                         memcpy(key_ptr, key2->key, key2->keylen);
447                         key_ptr += key2->keylen;
448                 }
449                 if (sctp_get_keylen(key1)) {
450                         memcpy(key_ptr, key1->key, key1->keylen);
451                 }
452         }
453         return (new_key);
454 }
455
456 sctp_sharedkey_t *
457 sctp_alloc_sharedkey(void)
458 {
459         sctp_sharedkey_t *new_key;
460
461         SCTP_MALLOC(new_key, sctp_sharedkey_t *, sizeof(*new_key),
462             SCTP_M_AUTH_KY);
463         if (new_key == NULL) {
464                 /* out of memory */
465                 return (NULL);
466         }
467         new_key->keyid = 0;
468         new_key->key = NULL;
469         new_key->refcount = 1;
470         new_key->deactivated = 0;
471         return (new_key);
472 }
473
474 void
475 sctp_free_sharedkey(sctp_sharedkey_t *skey)
476 {
477         if (skey == NULL)
478                 return;
479
480         if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&skey->refcount)) {
481                 if (skey->key != NULL)
482                         sctp_free_key(skey->key);
483                 SCTP_FREE(skey, SCTP_M_AUTH_KY);
484         }
485 }
486
487 sctp_sharedkey_t *
488 sctp_find_sharedkey(struct sctp_keyhead *shared_keys, uint16_t key_id)
489 {
490         sctp_sharedkey_t *skey;
491
492         LIST_FOREACH(skey, shared_keys, next) {
493                 if (skey->keyid == key_id)
494                         return (skey);
495         }
496         return (NULL);
497 }
498
499 int
500 sctp_insert_sharedkey(struct sctp_keyhead *shared_keys,
501     sctp_sharedkey_t *new_skey)
502 {
503         sctp_sharedkey_t *skey;
504
505         if ((shared_keys == NULL) || (new_skey == NULL))
506                 return (EINVAL);
507
508         /* insert into an empty list? */
509         if (LIST_EMPTY(shared_keys)) {
510                 LIST_INSERT_HEAD(shared_keys, new_skey, next);
511                 return (0);
512         }
513         /* insert into the existing list, ordered by key id */
514         LIST_FOREACH(skey, shared_keys, next) {
515                 if (new_skey->keyid < skey->keyid) {
516                         /* insert it before here */
517                         LIST_INSERT_BEFORE(skey, new_skey, next);
518                         return (0);
519                 } else if (new_skey->keyid == skey->keyid) {
520                         /* replace the existing key */
521                         /* verify this key *can* be replaced */
522                         if ((skey->deactivated) || (skey->refcount > 1)) {
523                                 SCTPDBG(SCTP_DEBUG_AUTH1,
524                                     "can't replace shared key id %u\n",
525                                     new_skey->keyid);
526                                 return (EBUSY);
527                         }
528                         SCTPDBG(SCTP_DEBUG_AUTH1,
529                             "replacing shared key id %u\n",
530                             new_skey->keyid);
531                         LIST_INSERT_BEFORE(skey, new_skey, next);
532                         LIST_REMOVE(skey, next);
533                         sctp_free_sharedkey(skey);
534                         return (0);
535                 }
536                 if (LIST_NEXT(skey, next) == NULL) {
537                         /* belongs at the end of the list */
538                         LIST_INSERT_AFTER(skey, new_skey, next);
539                         return (0);
540                 }
541         }
542         /* shouldn't reach here */
543         return (EINVAL);
544 }
545
546 void
547 sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t key_id)
548 {
549         sctp_sharedkey_t *skey;
550
551         /* find the shared key */
552         skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, key_id);
553
554         /* bump the ref count */
555         if (skey) {
556                 atomic_add_int(&skey->refcount, 1);
557                 SCTPDBG(SCTP_DEBUG_AUTH2,
558                     "%s: stcb %p key %u refcount acquire to %d\n",
559                     __func__, (void *)stcb, key_id, skey->refcount);
560         }
561 }
562
563 void
564 sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked)
565 {
566         sctp_sharedkey_t *skey;
567
568         /* find the shared key */
569         skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, key_id);
570
571         /* decrement the ref count */
572         if (skey) {
573                 SCTPDBG(SCTP_DEBUG_AUTH2,
574                     "%s: stcb %p key %u refcount release to %d\n",
575                     __func__, (void *)stcb, key_id, skey->refcount);
576
577                 /* see if a notification should be generated */
578                 if ((skey->refcount <= 2) && (skey->deactivated)) {
579                         /* notify ULP that key is no longer used */
580                         sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb,
581                             key_id, 0, so_locked);
582                         SCTPDBG(SCTP_DEBUG_AUTH2,
583                             "%s: stcb %p key %u no longer used, %d\n",
584                             __func__, (void *)stcb, key_id, skey->refcount);
585                 }
586                 sctp_free_sharedkey(skey);
587         }
588 }
589
590 static sctp_sharedkey_t *
591 sctp_copy_sharedkey(const sctp_sharedkey_t *skey)
592 {
593         sctp_sharedkey_t *new_skey;
594
595         if (skey == NULL)
596                 return (NULL);
597         new_skey = sctp_alloc_sharedkey();
598         if (new_skey == NULL)
599                 return (NULL);
600         if (skey->key != NULL)
601                 new_skey->key = sctp_set_key(skey->key->key, skey->key->keylen);
602         else
603                 new_skey->key = NULL;
604         new_skey->keyid = skey->keyid;
605         return (new_skey);
606 }
607
608 int
609 sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest)
610 {
611         sctp_sharedkey_t *skey, *new_skey;
612         int count = 0;
613
614         if ((src == NULL) || (dest == NULL))
615                 return (0);
616         LIST_FOREACH(skey, src, next) {
617                 new_skey = sctp_copy_sharedkey(skey);
618                 if (new_skey != NULL) {
619                         if (sctp_insert_sharedkey(dest, new_skey)) {
620                                 sctp_free_sharedkey(new_skey);
621                         } else {
622                                 count++;
623                         }
624                 }
625         }
626         return (count);
627 }
628
629 sctp_hmaclist_t *
630 sctp_alloc_hmaclist(uint16_t num_hmacs)
631 {
632         sctp_hmaclist_t *new_list;
633         int alloc_size;
634
635         alloc_size = sizeof(*new_list) + num_hmacs * sizeof(new_list->hmac[0]);
636         SCTP_MALLOC(new_list, sctp_hmaclist_t *, alloc_size,
637             SCTP_M_AUTH_HL);
638         if (new_list == NULL) {
639                 /* out of memory */
640                 return (NULL);
641         }
642         new_list->max_algo = num_hmacs;
643         new_list->num_algo = 0;
644         return (new_list);
645 }
646
647 void
648 sctp_free_hmaclist(sctp_hmaclist_t *list)
649 {
650         if (list != NULL) {
651                 SCTP_FREE(list, SCTP_M_AUTH_HL);
652         }
653 }
654
655 int
656 sctp_auth_add_hmacid(sctp_hmaclist_t *list, uint16_t hmac_id)
657 {
658         int i;
659
660         if (list == NULL)
661                 return (-1);
662         if (list->num_algo == list->max_algo) {
663                 SCTPDBG(SCTP_DEBUG_AUTH1,
664                     "SCTP: HMAC id list full, ignoring add %u\n", hmac_id);
665                 return (-1);
666         }
667         if ((hmac_id != SCTP_AUTH_HMAC_ID_SHA1) &&
668             (hmac_id != SCTP_AUTH_HMAC_ID_SHA256)) {
669                 return (-1);
670         }
671         /* Now is it already in the list */
672         for (i = 0; i < list->num_algo; i++) {
673                 if (list->hmac[i] == hmac_id) {
674                         /* already in list */
675                         return (-1);
676                 }
677         }
678         SCTPDBG(SCTP_DEBUG_AUTH1, "SCTP: add HMAC id %u to list\n", hmac_id);
679         list->hmac[list->num_algo++] = hmac_id;
680         return (0);
681 }
682
683 sctp_hmaclist_t *
684 sctp_copy_hmaclist(sctp_hmaclist_t *list)
685 {
686         sctp_hmaclist_t *new_list;
687         int i;
688
689         if (list == NULL)
690                 return (NULL);
691         /* get a new list */
692         new_list = sctp_alloc_hmaclist(list->max_algo);
693         if (new_list == NULL)
694                 return (NULL);
695         /* copy it */
696         new_list->max_algo = list->max_algo;
697         new_list->num_algo = list->num_algo;
698         for (i = 0; i < list->num_algo; i++)
699                 new_list->hmac[i] = list->hmac[i];
700         return (new_list);
701 }
702
703 sctp_hmaclist_t *
704 sctp_default_supported_hmaclist(void)
705 {
706         sctp_hmaclist_t *new_list;
707
708         new_list = sctp_alloc_hmaclist(2);
709         if (new_list == NULL)
710                 return (NULL);
711         /* We prefer SHA256, so list it first */
712         (void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA256);
713         (void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1);
714         return (new_list);
715 }
716
717 /*-
718  * HMAC algos are listed in priority/preference order
719  * find the best HMAC id to use for the peer based on local support
720  */
721 uint16_t
722 sctp_negotiate_hmacid(sctp_hmaclist_t *peer, sctp_hmaclist_t *local)
723 {
724         int i, j;
725
726         if ((local == NULL) || (peer == NULL))
727                 return (SCTP_AUTH_HMAC_ID_RSVD);
728
729         for (i = 0; i < peer->num_algo; i++) {
730                 for (j = 0; j < local->num_algo; j++) {
731                         if (peer->hmac[i] == local->hmac[j]) {
732                                 /* found the "best" one */
733                                 SCTPDBG(SCTP_DEBUG_AUTH1,
734                                     "SCTP: negotiated peer HMAC id %u\n",
735                                     peer->hmac[i]);
736                                 return (peer->hmac[i]);
737                         }
738                 }
739         }
740         /* didn't find one! */
741         return (SCTP_AUTH_HMAC_ID_RSVD);
742 }
743
744 /*-
745  * serialize the HMAC algo list and return space used
746  * caller must guarantee ptr has appropriate space
747  */
748 int
749 sctp_serialize_hmaclist(sctp_hmaclist_t *list, uint8_t *ptr)
750 {
751         int i;
752         uint16_t hmac_id;
753
754         if (list == NULL)
755                 return (0);
756
757         for (i = 0; i < list->num_algo; i++) {
758                 hmac_id = htons(list->hmac[i]);
759                 memcpy(ptr, &hmac_id, sizeof(hmac_id));
760                 ptr += sizeof(hmac_id);
761         }
762         return (list->num_algo * sizeof(hmac_id));
763 }
764
765 int
766 sctp_verify_hmac_param(struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs)
767 {
768         uint32_t i;
769
770         for (i = 0; i < num_hmacs; i++) {
771                 if (ntohs(hmacs->hmac_ids[i]) == SCTP_AUTH_HMAC_ID_SHA1) {
772                         return (0);
773                 }
774         }
775         return (-1);
776 }
777
778 sctp_authinfo_t *
779 sctp_alloc_authinfo(void)
780 {
781         sctp_authinfo_t *new_authinfo;
782
783         SCTP_MALLOC(new_authinfo, sctp_authinfo_t *, sizeof(*new_authinfo),
784             SCTP_M_AUTH_IF);
785
786         if (new_authinfo == NULL) {
787                 /* out of memory */
788                 return (NULL);
789         }
790         memset(new_authinfo, 0, sizeof(*new_authinfo));
791         return (new_authinfo);
792 }
793
794 void
795 sctp_free_authinfo(sctp_authinfo_t *authinfo)
796 {
797         if (authinfo == NULL)
798                 return;
799
800         if (authinfo->random != NULL)
801                 sctp_free_key(authinfo->random);
802         if (authinfo->peer_random != NULL)
803                 sctp_free_key(authinfo->peer_random);
804         if (authinfo->assoc_key != NULL)
805                 sctp_free_key(authinfo->assoc_key);
806         if (authinfo->recv_key != NULL)
807                 sctp_free_key(authinfo->recv_key);
808
809         /* We are NOT dynamically allocating authinfo's right now... */
810         /* SCTP_FREE(authinfo, SCTP_M_AUTH_??); */
811 }
812
813 uint32_t
814 sctp_get_auth_chunk_len(uint16_t hmac_algo)
815 {
816         int size;
817
818         size = sizeof(struct sctp_auth_chunk) + sctp_get_hmac_digest_len(hmac_algo);
819         return (SCTP_SIZE32(size));
820 }
821
822 uint32_t
823 sctp_get_hmac_digest_len(uint16_t hmac_algo)
824 {
825         switch (hmac_algo) {
826         case SCTP_AUTH_HMAC_ID_SHA1:
827                 return (SCTP_AUTH_DIGEST_LEN_SHA1);
828         case SCTP_AUTH_HMAC_ID_SHA256:
829                 return (SCTP_AUTH_DIGEST_LEN_SHA256);
830         default:
831                 /* unknown HMAC algorithm: can't do anything */
832                 return (0);
833         }                       /* end switch */
834 }
835
836 static inline int
837 sctp_get_hmac_block_len(uint16_t hmac_algo)
838 {
839         switch (hmac_algo) {
840         case SCTP_AUTH_HMAC_ID_SHA1:
841                 return (64);
842         case SCTP_AUTH_HMAC_ID_SHA256:
843                 return (64);
844         case SCTP_AUTH_HMAC_ID_RSVD:
845         default:
846                 /* unknown HMAC algorithm: can't do anything */
847                 return (0);
848         }                       /* end switch */
849 }
850
851 static void
852 sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t *ctx)
853 {
854         switch (hmac_algo) {
855         case SCTP_AUTH_HMAC_ID_SHA1:
856                 SCTP_SHA1_INIT(&ctx->sha1);
857                 break;
858         case SCTP_AUTH_HMAC_ID_SHA256:
859                 SCTP_SHA256_INIT(&ctx->sha256);
860                 break;
861         case SCTP_AUTH_HMAC_ID_RSVD:
862         default:
863                 /* unknown HMAC algorithm: can't do anything */
864                 return;
865         }                       /* end switch */
866 }
867
868 static void
869 sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t *ctx,
870     uint8_t *text, uint32_t textlen)
871 {
872         switch (hmac_algo) {
873         case SCTP_AUTH_HMAC_ID_SHA1:
874                 SCTP_SHA1_UPDATE(&ctx->sha1, text, textlen);
875                 break;
876         case SCTP_AUTH_HMAC_ID_SHA256:
877                 SCTP_SHA256_UPDATE(&ctx->sha256, text, textlen);
878                 break;
879         case SCTP_AUTH_HMAC_ID_RSVD:
880         default:
881                 /* unknown HMAC algorithm: can't do anything */
882                 return;
883         }                       /* end switch */
884 }
885
886 static void
887 sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t *ctx,
888     uint8_t *digest)
889 {
890         switch (hmac_algo) {
891         case SCTP_AUTH_HMAC_ID_SHA1:
892                 SCTP_SHA1_FINAL(digest, &ctx->sha1);
893                 break;
894         case SCTP_AUTH_HMAC_ID_SHA256:
895                 SCTP_SHA256_FINAL(digest, &ctx->sha256);
896                 break;
897         case SCTP_AUTH_HMAC_ID_RSVD:
898         default:
899                 /* unknown HMAC algorithm: can't do anything */
900                 return;
901         }                       /* end switch */
902 }
903
904 /*-
905  * Keyed-Hashing for Message Authentication: FIPS 198 (RFC 2104)
906  *
907  * Compute the HMAC digest using the desired hash key, text, and HMAC
908  * algorithm.  Resulting digest is placed in 'digest' and digest length
909  * is returned, if the HMAC was performed.
910  *
911  * WARNING: it is up to the caller to supply sufficient space to hold the
912  * resultant digest.
913  */
914 uint32_t
915 sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
916     uint8_t *text, uint32_t textlen, uint8_t *digest)
917 {
918         uint32_t digestlen;
919         uint32_t blocklen;
920         sctp_hash_context_t ctx;
921         uint8_t ipad[128], opad[128];   /* keyed hash inner/outer pads */
922         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
923         uint32_t i;
924
925         /* sanity check the material and length */
926         if ((key == NULL) || (keylen == 0) || (text == NULL) ||
927             (textlen == 0) || (digest == NULL)) {
928                 /* can't do HMAC with empty key or text or digest store */
929                 return (0);
930         }
931         /* validate the hmac algo and get the digest length */
932         digestlen = sctp_get_hmac_digest_len(hmac_algo);
933         if (digestlen == 0)
934                 return (0);
935
936         /* hash the key if it is longer than the hash block size */
937         blocklen = sctp_get_hmac_block_len(hmac_algo);
938         if (keylen > blocklen) {
939                 sctp_hmac_init(hmac_algo, &ctx);
940                 sctp_hmac_update(hmac_algo, &ctx, key, keylen);
941                 sctp_hmac_final(hmac_algo, &ctx, temp);
942                 /* set the hashed key as the key */
943                 keylen = digestlen;
944                 key = temp;
945         }
946         /* initialize the inner/outer pads with the key and "append" zeroes */
947         memset(ipad, 0, blocklen);
948         memset(opad, 0, blocklen);
949         memcpy(ipad, key, keylen);
950         memcpy(opad, key, keylen);
951
952         /* XOR the key with ipad and opad values */
953         for (i = 0; i < blocklen; i++) {
954                 ipad[i] ^= 0x36;
955                 opad[i] ^= 0x5c;
956         }
957
958         /* perform inner hash */
959         sctp_hmac_init(hmac_algo, &ctx);
960         sctp_hmac_update(hmac_algo, &ctx, ipad, blocklen);
961         sctp_hmac_update(hmac_algo, &ctx, text, textlen);
962         sctp_hmac_final(hmac_algo, &ctx, temp);
963
964         /* perform outer hash */
965         sctp_hmac_init(hmac_algo, &ctx);
966         sctp_hmac_update(hmac_algo, &ctx, opad, blocklen);
967         sctp_hmac_update(hmac_algo, &ctx, temp, digestlen);
968         sctp_hmac_final(hmac_algo, &ctx, digest);
969
970         return (digestlen);
971 }
972
973 /* mbuf version */
974 uint32_t
975 sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen,
976     struct mbuf *m, uint32_t m_offset, uint8_t *digest, uint32_t trailer)
977 {
978         uint32_t digestlen;
979         uint32_t blocklen;
980         sctp_hash_context_t ctx;
981         uint8_t ipad[128], opad[128];   /* keyed hash inner/outer pads */
982         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
983         uint32_t i;
984         struct mbuf *m_tmp;
985
986         /* sanity check the material and length */
987         if ((key == NULL) || (keylen == 0) || (m == NULL) || (digest == NULL)) {
988                 /* can't do HMAC with empty key or text or digest store */
989                 return (0);
990         }
991         /* validate the hmac algo and get the digest length */
992         digestlen = sctp_get_hmac_digest_len(hmac_algo);
993         if (digestlen == 0)
994                 return (0);
995
996         /* hash the key if it is longer than the hash block size */
997         blocklen = sctp_get_hmac_block_len(hmac_algo);
998         if (keylen > blocklen) {
999                 sctp_hmac_init(hmac_algo, &ctx);
1000                 sctp_hmac_update(hmac_algo, &ctx, key, keylen);
1001                 sctp_hmac_final(hmac_algo, &ctx, temp);
1002                 /* set the hashed key as the key */
1003                 keylen = digestlen;
1004                 key = temp;
1005         }
1006         /* initialize the inner/outer pads with the key and "append" zeroes */
1007         memset(ipad, 0, blocklen);
1008         memset(opad, 0, blocklen);
1009         memcpy(ipad, key, keylen);
1010         memcpy(opad, key, keylen);
1011
1012         /* XOR the key with ipad and opad values */
1013         for (i = 0; i < blocklen; i++) {
1014                 ipad[i] ^= 0x36;
1015                 opad[i] ^= 0x5c;
1016         }
1017
1018         /* perform inner hash */
1019         sctp_hmac_init(hmac_algo, &ctx);
1020         sctp_hmac_update(hmac_algo, &ctx, ipad, blocklen);
1021         /* find the correct starting mbuf and offset (get start of text) */
1022         m_tmp = m;
1023         while ((m_tmp != NULL) && (m_offset >= (uint32_t)SCTP_BUF_LEN(m_tmp))) {
1024                 m_offset -= SCTP_BUF_LEN(m_tmp);
1025                 m_tmp = SCTP_BUF_NEXT(m_tmp);
1026         }
1027         /* now use the rest of the mbuf chain for the text */
1028         while (m_tmp != NULL) {
1029                 if ((SCTP_BUF_NEXT(m_tmp) == NULL) && trailer) {
1030                         sctp_hmac_update(hmac_algo, &ctx, mtod(m_tmp, uint8_t *)+m_offset,
1031                             SCTP_BUF_LEN(m_tmp) - (trailer + m_offset));
1032                 } else {
1033                         sctp_hmac_update(hmac_algo, &ctx, mtod(m_tmp, uint8_t *)+m_offset,
1034                             SCTP_BUF_LEN(m_tmp) - m_offset);
1035                 }
1036
1037                 /* clear the offset since it's only for the first mbuf */
1038                 m_offset = 0;
1039                 m_tmp = SCTP_BUF_NEXT(m_tmp);
1040         }
1041         sctp_hmac_final(hmac_algo, &ctx, temp);
1042
1043         /* perform outer hash */
1044         sctp_hmac_init(hmac_algo, &ctx);
1045         sctp_hmac_update(hmac_algo, &ctx, opad, blocklen);
1046         sctp_hmac_update(hmac_algo, &ctx, temp, digestlen);
1047         sctp_hmac_final(hmac_algo, &ctx, digest);
1048
1049         return (digestlen);
1050 }
1051
1052 /*
1053  * computes the requested HMAC using a key struct (which may be modified if
1054  * the keylen exceeds the HMAC block len).
1055  */
1056 uint32_t
1057 sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t *key, uint8_t *text,
1058     uint32_t textlen, uint8_t *digest)
1059 {
1060         uint32_t digestlen;
1061         uint32_t blocklen;
1062         sctp_hash_context_t ctx;
1063         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
1064
1065         /* sanity check */
1066         if ((key == NULL) || (text == NULL) || (textlen == 0) ||
1067             (digest == NULL)) {
1068                 /* can't do HMAC with empty key or text or digest store */
1069                 return (0);
1070         }
1071         /* validate the hmac algo and get the digest length */
1072         digestlen = sctp_get_hmac_digest_len(hmac_algo);
1073         if (digestlen == 0)
1074                 return (0);
1075
1076         /* hash the key if it is longer than the hash block size */
1077         blocklen = sctp_get_hmac_block_len(hmac_algo);
1078         if (key->keylen > blocklen) {
1079                 sctp_hmac_init(hmac_algo, &ctx);
1080                 sctp_hmac_update(hmac_algo, &ctx, key->key, key->keylen);
1081                 sctp_hmac_final(hmac_algo, &ctx, temp);
1082                 /* save the hashed key as the new key */
1083                 key->keylen = digestlen;
1084                 memcpy(key->key, temp, key->keylen);
1085         }
1086         return (sctp_hmac(hmac_algo, key->key, key->keylen, text, textlen,
1087             digest));
1088 }
1089
1090 /* mbuf version */
1091 uint32_t
1092 sctp_compute_hmac_m(uint16_t hmac_algo, sctp_key_t *key, struct mbuf *m,
1093     uint32_t m_offset, uint8_t *digest)
1094 {
1095         uint32_t digestlen;
1096         uint32_t blocklen;
1097         sctp_hash_context_t ctx;
1098         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
1099
1100         /* sanity check */
1101         if ((key == NULL) || (m == NULL) || (digest == NULL)) {
1102                 /* can't do HMAC with empty key or text or digest store */
1103                 return (0);
1104         }
1105         /* validate the hmac algo and get the digest length */
1106         digestlen = sctp_get_hmac_digest_len(hmac_algo);
1107         if (digestlen == 0)
1108                 return (0);
1109
1110         /* hash the key if it is longer than the hash block size */
1111         blocklen = sctp_get_hmac_block_len(hmac_algo);
1112         if (key->keylen > blocklen) {
1113                 sctp_hmac_init(hmac_algo, &ctx);
1114                 sctp_hmac_update(hmac_algo, &ctx, key->key, key->keylen);
1115                 sctp_hmac_final(hmac_algo, &ctx, temp);
1116                 /* save the hashed key as the new key */
1117                 key->keylen = digestlen;
1118                 memcpy(key->key, temp, key->keylen);
1119         }
1120         return (sctp_hmac_m(hmac_algo, key->key, key->keylen, m, m_offset, digest, 0));
1121 }
1122
1123 int
1124 sctp_auth_is_supported_hmac(sctp_hmaclist_t *list, uint16_t id)
1125 {
1126         int i;
1127
1128         if ((list == NULL) || (id == SCTP_AUTH_HMAC_ID_RSVD))
1129                 return (0);
1130
1131         for (i = 0; i < list->num_algo; i++)
1132                 if (list->hmac[i] == id)
1133                         return (1);
1134
1135         /* not in the list */
1136         return (0);
1137 }
1138
1139 /*-
1140  * clear any cached key(s) if they match the given key id on an association.
1141  * the cached key(s) will be recomputed and re-cached at next use.
1142  * ASSUMES TCB_LOCK is already held
1143  */
1144 void
1145 sctp_clear_cachedkeys(struct sctp_tcb *stcb, uint16_t keyid)
1146 {
1147         if (stcb == NULL)
1148                 return;
1149
1150         if (keyid == stcb->asoc.authinfo.assoc_keyid) {
1151                 sctp_free_key(stcb->asoc.authinfo.assoc_key);
1152                 stcb->asoc.authinfo.assoc_key = NULL;
1153         }
1154         if (keyid == stcb->asoc.authinfo.recv_keyid) {
1155                 sctp_free_key(stcb->asoc.authinfo.recv_key);
1156                 stcb->asoc.authinfo.recv_key = NULL;
1157         }
1158 }
1159
1160 /*-
1161  * clear any cached key(s) if they match the given key id for all assocs on
1162  * an endpoint.
1163  * ASSUMES INP_WLOCK is already held
1164  */
1165 void
1166 sctp_clear_cachedkeys_ep(struct sctp_inpcb *inp, uint16_t keyid)
1167 {
1168         struct sctp_tcb *stcb;
1169
1170         if (inp == NULL)
1171                 return;
1172
1173         /* clear the cached keys on all assocs on this instance */
1174         LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
1175                 SCTP_TCB_LOCK(stcb);
1176                 sctp_clear_cachedkeys(stcb, keyid);
1177                 SCTP_TCB_UNLOCK(stcb);
1178         }
1179 }
1180
1181 /*-
1182  * delete a shared key from an association
1183  * ASSUMES TCB_LOCK is already held
1184  */
1185 int
1186 sctp_delete_sharedkey(struct sctp_tcb *stcb, uint16_t keyid)
1187 {
1188         sctp_sharedkey_t *skey;
1189
1190         if (stcb == NULL)
1191                 return (-1);
1192
1193         /* is the keyid the assoc active sending key */
1194         if (keyid == stcb->asoc.authinfo.active_keyid)
1195                 return (-1);
1196
1197         /* does the key exist? */
1198         skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, keyid);
1199         if (skey == NULL)
1200                 return (-1);
1201
1202         /* are there other refcount holders on the key? */
1203         if (skey->refcount > 1)
1204                 return (-1);
1205
1206         /* remove it */
1207         LIST_REMOVE(skey, next);
1208         sctp_free_sharedkey(skey);      /* frees skey->key as well */
1209
1210         /* clear any cached keys */
1211         sctp_clear_cachedkeys(stcb, keyid);
1212         return (0);
1213 }
1214
1215 /*-
1216  * deletes a shared key from the endpoint
1217  * ASSUMES INP_WLOCK is already held
1218  */
1219 int
1220 sctp_delete_sharedkey_ep(struct sctp_inpcb *inp, uint16_t keyid)
1221 {
1222         sctp_sharedkey_t *skey;
1223
1224         if (inp == NULL)
1225                 return (-1);
1226
1227         /* is the keyid the active sending key on the endpoint */
1228         if (keyid == inp->sctp_ep.default_keyid)
1229                 return (-1);
1230
1231         /* does the key exist? */
1232         skey = sctp_find_sharedkey(&inp->sctp_ep.shared_keys, keyid);
1233         if (skey == NULL)
1234                 return (-1);
1235
1236         /* endpoint keys are not refcounted */
1237
1238         /* remove it */
1239         LIST_REMOVE(skey, next);
1240         sctp_free_sharedkey(skey);      /* frees skey->key as well */
1241
1242         /* clear any cached keys */
1243         sctp_clear_cachedkeys_ep(inp, keyid);
1244         return (0);
1245 }
1246
1247 /*-
1248  * set the active key on an association
1249  * ASSUMES TCB_LOCK is already held
1250  */
1251 int
1252 sctp_auth_setactivekey(struct sctp_tcb *stcb, uint16_t keyid)
1253 {
1254         sctp_sharedkey_t *skey = NULL;
1255
1256         /* find the key on the assoc */
1257         skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, keyid);
1258         if (skey == NULL) {
1259                 /* that key doesn't exist */
1260                 return (-1);
1261         }
1262         if ((skey->deactivated) && (skey->refcount > 1)) {
1263                 /* can't reactivate a deactivated key with other refcounts */
1264                 return (-1);
1265         }
1266
1267         /* set the (new) active key */
1268         stcb->asoc.authinfo.active_keyid = keyid;
1269         /* reset the deactivated flag */
1270         skey->deactivated = 0;
1271
1272         return (0);
1273 }
1274
1275 /*-
1276  * set the active key on an endpoint
1277  * ASSUMES INP_WLOCK is already held
1278  */
1279 int
1280 sctp_auth_setactivekey_ep(struct sctp_inpcb *inp, uint16_t keyid)
1281 {
1282         sctp_sharedkey_t *skey;
1283
1284         /* find the key */
1285         skey = sctp_find_sharedkey(&inp->sctp_ep.shared_keys, keyid);
1286         if (skey == NULL) {
1287                 /* that key doesn't exist */
1288                 return (-1);
1289         }
1290         inp->sctp_ep.default_keyid = keyid;
1291         return (0);
1292 }
1293
1294 /*-
1295  * deactivates a shared key from the association
1296  * ASSUMES INP_WLOCK is already held
1297  */
1298 int
1299 sctp_deact_sharedkey(struct sctp_tcb *stcb, uint16_t keyid)
1300 {
1301         sctp_sharedkey_t *skey;
1302
1303         if (stcb == NULL)
1304                 return (-1);
1305
1306         /* is the keyid the assoc active sending key */
1307         if (keyid == stcb->asoc.authinfo.active_keyid)
1308                 return (-1);
1309
1310         /* does the key exist? */
1311         skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, keyid);
1312         if (skey == NULL)
1313                 return (-1);
1314
1315         /* are there other refcount holders on the key? */
1316         if (skey->refcount == 1) {
1317                 /* no other users, send a notification for this key */
1318                 sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb, keyid, 0,
1319                     SCTP_SO_LOCKED);
1320         }
1321
1322         /* mark the key as deactivated */
1323         skey->deactivated = 1;
1324
1325         return (0);
1326 }
1327
1328 /*-
1329  * deactivates a shared key from the endpoint
1330  * ASSUMES INP_WLOCK is already held
1331  */
1332 int
1333 sctp_deact_sharedkey_ep(struct sctp_inpcb *inp, uint16_t keyid)
1334 {
1335         sctp_sharedkey_t *skey;
1336
1337         if (inp == NULL)
1338                 return (-1);
1339
1340         /* is the keyid the active sending key on the endpoint */
1341         if (keyid == inp->sctp_ep.default_keyid)
1342                 return (-1);
1343
1344         /* does the key exist? */
1345         skey = sctp_find_sharedkey(&inp->sctp_ep.shared_keys, keyid);
1346         if (skey == NULL)
1347                 return (-1);
1348
1349         /* endpoint keys are not refcounted */
1350
1351         /* remove it */
1352         LIST_REMOVE(skey, next);
1353         sctp_free_sharedkey(skey);      /* frees skey->key as well */
1354
1355         return (0);
1356 }
1357
1358 /*
1359  * get local authentication parameters from cookie (from INIT-ACK)
1360  */
1361 void
1362 sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
1363     uint32_t offset, uint32_t length)
1364 {
1365         struct sctp_paramhdr *phdr, tmp_param;
1366         uint16_t plen, ptype;
1367         uint8_t random_store[SCTP_PARAM_BUFFER_SIZE];
1368         struct sctp_auth_random *p_random = NULL;
1369         uint16_t random_len = 0;
1370         uint8_t hmacs_store[SCTP_PARAM_BUFFER_SIZE];
1371         struct sctp_auth_hmac_algo *hmacs = NULL;
1372         uint16_t hmacs_len = 0;
1373         uint8_t chunks_store[SCTP_PARAM_BUFFER_SIZE];
1374         struct sctp_auth_chunk_list *chunks = NULL;
1375         uint16_t num_chunks = 0;
1376         sctp_key_t *new_key;
1377         uint32_t keylen;
1378
1379         /* convert to upper bound */
1380         length += offset;
1381
1382         phdr = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
1383             sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
1384         while (phdr != NULL) {
1385                 ptype = ntohs(phdr->param_type);
1386                 plen = ntohs(phdr->param_length);
1387
1388                 if ((plen < sizeof(struct sctp_paramhdr)) ||
1389                     (offset + plen > length))
1390                         break;
1391
1392                 if (ptype == SCTP_RANDOM) {
1393                         if (plen > sizeof(random_store))
1394                                 break;
1395                         phdr = sctp_get_next_param(m, offset,
1396                             (struct sctp_paramhdr *)random_store, plen);
1397                         if (phdr == NULL)
1398                                 return;
1399                         /* save the random and length for the key */
1400                         p_random = (struct sctp_auth_random *)phdr;
1401                         random_len = plen - sizeof(*p_random);
1402                 } else if (ptype == SCTP_HMAC_LIST) {
1403                         uint16_t num_hmacs;
1404                         uint16_t i;
1405
1406                         if (plen > sizeof(hmacs_store))
1407                                 break;
1408                         phdr = sctp_get_next_param(m, offset,
1409                             (struct sctp_paramhdr *)hmacs_store, plen);
1410                         if (phdr == NULL)
1411                                 return;
1412                         /* save the hmacs list and num for the key */
1413                         hmacs = (struct sctp_auth_hmac_algo *)phdr;
1414                         hmacs_len = plen - sizeof(*hmacs);
1415                         num_hmacs = hmacs_len / sizeof(hmacs->hmac_ids[0]);
1416                         if (stcb->asoc.local_hmacs != NULL)
1417                                 sctp_free_hmaclist(stcb->asoc.local_hmacs);
1418                         stcb->asoc.local_hmacs = sctp_alloc_hmaclist(num_hmacs);
1419                         if (stcb->asoc.local_hmacs != NULL) {
1420                                 for (i = 0; i < num_hmacs; i++) {
1421                                         (void)sctp_auth_add_hmacid(stcb->asoc.local_hmacs,
1422                                             ntohs(hmacs->hmac_ids[i]));
1423                                 }
1424                         }
1425                 } else if (ptype == SCTP_CHUNK_LIST) {
1426                         int i;
1427
1428                         if (plen > sizeof(chunks_store))
1429                                 break;
1430                         phdr = sctp_get_next_param(m, offset,
1431                             (struct sctp_paramhdr *)chunks_store, plen);
1432                         if (phdr == NULL)
1433                                 return;
1434                         chunks = (struct sctp_auth_chunk_list *)phdr;
1435                         num_chunks = plen - sizeof(*chunks);
1436                         /* save chunks list and num for the key */
1437                         if (stcb->asoc.local_auth_chunks != NULL)
1438                                 sctp_clear_chunklist(stcb->asoc.local_auth_chunks);
1439                         else
1440                                 stcb->asoc.local_auth_chunks = sctp_alloc_chunklist();
1441                         for (i = 0; i < num_chunks; i++) {
1442                                 (void)sctp_auth_add_chunk(chunks->chunk_types[i],
1443                                     stcb->asoc.local_auth_chunks);
1444                         }
1445                 }
1446                 /* get next parameter */
1447                 offset += SCTP_SIZE32(plen);
1448                 if (offset + sizeof(struct sctp_paramhdr) > length)
1449                         break;
1450                 phdr = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
1451                     (uint8_t *)&tmp_param);
1452         }
1453         /* concatenate the full random key */
1454         keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
1455         if (chunks != NULL) {
1456                 keylen += sizeof(*chunks) + num_chunks;
1457         }
1458         new_key = sctp_alloc_key(keylen);
1459         if (new_key != NULL) {
1460                 /* copy in the RANDOM */
1461                 if (p_random != NULL) {
1462                         keylen = sizeof(*p_random) + random_len;
1463                         memcpy(new_key->key, p_random, keylen);
1464                 } else {
1465                         keylen = 0;
1466                 }
1467                 /* append in the AUTH chunks */
1468                 if (chunks != NULL) {
1469                         memcpy(new_key->key + keylen, chunks,
1470                             sizeof(*chunks) + num_chunks);
1471                         keylen += sizeof(*chunks) + num_chunks;
1472                 }
1473                 /* append in the HMACs */
1474                 if (hmacs != NULL) {
1475                         memcpy(new_key->key + keylen, hmacs,
1476                             sizeof(*hmacs) + hmacs_len);
1477                 }
1478         }
1479         if (stcb->asoc.authinfo.random != NULL)
1480                 sctp_free_key(stcb->asoc.authinfo.random);
1481         stcb->asoc.authinfo.random = new_key;
1482         stcb->asoc.authinfo.random_len = random_len;
1483         sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
1484         sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.recv_keyid);
1485
1486         /* negotiate what HMAC to use for the peer */
1487         stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs,
1488             stcb->asoc.local_hmacs);
1489
1490         /* copy defaults from the endpoint */
1491         /* FIX ME: put in cookie? */
1492         stcb->asoc.authinfo.active_keyid = stcb->sctp_ep->sctp_ep.default_keyid;
1493         /* copy out the shared key list (by reference) from the endpoint */
1494         (void)sctp_copy_skeylist(&stcb->sctp_ep->sctp_ep.shared_keys,
1495             &stcb->asoc.shared_keys);
1496 }
1497
1498 /*
1499  * compute and fill in the HMAC digest for a packet
1500  */
1501 void
1502 sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset,
1503     struct sctp_auth_chunk *auth, struct sctp_tcb *stcb, uint16_t keyid)
1504 {
1505         uint32_t digestlen;
1506         sctp_sharedkey_t *skey;
1507         sctp_key_t *key;
1508
1509         if ((stcb == NULL) || (auth == NULL))
1510                 return;
1511
1512         /* zero the digest + chunk padding */
1513         digestlen = sctp_get_hmac_digest_len(stcb->asoc.peer_hmac_id);
1514         memset(auth->hmac, 0, SCTP_SIZE32(digestlen));
1515
1516         /* is the desired key cached? */
1517         if ((keyid != stcb->asoc.authinfo.assoc_keyid) ||
1518             (stcb->asoc.authinfo.assoc_key == NULL)) {
1519                 if (stcb->asoc.authinfo.assoc_key != NULL) {
1520                         /* free the old cached key */
1521                         sctp_free_key(stcb->asoc.authinfo.assoc_key);
1522                 }
1523                 skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, keyid);
1524                 /* the only way skey is NULL is if null key id 0 is used */
1525                 if (skey != NULL)
1526                         key = skey->key;
1527                 else
1528                         key = NULL;
1529                 /* compute a new assoc key and cache it */
1530                 stcb->asoc.authinfo.assoc_key =
1531                     sctp_compute_hashkey(stcb->asoc.authinfo.random,
1532                     stcb->asoc.authinfo.peer_random, key);
1533                 stcb->asoc.authinfo.assoc_keyid = keyid;
1534                 SCTPDBG(SCTP_DEBUG_AUTH1, "caching key id %u\n",
1535                     stcb->asoc.authinfo.assoc_keyid);
1536 #ifdef SCTP_DEBUG
1537                 if (SCTP_AUTH_DEBUG)
1538                         sctp_print_key(stcb->asoc.authinfo.assoc_key,
1539                             "Assoc Key");
1540 #endif
1541         }
1542
1543         /* set in the active key id */
1544         auth->shared_key_id = htons(keyid);
1545
1546         /* compute and fill in the digest */
1547         (void)sctp_compute_hmac_m(stcb->asoc.peer_hmac_id, stcb->asoc.authinfo.assoc_key,
1548             m, auth_offset, auth->hmac);
1549 }
1550
1551 static void
1552 sctp_zero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
1553 {
1554         struct mbuf *m_tmp;
1555         uint8_t *data;
1556
1557         /* sanity check */
1558         if (m == NULL)
1559                 return;
1560
1561         /* find the correct starting mbuf and offset (get start position) */
1562         m_tmp = m;
1563         while ((m_tmp != NULL) && (m_offset >= (uint32_t)SCTP_BUF_LEN(m_tmp))) {
1564                 m_offset -= SCTP_BUF_LEN(m_tmp);
1565                 m_tmp = SCTP_BUF_NEXT(m_tmp);
1566         }
1567         /* now use the rest of the mbuf chain */
1568         while ((m_tmp != NULL) && (size > 0)) {
1569                 data = mtod(m_tmp, uint8_t *)+m_offset;
1570                 if (size > (uint32_t)(SCTP_BUF_LEN(m_tmp) - m_offset)) {
1571                         memset(data, 0, SCTP_BUF_LEN(m_tmp) - m_offset);
1572                         size -= SCTP_BUF_LEN(m_tmp) - m_offset;
1573                 } else {
1574                         memset(data, 0, size);
1575                         size = 0;
1576                 }
1577                 /* clear the offset since it's only for the first mbuf */
1578                 m_offset = 0;
1579                 m_tmp = SCTP_BUF_NEXT(m_tmp);
1580         }
1581 }
1582
1583 /*-
1584  * process the incoming Authentication chunk
1585  * return codes:
1586  *   -1 on any authentication error
1587  *    0 on authentication verification
1588  */
1589 int
1590 sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
1591     struct mbuf *m, uint32_t offset)
1592 {
1593         uint16_t chunklen;
1594         uint16_t shared_key_id;
1595         uint16_t hmac_id;
1596         sctp_sharedkey_t *skey;
1597         uint32_t digestlen;
1598         uint8_t digest[SCTP_AUTH_DIGEST_LEN_MAX];
1599         uint8_t computed_digest[SCTP_AUTH_DIGEST_LEN_MAX];
1600
1601         /* auth is checked for NULL by caller */
1602         chunklen = ntohs(auth->ch.chunk_length);
1603         if (chunklen < sizeof(*auth)) {
1604                 SCTP_STAT_INCR(sctps_recvauthfailed);
1605                 return (-1);
1606         }
1607         SCTP_STAT_INCR(sctps_recvauth);
1608
1609         /* get the auth params */
1610         shared_key_id = ntohs(auth->shared_key_id);
1611         hmac_id = ntohs(auth->hmac_id);
1612         SCTPDBG(SCTP_DEBUG_AUTH1,
1613             "SCTP AUTH Chunk: shared key %u, HMAC id %u\n",
1614             shared_key_id, hmac_id);
1615
1616         /* is the indicated HMAC supported? */
1617         if (!sctp_auth_is_supported_hmac(stcb->asoc.local_hmacs, hmac_id)) {
1618                 struct mbuf *op_err;
1619                 struct sctp_error_auth_invalid_hmac *cause;
1620
1621                 SCTP_STAT_INCR(sctps_recvivalhmacid);
1622                 SCTPDBG(SCTP_DEBUG_AUTH1,
1623                     "SCTP Auth: unsupported HMAC id %u\n",
1624                     hmac_id);
1625                 /*
1626                  * report this in an Error Chunk: Unsupported HMAC
1627                  * Identifier
1628                  */
1629                 op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_error_auth_invalid_hmac),
1630                     0, M_NOWAIT, 1, MT_HEADER);
1631                 if (op_err != NULL) {
1632                         /* pre-reserve some space */
1633                         SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
1634                         /* fill in the error */
1635                         cause = mtod(op_err, struct sctp_error_auth_invalid_hmac *);
1636                         cause->cause.code = htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
1637                         cause->cause.length = htons(sizeof(struct sctp_error_auth_invalid_hmac));
1638                         cause->hmac_id = ntohs(hmac_id);
1639                         SCTP_BUF_LEN(op_err) = sizeof(struct sctp_error_auth_invalid_hmac);
1640                         /* queue it */
1641                         sctp_queue_op_err(stcb, op_err);
1642                 }
1643                 return (-1);
1644         }
1645         /* get the indicated shared key, if available */
1646         if ((stcb->asoc.authinfo.recv_key == NULL) ||
1647             (stcb->asoc.authinfo.recv_keyid != shared_key_id)) {
1648                 /* find the shared key on the assoc first */
1649                 skey = sctp_find_sharedkey(&stcb->asoc.shared_keys,
1650                     shared_key_id);
1651                 /* if the shared key isn't found, discard the chunk */
1652                 if (skey == NULL) {
1653                         SCTP_STAT_INCR(sctps_recvivalkeyid);
1654                         SCTPDBG(SCTP_DEBUG_AUTH1,
1655                             "SCTP Auth: unknown key id %u\n",
1656                             shared_key_id);
1657                         return (-1);
1658                 }
1659                 /* generate a notification if this is a new key id */
1660                 if (stcb->asoc.authinfo.recv_keyid != shared_key_id)
1661                         /*
1662                          * sctp_ulp_notify(SCTP_NOTIFY_AUTH_NEW_KEY, stcb,
1663                          * shared_key_id, (void
1664                          * *)stcb->asoc.authinfo.recv_keyid);
1665                          */
1666                         sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY,
1667                             shared_key_id, stcb->asoc.authinfo.recv_keyid,
1668                             SCTP_SO_NOT_LOCKED);
1669                 /* compute a new recv assoc key and cache it */
1670                 if (stcb->asoc.authinfo.recv_key != NULL)
1671                         sctp_free_key(stcb->asoc.authinfo.recv_key);
1672                 stcb->asoc.authinfo.recv_key =
1673                     sctp_compute_hashkey(stcb->asoc.authinfo.random,
1674                     stcb->asoc.authinfo.peer_random, skey->key);
1675                 stcb->asoc.authinfo.recv_keyid = shared_key_id;
1676 #ifdef SCTP_DEBUG
1677                 if (SCTP_AUTH_DEBUG)
1678                         sctp_print_key(stcb->asoc.authinfo.recv_key, "Recv Key");
1679 #endif
1680         }
1681         /* validate the digest length */
1682         digestlen = sctp_get_hmac_digest_len(hmac_id);
1683         if (chunklen < (sizeof(*auth) + digestlen)) {
1684                 /* invalid digest length */
1685                 SCTP_STAT_INCR(sctps_recvauthfailed);
1686                 SCTPDBG(SCTP_DEBUG_AUTH1,
1687                     "SCTP Auth: chunk too short for HMAC\n");
1688                 return (-1);
1689         }
1690         /* save a copy of the digest, zero the pseudo header, and validate */
1691         memcpy(digest, auth->hmac, digestlen);
1692         sctp_zero_m(m, offset + sizeof(*auth), SCTP_SIZE32(digestlen));
1693         (void)sctp_compute_hmac_m(hmac_id, stcb->asoc.authinfo.recv_key,
1694             m, offset, computed_digest);
1695
1696         /* compare the computed digest with the one in the AUTH chunk */
1697         if (timingsafe_bcmp(digest, computed_digest, digestlen) != 0) {
1698                 SCTP_STAT_INCR(sctps_recvauthfailed);
1699                 SCTPDBG(SCTP_DEBUG_AUTH1,
1700                     "SCTP Auth: HMAC digest check failed\n");
1701                 return (-1);
1702         }
1703         return (0);
1704 }
1705
1706 /*
1707  * Generate NOTIFICATION
1708  */
1709 void
1710 sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
1711     uint16_t keyid, uint16_t alt_keyid, int so_locked)
1712 {
1713         struct mbuf *m_notify;
1714         struct sctp_authkey_event *auth;
1715         struct sctp_queued_to_read *control;
1716
1717         if ((stcb == NULL) ||
1718             (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
1719             (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
1720             (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)
1721             ) {
1722                 /* If the socket is gone we are out of here */
1723                 return;
1724         }
1725
1726         if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_AUTHEVNT))
1727                 /* event not enabled */
1728                 return;
1729
1730         m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_authkey_event),
1731             0, M_NOWAIT, 1, MT_HEADER);
1732         if (m_notify == NULL)
1733                 /* no space left */
1734                 return;
1735
1736         SCTP_BUF_LEN(m_notify) = 0;
1737         auth = mtod(m_notify, struct sctp_authkey_event *);
1738         memset(auth, 0, sizeof(struct sctp_authkey_event));
1739         auth->auth_type = SCTP_AUTHENTICATION_EVENT;
1740         auth->auth_flags = 0;
1741         auth->auth_length = sizeof(*auth);
1742         auth->auth_keynumber = keyid;
1743         auth->auth_altkeynumber = alt_keyid;
1744         auth->auth_indication = indication;
1745         auth->auth_assoc_id = sctp_get_associd(stcb);
1746
1747         SCTP_BUF_LEN(m_notify) = sizeof(*auth);
1748         SCTP_BUF_NEXT(m_notify) = NULL;
1749
1750         /* append to socket */
1751         control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
1752             0, 0, stcb->asoc.context, 0, 0, 0, m_notify);
1753         if (control == NULL) {
1754                 /* no memory */
1755                 sctp_m_freem(m_notify);
1756                 return;
1757         }
1758         control->length = SCTP_BUF_LEN(m_notify);
1759         control->spec_flags = M_NOTIFICATION;
1760         /* not that we need this */
1761         control->tail_mbuf = m_notify;
1762         sctp_add_to_readq(stcb->sctp_ep, stcb, control,
1763             &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
1764 }
1765
1766 /*-
1767  * validates the AUTHentication related parameters in an INIT/INIT-ACK
1768  * Note: currently only used for INIT as INIT-ACK is handled inline
1769  * with sctp_load_addresses_from_init()
1770  */
1771 int
1772 sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
1773 {
1774         struct sctp_paramhdr *phdr, param_buf;
1775         uint16_t ptype, plen;
1776         int peer_supports_asconf = 0;
1777         int peer_supports_auth = 0;
1778         int got_random = 0, got_hmacs = 0, got_chklist = 0;
1779         uint8_t saw_asconf = 0;
1780         uint8_t saw_asconf_ack = 0;
1781
1782         /* go through each of the params. */
1783         phdr = sctp_get_next_param(m, offset, &param_buf, sizeof(param_buf));
1784         while (phdr) {
1785                 ptype = ntohs(phdr->param_type);
1786                 plen = ntohs(phdr->param_length);
1787
1788                 if (offset + plen > limit) {
1789                         break;
1790                 }
1791                 if (plen < sizeof(struct sctp_paramhdr)) {
1792                         break;
1793                 }
1794                 if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
1795                         /* A supported extension chunk */
1796                         struct sctp_supported_chunk_types_param *pr_supported;
1797                         uint8_t local_store[SCTP_SMALL_CHUNK_STORE];
1798                         int num_ent, i;
1799
1800                         if (plen > sizeof(local_store)) {
1801                                 break;
1802                         }
1803                         phdr = sctp_get_next_param(m, offset,
1804                             (struct sctp_paramhdr *)&local_store,
1805                             plen);
1806                         if (phdr == NULL) {
1807                                 return (-1);
1808                         }
1809                         pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
1810                         num_ent = plen - sizeof(struct sctp_paramhdr);
1811                         for (i = 0; i < num_ent; i++) {
1812                                 switch (pr_supported->chunk_types[i]) {
1813                                 case SCTP_ASCONF:
1814                                 case SCTP_ASCONF_ACK:
1815                                         peer_supports_asconf = 1;
1816                                         break;
1817                                 default:
1818                                         /* one we don't care about */
1819                                         break;
1820                                 }
1821                         }
1822                 } else if (ptype == SCTP_RANDOM) {
1823                         /* enforce the random length */
1824                         if (plen != (sizeof(struct sctp_auth_random) +
1825                             SCTP_AUTH_RANDOM_SIZE_REQUIRED)) {
1826                                 SCTPDBG(SCTP_DEBUG_AUTH1,
1827                                     "SCTP: invalid RANDOM len\n");
1828                                 return (-1);
1829                         }
1830                         got_random = 1;
1831                 } else if (ptype == SCTP_HMAC_LIST) {
1832                         struct sctp_auth_hmac_algo *hmacs;
1833                         uint8_t store[SCTP_PARAM_BUFFER_SIZE];
1834                         int num_hmacs;
1835
1836                         if (plen > sizeof(store)) {
1837                                 break;
1838                         }
1839                         phdr = sctp_get_next_param(m, offset,
1840                             (struct sctp_paramhdr *)store,
1841                             plen);
1842                         if (phdr == NULL) {
1843                                 return (-1);
1844                         }
1845                         hmacs = (struct sctp_auth_hmac_algo *)phdr;
1846                         num_hmacs = (plen - sizeof(*hmacs)) / sizeof(hmacs->hmac_ids[0]);
1847                         /* validate the hmac list */
1848                         if (sctp_verify_hmac_param(hmacs, num_hmacs)) {
1849                                 SCTPDBG(SCTP_DEBUG_AUTH1,
1850                                     "SCTP: invalid HMAC param\n");
1851                                 return (-1);
1852                         }
1853                         got_hmacs = 1;
1854                 } else if (ptype == SCTP_CHUNK_LIST) {
1855                         struct sctp_auth_chunk_list *chunks;
1856                         uint8_t chunks_store[SCTP_SMALL_CHUNK_STORE];
1857                         int i, num_chunks;
1858
1859                         if (plen > sizeof(chunks_store)) {
1860                                 break;
1861                         }
1862                         phdr = sctp_get_next_param(m, offset,
1863                             (struct sctp_paramhdr *)chunks_store,
1864                             plen);
1865                         if (phdr == NULL) {
1866                                 return (-1);
1867                         }
1868                         /*-
1869                          * Flip through the list and mark that the
1870                          * peer supports asconf/asconf_ack.
1871                          */
1872                         chunks = (struct sctp_auth_chunk_list *)phdr;
1873                         num_chunks = plen - sizeof(*chunks);
1874                         for (i = 0; i < num_chunks; i++) {
1875                                 /* record asconf/asconf-ack if listed */
1876                                 if (chunks->chunk_types[i] == SCTP_ASCONF)
1877                                         saw_asconf = 1;
1878                                 if (chunks->chunk_types[i] == SCTP_ASCONF_ACK)
1879                                         saw_asconf_ack = 1;
1880                         }
1881                         if (num_chunks)
1882                                 got_chklist = 1;
1883                 }
1884
1885                 offset += SCTP_SIZE32(plen);
1886                 if (offset >= limit) {
1887                         break;
1888                 }
1889                 phdr = sctp_get_next_param(m, offset, &param_buf,
1890                     sizeof(param_buf));
1891         }
1892         /* validate authentication required parameters */
1893         if (got_random && got_hmacs) {
1894                 peer_supports_auth = 1;
1895         } else {
1896                 peer_supports_auth = 0;
1897         }
1898         if (!peer_supports_auth && got_chklist) {
1899                 SCTPDBG(SCTP_DEBUG_AUTH1,
1900                     "SCTP: peer sent chunk list w/o AUTH\n");
1901                 return (-1);
1902         }
1903         if (peer_supports_asconf && !peer_supports_auth) {
1904                 SCTPDBG(SCTP_DEBUG_AUTH1,
1905                     "SCTP: peer supports ASCONF but not AUTH\n");
1906                 return (-1);
1907         } else if ((peer_supports_asconf) && (peer_supports_auth) &&
1908             ((saw_asconf == 0) || (saw_asconf_ack == 0))) {
1909                 return (-2);
1910         }
1911         return (0);
1912 }
1913
1914 void
1915 sctp_initialize_auth_params(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
1916 {
1917         uint16_t chunks_len = 0;
1918         uint16_t hmacs_len = 0;
1919         uint16_t random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT;
1920         sctp_key_t *new_key;
1921         uint16_t keylen;
1922
1923         /* initialize hmac list from endpoint */
1924         stcb->asoc.local_hmacs = sctp_copy_hmaclist(inp->sctp_ep.local_hmacs);
1925         if (stcb->asoc.local_hmacs != NULL) {
1926                 hmacs_len = stcb->asoc.local_hmacs->num_algo *
1927                     sizeof(stcb->asoc.local_hmacs->hmac[0]);
1928         }
1929         /* initialize auth chunks list from endpoint */
1930         stcb->asoc.local_auth_chunks =
1931             sctp_copy_chunklist(inp->sctp_ep.local_auth_chunks);
1932         if (stcb->asoc.local_auth_chunks != NULL) {
1933                 int i;
1934
1935                 for (i = 0; i < 256; i++) {
1936                         if (stcb->asoc.local_auth_chunks->chunks[i])
1937                                 chunks_len++;
1938                 }
1939         }
1940         /* copy defaults from the endpoint */
1941         stcb->asoc.authinfo.active_keyid = inp->sctp_ep.default_keyid;
1942
1943         /* copy out the shared key list (by reference) from the endpoint */
1944         (void)sctp_copy_skeylist(&inp->sctp_ep.shared_keys,
1945             &stcb->asoc.shared_keys);
1946
1947         /* now set the concatenated key (random + chunks + hmacs) */
1948         /* key includes parameter headers */
1949         keylen = (3 * sizeof(struct sctp_paramhdr)) + random_len + chunks_len +
1950             hmacs_len;
1951         new_key = sctp_alloc_key(keylen);
1952         if (new_key != NULL) {
1953                 struct sctp_paramhdr *ph;
1954                 int plen;
1955
1956                 /* generate and copy in the RANDOM */
1957                 ph = (struct sctp_paramhdr *)new_key->key;
1958                 ph->param_type = htons(SCTP_RANDOM);
1959                 plen = sizeof(*ph) + random_len;
1960                 ph->param_length = htons(plen);
1961                 SCTP_READ_RANDOM(new_key->key + sizeof(*ph), random_len);
1962                 keylen = plen;
1963
1964                 /* append in the AUTH chunks */
1965                 /* NOTE: currently we always have chunks to list */
1966                 ph = (struct sctp_paramhdr *)(new_key->key + keylen);
1967                 ph->param_type = htons(SCTP_CHUNK_LIST);
1968                 plen = sizeof(*ph) + chunks_len;
1969                 ph->param_length = htons(plen);
1970                 keylen += sizeof(*ph);
1971                 if (stcb->asoc.local_auth_chunks) {
1972                         int i;
1973
1974                         for (i = 0; i < 256; i++) {
1975                                 if (stcb->asoc.local_auth_chunks->chunks[i])
1976                                         new_key->key[keylen++] = i;
1977                         }
1978                 }
1979
1980                 /* append in the HMACs */
1981                 ph = (struct sctp_paramhdr *)(new_key->key + keylen);
1982                 ph->param_type = htons(SCTP_HMAC_LIST);
1983                 plen = sizeof(*ph) + hmacs_len;
1984                 ph->param_length = htons(plen);
1985                 keylen += sizeof(*ph);
1986                 (void)sctp_serialize_hmaclist(stcb->asoc.local_hmacs,
1987                     new_key->key + keylen);
1988         }
1989         if (stcb->asoc.authinfo.random != NULL)
1990                 sctp_free_key(stcb->asoc.authinfo.random);
1991         stcb->asoc.authinfo.random = new_key;
1992         stcb->asoc.authinfo.random_len = random_len;
1993 }