3 By Steve Reid <steve@edmweb.com>
6 Test Vectors (from FIPS PUB 180-1)
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
19 #include "bootmii_ppc.h"
20 #include "hollywood.h"
24 //should be divisibly by four
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)
33 unsigned long state[5];
34 unsigned long count[2];
35 unsigned char buffer[64];
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);
46 static void SHA1Transform(unsigned long state[5], unsigned char buffer[64]) {
47 SHA1Transforml(state, buffer, 1);
50 /* Hash a single 512-bit block. This is the core of the algorithm. */
52 static void SHA1Transforml(unsigned long state[5], unsigned char buffer[64], u32 len)
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]);
61 static u32 num_blocks;
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);
71 sync_after_write(block, 64*num_blocks);
73 // tell sha1 controller the block source address
74 write32(SHA_SRC, virt_to_phys(block));
76 // tell sha1 controller number of blocks
79 write32(SHA_CMD, (read32(SHA_CMD) & ~(SHA_CMD_AREA_BLOCK)) | num_blocks);
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);
85 // free the aligned data
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);
97 /* SHA1Init - Initialize new context */
99 static void SHA1Init(SHA1_CTX* context)
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);
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;
115 /* Run your data through this. */
117 static void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
121 j = (context->count[0] >> 3) & 63;
122 if ((context->count[0] += len << 3) < (len << 3))
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);
132 for ( ; i + 63 + (((BLOCKSIZE/2)-1)*64) < len; i += (64 + ((BLOCKSIZE/2)-1)*64)) {
133 SHA1Transforml(context->state, &data[i], BLOCKSIZE/2);
135 for ( ; i + 63 + (((BLOCKSIZE/4)-1)*64) < len; i += (64 + ((BLOCKSIZE/4)-1)*64)) {
136 SHA1Transforml(context->state, &data[i], BLOCKSIZE/4);
138 for ( ; i + 63 < len; i += 64) {
139 SHA1Transform(context->state, &data[i]);
144 memcpy(&context->buffer[j], &data[i], len - i);
148 /* Add padding and return the message digest. */
150 static void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
153 unsigned char finalcount[8];
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 */
160 SHA1Update(context, (unsigned char *)"\200", 1);
161 while ((context->count[0] & 504) != 448) {
162 SHA1Update(context, (unsigned char *)"\0", 1);
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);
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);
180 void SHA1(unsigned char *ptr, unsigned int size, unsigned char *outbuf)
185 SHA1Update(&ctx, ptr, size);
186 SHA1Final(outbuf, &ctx);
189 static void SHA1TestIt(const char *str, u32 len)
191 u8 *in = malloc(len*sizeof(u8));
193 strlcpy((char*)in, str, len+1);
195 u32 diff = read32(HW_TIMER);
196 SHA1(in, len, (u8*) out);
197 diff = read32(HW_TIMER)-diff;
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);
203 void SHA1TestCases(void)
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);
212 // expected sha1 hash of string "asdfasdfjalsdfjklasdkjflaksdjflaksdjflkasjdfklajsdfkljasldkfjlaskdjflkajsdfakljsdfklasjddflkjalskdjfasldfjlasdkjflaskjdflaksdf" (len = 126)
213 // 74e1e9e5489d08dc65108aff3a21756e8fc269d2
214 SHA1TestIt("asdfasdfjalsdfjklasdkjflaksdjflaksdjflkasjdfklajsdfkljasldkfjlaskdjflkajsdfakljsdfklasjddflkjalskdjfasldfjlasdkjflaskjdflaksdf", 126);