blob: 85b655b876e2d6c6569de1a6da1b8176ab0085b9 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/* Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved.
2 *
3 * Licensed under the Apache License 2.0 (the "License"). You may not use
4 * this file except in compliance with the License. You can obtain a copy
5 * in the file LICENSE in the source distribution or at
6 * https://www.openssl.org/source/license.html
7 */
8
9#include <debug.h>
10#include <string.h>
11#include <sys/types.h>
12#include <trace.h>
13#include "sha512.h"
14
15#define LOCAL_TRACE 0
16
17#if defined(__aarch64__)
18#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
19
20int SHA512_Init(SHA512_CTX *c)
21{
22 c->h[0] = U64(0x6a09e667f3bcc908);
23 c->h[1] = U64(0xbb67ae8584caa73b);
24 c->h[2] = U64(0x3c6ef372fe94f82b);
25 c->h[3] = U64(0xa54ff53a5f1d36f1);
26 c->h[4] = U64(0x510e527fade682d1);
27 c->h[5] = U64(0x9b05688c2b3e6c1f);
28 c->h[6] = U64(0x1f83d9abfb41bd6b);
29 c->h[7] = U64(0x5be0cd19137e2179);
30
31 c->Nl = 0;
32 c->Nh = 0;
33 c->num = 0;
34 c->md_len = SHA512_DIGEST_LENGTH;
35 return 1;
36}
37
38void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
39
40int SHA512_Final(unsigned char *md, SHA512_CTX *c)
41{
42 unsigned char *p = (unsigned char *)c->u.p;
43 size_t n = c->num;
44
45 p[n] = 0x80; /* There always is a room for one */
46 n++;
47 if (n > (sizeof(c->u) - 16))
48 memset(p + n, 0, sizeof(c->u) - n), n = 0,
49 sha512_block_data_order(c, p, 1);
50
51 memset(p + n, 0, sizeof(c->u) - 16 - n);
52# ifdef B_ENDIAN
53 c->u.d[SHA_LBLOCK - 2] = c->Nh;
54 c->u.d[SHA_LBLOCK - 1] = c->Nl;
55# else
56 p[sizeof(c->u) - 1] = (unsigned char)(c->Nl);
57 p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8);
58 p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16);
59 p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24);
60 p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32);
61 p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40);
62 p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48);
63 p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56);
64 p[sizeof(c->u) - 9] = (unsigned char)(c->Nh);
65 p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8);
66 p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16);
67 p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24);
68 p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32);
69 p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40);
70 p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48);
71 p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56);
72# endif
73
74 sha512_block_data_order(c, p, 1);
75
76 if (md == 0)
77 return 0;
78
79 switch (c->md_len) {
80 case SHA512_DIGEST_LENGTH:
81 for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
82 SHA_LONG64 t = c->h[n];
83
84 *(md++) = (unsigned char)(t >> 56);
85 *(md++) = (unsigned char)(t >> 48);
86 *(md++) = (unsigned char)(t >> 40);
87 *(md++) = (unsigned char)(t >> 32);
88 *(md++) = (unsigned char)(t >> 24);
89 *(md++) = (unsigned char)(t >> 16);
90 *(md++) = (unsigned char)(t >> 8);
91 *(md++) = (unsigned char)(t);
92 }
93 break;
94 /* ... as well as make sure md_len is not abused. */
95 default:
96 return 0;
97 }
98
99 return 1;
100}
101
102int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
103{
104 SHA_LONG64 l;
105 unsigned char *p = c->u.p;
106 const unsigned char *data = (const unsigned char *)_data;
107
108 if (len == 0)
109 return 1;
110
111 l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff);
112 if (l < c->Nl)
113 c->Nh++;
114 if (sizeof(len) >= 8)
115 c->Nh += (((SHA_LONG64) len) >> 61);
116 c->Nl = l;
117
118 if (c->num != 0) {
119 size_t n = sizeof(c->u) - c->num;
120
121 if (len < n) {
122 memcpy(p + c->num, data, len), c->num += (unsigned int)len;
123 return 1;
124 } else {
125 memcpy(p + c->num, data, n), c->num = 0;
126 len -= n, data += n;
127 sha512_block_data_order(c, p, 1);
128 }
129 }
130
131 if (len >= sizeof(c->u)) {
132# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
133 if ((size_t)data % sizeof(c->u.d[0]) != 0)
134 while (len >= sizeof(c->u))
135 memcpy(p, data, sizeof(c->u)),
136 sha512_block_data_order(c, p, 1),
137 len -= sizeof(c->u), data += sizeof(c->u);
138 else
139# endif
140 sha512_block_data_order(c, data, len / sizeof(c->u)),
141 data += len, len %= sizeof(c->u), data -= len;
142 }
143
144 if (len != 0)
145 memcpy(p, data, len), c->num = (int)len;
146
147 return 1;
148}
149
150
151void SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
152{
153# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
154 if ((size_t)data % sizeof(c->u.d[0]) != 0)
155 memcpy(c->u.p, data, sizeof(c->u.p)), data = c->u.p;
156# endif
157 sha512_block_data_order(c, data, 1);
158}
159
160unsigned char *SHA512(const void *d, size_t n, unsigned char *md)
161{
162 SHA512_CTX c;
163 static unsigned char m[SHA512_DIGEST_LENGTH];
164
165 if (md == NULL)
166 md = m;
167 SHA512_Init(&c);
168 SHA512_Update(&c, d, n);
169 SHA512_Final(md, &c);
170 return (md);
171}
172int sha512_hash(const void *input, int len, u8 *output)
173{
174 SHA512_CTX s_ctx;
175 memset((void *)&s_ctx, 0, sizeof(s_ctx));
176 SHA512_Init(&s_ctx);
177 SHA512_Update(&s_ctx,input,len);
178 SHA512_Final(output,&s_ctx);
179 return 0;
180}
181#elif defined(__arm__)
182
183int SHA512_Init(SHA512_CTX *c)
184{
185 PANIC_UNIMPLEMENTED;
186 return -1;
187}
188int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
189{
190 PANIC_UNIMPLEMENTED;
191 return -1;
192}
193int SHA512_Final(unsigned char *md, SHA512_CTX *c)
194{
195 PANIC_UNIMPLEMENTED;
196 return -1;
197}
198int sha512_hash(const void *input, int len, u8 *output)
199{
200 PANIC_UNIMPLEMENTED;
201 return -1;
202}
203#endif
204
205#define SHA512_ASM
206#if 0
207# ifndef SHA512_ASM
208static const SHA_LONG64 K512[80] = {
209 U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
210 U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
211 U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
212 U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
213 U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
214 U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
215 U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
216 U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
217 U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
218 U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
219 U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
220 U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
221 U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
222 U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
223 U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
224 U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
225 U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
226 U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
227 U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
228 U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
229 U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
230 U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
231 U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
232 U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
233 U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
234 U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
235 U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
236 U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
237 U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
238 U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
239 U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
240 U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
241 U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
242 U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
243 U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
244 U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
245 U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
246 U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
247 U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
248 U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817)
249};
250
251# ifndef PEDANTIC
252# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
253# if defined(__x86_64) || defined(__x86_64__)
254# define ROTR(a,n) ({ SHA_LONG64 ret; \
255 asm ("rorq %1,%0" \
256 : "=r"(ret) \
257 : "J"(n),"0"(a) \
258 : "cc"); ret; })
259# if !defined(B_ENDIAN)
260# define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x))); \
261 asm ("bswapq %0" \
262 : "=r"(ret) \
263 : "0"(ret)); ret; })
264# endif
265# elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN)
266
267# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
268 unsigned int hi=p[0],lo=p[1]; \
269 asm ("bswapl %0; bswapl %1;" \
270 : "=r"(lo),"=r"(hi) \
271 : "0"(lo),"1"(hi)); \
272 ((SHA_LONG64)hi)<<32|lo; })
273# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
274# define ROTR(a,n) ({ SHA_LONG64 ret; \
275 asm ("rotrdi %0,%1,%2" \
276 : "=r"(ret) \
277 : "r"(a),"K"(n)); ret; })
278# elif defined(__aarch64__)
279# define ROTR(a,n) ({ SHA_LONG64 ret; \
280 asm ("ror %0,%1,%2" \
281 : "=r"(ret) \
282 : "r"(a),"I"(n)); ret; })
283# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
284 __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
285# define PULL64(x) ({ SHA_LONG64 ret; \
286 asm ("rev %0,%1" \
287 : "=r"(ret) \
288 : "r"(*((const SHA_LONG64 *)(&(x))))); ret; })
289# endif
290# endif
291# elif defined(_MSC_VER)
292# define ROTR(a,n) _rotr64((a),n)
293# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
294static SHA_LONG64 __fastcall __pull64be(const void *x)
295{
296 _asm mov edx,[ecx + 0]
297 _asm mov eax,[ecx + 4]
298 _asm bswap edx _asm bswap eax
299}
300# define PULL64(x) __pull64be(&(x))
301# if _MSC_VER<=1200
302# pragma inline_depth(0)
303# endif
304# endif
305# endif
306# endif
307# ifndef PULL64
308# define B(x,j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8))
309# define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
310# endif
311# ifndef ROTR
312# define ROTR(x,s) (((x)>>s) | (x)<<(64-s))
313# endif
314# define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
315# define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
316# define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
317# define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
318# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
319# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
320# if defined(__i386) || defined(__i386__) || defined(_M_IX86)
321/*
322 * This code should give better results on 32-bit CPU with less than
323 * ~24 registers, both size and performance wise...
324 */
325
326# elif defined(OPENSSL_SMALL_FOOTPRINT)
327
328# else
329# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \
330 T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \
331 h = Sigma0(a) + Maj(a,b,c); \
332 d += T1; h += T1; } while (0)
333# define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \
334 s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \
335 s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \
336 T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \
337 ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0)
338
339# endif
340
341# endif /* SHA512_ASM */
342#endif