]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet/sctp_auth.c
- most all includes (#include <>) migrate to the sctp_os_bsd.h file
[FreeBSD/FreeBSD.git] / sys / netinet / sctp_auth.c
1 /*-
2  * Copyright (c) 2001-2006, Cisco Systems, Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * a) Redistributions of source code must retain the above copyright notice,
8  *   this list of conditions and the following disclaimer.
9  *
10  * b) Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *   the documentation and/or other materials provided with the distribution.
13  *
14  * c) Neither the name of Cisco Systems, Inc. nor the names of its
15  *    contributors may be used to endorse or promote products derived
16  *    from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <netinet/sctp_os.h>
35 #include <netinet/sctp.h>
36 #include <netinet/sctp_header.h>
37 #include <netinet/sctp_pcb.h>
38 #include <netinet/sctp_var.h>
39 #include <netinet/sctputil.h>
40 #include <netinet/sctp_indata.h>
41 #include <netinet/sctp_output.h>
42 #include <netinet/sctp_auth.h>
43
44 #ifdef SCTP_DEBUG
45 extern uint32_t sctp_debug_on;
46
47 #define SCTP_AUTH_DEBUG         (sctp_debug_on & SCTP_DEBUG_AUTH1)
48 #define SCTP_AUTH_DEBUG2        (sctp_debug_on & SCTP_DEBUG_AUTH2)
49 #endif                          /* SCTP_DEBUG */
50
51
52 inline void
53 sctp_clear_chunklist(sctp_auth_chklist_t * chklist)
54 {
55         bzero(chklist, sizeof(*chklist));
56         /* chklist->num_chunks = 0; */
57 }
58
59 sctp_auth_chklist_t *
60 sctp_alloc_chunklist(void)
61 {
62         sctp_auth_chklist_t *chklist;
63
64         SCTP_MALLOC(chklist, sctp_auth_chklist_t *, sizeof(*chklist),
65             "AUTH chklist");
66         if (chklist == NULL) {
67 #ifdef SCTP_DEBUG
68                 if (sctp_debug_on & SCTP_AUTH_DEBUG) {
69                         printf("sctp_alloc_chunklist: failed to get memory!\n");
70                 }
71 #endif                          /* SCTP_DEBUG */
72         } else {
73                 sctp_clear_chunklist(chklist);
74         }
75         return (chklist);
76 }
77
78 void
79 sctp_free_chunklist(sctp_auth_chklist_t * list)
80 {
81         if (list != NULL)
82                 SCTP_FREE(list);
83 }
84
85 sctp_auth_chklist_t *
86 sctp_copy_chunklist(sctp_auth_chklist_t * list)
87 {
88         sctp_auth_chklist_t *new_list;
89
90         if (list == NULL)
91                 return (NULL);
92
93         /* get a new list */
94         new_list = sctp_alloc_chunklist();
95         if (new_list == NULL)
96                 return (NULL);
97         /* copy it */
98         bcopy(list, new_list, sizeof(*new_list));
99
100         return (new_list);
101 }
102
103
104 /*
105  * add a chunk to the required chunks list
106  */
107 int
108 sctp_auth_add_chunk(uint8_t chunk, sctp_auth_chklist_t * list)
109 {
110         if (list == NULL)
111                 return (-1);
112
113         /* is chunk restricted? */
114         if ((chunk == SCTP_INITIATION) ||
115             (chunk == SCTP_INITIATION_ACK) ||
116             (chunk == SCTP_SHUTDOWN_COMPLETE) ||
117             (chunk == SCTP_AUTHENTICATION)) {
118                 return (-1);
119         }
120         if (list->chunks[chunk] == 0) {
121                 list->chunks[chunk] = 1;
122                 list->num_chunks++;
123 #ifdef SCTP_DEBUG
124                 if (SCTP_AUTH_DEBUG)
125                         printf("SCTP: added chunk %u (0x%02x) to Auth list\n",
126                             chunk, chunk);
127 #endif
128         }
129         return (0);
130 }
131
132 /*
133  * delete a chunk from the required chunks list
134  */
135 int
136 sctp_auth_delete_chunk(uint8_t chunk, sctp_auth_chklist_t * list)
137 {
138         if (list == NULL)
139                 return (-1);
140
141         /* is chunk restricted? */
142         if ((chunk == SCTP_ASCONF) ||
143             (chunk == SCTP_ASCONF_ACK)) {
144                 return (-1);
145         }
146         if (list->chunks[chunk] == 1) {
147                 list->chunks[chunk] = 0;
148                 list->num_chunks--;
149 #ifdef SCTP_DEBUG
150                 if (SCTP_AUTH_DEBUG)
151                         printf("SCTP: deleted chunk %u (0x%02x) from Auth list\n",
152                             chunk, chunk);
153 #endif
154         }
155         return (0);
156 }
157
158 inline int
159 sctp_auth_get_chklist_size(const sctp_auth_chklist_t * list)
160 {
161         if (list == NULL)
162                 return (0);
163         else
164                 return (list->num_chunks);
165 }
166
167 /*
168  * set the default list of chunks requiring AUTH
169  */
170 void
171 sctp_auth_set_default_chunks(sctp_auth_chklist_t * list)
172 {
173         sctp_auth_add_chunk(SCTP_ASCONF, list);
174         sctp_auth_add_chunk(SCTP_ASCONF_ACK, list);
175 }
176
177 /*
178  * return the current number and list of required chunks caller must
179  * guarantee ptr has space for up to 256 bytes
180  */
181 int
182 sctp_serialize_auth_chunks(const sctp_auth_chklist_t * list, uint8_t * ptr)
183 {
184         int i, count = 0;
185
186         if (list == NULL)
187                 return (0);
188
189         for (i = 0; i < 256; i++) {
190                 if (list->chunks[i] != 0) {
191                         *ptr++ = i;
192                         count++;
193                 }
194         }
195         return (count);
196 }
197
198 int
199 sctp_pack_auth_chunks(const sctp_auth_chklist_t * list, uint8_t * ptr)
200 {
201         int i, size = 0;
202
203         if (list == NULL)
204                 return (0);
205
206         if (list->num_chunks <= 32) {
207                 /* just list them, one byte each */
208                 for (i = 0; i < 256; i++) {
209                         if (list->chunks[i] != 0) {
210                                 *ptr++ = i;
211                                 size++;
212                         }
213                 }
214         } else {
215                 int index, offset;
216
217                 /* pack into a 32 byte bitfield */
218                 for (i = 0; i < 256; i++) {
219                         if (list->chunks[i] != 0) {
220                                 index = i / 8;
221                                 offset = i % 8;
222                                 ptr[index] |= (1 << offset);
223                         }
224                 }
225                 size = 32;
226         }
227         return (size);
228 }
229
230 int
231 sctp_unpack_auth_chunks(const uint8_t * ptr, uint8_t num_chunks,
232     sctp_auth_chklist_t * list)
233 {
234         int i;
235         int size;
236
237         if (list == NULL)
238                 return (0);
239
240         if (num_chunks <= 32) {
241                 /* just pull them, one byte each */
242                 for (i = 0; i < num_chunks; i++) {
243                         sctp_auth_add_chunk(*ptr++, list);
244                 }
245                 size = num_chunks;
246         } else {
247                 int index, offset;
248
249                 /* unpack from a 32 byte bitfield */
250                 for (index = 0; index < 32; index++) {
251                         for (offset = 0; offset < 8; offset++) {
252                                 if (ptr[index] & (1 << offset)) {
253                                         sctp_auth_add_chunk((index * 8) + offset, list);
254                                 }
255                         }
256                 }
257                 size = 32;
258         }
259         return (size);
260 }
261
262
263 /*
264  * allocate structure space for a key of length keylen
265  */
266 sctp_key_t *
267 sctp_alloc_key(uint32_t keylen)
268 {
269         sctp_key_t *new_key;
270
271         SCTP_MALLOC(new_key, sctp_key_t *, sizeof(*new_key) + keylen,
272             "AUTH key");
273         if (new_key == NULL) {
274                 /* out of memory */
275                 return (NULL);
276         }
277         new_key->keylen = keylen;
278         return (new_key);
279 }
280
281 void
282 sctp_free_key(sctp_key_t * key)
283 {
284         if (key != NULL)
285                 SCTP_FREE(key);
286 }
287
288 void
289 sctp_print_key(sctp_key_t * key, const char *str)
290 {
291         uint32_t i;
292
293         if (key == NULL) {
294                 printf("%s: [Null key]\n", str);
295                 return;
296         }
297         printf("%s: len %u, ", str, key->keylen);
298         if (key->keylen) {
299                 for (i = 0; i < key->keylen; i++)
300                         printf("%02x", key->key[i]);
301                 printf("\n");
302         } else {
303                 printf("[Null key]\n");
304         }
305 }
306
307 void
308 sctp_show_key(sctp_key_t * key, const char *str)
309 {
310         uint32_t i;
311
312         if (key == NULL) {
313                 printf("%s: [Null key]\n", str);
314                 return;
315         }
316         printf("%s: len %u, ", str, key->keylen);
317         if (key->keylen) {
318                 for (i = 0; i < key->keylen; i++)
319                         printf("%02x", key->key[i]);
320                 printf("\n");
321         } else {
322                 printf("[Null key]\n");
323         }
324 }
325
326 static inline uint32_t
327 sctp_get_keylen(sctp_key_t * key)
328 {
329         if (key != NULL)
330                 return (key->keylen);
331         else
332                 return (0);
333 }
334
335 /*
336  * generate a new random key of length 'keylen'
337  */
338 sctp_key_t *
339 sctp_generate_random_key(uint32_t keylen)
340 {
341         sctp_key_t *new_key;
342
343         /* validate keylen */
344         if (keylen > SCTP_AUTH_RANDOM_SIZE_MAX)
345                 keylen = SCTP_AUTH_RANDOM_SIZE_MAX;
346
347         new_key = sctp_alloc_key(keylen);
348         if (new_key == NULL) {
349                 /* out of memory */
350                 return (NULL);
351         }
352         SCTP_READ_RANDOM(new_key->key, keylen);
353         new_key->keylen = keylen;
354         return (new_key);
355 }
356
357 sctp_key_t *
358 sctp_set_key(uint8_t * key, uint32_t keylen)
359 {
360         sctp_key_t *new_key;
361
362         new_key = sctp_alloc_key(keylen);
363         if (new_key == NULL) {
364                 /* out of memory */
365                 return (NULL);
366         }
367         bcopy(key, new_key->key, keylen);
368         return (new_key);
369 }
370
371 /*
372  * given two keys of variable size, compute which key is "larger/smaller"
373  * returns: 1 if key1 > key2 -1 if key1 < key2 0 if key1 = key2
374  */
375 static int
376 sctp_compare_key(sctp_key_t * key1, sctp_key_t * key2)
377 {
378         uint32_t maxlen;
379         uint32_t i;
380         uint32_t key1len, key2len;
381         uint8_t *key_1, *key_2;
382         uint8_t temp[SCTP_AUTH_RANDOM_SIZE_MAX];
383
384         /* sanity/length check */
385         key1len = sctp_get_keylen(key1);
386         key2len = sctp_get_keylen(key2);
387         if ((key1len == 0) && (key2len == 0))
388                 return (0);
389         else if (key1len == 0)
390                 return (-1);
391         else if (key2len == 0)
392                 return (1);
393
394         if (key1len != key2len) {
395                 if (key1len >= key2len)
396                         maxlen = key1len;
397                 else
398                         maxlen = key2len;
399                 bzero(temp, maxlen);
400                 if (key1len < maxlen) {
401                         /* prepend zeroes to key1 */
402                         bcopy(key1->key, temp + (maxlen - key1len), key1len);
403                         key_1 = temp;
404                         key_2 = key2->key;
405                 } else {
406                         /* prepend zeroes to key2 */
407                         bcopy(key2->key, temp + (maxlen - key2len), key2len);
408                         key_1 = key1->key;
409                         key_2 = temp;
410                 }
411         } else {
412                 maxlen = key1len;
413                 key_1 = key1->key;
414                 key_2 = key2->key;
415         }
416
417         for (i = 0; i < maxlen; i++) {
418                 if (*key_1 > *key_2)
419                         return (1);
420                 else if (*key_1 < *key_2)
421                         return (-1);
422                 key_1++;
423                 key_2++;
424         }
425
426         /* keys are equal value, so check lengths */
427         if (key1len == key2len)
428                 return (0);
429         else if (key1len < key2len)
430                 return (-1);
431         else
432                 return (1);
433 }
434
435 /*
436  * generate the concatenated keying material based on the two keys and the
437  * shared key (if available). draft-ietf-tsvwg-auth specifies the specific
438  * order for concatenation
439  */
440 sctp_key_t *
441 sctp_compute_hashkey(sctp_key_t * key1, sctp_key_t * key2, sctp_key_t * shared)
442 {
443         uint32_t keylen;
444         sctp_key_t *new_key;
445         uint8_t *key_ptr;
446
447         keylen = sctp_get_keylen(key1) + sctp_get_keylen(key2) +
448             sctp_get_keylen(shared);
449
450         if (keylen > 0) {
451                 /* get space for the new key */
452                 new_key = sctp_alloc_key(keylen);
453                 if (new_key == NULL) {
454                         /* out of memory */
455                         return (NULL);
456                 }
457                 new_key->keylen = keylen;
458                 key_ptr = new_key->key;
459         } else {
460                 /* all keys empty/null?! */
461                 return (NULL);
462         }
463
464         /* concatenate the keys */
465         if (sctp_compare_key(key1, key2) <= 0) {
466                 /* key is key1 + shared + key2 */
467                 if (sctp_get_keylen(key1)) {
468                         bcopy(key1->key, key_ptr, key1->keylen);
469                         key_ptr += key1->keylen;
470                 }
471                 if (sctp_get_keylen(shared)) {
472                         bcopy(shared->key, key_ptr, shared->keylen);
473                         key_ptr += shared->keylen;
474                 }
475                 if (sctp_get_keylen(key2)) {
476                         bcopy(key2->key, key_ptr, key2->keylen);
477                         key_ptr += key2->keylen;
478                 }
479         } else {
480                 /* key is key2 + shared + key1 */
481                 if (sctp_get_keylen(key2)) {
482                         bcopy(key2->key, key_ptr, key2->keylen);
483                         key_ptr += key2->keylen;
484                 }
485                 if (sctp_get_keylen(shared)) {
486                         bcopy(shared->key, key_ptr, shared->keylen);
487                         key_ptr += shared->keylen;
488                 }
489                 if (sctp_get_keylen(key1)) {
490                         bcopy(key1->key, key_ptr, key1->keylen);
491                         key_ptr += key1->keylen;
492                 }
493         }
494         return (new_key);
495 }
496
497
498 sctp_sharedkey_t *
499 sctp_alloc_sharedkey(void)
500 {
501         sctp_sharedkey_t *new_key;
502
503         SCTP_MALLOC(new_key, sctp_sharedkey_t *, sizeof(*new_key),
504             "AUTH skey");
505         if (new_key == NULL) {
506                 /* out of memory */
507                 return (NULL);
508         }
509         new_key->keyid = 0;
510         new_key->key = NULL;
511         return (new_key);
512 }
513
514 void
515 sctp_free_sharedkey(sctp_sharedkey_t * skey)
516 {
517         if (skey != NULL) {
518                 if (skey->key != NULL)
519                         sctp_free_key(skey->key);
520                 SCTP_FREE(skey);
521         }
522 }
523
524 sctp_sharedkey_t *
525 sctp_find_sharedkey(struct sctp_keyhead *shared_keys, uint16_t key_id)
526 {
527         sctp_sharedkey_t *skey;
528
529         LIST_FOREACH(skey, shared_keys, next) {
530                 if (skey->keyid == key_id)
531                         return (skey);
532         }
533         return (NULL);
534 }
535
536 void
537 sctp_insert_sharedkey(struct sctp_keyhead *shared_keys,
538     sctp_sharedkey_t * new_skey)
539 {
540         sctp_sharedkey_t *skey;
541
542         if ((shared_keys == NULL) || (new_skey == NULL))
543                 return;
544
545         /* insert into an empty list? */
546         if (LIST_EMPTY(shared_keys)) {
547                 LIST_INSERT_HEAD(shared_keys, new_skey, next);
548                 return;
549         }
550         /* insert into the existing list, ordered by key id */
551         LIST_FOREACH(skey, shared_keys, next) {
552                 if (new_skey->keyid < skey->keyid) {
553                         /* insert it before here */
554                         LIST_INSERT_BEFORE(skey, new_skey, next);
555                         return;
556                 } else if (new_skey->keyid == skey->keyid) {
557                         /* replace the existing key */
558 #ifdef SCTP_DEBUG
559                         if (SCTP_AUTH_DEBUG)
560                                 printf("replacing shared key id %u\n", new_skey->keyid);
561 #endif
562                         LIST_INSERT_BEFORE(skey, new_skey, next);
563                         LIST_REMOVE(skey, next);
564                         sctp_free_sharedkey(skey);
565                         return;
566                 }
567                 if (LIST_NEXT(skey, next) == NULL) {
568                         /* belongs at the end of the list */
569                         LIST_INSERT_AFTER(skey, new_skey, next);
570                         return;
571                 }
572         }
573 }
574
575 static sctp_sharedkey_t *
576 sctp_copy_sharedkey(const sctp_sharedkey_t * skey)
577 {
578         sctp_sharedkey_t *new_skey;
579
580         if (skey == NULL)
581                 return (NULL);
582         new_skey = sctp_alloc_sharedkey();
583         if (new_skey == NULL)
584                 return (NULL);
585         if (skey->key != NULL)
586                 new_skey->key = sctp_set_key(skey->key->key, skey->key->keylen);
587         else
588                 new_skey->key = NULL;
589         new_skey->keyid = skey->keyid;
590         return (new_skey);
591 }
592
593 int
594 sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest)
595 {
596         sctp_sharedkey_t *skey, *new_skey;
597         int count = 0;
598
599         if ((src == NULL) || (dest == NULL))
600                 return (0);
601         LIST_FOREACH(skey, src, next) {
602                 new_skey = sctp_copy_sharedkey(skey);
603                 if (new_skey != NULL) {
604                         sctp_insert_sharedkey(dest, new_skey);
605                         count++;
606                 }
607         }
608         return (count);
609 }
610
611
612 sctp_hmaclist_t *
613 sctp_alloc_hmaclist(uint8_t num_hmacs)
614 {
615         sctp_hmaclist_t *new_list;
616         int alloc_size;
617
618         alloc_size = sizeof(*new_list) + num_hmacs * sizeof(new_list->hmac[0]);
619         SCTP_MALLOC(new_list, sctp_hmaclist_t *, alloc_size,
620             "AUTH HMAC list");
621         if (new_list == NULL) {
622                 /* out of memory */
623                 return (NULL);
624         }
625         new_list->max_algo = num_hmacs;
626         new_list->num_algo = 0;
627         return (new_list);
628 }
629
630 void
631 sctp_free_hmaclist(sctp_hmaclist_t * list)
632 {
633         if (list != NULL) {
634                 SCTP_FREE(list);
635                 list = NULL;
636         }
637 }
638
639 int
640 sctp_auth_add_hmacid(sctp_hmaclist_t * list, uint16_t hmac_id)
641 {
642         if (list == NULL)
643                 return (-1);
644         if (list->num_algo == list->max_algo) {
645 #ifdef SCTP_DEBUG
646                 if (SCTP_AUTH_DEBUG)
647                         printf("SCTP: HMAC id list full, ignoring add %u\n", hmac_id);
648 #endif
649                 return (-1);
650         }
651         if ((hmac_id != SCTP_AUTH_HMAC_ID_SHA1) &&
652 #ifdef HAVE_SHA224
653             (hmac_id != SCTP_AUTH_HMAC_ID_SHA224) &&
654 #endif
655 #ifdef HAVE_SHA2
656             (hmac_id != SCTP_AUTH_HMAC_ID_SHA256) &&
657             (hmac_id != SCTP_AUTH_HMAC_ID_SHA384) &&
658             (hmac_id != SCTP_AUTH_HMAC_ID_SHA512) &&
659 #endif
660             (hmac_id != SCTP_AUTH_HMAC_ID_MD5)) {
661                 return (-1);
662         }
663 #ifdef SCTP_DEBUG
664         if (SCTP_AUTH_DEBUG)
665                 printf("SCTP: add HMAC id %u to list\n", hmac_id);
666 #endif
667         list->hmac[list->num_algo++] = hmac_id;
668         return (0);
669 }
670
671 sctp_hmaclist_t *
672 sctp_copy_hmaclist(sctp_hmaclist_t * list)
673 {
674         sctp_hmaclist_t *new_list;
675         int i;
676
677         if (list == NULL)
678                 return (NULL);
679         /* get a new list */
680         new_list = sctp_alloc_hmaclist(list->max_algo);
681         if (new_list == NULL)
682                 return (NULL);
683         /* copy it */
684         new_list->max_algo = list->max_algo;
685         new_list->num_algo = list->num_algo;
686         for (i = 0; i < list->num_algo; i++)
687                 new_list->hmac[i] = list->hmac[i];
688         return (new_list);
689 }
690
691 sctp_hmaclist_t *
692 sctp_default_supported_hmaclist(void)
693 {
694         sctp_hmaclist_t *new_list;
695
696         new_list = sctp_alloc_hmaclist(2);
697         if (new_list == NULL)
698                 return (NULL);
699         sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1);
700         sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA256);
701         return (new_list);
702 }
703
704 /*
705  * HMAC algos are listed in priority/preference order find the best HMAC id
706  * to use for the peer based on local support
707  */
708 uint16_t
709 sctp_negotiate_hmacid(sctp_hmaclist_t * peer, sctp_hmaclist_t * local)
710 {
711         int i, j;
712
713         if ((local == NULL) || (peer == NULL))
714                 return (SCTP_AUTH_HMAC_ID_RSVD);
715
716         for (i = 0; i < peer->num_algo; i++) {
717                 for (j = 0; j < local->num_algo; j++) {
718                         if (peer->hmac[i] == local->hmac[j]) {
719 #ifndef SCTP_AUTH_DRAFT_04
720                                 /* "skip" MD5 as it's been deprecated */
721                                 if (peer->hmac[i] == SCTP_AUTH_HMAC_ID_MD5)
722                                         continue;
723 #endif
724
725                                 /* found the "best" one */
726 #ifdef SCTP_DEBUG
727                                 if (SCTP_AUTH_DEBUG)
728                                         printf("SCTP: negotiated peer HMAC id %u\n", peer->hmac[i]);
729 #endif
730                                 return (peer->hmac[i]);
731                         }
732                 }
733         }
734         /* didn't find one! */
735         return (SCTP_AUTH_HMAC_ID_RSVD);
736 }
737
738 /*
739  * serialize the HMAC algo list and return space used caller must guarantee
740  * ptr has appropriate space
741  */
742 int
743 sctp_serialize_hmaclist(sctp_hmaclist_t * list, uint8_t * ptr)
744 {
745         int i;
746         uint16_t hmac_id;
747
748         if (list == NULL)
749                 return (0);
750
751         for (i = 0; i < list->num_algo; i++) {
752                 hmac_id = htons(list->hmac[i]);
753                 bcopy(&hmac_id, ptr, sizeof(hmac_id));
754                 ptr += sizeof(hmac_id);
755         }
756         return (list->num_algo * sizeof(hmac_id));
757 }
758
759 int
760 sctp_verify_hmac_param(struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs)
761 {
762         uint32_t i;
763         uint16_t hmac_id;
764         uint32_t sha1_supported = 0;
765
766         for (i = 0; i < num_hmacs; i++) {
767                 hmac_id = ntohs(hmacs->hmac_ids[i]);
768                 if (hmac_id == SCTP_AUTH_HMAC_ID_SHA1)
769                         sha1_supported = 1;
770         }
771         /* all HMAC id's are supported */
772         if (sha1_supported == 0)
773                 return (-1);
774         else
775                 return (0);
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             "AUTH info");
785         if (new_authinfo == NULL) {
786                 /* out of memory */
787                 return (NULL);
788         }
789         bzero(&new_authinfo, sizeof(*new_authinfo));
790         return (new_authinfo);
791 }
792
793 void
794 sctp_free_authinfo(sctp_authinfo_t * authinfo)
795 {
796         if (authinfo == NULL)
797                 return;
798
799         if (authinfo->random != NULL)
800                 sctp_free_key(authinfo->random);
801         if (authinfo->peer_random != NULL)
802                 sctp_free_key(authinfo->peer_random);
803         if (authinfo->assoc_key != NULL)
804                 sctp_free_key(authinfo->assoc_key);
805         if (authinfo->recv_key != NULL)
806                 sctp_free_key(authinfo->recv_key);
807
808         /* We are NOT dynamically allocating authinfo's right now... */
809         /* SCTP_FREE(authinfo); */
810 }
811
812
813 inline 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_MD5:
829                 return (SCTP_AUTH_DIGEST_LEN_MD5);
830 #ifdef HAVE_SHA224
831         case SCTP_AUTH_HMAC_ID_SHA224:
832                 return (SCTP_AUTH_DIGEST_LEN_SHA224);
833 #endif
834 #ifdef HAVE_SHA2
835         case SCTP_AUTH_HMAC_ID_SHA256:
836                 return (SCTP_AUTH_DIGEST_LEN_SHA256);
837         case SCTP_AUTH_HMAC_ID_SHA384:
838                 return (SCTP_AUTH_DIGEST_LEN_SHA384);
839         case SCTP_AUTH_HMAC_ID_SHA512:
840                 return (SCTP_AUTH_DIGEST_LEN_SHA512);
841 #endif
842         default:
843                 /* unknown HMAC algorithm: can't do anything */
844                 return (0);
845         }                       /* end switch */
846 }
847
848 static inline int
849 sctp_get_hmac_block_len(uint16_t hmac_algo)
850 {
851         switch (hmac_algo) {
852                 case SCTP_AUTH_HMAC_ID_SHA1:
853                 case SCTP_AUTH_HMAC_ID_MD5:
854 #ifdef HAVE_SHA224
855                 case SCTP_AUTH_HMAC_ID_SHA224:
856                 return (64);
857 #endif
858 #ifdef HAVE_SHA2
859         case SCTP_AUTH_HMAC_ID_SHA256:
860                 return (64);
861         case SCTP_AUTH_HMAC_ID_SHA384:
862         case SCTP_AUTH_HMAC_ID_SHA512:
863                 return (128);
864 #endif
865         case SCTP_AUTH_HMAC_ID_RSVD:
866         default:
867                 /* unknown HMAC algorithm: can't do anything */
868                 return (0);
869         }                       /* end switch */
870 }
871
872 static void
873 sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t * ctx)
874 {
875         switch (hmac_algo) {
876                 case SCTP_AUTH_HMAC_ID_SHA1:
877                 SHA1_Init(&ctx->sha1);
878                 break;
879         case SCTP_AUTH_HMAC_ID_MD5:
880                 MD5_Init(&ctx->md5);
881                 break;
882 #ifdef HAVE_SHA224
883         case SCTP_AUTH_HMAC_ID_SHA224:
884                 break;
885 #endif
886 #ifdef HAVE_SHA2
887         case SCTP_AUTH_HMAC_ID_SHA256:
888                 SHA256_Init(&ctx->sha256);
889                 break;
890         case SCTP_AUTH_HMAC_ID_SHA384:
891                 SHA384_Init(&ctx->sha384);
892                 break;
893         case SCTP_AUTH_HMAC_ID_SHA512:
894                 SHA512_Init(&ctx->sha512);
895                 break;
896 #endif
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 static void
905 sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t * ctx,
906     const uint8_t * text, uint32_t textlen)
907 {
908         switch (hmac_algo) {
909                 case SCTP_AUTH_HMAC_ID_SHA1:
910                 SHA1_Update(&ctx->sha1, text, textlen);
911                 break;
912         case SCTP_AUTH_HMAC_ID_MD5:
913                 MD5_Update(&ctx->md5, text, textlen);
914                 break;
915 #ifdef HAVE_SHA224
916         case SCTP_AUTH_HMAC_ID_SHA224:
917                 break;
918 #endif
919 #ifdef HAVE_SHA2
920         case SCTP_AUTH_HMAC_ID_SHA256:
921                 SHA256_Update(&ctx->sha256, text, textlen);
922                 break;
923         case SCTP_AUTH_HMAC_ID_SHA384:
924                 SHA384_Update(&ctx->sha384, text, textlen);
925                 break;
926         case SCTP_AUTH_HMAC_ID_SHA512:
927                 SHA512_Update(&ctx->sha512, text, textlen);
928                 break;
929 #endif
930         case SCTP_AUTH_HMAC_ID_RSVD:
931         default:
932                 /* unknown HMAC algorithm: can't do anything */
933                 return;
934         }                       /* end switch */
935 }
936
937 static void
938 sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t * ctx,
939     uint8_t * digest)
940 {
941         switch (hmac_algo) {
942                 case SCTP_AUTH_HMAC_ID_SHA1:
943                 SHA1_Final(digest, &ctx->sha1);
944                 break;
945         case SCTP_AUTH_HMAC_ID_MD5:
946                 MD5_Final(digest, &ctx->md5);
947                 break;
948 #ifdef HAVE_SHA224
949         case SCTP_AUTH_HMAC_ID_SHA224:
950                 break;
951 #endif
952 #ifdef HAVE_SHA2
953         case SCTP_AUTH_HMAC_ID_SHA256:
954                 SHA256_Final(digest, &ctx->sha256);
955                 break;
956         case SCTP_AUTH_HMAC_ID_SHA384:
957                 /* SHA384 is truncated SHA512 */
958                 SHA384_Final(digest, &ctx->sha384);
959                 break;
960         case SCTP_AUTH_HMAC_ID_SHA512:
961                 SHA512_Final(digest, &ctx->sha512);
962                 break;
963 #endif
964         case SCTP_AUTH_HMAC_ID_RSVD:
965         default:
966                 /* unknown HMAC algorithm: can't do anything */
967                 return;
968         }                       /* end switch */
969 }
970
971 /*
972  * Keyed-Hashing for Message Authentication: FIPS 198 (RFC 2104)
973  *
974  * Compute the HMAC digest using the desired hash key, text, and HMAC
975  * algorithm.  Resulting digest is placed in 'digest' and digest length
976  * is returned, if the HMAC was performed.
977  *
978  * WARNING: it is up to the caller to supply sufficient space to hold the
979  * resultant digest.
980  */
981 uint32_t
982 sctp_hmac(uint16_t hmac_algo, uint8_t * key, uint32_t keylen,
983     const uint8_t * text, uint32_t textlen, uint8_t * digest)
984 {
985         uint32_t digestlen;
986         uint32_t blocklen;
987         sctp_hash_context_t ctx;
988         uint8_t ipad[128], opad[128];   /* keyed hash inner/outer pads */
989         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
990         uint32_t i;
991
992         /* sanity check the material and length */
993         if ((key == NULL) || (keylen == 0) || (text == NULL) ||
994             (textlen == 0) || (digest == NULL)) {
995                 /* can't do HMAC with empty key or text or digest store */
996                 return (0);
997         }
998         /* validate the hmac algo and get the digest length */
999         digestlen = sctp_get_hmac_digest_len(hmac_algo);
1000         if (digestlen == 0)
1001                 return (0);
1002
1003         /* hash the key if it is longer than the hash block size */
1004         blocklen = sctp_get_hmac_block_len(hmac_algo);
1005         if (keylen > blocklen) {
1006                 sctp_hmac_init(hmac_algo, &ctx);
1007                 sctp_hmac_update(hmac_algo, &ctx, key, keylen);
1008                 sctp_hmac_final(hmac_algo, &ctx, temp);
1009                 /* set the hashed key as the key */
1010                 keylen = digestlen;
1011                 key = temp;
1012         }
1013         /* initialize the inner/outer pads with the key and "append" zeroes */
1014         bzero(ipad, blocklen);
1015         bzero(opad, blocklen);
1016         bcopy(key, ipad, keylen);
1017         bcopy(key, opad, keylen);
1018
1019         /* XOR the key with ipad and opad values */
1020         for (i = 0; i < blocklen; i++) {
1021                 ipad[i] ^= 0x36;
1022                 opad[i] ^= 0x5c;
1023         }
1024
1025         /* perform inner hash */
1026         sctp_hmac_init(hmac_algo, &ctx);
1027         sctp_hmac_update(hmac_algo, &ctx, ipad, blocklen);
1028         sctp_hmac_update(hmac_algo, &ctx, text, textlen);
1029         sctp_hmac_final(hmac_algo, &ctx, temp);
1030
1031         /* perform outer hash */
1032         sctp_hmac_init(hmac_algo, &ctx);
1033         sctp_hmac_update(hmac_algo, &ctx, opad, blocklen);
1034         sctp_hmac_update(hmac_algo, &ctx, temp, digestlen);
1035         sctp_hmac_final(hmac_algo, &ctx, digest);
1036
1037         return (digestlen);
1038 }
1039
1040 /* mbuf version */
1041 uint32_t
1042 sctp_hmac_m(uint16_t hmac_algo, uint8_t * key, uint32_t keylen,
1043     struct mbuf *m, uint32_t m_offset, uint8_t * digest)
1044 {
1045         uint32_t digestlen;
1046         uint32_t blocklen;
1047         sctp_hash_context_t ctx;
1048         uint8_t ipad[128], opad[128];   /* keyed hash inner/outer pads */
1049         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
1050         uint32_t i;
1051         struct mbuf *m_tmp;
1052
1053         /* sanity check the material and length */
1054         if ((key == NULL) || (keylen == 0) || (m == NULL) || (digest == NULL)) {
1055                 /* can't do HMAC with empty key or text or digest store */
1056                 return (0);
1057         }
1058         /* validate the hmac algo and get the digest length */
1059         digestlen = sctp_get_hmac_digest_len(hmac_algo);
1060         if (digestlen == 0)
1061                 return (0);
1062
1063         /* hash the key if it is longer than the hash block size */
1064         blocklen = sctp_get_hmac_block_len(hmac_algo);
1065         if (keylen > blocklen) {
1066                 sctp_hmac_init(hmac_algo, &ctx);
1067                 sctp_hmac_update(hmac_algo, &ctx, key, keylen);
1068                 sctp_hmac_final(hmac_algo, &ctx, temp);
1069                 /* set the hashed key as the key */
1070                 keylen = digestlen;
1071                 key = temp;
1072         }
1073         /* initialize the inner/outer pads with the key and "append" zeroes */
1074         bzero(ipad, blocklen);
1075         bzero(opad, blocklen);
1076         bcopy(key, ipad, keylen);
1077         bcopy(key, opad, keylen);
1078
1079         /* XOR the key with ipad and opad values */
1080         for (i = 0; i < blocklen; i++) {
1081                 ipad[i] ^= 0x36;
1082                 opad[i] ^= 0x5c;
1083         }
1084
1085         /* perform inner hash */
1086         sctp_hmac_init(hmac_algo, &ctx);
1087         sctp_hmac_update(hmac_algo, &ctx, ipad, blocklen);
1088         /* find the correct starting mbuf and offset (get start of text) */
1089         m_tmp = m;
1090         while ((m_tmp != NULL) && (m_offset >= (uint32_t) SCTP_BUF_LEN(m_tmp))) {
1091                 m_offset -= SCTP_BUF_LEN(m_tmp);
1092                 m_tmp = SCTP_BUF_NEXT(m_tmp);
1093         }
1094         /* now use the rest of the mbuf chain for the text */
1095         while (m_tmp != NULL) {
1096                 sctp_hmac_update(hmac_algo, &ctx, mtod(m_tmp, uint8_t *) + m_offset,
1097                     SCTP_BUF_LEN(m_tmp) - m_offset);
1098
1099                 /* clear the offset since it's only for the first mbuf */
1100                 m_offset = 0;
1101                 m_tmp = SCTP_BUF_NEXT(m_tmp);
1102         }
1103         sctp_hmac_final(hmac_algo, &ctx, temp);
1104
1105         /* perform outer hash */
1106         sctp_hmac_init(hmac_algo, &ctx);
1107         sctp_hmac_update(hmac_algo, &ctx, opad, blocklen);
1108         sctp_hmac_update(hmac_algo, &ctx, temp, digestlen);
1109         sctp_hmac_final(hmac_algo, &ctx, digest);
1110
1111         return (digestlen);
1112 }
1113
1114 /*
1115  * verify the HMAC digest using the desired hash key, text, and HMAC
1116  * algorithm. Returns -1 on error, 0 on success.
1117  */
1118 int
1119 sctp_verify_hmac(uint16_t hmac_algo, uint8_t * key, uint32_t keylen,
1120     const uint8_t * text, uint32_t textlen,
1121     uint8_t * digest, uint32_t digestlen)
1122 {
1123         uint32_t len;
1124         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
1125
1126         /* sanity check the material and length */
1127         if ((key == NULL) || (keylen == 0) ||
1128             (text == NULL) || (textlen == 0) || (digest == NULL)) {
1129                 /* can't do HMAC with empty key or text or digest */
1130                 return (-1);
1131         }
1132         len = sctp_get_hmac_digest_len(hmac_algo);
1133         if ((len == 0) || (digestlen != len))
1134                 return (-1);
1135
1136         /* compute the expected hash */
1137         if (sctp_hmac(hmac_algo, key, keylen, text, textlen, temp) != len)
1138                 return (-1);
1139
1140         if (memcmp(digest, temp, digestlen) != 0)
1141                 return (-1);
1142         else
1143                 return (0);
1144 }
1145
1146
1147 /*
1148  * computes the requested HMAC using a key struct (which may be modified if
1149  * the keylen exceeds the HMAC block len).
1150  */
1151 uint32_t
1152 sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t * key, const uint8_t * text,
1153     uint32_t textlen, uint8_t * digest)
1154 {
1155         uint32_t digestlen;
1156         uint32_t blocklen;
1157         sctp_hash_context_t ctx;
1158         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
1159
1160         /* sanity check */
1161         if ((key == NULL) || (text == NULL) || (textlen == 0) ||
1162             (digest == NULL)) {
1163                 /* can't do HMAC with empty key or text or digest store */
1164                 return (0);
1165         }
1166         /* validate the hmac algo and get the digest length */
1167         digestlen = sctp_get_hmac_digest_len(hmac_algo);
1168         if (digestlen == 0)
1169                 return (0);
1170
1171         /* hash the key if it is longer than the hash block size */
1172         blocklen = sctp_get_hmac_block_len(hmac_algo);
1173         if (key->keylen > blocklen) {
1174                 sctp_hmac_init(hmac_algo, &ctx);
1175                 sctp_hmac_update(hmac_algo, &ctx, key->key, key->keylen);
1176                 sctp_hmac_final(hmac_algo, &ctx, temp);
1177                 /* save the hashed key as the new key */
1178                 key->keylen = digestlen;
1179                 bcopy(temp, key->key, key->keylen);
1180         }
1181         return (sctp_hmac(hmac_algo, key->key, key->keylen, text, textlen,
1182             digest));
1183 }
1184
1185 /* mbuf version */
1186 uint32_t
1187 sctp_compute_hmac_m(uint16_t hmac_algo, sctp_key_t * key, struct mbuf *m,
1188     uint32_t m_offset, uint8_t * digest)
1189 {
1190         uint32_t digestlen;
1191         uint32_t blocklen;
1192         sctp_hash_context_t ctx;
1193         uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX];
1194
1195         /* sanity check */
1196         if ((key == NULL) || (m == NULL) || (digest == NULL)) {
1197                 /* can't do HMAC with empty key or text or digest store */
1198                 return (0);
1199         }
1200         /* validate the hmac algo and get the digest length */
1201         digestlen = sctp_get_hmac_digest_len(hmac_algo);
1202         if (digestlen == 0)
1203                 return (0);
1204
1205         /* hash the key if it is longer than the hash block size */
1206         blocklen = sctp_get_hmac_block_len(hmac_algo);
1207         if (key->keylen > blocklen) {
1208                 sctp_hmac_init(hmac_algo, &ctx);
1209                 sctp_hmac_update(hmac_algo, &ctx, key->key, key->keylen);
1210                 sctp_hmac_final(hmac_algo, &ctx, temp);
1211                 /* save the hashed key as the new key */
1212                 key->keylen = digestlen;
1213                 bcopy(temp, key->key, key->keylen);
1214         }
1215         return (sctp_hmac_m(hmac_algo, key->key, key->keylen, m, m_offset, digest));
1216 }
1217
1218 int
1219 sctp_auth_is_supported_hmac(sctp_hmaclist_t * list, uint16_t id)
1220 {
1221         int i;
1222
1223         if ((list == NULL) || (id == SCTP_AUTH_HMAC_ID_RSVD))
1224                 return (0);
1225
1226         for (i = 0; i < list->num_algo; i++)
1227                 if (list->hmac[i] == id)
1228                         return (1);
1229
1230         /* not in the list */
1231         return (0);
1232 }
1233
1234
1235 /*
1236  * clear any cached key(s) if they match the given key id on an association
1237  * the cached key(s) will be recomputed and re-cached at next use. ASSUMES
1238  * TCB_LOCK is already held
1239  */
1240 void
1241 sctp_clear_cachedkeys(struct sctp_tcb *stcb, uint16_t keyid)
1242 {
1243         if (stcb == NULL)
1244                 return;
1245
1246         if (keyid == stcb->asoc.authinfo.assoc_keyid) {
1247                 sctp_free_key(stcb->asoc.authinfo.assoc_key);
1248                 stcb->asoc.authinfo.assoc_key = NULL;
1249         }
1250         if (keyid == stcb->asoc.authinfo.recv_keyid) {
1251                 sctp_free_key(stcb->asoc.authinfo.recv_key);
1252                 stcb->asoc.authinfo.recv_key = NULL;
1253         }
1254 }
1255
1256 /*
1257  * clear any cached key(s) if they match the given key id for all assocs on
1258  * an association ASSUMES INP_WLOCK is already held
1259  */
1260 void
1261 sctp_clear_cachedkeys_ep(struct sctp_inpcb *inp, uint16_t keyid)
1262 {
1263         struct sctp_tcb *stcb;
1264
1265         if (inp == NULL)
1266                 return;
1267
1268         /* clear the cached keys on all assocs on this instance */
1269         LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
1270                 SCTP_TCB_LOCK(stcb);
1271                 sctp_clear_cachedkeys(stcb, keyid);
1272                 SCTP_TCB_UNLOCK(stcb);
1273         }
1274 }
1275
1276 /*
1277  * delete a shared key from an association ASSUMES TCB_LOCK is already held
1278  */
1279 int
1280 sctp_delete_sharedkey(struct sctp_tcb *stcb, uint16_t keyid)
1281 {
1282         sctp_sharedkey_t *skey;
1283
1284         if (stcb == NULL)
1285                 return (-1);
1286
1287         /* is the keyid the assoc active sending key */
1288         if (keyid == stcb->asoc.authinfo.assoc_keyid)
1289                 return (-1);
1290
1291         /* does the key exist? */
1292         skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, keyid);
1293         if (skey == NULL)
1294                 return (-1);
1295
1296         /* remove it */
1297         LIST_REMOVE(skey, next);
1298         sctp_free_sharedkey(skey);      /* frees skey->key as well */
1299
1300         /* clear any cached keys */
1301         sctp_clear_cachedkeys(stcb, keyid);
1302         return (0);
1303 }
1304
1305 /*
1306  * deletes a shared key from the endpoint ASSUMES INP_WLOCK is already held
1307  */
1308 int
1309 sctp_delete_sharedkey_ep(struct sctp_inpcb *inp, uint16_t keyid)
1310 {
1311         sctp_sharedkey_t *skey;
1312         struct sctp_tcb *stcb;
1313
1314         if (inp == NULL)
1315                 return (-1);
1316
1317         /* is the keyid the active sending key on the endpoint or any assoc */
1318         if (keyid == inp->sctp_ep.default_keyid)
1319                 return (-1);
1320         LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
1321                 SCTP_TCB_LOCK(stcb);
1322                 if (keyid == stcb->asoc.authinfo.assoc_keyid) {
1323                         SCTP_TCB_UNLOCK(stcb);
1324                         return (-1);
1325                 }
1326                 SCTP_TCB_UNLOCK(stcb);
1327         }
1328
1329         /* does the key exist? */
1330         skey = sctp_find_sharedkey(&inp->sctp_ep.shared_keys, keyid);
1331         if (skey == NULL)
1332                 return (-1);
1333
1334         /* remove it */
1335         LIST_REMOVE(skey, next);
1336         sctp_free_sharedkey(skey);      /* frees skey->key as well */
1337
1338         /* clear any cached keys */
1339         sctp_clear_cachedkeys_ep(inp, keyid);
1340         return (0);
1341 }
1342
1343 /*
1344  * set the active key on an association ASSUME TCB_LOCK is already held
1345  */
1346 int
1347 sctp_auth_setactivekey(struct sctp_tcb *stcb, uint16_t keyid)
1348 {
1349         sctp_sharedkey_t *skey = NULL;
1350         sctp_key_t *key = NULL;
1351         int using_ep_key = 0;
1352
1353         /* find the key on the assoc */
1354         skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, keyid);
1355         if (skey == NULL) {
1356                 /* if not on the assoc, find the key on the endpoint */
1357                 SCTP_INP_RLOCK(stcb->sctp_ep);
1358                 skey = sctp_find_sharedkey(&stcb->sctp_ep->sctp_ep.shared_keys,
1359                     keyid);
1360                 using_ep_key = 1;
1361         }
1362         if (skey == NULL) {
1363                 /* that key doesn't exist */
1364                 if (using_ep_key)
1365                         SCTP_INP_RUNLOCK(stcb->sctp_ep);
1366                 return (-1);
1367         }
1368         /* get the shared key text */
1369         key = skey->key;
1370
1371         /* free any existing cached key */
1372         if (stcb->asoc.authinfo.assoc_key != NULL)
1373                 sctp_free_key(stcb->asoc.authinfo.assoc_key);
1374         /* compute a new assoc key and cache it */
1375         stcb->asoc.authinfo.assoc_key =
1376             sctp_compute_hashkey(stcb->asoc.authinfo.random,
1377             stcb->asoc.authinfo.peer_random, key);
1378         stcb->asoc.authinfo.assoc_keyid = keyid;
1379 #ifdef SCTP_DEBUG
1380         if (SCTP_AUTH_DEBUG)
1381                 sctp_print_key(stcb->asoc.authinfo.assoc_key, "Assoc Key");
1382 #endif
1383
1384         if (using_ep_key)
1385                 SCTP_INP_RUNLOCK(stcb->sctp_ep);
1386         return (0);
1387 }
1388
1389 /*
1390  * set the active key on an endpoint ASSUMES INP_WLOCK is already held
1391  */
1392 int
1393 sctp_auth_setactivekey_ep(struct sctp_inpcb *inp, uint16_t keyid)
1394 {
1395         sctp_sharedkey_t *skey;
1396
1397         /* find the key */
1398         skey = sctp_find_sharedkey(&inp->sctp_ep.shared_keys, keyid);
1399         if (skey == NULL) {
1400                 /* that key doesn't exist */
1401                 return (-1);
1402         }
1403         inp->sctp_ep.default_keyid = keyid;
1404         return (0);
1405 }
1406
1407 /*
1408  * get local authentication parameters from cookie (from INIT-ACK)
1409  */
1410 void
1411 sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
1412     uint32_t offset, uint32_t length)
1413 {
1414         struct sctp_paramhdr *phdr, tmp_param;
1415         uint16_t plen, ptype;
1416         uint8_t store[384];
1417         struct sctp_auth_random *random = NULL;
1418         uint16_t random_len = 0;
1419         struct sctp_auth_hmac_algo *hmacs = NULL;
1420         uint16_t hmacs_len = 0;
1421         struct sctp_auth_chunk_list *chunks = NULL;
1422         uint16_t num_chunks = 0;
1423         sctp_key_t *new_key;
1424         uint32_t keylen;
1425
1426         /* convert to upper bound */
1427         length += offset;
1428
1429         phdr = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
1430             sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
1431         while (phdr != NULL) {
1432                 ptype = ntohs(phdr->param_type);
1433                 plen = ntohs(phdr->param_length);
1434
1435                 if ((plen == 0) || (offset + plen > length))
1436                         break;
1437
1438                 if (ptype == SCTP_RANDOM) {
1439                         if (plen > sizeof(store))
1440                                 break;
1441                         phdr = sctp_get_next_param(m, offset,
1442                             (struct sctp_paramhdr *)store, plen);
1443                         if (phdr == NULL)
1444                                 return;
1445                         /* save the random and length for the key */
1446                         random = (struct sctp_auth_random *)phdr;
1447                         random_len = plen - sizeof(*random);
1448                 } else if (ptype == SCTP_HMAC_LIST) {
1449                         int num_hmacs;
1450                         int i;
1451
1452                         if (plen > sizeof(store))
1453                                 break;
1454                         phdr = sctp_get_next_param(m, offset,
1455                             (struct sctp_paramhdr *)store, plen);
1456                         if (phdr == NULL)
1457                                 return;
1458                         /* save the hmacs list and num for the key */
1459                         hmacs = (struct sctp_auth_hmac_algo *)phdr;
1460                         hmacs_len = plen - sizeof(*hmacs);
1461                         num_hmacs = hmacs_len / sizeof(hmacs->hmac_ids[0]);
1462                         if (stcb->asoc.local_hmacs != NULL)
1463                                 sctp_free_hmaclist(stcb->asoc.local_hmacs);
1464                         stcb->asoc.local_hmacs = sctp_alloc_hmaclist(num_hmacs);
1465                         if (stcb->asoc.local_hmacs != NULL) {
1466                                 for (i = 0; i < num_hmacs; i++) {
1467                                         sctp_auth_add_hmacid(stcb->asoc.local_hmacs,
1468                                             ntohs(hmacs->hmac_ids[i]));
1469                                 }
1470                         }
1471                 } else if (ptype == SCTP_CHUNK_LIST) {
1472                         int i;
1473
1474                         if (plen > sizeof(store))
1475                                 break;
1476                         phdr = sctp_get_next_param(m, offset,
1477                             (struct sctp_paramhdr *)store, plen);
1478                         if (phdr == NULL)
1479                                 return;
1480                         chunks = (struct sctp_auth_chunk_list *)phdr;
1481                         num_chunks = plen - sizeof(*chunks);
1482                         /* save chunks list and num for the key */
1483                         if (stcb->asoc.local_auth_chunks != NULL)
1484                                 sctp_clear_chunklist(stcb->asoc.local_auth_chunks);
1485                         else
1486                                 stcb->asoc.local_auth_chunks = sctp_alloc_chunklist();
1487                         for (i = 0; i < num_chunks; i++) {
1488                                 sctp_auth_add_chunk(chunks->chunk_types[i],
1489                                     stcb->asoc.local_auth_chunks);
1490                         }
1491                 }
1492                 /* get next parameter */
1493                 offset += SCTP_SIZE32(plen);
1494                 if (offset + sizeof(struct sctp_paramhdr) > length)
1495                         break;
1496                 phdr = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
1497                     (uint8_t *) & tmp_param);
1498         }
1499         /* concatenate the full random key */
1500         keylen = random_len + num_chunks + hmacs_len;
1501         new_key = sctp_alloc_key(keylen);
1502         if (new_key != NULL) {
1503                 /* copy in the RANDOM */
1504                 if (random != NULL)
1505                         bcopy(random->random_data, new_key->key, random_len);
1506                 /* append in the AUTH chunks */
1507                 if (chunks != NULL)
1508                         bcopy(chunks->chunk_types, new_key->key + random_len,
1509                             num_chunks);
1510                 /* append in the HMACs */
1511                 if (hmacs != NULL)
1512                         bcopy(hmacs->hmac_ids, new_key->key + random_len + num_chunks,
1513                             hmacs_len);
1514         }
1515         if (stcb->asoc.authinfo.random != NULL)
1516                 sctp_free_key(stcb->asoc.authinfo.random);
1517         stcb->asoc.authinfo.random = new_key;
1518         stcb->asoc.authinfo.random_len = random_len;
1519 #ifdef SCTP_AUTH_DRAFT_04
1520         /* don't include the chunks and hmacs for draft -04 */
1521         stcb->asoc.authinfo.random->keylen = random_len;
1522 #endif
1523         sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
1524         sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.recv_keyid);
1525
1526         /* negotiate what HMAC to use for the peer */
1527         stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs,
1528             stcb->asoc.local_hmacs);
1529         /* copy defaults from the endpoint */
1530         /* FIX ME: put in cookie? */
1531         stcb->asoc.authinfo.assoc_keyid = stcb->sctp_ep->sctp_ep.default_keyid;
1532 }
1533
1534 /*
1535  * compute and fill in the HMAC digest for a packet
1536  */
1537 void
1538 sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset,
1539     struct sctp_auth_chunk *auth, struct sctp_tcb *stcb)
1540 {
1541         uint32_t digestlen;
1542         sctp_sharedkey_t *skey;
1543         sctp_key_t *key;
1544
1545         if ((stcb == NULL) || (auth == NULL))
1546                 return;
1547
1548         /* zero the digest + chunk padding */
1549         digestlen = sctp_get_hmac_digest_len(stcb->asoc.peer_hmac_id);
1550         bzero(auth->hmac, SCTP_SIZE32(digestlen));
1551         /* is an assoc key cached? */
1552         if (stcb->asoc.authinfo.assoc_key == NULL) {
1553                 skey = sctp_find_sharedkey(&stcb->asoc.shared_keys,
1554                     stcb->asoc.authinfo.assoc_keyid);
1555                 if (skey == NULL) {
1556                         /* not in the assoc list, so check the endpoint list */
1557                         skey = sctp_find_sharedkey(&stcb->sctp_ep->sctp_ep.shared_keys,
1558                             stcb->asoc.authinfo.assoc_keyid);
1559                 }
1560                 /* the only way skey is NULL is if null key id 0 is used */
1561                 if (skey != NULL)
1562                         key = skey->key;
1563                 else
1564                         key = NULL;
1565                 /* compute a new assoc key and cache it */
1566                 stcb->asoc.authinfo.assoc_key =
1567                     sctp_compute_hashkey(stcb->asoc.authinfo.random,
1568                     stcb->asoc.authinfo.peer_random, key);
1569 #ifdef SCTP_DEBUG
1570                 if (SCTP_AUTH_DEBUG) {
1571                         printf("caching key id %u\n",
1572                             stcb->asoc.authinfo.assoc_keyid);
1573                         sctp_print_key(stcb->asoc.authinfo.assoc_key, "Assoc Key");
1574                 }
1575 #endif
1576         }
1577         /* set in the active key id */
1578         auth->shared_key_id = htons(stcb->asoc.authinfo.assoc_keyid);
1579
1580         /* compute and fill in the digest */
1581         (void)sctp_compute_hmac_m(stcb->asoc.peer_hmac_id,
1582             stcb->asoc.authinfo.assoc_key,
1583             m, auth_offset, auth->hmac);
1584 }
1585
1586
1587 static void
1588 sctp_bzero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
1589 {
1590         struct mbuf *m_tmp;
1591         uint8_t *data;
1592
1593         /* sanity check */
1594         if (m == NULL)
1595                 return;
1596
1597         /* find the correct starting mbuf and offset (get start position) */
1598         m_tmp = m;
1599         while ((m_tmp != NULL) && (m_offset >= (uint32_t) SCTP_BUF_LEN(m_tmp))) {
1600                 m_offset -= SCTP_BUF_LEN(m_tmp);
1601                 m_tmp = SCTP_BUF_NEXT(m_tmp);
1602         }
1603         /* now use the rest of the mbuf chain */
1604         while ((m_tmp != NULL) && (size > 0)) {
1605                 data = mtod(m_tmp, uint8_t *) + m_offset;
1606                 if (size > (uint32_t) SCTP_BUF_LEN(m_tmp)) {
1607                         bzero(data, SCTP_BUF_LEN(m_tmp));
1608                         size -= SCTP_BUF_LEN(m_tmp);
1609                 } else {
1610                         bzero(data, size);
1611                         size = 0;
1612                 }
1613                 /* clear the offset since it's only for the first mbuf */
1614                 m_offset = 0;
1615                 m_tmp = SCTP_BUF_NEXT(m_tmp);
1616         }
1617 }
1618
1619 /*
1620  * process the incoming Authentication chunk return codes: -1 on any
1621  * authentication error 0 on authentication verification
1622  */
1623 int
1624 sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
1625     struct mbuf *m, uint32_t offset)
1626 {
1627         uint16_t chunklen;
1628         uint16_t shared_key_id;
1629         uint16_t hmac_id;
1630         sctp_sharedkey_t *skey;
1631         uint32_t digestlen;
1632         uint8_t digest[SCTP_AUTH_DIGEST_LEN_MAX];
1633         uint8_t computed_digest[SCTP_AUTH_DIGEST_LEN_MAX];
1634
1635         /* auth is checked for NULL by caller */
1636         chunklen = ntohs(auth->ch.chunk_length);
1637         if (chunklen < sizeof(*auth)) {
1638                 SCTP_STAT_INCR(sctps_recvauthfailed);
1639                 return (-1);
1640         }
1641         SCTP_STAT_INCR(sctps_recvauth);
1642
1643         /* get the auth params */
1644         shared_key_id = ntohs(auth->shared_key_id);
1645         hmac_id = ntohs(auth->hmac_id);
1646 #ifdef SCTP_DEBUG
1647         if (SCTP_AUTH_DEBUG)
1648                 printf("SCTP AUTH Chunk: shared key %u, HMAC id %u\n",
1649                     shared_key_id, hmac_id);
1650 #endif
1651
1652         /* is the indicated HMAC supported? */
1653         if (!sctp_auth_is_supported_hmac(stcb->asoc.local_hmacs, hmac_id)) {
1654                 struct mbuf *m_err;
1655                 struct sctp_auth_invalid_hmac *err;
1656
1657                 SCTP_STAT_INCR(sctps_recvivalhmacid);
1658 #ifdef SCTP_DEBUG
1659                 if (SCTP_AUTH_DEBUG)
1660                         printf("SCTP Auth: unsupported HMAC id %u\n", hmac_id);
1661 #endif
1662                 /*
1663                  * report this in an Error Chunk: Unsupported HMAC
1664                  * Identifier
1665                  */
1666                 m_err = sctp_get_mbuf_for_msg(sizeof(*err), 0, M_DONTWAIT, 1, MT_HEADER);
1667                 if (m_err != NULL) {
1668                         /* pre-reserve some space */
1669                         SCTP_BUF_RESV_UF(m_err, sizeof(struct sctp_chunkhdr));
1670                         /* fill in the error */
1671                         err = mtod(m_err, struct sctp_auth_invalid_hmac *);
1672                         bzero(err, sizeof(*err));
1673                         err->ph.param_type = htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
1674                         err->ph.param_length = htons(sizeof(*err));
1675                         err->hmac_id = ntohs(hmac_id);
1676                         SCTP_BUF_LEN(m_err) = sizeof(*err);
1677                         /* queue it */
1678                         sctp_queue_op_err(stcb, m_err);
1679                 }
1680                 return (-1);
1681         }
1682         /* get the indicated shared key, if available */
1683         if ((stcb->asoc.authinfo.recv_key == NULL) ||
1684             (stcb->asoc.authinfo.recv_keyid != shared_key_id)) {
1685                 /* find the shared key on the assoc first */
1686                 skey = sctp_find_sharedkey(&stcb->asoc.shared_keys, shared_key_id);
1687                 if (skey == NULL) {
1688                         /* if not on the assoc, find it on the endpoint */
1689                         skey = sctp_find_sharedkey(&stcb->sctp_ep->sctp_ep.shared_keys,
1690                             shared_key_id);
1691                 }
1692                 /* if the shared key isn't found, discard the chunk */
1693                 if (skey == NULL) {
1694                         SCTP_STAT_INCR(sctps_recvivalkeyid);
1695 #ifdef SCTP_DEBUG
1696                         if (SCTP_AUTH_DEBUG)
1697                                 printf("SCTP Auth: unknown key id %u\n",
1698                                     shared_key_id);
1699 #endif
1700                         return (-1);
1701                 }
1702                 /* generate a notification if this is a new key id */
1703                 if (stcb->asoc.authinfo.recv_keyid != shared_key_id)
1704                         /*
1705                          * sctp_ulp_notify(SCTP_NOTIFY_AUTH_NEW_KEY, stcb,
1706                          * shared_key_id, (void
1707                          * *)stcb->asoc.authinfo.recv_keyid);
1708                          */
1709                         sctp_notify_authentication(stcb, SCTP_AUTH_NEWKEY,
1710                             shared_key_id, stcb->asoc.authinfo.recv_keyid);
1711                 /* compute a new recv assoc key and cache it */
1712                 if (stcb->asoc.authinfo.recv_key != NULL)
1713                         sctp_free_key(stcb->asoc.authinfo.recv_key);
1714                 stcb->asoc.authinfo.recv_key =
1715                     sctp_compute_hashkey(stcb->asoc.authinfo.random,
1716                     stcb->asoc.authinfo.peer_random, skey->key);
1717                 stcb->asoc.authinfo.recv_keyid = shared_key_id;
1718 #ifdef SCTP_DEBUG
1719                 if (SCTP_AUTH_DEBUG)
1720                         sctp_print_key(stcb->asoc.authinfo.recv_key, "Recv Key");
1721 #endif
1722         }
1723         /* validate the digest length */
1724         digestlen = sctp_get_hmac_digest_len(hmac_id);
1725         if (chunklen < (sizeof(*auth) + digestlen)) {
1726                 /* invalid digest length */
1727                 SCTP_STAT_INCR(sctps_recvauthfailed);
1728 #ifdef SCTP_DEBUG
1729                 if (SCTP_AUTH_DEBUG)
1730                         printf("SCTP Auth: chunk too short for HMAC\n");
1731 #endif
1732                 return (-1);
1733         }
1734         /* save a copy of the digest, zero the pseudo header, and validate */
1735         bcopy(auth->hmac, digest, digestlen);
1736         sctp_bzero_m(m, offset + sizeof(*auth), SCTP_SIZE32(digestlen));
1737         (void)sctp_compute_hmac_m(hmac_id, stcb->asoc.authinfo.recv_key,
1738             m, offset, computed_digest);
1739
1740         /* compare the computed digest with the one in the AUTH chunk */
1741         if (memcmp(digest, computed_digest, digestlen) != 0) {
1742                 SCTP_STAT_INCR(sctps_recvauthfailed);
1743 #ifdef SCTP_DEBUG
1744                 if (SCTP_AUTH_DEBUG)
1745                         printf("SCTP Auth: HMAC digest check failed\n");
1746 #endif
1747                 return (-1);
1748         }
1749         return (0);
1750 }
1751
1752 /*
1753  * Generate NOTIFICATION
1754  */
1755 void
1756 sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
1757     uint16_t keyid, uint16_t alt_keyid)
1758 {
1759         struct mbuf *m_notify;
1760         struct sctp_authkey_event *auth;
1761         struct sctp_queued_to_read *control;
1762
1763         if (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_AUTHEVNT))
1764                 /* event not enabled */
1765                 return;
1766
1767         m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_authkey_event),
1768             0, M_DONTWAIT, 1, MT_HEADER);
1769         if (m_notify == NULL)
1770                 /* no space left */
1771                 return;
1772
1773         SCTP_BUF_LEN(m_notify) = 0;
1774         auth = mtod(m_notify, struct sctp_authkey_event *);
1775         auth->auth_type = SCTP_AUTHENTICATION_EVENT;
1776         auth->auth_flags = 0;
1777         auth->auth_length = sizeof(*auth);
1778         auth->auth_keynumber = keyid;
1779         auth->auth_altkeynumber = alt_keyid;
1780         auth->auth_indication = indication;
1781         auth->auth_assoc_id = sctp_get_associd(stcb);
1782
1783         SCTP_BUF_LEN(m_notify) = sizeof(*auth);
1784         SCTP_BUF_NEXT(m_notify) = NULL;
1785
1786         /* append to socket */
1787         control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
1788             0, 0, 0, 0, 0, 0, m_notify);
1789         if (control == NULL) {
1790                 /* no memory */
1791                 sctp_m_freem(m_notify);
1792                 return;
1793         }
1794         control->spec_flags = M_NOTIFICATION;
1795         control->length = SCTP_BUF_LEN(m_notify);
1796         /* not that we need this */
1797         control->tail_mbuf = m_notify;
1798         sctp_add_to_readq(stcb->sctp_ep, stcb, control,
1799             &stcb->sctp_socket->so_rcv, 1);
1800 }
1801
1802
1803 /*
1804  * validates the AUTHentication related parameters in an INIT/INIT-ACK
1805  * Note: currently only used for INIT as INIT-ACK is handled inline
1806  * with sctp_load_addresses_from_init()
1807  */
1808 int
1809 sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
1810 {
1811         struct sctp_paramhdr *phdr, parm_buf;
1812         uint16_t ptype, plen;
1813         int peer_supports_asconf = 0;
1814         int peer_supports_auth = 0;
1815         int got_random = 0, got_hmacs = 0;
1816
1817         /* go through each of the params. */
1818         phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
1819         while (phdr) {
1820                 ptype = ntohs(phdr->param_type);
1821                 plen = ntohs(phdr->param_length);
1822
1823                 if (offset + plen > limit) {
1824                         break;
1825                 }
1826                 if (plen == 0) {
1827                         break;
1828                 }
1829                 if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
1830                         /* A supported extension chunk */
1831                         struct sctp_supported_chunk_types_param *pr_supported;
1832                         uint8_t local_store[128];
1833                         int num_ent, i;
1834
1835                         phdr = sctp_get_next_param(m, offset,
1836                             (struct sctp_paramhdr *)&local_store, plen);
1837                         if (phdr == NULL) {
1838                                 return (-1);
1839                         }
1840                         pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
1841                         num_ent = plen - sizeof(struct sctp_paramhdr);
1842                         for (i = 0; i < num_ent; i++) {
1843                                 switch (pr_supported->chunk_types[i]) {
1844                                 case SCTP_ASCONF:
1845                                 case SCTP_ASCONF_ACK:
1846                                         peer_supports_asconf = 1;
1847                                         break;
1848                                 case SCTP_AUTHENTICATION:
1849                                         peer_supports_auth = 1;
1850                                         break;
1851                                 default:
1852                                         /* one we don't care about */
1853                                         break;
1854                                 }
1855                         }
1856                 } else if (ptype == SCTP_RANDOM) {
1857                         got_random = 1;
1858                         /* enforce the random length */
1859                         if (plen != (sizeof(struct sctp_auth_random) +
1860                             SCTP_AUTH_RANDOM_SIZE_REQUIRED)) {
1861 #ifdef SCTP_DEBUG
1862                                 if (sctp_debug_on & SCTP_DEBUG_AUTH1)
1863                                         printf("SCTP: invalid RANDOM len\n");
1864 #endif
1865                                 return (-1);
1866                         }
1867                 } else if (ptype == SCTP_HMAC_LIST) {
1868                         uint8_t store[256];
1869                         struct sctp_auth_hmac_algo *hmacs;
1870                         int num_hmacs;
1871
1872                         if (plen > sizeof(store))
1873                                 break;
1874                         phdr = sctp_get_next_param(m, offset,
1875                             (struct sctp_paramhdr *)store, plen);
1876                         if (phdr == NULL)
1877                                 return (-1);
1878                         hmacs = (struct sctp_auth_hmac_algo *)phdr;
1879                         num_hmacs = (plen - sizeof(*hmacs)) /
1880                             sizeof(hmacs->hmac_ids[0]);
1881                         /* validate the hmac list */
1882                         if (sctp_verify_hmac_param(hmacs, num_hmacs)) {
1883 #ifdef SCTP_DEBUG
1884                                 if (sctp_debug_on & SCTP_DEBUG_AUTH1)
1885                                         printf("SCTP: invalid HMAC param\n");
1886 #endif
1887                                 return (-1);
1888                         }
1889                         got_hmacs = 1;
1890                 }
1891                 offset += SCTP_SIZE32(plen);
1892                 if (offset >= limit) {
1893                         break;
1894                 }
1895                 phdr = sctp_get_next_param(m, offset, &parm_buf,
1896                     sizeof(parm_buf));
1897         }
1898         /* validate authentication required parameters */
1899         if (got_random && got_hmacs) {
1900                 peer_supports_auth = 1;
1901         } else {
1902                 peer_supports_auth = 0;
1903         }
1904         if (!sctp_asconf_auth_nochk && peer_supports_asconf &&
1905             !peer_supports_auth) {
1906 #ifdef SCTP_DEBUG
1907                 if (sctp_debug_on & SCTP_DEBUG_AUTH1)
1908                         printf("SCTP: peer supports ASCONF but not AUTH\n");
1909 #endif
1910                 return (-1);
1911         }
1912         return (0);
1913 }
1914
1915 void
1916 sctp_initialize_auth_params(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
1917 {
1918         uint16_t chunks_len = 0;
1919         uint16_t hmacs_len = 0;
1920         uint16_t random_len = sctp_auth_random_len;
1921         sctp_key_t *new_key;
1922         uint16_t keylen;
1923
1924         /* initialize hmac list from endpoint */
1925         stcb->asoc.local_hmacs = sctp_copy_hmaclist(inp->sctp_ep.local_hmacs);
1926         if (stcb->asoc.local_hmacs != NULL) {
1927                 hmacs_len = stcb->asoc.local_hmacs->num_algo *
1928                     sizeof(stcb->asoc.local_hmacs->hmac[0]);
1929         }
1930         /* initialize auth chunks list from endpoint */
1931         stcb->asoc.local_auth_chunks =
1932             sctp_copy_chunklist(inp->sctp_ep.local_auth_chunks);
1933         if (stcb->asoc.local_auth_chunks != NULL) {
1934                 int i;
1935
1936                 for (i = 0; i < 256; i++) {
1937                         if (stcb->asoc.local_auth_chunks->chunks[i])
1938                                 chunks_len++;
1939                 }
1940         }
1941         /* copy defaults from the endpoint */
1942         stcb->asoc.authinfo.assoc_keyid = inp->sctp_ep.default_keyid;
1943
1944         /* now set the concatenated key (random + chunks + hmacs) */
1945         keylen = random_len + chunks_len + hmacs_len;
1946         new_key = sctp_alloc_key(keylen);
1947         if (new_key != NULL) {
1948                 /* generate and copy in the RANDOM */
1949                 SCTP_READ_RANDOM(new_key->key, random_len);
1950                 keylen = random_len;
1951                 /* append in the AUTH chunks */
1952                 if (stcb->asoc.local_auth_chunks) {
1953                         int i;
1954
1955                         for (i = 0; i < 256; i++) {
1956                                 if (stcb->asoc.local_auth_chunks->chunks[i])
1957                                         new_key->key[keylen++] = i;
1958                         }
1959                 }
1960                 /* append in the HMACs */
1961                 sctp_serialize_hmaclist(stcb->asoc.local_hmacs,
1962                     new_key->key + keylen);
1963         }
1964         if (stcb->asoc.authinfo.random != NULL)
1965                 sctp_free_key(stcb->asoc.authinfo.random);
1966         stcb->asoc.authinfo.random = new_key;
1967         stcb->asoc.authinfo.random_len = random_len;
1968 #ifdef SCTP_AUTH_DRAFT_04
1969         /* don't include the chunks and hmacs for draft -04 */
1970         stcb->asoc.authinfo.random->keylen = random_len;
1971 #endif
1972 }
1973
1974
1975 #ifdef SCTP_HMAC_TEST
1976 /*
1977  * HMAC and key concatenation tests
1978  */
1979 static void
1980 sctp_print_digest(uint8_t * digest, uint32_t digestlen, const char *str)
1981 {
1982         uint32_t i;
1983
1984         printf("\n%s: 0x", str);
1985         if (digest == NULL)
1986                 return;
1987
1988         for (i = 0; i < digestlen; i++)
1989                 printf("%02x", digest[i]);
1990 }
1991
1992 static int
1993 sctp_test_hmac(const char *str, uint16_t hmac_id, uint8_t * key,
1994     uint32_t keylen, uint8_t * text, uint32_t textlen,
1995     uint8_t * digest, uint32_t digestlen)
1996 {
1997         uint8_t computed_digest[SCTP_AUTH_DIGEST_LEN_MAX];
1998
1999         printf("\n%s:", str);
2000         sctp_hmac(hmac_id, key, keylen, text, textlen, computed_digest);
2001         sctp_print_digest(digest, digestlen, "Expected digest");
2002         sctp_print_digest(computed_digest, digestlen, "Computed digest");
2003         if (memcmp(digest, computed_digest, digestlen) != 0) {
2004                 printf("\nFAILED");
2005                 return (-1);
2006         } else {
2007                 printf("\nPASSED");
2008                 return (0);
2009         }
2010 }
2011
2012
2013 /*
2014  * RFC 2202: HMAC-SHA1 test cases
2015  */
2016 void
2017 sctp_test_hmac_sha1(void)
2018 {
2019         uint8_t *digest;
2020         uint8_t key[128];
2021         uint32_t keylen;
2022         uint8_t text[128];
2023         uint32_t textlen;
2024         uint32_t digestlen = 20;
2025         int failed = 0;
2026
2027         /*
2028          * test_case =     1 key =
2029          * 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b key_len =       20
2030          * data =          "Hi There" data_len =      8 digest =
2031          * 0xb617318655057264e28bc0b6fb378c8ef146be00
2032          */
2033         keylen = 20;
2034         memset(key, 0x0b, keylen);
2035         textlen = 8;
2036         strcpy(text, "Hi There");
2037         digest = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00";
2038         if (sctp_test_hmac("SHA1 test case 1", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
2039             text, textlen, digest, digestlen) < 0)
2040                 failed++;
2041
2042         /*
2043          * test_case =     2 key =           "Jefe" key_len =       4 data =
2044          * "what do ya want for nothing?" data_len =      28 digest =
2045          * 0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79
2046          */
2047         keylen = 4;
2048         strcpy(key, "Jefe");
2049         textlen = 28;
2050         strcpy(text, "what do ya want for nothing?");
2051         digest = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79";
2052         if (sctp_test_hmac("SHA1 test case 2", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
2053             text, textlen, digest, digestlen) < 0)
2054                 failed++;
2055
2056         /*
2057          * test_case =     3 key =
2058          * 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa key_len =       20
2059          * data =          0xdd repeated 50 times data_len =      50 digest
2060          * = 0x125d7342b9ac11cd91a39af48aa17b4f63f175d3
2061          */
2062         keylen = 20;
2063         memset(key, 0xaa, keylen);
2064         textlen = 50;
2065         memset(text, 0xdd, textlen);
2066         digest = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3";
2067         if (sctp_test_hmac("SHA1 test case 3", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
2068             text, textlen, digest, digestlen) < 0)
2069                 failed++;
2070
2071         /*
2072          * test_case =     4 key =
2073          * 0x0102030405060708090a0b0c0d0e0f10111213141516171819 key_len = 25
2074          * data =          0xcd repeated 50 times data_len =      50 digest
2075          * =        0x4c9007f4026250c6bc8414f9bf50c86c2d7235da
2076          */
2077         keylen = 25;
2078         memcpy(key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", keylen);
2079         textlen = 50;
2080         memset(text, 0xcd, textlen);
2081         digest = "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda";
2082         if (sctp_test_hmac("SHA1 test case 4", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
2083             text, textlen, digest, digestlen) < 0)
2084                 failed++;
2085
2086         /*
2087          * test_case =     5 key =
2088          * 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c key_len =       20
2089          * data =          "Test With Truncation" data_len =      20 digest
2090          * = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 digest-96 =
2091          * 0x4c1a03424b55e07fe7f27be1
2092          */
2093         keylen = 20;
2094         memset(key, 0x0c, keylen);
2095         textlen = 20;
2096         strcpy(text, "Test With Truncation");
2097         digest = "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04";
2098         if (sctp_test_hmac("SHA1 test case 5", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
2099             text, textlen, digest, digestlen) < 0)
2100                 failed++;
2101
2102         /*
2103          * test_case =     6 key =           0xaa repeated 80 times key_len
2104          * = 80 data =          "Test Using Larger Than Block-Size Key -
2105          * Hash Key First" data_len =      54 digest =
2106          * 0xaa4ae5e15272d00e95705637ce8a3b55ed402112
2107          */
2108         keylen = 80;
2109         memset(key, 0xaa, keylen);
2110         textlen = 54;
2111         strcpy(text, "Test Using Larger Than Block-Size Key - Hash Key First");
2112         digest = "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12";
2113         if (sctp_test_hmac("SHA1 test case 6", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
2114             text, textlen, digest, digestlen) < 0)
2115                 failed++;
2116
2117         /*
2118          * test_case =     7 key =           0xaa repeated 80 times key_len
2119          * = 80 data =          "Test Using Larger Than Block-Size Key and
2120          * Larger Than One Block-Size Data" data_len =      73 digest =
2121          * 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91
2122          */
2123         keylen = 80;
2124         memset(key, 0xaa, keylen);
2125         textlen = 73;
2126         strcpy(text, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data");
2127         digest = "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91";
2128         if (sctp_test_hmac("SHA1 test case 7", SCTP_AUTH_HMAC_ID_SHA1, key, keylen,
2129             text, textlen, digest, digestlen) < 0)
2130                 failed++;
2131
2132         /* done with all tests */
2133         if (failed)
2134                 printf("\nSHA1 test results: %d cases failed", failed);
2135         else
2136                 printf("\nSHA1 test results: all test cases passed");
2137 }
2138
2139 /*
2140  * RFC 2202: HMAC-MD5 test cases
2141  */
2142 void
2143 sctp_test_hmac_md5(void)
2144 {
2145         uint8_t *digest;
2146         uint8_t key[128];
2147         uint32_t keylen;
2148         uint8_t text[128];
2149         uint32_t textlen;
2150         uint32_t digestlen = 16;
2151         int failed = 0;
2152
2153         /*
2154          * test_case =     1 key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
2155          * key_len =       16 data = "Hi There" data_len =      8 digest =
2156          * 0x9294727a3638bb1c13f48ef8158bfc9d
2157          */
2158         keylen = 16;
2159         memset(key, 0x0b, keylen);
2160         textlen = 8;
2161         strcpy(text, "Hi There");
2162         digest = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d";
2163         if (sctp_test_hmac("MD5 test case 1", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
2164             text, textlen, digest, digestlen) < 0)
2165                 failed++;
2166
2167         /*
2168          * test_case =     2 key =           "Jefe" key_len =       4 data =
2169          * "what do ya want for nothing?" data_len =      28 digest =
2170          * 0x750c783e6ab0b503eaa86e310a5db738
2171          */
2172         keylen = 4;
2173         strcpy(key, "Jefe");
2174         textlen = 28;
2175         strcpy(text, "what do ya want for nothing?");
2176         digest = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
2177         if (sctp_test_hmac("MD5 test case 2", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
2178             text, textlen, digest, digestlen) < 0)
2179                 failed++;
2180
2181         /*
2182          * test_case =     3 key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2183          * key_len =       16 data = 0xdd repeated 50 times data_len = 50
2184          * digest = 0x56be34521d144c88dbb8c733f0e8b3f6
2185          */
2186         keylen = 16;
2187         memset(key, 0xaa, keylen);
2188         textlen = 50;
2189         memset(text, 0xdd, textlen);
2190         digest = "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6";
2191         if (sctp_test_hmac("MD5 test case 3", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
2192             text, textlen, digest, digestlen) < 0)
2193                 failed++;
2194
2195         /*
2196          * test_case =     4 key =
2197          * 0x0102030405060708090a0b0c0d0e0f10111213141516171819 key_len = 25
2198          * data =          0xcd repeated 50 times data_len =      50 digest
2199          * =        0x697eaf0aca3a3aea3a75164746ffaa79
2200          */
2201         keylen = 25;
2202         memcpy(key, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", keylen);
2203         textlen = 50;
2204         memset(text, 0xcd, textlen);
2205         digest = "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79";
2206         if (sctp_test_hmac("MD5 test case 4", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
2207             text, textlen, digest, digestlen) < 0)
2208                 failed++;
2209
2210         /*
2211          * test_case =     5 key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
2212          * key_len =       16 data = "Test With Truncation" data_len = 20
2213          * digest = 0x56461ef2342edc00f9bab995690efd4c digest-96
2214          * 0x56461ef2342edc00f9bab995
2215          */
2216         keylen = 16;
2217         memset(key, 0x0c, keylen);
2218         textlen = 20;
2219         strcpy(text, "Test With Truncation");
2220         digest = "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c";
2221         if (sctp_test_hmac("MD5 test case 5", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
2222             text, textlen, digest, digestlen) < 0)
2223                 failed++;
2224
2225         /*
2226          * test_case =     6 key =           0xaa repeated 80 times key_len
2227          * = 80 data =          "Test Using Larger Than Block-Size Key -
2228          * Hash Key First" data_len =      54 digest =
2229          * 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd
2230          */
2231         keylen = 80;
2232         memset(key, 0xaa, keylen);
2233         textlen = 54;
2234         strcpy(text, "Test Using Larger Than Block-Size Key - Hash Key First");
2235         digest = "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd";
2236         if (sctp_test_hmac("MD5 test case 6", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
2237             text, textlen, digest, digestlen) < 0)
2238                 failed++;
2239
2240         /*
2241          * test_case =     7 key =           0xaa repeated 80 times key_len
2242          * = 80 data =          "Test Using Larger Than Block-Size Key and
2243          * Larger Than One Block-Size Data" data_len =      73 digest =
2244          * 0x6f630fad67cda0ee1fb1f562db3aa53e
2245          */
2246         keylen = 80;
2247         memset(key, 0xaa, keylen);
2248         textlen = 73;
2249         strcpy(text, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data");
2250         digest = "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e";
2251         if (sctp_test_hmac("MD5 test case 7", SCTP_AUTH_HMAC_ID_MD5, key, keylen,
2252             text, textlen, digest, digestlen) < 0)
2253                 failed++;
2254
2255         /* done with all tests */
2256         if (failed)
2257                 printf("\nMD5 test results: %d cases failed", failed);
2258         else
2259                 printf("\nMD5 test results: all test cases passed");
2260 }
2261
2262 /*
2263  * test assoc key concatenation
2264  */
2265 static int
2266 sctp_test_key_concatenation(sctp_key_t * key1, sctp_key_t * key2,
2267     sctp_key_t * expected_key)
2268 {
2269         sctp_key_t *key;
2270         int ret_val;
2271
2272         sctp_show_key(key1, "\nkey1");
2273         sctp_show_key(key2, "\nkey2");
2274         key = sctp_compute_hashkey(key1, key2, NULL);
2275         sctp_show_key(expected_key, "\nExpected");
2276         sctp_show_key(key, "\nComputed");
2277         if (memcmp(key, expected_key, expected_key->keylen) != 0) {
2278                 printf("\nFAILED");
2279                 ret_val = -1;
2280         } else {
2281                 printf("\nPASSED");
2282                 ret_val = 0;
2283         }
2284         sctp_free_key(key1);
2285         sctp_free_key(key2);
2286         sctp_free_key(expected_key);
2287         sctp_free_key(key);
2288         return (ret_val);
2289 }
2290
2291
2292 void
2293 sctp_test_authkey(void)
2294 {
2295         sctp_key_t *key1, *key2, *expected_key;
2296         int failed = 0;
2297
2298         /* test case 1 */
2299         key1 = sctp_set_key("\x01\x01\x01\x01", 4);
2300         key2 = sctp_set_key("\x01\x02\x03\x04", 4);
2301         expected_key = sctp_set_key("\x01\x01\x01\x01\x01\x02\x03\x04", 8);
2302         if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
2303                 failed++;
2304
2305         /* test case 2 */
2306         key1 = sctp_set_key("\x00\x00\x00\x01", 4);
2307         key2 = sctp_set_key("\x02", 1);
2308         expected_key = sctp_set_key("\x00\x00\x00\x01\x02", 5);
2309         if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
2310                 failed++;
2311
2312         /* test case 3 */
2313         key1 = sctp_set_key("\x01", 1);
2314         key2 = sctp_set_key("\x00\x00\x00\x02", 4);
2315         expected_key = sctp_set_key("\x01\x00\x00\x00\x02", 5);
2316         if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
2317                 failed++;
2318
2319         /* test case 4 */
2320         key1 = sctp_set_key("\x00\x00\x00\x01", 4);
2321         key2 = sctp_set_key("\x01", 1);
2322         expected_key = sctp_set_key("\x01\x00\x00\x00\x01", 5);
2323         if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
2324                 failed++;
2325
2326         /* test case 5 */
2327         key1 = sctp_set_key("\x01", 1);
2328         key2 = sctp_set_key("\x00\x00\x00\x01", 4);
2329         expected_key = sctp_set_key("\x01\x00\x00\x00\x01", 5);
2330         if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
2331                 failed++;
2332
2333         /* test case 6 */
2334         key1 = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07", 11);
2335         key2 = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x08", 11);
2336         expected_key = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x08", 22);
2337         if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
2338                 failed++;
2339
2340         /* test case 7 */
2341         key1 = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x08", 11);
2342         key2 = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07", 11);
2343         expected_key = sctp_set_key("\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x08", 22);
2344         if (sctp_test_key_concatenation(key1, key2, expected_key) < 0)
2345                 failed++;
2346
2347         /* done with all tests */
2348         if (failed)
2349                 printf("\nKey concatenation test results: %d cases failed", failed);
2350         else
2351                 printf("\nKey concatenation test results: all test cases passed");
2352 }
2353
2354
2355 #if defined(STANDALONE_HMAC_TEST)
2356 int
2357 main(void)
2358 {
2359         sctp_test_hmac_sha1();
2360         sctp_test_hmac_md5();
2361         sctp_test_authkey();
2362 }
2363
2364 #endif                          /* STANDALONE_HMAC_TEST */
2365
2366 #endif                          /* SCTP_HMAC_TEST */