LCOV - code coverage report
Current view: top level - netwerk/sctp/src/netinet - sctp_sha1.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 128 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
       3             :  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
       4             :  * Copyright (c) 2008-2013, by Michael Tuexen. All rights reserved.
       5             :  * Copyright (c) 2013,      by Lally Singh. All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions are met:
       9             :  *
      10             :  * a) Redistributions of source code must retain the above copyright notice,
      11             :  *   this list of conditions and the following disclaimer.
      12             :  *
      13             :  * b) Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in
      15             :  *   the documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * c) Neither the name of Cisco Systems, Inc. nor the names of its
      18             :  *    contributors may be used to endorse or promote products derived
      19             :  *    from this software without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      22             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
      23             :  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      25             :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      26             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      27             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      28             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      29             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      30             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
      31             :  * THE POSSIBILITY OF SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include <netinet/sctp_sha1.h>
      35             : 
      36             : #if defined(SCTP_USE_NSS_SHA1)
      37             : /* A SHA-1 Digest is 160 bits, or 20 bytes */
      38             : #define SHA_DIGEST_LENGTH (20)
      39             : 
      40             : void
      41             : sctp_sha1_init(struct sctp_sha1_context *ctx)
      42             : {
      43             :         ctx->pk11_ctx = PK11_CreateDigestContext(SEC_OID_SHA1);
      44             :         PK11_DigestBegin(ctx->pk11_ctx);
      45             : }
      46             : 
      47             : void
      48             : sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
      49             : {
      50             :         PK11_DigestOp(ctx->pk11_ctx, ptr, siz);
      51             : }
      52             : 
      53             : void
      54             : sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
      55             : {
      56             :         unsigned int output_len = 0;
      57             : 
      58             :         PK11_DigestFinal(ctx->pk11_ctx, digest, &output_len, SHA_DIGEST_LENGTH);
      59             :         PK11_DestroyContext(ctx->pk11_ctx, PR_TRUE);
      60             : }
      61             : 
      62             : #elif defined(SCTP_USE_OPENSSL_SHA1)
      63             : 
      64             : void
      65             : sctp_sha1_init(struct sctp_sha1_context *ctx)
      66             : {
      67             :         SHA1_Init(&ctx->sha_ctx);
      68             : }
      69             : 
      70             : void
      71             : sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
      72             : {
      73             :         SHA1_Update(&ctx->sha_ctx, ptr, (unsigned long)siz);
      74             : }
      75             : 
      76             : void
      77             : sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
      78             : {
      79             :         SHA1_Final(digest, &ctx->sha_ctx);
      80             : }
      81             : 
      82             : #else
      83             : 
      84             : #include <string.h>
      85             : #if defined(__Userspace_os_Windows)
      86             : #include <winsock2.h>
      87             : #elif !defined(__Windows__)
      88             : #include <arpa/inet.h>
      89             : #endif
      90             : 
      91             : #define F1(B,C,D) (((B & C) | ((~B) & D)))      /* 0  <= t <= 19 */
      92             : #define F2(B,C,D) (B ^ C ^ D)   /* 20 <= t <= 39 */
      93             : #define F3(B,C,D) ((B & C) | (B & D) | (C & D))     /* 40 <= t <= 59 */
      94             : #define F4(B,C,D) (B ^ C ^ D)   /* 600 <= t <= 79 */
      95             : 
      96             : /* circular shift */
      97             : #define CSHIFT(A,B) ((B << A) | (B >> (32-A)))
      98             : 
      99             : #define K1 0x5a827999           /* 0  <= t <= 19 */
     100             : #define K2 0x6ed9eba1           /* 20 <= t <= 39 */
     101             : #define K3 0x8f1bbcdc           /* 40 <= t <= 59 */
     102             : #define K4 0xca62c1d6           /* 60 <= t <= 79 */
     103             : 
     104             : #define H0INIT 0x67452301
     105             : #define H1INIT 0xefcdab89
     106             : #define H2INIT 0x98badcfe
     107             : #define H3INIT 0x10325476
     108             : #define H4INIT 0xc3d2e1f0
     109             : 
     110             : void
     111           0 : sctp_sha1_init(struct sctp_sha1_context *ctx)
     112             : {
     113             :         /* Init the SHA-1 context structure */
     114           0 :         ctx->A = 0;
     115           0 :         ctx->B = 0;
     116           0 :         ctx->C = 0;
     117           0 :         ctx->D = 0;
     118           0 :         ctx->E = 0;
     119           0 :         ctx->H0 = H0INIT;
     120           0 :         ctx->H1 = H1INIT;
     121           0 :         ctx->H2 = H2INIT;
     122           0 :         ctx->H3 = H3INIT;
     123           0 :         ctx->H4 = H4INIT;
     124           0 :         ctx->TEMP = 0;
     125           0 :         memset(ctx->words, 0, sizeof(ctx->words));
     126           0 :         ctx->how_many_in_block = 0;
     127           0 :         ctx->running_total = 0;
     128           0 : }
     129             : 
     130             : static void
     131           0 : sctp_sha1_process_a_block(struct sctp_sha1_context *ctx, unsigned int *block)
     132             : {
     133             :         int i;
     134             : 
     135             :         /* init the W0-W15 to the block of words being hashed. */
     136             :         /* step a) */
     137           0 :         for (i = 0; i < 16; i++) {
     138           0 :                 ctx->words[i] = ntohl(block[i]);
     139             :         }
     140             :         /* now init the rest based on the SHA-1 formula, step b) */
     141           0 :         for (i = 16; i < 80; i++) {
     142           0 :                 ctx->words[i] = CSHIFT(1, ((ctx->words[(i - 3)]) ^
     143             :                     (ctx->words[(i - 8)]) ^
     144             :                     (ctx->words[(i - 14)]) ^
     145             :                     (ctx->words[(i - 16)])));
     146             :         }
     147             :         /* step c) */
     148           0 :         ctx->A = ctx->H0;
     149           0 :         ctx->B = ctx->H1;
     150           0 :         ctx->C = ctx->H2;
     151           0 :         ctx->D = ctx->H3;
     152           0 :         ctx->E = ctx->H4;
     153             : 
     154             :         /* step d) */
     155           0 :         for (i = 0; i < 80; i++) {
     156           0 :                 if (i < 20) {
     157           0 :                         ctx->TEMP = ((CSHIFT(5, ctx->A)) +
     158           0 :                             (F1(ctx->B, ctx->C, ctx->D)) +
     159           0 :                             (ctx->E) +
     160           0 :                             ctx->words[i] +
     161             :                             K1);
     162           0 :                 } else if (i < 40) {
     163           0 :                         ctx->TEMP = ((CSHIFT(5, ctx->A)) +
     164           0 :                             (F2(ctx->B, ctx->C, ctx->D)) +
     165           0 :                             (ctx->E) +
     166           0 :                             (ctx->words[i]) +
     167             :                             K2);
     168           0 :                 } else if (i < 60) {
     169           0 :                         ctx->TEMP = ((CSHIFT(5, ctx->A)) +
     170           0 :                             (F3(ctx->B, ctx->C, ctx->D)) +
     171           0 :                             (ctx->E) +
     172           0 :                             (ctx->words[i]) +
     173             :                             K3);
     174             :                 } else {
     175           0 :                         ctx->TEMP = ((CSHIFT(5, ctx->A)) +
     176           0 :                             (F4(ctx->B, ctx->C, ctx->D)) +
     177           0 :                             (ctx->E) +
     178           0 :                             (ctx->words[i]) +
     179             :                             K4);
     180             :                 }
     181           0 :                 ctx->E = ctx->D;
     182           0 :                 ctx->D = ctx->C;
     183           0 :                 ctx->C = CSHIFT(30, ctx->B);
     184           0 :                 ctx->B = ctx->A;
     185           0 :                 ctx->A = ctx->TEMP;
     186             :         }
     187             :         /* step e) */
     188           0 :         ctx->H0 = (ctx->H0) + (ctx->A);
     189           0 :         ctx->H1 = (ctx->H1) + (ctx->B);
     190           0 :         ctx->H2 = (ctx->H2) + (ctx->C);
     191           0 :         ctx->H3 = (ctx->H3) + (ctx->D);
     192           0 :         ctx->H4 = (ctx->H4) + (ctx->E);
     193           0 : }
     194             : 
     195             : void
     196           0 : sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
     197             : {
     198             :         unsigned int number_left, left_to_fill;
     199             : 
     200           0 :         number_left = siz;
     201           0 :         while (number_left > 0) {
     202           0 :                 left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block;
     203           0 :                 if (left_to_fill > number_left) {
     204             :                         /* can only partially fill up this one */
     205           0 :                         memcpy(&ctx->sha_block[ctx->how_many_in_block],
     206             :                             ptr, number_left);
     207           0 :                         ctx->how_many_in_block += number_left;
     208           0 :                         ctx->running_total += number_left;
     209           0 :                         break;
     210             :                 } else {
     211             :                         /* block is now full, process it */
     212           0 :                         memcpy(&ctx->sha_block[ctx->how_many_in_block],
     213             :                             ptr, left_to_fill);
     214           0 :                         sctp_sha1_process_a_block(ctx,
     215           0 :                             (unsigned int *)ctx->sha_block);
     216           0 :                         number_left -= left_to_fill;
     217           0 :                         ctx->running_total += left_to_fill;
     218           0 :                         ctx->how_many_in_block = 0;
     219           0 :                         ptr = (const unsigned char *)(ptr + left_to_fill);
     220             :                 }
     221             :         }
     222           0 : }
     223             : 
     224             : void
     225           0 : sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
     226             : {
     227             :         /*
     228             :          * if any left in block fill with padding and process. Then transfer
     229             :          * the digest to the pointer. At the last block some special rules
     230             :          * need to apply. We must add a 1 bit following the message, then we
     231             :          * pad with 0's. The total size is encoded as a 64 bit number at the
     232             :          * end. Now if the last buffer has more than 55 octets in it we
     233             :          * cannot fit the 64 bit number + 10000000 pad on the end and must
     234             :          * add the 10000000 pad, pad the rest of the message with 0's and
     235             :          * then create an all 0 message with just the 64 bit size at the end
     236             :          * and run this block through by itself.  Also the 64 bit int must
     237             :          * be in network byte order.
     238             :          */
     239             :         int left_to_fill;
     240             :         unsigned int i, *ptr;
     241             : 
     242           0 :         if (ctx->how_many_in_block > 55) {
     243             :                 /*
     244             :                  * special case, we need to process two blocks here. One for
     245             :                  * the current stuff plus possibly the pad. The other for
     246             :                  * the size.
     247             :                  */
     248           0 :                 left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block;
     249           0 :                 if (left_to_fill == 0) {
     250             :                         /* Should not really happen but I am paranoid */
     251           0 :                         sctp_sha1_process_a_block(ctx,
     252           0 :                             (unsigned int *)ctx->sha_block);
     253             :                         /* init last block, a bit different than the rest */
     254           0 :                         ctx->sha_block[0] = '\x80';
     255           0 :                         for (i = 1; i < sizeof(ctx->sha_block); i++) {
     256           0 :                                 ctx->sha_block[i] = 0x0;
     257             :                         }
     258           0 :                 } else if (left_to_fill == 1) {
     259           0 :                         ctx->sha_block[ctx->how_many_in_block] = '\x80';
     260           0 :                         sctp_sha1_process_a_block(ctx,
     261           0 :                             (unsigned int *)ctx->sha_block);
     262             :                         /* init last block */
     263           0 :                         memset(ctx->sha_block, 0, sizeof(ctx->sha_block));
     264             :                 } else {
     265           0 :                         ctx->sha_block[ctx->how_many_in_block] = '\x80';
     266           0 :                         for (i = (ctx->how_many_in_block + 1);
     267             :                             i < sizeof(ctx->sha_block);
     268           0 :                             i++) {
     269           0 :                                 ctx->sha_block[i] = 0x0;
     270             :                         }
     271           0 :                         sctp_sha1_process_a_block(ctx,
     272           0 :                             (unsigned int *)ctx->sha_block);
     273             :                         /* init last block */
     274           0 :                         memset(ctx->sha_block, 0, sizeof(ctx->sha_block));
     275             :                 }
     276             :                 /* This is in bits so multiply by 8 */
     277           0 :                 ctx->running_total *= 8;
     278           0 :                 ptr = (unsigned int *)&ctx->sha_block[60];
     279           0 :                 *ptr = htonl(ctx->running_total);
     280           0 :                 sctp_sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
     281             :         } else {
     282             :                 /*
     283             :                  * easy case, we just pad this message to size - end with 0
     284             :                  * add the magic 0x80 to the next word and then put the
     285             :                  * network byte order size in the last spot and process the
     286             :                  * block.
     287             :                  */
     288           0 :                 ctx->sha_block[ctx->how_many_in_block] = '\x80';
     289           0 :                 for (i = (ctx->how_many_in_block + 1);
     290             :                     i < sizeof(ctx->sha_block);
     291           0 :                     i++) {
     292           0 :                         ctx->sha_block[i] = 0x0;
     293             :                 }
     294             :                 /* get last int spot */
     295           0 :                 ctx->running_total *= 8;
     296           0 :                 ptr = (unsigned int *)&ctx->sha_block[60];
     297           0 :                 *ptr = htonl(ctx->running_total);
     298           0 :                 sctp_sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
     299             :         }
     300             :         /* transfer the digest back to the user */
     301           0 :         digest[3] = (ctx->H0 & 0xff);
     302           0 :         digest[2] = ((ctx->H0 >> 8) & 0xff);
     303           0 :         digest[1] = ((ctx->H0 >> 16) & 0xff);
     304           0 :         digest[0] = ((ctx->H0 >> 24) & 0xff);
     305             : 
     306           0 :         digest[7] = (ctx->H1 & 0xff);
     307           0 :         digest[6] = ((ctx->H1 >> 8) & 0xff);
     308           0 :         digest[5] = ((ctx->H1 >> 16) & 0xff);
     309           0 :         digest[4] = ((ctx->H1 >> 24) & 0xff);
     310             : 
     311           0 :         digest[11] = (ctx->H2 & 0xff);
     312           0 :         digest[10] = ((ctx->H2 >> 8) & 0xff);
     313           0 :         digest[9] = ((ctx->H2 >> 16) & 0xff);
     314           0 :         digest[8] = ((ctx->H2 >> 24) & 0xff);
     315             : 
     316           0 :         digest[15] = (ctx->H3 & 0xff);
     317           0 :         digest[14] = ((ctx->H3 >> 8) & 0xff);
     318           0 :         digest[13] = ((ctx->H3 >> 16) & 0xff);
     319           0 :         digest[12] = ((ctx->H3 >> 24) & 0xff);
     320             : 
     321           0 :         digest[19] = (ctx->H4 & 0xff);
     322           0 :         digest[18] = ((ctx->H4 >> 8) & 0xff);
     323           0 :         digest[17] = ((ctx->H4 >> 16) & 0xff);
     324           0 :         digest[16] = ((ctx->H4 >> 24) & 0xff);
     325           0 : }
     326             : 
     327             : #endif

Generated by: LCOV version 1.13