Clone a tag rather than SeaBIOS stable branch HEAD
[coreboot.git] / payloads / libpayload / crypto / sha1.c
1 /*
2  * This file is part of the libpayload project.
3  *
4  * It has originally been taken from the OpenBSD project.
5  */
6
7 /*      $OpenBSD: sha1.c,v 1.20 2005/08/08 08:05:35 espie Exp $ */
8
9 /*
10  * SHA-1 in C
11  * By Steve Reid <steve@edmweb.com>
12  * 100% Public Domain
13  *
14  * Test Vectors (from FIPS PUB 180-1)
15  * "abc"
16  *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
17  * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
18  *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
19  * A million repetitions of "a"
20  *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
21  */
22
23 #include <libpayload-config.h>
24 #include <libpayload.h>
25
26 typedef u8 u_int8_t;
27 typedef u32 u_int32_t;
28 typedef u64 u_int64_t;
29 typedef unsigned int u_int;
30
31 /* Moved from libpayload.h */
32
33 #ifdef CONFIG_TARGET_I386
34 #define BYTE_ORDER      LITTLE_ENDIAN
35 #else
36 #define BYTE_ORDER      BIG_ENDIAN
37 #endif
38
39 #if 0
40 #include <sys/param.h>
41 #include <string.h>
42 #include <sha1.h>
43 #endif
44
45 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
46
47 /*
48  * blk0() and blk() perform the initial expand.
49  * I got the idea of expanding during the round function from SSLeay
50  */
51 #if BYTE_ORDER == LITTLE_ENDIAN
52 # define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
53     |(rol(block->l[i],8)&0x00FF00FF))
54 #else
55 # define blk0(i) block->l[i]
56 #endif
57 #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
58     ^block->l[(i+2)&15]^block->l[i&15],1))
59
60 /*
61  * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
62  */
63 #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
64 #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
65 #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
66 #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
67 #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
68
69 /*
70  * Hash a single 512-bit block. This is the core of the algorithm.
71  */
72 void
73 SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH])
74 {
75         u_int32_t a, b, c, d, e;
76         u_int8_t workspace[SHA1_BLOCK_LENGTH];
77         typedef union {
78                 u_int8_t c[64];
79                 u_int32_t l[16];
80         } CHAR64LONG16;
81         CHAR64LONG16 *block = (CHAR64LONG16 *)workspace;
82
83         (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH);
84
85         /* Copy context->state[] to working vars */
86         a = state[0];
87         b = state[1];
88         c = state[2];
89         d = state[3];
90         e = state[4];
91
92         /* 4 rounds of 20 operations each. Loop unrolled. */
93         R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
94         R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
95         R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
96         R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
97         R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
98         R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
99         R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
100         R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
101         R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
102         R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
103         R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
104         R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
105         R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
106         R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
107         R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
108         R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
109         R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
110         R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
111         R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
112         R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
113
114         /* Add the working vars back into context.state[] */
115         state[0] += a;
116         state[1] += b;
117         state[2] += c;
118         state[3] += d;
119         state[4] += e;
120
121         /* Wipe variables */
122         a = b = c = d = e = 0;
123 }
124
125
126 /*
127  * SHA1Init - Initialize new context
128  */
129 void
130 SHA1Init(SHA1_CTX *context)
131 {
132
133         /* SHA1 initialization constants */
134         context->count = 0;
135         context->state[0] = 0x67452301;
136         context->state[1] = 0xEFCDAB89;
137         context->state[2] = 0x98BADCFE;
138         context->state[3] = 0x10325476;
139         context->state[4] = 0xC3D2E1F0;
140 }
141
142
143 /*
144  * Run your data through this.
145  */
146 void
147 SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len)
148 {
149         size_t i, j;
150
151         j = (size_t)((context->count >> 3) & 63);
152         context->count += (len << 3);
153         if ((j + len) > 63) {
154                 (void)memcpy(&context->buffer[j], data, (i = 64-j));
155                 SHA1Transform(context->state, context->buffer);
156                 for ( ; i + 63 < len; i += 64)
157                         SHA1Transform(context->state, (u_int8_t *)&data[i]);
158                 j = 0;
159         } else {
160                 i = 0;
161         }
162         (void)memcpy(&context->buffer[j], &data[i], len - i);
163 }
164
165
166 /*
167  * Add padding and return the message digest.
168  */
169 void
170 SHA1Pad(SHA1_CTX *context)
171 {
172         u_int8_t finalcount[8];
173         u_int i;
174
175         for (i = 0; i < 8; i++) {
176                 finalcount[i] = (u_int8_t)((context->count >>
177                     ((7 - (i & 7)) * 8)) & 255);        /* Endian independent */
178         }
179         SHA1Update(context, (u_int8_t *)"\200", 1);
180         while ((context->count & 504) != 448)
181                 SHA1Update(context, (u_int8_t *)"\0", 1);
182         SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
183 }
184
185 void
186 SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
187 {
188         u_int i;
189
190         SHA1Pad(context);
191         if (digest) {
192                 for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
193                         digest[i] = (u_int8_t)
194                            ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
195                 }
196                 memset(context, 0, sizeof(*context));
197         }
198 }
199
200 /**
201  * Compute the SHA-1 hash of the given data as specified by the 'data' and
202  * 'len' arguments, and place the result -- 160 bits (20 bytes) -- into the
203  * specified output buffer 'buf'.
204  *
205  * @param data Pointer to the input data that shall be hashed.
206  * @param len Length of the input data (in bytes).
207  * @param buf Buffer which will hold the resulting hash (must be at
208  *            least 20 bytes in size).
209  * @return Pointer to the output buffer where the hash is stored.
210  */
211 u8 *sha1(const u8 *data, size_t len, u8 *buf)
212 {
213         SHA1_CTX ctx;
214
215         SHA1Init(&ctx);
216         SHA1Update(&ctx, data, len);
217         SHA1Final(buf, &ctx);
218
219         return buf;
220 }