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