sha1.c
author Kristian H?gsberg <krh@redhat.com>
Sat Sep 29 23:30:35 2007 -0400 (2007-09-29)
changeset 42 aedfc8f95227
permissions -rw-r--r--
Get version flags for requires in rpmdb importer.
     1 /*
     2  * The contents of this file are subject to the Mozilla Public
     3  * License Version 1.1 (the "License"); you may not use this file
     4  * except in compliance with the License. You may obtain a copy of
     5  * the License at http://www.mozilla.org/MPL/
     6  *
     7  * Software distributed under the License is distributed on an "AS
     8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
     9  * implied. See the License for the specific language governing
    10  * rights and limitations under the License.
    11  *
    12  * The Original Code is SHA 180-1 Reference Implementation (Compact version)
    13  *
    14  * The Initial Developer of the Original Code is Paul Kocher of
    15  * Cryptography Research.  Portions created by Paul Kocher are
    16  * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
    17  * Rights Reserved.
    18  *
    19  * Contributor(s):
    20  *
    21  *     Paul Kocher
    22  *
    23  * Alternatively, the contents of this file may be used under the
    24  * terms of the GNU General Public License Version 2 or later (the
    25  * "GPL"), in which case the provisions of the GPL are applicable
    26  * instead of those above.  If you wish to allow use of your
    27  * version of this file only under the terms of the GPL and not to
    28  * allow others to use your version of this file under the MPL,
    29  * indicate your decision by deleting the provisions above and
    30  * replace them with the notice and other provisions required by
    31  * the GPL.  If you do not delete the provisions above, a recipient
    32  * may use your version of this file under either the MPL or the
    33  * GPL.
    34  */
    35 
    36 #include "sha1.h"
    37 
    38 static void shaHashBlock(SHA_CTX *ctx);
    39 
    40 void SHA1_Init(SHA_CTX *ctx) {
    41   int i;
    42 
    43   ctx->lenW = 0;
    44   ctx->sizeHi = ctx->sizeLo = 0;
    45 
    46   /* Initialize H with the magic constants (see FIPS180 for constants)
    47    */
    48   ctx->H[0] = 0x67452301;
    49   ctx->H[1] = 0xefcdab89;
    50   ctx->H[2] = 0x98badcfe;
    51   ctx->H[3] = 0x10325476;
    52   ctx->H[4] = 0xc3d2e1f0;
    53 
    54   for (i = 0; i < 80; i++)
    55     ctx->W[i] = 0;
    56 }
    57 
    58 
    59 void SHA1_Update(SHA_CTX *ctx, const void *_dataIn, int len) {
    60   const unsigned char *dataIn = _dataIn;
    61   int i;
    62 
    63   /* Read the data into W and process blocks as they get full
    64    */
    65   for (i = 0; i < len; i++) {
    66     ctx->W[ctx->lenW / 4] <<= 8;
    67     ctx->W[ctx->lenW / 4] |= (unsigned int)dataIn[i];
    68     if ((++ctx->lenW) % 64 == 0) {
    69       shaHashBlock(ctx);
    70       ctx->lenW = 0;
    71     }
    72     ctx->sizeLo += 8;
    73     ctx->sizeHi += (ctx->sizeLo < 8);
    74   }
    75 }
    76 
    77 
    78 void SHA1_Final(unsigned char hashout[20], SHA_CTX *ctx) {
    79   unsigned char pad0x80 = 0x80;
    80   unsigned char pad0x00 = 0x00;
    81   unsigned char padlen[8];
    82   int i;
    83 
    84   /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
    85    */
    86   padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
    87   padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
    88   padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
    89   padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
    90   padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
    91   padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
    92   padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
    93   padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
    94   SHA1_Update(ctx, &pad0x80, 1);
    95   while (ctx->lenW != 56)
    96     SHA1_Update(ctx, &pad0x00, 1);
    97   SHA1_Update(ctx, padlen, 8);
    98 
    99   /* Output hash
   100    */
   101   for (i = 0; i < 20; i++) {
   102     hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
   103     ctx->H[i / 4] <<= 8;
   104   }
   105 
   106   /*
   107    *  Re-initialize the context (also zeroizes contents)
   108    */
   109   SHA1_Init(ctx);
   110 }
   111 
   112 
   113 #define SHA_ROT(X,n) (((X) << (n)) | ((X) >> (32-(n))))
   114 
   115 static void shaHashBlock(SHA_CTX *ctx) {
   116   int t;
   117   unsigned int A,B,C,D,E,TEMP;
   118 
   119   for (t = 16; t <= 79; t++)
   120     ctx->W[t] =
   121       SHA_ROT(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
   122 
   123   A = ctx->H[0];
   124   B = ctx->H[1];
   125   C = ctx->H[2];
   126   D = ctx->H[3];
   127   E = ctx->H[4];
   128 
   129   for (t = 0; t <= 19; t++) {
   130     TEMP = SHA_ROT(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999;
   131     E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   132   }
   133   for (t = 20; t <= 39; t++) {
   134     TEMP = SHA_ROT(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1;
   135     E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   136   }
   137   for (t = 40; t <= 59; t++) {
   138     TEMP = SHA_ROT(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdc;
   139     E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   140   }
   141   for (t = 60; t <= 79; t++) {
   142     TEMP = SHA_ROT(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6;
   143     E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   144   }
   145 
   146   ctx->H[0] += A;
   147   ctx->H[1] += B;
   148   ctx->H[2] += C;
   149   ctx->H[3] += D;
   150   ctx->H[4] += E;
   151 }