Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/hashes/sha2/sha512.c
5972 views
1
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2
*
3
* LibTomCrypt is a library that provides various cryptographic
4
* algorithms in a highly modular and flexible manner.
5
*
6
* The library is free for all purposes without any express
7
* guarantee it works.
8
*/
9
#include "tomcrypt.h"
10
11
/**
12
@param sha512.c
13
LTC_SHA512 by Tom St Denis
14
*/
15
16
#ifdef LTC_SHA512
17
18
const struct ltc_hash_descriptor sha512_desc =
19
{
20
"sha512",
21
5,
22
64,
23
128,
24
25
/* OID */
26
{ 2, 16, 840, 1, 101, 3, 4, 2, 3, },
27
9,
28
29
&sha512_init,
30
&sha512_process,
31
&sha512_done,
32
&sha512_test,
33
NULL
34
};
35
36
/* the K array */
37
static const ulong64 K[80] = {
38
CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
39
CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
40
CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
41
CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
42
CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
43
CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
44
CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
45
CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
46
CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
47
CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
48
CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
49
CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
50
CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
51
CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
52
CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
53
CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
54
CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
55
CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
56
CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
57
CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
58
CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
59
CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
60
CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
61
CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
62
CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
63
CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
64
CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
65
CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
66
CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
67
CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
68
CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
69
CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
70
CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
71
CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
72
CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
73
CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
74
CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
75
CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
76
CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
77
CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
78
};
79
80
/* Various logical functions */
81
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
82
#define Maj(x,y,z) (((x | y) & z) | (x & y))
83
#define S(x, n) ROR64c(x, n)
84
#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
85
#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
86
#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
87
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
88
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
89
90
/* compress 1024-bits */
91
#ifdef LTC_CLEAN_STACK
92
static int _sha512_compress(hash_state * md, unsigned char *buf)
93
#else
94
static int sha512_compress(hash_state * md, unsigned char *buf)
95
#endif
96
{
97
ulong64 S[8], W[80], t0, t1;
98
int i;
99
100
/* copy state into S */
101
for (i = 0; i < 8; i++) {
102
S[i] = md->sha512.state[i];
103
}
104
105
/* copy the state into 1024-bits into W[0..15] */
106
for (i = 0; i < 16; i++) {
107
LOAD64H(W[i], buf + (8*i));
108
}
109
110
/* fill W[16..79] */
111
for (i = 16; i < 80; i++) {
112
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
113
}
114
115
/* Compress */
116
#ifdef LTC_SMALL_CODE
117
for (i = 0; i < 80; i++) {
118
t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
119
t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
120
S[7] = S[6];
121
S[6] = S[5];
122
S[5] = S[4];
123
S[4] = S[3] + t0;
124
S[3] = S[2];
125
S[2] = S[1];
126
S[1] = S[0];
127
S[0] = t0 + t1;
128
}
129
#else
130
#define RND(a,b,c,d,e,f,g,h,i) \
131
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
132
t1 = Sigma0(a) + Maj(a, b, c); \
133
d += t0; \
134
h = t0 + t1;
135
136
for (i = 0; i < 80; i += 8) {
137
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
138
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
139
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
140
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
141
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
142
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
143
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
144
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
145
}
146
#endif
147
148
149
/* feedback */
150
for (i = 0; i < 8; i++) {
151
md->sha512.state[i] = md->sha512.state[i] + S[i];
152
}
153
154
return CRYPT_OK;
155
}
156
157
/* compress 1024-bits */
158
#ifdef LTC_CLEAN_STACK
159
static int sha512_compress(hash_state * md, unsigned char *buf)
160
{
161
int err;
162
err = _sha512_compress(md, buf);
163
burn_stack(sizeof(ulong64) * 90 + sizeof(int));
164
return err;
165
}
166
#endif
167
168
/**
169
Initialize the hash state
170
@param md The hash state you wish to initialize
171
@return CRYPT_OK if successful
172
*/
173
int sha512_init(hash_state * md)
174
{
175
LTC_ARGCHK(md != NULL);
176
md->sha512.curlen = 0;
177
md->sha512.length = 0;
178
md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
179
md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
180
md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
181
md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
182
md->sha512.state[4] = CONST64(0x510e527fade682d1);
183
md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
184
md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
185
md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
186
return CRYPT_OK;
187
}
188
189
/**
190
Process a block of memory though the hash
191
@param md The hash state
192
@param in The data to hash
193
@param inlen The length of the data (octets)
194
@return CRYPT_OK if successful
195
*/
196
HASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
197
198
/**
199
Terminate the hash to get the digest
200
@param md The hash state
201
@param out [out] The destination of the hash (64 bytes)
202
@return CRYPT_OK if successful
203
*/
204
int sha512_done(hash_state * md, unsigned char *out)
205
{
206
int i;
207
208
LTC_ARGCHK(md != NULL);
209
LTC_ARGCHK(out != NULL);
210
211
if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
212
return CRYPT_INVALID_ARG;
213
}
214
215
/* increase the length of the message */
216
md->sha512.length += md->sha512.curlen * CONST64(8);
217
218
/* append the '1' bit */
219
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
220
221
/* if the length is currently above 112 bytes we append zeros
222
* then compress. Then we can fall back to padding zeros and length
223
* encoding like normal.
224
*/
225
if (md->sha512.curlen > 112) {
226
while (md->sha512.curlen < 128) {
227
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
228
}
229
sha512_compress(md, md->sha512.buf);
230
md->sha512.curlen = 0;
231
}
232
233
/* pad upto 120 bytes of zeroes
234
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
235
* > 2^64 bits of data... :-)
236
*/
237
while (md->sha512.curlen < 120) {
238
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
239
}
240
241
/* store length */
242
STORE64H(md->sha512.length, md->sha512.buf+120);
243
sha512_compress(md, md->sha512.buf);
244
245
/* copy output */
246
for (i = 0; i < 8; i++) {
247
STORE64H(md->sha512.state[i], out+(8*i));
248
}
249
#ifdef LTC_CLEAN_STACK
250
zeromem(md, sizeof(hash_state));
251
#endif
252
return CRYPT_OK;
253
}
254
255
/**
256
Self-test the hash
257
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
258
*/
259
int sha512_test(void)
260
{
261
#ifndef LTC_TEST
262
return CRYPT_NOP;
263
#else
264
static const struct {
265
const char *msg;
266
unsigned char hash[64];
267
} tests[] = {
268
{ "abc",
269
{ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
270
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
271
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
272
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
273
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
274
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
275
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
276
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
277
},
278
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
279
{ 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
280
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
281
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
282
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
283
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
284
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
285
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
286
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
287
},
288
};
289
290
int i;
291
unsigned char tmp[64];
292
hash_state md;
293
294
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
295
sha512_init(&md);
296
sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
297
sha512_done(&md, tmp);
298
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA512", i)) {
299
return CRYPT_FAIL_TESTVECTOR;
300
}
301
}
302
return CRYPT_OK;
303
#endif
304
}
305
306
#endif
307
308