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

Cache object: 3ea5e03d58db3dde596c2cb73693e3dc


[ 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.