1 /**********************************************************************
2 Copyright(c) 2011-2016 Intel Corporation All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
31 #include "sha512_mb.h"
32 #include "memcpy_inline.h"
33 #include "endian_helper.h"
37 #define inline __inline
40 /* From the FIPS, these are the same as for SHA256, but operating on 64 bit words
43 #define ch(e,f,g) ((e & f) ^ (g & ~e))
44 #define maj(a,b,c) ((a & b) ^ (a & c) ^ (b & c))
46 /* Sigma functions have same form as SHA256 but
47 * - change the word size to 64bit
48 * - change the amount to rotate
50 #define ror64(x, r) (((x)>>(r)) ^ ((x)<<(64-(r))))
52 /* Technically, s0 should be S0 as these are "capital sigma" functions, and likewise the case
53 * of the S0 should be s0, but keep as-is to avoid confusion with the other reference functions.
55 #define s0(a) (ror64(a,28) ^ ror64(a,34) ^ ror64(a,39))
56 #define s1(e) (ror64(e,14) ^ ror64(e,18) ^ ror64(e,41))
58 #define S0(w) (ror64(w,1) ^ ror64(w,8) ^ (w >> 7))
59 #define S1(w) (ror64(w,19) ^ ror64(w,61) ^ (w >> 6))
61 #define W(x) w[(x) & 15]
63 #define step(i,a,b,c,d,e,f,g,h,k) \
64 if (i<16) W(i) = to_be64(ww[i]); \
66 W(i) = W(i-16) + S0(W(i-15)) + W(i-7) + S1(W(i-2)); \
67 t2 = s0(a) + maj(a,b,c); \
68 t1 = h + s1(e) + ch(e,f,g) + k + W(i); \
72 static void sha512_init(SHA512_HASH_CTX
* ctx
, const void *buffer
, uint32_t len
);
73 static uint32_t sha512_update(SHA512_HASH_CTX
* ctx
, const void *buffer
, uint32_t len
);
74 static void sha512_final(SHA512_HASH_CTX
* ctx
, uint32_t remain_len
);
75 static void sha512_single(const void *data
, uint64_t digest
[]);
76 static inline void hash_init_digest(SHA512_WORD_T
* digest
);
78 void sha512_ctx_mgr_init_base(SHA512_HASH_CTX_MGR
* mgr
)
82 SHA512_HASH_CTX
*sha512_ctx_mgr_submit_base(SHA512_HASH_CTX_MGR
* mgr
, SHA512_HASH_CTX
* ctx
,
83 const void *buffer
, uint32_t len
,
88 if (flags
& (~HASH_ENTIRE
)) {
89 // User should not pass anything other than FIRST, UPDATE, or LAST
90 ctx
->error
= HASH_CTX_ERROR_INVALID_FLAGS
;
94 if ((ctx
->status
& HASH_CTX_STS_PROCESSING
) && (flags
== HASH_ENTIRE
)) {
95 // Cannot submit a new entire job to a currently processing job.
96 ctx
->error
= HASH_CTX_ERROR_ALREADY_PROCESSING
;
100 if ((ctx
->status
& HASH_CTX_STS_COMPLETE
) && !(flags
& HASH_FIRST
)) {
101 // Cannot update a finished job.
102 ctx
->error
= HASH_CTX_ERROR_ALREADY_COMPLETED
;
106 if (flags
== HASH_FIRST
) {
108 sha512_init(ctx
, buffer
, len
);
109 sha512_update(ctx
, buffer
, len
);
112 if (flags
== HASH_UPDATE
) {
113 sha512_update(ctx
, buffer
, len
);
116 if (flags
== HASH_LAST
) {
117 remain_len
= sha512_update(ctx
, buffer
, len
);
118 sha512_final(ctx
, remain_len
);
121 if (flags
== HASH_ENTIRE
) {
122 sha512_init(ctx
, buffer
, len
);
123 remain_len
= sha512_update(ctx
, buffer
, len
);
124 sha512_final(ctx
, remain_len
);
130 SHA512_HASH_CTX
*sha512_ctx_mgr_flush_base(SHA512_HASH_CTX_MGR
* mgr
)
135 static void sha512_init(SHA512_HASH_CTX
* ctx
, const void *buffer
, uint32_t len
)
138 hash_init_digest(ctx
->job
.result_digest
);
140 // Reset byte counter
141 ctx
->total_length
= 0;
143 // Clear extra blocks
144 ctx
->partial_block_buffer_length
= 0;
146 // If we made it here, there were no errors during this call to submit
147 ctx
->error
= HASH_CTX_ERROR_NONE
;
149 // Mark it as processing
150 ctx
->status
= HASH_CTX_STS_PROCESSING
;
153 static uint32_t sha512_update(SHA512_HASH_CTX
* ctx
, const void *buffer
, uint32_t len
)
155 uint32_t remain_len
= len
;
156 uint64_t *digest
= ctx
->job
.result_digest
;
158 while (remain_len
>= SHA512_BLOCK_SIZE
) {
159 sha512_single(buffer
, digest
);
160 buffer
= (void *)((uint8_t *) buffer
+ SHA512_BLOCK_SIZE
);
161 remain_len
-= SHA512_BLOCK_SIZE
;
162 ctx
->total_length
+= SHA512_BLOCK_SIZE
;
164 ctx
->status
= HASH_CTX_STS_IDLE
;
165 ctx
->incoming_buffer
= buffer
;
169 static void sha512_final(SHA512_HASH_CTX
* ctx
, uint32_t remain_len
)
171 const void *buffer
= ctx
->incoming_buffer
;
172 uint32_t i
= remain_len
, j
;
173 uint8_t buf
[2 * SHA512_BLOCK_SIZE
];
174 uint64_t *digest
= ctx
->job
.result_digest
;
176 ctx
->total_length
+= i
;
177 memcpy(buf
, buffer
, i
);
179 for (j
= i
; j
< (2 * SHA512_BLOCK_SIZE
); j
++)
182 if (i
> SHA512_BLOCK_SIZE
- SHA512_PADLENGTHFIELD_SIZE
)
183 i
= 2 * SHA512_BLOCK_SIZE
;
185 i
= SHA512_BLOCK_SIZE
;
187 *(uint64_t *) (buf
+ i
- 8) = to_be64((uint64_t) ctx
->total_length
* 8);
189 sha512_single(buf
, digest
);
190 if (i
== 2 * SHA512_BLOCK_SIZE
) {
191 sha512_single(buf
+ SHA512_BLOCK_SIZE
, digest
);
194 ctx
->status
= HASH_CTX_STS_COMPLETE
;
197 void sha512_single(const void *data
, uint64_t digest
[])
199 /* Check these are all uint64_t */
200 uint64_t a
, b
, c
, d
, e
, f
, g
, h
, t1
, t2
;
202 uint64_t *ww
= (uint64_t *) data
;
213 step(0, a
, b
, c
, d
, e
, f
, g
, h
, 0x428a2f98d728ae22);
214 step(1, h
, a
, b
, c
, d
, e
, f
, g
, 0x7137449123ef65cd);
215 step(2, g
, h
, a
, b
, c
, d
, e
, f
, 0xb5c0fbcfec4d3b2f);
216 step(3, f
, g
, h
, a
, b
, c
, d
, e
, 0xe9b5dba58189dbbc);
217 step(4, e
, f
, g
, h
, a
, b
, c
, d
, 0x3956c25bf348b538);
218 step(5, d
, e
, f
, g
, h
, a
, b
, c
, 0x59f111f1b605d019);
219 step(6, c
, d
, e
, f
, g
, h
, a
, b
, 0x923f82a4af194f9b);
220 step(7, b
, c
, d
, e
, f
, g
, h
, a
, 0xab1c5ed5da6d8118);
221 step(8, a
, b
, c
, d
, e
, f
, g
, h
, 0xd807aa98a3030242);
222 step(9, h
, a
, b
, c
, d
, e
, f
, g
, 0x12835b0145706fbe);
223 step(10, g
, h
, a
, b
, c
, d
, e
, f
, 0x243185be4ee4b28c);
224 step(11, f
, g
, h
, a
, b
, c
, d
, e
, 0x550c7dc3d5ffb4e2);
225 step(12, e
, f
, g
, h
, a
, b
, c
, d
, 0x72be5d74f27b896f);
226 step(13, d
, e
, f
, g
, h
, a
, b
, c
, 0x80deb1fe3b1696b1);
227 step(14, c
, d
, e
, f
, g
, h
, a
, b
, 0x9bdc06a725c71235);
228 step(15, b
, c
, d
, e
, f
, g
, h
, a
, 0xc19bf174cf692694);
229 step(16, a
, b
, c
, d
, e
, f
, g
, h
, 0xe49b69c19ef14ad2);
230 step(17, h
, a
, b
, c
, d
, e
, f
, g
, 0xefbe4786384f25e3);
231 step(18, g
, h
, a
, b
, c
, d
, e
, f
, 0x0fc19dc68b8cd5b5);
232 step(19, f
, g
, h
, a
, b
, c
, d
, e
, 0x240ca1cc77ac9c65);
233 step(20, e
, f
, g
, h
, a
, b
, c
, d
, 0x2de92c6f592b0275);
234 step(21, d
, e
, f
, g
, h
, a
, b
, c
, 0x4a7484aa6ea6e483);
235 step(22, c
, d
, e
, f
, g
, h
, a
, b
, 0x5cb0a9dcbd41fbd4);
236 step(23, b
, c
, d
, e
, f
, g
, h
, a
, 0x76f988da831153b5);
237 step(24, a
, b
, c
, d
, e
, f
, g
, h
, 0x983e5152ee66dfab);
238 step(25, h
, a
, b
, c
, d
, e
, f
, g
, 0xa831c66d2db43210);
239 step(26, g
, h
, a
, b
, c
, d
, e
, f
, 0xb00327c898fb213f);
240 step(27, f
, g
, h
, a
, b
, c
, d
, e
, 0xbf597fc7beef0ee4);
241 step(28, e
, f
, g
, h
, a
, b
, c
, d
, 0xc6e00bf33da88fc2);
242 step(29, d
, e
, f
, g
, h
, a
, b
, c
, 0xd5a79147930aa725);
243 step(30, c
, d
, e
, f
, g
, h
, a
, b
, 0x06ca6351e003826f);
244 step(31, b
, c
, d
, e
, f
, g
, h
, a
, 0x142929670a0e6e70);
245 step(32, a
, b
, c
, d
, e
, f
, g
, h
, 0x27b70a8546d22ffc);
246 step(33, h
, a
, b
, c
, d
, e
, f
, g
, 0x2e1b21385c26c926);
247 step(34, g
, h
, a
, b
, c
, d
, e
, f
, 0x4d2c6dfc5ac42aed);
248 step(35, f
, g
, h
, a
, b
, c
, d
, e
, 0x53380d139d95b3df);
249 step(36, e
, f
, g
, h
, a
, b
, c
, d
, 0x650a73548baf63de);
250 step(37, d
, e
, f
, g
, h
, a
, b
, c
, 0x766a0abb3c77b2a8);
251 step(38, c
, d
, e
, f
, g
, h
, a
, b
, 0x81c2c92e47edaee6);
252 step(39, b
, c
, d
, e
, f
, g
, h
, a
, 0x92722c851482353b);
253 step(40, a
, b
, c
, d
, e
, f
, g
, h
, 0xa2bfe8a14cf10364);
254 step(41, h
, a
, b
, c
, d
, e
, f
, g
, 0xa81a664bbc423001);
255 step(42, g
, h
, a
, b
, c
, d
, e
, f
, 0xc24b8b70d0f89791);
256 step(43, f
, g
, h
, a
, b
, c
, d
, e
, 0xc76c51a30654be30);
257 step(44, e
, f
, g
, h
, a
, b
, c
, d
, 0xd192e819d6ef5218);
258 step(45, d
, e
, f
, g
, h
, a
, b
, c
, 0xd69906245565a910);
259 step(46, c
, d
, e
, f
, g
, h
, a
, b
, 0xf40e35855771202a);
260 step(47, b
, c
, d
, e
, f
, g
, h
, a
, 0x106aa07032bbd1b8);
261 step(48, a
, b
, c
, d
, e
, f
, g
, h
, 0x19a4c116b8d2d0c8);
262 step(49, h
, a
, b
, c
, d
, e
, f
, g
, 0x1e376c085141ab53);
263 step(50, g
, h
, a
, b
, c
, d
, e
, f
, 0x2748774cdf8eeb99);
264 step(51, f
, g
, h
, a
, b
, c
, d
, e
, 0x34b0bcb5e19b48a8);
265 step(52, e
, f
, g
, h
, a
, b
, c
, d
, 0x391c0cb3c5c95a63);
266 step(53, d
, e
, f
, g
, h
, a
, b
, c
, 0x4ed8aa4ae3418acb);
267 step(54, c
, d
, e
, f
, g
, h
, a
, b
, 0x5b9cca4f7763e373);
268 step(55, b
, c
, d
, e
, f
, g
, h
, a
, 0x682e6ff3d6b2b8a3);
269 step(56, a
, b
, c
, d
, e
, f
, g
, h
, 0x748f82ee5defb2fc);
270 step(57, h
, a
, b
, c
, d
, e
, f
, g
, 0x78a5636f43172f60);
271 step(58, g
, h
, a
, b
, c
, d
, e
, f
, 0x84c87814a1f0ab72);
272 step(59, f
, g
, h
, a
, b
, c
, d
, e
, 0x8cc702081a6439ec);
273 step(60, e
, f
, g
, h
, a
, b
, c
, d
, 0x90befffa23631e28);
274 step(61, d
, e
, f
, g
, h
, a
, b
, c
, 0xa4506cebde82bde9);
275 step(62, c
, d
, e
, f
, g
, h
, a
, b
, 0xbef9a3f7b2c67915);
276 step(63, b
, c
, d
, e
, f
, g
, h
, a
, 0xc67178f2e372532b); // step 63
277 step(64, a
, b
, c
, d
, e
, f
, g
, h
, 0xca273eceea26619c);
278 step(65, h
, a
, b
, c
, d
, e
, f
, g
, 0xd186b8c721c0c207);
279 step(66, g
, h
, a
, b
, c
, d
, e
, f
, 0xeada7dd6cde0eb1e);
280 step(67, f
, g
, h
, a
, b
, c
, d
, e
, 0xf57d4f7fee6ed178);
281 step(68, e
, f
, g
, h
, a
, b
, c
, d
, 0x06f067aa72176fba);
282 step(69, d
, e
, f
, g
, h
, a
, b
, c
, 0x0a637dc5a2c898a6);
283 step(70, c
, d
, e
, f
, g
, h
, a
, b
, 0x113f9804bef90dae);
284 step(71, b
, c
, d
, e
, f
, g
, h
, a
, 0x1b710b35131c471b);
285 step(72, a
, b
, c
, d
, e
, f
, g
, h
, 0x28db77f523047d84);
286 step(73, h
, a
, b
, c
, d
, e
, f
, g
, 0x32caab7b40c72493);
287 step(74, g
, h
, a
, b
, c
, d
, e
, f
, 0x3c9ebe0a15c9bebc);
288 step(75, f
, g
, h
, a
, b
, c
, d
, e
, 0x431d67c49c100d4c);
289 step(76, e
, f
, g
, h
, a
, b
, c
, d
, 0x4cc5d4becb3e42b6);
290 step(77, d
, e
, f
, g
, h
, a
, b
, c
, 0x597f299cfc657e2a);
291 step(78, c
, d
, e
, f
, g
, h
, a
, b
, 0x5fcb6fab3ad6faec);
292 step(79, b
, c
, d
, e
, f
, g
, h
, a
, 0x6c44198c4a475817); // step 79
304 static inline void hash_init_digest(SHA512_WORD_T
* digest
)
306 static const SHA512_WORD_T hash_initial_digest
[SHA512_DIGEST_NWORDS
] =
307 { SHA512_INITIAL_DIGEST
};
308 memcpy_fixedlen(digest
, hash_initial_digest
, sizeof(hash_initial_digest
));
316 struct slver sha512_ctx_mgr_init_base_slver_000002f3
;
317 struct slver sha512_ctx_mgr_init_base_slver
= { 0x02f3, 0x00, 0x00 };
319 struct slver sha512_ctx_mgr_submit_base_slver_000002f4
;
320 struct slver sha512_ctx_mgr_submit_base_slver
= { 0x02f4, 0x00, 0x00 };
322 struct slver sha512_ctx_mgr_flush_base_slver_000002f5
;
323 struct slver sha512_ctx_mgr_flush_base_slver
= { 0x02f5, 0x00, 0x00 };