Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / sshd / libtomcrypt / sha512.c
1 #include "mycrypt.h"
2
3 #ifdef SHA512
4
5 const struct _hash_descriptor sha512_desc =
6 {
7     "sha512",
8     5,
9     64,
10     128,
11     &sha512_init,
12     &sha512_process,
13     &sha512_done,
14     &sha512_test
15 };
16
17 /* the K array */
18 static const ulong64 K[80] = {
19 CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), 
20 CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
21 CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), 
22 CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
23 CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), 
24 CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
25 CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), 
26 CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
27 CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), 
28 CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
29 CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), 
30 CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
31 CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), 
32 CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
33 CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), 
34 CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
35 CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), 
36 CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
37 CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), 
38 CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
39 CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
40 CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
41 CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), 
42 CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
43 CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), 
44 CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
45 CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), 
46 CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
47 CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), 
48 CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
49 CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), 
50 CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
51 CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), 
52 CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
53 CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), 
54 CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
55 CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), 
56 CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
57 CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), 
58 CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
59 };
60
61 /* Various logical functions */
62 #define Ch(x,y,z)       (z ^ (x & (y ^ z)))
63 #define Maj(x,y,z)      (((x | y) & z) | (x & y)) 
64 #define S(x, n)         ROR64((x),(n))
65 #define R(x, n)         (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
66 #define Sigma0(x)       (S(x, 28) ^ S(x, 34) ^ S(x, 39))
67 #define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
68 #define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
69 #define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
70
71 /* compress 1024-bits */
72 #ifdef CLEAN_STACK
73 static void _sha512_compress(hash_state * md)
74 #else
75 static void sha512_compress(hash_state * md)
76 #endif
77 {
78     ulong64 S[8], W[80], t0, t1;
79     int i;
80
81     _ARGCHK(md != NULL);
82
83     /* copy state into S */
84     for (i = 0; i < 8; i++)
85         S[i] = md->sha512.state[i];
86
87     /* copy the state into 1024-bits into W[0..15] */
88     for (i = 0; i < 16; i++) {
89         LOAD64H(W[i], md->sha512.buf + (8*i));
90     }
91
92     /* fill W[16..79] */
93     for (i = 16; i < 80; i++) {
94         W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
95     }        
96
97     /* Compress */
98     for (i = 0; i < 80; i++) {
99         t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
100         t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
101         S[7] = S[6];
102         S[6] = S[5];
103         S[5] = S[4];
104         S[4] = S[3] + t0;
105         S[3] = S[2];
106         S[2] = S[1];
107         S[1] = S[0];
108         S[0] = t0 + t1;
109     }
110
111     /* feedback */
112     for (i = 0; i < 8; i++) {
113         md->sha512.state[i] = md->sha512.state[i] + S[i];
114     }
115 }
116
117 /* compress 1024-bits */
118 #ifdef CLEAN_STACK
119 static void sha512_compress(hash_state * md)
120 {
121     _sha512_compress(md);
122     burn_stack(sizeof(ulong64) * 90 + sizeof(int));
123 }
124 #endif
125
126 /* init the sha512 state */
127 void sha512_init(hash_state * md)
128 {
129     _ARGCHK(md != NULL);
130
131     md->sha512.curlen = 0;
132     md->sha512.length = 0;
133     md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
134     md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
135     md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
136     md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
137     md->sha512.state[4] = CONST64(0x510e527fade682d1);
138     md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
139     md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
140     md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
141 }
142
143 void sha512_process(hash_state * md, const unsigned char *buf, unsigned long len)
144 {
145     unsigned long n;
146     _ARGCHK(md != NULL);
147     _ARGCHK(buf != NULL);
148     while (len > 0) {
149         n = MIN(len, (128 - md->sha512.curlen));
150         memcpy(md->sha512.buf + md->sha512.curlen, buf, (size_t)n);
151         md->sha512.curlen += n;
152         buf               += n;
153         len               -= n;
154
155         /* is 128 bytes full? */
156         if (md->sha512.curlen == 128) {
157             sha512_compress(md);
158             md->sha512.length += 1024;
159             md->sha512.curlen = 0;
160         }
161     }
162 }
163
164 void sha512_done(hash_state * md, unsigned char *hash)
165 {
166     int i;
167
168     _ARGCHK(md != NULL);
169     _ARGCHK(hash != NULL);
170
171     /* increase the length of the message */
172     md->sha512.length += md->sha512.curlen * CONST64(8);
173
174     /* append the '1' bit */
175     md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
176
177     /* if the length is currently above 112 bytes we append zeros
178      * then compress.  Then we can fall back to padding zeros and length
179      * encoding like normal.
180      */
181     if (md->sha512.curlen > 112) {
182         while (md->sha512.curlen < 128) {
183             md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
184         }
185         sha512_compress(md);
186         md->sha512.curlen = 0;
187     }
188
189     /* pad upto 120 bytes of zeroes 
190      * note: that from 112 to 120 is the 64 MSB of the length.  We assume that you won't hash
191      * > 2^64 bits of data... :-)
192      */
193     while (md->sha512.curlen < 120) {
194         md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
195     }
196
197     /* store length */
198     STORE64H(md->sha512.length, md->sha512.buf+120);
199     sha512_compress(md);
200
201     /* copy output */
202     for (i = 0; i < 8; i++) {
203         STORE64H(md->sha512.state[i], hash+(8*i));
204     }
205 #ifdef CLEAN_STACK
206     zeromem(md, sizeof(hash_state));
207 #endif
208 }
209
210 int  sha512_test(void)
211 {
212  #ifndef LTC_TEST
213     return CRYPT_NOP;
214  #else    
215   static const struct {
216       char *msg;
217       unsigned char hash[64];
218   } tests[] = {
219     { "abc",
220      { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
221        0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
222        0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
223        0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
224        0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
225        0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
226        0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
227        0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
228     },
229     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
230      { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
231        0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
232        0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
233        0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
234        0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
235        0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
236        0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
237        0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
238     },
239   };
240
241   int i;
242   unsigned char tmp[64];
243   hash_state md;
244
245   for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
246       sha512_init(&md);
247       sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
248       sha512_done(&md, tmp);
249       if (memcmp(tmp, tests[i].hash, 64) != 0) {
250          return CRYPT_FAIL_TESTVECTOR;
251       }
252   }
253   return CRYPT_OK;
254   #endif
255 }
256
257 #ifdef SHA384
258    #include "sha384.c"
259 #endif
260
261 #endif
262
263
264