50#define SCTP_AUTH_DEBUG (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_AUTH1)
51#define SCTP_AUTH_DEBUG2 (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_AUTH2)
57 memset(chklist, 0,
sizeof(*chklist));
68 if (chklist == NULL) {
96 memcpy(new_list, list,
sizeof(*new_list));
117 if (list->
chunks[chunk] == 0) {
121 "SCTP: added chunk %u (0x%02x) to Auth list\n",
136 if (list->
chunks[chunk] == 1) {
140 "SCTP: deleted chunk %u (0x%02x) from Auth list\n",
167 for (i = 0; i < 256; i++) {
168 if (list->
chunks[i] != 0) {
186 for (i = 0; i < 256; i++) {
187 if (list->
chunks[i] != 0) {
196 for (i = 0; i < 256; i++) {
197 if (list->
chunks[i] != 0) {
200 ptr[index] |= (1 << offset);
218 if (num_chunks <= 32) {
220 for (i = 0; i < num_chunks; i++) {
228 for (index = 0; index < 32; index++) {
229 for (offset = 0; offset < 8; offset++) {
230 if (ptr[index] & (1 << offset)) {
250 if (new_key == NULL) {
276 for (i = 0; i < key->
keylen; i++)
295 for (i = 0; i < key->
keylen; i++)
321 if (new_key == NULL) {
336 if (new_key == NULL) {
340 memcpy(new_key->
key, key, keylen);
362 if ((key1len == 0) && (key2len == 0))
364 else if (key1len == 0)
366 else if (key2len == 0)
369 if (key1len < key2len) {
377 for (i = 0; i < maxlen; i++) {
379 val1 = (i < (maxlen - key1len)) ? 0 : *(key_1++);
380 val2 = (i < (maxlen - key2len)) ? 0 : *(key_2++);
383 }
else if (val1 < val2) {
388 if (key1len == key2len)
390 else if (key1len < key2len)
414 if (new_key == NULL) {
419 key_ptr = new_key->
key;
429 memcpy(key_ptr, shared->
key, shared->
keylen);
430 key_ptr += shared->
keylen;
433 memcpy(key_ptr, key1->
key, key1->
keylen);
437 memcpy(key_ptr, key2->
key, key2->
keylen);
442 memcpy(key_ptr, shared->
key, shared->
keylen);
443 key_ptr += shared->
keylen;
446 memcpy(key_ptr, key2->
key, key2->
keylen);
450 memcpy(key_ptr, key1->
key, key1->
keylen);
463 if (new_key == NULL) {
481 if (skey->
key != NULL)
492 LIST_FOREACH(skey, shared_keys,
next) {
493 if (skey->
keyid == key_id)
505 if ((shared_keys == NULL) || (new_skey == NULL))
509 if (LIST_EMPTY(shared_keys)) {
510 LIST_INSERT_HEAD(shared_keys, new_skey,
next);
514 LIST_FOREACH(skey, shared_keys,
next) {
517 LIST_INSERT_BEFORE(skey, new_skey,
next);
524 "can't replace shared key id %u\n",
529 "replacing shared key id %u\n",
531 LIST_INSERT_BEFORE(skey, new_skey,
next);
532 LIST_REMOVE(skey,
next);
536 if (LIST_NEXT(skey,
next) == NULL) {
538 LIST_INSERT_AFTER(skey, new_skey,
next);
558 "%s: stcb %p key %u refcount acquire to %d\n",
559 __func__, (
void *)stcb, key_id, skey->
refcount);
574 "%s: stcb %p key %u refcount release to %d\n",
575 __func__, (
void *)stcb, key_id, skey->
refcount);
581 key_id, 0, so_locked);
583 "%s: stcb %p key %u no longer used, %d\n",
584 __func__, (
void *)stcb, key_id, skey->
refcount);
598 if (new_skey == NULL)
600 if (skey->
key != NULL)
603 new_skey->
key = NULL;
614 if ((src == NULL) || (dest == NULL))
616 LIST_FOREACH(skey, src,
next) {
618 if (new_skey != NULL) {
635 alloc_size =
sizeof(*new_list) + num_hmacs *
sizeof(new_list->
hmac[0]);
638 if (new_list == NULL) {
664 "SCTP: HMAC id list full, ignoring add %u\n", hmac_id);
672 for (i = 0; i < list->
num_algo; i++) {
673 if (list->
hmac[i] == hmac_id) {
693 if (new_list == NULL)
698 for (i = 0; i < list->
num_algo; i++)
709 if (new_list == NULL)
726 if ((local == NULL) || (peer == NULL))
729 for (i = 0; i < peer->
num_algo; i++) {
730 for (j = 0; j < local->
num_algo; j++) {
731 if (peer->
hmac[i] == local->
hmac[j]) {
734 "SCTP: negotiated peer HMAC id %u\n",
736 return (peer->
hmac[i]);
757 for (i = 0; i < list->
num_algo; i++) {
758 hmac_id = htons(list->
hmac[i]);
759 memcpy(ptr, &hmac_id,
sizeof(hmac_id));
760 ptr +=
sizeof(hmac_id);
762 return (list->
num_algo *
sizeof(hmac_id));
770 for (i = 0; i < num_hmacs; i++) {
786 if (new_authinfo == NULL) {
790 memset(new_authinfo, 0,
sizeof(*new_authinfo));
791 return (new_authinfo);
797 if (authinfo == NULL)
800 if (authinfo->
random != NULL)
926 if ((key == NULL) || (keylen == 0) || (text == NULL) ||
927 (textlen == 0) || (digest == NULL)) {
938 if (keylen > blocklen) {
947 memset(ipad, 0, blocklen);
948 memset(opad, 0, blocklen);
949 memcpy(ipad, key, keylen);
950 memcpy(opad, key, keylen);
953 for (i = 0; i < blocklen; i++) {
987 if ((key == NULL) || (keylen == 0) || (m == NULL) || (digest == NULL)) {
998 if (keylen > blocklen) {
1007 memset(ipad, 0, blocklen);
1008 memset(opad, 0, blocklen);
1009 memcpy(ipad, key, keylen);
1010 memcpy(opad, key, keylen);
1013 for (i = 0; i < blocklen; i++) {
1028 while (m_tmp != NULL) {
1066 if ((key == NULL) || (text == NULL) || (textlen == 0) ||
1078 if (key->
keylen > blocklen) {
1101 if ((key == NULL) || (m == NULL) || (digest == NULL)) {
1112 if (key->
keylen > blocklen) {
1131 for (i = 0; i < list->
num_algo; i++)
1132 if (list->
hmac[i] ==
id)
1207 LIST_REMOVE(skey,
next);
1239 LIST_REMOVE(skey,
next);
1352 LIST_REMOVE(skey,
next);
1384 while (phdr != NULL) {
1389 (offset + plen > length))
1393 if (plen >
sizeof(random_store))
1401 random_len = plen -
sizeof(*p_random);
1406 if (plen >
sizeof(hmacs_store))
1414 hmacs_len = plen -
sizeof(*hmacs);
1415 num_hmacs = hmacs_len /
sizeof(hmacs->hmac_ids[0]);
1420 for (i = 0; i < num_hmacs; i++) {
1422 ntohs(hmacs->hmac_ids[i]));
1428 if (plen >
sizeof(chunks_store))
1435 num_chunks = plen -
sizeof(*chunks);
1441 for (i = 0; i < num_chunks; i++) {
1454 keylen =
sizeof(*p_random) + random_len +
sizeof(*hmacs) + hmacs_len;
1455 if (chunks != NULL) {
1456 keylen +=
sizeof(*chunks) + num_chunks;
1459 if (new_key != NULL) {
1461 if (p_random != NULL) {
1462 keylen =
sizeof(*p_random) + random_len;
1463 memcpy(new_key->
key, p_random, keylen);
1468 if (chunks != NULL) {
1469 memcpy(new_key->
key + keylen, chunks,
1470 sizeof(*chunks) + num_chunks);
1471 keylen +=
sizeof(*chunks) + num_chunks;
1474 if (hmacs != NULL) {
1475 memcpy(new_key->
key + keylen, hmacs,
1476 sizeof(*hmacs) + hmacs_len);
1509 if ((stcb == NULL) || (auth == NULL))
1537 if (SCTP_AUTH_DEBUG)
1548 m, auth_offset, auth->
hmac);
1568 while ((m_tmp != NULL) && (size > 0)) {
1569 data = mtod(m_tmp,
uint8_t *)+m_offset;
1574 memset(data, 0, size);
1603 if (chunklen <
sizeof(*auth)) {
1611 hmac_id = ntohs(auth->
hmac_id);
1613 "SCTP AUTH Chunk: shared key %u, HMAC id %u\n",
1614 shared_key_id, hmac_id);
1618 struct mbuf *op_err;
1623 "SCTP Auth: unsupported HMAC id %u\n",
1630 0, M_NOWAIT, 1, MT_HEADER);
1631 if (op_err != NULL) {
1655 "SCTP Auth: unknown key id %u\n",
1677 if (SCTP_AUTH_DEBUG)
1683 if (chunklen < (
sizeof(*auth) + digestlen)) {
1687 "SCTP Auth: chunk too short for HMAC\n");
1691 memcpy(digest, auth->
hmac, digestlen);
1694 m, offset, computed_digest);
1697 if (timingsafe_bcmp(digest, computed_digest, digestlen) != 0) {
1700 "SCTP Auth: HMAC digest check failed\n");
1713 struct mbuf *m_notify;
1717 if ((
stcb == NULL) ||
1731 0, M_NOWAIT, 1, MT_HEADER);
1732 if (m_notify == NULL)
1753 if (control == NULL) {
1776 int peer_supports_asconf = 0;
1777 int peer_supports_auth = 0;
1778 int got_random = 0, got_hmacs = 0, got_chklist = 0;
1788 if (offset + plen > limit) {
1800 if (plen >
sizeof(local_store)) {
1811 for (i = 0; i < num_ent; i++) {
1815 peer_supports_asconf = 1;
1827 "SCTP: invalid RANDOM len\n");
1836 if (plen >
sizeof(store)) {
1846 num_hmacs = (plen -
sizeof(*hmacs)) /
sizeof(hmacs->
hmac_ids[0]);
1850 "SCTP: invalid HMAC param\n");
1859 if (plen >
sizeof(chunks_store)) {
1873 num_chunks = plen -
sizeof(*chunks);
1874 for (i = 0; i < num_chunks; i++) {
1886 if (offset >= limit) {
1893 if (got_random && got_hmacs) {
1894 peer_supports_auth = 1;
1896 peer_supports_auth = 0;
1898 if (!peer_supports_auth && got_chklist) {
1900 "SCTP: peer sent chunk list w/o AUTH\n");
1903 if (peer_supports_asconf && !peer_supports_auth) {
1905 "SCTP: peer supports ASCONF but not AUTH\n");
1907 }
else if ((peer_supports_asconf) && (peer_supports_auth) &&
1908 ((saw_asconf == 0) || (saw_asconf_ack == 0))) {
1935 for (i = 0; i < 256; i++) {
1949 keylen = (3 *
sizeof(
struct sctp_paramhdr)) + random_len + chunks_len +
1952 if (new_key != NULL) {
1959 plen =
sizeof(*ph) + random_len;
1968 plen =
sizeof(*ph) + chunks_len;
1970 keylen +=
sizeof(*ph);
1974 for (i = 0; i < 256; i++) {
1976 new_key->
key[keylen++] = i;
1983 plen =
sizeof(*ph) + hmacs_len;
1985 keylen +=
sizeof(*ph);
1987 new_key->
key + keylen);
#define SCTP_INITIATION_ACK
#define SCTP_PCB_FLAGS_SOCKET_ALLGONE
#define SCTP_PCB_FLAGS_SOCKET_GONE
#define SCTP_AUTHENTICATION
#define SCTP_PCB_FLAGS_AUTHEVNT
#define SCTP_SHUTDOWN_COMPLETE
#define SCTP_CAUSE_UNSUPPORTED_HMACID
int sctp_pack_auth_chunks(const sctp_auth_chklist_t *list, uint8_t *ptr)
static void sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t *ctx, uint8_t *text, uint32_t textlen)
static void sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t *ctx)
int sctp_auth_is_supported_hmac(sctp_hmaclist_t *list, uint16_t id)
int sctp_serialize_auth_chunks(const sctp_auth_chklist_t *list, uint8_t *ptr)
static int sctp_get_hmac_block_len(uint16_t hmac_algo)
sctp_auth_chklist_t * sctp_copy_chunklist(sctp_auth_chklist_t *list)
int sctp_auth_add_hmacid(sctp_hmaclist_t *list, uint16_t hmac_id)
int sctp_auth_delete_chunk(uint8_t chunk, sctp_auth_chklist_t *list)
void sctp_free_key(sctp_key_t *key)
void sctp_clear_chunklist(sctp_auth_chklist_t *chklist)
uint32_t sctp_get_hmac_digest_len(uint16_t hmac_algo)
sctp_key_t * sctp_compute_hashkey(sctp_key_t *key1, sctp_key_t *key2, sctp_key_t *shared)
void sctp_free_chunklist(sctp_auth_chklist_t *list)
void sctp_free_hmaclist(sctp_hmaclist_t *list)
uint32_t sctp_compute_hmac_m(uint16_t hmac_algo, sctp_key_t *key, struct mbuf *m, uint32_t m_offset, uint8_t *digest)
sctp_hmaclist_t * sctp_copy_hmaclist(sctp_hmaclist_t *list)
sctp_sharedkey_t * sctp_alloc_sharedkey(void)
int sctp_deact_sharedkey(struct sctp_tcb *stcb, uint16_t keyid)
size_t sctp_auth_get_chklist_size(const sctp_auth_chklist_t *list)
static void sctp_zero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
sctp_key_t * sctp_set_key(uint8_t *key, uint32_t keylen)
void sctp_print_key(sctp_key_t *key, const char *str)
int sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
int sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest)
static sctp_sharedkey_t * sctp_copy_sharedkey(const sctp_sharedkey_t *skey)
int sctp_auth_add_chunk(uint8_t chunk, sctp_auth_chklist_t *list)
void sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication, uint16_t keyid, uint16_t alt_keyid, int so_locked)
void sctp_show_key(sctp_key_t *key, const char *str)
static int sctp_compare_key(sctp_key_t *key1, sctp_key_t *key2)
uint16_t sctp_negotiate_hmacid(sctp_hmaclist_t *peer, sctp_hmaclist_t *local)
int sctp_delete_sharedkey_ep(struct sctp_inpcb *inp, uint16_t keyid)
sctp_authinfo_t * sctp_alloc_authinfo(void)
int sctp_delete_sharedkey(struct sctp_tcb *stcb, uint16_t keyid)
void sctp_clear_cachedkeys_ep(struct sctp_inpcb *inp, uint16_t keyid)
int sctp_serialize_hmaclist(sctp_hmaclist_t *list, uint8_t *ptr)
int sctp_auth_setactivekey_ep(struct sctp_inpcb *inp, uint16_t keyid)
int sctp_verify_hmac_param(struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs)
void sctp_free_sharedkey(sctp_sharedkey_t *skey)
static uint32_t sctp_get_keylen(sctp_key_t *key)
void sctp_initialize_auth_params(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
void sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t key_id)
void sctp_free_authinfo(sctp_authinfo_t *authinfo)
sctp_key_t * sctp_generate_random_key(uint32_t keylen)
sctp_auth_chklist_t * sctp_alloc_chunklist(void)
int sctp_insert_sharedkey(struct sctp_keyhead *shared_keys, sctp_sharedkey_t *new_skey)
sctp_sharedkey_t * sctp_find_sharedkey(struct sctp_keyhead *shared_keys, uint16_t key_id)
sctp_key_t * sctp_alloc_key(uint32_t keylen)
void sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m, uint32_t offset, uint32_t length)
void sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked)
int sctp_unpack_auth_chunks(const uint8_t *ptr, uint8_t num_chunks, sctp_auth_chklist_t *list)
int sctp_deact_sharedkey_ep(struct sctp_inpcb *inp, uint16_t keyid)
sctp_hmaclist_t * sctp_alloc_hmaclist(uint16_t num_hmacs)
uint32_t sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t *key, uint8_t *text, uint32_t textlen, uint8_t *digest)
void sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset, struct sctp_auth_chunk *auth, struct sctp_tcb *stcb, uint16_t keyid)
sctp_hmaclist_t * sctp_default_supported_hmaclist(void)
int sctp_auth_setactivekey(struct sctp_tcb *stcb, uint16_t keyid)
void sctp_clear_cachedkeys(struct sctp_tcb *stcb, uint16_t keyid)
uint32_t sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, uint8_t *text, uint32_t textlen, uint8_t *digest)
uint32_t sctp_get_auth_chunk_len(uint16_t hmac_algo)
static void sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t *ctx, uint8_t *digest)
int sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth, struct mbuf *m, uint32_t offset)
uint32_t sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, struct mbuf *m, uint32_t m_offset, uint8_t *digest, uint32_t trailer)
#define SCTP_AUTH_DIGEST_LEN_MAX
#define SCTP_AUTH_RANDOM_SIZE_DEFAULT
#define SCTP_AUTH_RANDOM_SIZE_REQUIRED
#define SCTP_AUTH_DIGEST_LEN_SHA256
#define SCTP_AUTH_DIGEST_LEN_SHA1
struct mbuf * sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int allonebuf, int type)
#define SCTP_PARAM_BUFFER_SIZE
#define SCTP_SUPPORTED_CHUNK_EXT
#define SCTP_NOTIFY_AUTH_FREE_KEY
#define SCTP_SO_NOT_LOCKED
#define SCTP_SMALL_CHUNK_STORE
#define SCTP_STATE_CLOSED_SOCKET
struct sctp_queued_to_read * sctp_build_readq_entry(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t tsn, uint32_t ppid, uint32_t context, uint16_t sid, uint32_t mid, uint8_t flags, struct mbuf *dm)
#define SCTP_TCB_LOCK(_tcb)
#define SCTP_TCB_UNLOCK(_tcb)
#define SCTP_BUF_RESV_UF(m, size)
#define SCTP_READ_RANDOM(buf, len)
#define SCTP_MALLOC(var, type, size, name)
#define SCTP_DECREMENT_AND_CHECK_REFCOUNT(addr)
#define SCTP_PRINTF(params...)
#define SCTP_SHA256_UPDATE
#define SCTP_FREE(var, type)
#define SCTP_SHA256_FINAL(x, y)
#define SCTPDBG(level, params...)
#define SCTP_SHA1_FINAL(x, y)
void sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err)
#define SCTP_AUTH_HMAC_ID_SHA1
#define SCTP_AUTH_NEW_KEY
#define SCTP_AUTH_HMAC_ID_RSVD
#define SCTP_AUTH_HMAC_ID_SHA256
#define SCTP_AUTHENTICATION_EVENT
#define SCTP_STAT_INCR(_x)
#define sctp_stcb_is_feature_off(inp, stcb, feature)
struct sctp_paramhdr * sctp_get_next_param(struct mbuf *m, int offset, struct sctp_paramhdr *pull, int pull_limit)
void sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, uint32_t error, void *data, int so_locked)
void sctp_add_to_readq(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_queued_to_read *control, struct sockbuf *sb, int end, int inp_read_lock_held, int so_locked)
caddr_t sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t *in_ptr)
#define sctp_get_associd(stcb)
#define SCTP_READ_LOCK_NOT_HELD
sctp_auth_chklist_t * local_auth_chunks
struct sctp_keyhead shared_keys
sctp_hmaclist_t * local_hmacs
sctp_hmaclist_t * peer_hmacs
struct sctp_nets * primary_destination
sctp_assoc_t auth_assoc_id
uint16_t auth_altkeynumber
struct sctp_error_cause cause
struct sctpasochead sctp_asoc_list
struct sctp_keyhead shared_keys
sctp_auth_chklist_t * local_auth_chunks
sctp_hmaclist_t * local_hmacs
struct socket * sctp_socket
struct sctp_association asoc
struct sctp_inpcb * sctp_ep