• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2008 Google Inc. All Rights Reserved.
2 // Author: mschilder@google.com (Marius Schilder)
3 //
4 // Optimized for minimal code size.
5 
6 #include "sha.h"
7 
8 #define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
9 
SHA1_Transform(SHA_CTX * ctx)10 static void SHA1_Transform(SHA_CTX* ctx) {
11   uint32_t W[80];
12   uint32_t A, B, C, D, E;
13   uint8_t* p = ctx->buf.b;
14   int t;
15 
16   for(t = 0; t < 16; ++t) {
17     uint32_t tmp =  *p++ << 24;
18     tmp |= *p++ << 16;
19     tmp |= *p++ << 8;
20     tmp |= *p++;
21     W[t] = tmp;
22   }
23 
24   for(; t < 80; t++) {
25     W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
26   }
27 
28   A = ctx->state[0];
29   B = ctx->state[1];
30   C = ctx->state[2];
31   D = ctx->state[3];
32   E = ctx->state[4];
33 
34   for(t = 0; t < 80; t++) {
35     uint32_t tmp = rol(5,A) + E + W[t];
36 
37     if (t < 20)
38       tmp += (D^(B&(C^D))) + 0x5A827999;
39     else if ( t < 40)
40       tmp += (B^C^D) + 0x6ED9EBA1;
41     else if ( t < 60)
42       tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
43     else
44       tmp += (B^C^D) + 0xCA62C1D6;
45 
46     E = D;
47     D = C;
48     C = rol(30,B);
49     B = A;
50     A = tmp;
51   }
52 
53   ctx->state[0] += A;
54   ctx->state[1] += B;
55   ctx->state[2] += C;
56   ctx->state[3] += D;
57   ctx->state[4] += E;
58 }
59 
SHA_init(SHA_CTX * ctx)60 void SHA_init(SHA_CTX* ctx) {
61   ctx->state[0] = 0x67452301;
62   ctx->state[1] = 0xEFCDAB89;
63   ctx->state[2] = 0x98BADCFE;
64   ctx->state[3] = 0x10325476;
65   ctx->state[4] = 0xC3D2E1F0;
66   ctx->count = 0;
67 }
68 
69 
SHA_update(SHA_CTX * ctx,const void * data,int len)70 void SHA_update(SHA_CTX* ctx, const void* data, int len) {
71   int i = ctx->count % sizeof(ctx->buf);
72   const uint8_t* p = (const uint8_t*)data;
73 
74   ctx->count += len;
75 
76   while (len--) {
77     ctx->buf.b[i++] = *p++;
78     if (i == sizeof(ctx->buf)) {
79       SHA1_Transform(ctx);
80       i = 0;
81     }
82   }
83 }
84 
85 
SHA_final(SHA_CTX * ctx)86 const uint8_t* SHA_final(SHA_CTX* ctx) {
87   uint8_t *p = ctx->buf.b;
88   uint64_t cnt = ctx->count * 8;
89   int i;
90 
91   SHA_update(ctx, (uint8_t*)"\x80", 1);
92   while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
93     SHA_update(ctx, (uint8_t*)"\0", 1);
94   }
95   for (i = 0; i < 8; ++i) {
96     uint8_t tmp = cnt >> ((7 - i) * 8);
97     SHA_update(ctx, &tmp, 1);
98   }
99 
100   for (i = 0; i < 5; i++) {
101     uint32_t tmp = ctx->state[i];
102     *p++ = tmp >> 24;
103     *p++ = tmp >> 16;
104     *p++ = tmp >> 8;
105     *p++ = tmp >> 0;
106   }
107 
108   return ctx->buf.b;
109 }
110 
111 /* Convenience function */
SHA(const void * data,int len,uint8_t * digest)112 const uint8_t* SHA(const void* data, int len, uint8_t* digest) {
113   const uint8_t* p;
114   int i;
115   SHA_CTX ctx;
116   SHA_init(&ctx);
117   SHA_update(&ctx, data, len);
118   p = SHA_final(&ctx);
119   for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
120     digest[i] = *p++;
121   }
122   return digest;
123 }
124