diff options
Diffstat (limited to 'linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/sha512.c')
-rwxr-xr-x | linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/sha512.c | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/sha512.c b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/sha512.c new file mode 100755 index 0000000..e62165b --- /dev/null +++ b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/sha512.c | |||
@@ -0,0 +1,400 @@ | |||
1 | /* sha512.c - SHA384 and SHA512 hash functions | ||
2 | * Copyright (C) 2003 Free Software Foundation, Inc. | ||
3 | * | ||
4 | * Please see below for more legal information! | ||
5 | * | ||
6 | * This file is part of Libgcrypt. | ||
7 | * | ||
8 | * Libgcrypt is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU Lesser general Public License as | ||
10 | * published by the Free Software Foundation; either version 2.1 of | ||
11 | * the License, or (at your option) any later version. | ||
12 | * | ||
13 | * Libgcrypt is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
21 | */ | ||
22 | |||
23 | |||
24 | /* Test vectors from FIPS-180-2: | ||
25 | * | ||
26 | * "abc" | ||
27 | * 384: | ||
28 | * CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163 | ||
29 | * 1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7 | ||
30 | * 512: | ||
31 | * DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A | ||
32 | * 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F | ||
33 | * | ||
34 | * "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" | ||
35 | * 384: | ||
36 | * 09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2 | ||
37 | * 2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039 | ||
38 | * 512: | ||
39 | * 8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018 | ||
40 | * 501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909 | ||
41 | * | ||
42 | * "a" x 1000000 | ||
43 | * 384: | ||
44 | * 9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852 | ||
45 | * 7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985 | ||
46 | * 512: | ||
47 | * E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB | ||
48 | * DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B | ||
49 | */ | ||
50 | |||
51 | |||
52 | #include <config.h> | ||
53 | #include <string.h> | ||
54 | #include "g10lib.h" | ||
55 | #include "bithelp.h" | ||
56 | #include "cipher.h" | ||
57 | |||
58 | typedef struct | ||
59 | { | ||
60 | u64 h0, h1, h2, h3, h4, h5, h6, h7; | ||
61 | u64 nblocks; | ||
62 | byte buf[128]; | ||
63 | int count; | ||
64 | } SHA512_CONTEXT; | ||
65 | |||
66 | static void | ||
67 | sha512_init (void *context) | ||
68 | { | ||
69 | SHA512_CONTEXT *hd = context; | ||
70 | |||
71 | hd->h0 = U64_C(0x6a09e667f3bcc908); | ||
72 | hd->h1 = U64_C(0xbb67ae8584caa73b); | ||
73 | hd->h2 = U64_C(0x3c6ef372fe94f82b); | ||
74 | hd->h3 = U64_C(0xa54ff53a5f1d36f1); | ||
75 | hd->h4 = U64_C(0x510e527fade682d1); | ||
76 | hd->h5 = U64_C(0x9b05688c2b3e6c1f); | ||
77 | hd->h6 = U64_C(0x1f83d9abfb41bd6b); | ||
78 | hd->h7 = U64_C(0x5be0cd19137e2179); | ||
79 | |||
80 | hd->nblocks = 0; | ||
81 | hd->count = 0; | ||
82 | } | ||
83 | |||
84 | static void | ||
85 | sha384_init (void *context) | ||
86 | { | ||
87 | SHA512_CONTEXT *hd = context; | ||
88 | |||
89 | hd->h0 = U64_C(0xcbbb9d5dc1059ed8); | ||
90 | hd->h1 = U64_C(0x629a292a367cd507); | ||
91 | hd->h2 = U64_C(0x9159015a3070dd17); | ||
92 | hd->h3 = U64_C(0x152fecd8f70e5939); | ||
93 | hd->h4 = U64_C(0x67332667ffc00b31); | ||
94 | hd->h5 = U64_C(0x8eb44a8768581511); | ||
95 | hd->h6 = U64_C(0xdb0c2e0d64f98fa7); | ||
96 | hd->h7 = U64_C(0x47b5481dbefa4fa4); | ||
97 | |||
98 | hd->nblocks = 0; | ||
99 | hd->count = 0; | ||
100 | } | ||
101 | |||
102 | |||
103 | /**************** | ||
104 | * Transform the message W which consists of 16 64-bit-words | ||
105 | */ | ||
106 | static void | ||
107 | transform (SHA512_CONTEXT *hd, byte *data) | ||
108 | { | ||
109 | u64 a, b, c, d, e, f, g, h; | ||
110 | u64 w[80]; | ||
111 | int t; | ||
112 | static const u64 k[] = | ||
113 | { | ||
114 | U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd), | ||
115 | U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc), | ||
116 | U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019), | ||
117 | U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118), | ||
118 | U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe), | ||
119 | U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2), | ||
120 | U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1), | ||
121 | U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694), | ||
122 | U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3), | ||
123 | U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65), | ||
124 | U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483), | ||
125 | U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5), | ||
126 | U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210), | ||
127 | U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4), | ||
128 | U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725), | ||
129 | U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70), | ||
130 | U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926), | ||
131 | U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df), | ||
132 | U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8), | ||
133 | U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b), | ||
134 | U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001), | ||
135 | U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30), | ||
136 | U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910), | ||
137 | U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8), | ||
138 | U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53), | ||
139 | U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8), | ||
140 | U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb), | ||
141 | U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3), | ||
142 | U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60), | ||
143 | U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec), | ||
144 | U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9), | ||
145 | U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b), | ||
146 | U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207), | ||
147 | U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178), | ||
148 | U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6), | ||
149 | U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b), | ||
150 | U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493), | ||
151 | U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c), | ||
152 | U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a), | ||
153 | U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817) | ||
154 | }; | ||
155 | |||
156 | /* get values from the chaining vars */ | ||
157 | a = hd->h0; | ||
158 | b = hd->h1; | ||
159 | c = hd->h2; | ||
160 | d = hd->h3; | ||
161 | e = hd->h4; | ||
162 | f = hd->h5; | ||
163 | g = hd->h6; | ||
164 | h = hd->h7; | ||
165 | |||
166 | #ifdef WORDS_BIGENDIAN | ||
167 | memcpy (w, data, 128); | ||
168 | #else | ||
169 | { | ||
170 | int i; | ||
171 | byte *p2; | ||
172 | |||
173 | for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += 8) | ||
174 | { | ||
175 | p2[7] = *data++; | ||
176 | p2[6] = *data++; | ||
177 | p2[5] = *data++; | ||
178 | p2[4] = *data++; | ||
179 | p2[3] = *data++; | ||
180 | p2[2] = *data++; | ||
181 | p2[1] = *data++; | ||
182 | p2[0] = *data++; | ||
183 | } | ||
184 | } | ||
185 | #endif | ||
186 | |||
187 | #define ROTR(x,n) (((x)>>(n)) | ((x)<<(64-(n)))) | ||
188 | #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) | ||
189 | #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | ||
190 | #define Sum0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) | ||
191 | #define Sum1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) | ||
192 | #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) | ||
193 | #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) | ||
194 | |||
195 | for (t = 16; t < 80; t++) | ||
196 | w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16]; | ||
197 | |||
198 | for (t = 0; t < 80; t++) | ||
199 | { | ||
200 | u64 t1, t2; | ||
201 | |||
202 | t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; | ||
203 | t2 = Sum0 (a) + Maj (a, b, c); | ||
204 | h = g; | ||
205 | g = f; | ||
206 | f = e; | ||
207 | e = d + t1; | ||
208 | d = c; | ||
209 | c = b; | ||
210 | b = a; | ||
211 | a = t1 + t2; | ||
212 | |||
213 | /* printf("t=%d a=%016llX b=%016llX c=%016llX d=%016llX " | ||
214 | "e=%016llX f=%016llX g=%016llX h=%016llX\n",t,a,b,c,d,e,f,g,h); */ | ||
215 | } | ||
216 | |||
217 | /* update chaining vars */ | ||
218 | hd->h0 += a; | ||
219 | hd->h1 += b; | ||
220 | hd->h2 += c; | ||
221 | hd->h3 += d; | ||
222 | hd->h4 += e; | ||
223 | hd->h5 += f; | ||
224 | hd->h6 += g; | ||
225 | hd->h7 += h; | ||
226 | } | ||
227 | |||
228 | |||
229 | /* Update the message digest with the contents | ||
230 | * of INBUF with length INLEN. | ||
231 | */ | ||
232 | static void | ||
233 | sha512_write (void *context, byte *inbuf, size_t inlen) | ||
234 | { | ||
235 | SHA512_CONTEXT *hd = context; | ||
236 | |||
237 | if (hd->count == 128) | ||
238 | { /* flush the buffer */ | ||
239 | transform (hd, hd->buf); | ||
240 | _gcry_burn_stack (768); | ||
241 | hd->count = 0; | ||
242 | hd->nblocks++; | ||
243 | } | ||
244 | if (!inbuf) | ||
245 | return; | ||
246 | if (hd->count) | ||
247 | { | ||
248 | for (; inlen && hd->count < 128; inlen--) | ||
249 | hd->buf[hd->count++] = *inbuf++; | ||
250 | sha512_write (context, NULL, 0); | ||
251 | if (!inlen) | ||
252 | return; | ||
253 | } | ||
254 | |||
255 | while (inlen >= 128) | ||
256 | { | ||
257 | transform (hd, inbuf); | ||
258 | hd->count = 0; | ||
259 | hd->nblocks++; | ||
260 | inlen -= 128; | ||
261 | inbuf += 128; | ||
262 | } | ||
263 | _gcry_burn_stack (768); | ||
264 | for (; inlen && hd->count < 128; inlen--) | ||
265 | hd->buf[hd->count++] = *inbuf++; | ||
266 | } | ||
267 | |||
268 | |||
269 | /* The routine final terminates the computation and | ||
270 | * returns the digest. | ||
271 | * The handle is prepared for a new cycle, but adding bytes to the | ||
272 | * handle will the destroy the returned buffer. | ||
273 | * Returns: 64 bytes representing the digest. When used for sha384, | ||
274 | * we take the leftmost 48 of those bytes. | ||
275 | */ | ||
276 | |||
277 | static void | ||
278 | sha512_final (void *context) | ||
279 | { | ||
280 | SHA512_CONTEXT *hd = context; | ||
281 | u64 t, msb, lsb; | ||
282 | byte *p; | ||
283 | |||
284 | sha512_write (context, NULL, 0); /* flush */ ; | ||
285 | |||
286 | t = hd->nblocks; | ||
287 | /* multiply by 128 to make a byte count */ | ||
288 | lsb = t << 7; | ||
289 | msb = t >> 57; | ||
290 | /* add the count */ | ||
291 | t = lsb; | ||
292 | if ((lsb += hd->count) < t) | ||
293 | msb++; | ||
294 | /* multiply by 8 to make a bit count */ | ||
295 | t = lsb; | ||
296 | lsb <<= 3; | ||
297 | msb <<= 3; | ||
298 | msb |= t >> 61; | ||
299 | |||
300 | if (hd->count < 112) | ||
301 | { /* enough room */ | ||
302 | hd->buf[hd->count++] = 0x80; /* pad */ | ||
303 | while (hd->count < 112) | ||
304 | hd->buf[hd->count++] = 0; /* pad */ | ||
305 | } | ||
306 | else | ||
307 | { /* need one extra block */ | ||
308 | hd->buf[hd->count++] = 0x80; /* pad character */ | ||
309 | while (hd->count < 128) | ||
310 | hd->buf[hd->count++] = 0; | ||
311 | sha512_write (context, NULL, 0); /* flush */ ; | ||
312 | memset (hd->buf, 0, 112); /* fill next block with zeroes */ | ||
313 | } | ||
314 | /* append the 128 bit count */ | ||
315 | hd->buf[112] = msb >> 56; | ||
316 | hd->buf[113] = msb >> 48; | ||
317 | hd->buf[114] = msb >> 40; | ||
318 | hd->buf[115] = msb >> 32; | ||
319 | hd->buf[116] = msb >> 24; | ||
320 | hd->buf[117] = msb >> 16; | ||
321 | hd->buf[118] = msb >> 8; | ||
322 | hd->buf[119] = msb; | ||
323 | |||
324 | hd->buf[120] = lsb >> 56; | ||
325 | hd->buf[121] = lsb >> 48; | ||
326 | hd->buf[122] = lsb >> 40; | ||
327 | hd->buf[123] = lsb >> 32; | ||
328 | hd->buf[124] = lsb >> 24; | ||
329 | hd->buf[125] = lsb >> 16; | ||
330 | hd->buf[126] = lsb >> 8; | ||
331 | hd->buf[127] = lsb; | ||
332 | transform (hd, hd->buf); | ||
333 | _gcry_burn_stack (768); | ||
334 | |||
335 | p = hd->buf; | ||
336 | #ifdef WORDS_BIGENDIAN | ||
337 | #define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0) | ||
338 | #else /* little endian */ | ||
339 | #define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48; \ | ||
340 | *p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32; \ | ||
341 | *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ | ||
342 | *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while (0) | ||
343 | #endif | ||
344 | X (0); | ||
345 | X (1); | ||
346 | X (2); | ||
347 | X (3); | ||
348 | X (4); | ||
349 | X (5); | ||
350 | /* Note that these last two chunks are included even for SHA384. | ||
351 | We just ignore them. */ | ||
352 | X (6); | ||
353 | X (7); | ||
354 | #undef X | ||
355 | } | ||
356 | |||
357 | static byte * | ||
358 | sha512_read (void *context) | ||
359 | { | ||
360 | SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context; | ||
361 | return hd->buf; | ||
362 | } | ||
363 | |||
364 | static byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */ | ||
365 | { | ||
366 | 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, | ||
367 | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, | ||
368 | 0x00, 0x04, 0x40 | ||
369 | }; | ||
370 | |||
371 | static gcry_md_oid_spec_t oid_spec_sha512[] = | ||
372 | { | ||
373 | { "2.16.840.1.101.3.4.2.3" }, | ||
374 | { NULL } | ||
375 | }; | ||
376 | |||
377 | gcry_md_spec_t _gcry_digest_spec_sha512 = { | ||
378 | "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64, | ||
379 | sha512_init, sha512_write, sha512_final, sha512_read, | ||
380 | sizeof (SHA512_CONTEXT), | ||
381 | }; | ||
382 | |||
383 | static byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */ | ||
384 | { | ||
385 | 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, | ||
386 | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, | ||
387 | 0x00, 0x04, 0x30 | ||
388 | }; | ||
389 | |||
390 | static gcry_md_oid_spec_t oid_spec_sha384[] = | ||
391 | { | ||
392 | { "2.16.840.1.101.3.4.2.2" }, | ||
393 | { NULL }, | ||
394 | }; | ||
395 | |||
396 | gcry_md_spec_t _gcry_digest_spec_sha384 = { | ||
397 | "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48, | ||
398 | sha384_init, sha512_write, sha512_final, sha512_read, | ||
399 | sizeof (SHA512_CONTEXT), | ||
400 | }; | ||