1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/sha1.c Wed Sep 19 15:28:19 2007 -0400
1.3 @@ -0,0 +1,151 @@
1.4 +/*
1.5 + * The contents of this file are subject to the Mozilla Public
1.6 + * License Version 1.1 (the "License"); you may not use this file
1.7 + * except in compliance with the License. You may obtain a copy of
1.8 + * the License at http://www.mozilla.org/MPL/
1.9 + *
1.10 + * Software distributed under the License is distributed on an "AS
1.11 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
1.12 + * implied. See the License for the specific language governing
1.13 + * rights and limitations under the License.
1.14 + *
1.15 + * The Original Code is SHA 180-1 Reference Implementation (Compact version)
1.16 + *
1.17 + * The Initial Developer of the Original Code is Paul Kocher of
1.18 + * Cryptography Research. Portions created by Paul Kocher are
1.19 + * Copyright (C) 1995-9 by Cryptography Research, Inc. All
1.20 + * Rights Reserved.
1.21 + *
1.22 + * Contributor(s):
1.23 + *
1.24 + * Paul Kocher
1.25 + *
1.26 + * Alternatively, the contents of this file may be used under the
1.27 + * terms of the GNU General Public License Version 2 or later (the
1.28 + * "GPL"), in which case the provisions of the GPL are applicable
1.29 + * instead of those above. If you wish to allow use of your
1.30 + * version of this file only under the terms of the GPL and not to
1.31 + * allow others to use your version of this file under the MPL,
1.32 + * indicate your decision by deleting the provisions above and
1.33 + * replace them with the notice and other provisions required by
1.34 + * the GPL. If you do not delete the provisions above, a recipient
1.35 + * may use your version of this file under either the MPL or the
1.36 + * GPL.
1.37 + */
1.38 +
1.39 +#include "sha1.h"
1.40 +
1.41 +static void shaHashBlock(SHA_CTX *ctx);
1.42 +
1.43 +void SHA1_Init(SHA_CTX *ctx) {
1.44 + int i;
1.45 +
1.46 + ctx->lenW = 0;
1.47 + ctx->sizeHi = ctx->sizeLo = 0;
1.48 +
1.49 + /* Initialize H with the magic constants (see FIPS180 for constants)
1.50 + */
1.51 + ctx->H[0] = 0x67452301;
1.52 + ctx->H[1] = 0xefcdab89;
1.53 + ctx->H[2] = 0x98badcfe;
1.54 + ctx->H[3] = 0x10325476;
1.55 + ctx->H[4] = 0xc3d2e1f0;
1.56 +
1.57 + for (i = 0; i < 80; i++)
1.58 + ctx->W[i] = 0;
1.59 +}
1.60 +
1.61 +
1.62 +void SHA1_Update(SHA_CTX *ctx, const void *_dataIn, int len) {
1.63 + const unsigned char *dataIn = _dataIn;
1.64 + int i;
1.65 +
1.66 + /* Read the data into W and process blocks as they get full
1.67 + */
1.68 + for (i = 0; i < len; i++) {
1.69 + ctx->W[ctx->lenW / 4] <<= 8;
1.70 + ctx->W[ctx->lenW / 4] |= (unsigned int)dataIn[i];
1.71 + if ((++ctx->lenW) % 64 == 0) {
1.72 + shaHashBlock(ctx);
1.73 + ctx->lenW = 0;
1.74 + }
1.75 + ctx->sizeLo += 8;
1.76 + ctx->sizeHi += (ctx->sizeLo < 8);
1.77 + }
1.78 +}
1.79 +
1.80 +
1.81 +void SHA1_Final(unsigned char hashout[20], SHA_CTX *ctx) {
1.82 + unsigned char pad0x80 = 0x80;
1.83 + unsigned char pad0x00 = 0x00;
1.84 + unsigned char padlen[8];
1.85 + int i;
1.86 +
1.87 + /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
1.88 + */
1.89 + padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
1.90 + padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
1.91 + padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
1.92 + padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
1.93 + padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
1.94 + padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
1.95 + padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
1.96 + padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
1.97 + SHA1_Update(ctx, &pad0x80, 1);
1.98 + while (ctx->lenW != 56)
1.99 + SHA1_Update(ctx, &pad0x00, 1);
1.100 + SHA1_Update(ctx, padlen, 8);
1.101 +
1.102 + /* Output hash
1.103 + */
1.104 + for (i = 0; i < 20; i++) {
1.105 + hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
1.106 + ctx->H[i / 4] <<= 8;
1.107 + }
1.108 +
1.109 + /*
1.110 + * Re-initialize the context (also zeroizes contents)
1.111 + */
1.112 + SHA1_Init(ctx);
1.113 +}
1.114 +
1.115 +
1.116 +#define SHA_ROT(X,n) (((X) << (n)) | ((X) >> (32-(n))))
1.117 +
1.118 +static void shaHashBlock(SHA_CTX *ctx) {
1.119 + int t;
1.120 + unsigned int A,B,C,D,E,TEMP;
1.121 +
1.122 + for (t = 16; t <= 79; t++)
1.123 + ctx->W[t] =
1.124 + SHA_ROT(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
1.125 +
1.126 + A = ctx->H[0];
1.127 + B = ctx->H[1];
1.128 + C = ctx->H[2];
1.129 + D = ctx->H[3];
1.130 + E = ctx->H[4];
1.131 +
1.132 + for (t = 0; t <= 19; t++) {
1.133 + TEMP = SHA_ROT(A,5) + (((C^D)&B)^D) + E + ctx->W[t] + 0x5a827999;
1.134 + E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
1.135 + }
1.136 + for (t = 20; t <= 39; t++) {
1.137 + TEMP = SHA_ROT(A,5) + (B^C^D) + E + ctx->W[t] + 0x6ed9eba1;
1.138 + E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
1.139 + }
1.140 + for (t = 40; t <= 59; t++) {
1.141 + TEMP = SHA_ROT(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdc;
1.142 + E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
1.143 + }
1.144 + for (t = 60; t <= 79; t++) {
1.145 + TEMP = SHA_ROT(A,5) + (B^C^D) + E + ctx->W[t] + 0xca62c1d6;
1.146 + E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
1.147 + }
1.148 +
1.149 + ctx->H[0] += A;
1.150 + ctx->H[1] += B;
1.151 + ctx->H[2] += C;
1.152 + ctx->H[3] += D;
1.153 + ctx->H[4] += E;
1.154 +}