Line | Count | Source (jump to first uncovered line) |
1 | | /* sha512.c |
2 | | |
3 | | The sha512 hash function. |
4 | | See http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf |
5 | | |
6 | | Copyright (C) 2001, 2010 Niels Möller |
7 | | Copyright (C) 2014 Joachim Strömbergson |
8 | | |
9 | | This file is part of GNU Nettle. |
10 | | |
11 | | GNU Nettle is free software: you can redistribute it and/or |
12 | | modify it under the terms of either: |
13 | | |
14 | | * the GNU Lesser General Public License as published by the Free |
15 | | Software Foundation; either version 3 of the License, or (at your |
16 | | option) any later version. |
17 | | |
18 | | or |
19 | | |
20 | | * the GNU General Public License as published by the Free |
21 | | Software Foundation; either version 2 of the License, or (at your |
22 | | option) any later version. |
23 | | |
24 | | or both in parallel, as here. |
25 | | |
26 | | GNU Nettle is distributed in the hope that it will be useful, |
27 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
29 | | General Public License for more details. |
30 | | |
31 | | You should have received copies of the GNU General Public License and |
32 | | the GNU Lesser General Public License along with this program. If |
33 | | not, see http://www.gnu.org/licenses/. |
34 | | */ |
35 | | |
36 | | /* Modelled after the sha1.c code by Peter Gutmann. */ |
37 | | |
38 | | #if HAVE_CONFIG_H |
39 | | # include "config.h" |
40 | | #endif |
41 | | |
42 | | #include <assert.h> |
43 | | #include <stdlib.h> |
44 | | #include <string.h> |
45 | | |
46 | | #include "sha2.h" |
47 | | #include "sha2-internal.h" |
48 | | |
49 | | #include "macros.h" |
50 | | |
51 | | /* Generated by the gp script |
52 | | |
53 | | { |
54 | | print("obase=16"); |
55 | | for (i = 1,80, |
56 | | root = prime(i)^(1/3); |
57 | | fraction = root - floor(root); |
58 | | print(floor(2^64 * fraction)); |
59 | | ); |
60 | | quit(); |
61 | | } |
62 | | |
63 | | piped through |
64 | | |
65 | | |grep -v '^[' | bc \ |
66 | | |awk '{printf("0x%sULL,%s", $1, NR%3 == 0 ? "\n" : "");}' |
67 | | |
68 | | to convert it to hex. |
69 | | */ |
70 | | |
71 | | static const uint64_t |
72 | | K[80] = |
73 | | { |
74 | | 0x428A2F98D728AE22ULL,0x7137449123EF65CDULL, |
75 | | 0xB5C0FBCFEC4D3B2FULL,0xE9B5DBA58189DBBCULL, |
76 | | 0x3956C25BF348B538ULL,0x59F111F1B605D019ULL, |
77 | | 0x923F82A4AF194F9BULL,0xAB1C5ED5DA6D8118ULL, |
78 | | 0xD807AA98A3030242ULL,0x12835B0145706FBEULL, |
79 | | 0x243185BE4EE4B28CULL,0x550C7DC3D5FFB4E2ULL, |
80 | | 0x72BE5D74F27B896FULL,0x80DEB1FE3B1696B1ULL, |
81 | | 0x9BDC06A725C71235ULL,0xC19BF174CF692694ULL, |
82 | | 0xE49B69C19EF14AD2ULL,0xEFBE4786384F25E3ULL, |
83 | | 0x0FC19DC68B8CD5B5ULL,0x240CA1CC77AC9C65ULL, |
84 | | 0x2DE92C6F592B0275ULL,0x4A7484AA6EA6E483ULL, |
85 | | 0x5CB0A9DCBD41FBD4ULL,0x76F988DA831153B5ULL, |
86 | | 0x983E5152EE66DFABULL,0xA831C66D2DB43210ULL, |
87 | | 0xB00327C898FB213FULL,0xBF597FC7BEEF0EE4ULL, |
88 | | 0xC6E00BF33DA88FC2ULL,0xD5A79147930AA725ULL, |
89 | | 0x06CA6351E003826FULL,0x142929670A0E6E70ULL, |
90 | | 0x27B70A8546D22FFCULL,0x2E1B21385C26C926ULL, |
91 | | 0x4D2C6DFC5AC42AEDULL,0x53380D139D95B3DFULL, |
92 | | 0x650A73548BAF63DEULL,0x766A0ABB3C77B2A8ULL, |
93 | | 0x81C2C92E47EDAEE6ULL,0x92722C851482353BULL, |
94 | | 0xA2BFE8A14CF10364ULL,0xA81A664BBC423001ULL, |
95 | | 0xC24B8B70D0F89791ULL,0xC76C51A30654BE30ULL, |
96 | | 0xD192E819D6EF5218ULL,0xD69906245565A910ULL, |
97 | | 0xF40E35855771202AULL,0x106AA07032BBD1B8ULL, |
98 | | 0x19A4C116B8D2D0C8ULL,0x1E376C085141AB53ULL, |
99 | | 0x2748774CDF8EEB99ULL,0x34B0BCB5E19B48A8ULL, |
100 | | 0x391C0CB3C5C95A63ULL,0x4ED8AA4AE3418ACBULL, |
101 | | 0x5B9CCA4F7763E373ULL,0x682E6FF3D6B2B8A3ULL, |
102 | | 0x748F82EE5DEFB2FCULL,0x78A5636F43172F60ULL, |
103 | | 0x84C87814A1F0AB72ULL,0x8CC702081A6439ECULL, |
104 | | 0x90BEFFFA23631E28ULL,0xA4506CEBDE82BDE9ULL, |
105 | | 0xBEF9A3F7B2C67915ULL,0xC67178F2E372532BULL, |
106 | | 0xCA273ECEEA26619CULL,0xD186B8C721C0C207ULL, |
107 | | 0xEADA7DD6CDE0EB1EULL,0xF57D4F7FEE6ED178ULL, |
108 | | 0x06F067AA72176FBAULL,0x0A637DC5A2C898A6ULL, |
109 | | 0x113F9804BEF90DAEULL,0x1B710B35131C471BULL, |
110 | | 0x28DB77F523047D84ULL,0x32CAAB7B40C72493ULL, |
111 | | 0x3C9EBE0A15C9BEBCULL,0x431D67C49C100D4CULL, |
112 | | 0x4CC5D4BECB3E42B6ULL,0x597F299CFC657E2AULL, |
113 | | 0x5FCB6FAB3AD6FAECULL,0x6C44198C4A475817ULL, |
114 | | }; |
115 | | |
116 | 0 | #define COMPRESS(ctx, data) (sha512_compress((ctx)->state, (data))) |
117 | | |
118 | | void |
119 | | sha512_init(struct sha512_ctx *ctx) |
120 | 0 | { |
121 | | /* Initial values, generated by the gp script |
122 | | { |
123 | | for (i = 1,8, |
124 | | root = prime(i)^(1/2); |
125 | | fraction = root - floor(root); |
126 | | print(floor(2^64 * fraction)); |
127 | | ); |
128 | | } |
129 | | . */ |
130 | 0 | static const uint64_t H0[_SHA512_DIGEST_LENGTH] = |
131 | 0 | { |
132 | 0 | 0x6A09E667F3BCC908ULL,0xBB67AE8584CAA73BULL, |
133 | 0 | 0x3C6EF372FE94F82BULL,0xA54FF53A5F1D36F1ULL, |
134 | 0 | 0x510E527FADE682D1ULL,0x9B05688C2B3E6C1FULL, |
135 | 0 | 0x1F83D9ABFB41BD6BULL,0x5BE0CD19137E2179ULL, |
136 | 0 | }; |
137 | |
|
138 | 0 | memcpy(ctx->state, H0, sizeof(H0)); |
139 | | |
140 | | /* Initialize bit count */ |
141 | 0 | ctx->count_low = ctx->count_high = 0; |
142 | | |
143 | | /* Initialize buffer */ |
144 | 0 | ctx->index = 0; |
145 | 0 | } |
146 | | |
147 | | void |
148 | | sha512_update(struct sha512_ctx *ctx, |
149 | | size_t length, const uint8_t *data) |
150 | 0 | { |
151 | 0 | MD_UPDATE (ctx, length, data, COMPRESS, MD_INCR(ctx)); |
152 | 0 | } |
153 | | |
154 | | static void |
155 | | sha512_write_digest(struct sha512_ctx *ctx, |
156 | | size_t length, |
157 | | uint8_t *digest) |
158 | 0 | { |
159 | 0 | uint64_t high, low; |
160 | |
|
161 | 0 | unsigned i; |
162 | 0 | unsigned words; |
163 | 0 | unsigned leftover; |
164 | |
|
165 | 0 | assert(length <= SHA512_DIGEST_SIZE); |
166 | | |
167 | 0 | MD_PAD(ctx, 16, COMPRESS); |
168 | | |
169 | | /* There are 1024 = 2^10 bits in one block */ |
170 | 0 | high = (ctx->count_high << 10) | (ctx->count_low >> 54); |
171 | 0 | low = (ctx->count_low << 10) | (ctx->index << 3); |
172 | | |
173 | | /* This is slightly inefficient, as the numbers are converted to |
174 | | big-endian format, and will be converted back by the compression |
175 | | function. It's probably not worth the effort to fix this. */ |
176 | 0 | WRITE_UINT64(ctx->block + (SHA512_BLOCK_SIZE - 16), high); |
177 | 0 | WRITE_UINT64(ctx->block + (SHA512_BLOCK_SIZE - 8), low); |
178 | 0 | sha512_compress(ctx->state, ctx->block); |
179 | |
|
180 | 0 | words = length / 8; |
181 | 0 | leftover = length % 8; |
182 | |
|
183 | 0 | for (i = 0; i < words; i++, digest += 8) |
184 | 0 | WRITE_UINT64(digest, ctx->state[i]); |
185 | |
|
186 | 0 | if (leftover) |
187 | 0 | { |
188 | | /* Truncate to the right size */ |
189 | 0 | uint64_t word = ctx->state[i] >> (8*(8 - leftover)); |
190 | |
|
191 | 0 | do { |
192 | 0 | digest[--leftover] = word & 0xff; |
193 | 0 | word >>= 8; |
194 | 0 | } while (leftover); |
195 | 0 | } |
196 | 0 | } |
197 | | |
198 | | void |
199 | | sha512_digest(struct sha512_ctx *ctx, |
200 | | size_t length, |
201 | | uint8_t *digest) |
202 | 0 | { |
203 | 0 | assert(length <= SHA512_DIGEST_SIZE); |
204 | | |
205 | 0 | sha512_write_digest(ctx, length, digest); |
206 | 0 | sha512_init(ctx); |
207 | 0 | } |
208 | | |
209 | | /* sha384 variant. */ |
210 | | void |
211 | | sha384_init(struct sha512_ctx *ctx) |
212 | 0 | { |
213 | | /* Initial values, generated by the gp script |
214 | | { |
215 | | for (i = 9,16, |
216 | | root = prime(i)^(1/2); |
217 | | fraction = root - floor(root); |
218 | | print(floor(2^64 * fraction)); |
219 | | ); |
220 | | } |
221 | | . */ |
222 | 0 | static const uint64_t H0[_SHA512_DIGEST_LENGTH] = |
223 | 0 | { |
224 | 0 | 0xCBBB9D5DC1059ED8ULL, 0x629A292A367CD507ULL, |
225 | 0 | 0x9159015A3070DD17ULL, 0x152FECD8F70E5939ULL, |
226 | 0 | 0x67332667FFC00B31ULL, 0x8EB44A8768581511ULL, |
227 | 0 | 0xDB0C2E0D64F98FA7ULL, 0x47B5481DBEFA4FA4ULL, |
228 | 0 | }; |
229 | |
|
230 | 0 | memcpy(ctx->state, H0, sizeof(H0)); |
231 | | |
232 | | /* Initialize bit count */ |
233 | 0 | ctx->count_low = ctx->count_high = 0; |
234 | | |
235 | | /* Initialize buffer */ |
236 | 0 | ctx->index = 0; |
237 | 0 | } |
238 | | |
239 | | void |
240 | | sha384_digest(struct sha512_ctx *ctx, |
241 | | size_t length, |
242 | | uint8_t *digest) |
243 | 0 | { |
244 | 0 | assert(length <= SHA384_DIGEST_SIZE); |
245 | | |
246 | 0 | sha512_write_digest(ctx, length, digest); |
247 | 0 | sha384_init(ctx); |
248 | 0 | } |
249 | | |
250 | | |
251 | | /* sha-512/224 variant. */ |
252 | | void |
253 | | sha512_224_init(struct sha512_224_ctx *ctx) |
254 | 0 | { |
255 | 0 | static const uint64_t H0[_SHA512_DIGEST_LENGTH] = |
256 | 0 | { |
257 | 0 | 0x8c3d37c819544da2ULL, 0x73e1996689dcd4d6ULL, |
258 | 0 | 0x1dfab7ae32ff9c82ULL, 0x679dd514582f9fcfULL, |
259 | 0 | 0x0f6d2b697bd44da8ULL, 0x77e36f7304c48942ULL, |
260 | 0 | 0x3f9d85a86a1d36c8ULL, 0x1112e6ad91d692a1ULL, |
261 | 0 | }; |
262 | |
|
263 | 0 | memcpy(ctx->state, H0, sizeof(H0)); |
264 | | |
265 | | /* Initialize bit count */ |
266 | 0 | ctx->count_low = ctx->count_high = 0; |
267 | | |
268 | | /* Initialize buffer */ |
269 | 0 | ctx->index = 0; |
270 | 0 | } |
271 | | |
272 | | void |
273 | | sha512_224_digest(struct sha512_224_ctx *ctx, |
274 | | size_t length, |
275 | | uint8_t *digest) |
276 | 0 | { |
277 | 0 | assert(length <= SHA224_DIGEST_SIZE); |
278 | | |
279 | 0 | sha512_write_digest(ctx, length, digest); |
280 | 0 | sha512_224_init(ctx); |
281 | 0 | } |
282 | | |
283 | | |
284 | | /* sha-512/256 variant. */ |
285 | | void |
286 | | sha512_256_init(struct sha512_256_ctx *ctx) |
287 | 0 | { |
288 | 0 | static const uint64_t H0[_SHA512_DIGEST_LENGTH] = |
289 | 0 | { |
290 | 0 | 0x22312194fc2bf72cULL, 0x9f555fa3c84c64c2ULL, |
291 | 0 | 0x2393b86b6f53b151ULL, 0x963877195940eabdULL, |
292 | 0 | 0x96283ee2a88effe3ULL, 0xbe5e1e2553863992ULL, |
293 | 0 | 0x2b0199fc2c85b8aaULL, 0x0eb72ddc81c52ca2ULL, |
294 | 0 | }; |
295 | |
|
296 | 0 | memcpy(ctx->state, H0, sizeof(H0)); |
297 | | |
298 | | /* Initialize bit count */ |
299 | 0 | ctx->count_low = ctx->count_high = 0; |
300 | | |
301 | | /* Initialize buffer */ |
302 | 0 | ctx->index = 0; |
303 | 0 | } |
304 | | |
305 | | void |
306 | | sha512_256_digest(struct sha512_256_ctx *ctx, |
307 | | size_t length, |
308 | | uint8_t *digest) |
309 | 0 | { |
310 | 0 | assert(length <= SHA256_DIGEST_SIZE); |
311 | | |
312 | 0 | sha512_write_digest(ctx, length, digest); |
313 | 0 | sha512_256_init(ctx); |
314 | 0 | } |
315 | | |
316 | | void |
317 | | sha512_compress(uint64_t *state, const uint8_t *input) |
318 | 0 | { |
319 | 0 | _nettle_sha512_compress(state, input, K); |
320 | 0 | } |