Line data Source code
1 : /**
2 : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : /*
25 : * Sha2 source code in public domain
26 : * */
27 :
28 : #include "SPCoreCrypto.h"
29 :
30 : namespace STAPPLER_VERSIONIZED sha256 {
31 :
32 : using sha256_state = stappler::crypto::Sha256::_Ctx;
33 :
34 : typedef uint32_t u32;
35 : typedef uint64_t u64;
36 :
37 : static const u32 K[64] = {
38 : 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
39 : 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
40 : 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
41 : 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
42 : 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
43 : 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
44 : 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
45 : 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
46 : 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
47 : 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
48 : 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
49 : 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
50 : 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
51 : };
52 :
53 1200 : static u32 sha_min(u32 x, u32 y) {
54 1200 : return x < y ? x : y;
55 : }
56 :
57 122000 : static u32 load32(const unsigned char* y) {
58 122000 : return (u32(y[0]) << 24) | (u32(y[1]) << 16) | (u32(y[2]) << 8) | (u32(y[3]) << 0);
59 : }
60 :
61 875 : static void store64(u64 x, unsigned char* y) {
62 7875 : for(int i = 0; i != 8; ++i)
63 7000 : y[i] = (x >> ((7-i) * 8)) & 255;
64 875 : }
65 :
66 7000 : static void store32(u32 x, unsigned char* y) {
67 35000 : for(int i = 0; i != 4; ++i)
68 28000 : y[i] = (x >> ((3-i) * 8)) & 255;
69 7000 : }
70 :
71 488000 : static u32 Ch(u32 x, u32 y, u32 z) { return z ^ (x & (y ^ z)); }
72 488000 : static u32 Maj(u32 x, u32 y, u32 z) { return ((x | y) & z) | (x & y); }
73 4392000 : static u32 Rot(u32 x, u32 n) { return (x >> (n & 31)) | (x << (32 - (n & 31))); }
74 732000 : static u32 Sh(u32 x, u32 n) { return x >> n; }
75 488000 : static u32 Sigma0(u32 x) { return Rot(x, 2) ^ Rot(x, 13) ^ Rot(x, 22); }
76 488000 : static u32 Sigma1(u32 x) { return Rot(x, 6) ^ Rot(x, 11) ^ Rot(x, 25); }
77 366000 : static u32 Gamma0(u32 x) { return Rot(x, 7) ^ Rot(x, 18) ^ Sh(x, 3); }
78 366000 : static u32 Gamma1(u32 x) { return Rot(x, 17) ^ Rot(x, 19) ^ Sh(x, 10); }
79 :
80 7625 : static void sha_compress(sha256_state& md, const unsigned char* buf) {
81 : u32 S[8], W[64], t0, t1, t;
82 :
83 : // Copy state into S
84 68625 : for(int i = 0; i < 8; i++)
85 61000 : S[i] = md.state[i];
86 :
87 : // Copy the state into 512-bits into W[0..15]
88 129625 : for(int i = 0; i < 16; i++)
89 122000 : W[i] = load32(buf + (4*i));
90 :
91 : // Fill W[16..63]
92 373625 : for(int i = 16; i < 64; i++)
93 366000 : W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
94 :
95 : // Compress
96 488000 : auto RND = [&](u32 a, u32 b, u32 c, u32& d, u32 e, u32 f, u32 g, u32& h, u32 i) {
97 488000 : t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];
98 488000 : t1 = Sigma0(a) + Maj(a, b, c);
99 488000 : d += t0;
100 488000 : h = t0 + t1;
101 495625 : };
102 :
103 495625 : for(int i = 0; i < 64; ++i) {
104 488000 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
105 488000 : t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
106 488000 : S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
107 : }
108 :
109 : // Feedback
110 68625 : for(int i = 0; i < 8; i++)
111 61000 : md.state[i] = md.state[i] + S[i];
112 7625 : }
113 :
114 : // Public interface
115 :
116 1100 : void sha_init(sha256_state& md) {
117 1100 : md.curlen = 0;
118 1100 : md.length = 0;
119 1100 : md.state[0] = 0x6A09E667UL;
120 1100 : md.state[1] = 0xBB67AE85UL;
121 1100 : md.state[2] = 0x3C6EF372UL;
122 1100 : md.state[3] = 0xA54FF53AUL;
123 1100 : md.state[4] = 0x510E527FUL;
124 1100 : md.state[5] = 0x9B05688CUL;
125 1100 : md.state[6] = 0x1F83D9ABUL;
126 1100 : md.state[7] = 0x5BE0CD19UL;
127 1100 : }
128 :
129 1500 : static void sha_process(sha256_state& md, const void* src, u32 inlen) {
130 1500 : const u32 block_size = sizeof(sha256_state::buf);
131 1500 : auto in = static_cast<const unsigned char*>(src);
132 :
133 9300 : while(inlen > 0) {
134 7800 : if(md.curlen == 0 && inlen >= block_size) {
135 6600 : sha_compress(md, in);
136 6600 : md.length += block_size * 8;
137 6600 : in += block_size;
138 6600 : inlen -= block_size;
139 : } else {
140 1200 : u32 n = sha_min(inlen, (block_size - md.curlen));
141 1200 : memcpy(md.buf + md.curlen, in, n);
142 1200 : md.curlen += n;
143 1200 : in += n;
144 1200 : inlen -= n;
145 :
146 1200 : if(md.curlen == block_size) {
147 150 : sha_compress(md, md.buf);
148 150 : md.length += 8*block_size;
149 150 : md.curlen = 0;
150 : }
151 : }
152 : }
153 1500 : }
154 :
155 875 : static void sha_done(sha256_state& md, void* out) {
156 : // Increase the length of the message
157 875 : md.length += md.curlen * 8;
158 :
159 : // Append the '1' bit
160 875 : md.buf[md.curlen++] = static_cast<unsigned char>(0x80);
161 :
162 : // If the length is currently above 56 bytes we append zeros then compress.
163 : // Then we can fall back to padding zeros and length encoding like normal.
164 875 : if(md.curlen > 56) {
165 0 : while(md.curlen < 64)
166 0 : md.buf[md.curlen++] = 0;
167 0 : sha_compress(md, md.buf);
168 0 : md.curlen = 0;
169 : }
170 :
171 : // Pad upto 56 bytes of zeroes
172 22100 : while(md.curlen < 56)
173 21225 : md.buf[md.curlen++] = 0;
174 :
175 : // Store length
176 875 : store64(md.length, md.buf+56);
177 875 : sha_compress(md, md.buf);
178 :
179 : // Copy output
180 7875 : for(int i = 0; i < 8; i++)
181 7000 : store32(md.state[i], static_cast<unsigned char*>(out)+(4*i));
182 875 : }
183 :
184 : }
185 :
186 : namespace STAPPLER_VERSIONIZED sha512 {
187 :
188 : using sha512_state = stappler::crypto::Sha512::_Ctx;
189 :
190 : typedef uint32_t u32;
191 : typedef uint64_t u64;
192 :
193 : static const u64 K[80] =
194 : {
195 : 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL,
196 : 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
197 : 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
198 : 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
199 : 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL,
200 : 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
201 : 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL,
202 : 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
203 : 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
204 : 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
205 : 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL,
206 : 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
207 : 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL,
208 : 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
209 : 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
210 : 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
211 : };
212 :
213 4375 : static u32 sha_min(u32 x, u32 y) {
214 4375 : return x < y ? x : y;
215 : }
216 :
217 20250 : static void store64(u64 x, unsigned char* y) {
218 182250 : for(int i = 0; i != 8; ++i)
219 162000 : y[i] = (x >> ((7-i) * 8)) & 255;
220 20250 : }
221 :
222 101600 : static u64 load64(const unsigned char* y) {
223 101600 : u64 res = 0;
224 914400 : for(int i = 0; i != 8; ++i)
225 812800 : res |= u64(y[i]) << ((7-i) * 8);
226 101600 : return res;
227 : }
228 :
229 508000 : static u64 Ch(u64 x, u64 y, u64 z) { return z ^ (x & (y ^ z)); }
230 508000 : static u64 Maj(u64 x, u64 y, u64 z) { return ((x | y) & z) | (x & y); }
231 4673600 : static u64 Rot(u64 x, u64 n) { return (x >> (n & 63)) | (x << (64 - (n & 63))); }
232 812800 : static u64 Sh(u64 x, u64 n) { return x >> n; }
233 508000 : static u64 Sigma0(u64 x) { return Rot(x, 28) ^ Rot(x, 34) ^ Rot(x, 39); }
234 508000 : static u64 Sigma1(u64 x) { return Rot(x, 14) ^ Rot(x, 18) ^ Rot(x, 41); }
235 406400 : static u64 Gamma0(u64 x) { return Rot(x, 1) ^ Rot(x, 8) ^ Sh(x, 7); }
236 406400 : static u64 Gamma1(u64 x) { return Rot(x, 19) ^ Rot(x, 61) ^ Sh(x, 6); }
237 :
238 6350 : static void sha_compress(sha512_state& md, const unsigned char *buf) {
239 : u64 S[8], W[80], t0, t1;
240 :
241 : // Copy state into S
242 57150 : for(int i = 0; i < 8; i++)
243 50800 : S[i] = md.state[i];
244 :
245 : // Copy the state into 1024-bits into W[0..15]
246 107950 : for(int i = 0; i < 16; i++)
247 101600 : W[i] = load64(buf + (8*i));
248 :
249 : // Fill W[16..79]
250 412750 : for(int i = 16; i < 80; i++)
251 406400 : W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
252 :
253 : // Compress
254 508000 : auto RND = [&](u64 a, u64 b, u64 c, u64& d, u64 e, u64 f, u64 g, u64& h, u64 i) {
255 508000 : t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];
256 508000 : t1 = Sigma0(a) + Maj(a, b, c);
257 508000 : d += t0;
258 508000 : h = t0 + t1;
259 514350 : };
260 :
261 69850 : for(int i = 0; i < 80; i += 8) {
262 63500 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
263 63500 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
264 63500 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
265 63500 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
266 63500 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
267 63500 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
268 63500 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
269 63500 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
270 : }
271 :
272 : // Feedback
273 57150 : for(int i = 0; i < 8; i++)
274 50800 : md.state[i] = md.state[i] + S[i];
275 6350 : }
276 :
277 : // Public interface
278 :
279 2350 : static void sha_init(sha512_state& md) {
280 2350 : md.curlen = 0;
281 2350 : md.length = 0;
282 2350 : md.state[0] = 0x6a09e667f3bcc908ULL;
283 2350 : md.state[1] = 0xbb67ae8584caa73bULL;
284 2350 : md.state[2] = 0x3c6ef372fe94f82bULL;
285 2350 : md.state[3] = 0xa54ff53a5f1d36f1ULL;
286 2350 : md.state[4] = 0x510e527fade682d1ULL;
287 2350 : md.state[5] = 0x9b05688c2b3e6c1fULL;
288 2350 : md.state[6] = 0x1f83d9abfb41bd6bULL;
289 2350 : md.state[7] = 0x5be0cd19137e2179ULL;
290 2350 : }
291 :
292 4775 : static void sha_process(sha512_state& md, const void* src, u32 inlen) {
293 4775 : const u32 block_size = sizeof(sha512_state::buf);
294 4775 : auto in = static_cast<const unsigned char*>(src);
295 :
296 13175 : while (inlen > 0) {
297 8400 : if(md.curlen == 0 && inlen >= block_size) {
298 4025 : sha_compress(md, in);
299 4025 : md.length += block_size * 8;
300 4025 : in += block_size;
301 4025 : inlen -= block_size;
302 : } else {
303 4375 : u32 n = sha_min(inlen, (block_size - md.curlen));
304 4375 : memcpy(md.buf + md.curlen, in, n);
305 4375 : md.curlen += n;
306 4375 : in += n;
307 4375 : inlen -= n;
308 :
309 4375 : if(md.curlen == block_size) {
310 75 : sha_compress(md, md.buf);
311 75 : md.length += 8*block_size;
312 75 : md.curlen = 0;
313 : }
314 : }
315 : }
316 4775 : }
317 :
318 2250 : static void sha_done(sha512_state& md, void *out) {
319 : // Increase the length of the message
320 2250 : md.length += md.curlen * 8ULL;
321 :
322 : // Append the '1' bit
323 2250 : md.buf[md.curlen++] = static_cast<unsigned char>(0x80);
324 :
325 : // If the length is currently above 112 bytes we append zeros then compress.
326 : // Then we can fall back to padding zeros and length encoding like normal.
327 2250 : if(md.curlen > 112) {
328 0 : while(md.curlen < 128)
329 0 : md.buf[md.curlen++] = 0;
330 0 : sha_compress(md, md.buf);
331 0 : md.curlen = 0;
332 : }
333 :
334 : // Pad upto 120 bytes of zeroes
335 : // note: that from 112 to 120 is the 64 MSB of the length. We assume that
336 : // you won't hash 2^64 bits of data... :-)
337 142400 : while(md.curlen < 120)
338 140150 : md.buf[md.curlen++] = 0;
339 :
340 : // Store length
341 2250 : store64(md.length, md.buf+120);
342 2250 : sha_compress(md, md.buf);
343 :
344 : // Copy output
345 20250 : for(int i = 0; i < 8; i++)
346 18000 : store64(md.state[i], static_cast<unsigned char*>(out)+(8*i));
347 2250 : }
348 :
349 : }
350 :
351 :
352 : namespace STAPPLER_VERSIONIZED sha1 {
353 :
354 : using Sha1 = stappler::crypto::Sha1;
355 :
356 : /* SHA f()-functions */
357 : #define f1(x,y,z) ((x & y) | (~x & z))
358 : #define f2(x,y,z) (x ^ y ^ z)
359 : #define f3(x,y,z) ((x & y) | (x & z) | (y & z))
360 : #define f4(x,y,z) (x ^ y ^ z)
361 :
362 : /* SHA constants */
363 : static constexpr uint32_t CONST1 = 0x5a827999L;
364 : static constexpr uint32_t CONST2 = 0x6ed9eba1L;
365 : static constexpr uint32_t CONST3 = 0x8f1bbcdcL;
366 : static constexpr uint32_t CONST4 = 0xca62c1d6L;
367 :
368 : static constexpr uint32_t SHA_BLOCKSIZE = 64;
369 :
370 : /* 32-bit rotate */
371 :
372 : #define ROT32(x,n) ((x << n) | (x >> (32 - n)))
373 :
374 : #define FUNC(n,i) \
375 : temp = ROT32(A,5) + f##n(B,C,D) + E + W[i] + CONST##n; \
376 : E = D; D = C; C = ROT32(B,30); B = A; A = temp
377 :
378 : /* do SHA transformation */
379 200 : static void sha_transform(stappler::crypto::Sha1::_Ctx &sha_info) {
380 : int i;
381 : uint32_t temp, A, B, C, D, E, W[80];
382 :
383 3400 : for (i = 0; i < 16; ++i) {
384 3200 : W[i] = sha_info.data[i];
385 : }
386 13000 : for (i = 16; i < 80; ++i) {
387 12800 : W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
388 :
389 12800 : W[i] = ROT32(W[i], 1);
390 : }
391 :
392 200 : A = sha_info.digest[0];
393 200 : B = sha_info.digest[1];
394 200 : C = sha_info.digest[2];
395 200 : D = sha_info.digest[3];
396 200 : E = sha_info.digest[4];
397 :
398 200 : FUNC(1, 0); FUNC(1, 1); FUNC(1, 2); FUNC(1, 3); FUNC(1, 4);
399 200 : FUNC(1, 5); FUNC(1, 6); FUNC(1, 7); FUNC(1, 8); FUNC(1, 9);
400 200 : FUNC(1,10); FUNC(1,11); FUNC(1,12); FUNC(1,13); FUNC(1,14);
401 200 : FUNC(1,15); FUNC(1,16); FUNC(1,17); FUNC(1,18); FUNC(1,19);
402 :
403 200 : FUNC(2,20); FUNC(2,21); FUNC(2,22); FUNC(2,23); FUNC(2,24);
404 200 : FUNC(2,25); FUNC(2,26); FUNC(2,27); FUNC(2,28); FUNC(2,29);
405 200 : FUNC(2,30); FUNC(2,31); FUNC(2,32); FUNC(2,33); FUNC(2,34);
406 200 : FUNC(2,35); FUNC(2,36); FUNC(2,37); FUNC(2,38); FUNC(2,39);
407 :
408 200 : FUNC(3,40); FUNC(3,41); FUNC(3,42); FUNC(3,43); FUNC(3,44);
409 200 : FUNC(3,45); FUNC(3,46); FUNC(3,47); FUNC(3,48); FUNC(3,49);
410 200 : FUNC(3,50); FUNC(3,51); FUNC(3,52); FUNC(3,53); FUNC(3,54);
411 200 : FUNC(3,55); FUNC(3,56); FUNC(3,57); FUNC(3,58); FUNC(3,59);
412 :
413 200 : FUNC(4,60); FUNC(4,61); FUNC(4,62); FUNC(4,63); FUNC(4,64);
414 200 : FUNC(4,65); FUNC(4,66); FUNC(4,67); FUNC(4,68); FUNC(4,69);
415 200 : FUNC(4,70); FUNC(4,71); FUNC(4,72); FUNC(4,73); FUNC(4,74);
416 200 : FUNC(4,75); FUNC(4,76); FUNC(4,77); FUNC(4,78); FUNC(4,79);
417 :
418 200 : sha_info.digest[0] += A;
419 200 : sha_info.digest[1] += B;
420 200 : sha_info.digest[2] += C;
421 200 : sha_info.digest[3] += D;
422 200 : sha_info.digest[4] += E;
423 200 : }
424 :
425 : /* count is the number of bytes to do an endian flip */
426 200 : static void maybe_byte_reverse(uint32_t *buffer, int count) {
427 : int i;
428 : uint8_t ct[4], *cp;
429 :
430 : /* do the swap only if it is little endian */
431 : if constexpr (stappler::Endian::Host == stappler::Endian::Little) {
432 200 : count /= sizeof(uint32_t);
433 200 : cp = reinterpret_cast<uint8_t *>(buffer);
434 3400 : for (i = 0; i < count; ++i) {
435 3200 : ct[0] = cp[0];
436 3200 : ct[1] = cp[1];
437 3200 : ct[2] = cp[2];
438 3200 : ct[3] = cp[3];
439 3200 : cp[0] = ct[3];
440 3200 : cp[1] = ct[2];
441 3200 : cp[2] = ct[1];
442 3200 : cp[3] = ct[0];
443 3200 : cp += sizeof(uint32_t);
444 : }
445 : }
446 200 : }
447 :
448 225 : void sha_init(Sha1::_Ctx &sha_info) {
449 225 : sha_info.digest[0] = 0x67452301L;
450 225 : sha_info.digest[1] = 0xefcdab89L;
451 225 : sha_info.digest[2] = 0x98badcfeL;
452 225 : sha_info.digest[3] = 0x10325476L;
453 225 : sha_info.digest[4] = 0xc3d2e1f0L;
454 225 : sha_info.count_lo = 0L;
455 225 : sha_info.count_hi = 0L;
456 225 : sha_info.local = 0;
457 225 : }
458 :
459 250 : void sha_process(Sha1::_Ctx &sha_info, const uint8_t *buffer, uint32_t count) {
460 : unsigned int i;
461 :
462 250 : if ((sha_info.count_lo + (count << 3)) < sha_info.count_lo) {
463 0 : ++sha_info.count_hi;
464 : }
465 250 : sha_info.count_lo += count << 3;
466 250 : sha_info.count_hi += count >> 29;
467 250 : if (sha_info.local) {
468 100 : i = SHA_BLOCKSIZE - sha_info.local;
469 100 : if (i > count) {
470 100 : i = count;
471 : }
472 100 : memcpy(reinterpret_cast<uint8_t *>(sha_info.data) + sha_info.local, buffer, i);
473 100 : count -= i;
474 100 : buffer += i;
475 100 : sha_info.local += i;
476 100 : if (sha_info.local == SHA_BLOCKSIZE) {
477 0 : maybe_byte_reverse(sha_info.data, SHA_BLOCKSIZE);
478 0 : sha_transform(sha_info);
479 : } else {
480 100 : return;
481 : }
482 : }
483 150 : while (count >= SHA_BLOCKSIZE) {
484 0 : memcpy(sha_info.data, buffer, SHA_BLOCKSIZE);
485 0 : buffer += SHA_BLOCKSIZE;
486 0 : count -= SHA_BLOCKSIZE;
487 0 : maybe_byte_reverse(sha_info.data, SHA_BLOCKSIZE);
488 0 : sha_transform(sha_info);
489 : }
490 150 : memcpy(sha_info.data, buffer, count);
491 150 : sha_info.local = count;
492 : }
493 :
494 150 : void sha_done(stappler::crypto::Sha1::_Ctx &sha_info, uint8_t *digest) {
495 : int count, i, j;
496 : uint32_t lo_bit_count, hi_bit_count, k;
497 :
498 150 : lo_bit_count = sha_info.count_lo;
499 150 : hi_bit_count = sha_info.count_hi;
500 150 : count = int32_t((lo_bit_count >> 3) & 0x3f);
501 150 : reinterpret_cast<uint8_t *>(sha_info.data)[count++] = 0x80;
502 150 : if (count > int(SHA_BLOCKSIZE - 8)) {
503 50 : memset(reinterpret_cast<uint8_t *>(sha_info.data) + count, 0, SHA_BLOCKSIZE - count);
504 50 : maybe_byte_reverse(sha_info.data, SHA_BLOCKSIZE);
505 50 : sha_transform(sha_info);
506 50 : memset(reinterpret_cast<uint8_t *>(sha_info.data), 0, SHA_BLOCKSIZE - 8);
507 : } else {
508 100 : memset(reinterpret_cast<uint8_t *>(sha_info.data) + count, 0,
509 100 : SHA_BLOCKSIZE - 8 - count);
510 : }
511 150 : maybe_byte_reverse(sha_info.data, SHA_BLOCKSIZE);
512 150 : sha_info.data[14] = hi_bit_count;
513 150 : sha_info.data[15] = lo_bit_count;
514 150 : sha_transform(sha_info);
515 :
516 900 : for (i = 0, j = 0; j < int(stappler::crypto::Sha1::Length); i++) {
517 750 : k = sha_info.digest[i];
518 750 : digest[j++] = uint8_t((k >> 24) & 0xff);
519 750 : digest[j++] = uint8_t((k >> 16) & 0xff);
520 750 : digest[j++] = uint8_t((k >> 8) & 0xff);
521 750 : digest[j++] = uint8_t(k & 0xff);
522 : }
523 150 : }
524 :
525 : }
526 :
527 :
528 : namespace STAPPLER_VERSIONIZED stappler::crypto {
529 :
530 25 : Sha1::Buf Sha1::make(const CoderSource &source, const StringView &salt) {
531 25 : return Sha1().update(salt.empty()?StringView(SP_SECURE_KEY):salt).update(source).final();
532 : }
533 :
534 25 : Sha1::Buf Sha1::hmac(const CoderSource &data, const CoderSource &key) {
535 : Buf ret;
536 25 : std::array<uint8_t, Length * 2> keyData = { 0 };
537 :
538 25 : Sha1 shaCtx;
539 25 : if (key.size() > Length * 2) {
540 0 : shaCtx.update(key).final(keyData.data());
541 : } else {
542 25 : memcpy(keyData.data(), key.data(), key.size());
543 : }
544 :
545 1025 : for (auto &it : keyData) {
546 1000 : it ^= HMAC_I_PAD;
547 : }
548 :
549 25 : shaCtx.init().update(keyData).update(data).final(ret.data());
550 :
551 1025 : for (auto &it : keyData) {
552 1000 : it ^= HMAC_I_PAD ^ HMAC_O_PAD;
553 : }
554 :
555 25 : shaCtx.init().update(keyData).update(ret).final(ret.data());
556 50 : return ret;
557 : }
558 :
559 125 : Sha1::Sha1() { sha1::sha_init(ctx); }
560 100 : Sha1 & Sha1::init() { sha1::sha_init(ctx); return *this; }
561 :
562 250 : Sha1 & Sha1::update(const uint8_t *ptr, size_t len) {
563 250 : if (len > 0) {
564 250 : sha1::sha_process(ctx, ptr, (uint32_t)len);
565 : }
566 250 : return *this;
567 : }
568 :
569 250 : Sha1 & Sha1::update(const CoderSource &source) {
570 250 : return update(source.data(), source.size());
571 : }
572 :
573 75 : Sha1::Buf Sha1::final() {
574 : Sha1::Buf ret;
575 75 : sha1::sha_done(ctx, ret.data());
576 75 : return ret;
577 : }
578 75 : void Sha1::final(uint8_t *buf) {
579 75 : sha1::sha_done(ctx, buf);
580 75 : }
581 :
582 700 : Sha512::Buf Sha512::make(const CoderSource &source, const StringView &salt) {
583 700 : return Sha512().update(salt.empty()?StringView(SP_SECURE_KEY):salt).update(source).final();
584 : }
585 :
586 225 : Sha512::Buf Sha512::hmac(const CoderSource &data, const CoderSource &key) {
587 : Buf ret;
588 225 : std::array<uint8_t, Length * 2> keyData = { 0 };
589 :
590 225 : Sha512 shaCtx;
591 225 : if (key.size() > Length * 2) {
592 125 : shaCtx.update(key).final(keyData.data());
593 : } else {
594 100 : memcpy(keyData.data(), key.data(), key.size());
595 : }
596 :
597 29025 : for (auto &it : keyData) {
598 28800 : it ^= HMAC_I_PAD;
599 : }
600 :
601 225 : shaCtx.init().update(keyData).update(data).final(ret.data());
602 :
603 29025 : for (auto &it : keyData) {
604 28800 : it ^= HMAC_I_PAD ^ HMAC_O_PAD;
605 : }
606 :
607 225 : shaCtx.init().update(keyData).update(ret).final(ret.data());
608 450 : return ret;
609 : }
610 :
611 1900 : Sha512::Sha512() { sha512::sha_init(ctx); }
612 450 : Sha512 & Sha512::init() { sha512::sha_init(ctx); return *this; }
613 :
614 4775 : Sha512 & Sha512::update(const uint8_t *ptr, size_t len) {
615 4775 : if (len > 0) {
616 4775 : sha512::sha_process(ctx, ptr, (uint32_t)len);
617 : }
618 4775 : return *this;
619 : }
620 :
621 4125 : Sha512 & Sha512::update(const CoderSource &source) {
622 4125 : return update(source.data(), source.size());
623 : }
624 :
625 1025 : Sha512::Buf Sha512::final() {
626 : Sha512::Buf ret;
627 1025 : sha512::sha_done(ctx, ret.data());
628 1025 : return ret;
629 : }
630 1225 : void Sha512::final(uint8_t *buf) {
631 1225 : sha512::sha_done(ctx, buf);
632 1225 : }
633 :
634 :
635 25 : Sha256::Buf Sha256::make(const CoderSource &source, const StringView &salt) {
636 25 : return Sha256().update(salt.empty()?StringView(SP_SECURE_KEY):salt).update(source).final();
637 : }
638 :
639 225 : Sha256::Buf Sha256::hmac(const CoderSource &data, const CoderSource &key) {
640 : Buf ret;
641 225 : std::array<uint8_t, Length * 2> keyData = { 0 };
642 225 : memset(keyData.data(), 0, keyData.size());
643 :
644 225 : Sha256 shaCtx;
645 225 : if (key.size() > Length * 2) {
646 125 : shaCtx.init().update(key).final(keyData.data());
647 : } else {
648 100 : memcpy(keyData.data(), key.data(), key.size());
649 : }
650 :
651 14625 : for (auto &it : keyData) {
652 14400 : it ^= HMAC_I_PAD;
653 : }
654 :
655 225 : shaCtx.init().update(keyData).update(data).final(ret.data());
656 :
657 14625 : for (auto &it : keyData) {
658 14400 : it ^= HMAC_I_PAD ^ HMAC_O_PAD;
659 : }
660 :
661 225 : shaCtx.init().update(keyData).update(ret).final(ret.data());
662 450 : return ret;
663 : }
664 :
665 525 : Sha256::Sha256() { sha256::sha_init(ctx); }
666 575 : Sha256 & Sha256::init() { sha256::sha_init(ctx); return *this; }
667 :
668 1500 : Sha256 & Sha256::update(const uint8_t *ptr, size_t len) {
669 1500 : if (len) {
670 1500 : sha256::sha_process(ctx, ptr, (uint32_t)len);
671 : }
672 1500 : return *this;
673 : }
674 :
675 1500 : Sha256 & Sha256::update(const CoderSource &source) {
676 1500 : return update(source.data(), source.size());
677 : }
678 :
679 300 : Sha256::Buf Sha256::final() {
680 : Sha256::Buf ret;
681 300 : sha256::sha_done(ctx, ret.data());
682 300 : return ret;
683 : }
684 575 : void Sha256::final(uint8_t *buf) {
685 575 : sha256::sha_done(ctx, buf);
686 575 : }
687 :
688 : }
|