1/* sha.c
2**
3** Copyright 2008, The Android Open Source Project
4**
5** Redistribution and use in source and binary forms, with or without
6** modification, are permitted provided that the following conditions are met:
7**     * Redistributions of source code must retain the above copyright
8**       notice, this list of conditions and the following disclaimer.
9**     * Redistributions in binary form must reproduce the above copyright
10**       notice, this list of conditions and the following disclaimer in the
11**       documentation and/or other materials provided with the distribution.
12**     * Neither the name of Google Inc. nor the names of its contributors may
13**       be used to endorse or promote products derived from this software
14**       without specific prior written permission.
15**
16** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
17** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#include "mincrypt/sha.h"
29
30// Some machines lack byteswap.h and endian.h.  These have to use the
31// slower code, even if they're little-endian.
32
33#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
34
35#include <byteswap.h>
36#include <memory.h>
37
38// This version is about 28% faster than the generic version below,
39// but assumes little-endianness.
40
41static inline uint32_t ror27(uint32_t val) {
42    return (val >> 27) | (val << 5);
43}
44static inline uint32_t ror2(uint32_t val) {
45    return (val >> 2) | (val << 30);
46}
47static inline uint32_t ror31(uint32_t val) {
48    return (val >> 31) | (val << 1);
49}
50
51static void SHA1_Transform(SHA_CTX* ctx) {
52    uint32_t W[80];
53    register uint32_t A, B, C, D, E;
54    int t;
55
56    A = ctx->state[0];
57    B = ctx->state[1];
58    C = ctx->state[2];
59    D = ctx->state[3];
60    E = ctx->state[4];
61
62#define SHA_F1(A,B,C,D,E,t)                     \
63    E += ror27(A) +                             \
64        (W[t] = bswap_32(ctx->buf.w[t])) +      \
65        (D^(B&(C^D))) + 0x5A827999;             \
66    B = ror2(B);
67
68    for (t = 0; t < 15; t += 5) {
69        SHA_F1(A,B,C,D,E,t + 0);
70        SHA_F1(E,A,B,C,D,t + 1);
71        SHA_F1(D,E,A,B,C,t + 2);
72        SHA_F1(C,D,E,A,B,t + 3);
73        SHA_F1(B,C,D,E,A,t + 4);
74    }
75    SHA_F1(A,B,C,D,E,t + 0);  // 16th one, t == 15
76
77#undef SHA_F1
78
79#define SHA_F1(A,B,C,D,E,t)                                     \
80    E += ror27(A) +                                             \
81        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
82        (D^(B&(C^D))) + 0x5A827999;                             \
83    B = ror2(B);
84
85    SHA_F1(E,A,B,C,D,t + 1);
86    SHA_F1(D,E,A,B,C,t + 2);
87    SHA_F1(C,D,E,A,B,t + 3);
88    SHA_F1(B,C,D,E,A,t + 4);
89
90#undef SHA_F1
91
92#define SHA_F2(A,B,C,D,E,t)                                     \
93    E += ror27(A) +                                             \
94        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
95        (B^C^D) + 0x6ED9EBA1;                                   \
96    B = ror2(B);
97
98    for (t = 20; t < 40; t += 5) {
99        SHA_F2(A,B,C,D,E,t + 0);
100        SHA_F2(E,A,B,C,D,t + 1);
101        SHA_F2(D,E,A,B,C,t + 2);
102        SHA_F2(C,D,E,A,B,t + 3);
103        SHA_F2(B,C,D,E,A,t + 4);
104    }
105
106#undef SHA_F2
107
108#define SHA_F3(A,B,C,D,E,t)                                     \
109    E += ror27(A) +                                             \
110        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
111        ((B&C)|(D&(B|C))) + 0x8F1BBCDC;                         \
112    B = ror2(B);
113
114    for (; t < 60; t += 5) {
115        SHA_F3(A,B,C,D,E,t + 0);
116        SHA_F3(E,A,B,C,D,t + 1);
117        SHA_F3(D,E,A,B,C,t + 2);
118        SHA_F3(C,D,E,A,B,t + 3);
119        SHA_F3(B,C,D,E,A,t + 4);
120    }
121
122#undef SHA_F3
123
124#define SHA_F4(A,B,C,D,E,t)                                     \
125    E += ror27(A) +                                             \
126        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
127        (B^C^D) + 0xCA62C1D6;                                   \
128    B = ror2(B);
129
130    for (; t < 80; t += 5) {
131        SHA_F4(A,B,C,D,E,t + 0);
132        SHA_F4(E,A,B,C,D,t + 1);
133        SHA_F4(D,E,A,B,C,t + 2);
134        SHA_F4(C,D,E,A,B,t + 3);
135        SHA_F4(B,C,D,E,A,t + 4);
136    }
137
138#undef SHA_F4
139
140    ctx->state[0] += A;
141    ctx->state[1] += B;
142    ctx->state[2] += C;
143    ctx->state[3] += D;
144    ctx->state[4] += E;
145}
146
147void SHA_update(SHA_CTX* ctx, const void* data, int len) {
148    int i = ctx->count % sizeof(ctx->buf);
149    const uint8_t* p = (const uint8_t*)data;
150
151    ctx->count += len;
152
153    while (len > sizeof(ctx->buf) - i) {
154        memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
155        len -= sizeof(ctx->buf) - i;
156        p += sizeof(ctx->buf) - i;
157        SHA1_Transform(ctx);
158        i = 0;
159    }
160
161    while (len--) {
162        ctx->buf.b[i++] = *p++;
163        if (i == sizeof(ctx->buf)) {
164            SHA1_Transform(ctx);
165            i = 0;
166        }
167    }
168}
169
170
171const uint8_t* SHA_final(SHA_CTX* ctx) {
172    uint64_t cnt = ctx->count * 8;
173    int i;
174
175    SHA_update(ctx, (uint8_t*)"\x80", 1);
176    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
177        SHA_update(ctx, (uint8_t*)"\0", 1);
178    }
179    for (i = 0; i < 8; ++i) {
180        uint8_t tmp = cnt >> ((7 - i) * 8);
181        SHA_update(ctx, &tmp, 1);
182    }
183
184    for (i = 0; i < 5; i++) {
185        ctx->buf.w[i] = bswap_32(ctx->state[i]);
186    }
187
188    return ctx->buf.b;
189}
190
191#else   // #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
192
193#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
194
195static void SHA1_transform(SHA_CTX *ctx) {
196    uint32_t W[80];
197    uint32_t A, B, C, D, E;
198    uint8_t *p = ctx->buf;
199    int t;
200
201    for(t = 0; t < 16; ++t) {
202        uint32_t tmp =  *p++ << 24;
203        tmp |= *p++ << 16;
204        tmp |= *p++ << 8;
205        tmp |= *p++;
206        W[t] = tmp;
207    }
208
209    for(; t < 80; t++) {
210        W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
211    }
212
213    A = ctx->state[0];
214    B = ctx->state[1];
215    C = ctx->state[2];
216    D = ctx->state[3];
217    E = ctx->state[4];
218
219    for(t = 0; t < 80; t++) {
220        uint32_t tmp = rol(5,A) + E + W[t];
221
222        if (t < 20)
223            tmp += (D^(B&(C^D))) + 0x5A827999;
224        else if ( t < 40)
225            tmp += (B^C^D) + 0x6ED9EBA1;
226        else if ( t < 60)
227            tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
228        else
229            tmp += (B^C^D) + 0xCA62C1D6;
230
231        E = D;
232        D = C;
233        C = rol(30,B);
234        B = A;
235        A = tmp;
236    }
237
238    ctx->state[0] += A;
239    ctx->state[1] += B;
240    ctx->state[2] += C;
241    ctx->state[3] += D;
242    ctx->state[4] += E;
243}
244
245void SHA_update(SHA_CTX *ctx, const void *data, int len) {
246    int i = ctx->count % sizeof(ctx->buf);
247    const uint8_t* p = (const uint8_t*)data;
248
249    ctx->count += len;
250
251    while (len--) {
252        ctx->buf[i++] = *p++;
253        if (i == sizeof(ctx->buf)) {
254            SHA1_transform(ctx);
255            i = 0;
256        }
257    }
258}
259const uint8_t *SHA_final(SHA_CTX *ctx) {
260    uint8_t *p = ctx->buf;
261    uint64_t cnt = ctx->count * 8;
262    int i;
263
264    SHA_update(ctx, (uint8_t*)"\x80", 1);
265    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
266        SHA_update(ctx, (uint8_t*)"\0", 1);
267    }
268    for (i = 0; i < 8; ++i) {
269        uint8_t tmp = cnt >> ((7 - i) * 8);
270        SHA_update(ctx, &tmp, 1);
271    }
272
273    for (i = 0; i < 5; i++) {
274        uint32_t tmp = ctx->state[i];
275        *p++ = tmp >> 24;
276        *p++ = tmp >> 16;
277        *p++ = tmp >> 8;
278        *p++ = tmp >> 0;
279    }
280
281    return ctx->buf;
282}
283
284#endif // endianness
285
286void SHA_init(SHA_CTX* ctx) {
287    ctx->state[0] = 0x67452301;
288    ctx->state[1] = 0xEFCDAB89;
289    ctx->state[2] = 0x98BADCFE;
290    ctx->state[3] = 0x10325476;
291    ctx->state[4] = 0xC3D2E1F0;
292    ctx->count = 0;
293}
294
295/* Convenience function */
296const uint8_t* SHA(const void *data, int len, uint8_t *digest) {
297    const uint8_t *p;
298    int i;
299    SHA_CTX ctx;
300    SHA_init(&ctx);
301    SHA_update(&ctx, data, len);
302    p = SHA_final(&ctx);
303    for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
304        digest[i] = *p++;
305    }
306    return digest;
307}
308