port-work; won't compile or even work
[ppcskel.git] / sha1.c
1 /*
2 SHA-1 in C
3 By Steve Reid <steve@edmweb.com>
4 100% Public Domain
5
6 Test Vectors (from FIPS PUB 180-1)
7 "abc"
8   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
9 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
10   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
11 A million repetitions of "a"
12   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
13 */
14
15 #define SHA1HANDSOFF
16
17 #include "string.h"
18 #include "sha1.h"
19 #include "bootmii_ppc.h"
20 #include "hollywood.h"
21 #include "malloc.h"
22 #include "types.h"
23
24 //should be divisibly by four
25 #define BLOCKSIZE 32
26
27 #define SHA_CMD_FLAG_EXEC (1<<31)
28 #define SHA_CMD_FLAG_IRQ  (1<<30)
29 #define SHA_CMD_FLAG_ERR  (1<<29)
30 #define SHA_CMD_AREA_BLOCK ((1<<10) - 1)
31
32 typedef struct {
33         unsigned long state[5];
34         unsigned long count[2];
35         unsigned char buffer[64];
36 } SHA1_CTX;
37
38 typedef u32 sha1[5];
39
40 static void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
41 static void SHA1Transforml(unsigned long state[5], unsigned char buffer[64], u32 len);
42 static void SHA1Init(SHA1_CTX* context);
43 static void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
44 static void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
45
46 static void SHA1Transform(unsigned long state[5], unsigned char buffer[64]) {
47         SHA1Transforml(state, buffer, 1);
48 }
49
50 /* Hash a single 512-bit block. This is the core of the algorithm. */
51
52 static void SHA1Transforml(unsigned long state[5], unsigned char buffer[64], u32 len)
53 {
54         /* Copy context->state[] to working vars */
55         write32(SHA_H0, state[0]);
56         write32(SHA_H1, state[1]);
57         write32(SHA_H2, state[2]);
58         write32(SHA_H3, state[3]);
59         write32(SHA_H4, state[4]);
60
61         static u32 num_blocks;
62         num_blocks = len;
63
64         // assign block to local copy which is 64-byte aligned
65         static u8 block[64*BLOCKSIZE] ALIGNED(64);
66         // for further improvments!
67         // u8 *block = memalign(64, 64*num_blocks);
68         memcpy(block, buffer, 64*num_blocks);
69
70         // royal flush :)
71         sync_after_write(block, 64*num_blocks);
72
73         // tell sha1 controller the block source address
74         write32(SHA_SRC, virt_to_phys(block));
75         
76         // tell sha1 controller number of blocks
77         if (num_blocks != 0)
78                 num_blocks--;
79         write32(SHA_CMD, (read32(SHA_CMD) & ~(SHA_CMD_AREA_BLOCK)) | num_blocks);
80
81         // fire up hashing and wait till its finished
82         write32(SHA_CMD, read32(SHA_CMD) | SHA_CMD_FLAG_EXEC);
83         while (read32(SHA_CMD) & SHA_CMD_FLAG_EXEC);
84
85         // free the aligned data
86         // free(block);
87
88         /* Add the working vars back into context.state[] */
89         state[0] = read32(SHA_H0);
90         state[1] = read32(SHA_H1);
91         state[2] = read32(SHA_H2);
92         state[3] = read32(SHA_H3);
93         state[4] = read32(SHA_H4);
94 }
95
96
97 /* SHA1Init - Initialize new context */
98
99 static void SHA1Init(SHA1_CTX* context)
100 {
101         // reset sha-1 engine
102         write32(SHA_CMD, read32(SHA_CMD) & ~(SHA_CMD_FLAG_EXEC));
103         while ((read32(SHA_CMD) & SHA_CMD_FLAG_EXEC) != 0);
104
105         /* SHA1 initialization constants */
106         context->state[0] = 0x67452301;
107         context->state[1] = 0xEFCDAB89;
108         context->state[2] = 0x98BADCFE;
109         context->state[3] = 0x10325476;
110         context->state[4] = 0xC3D2E1F0;
111         context->count[0] = context->count[1] = 0;
112 }
113
114
115 /* Run your data through this. */
116
117 static void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
118 {
119         unsigned int i, j;
120
121         j = (context->count[0] >> 3) & 63;
122         if ((context->count[0] += len << 3) < (len << 3)) 
123                 context->count[1]++;
124         context->count[1] += (len >> 29);
125         if ((j + len) > 63) {
126                 memcpy(&context->buffer[j], data, (i = 64-j));
127                 SHA1Transform(context->state, context->buffer);
128                 // try bigger blocks at once
129                 for ( ; i + 63 + ((BLOCKSIZE-1)*64) < len; i += (64 + (BLOCKSIZE-1)*64)) {
130                         SHA1Transforml(context->state, &data[i], BLOCKSIZE);
131                 }
132                 for ( ; i + 63 + (((BLOCKSIZE/2)-1)*64) < len; i += (64 + ((BLOCKSIZE/2)-1)*64)) {
133                         SHA1Transforml(context->state, &data[i], BLOCKSIZE/2);
134                 }
135                 for ( ; i + 63 + (((BLOCKSIZE/4)-1)*64) < len; i += (64 + ((BLOCKSIZE/4)-1)*64)) {
136                         SHA1Transforml(context->state, &data[i], BLOCKSIZE/4);
137                 }
138                 for ( ; i + 63 < len; i += 64) {
139                         SHA1Transform(context->state, &data[i]);
140                 }
141                 j = 0;
142         }
143         else i = 0;
144         memcpy(&context->buffer[j], &data[i], len - i);
145 }
146
147
148 /* Add padding and return the message digest. */
149
150 static void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
151 {
152         unsigned long i, j;
153         unsigned char finalcount[8];
154
155         for (i = 0; i < 8; i++) {
156                 finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
157                 >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
158         }
159
160         SHA1Update(context, (unsigned char *)"\200", 1);
161         while ((context->count[0] & 504) != 448) {
162                 SHA1Update(context, (unsigned char *)"\0", 1);
163         }
164         SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
165         for (i = 0; i < 20; i++) {
166                 digest[i] = (unsigned char)
167                 ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
168         }
169         /* Wipe variables */
170         i = j = 0;
171         memset(context->buffer, 0, 64);
172         memset(context->state, 0, 20);
173         memset(context->count, 0, 8);
174         memset(&finalcount, 0, 8);
175 #ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
176         SHA1Transform(context->state, context->buffer);
177 #endif
178 }
179
180 void SHA1(unsigned char *ptr, unsigned int size, unsigned char *outbuf) 
181 {
182         SHA1_CTX ctx;
183   
184         SHA1Init(&ctx);
185         SHA1Update(&ctx, ptr, size);
186         SHA1Final(outbuf, &ctx);
187 }
188
189 static void SHA1TestIt(const char *str, u32 len)
190 {
191         u8 *in = malloc(len*sizeof(u8));
192         sha1 out;
193         strlcpy((char*)in, str, len+1);
194
195         u32 diff = read32(HW_TIMER);
196         SHA1(in, len, (u8*) out);
197         diff = read32(HW_TIMER)-diff;
198
199         printf("SHA-1 (in hardware) says (H0|H1|H2|H3|H4): %08X|%08X|%08X|%08X|%08X this was calculatet in %02d (hollywood-)cycles\n", out[0], out[1], out[2], out[3], out[4], diff);
200 }
201
202
203 void SHA1TestCases(void)
204 {
205         // expected sha1 hash of string "lasasdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5" (len = 3811)
206         // 33ad104c4fd0de2e90edd6f6103de8304043ab20
207         SHA1TestIt("lasasdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5asdfasghasfghahadghadghadfghasdgfasdgfafghasdfgasdfasdfasdfasdfasdfahadhjaer5yq35635uyjzgzdghad56q346aw456w46aw5", 3811);
208         // expected sha1 hash of string "asdf" (len = 4)
209         // 3da541559918a808c2402bba5012f6c60b27661c
210         SHA1TestIt("asdf", 4);
211
212         // expected sha1 hash of string "asdfasdfjalsdfjklasdkjflaksdjflaksdjflkasjdfklajsdfkljasldkfjlaskdjflkajsdfakljsdfklasjddflkjalskdjfasldfjlasdkjflaskjdflaksdf" (len = 126)
213         // 74e1e9e5489d08dc65108aff3a21756e8fc269d2
214         SHA1TestIt("asdfasdfjalsdfjklasdkjflaksdjflaksdjflkasjdfklajsdfkljasldkfjlaskdjflkajsdfakljsdfklasjddflkjalskdjfasldfjlasdkjflaskjdflaksdf", 126);
215 }
216