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_sha1.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 /*      $KAME: sctp_sha1.c,v 1.8 2004/02/24 21:52:27 itojun Exp $       */
    2 /*      $DragonFly: src/sys/netinet/sctp_sha1.c,v 1.1 2005/07/15 14:46:17 eirikn Exp $  */
    3 
    4 /*
    5  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
    6  * 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
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Cisco Systems, Inc.
   19  * 4. Neither the name of the project nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  */
   35 #include <netinet/sctp_sha1.h>
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 void
   39 SHA1_Init(struct sha1_context *ctx)
   40 {
   41         /* Init the SHA-1 context structure */
   42         ctx->A = 0;
   43         ctx->B = 0;
   44         ctx->C = 0;
   45         ctx->D = 0;
   46         ctx->E = 0;
   47         ctx->H0 = H0INIT;
   48         ctx->H1 = H1INIT;
   49         ctx->H2 = H2INIT;
   50         ctx->H3 = H3INIT;
   51         ctx->H4 = H4INIT;
   52         ctx->TEMP = 0;
   53         memset(ctx->words, 0, sizeof(ctx->words));
   54         ctx->how_many_in_block = 0;
   55         ctx->running_total = 0;
   56 }
   57 
   58 static void
   59 sha1_process_a_block(struct sha1_context *ctx, unsigned int *block)
   60 {
   61         int i;
   62         /* init the W0-W15 to the block of words being hashed. */
   63         /* step a) */
   64         for (i = 0; i < 16; i++) {
   65                 ctx->words[i] = ntohl(block[i]);
   66         }
   67         /* now init the rest based on the SHA-1 formula, step b) */
   68         for (i = 16; i < 80; i++) {
   69                 ctx->words[i] = CSHIFT(1, ((ctx->words[(i-3)]) ^
   70                                            (ctx->words[(i-8)]) ^
   71                                            (ctx->words[(i-14)]) ^
   72                                            (ctx->words[(i-16)])));
   73         }
   74         /* step c) */
   75         ctx->A = ctx->H0;
   76         ctx->B = ctx->H1;
   77         ctx->C = ctx->H2;
   78         ctx->D = ctx->H3;
   79         ctx->E = ctx->H4;
   80 
   81         /* step d) */
   82         for (i = 0; i < 80; i++) {
   83                 if (i < 20) {
   84                         ctx->TEMP = ((CSHIFT(5, ctx->A)) +
   85                                      (F1(ctx->B, ctx->C, ctx->D)) +
   86                                      (ctx->E) +
   87                                      ctx->words[i] +
   88                                      K1);
   89                 } else if (i < 40) {
   90                         ctx->TEMP = ((CSHIFT(5, ctx->A)) +
   91                                      (F2(ctx->B, ctx->C, ctx->D)) +
   92                                      (ctx->E) +
   93                                      (ctx->words[i]) +
   94                                      K2);
   95                 } else if (i < 60) {
   96                         ctx->TEMP = ((CSHIFT(5, ctx->A)) +
   97                                      (F3(ctx->B, ctx->C, ctx->D)) +
   98                                      (ctx->E) +
   99                                      (ctx->words[i]) +
  100                                      K3);
  101                 } else {
  102                         ctx->TEMP = ((CSHIFT(5, ctx->A)) +
  103                                      (F4(ctx->B, ctx->C, ctx->D)) +
  104                                      (ctx->E) +
  105                                      (ctx->words[i]) +
  106                                      K4);
  107                 }
  108                 ctx->E = ctx->D;
  109                 ctx->D = ctx->C;
  110                 ctx->C = CSHIFT(30, ctx->B);
  111                 ctx->B = ctx->A;
  112                 ctx->A = ctx->TEMP;
  113         }
  114         /* step e) */
  115         ctx->H0 = (ctx->H0) + (ctx->A);
  116         ctx->H1 = (ctx->H1) + (ctx->B);
  117         ctx->H2 = (ctx->H2) + (ctx->C);
  118         ctx->H3 = (ctx->H3) + (ctx->D);
  119         ctx->H4 = (ctx->H4) + (ctx->E);
  120 }
  121 
  122 
  123 void
  124 SHA1_Process(struct sha1_context *ctx, unsigned char *ptr, int siz)
  125 {
  126         int number_left, left_to_fill;
  127         number_left = siz;
  128         while (number_left > 0) {
  129                 left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block;
  130                 if (left_to_fill > number_left) {
  131                         /* can only partially fill up this one */
  132                         memcpy(&ctx->sha_block[ctx->how_many_in_block],
  133                                ptr, number_left);
  134                         ctx->how_many_in_block += number_left;
  135                         ctx->running_total += number_left;
  136                         number_left = 0;
  137                         break;
  138                 } else {
  139                         /* block is now full, process it */
  140                         memcpy(&ctx->sha_block[ctx->how_many_in_block],
  141                                ptr, left_to_fill);
  142                         sha1_process_a_block(ctx,
  143                                              (unsigned int *)ctx->sha_block);
  144                         number_left -= left_to_fill;
  145                         ctx->running_total += left_to_fill;
  146                         ctx->how_many_in_block = 0;
  147                         ptr = (unsigned char *)((caddr_t)ptr + left_to_fill);
  148                 }
  149         }
  150 }
  151 
  152 void
  153 SHA1_Final(struct sha1_context *ctx, unsigned char *digest)
  154 {
  155         /*
  156          * if any left in block fill with padding and process. Then
  157          * transfer the digest to the pointer. At the last block some
  158          * special rules need to apply. We must add a 1 bit following
  159          * the message, then we pad with 0's. The total size is encoded
  160          * as a 64 bit number at the end. Now if the last buffer has
  161          * more than 55 octets in it we cannot fit the 64 bit number +
  162          * 10000000 pad on the end and must add the 10000000 pad, pad
  163          * the rest of the message with 0's and then create an all 0
  164          * message with just the 64 bit size at the end and run this
  165          * block through by itself.  Also the 64 bit int must be in
  166          * network byte order.
  167          */
  168         int left_to_fill;
  169         unsigned int i, *ptr;
  170         if (ctx->how_many_in_block > 55) {
  171                 /*
  172                  * special case, we need to process two blocks here.
  173                  * One for the current stuff plus possibly the pad.
  174                  * The other for the size.
  175                  */
  176                 left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block;
  177                 if (left_to_fill == 0) {
  178                         /* Should not really happen but I am paranoid */
  179                         sha1_process_a_block(ctx,
  180                                              (unsigned int *)ctx->sha_block);
  181                         /* init last block, a bit different than the rest */
  182                         ctx->sha_block[0] = 0x80;
  183                         for (i = 1; i < sizeof(ctx->sha_block); i++) {
  184                                 ctx->sha_block[i] = 0x0;
  185                         }
  186                 } else if (left_to_fill == 1) {
  187                         ctx->sha_block[ctx->how_many_in_block] = 0x80;
  188                         sha1_process_a_block(ctx,
  189                                              (unsigned int *)ctx->sha_block);
  190                         /* init last block */
  191                         memset(ctx->sha_block, 0, sizeof(ctx->sha_block));
  192                 } else {
  193                         ctx->sha_block[ctx->how_many_in_block] = 0x80;
  194                         for (i =( ctx->how_many_in_block + 1);
  195                              i < sizeof(ctx->sha_block);
  196                              i++) {
  197                                 ctx->sha_block[i] = 0x0;
  198                         }
  199                         sha1_process_a_block(ctx,
  200                                              (unsigned int *)ctx->sha_block);
  201                         /* init last block */
  202                         memset(ctx->sha_block, 0, sizeof(ctx->sha_block));
  203                 }
  204                 /* This is in bits so multiply by 8 */
  205                 ctx->running_total *= 8;
  206                 ptr = (unsigned int *)&ctx->sha_block[60];
  207                 *ptr = htonl(ctx->running_total);
  208                 sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
  209         } else {
  210                 /*
  211                  * easy case, we just pad this message to size - end with 0
  212                  * add the magic 0x80 to the next word and then put the
  213                  * network byte order size in the last spot and process
  214                  * the block.
  215                  */
  216                 ctx->sha_block[ctx->how_many_in_block] = 0x80;
  217                 for (i = (ctx->how_many_in_block + 1);
  218                      i < sizeof(ctx->sha_block);
  219                      i++) {
  220                         ctx->sha_block[i] = 0x0;
  221                 }
  222                 /* get last int spot */
  223                 ctx->running_total *= 8;
  224                 ptr = (unsigned int *)&ctx->sha_block[60];
  225                 *ptr = htonl(ctx->running_total);
  226                 sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
  227         }
  228         /* transfer the digest back to the user */
  229         digest[3] = (ctx->H0 & 0xff);
  230         digest[2] = ((ctx->H0 >> 8) & 0xff);
  231         digest[1] = ((ctx->H0 >> 16) & 0xff);
  232         digest[0] = ((ctx->H0 >> 24) & 0xff);
  233 
  234         digest[7] = (ctx->H1 & 0xff);
  235         digest[6] = ((ctx->H1 >> 8) & 0xff);
  236         digest[5] = ((ctx->H1 >> 16) & 0xff);
  237         digest[4] = ((ctx->H1 >> 24) & 0xff);
  238 
  239         digest[11] = (ctx->H2 & 0xff);
  240         digest[10] = ((ctx->H2 >> 8) & 0xff);
  241         digest[9] = ((ctx->H2 >> 16) & 0xff);
  242         digest[8] = ((ctx->H2 >> 24) & 0xff);
  243 
  244         digest[15] = (ctx->H3 & 0xff);
  245         digest[14] = ((ctx->H3 >> 8) & 0xff);
  246         digest[13] = ((ctx->H3 >> 16) & 0xff);
  247         digest[12] = ((ctx->H3 >> 24) & 0xff);
  248 
  249         digest[19] = (ctx->H4 & 0xff);
  250         digest[18] = ((ctx->H4 >> 8) & 0xff);
  251         digest[17] = ((ctx->H4 >> 16) & 0xff);
  252         digest[16] = ((ctx->H4 >> 24) & 0xff);
  253 }
  254 
  255 
  256 
  257 
  258 
  259 
  260 

Cache object: 82cbd60fe194dda8b5809514ffefc99a


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