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/libkern/crypto/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 /*
    2  * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    6  * This file contains Original Code and/or Modifications of Original Code
    7  * as defined in and that are subject to the Apple Public Source License
    8  * Version 2.0 (the 'License'). You may not use this file except in
    9  * compliance with the License. The rights granted to you under the License
   10  * may not be used to create, or enable the creation or redistribution of,
   11  * unlawful or unlicensed copies of an Apple operating system, or to
   12  * circumvent, violate, or enable the circumvention or violation of, any
   13  * terms of an Apple operating system software license agreement.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   18  * The Original Code and all software distributed under the License are
   19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   23  * Please see the License for the specific language governing rights and
   24  * limitations under the License.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   28 
   29 /*
   30  * This SHA1 code is based on the basic framework from the reference
   31  * implementation for MD5.  That implementation is Copyright (C)
   32  * 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
   33  *
   34  * License to copy and use this software is granted provided that it
   35  * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   36  * Algorithm" in all material mentioning or referencing this software
   37  * or this function.
   38  *
   39  * License is also granted to make and use derivative works provided
   40  * that such works are identified as "derived from the RSA Data
   41  * Security, Inc. MD5 Message-Digest Algorithm" in all material
   42  * mentioning or referencing the derived work.
   43  *
   44  * RSA Data Security, Inc. makes no representations concerning either
   45  * the merchantability of this software or the suitability of this
   46  * software for any particular purpose. It is provided "as is"
   47  * without express or implied warranty of any kind.
   48  *
   49  * These notices must be retained in any copies of any part of this
   50  * documentation and/or software.
   51  *
   52  * Based on the FIPS 180-1: Secure Hash Algorithm (SHA-1) available at
   53  * http://www.itl.nist.gov/div897/pubs/fip180-1.htm
   54  */
   55 
   56 #include <sys/types.h>
   57 #include <sys/systm.h>
   58 #include <libkern/OSAtomic.h>
   59 #include <libkern/crypto/sha1.h>
   60 
   61 #define memset(x, y, z) bzero(x, z);
   62 #define memcpy(x, y, z) bcopy(y, x, z)
   63 
   64 /* Internal mappings to the legacy sha1_ctxt structure. */
   65 #define state   h.b32
   66 #define bcount  c.b32
   67 #define buffer  m.b8
   68 
   69 /*
   70  * The digest algorithm interprets the input message as a sequence of 32-bit
   71  * big-endian words.  We must reverse bytes in each word on x86/64 platforms,
   72  * but not on big-endian ones such as PPC.  For performance, we take advantage
   73  * of the bswap instruction on x86/64 to perform byte-reversal.  On PPC, we
   74  * could do 4-byte load if the address is 4-byte aligned which should further
   75  * improve the performance.  But for code simplicity, we punt and do 1-byte
   76  * loads instead.
   77  */
   78 #if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
   79 #define FETCH_32(p) ({                                                  \
   80         register u_int32_t l = (u_int32_t)*((const u_int32_t *)(p));    \
   81         __asm__ __volatile__("bswap %0" : "=r" (l) : "" (l));          \
   82         l;                                                              \
   83 })
   84 #else
   85 #define FETCH_32(p)                                                     \
   86         (((u_int32_t)*((const u_int8_t *)(p) + 3)) |                    \
   87         (((u_int32_t)*((const u_int8_t *)(p) + 2)) << 8) |              \
   88         (((u_int32_t)*((const u_int8_t *)(p) + 1)) << 16) |             \
   89         (((u_int32_t)*((const u_int8_t *)(p))) << 24))
   90 #endif /* __i386__ || __x86_64__ */
   91 
   92 /*
   93  * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
   94  * a multiple of 4. This is not compatible with memcpy().
   95  */
   96 static void
   97 Encode(unsigned char *output, u_int32_t *input, unsigned int len)
   98 {
   99         unsigned int i, j;
  100 
  101         for (i = 0, j = 0; j < len; i++, j += 4) {
  102                 output[j + 3] = input[i] & 0xff;
  103                 output[j + 2] = (input[i] >> 8) & 0xff;
  104                 output[j + 1] = (input[i] >> 16) & 0xff;
  105                 output[j] = (input[i] >> 24) & 0xff;
  106         }
  107 }
  108 
  109 static unsigned char PADDING[64] = { 0x80, /* zeros */ };
  110 
  111 /* Constants from FIPS 180-1 */
  112 #define K_00_19         0x5a827999UL
  113 #define K_20_39         0x6ed9eba1UL
  114 #define K_40_59         0x8f1bbcdcUL
  115 #define K_60_79         0xca62c1d6UL
  116 
  117 /* F, G, H and I are basic SHA1 functions. */
  118 #define F(b, c, d)      ((((c) ^ (d)) & (b)) ^ (d))
  119 #define G(b, c, d)      ((b) ^ (c) ^ (d))
  120 #define H(b, c, d)      (((b) & (c)) | (((b) | (c)) & (d)))
  121 
  122 /* ROTATE_LEFT rotates x left n bits. */
  123 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
  124 
  125 /* R, R1-R4 are macros used during each transformation round. */
  126 #define R(f, k, v, w, x, y, z, i) {                             \
  127         (v) = ROTATE_LEFT(w, 5) + f(x, y, z) + (v) + (i) + (k); \
  128         (x) = ROTATE_LEFT(x, 30);                               \
  129 }
  130 
  131 #define R1(v, w, x, y, z, i)    R(F, K_00_19, v, w, x, y, z, i)
  132 #define R2(v, w, x, y, z, i)    R(G, K_20_39, v, w, x, y, z, i)
  133 #define R3(v, w, x, y, z, i)    R(H, K_40_59, v, w, x, y, z, i)
  134 #define R4(v, w, x, y, z, i)    R(G, K_60_79, v, w, x, y, z, i)
  135 
  136 /* WUPDATE represents Wt variable that gets updated for steps 16-79 */
  137 #define WUPDATE(p, q, r, s) {           \
  138         (p) = ((q) ^ (r) ^ (s) ^ (p));  \
  139         (p) = ROTATE_LEFT(p, 1);        \
  140 }
  141 
  142 static void SHA1Transform(u_int32_t, u_int32_t, u_int32_t, u_int32_t,
  143     u_int32_t, const u_int8_t *, SHA1_CTX *);
  144 
  145 void _SHA1Update(SHA1_CTX *context, const void *inpp, size_t inputLen);
  146 
  147 void SHA1Final_r(SHA1_CTX *, void *);
  148 
  149 typedef kern_return_t (*InKernelPerformSHA1Func)(void *ref, const void *data, size_t dataLen, u_int32_t *inHash, u_int32_t options, u_int32_t *outHash, Boolean usePhysicalAddress); 
  150 void sha1_hardware_hook(Boolean option, InKernelPerformSHA1Func func, void *ref);
  151 static void *SHA1Ref;
  152 InKernelPerformSHA1Func performSHA1WithinKernelOnly; 
  153 #define SHA1_USE_HARDWARE_THRESHOLD 2048 //bytes 
  154 
  155 
  156 /*
  157  * SHA1 initialization. Begins a SHA1 operation, writing a new context.
  158  */
  159 void
  160 SHA1Init(SHA1_CTX *context)
  161 {
  162         context->bcount[0] = context->bcount[1] = 0;
  163         context->count = 0;
  164 
  165         /* Load magic initialization constants.  */
  166         context->state[0] = 0x67452301UL;
  167         context->state[1] = 0xefcdab89UL;
  168         context->state[2] = 0x98badcfeUL;
  169         context->state[3] = 0x10325476UL;
  170         context->state[4] = 0xc3d2e1f0UL;
  171 }
  172 
  173 /*
  174  * SHA1 block update operation. Continues a SHA1 message-digest
  175  * operation, processing another message block, and updating the
  176  * context.
  177  */
  178 void
  179 _SHA1Update(SHA1_CTX *context, const void *inpp, size_t inputLen)
  180 {
  181         u_int32_t i, index, partLen;
  182         const unsigned char *input = (const unsigned char *)inpp;
  183 
  184         if (inputLen == 0)
  185                 return;
  186 
  187         /* Compute number of bytes mod 64 */
  188         index = (context->bcount[1] >> 3) & 0x3F;
  189 
  190         /* Update number of bits */
  191         if ((context->bcount[1] += (inputLen << 3)) < (inputLen << 3))
  192                 context->bcount[0]++;
  193         context->bcount[0] += (inputLen >> 29);
  194 
  195         partLen = 64 - index;
  196 
  197         /* Transform as many times as possible. */
  198         i = 0;
  199         if (inputLen >= partLen) {
  200                 if (index != 0) {
  201                         memcpy(&context->buffer[index], input, partLen);
  202                         SHA1Transform(context->state[0], context->state[1],
  203                             context->state[2], context->state[3],
  204                             context->state[4], context->buffer, context);
  205                         i = partLen;
  206                 }
  207 
  208                 for (; i + 63 < inputLen; i += 64)
  209                         SHA1Transform(context->state[0], context->state[1],
  210                             context->state[2], context->state[3],
  211                             context->state[4], &input[i], context);
  212 
  213                 if (inputLen == i)
  214                         return;
  215 
  216                 index = 0;
  217         }
  218 
  219         /* Buffer remaining input */
  220         memcpy(&context->buffer[index], &input[i], inputLen - i);
  221 }
  222 
  223 
  224 
  225 
  226 /*
  227  * This function is called by the SHA1 hardware kext during its init. 
  228  * This will register the function to call to perform SHA1 using hardware. 
  229  */
  230 void sha1_hardware_hook(Boolean option, InKernelPerformSHA1Func func, void *ref)
  231 {
  232         if(option) {
  233                 // Establish the hook. The hardware is ready.
  234                 OSCompareAndSwapPtr((void*)NULL, (void*)ref, (void * volatile*)&SHA1Ref); 
  235 
  236                 if(!OSCompareAndSwapPtr((void *)NULL, (void *)func, (void * volatile *)&performSHA1WithinKernelOnly)) {
  237                         panic("sha1_hardware_hook: Called twice.. Should never happen\n");
  238                 }
  239         }
  240         else {
  241                 // The hardware is going away. Tear down the hook.      
  242                 performSHA1WithinKernelOnly = NULL;
  243                 SHA1Ref = NULL;
  244         }
  245 }
  246 
  247 static u_int32_t SHA1UpdateWithHardware(SHA1_CTX *context, const unsigned char *data, size_t dataLen, Boolean usePhysicalAddress)
  248 {
  249         u_int32_t *inHashBuffer = context->state;
  250         u_int32_t options = 0;
  251         int result;
  252 
  253         result = performSHA1WithinKernelOnly(SHA1Ref, data, dataLen, inHashBuffer, options, inHashBuffer, usePhysicalAddress);
  254         if(result != KERN_SUCCESS) {
  255                 //The hardware failed to hash for some reason. Fall back to software. 
  256                 return 0;
  257         }
  258 
  259         //Update the context with the total length.
  260         /* Update number of bits */
  261         if ((context->bcount[1] += (dataLen << 3)) < (dataLen << 3))
  262                 context->bcount[0]++;
  263         context->bcount[0] += (dataLen >> 29);
  264         return dataLen;
  265 }
  266 
  267 /*
  268  * This is function is only called in from the pagefault path or from page_copy().
  269  * So we assume that we can safely convert the virtual address to the physical address and use it.
  270  * Assumptions: The passed in address(inpp) is a kernel virtual address 
  271  * and a physical page has been faulted in. 
  272  * The inputLen passed in should always be less than or equal to a  page size (4096) 
  273  * and inpp should be on a page boundary. 
  274  * "performSHA1WithinKernelOnly" is initialized only when the hardware driver exists and is ready.
  275  */
  276 void SHA1UpdateUsePhysicalAddress(SHA1_CTX *context, const void *inpp, size_t inputLen)
  277 {
  278         Boolean usePhysicalAddress = TRUE;
  279         if((inputLen == PAGE_SIZE) && performSHA1WithinKernelOnly) { // If hardware exists and is ready.
  280                 if(SHA1UpdateWithHardware(context, (const unsigned char *)inpp, inputLen, usePhysicalAddress))
  281                         return;
  282                 //else for some reason the hardware failed.. 
  283                 //fall through to software and try the hash in software. 
  284         }
  285         //Use the software implementation since the hardware is absent or 
  286         // has not been initialized yet or inputLen !=  PAGE_SIZE. 
  287         _SHA1Update(context, inpp, inputLen);
  288 }
  289 
  290 /*
  291  * A wrapper around _SHA1Update() to pick between software or hardware based SHA1. 
  292  *
  293  */
  294 void SHA1Update(SHA1_CTX *context, const void *inpp, size_t inputLen)
  295 {
  296         const unsigned char *input = (const unsigned char *)inpp;
  297         Boolean usePhysicalAddress = FALSE;
  298         u_int32_t index;
  299         
  300         if((inputLen > SHA1_USE_HARDWARE_THRESHOLD) && performSHA1WithinKernelOnly) { 
  301                 index = (context->bcount[1] >> 3) & 0x3F;
  302                 if(index != 0) {  //bytes left in the context. Handle them first.
  303                         u_int32_t partLen = 64 - index;
  304                         memcpy(&context->buffer[index], input, partLen);
  305                         _SHA1Update(context, inpp, inputLen);
  306                         inputLen -= partLen; 
  307                         input += partLen; 
  308                 }
  309                 
  310                 u_int32_t lenForHardware = inputLen & (~0x3F); //multiple of 64
  311                 u_int32_t bytesHashed = 0;
  312                 bytesHashed = SHA1UpdateWithHardware(context, input, lenForHardware, usePhysicalAddress);       
  313                 
  314                 inputLen -= bytesHashed;
  315                 input += bytesHashed;
  316         }
  317 
  318         //Fall through to the software implementation.
  319         _SHA1Update(context, input, inputLen);
  320 }
  321 
  322 /*
  323  * For backwards compatibility, sha1_result symbol is mapped to this
  324  * routine since it's equivalent to SHA1Final with reversed parameters.
  325  */
  326 void
  327 SHA1Final_r(SHA1_CTX *context, void *digest)
  328 {
  329         SHA1Final(digest, context);
  330 }
  331 
  332 /*
  333  * SHA1 finalization. Ends an SHA1 message-digest operation, writing the
  334  * the message digest and zeroizing the context.
  335  */
  336 void
  337 SHA1Final(void *digest, SHA1_CTX *context)
  338 {
  339         unsigned char bits[8];
  340         u_int32_t index = (context->bcount[1] >> 3) & 0x3f;
  341 
  342         /* Save number of bits */
  343         Encode(bits, context->bcount, 8);
  344 
  345         /* Pad out to 56 mod 64. */
  346         SHA1Update(context, PADDING, ((index < 56) ? 56 : 120) - index);
  347 
  348         /* Append length (before padding) */
  349         SHA1Update(context, bits, 8);
  350 
  351         /* Store state in digest */
  352         Encode(digest, context->state, 20);
  353 
  354         /* Zeroize sensitive information. */
  355         memset(context, 0, sizeof (*context));
  356 }
  357 
  358 /*
  359  * SHA1 basic transformation. Transforms state based on block.
  360  */
  361 static void
  362 SHA1Transform(u_int32_t a, u_int32_t b, u_int32_t c, u_int32_t d,
  363     u_int32_t e, const u_int8_t block[64], SHA1_CTX *context)
  364 {
  365         /* Register (instead of array) is a win in most cases */
  366         register u_int32_t w0, w1, w2, w3, w4, w5, w6, w7;
  367         register u_int32_t w8, w9, w10, w11, w12, w13, w14, w15;
  368 
  369         w15 = FETCH_32(block + 60);
  370         w14 = FETCH_32(block + 56);
  371         w13 = FETCH_32(block + 52);
  372         w12 = FETCH_32(block + 48);
  373         w11 = FETCH_32(block + 44);
  374         w10 = FETCH_32(block + 40);
  375         w9  = FETCH_32(block + 36);
  376         w8  = FETCH_32(block + 32);
  377         w7  = FETCH_32(block + 28);
  378         w6  = FETCH_32(block + 24);
  379         w5  = FETCH_32(block + 20);
  380         w4  = FETCH_32(block + 16);
  381         w3  = FETCH_32(block + 12);
  382         w2  = FETCH_32(block +  8);
  383         w1  = FETCH_32(block +  4);
  384         w0  = FETCH_32(block +  0);
  385 
  386         /* Round 1 */
  387                                         R1(e, a, b, c, d,  w0);         /*  0 */
  388                                         R1(d, e, a, b, c,  w1);         /*  1 */
  389                                         R1(c, d, e, a, b,  w2);         /*  2 */
  390                                         R1(b, c, d, e, a,  w3);         /*  3 */
  391                                         R1(a, b, c, d, e,  w4);         /*  4 */
  392                                         R1(e, a, b, c, d,  w5);         /*  5 */
  393                                         R1(d, e, a, b, c,  w6);         /*  6 */
  394                                         R1(c, d, e, a, b,  w7);         /*  7 */
  395                                         R1(b, c, d, e, a,  w8);         /*  8 */
  396                                         R1(a, b, c, d, e,  w9);         /*  9 */
  397                                         R1(e, a, b, c, d, w10);         /* 10 */
  398                                         R1(d, e, a, b, c, w11);         /* 11 */
  399                                         R1(c, d, e, a, b, w12);         /* 12 */
  400                                         R1(b, c, d, e, a, w13);         /* 13 */
  401                                         R1(a, b, c, d, e, w14);         /* 14 */
  402                                         R1(e, a, b, c, d, w15);         /* 15 */
  403         WUPDATE( w0, w13,  w8,  w2);    R1(d, e, a, b, c,  w0);         /* 16 */
  404         WUPDATE( w1, w14,  w9,  w3);    R1(c, d, e, a, b,  w1);         /* 17 */
  405         WUPDATE( w2, w15, w10,  w4);    R1(b, c, d, e, a,  w2);         /* 18 */
  406         WUPDATE( w3,  w0, w11,  w5);    R1(a, b, c, d, e,  w3);         /* 19 */
  407 
  408         /* Round 2 */
  409         WUPDATE( w4,  w1, w12,  w6);    R2(e, a, b, c, d,  w4);         /* 20 */
  410         WUPDATE( w5,  w2, w13,  w7);    R2(d, e, a, b, c,  w5);         /* 21 */
  411         WUPDATE( w6,  w3, w14,  w8);    R2(c, d, e, a, b,  w6);         /* 22 */
  412         WUPDATE( w7,  w4, w15,  w9);    R2(b, c, d, e, a,  w7);         /* 23 */
  413         WUPDATE( w8,  w5,  w0, w10);    R2(a, b, c, d, e,  w8);         /* 24 */
  414         WUPDATE( w9,  w6,  w1, w11);    R2(e, a, b, c, d,  w9);         /* 25 */
  415         WUPDATE(w10,  w7,  w2, w12);    R2(d, e, a, b, c, w10);         /* 26 */
  416         WUPDATE(w11,  w8,  w3, w13);    R2(c, d, e, a, b, w11);         /* 27 */
  417         WUPDATE(w12,  w9,  w4, w14);    R2(b, c, d, e, a, w12);         /* 28 */
  418         WUPDATE(w13, w10,  w5, w15);    R2(a, b, c, d, e, w13);         /* 29 */
  419         WUPDATE(w14, w11,  w6,  w0);    R2(e, a, b, c, d, w14);         /* 30 */
  420         WUPDATE(w15, w12,  w7,  w1);    R2(d, e, a, b, c, w15);         /* 31 */
  421         WUPDATE( w0, w13,  w8,  w2);    R2(c, d, e, a, b,  w0);         /* 32 */
  422         WUPDATE( w1, w14,  w9,  w3);    R2(b, c, d, e, a,  w1);         /* 33 */
  423         WUPDATE( w2, w15, w10,  w4);    R2(a, b, c, d, e,  w2);         /* 34 */
  424         WUPDATE( w3,  w0, w11,  w5);    R2(e, a, b, c, d,  w3);         /* 35 */
  425         WUPDATE( w4,  w1, w12,  w6);    R2(d, e, a, b, c,  w4);         /* 36 */
  426         WUPDATE( w5,  w2, w13,  w7);    R2(c, d, e, a, b,  w5);         /* 37 */
  427         WUPDATE( w6,  w3, w14,  w8);    R2(b, c, d, e, a,  w6);         /* 38 */
  428         WUPDATE( w7,  w4, w15,  w9);    R2(a, b, c, d, e,  w7);         /* 39 */
  429 
  430         /* Round 3 */
  431         WUPDATE( w8,  w5,  w0, w10);    R3(e, a, b, c, d,  w8);         /* 40 */
  432         WUPDATE( w9,  w6,  w1, w11);    R3(d, e, a, b, c,  w9);         /* 41 */
  433         WUPDATE(w10,  w7,  w2, w12);    R3(c, d, e, a, b, w10);         /* 42 */
  434         WUPDATE(w11,  w8,  w3, w13);    R3(b, c, d, e, a, w11);         /* 43 */
  435         WUPDATE(w12,  w9,  w4, w14);    R3(a, b, c, d, e, w12);         /* 44 */
  436         WUPDATE(w13, w10,  w5, w15);    R3(e, a, b, c, d, w13);         /* 45 */
  437         WUPDATE(w14, w11,  w6,  w0);    R3(d, e, a, b, c, w14);         /* 46 */
  438         WUPDATE(w15, w12,  w7,  w1);    R3(c, d, e, a, b, w15);         /* 47 */
  439         WUPDATE( w0, w13,  w8,  w2);    R3(b, c, d, e, a,  w0);         /* 48 */
  440         WUPDATE( w1, w14,  w9,  w3);    R3(a, b, c, d, e,  w1);         /* 49 */
  441         WUPDATE( w2, w15, w10,  w4);    R3(e, a, b, c, d,  w2);         /* 50 */
  442         WUPDATE( w3,  w0, w11,  w5);    R3(d, e, a, b, c,  w3);         /* 51 */
  443         WUPDATE( w4,  w1, w12,  w6);    R3(c, d, e, a, b,  w4);         /* 52 */
  444         WUPDATE( w5,  w2, w13,  w7);    R3(b, c, d, e, a,  w5);         /* 53 */
  445         WUPDATE( w6,  w3, w14,  w8);    R3(a, b, c, d, e,  w6);         /* 54 */
  446         WUPDATE( w7,  w4, w15,  w9);    R3(e, a, b, c, d,  w7);         /* 55 */
  447         WUPDATE( w8,  w5,  w0, w10);    R3(d, e, a, b, c,  w8);         /* 56 */
  448         WUPDATE( w9,  w6,  w1, w11);    R3(c, d, e, a, b,  w9);         /* 57 */
  449         WUPDATE(w10,  w7,  w2, w12);    R3(b, c, d, e, a, w10);         /* 58 */
  450         WUPDATE(w11,  w8,  w3, w13);    R3(a, b, c, d, e, w11);         /* 59 */
  451 
  452         WUPDATE(w12,  w9,  w4, w14);    R4(e, a, b, c, d, w12);         /* 60 */
  453         WUPDATE(w13, w10,  w5, w15);    R4(d, e, a, b, c, w13);         /* 61 */
  454         WUPDATE(w14, w11,  w6,  w0);    R4(c, d, e, a, b, w14);         /* 62 */
  455         WUPDATE(w15, w12,  w7,  w1);    R4(b, c, d, e, a, w15);         /* 63 */
  456         WUPDATE( w0, w13,  w8,  w2);    R4(a, b, c, d, e,  w0);         /* 64 */
  457         WUPDATE( w1, w14,  w9,  w3);    R4(e, a, b, c, d,  w1);         /* 65 */
  458         WUPDATE( w2, w15, w10,  w4);    R4(d, e, a, b, c,  w2);         /* 66 */
  459         WUPDATE( w3,  w0, w11,  w5);    R4(c, d, e, a, b,  w3);         /* 67 */
  460         WUPDATE( w4,  w1, w12,  w6);    R4(b, c, d, e, a,  w4);         /* 68 */
  461         WUPDATE( w5,  w2, w13,  w7);    R4(a, b, c, d, e,  w5);         /* 69 */
  462         WUPDATE( w6,  w3, w14,  w8);    R4(e, a, b, c, d,  w6);         /* 70 */
  463         WUPDATE( w7,  w4, w15,  w9);    R4(d, e, a, b, c,  w7);         /* 71 */
  464         WUPDATE( w8,  w5,  w0, w10);    R4(c, d, e, a, b,  w8);         /* 72 */
  465         WUPDATE( w9,  w6,  w1, w11);    R4(b, c, d, e, a,  w9);         /* 73 */
  466         WUPDATE(w10,  w7,  w2, w12);    R4(a, b, c, d, e, w10);         /* 74 */
  467         WUPDATE(w11,  w8,  w3, w13);    R4(e, a, b, c, d, w11);         /* 75 */
  468         WUPDATE(w12,  w9,  w4, w14);    R4(d, e, a, b, c, w12);         /* 76 */
  469         WUPDATE(w13, w10,  w5, w15);    R4(c, d, e, a, b, w13);         /* 77 */
  470         WUPDATE(w14, w11,  w6,  w0);    R4(b, c, d, e, a, w14);         /* 78 */
  471         WUPDATE(w15, w12,  w7,  w1);    R4(a, b, c, d, e, w15);         /* 79 */
  472 
  473         context->state[0] += a;
  474         context->state[1] += b;
  475         context->state[2] += c;
  476         context->state[3] += d;
  477         context->state[4] += e;
  478 
  479         /* Zeroize sensitive information. */
  480         w15 = w14 = w13 = w12 = w11 = w10 = w9 = w8 = 0;
  481         w7 = w6 = w5 = w4 = w3 = w2 = w1 = w0 = 0;
  482 }

Cache object: 104644cd9e911f50e92b9e9734481544


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