1 /**********************************************************************
2 Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
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
12 distribution.
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.
16
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 **********************************************************************/
29
30 #include <string.h>
31 #include "sha512_mb.h"
32 #include "endian_helper.h"
33
34 ////////////////////////////////////////////////////////////////////////
35 ////////////////////////////////////////////////////////////////////////
36 // Reference SHA512 Functions
37 ////////////////////////////////////////////////////////////////////////
38 ////////////////////////////////////////////////////////////////////////
39
40 #define H0 0x6a09e667f3bcc908
41 #define H1 0xbb67ae8584caa73b
42 #define H2 0x3c6ef372fe94f82b
43 #define H3 0xa54ff53a5f1d36f1
44 #define H4 0x510e527fade682d1
45 #define H5 0x9b05688c2b3e6c1f
46 #define H6 0x1f83d9abfb41bd6b
47 #define H7 0x5be0cd19137e2179
48
49 void
50 sha512_single(const uint8_t *data, uint64_t digest[]);
51
52 void
sha512_ref(uint8_t * input_data,uint64_t * digest,uint32_t len)53 sha512_ref(uint8_t *input_data, uint64_t *digest, uint32_t len)
54 {
55 uint32_t i, j;
56 uint8_t buf[2 * ISAL_SHA512_BLOCK_SIZE];
57
58 /* 128 bit lengths not needed as len is uint32_t, so use 64 bit length
59 * and pad the first 64 bits with zeros. */
60
61 digest[0] = H0;
62 digest[1] = H1;
63 digest[2] = H2;
64 digest[3] = H3;
65 digest[4] = H4;
66 digest[5] = H5;
67 digest[6] = H6;
68 digest[7] = H7;
69
70 i = len;
71 /* Hash the complete blocks */
72 while (i >= ISAL_SHA512_BLOCK_SIZE) {
73 sha512_single(input_data, digest);
74 input_data += ISAL_SHA512_BLOCK_SIZE;
75 i -= ISAL_SHA512_BLOCK_SIZE;
76 }
77
78 /* Copy remainder to a buffer to be padded */
79 memcpy(buf, input_data, i);
80 buf[i++] = 0x80;
81
82 // Pad more than required here and overwrite with length
83 for (j = i; j < (2 * ISAL_SHA512_BLOCK_SIZE); j++)
84 buf[j] = 0;
85
86 if (i > ISAL_SHA512_BLOCK_SIZE - ISAL_SHA512_PADLENGTHFIELD_SIZE)
87 i = 2 * ISAL_SHA512_BLOCK_SIZE;
88 else
89 i = ISAL_SHA512_BLOCK_SIZE;
90
91 *(uint64_t *) (buf + i - 8) = to_be64((uint64_t) len * 8);
92
93 /* Hash the padded last block */
94 sha512_single(buf, digest);
95 if (i == 256)
96 sha512_single(buf + 128, digest);
97 }
98
99 /* From the FIPS, these are the same as for SHA256, but operating on 64 bit words
100 * instead of 32 bit.
101 */
102 #define ch(e, f, g) ((e & f) ^ (g & ~e))
103 #define maj(a, b, c) ((a & b) ^ (a & c) ^ (b & c))
104
105 /* Sigma functions have same form as SHA256 but
106 * - change the word size to 64bit
107 * - change the amount to rotate
108 */
109 #define ror64(x, r) (((x) >> (r)) ^ ((x) << (64 - (r))))
110
111 /* Technically, s0 should be S0 as these are "capital sigma" functions, and likewise the case
112 * of the S0 should be s0, but keep as-is to avoid confusion with the other reference functions.
113 */
114 #define s0(a) (ror64(a, 28) ^ ror64(a, 34) ^ ror64(a, 39))
115 #define s1(e) (ror64(e, 14) ^ ror64(e, 18) ^ ror64(e, 41))
116
117 #define S0(w) (ror64(w, 1) ^ ror64(w, 8) ^ (w >> 7))
118 #define S1(w) (ror64(w, 19) ^ ror64(w, 61) ^ (w >> 6))
119
120 #define W(x) w[(x) & 15]
121
122 #define step(i, a, b, c, d, e, f, g, h, k) \
123 if (i < 16) \
124 W(i) = to_be64(ww[i]); \
125 else \
126 W(i) = W(i - 16) + S0(W(i - 15)) + W(i - 7) + S1(W(i - 2)); \
127 t2 = s0(a) + maj(a, b, c); \
128 t1 = h + s1(e) + ch(e, f, g) + k + W(i); \
129 d += t1; \
130 h = t1 + t2;
131
132 void
sha512_single(const uint8_t * data,uint64_t digest[])133 sha512_single(const uint8_t *data, uint64_t digest[])
134 {
135 /* Check these are all uint64_t */
136 uint64_t a, b, c, d, e, f, g, h, t1, t2;
137 uint64_t w[16];
138 uint64_t *ww = (uint64_t *) data;
139
140 a = digest[0];
141 b = digest[1];
142 c = digest[2];
143 d = digest[3];
144 e = digest[4];
145 f = digest[5];
146 g = digest[6];
147 h = digest[7];
148
149 step(0, a, b, c, d, e, f, g, h, 0x428a2f98d728ae22);
150 step(1, h, a, b, c, d, e, f, g, 0x7137449123ef65cd);
151 step(2, g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2f);
152 step(3, f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbc);
153 step(4, e, f, g, h, a, b, c, d, 0x3956c25bf348b538);
154 step(5, d, e, f, g, h, a, b, c, 0x59f111f1b605d019);
155 step(6, c, d, e, f, g, h, a, b, 0x923f82a4af194f9b);
156 step(7, b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118);
157 step(8, a, b, c, d, e, f, g, h, 0xd807aa98a3030242);
158 step(9, h, a, b, c, d, e, f, g, 0x12835b0145706fbe);
159 step(10, g, h, a, b, c, d, e, f, 0x243185be4ee4b28c);
160 step(11, f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2);
161 step(12, e, f, g, h, a, b, c, d, 0x72be5d74f27b896f);
162 step(13, d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1);
163 step(14, c, d, e, f, g, h, a, b, 0x9bdc06a725c71235);
164 step(15, b, c, d, e, f, g, h, a, 0xc19bf174cf692694);
165 step(16, a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2);
166 step(17, h, a, b, c, d, e, f, g, 0xefbe4786384f25e3);
167 step(18, g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5);
168 step(19, f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65);
169 step(20, e, f, g, h, a, b, c, d, 0x2de92c6f592b0275);
170 step(21, d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483);
171 step(22, c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4);
172 step(23, b, c, d, e, f, g, h, a, 0x76f988da831153b5);
173 step(24, a, b, c, d, e, f, g, h, 0x983e5152ee66dfab);
174 step(25, h, a, b, c, d, e, f, g, 0xa831c66d2db43210);
175 step(26, g, h, a, b, c, d, e, f, 0xb00327c898fb213f);
176 step(27, f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4);
177 step(28, e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2);
178 step(29, d, e, f, g, h, a, b, c, 0xd5a79147930aa725);
179 step(30, c, d, e, f, g, h, a, b, 0x06ca6351e003826f);
180 step(31, b, c, d, e, f, g, h, a, 0x142929670a0e6e70);
181 step(32, a, b, c, d, e, f, g, h, 0x27b70a8546d22ffc);
182 step(33, h, a, b, c, d, e, f, g, 0x2e1b21385c26c926);
183 step(34, g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aed);
184 step(35, f, g, h, a, b, c, d, e, 0x53380d139d95b3df);
185 step(36, e, f, g, h, a, b, c, d, 0x650a73548baf63de);
186 step(37, d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8);
187 step(38, c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6);
188 step(39, b, c, d, e, f, g, h, a, 0x92722c851482353b);
189 step(40, a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364);
190 step(41, h, a, b, c, d, e, f, g, 0xa81a664bbc423001);
191 step(42, g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791);
192 step(43, f, g, h, a, b, c, d, e, 0xc76c51a30654be30);
193 step(44, e, f, g, h, a, b, c, d, 0xd192e819d6ef5218);
194 step(45, d, e, f, g, h, a, b, c, 0xd69906245565a910);
195 step(46, c, d, e, f, g, h, a, b, 0xf40e35855771202a);
196 step(47, b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8);
197 step(48, a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8);
198 step(49, h, a, b, c, d, e, f, g, 0x1e376c085141ab53);
199 step(50, g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99);
200 step(51, f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8);
201 step(52, e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63);
202 step(53, d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acb);
203 step(54, c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373);
204 step(55, b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3);
205 step(56, a, b, c, d, e, f, g, h, 0x748f82ee5defb2fc);
206 step(57, h, a, b, c, d, e, f, g, 0x78a5636f43172f60);
207 step(58, g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72);
208 step(59, f, g, h, a, b, c, d, e, 0x8cc702081a6439ec);
209 step(60, e, f, g, h, a, b, c, d, 0x90befffa23631e28);
210 step(61, d, e, f, g, h, a, b, c, 0xa4506cebde82bde9);
211 step(62, c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915);
212 step(63, b, c, d, e, f, g, h, a, 0xc67178f2e372532b); // step 63
213 step(64, a, b, c, d, e, f, g, h, 0xca273eceea26619c);
214 step(65, h, a, b, c, d, e, f, g, 0xd186b8c721c0c207);
215 step(66, g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1e);
216 step(67, f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178);
217 step(68, e, f, g, h, a, b, c, d, 0x06f067aa72176fba);
218 step(69, d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6);
219 step(70, c, d, e, f, g, h, a, b, 0x113f9804bef90dae);
220 step(71, b, c, d, e, f, g, h, a, 0x1b710b35131c471b);
221 step(72, a, b, c, d, e, f, g, h, 0x28db77f523047d84);
222 step(73, h, a, b, c, d, e, f, g, 0x32caab7b40c72493);
223 step(74, g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebc);
224 step(75, f, g, h, a, b, c, d, e, 0x431d67c49c100d4c);
225 step(76, e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6);
226 step(77, d, e, f, g, h, a, b, c, 0x597f299cfc657e2a);
227 step(78, c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faec);
228 step(79, b, c, d, e, f, g, h, a, 0x6c44198c4a475817); // step 79
229
230 digest[0] += a;
231 digest[1] += b;
232 digest[2] += c;
233 digest[3] += d;
234 digest[4] += e;
235 digest[5] += f;
236 digest[6] += g;
237 digest[7] += h;
238 }
239