sha.c revision a6de77de1727d5c40fdfdf841f3e8d13e0fc0140
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 <byteswap.h>
29#include <endian.h>
30#include <memory.h>
31
32#include "mincrypt/sha.h"
33
34#if __BYTE_ORDER == __LITTLE_ENDIAN
35
36// This version is about 28% faster than the generic version below,
37// but assumes little-endianness.
38
39static inline uint32_t ror27(uint32_t val) {
40    return (val >> 27) | (val << 5);
41}
42static inline uint32_t ror2(uint32_t val) {
43    return (val >> 2) | (val << 30);
44}
45static inline uint32_t ror31(uint32_t val) {
46    return (val >> 31) | (val << 1);
47}
48
49static void SHA1_Transform(SHA_CTX* ctx) {
50    uint32_t W[80];
51    register uint32_t A, B, C, D, E;
52    int t;
53
54    A = ctx->state[0];
55    B = ctx->state[1];
56    C = ctx->state[2];
57    D = ctx->state[3];
58    E = ctx->state[4];
59
60#define SHA_F1(A,B,C,D,E,t)                     \
61    E += ror27(A) +                             \
62        (W[t] = bswap_32(ctx->buf.w[t])) +      \
63        (D^(B&(C^D))) + 0x5A827999;             \
64    B = ror2(B);
65
66    for (t = 0; t < 15; t += 5) {
67        SHA_F1(A,B,C,D,E,t + 0);
68        SHA_F1(E,A,B,C,D,t + 1);
69        SHA_F1(D,E,A,B,C,t + 2);
70        SHA_F1(C,D,E,A,B,t + 3);
71        SHA_F1(B,C,D,E,A,t + 4);
72    }
73    SHA_F1(A,B,C,D,E,t + 0);  // 16th one, t == 15
74
75#undef SHA_F1
76
77#define SHA_F1(A,B,C,D,E,t)                                     \
78    E += ror27(A) +                                             \
79        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
80        (D^(B&(C^D))) + 0x5A827999;                             \
81    B = ror2(B);
82
83    SHA_F1(E,A,B,C,D,t + 1);
84    SHA_F1(D,E,A,B,C,t + 2);
85    SHA_F1(C,D,E,A,B,t + 3);
86    SHA_F1(B,C,D,E,A,t + 4);
87
88#undef SHA_F1
89
90#define SHA_F2(A,B,C,D,E,t)                                     \
91    E += ror27(A) +                                             \
92        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
93        (B^C^D) + 0x6ED9EBA1;                                   \
94    B = ror2(B);
95
96    for (t = 20; t < 40; t += 5) {
97        SHA_F2(A,B,C,D,E,t + 0);
98        SHA_F2(E,A,B,C,D,t + 1);
99        SHA_F2(D,E,A,B,C,t + 2);
100        SHA_F2(C,D,E,A,B,t + 3);
101        SHA_F2(B,C,D,E,A,t + 4);
102    }
103
104#undef SHA_F2
105
106#define SHA_F3(A,B,C,D,E,t)                                     \
107    E += ror27(A) +                                             \
108        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
109        ((B&C)|(D&(B|C))) + 0x8F1BBCDC;                         \
110    B = ror2(B);
111
112    for (; t < 60; t += 5) {
113        SHA_F3(A,B,C,D,E,t + 0);
114        SHA_F3(E,A,B,C,D,t + 1);
115        SHA_F3(D,E,A,B,C,t + 2);
116        SHA_F3(C,D,E,A,B,t + 3);
117        SHA_F3(B,C,D,E,A,t + 4);
118    }
119
120#undef SHA_F3
121
122#define SHA_F4(A,B,C,D,E,t)                                     \
123    E += ror27(A) +                                             \
124        (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +   \
125        (B^C^D) + 0xCA62C1D6;                                   \
126    B = ror2(B);
127
128    for (; t < 80; t += 5) {
129        SHA_F4(A,B,C,D,E,t + 0);
130        SHA_F4(E,A,B,C,D,t + 1);
131        SHA_F4(D,E,A,B,C,t + 2);
132        SHA_F4(C,D,E,A,B,t + 3);
133        SHA_F4(B,C,D,E,A,t + 4);
134    }
135
136#undef SHA_F4
137
138    ctx->state[0] += A;
139    ctx->state[1] += B;
140    ctx->state[2] += C;
141    ctx->state[3] += D;
142    ctx->state[4] += E;
143}
144
145void SHA_update(SHA_CTX* ctx, const void* data, int len) {
146    int i = ctx->count % sizeof(ctx->buf);
147    const uint8_t* p = (const uint8_t*)data;
148
149    ctx->count += len;
150
151    while (len > sizeof(ctx->buf) - i) {
152        memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
153        len -= sizeof(ctx->buf) - i;
154        p += sizeof(ctx->buf) - i;
155        SHA1_Transform(ctx);
156        i = 0;
157    }
158
159    while (len--) {
160        ctx->buf.b[i++] = *p++;
161        if (i == sizeof(ctx->buf)) {
162            SHA1_Transform(ctx);
163            i = 0;
164        }
165    }
166}
167
168
169const uint8_t* SHA_final(SHA_CTX* ctx) {
170    uint64_t cnt = ctx->count * 8;
171    int i;
172
173    SHA_update(ctx, (uint8_t*)"\x80", 1);
174    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
175        SHA_update(ctx, (uint8_t*)"\0", 1);
176    }
177    for (i = 0; i < 8; ++i) {
178        uint8_t tmp = cnt >> ((7 - i) * 8);
179        SHA_update(ctx, &tmp, 1);
180    }
181
182    for (i = 0; i < 5; i++) {
183        ctx->buf.w[i] = bswap_32(ctx->state[i]);
184    }
185
186    return ctx->buf.b;
187}
188
189#else   // __BYTE_ORDER == BIG_ENDIAN
190
191#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
192
193static void SHA1_transform(SHA_CTX *ctx) {
194    uint32_t W[80];
195    uint32_t A, B, C, D, E;
196    uint8_t *p = ctx->buf;
197    int t;
198
199    for(t = 0; t < 16; ++t) {
200        uint32_t tmp =  *p++ << 24;
201        tmp |= *p++ << 16;
202        tmp |= *p++ << 8;
203        tmp |= *p++;
204        W[t] = tmp;
205    }
206
207    for(; t < 80; t++) {
208        W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
209    }
210
211    A = ctx->state[0];
212    B = ctx->state[1];
213    C = ctx->state[2];
214    D = ctx->state[3];
215    E = ctx->state[4];
216
217    for(t = 0; t < 80; t++) {
218        uint32_t tmp = rol(5,A) + E + W[t];
219
220        if (t < 20)
221            tmp += (D^(B&(C^D))) + 0x5A827999;
222        else if ( t < 40)
223            tmp += (B^C^D) + 0x6ED9EBA1;
224        else if ( t < 60)
225            tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
226        else
227            tmp += (B^C^D) + 0xCA62C1D6;
228
229        E = D;
230        D = C;
231        C = rol(30,B);
232        B = A;
233        A = tmp;
234    }
235
236    ctx->state[0] += A;
237    ctx->state[1] += B;
238    ctx->state[2] += C;
239    ctx->state[3] += D;
240    ctx->state[4] += E;
241}
242
243void SHA_update(SHA_CTX *ctx, const void *data, int len) {
244    int i = ctx->count % sizeof(ctx->buf);
245    const uint8_t* p = (const uint8_t*)data;
246
247    ctx->count += len;
248
249    while (len--) {
250        ctx->buf[i++] = *p++;
251        if (i == sizeof(ctx->buf)) {
252            SHA1_transform(ctx);
253            i = 0;
254        }
255    }
256}
257const uint8_t *SHA_final(SHA_CTX *ctx) {
258    uint8_t *p = ctx->buf;
259    uint64_t cnt = ctx->count * 8;
260    int i;
261
262    SHA_update(ctx, (uint8_t*)"\x80", 1);
263    while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
264        SHA_update(ctx, (uint8_t*)"\0", 1);
265    }
266    for (i = 0; i < 8; ++i) {
267        uint8_t tmp = cnt >> ((7 - i) * 8);
268        SHA_update(ctx, &tmp, 1);
269    }
270
271    for (i = 0; i < 5; i++) {
272        uint32_t tmp = ctx->state[i];
273        *p++ = tmp >> 24;
274        *p++ = tmp >> 16;
275        *p++ = tmp >> 8;
276        *p++ = tmp >> 0;
277    }
278
279    return ctx->buf;
280}
281
282#endif // endianness
283
284void SHA_init(SHA_CTX* ctx) {
285    ctx->state[0] = 0x67452301;
286    ctx->state[1] = 0xEFCDAB89;
287    ctx->state[2] = 0x98BADCFE;
288    ctx->state[3] = 0x10325476;
289    ctx->state[4] = 0xC3D2E1F0;
290    ctx->count = 0;
291}
292
293/* Convenience function */
294const uint8_t* SHA(const void *data, int len, uint8_t *digest) {
295    const uint8_t *p;
296    int i;
297    SHA_CTX ctx;
298    SHA_init(&ctx);
299    SHA_update(&ctx, data, len);
300    p = SHA_final(&ctx);
301    for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
302        digest[i] = *p++;
303    }
304    return digest;
305}
306