The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/sctp_auth.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 72f5d170026beace7b589f4103c841d3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.