xref: /freebsd/sys/crypto/openssl/ossl_sha512.c (revision 43a5ec4eb41567cc92586503212743d89686d78f)
1 /*
2  * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD$");
12 
13 #include <sys/libkern.h>
14 #include <sys/malloc.h>
15 
16 #include <opencrypto/cryptodev.h>
17 #include <opencrypto/xform_auth.h>
18 
19 #include <crypto/openssl/ossl.h>
20 #include <crypto/openssl/ossl_sha.h>
21 
22 /* sha512-x86_64.S */
23 void sha512_block_data_order(SHA512_CTX *c, const void *in, size_t num);
24 
25 /* From crypto/sha/sha512.c */
26 
27 #if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
28 # define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
29 #endif
30 
31 static void
32 ossl_sha384_init(void *c_)
33 {
34     SHA512_CTX *c = c_;
35     c->h[0] = U64(0xcbbb9d5dc1059ed8);
36     c->h[1] = U64(0x629a292a367cd507);
37     c->h[2] = U64(0x9159015a3070dd17);
38     c->h[3] = U64(0x152fecd8f70e5939);
39     c->h[4] = U64(0x67332667ffc00b31);
40     c->h[5] = U64(0x8eb44a8768581511);
41     c->h[6] = U64(0xdb0c2e0d64f98fa7);
42     c->h[7] = U64(0x47b5481dbefa4fa4);
43 
44     c->Nl = 0;
45     c->Nh = 0;
46     c->num = 0;
47     c->md_len = SHA384_DIGEST_LENGTH;
48 }
49 
50 static void
51 ossl_sha512_init(void *c_)
52 {
53     SHA512_CTX *c = c_;
54     c->h[0] = U64(0x6a09e667f3bcc908);
55     c->h[1] = U64(0xbb67ae8584caa73b);
56     c->h[2] = U64(0x3c6ef372fe94f82b);
57     c->h[3] = U64(0xa54ff53a5f1d36f1);
58     c->h[4] = U64(0x510e527fade682d1);
59     c->h[5] = U64(0x9b05688c2b3e6c1f);
60     c->h[6] = U64(0x1f83d9abfb41bd6b);
61     c->h[7] = U64(0x5be0cd19137e2179);
62 
63     c->Nl = 0;
64     c->Nh = 0;
65     c->num = 0;
66     c->md_len = SHA512_DIGEST_LENGTH;
67 }
68 
69 static void
70 ossl_sha512_final(uint8_t *md, void *c_)
71 {
72     SHA512_CTX *c = c_;
73     unsigned char *p = (unsigned char *)c->u.p;
74     size_t n = c->num;
75 
76     p[n] = 0x80;                /* There always is a room for one */
77     n++;
78     if (n > (sizeof(c->u) - 16)) {
79         memset(p + n, 0, sizeof(c->u) - n);
80         n = 0;
81         sha512_block_data_order(c, p, 1);
82     }
83 
84     memset(p + n, 0, sizeof(c->u) - 16 - n);
85 #if _BYTE_ORDER == _BIG_ENDIAN
86     c->u.d[SHA_LBLOCK - 2] = c->Nh;
87     c->u.d[SHA_LBLOCK - 1] = c->Nl;
88 #else
89     p[sizeof(c->u) - 1] = (unsigned char)(c->Nl);
90     p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8);
91     p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16);
92     p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24);
93     p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32);
94     p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40);
95     p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48);
96     p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56);
97     p[sizeof(c->u) - 9] = (unsigned char)(c->Nh);
98     p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8);
99     p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16);
100     p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24);
101     p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32);
102     p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40);
103     p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48);
104     p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56);
105 #endif
106 
107     sha512_block_data_order(c, p, 1);
108 
109     switch (c->md_len) {
110     /* Let compiler decide if it's appropriate to unroll... */
111     case SHA224_DIGEST_LENGTH:
112         for (n = 0; n < SHA224_DIGEST_LENGTH / 8; n++) {
113             SHA_LONG64 t = c->h[n];
114 
115             *(md++) = (unsigned char)(t >> 56);
116             *(md++) = (unsigned char)(t >> 48);
117             *(md++) = (unsigned char)(t >> 40);
118             *(md++) = (unsigned char)(t >> 32);
119             *(md++) = (unsigned char)(t >> 24);
120             *(md++) = (unsigned char)(t >> 16);
121             *(md++) = (unsigned char)(t >> 8);
122             *(md++) = (unsigned char)(t);
123         }
124         /*
125          * For 224 bits, there are four bytes left over that have to be
126          * processed separately.
127          */
128         {
129             SHA_LONG64 t = c->h[SHA224_DIGEST_LENGTH / 8];
130 
131             *(md++) = (unsigned char)(t >> 56);
132             *(md++) = (unsigned char)(t >> 48);
133             *(md++) = (unsigned char)(t >> 40);
134             *(md++) = (unsigned char)(t >> 32);
135         }
136         break;
137     case SHA256_DIGEST_LENGTH:
138         for (n = 0; n < SHA256_DIGEST_LENGTH / 8; n++) {
139             SHA_LONG64 t = c->h[n];
140 
141             *(md++) = (unsigned char)(t >> 56);
142             *(md++) = (unsigned char)(t >> 48);
143             *(md++) = (unsigned char)(t >> 40);
144             *(md++) = (unsigned char)(t >> 32);
145             *(md++) = (unsigned char)(t >> 24);
146             *(md++) = (unsigned char)(t >> 16);
147             *(md++) = (unsigned char)(t >> 8);
148             *(md++) = (unsigned char)(t);
149         }
150         break;
151     case SHA384_DIGEST_LENGTH:
152         for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
153             SHA_LONG64 t = c->h[n];
154 
155             *(md++) = (unsigned char)(t >> 56);
156             *(md++) = (unsigned char)(t >> 48);
157             *(md++) = (unsigned char)(t >> 40);
158             *(md++) = (unsigned char)(t >> 32);
159             *(md++) = (unsigned char)(t >> 24);
160             *(md++) = (unsigned char)(t >> 16);
161             *(md++) = (unsigned char)(t >> 8);
162             *(md++) = (unsigned char)(t);
163         }
164         break;
165     case SHA512_DIGEST_LENGTH:
166         for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
167             SHA_LONG64 t = c->h[n];
168 
169             *(md++) = (unsigned char)(t >> 56);
170             *(md++) = (unsigned char)(t >> 48);
171             *(md++) = (unsigned char)(t >> 40);
172             *(md++) = (unsigned char)(t >> 32);
173             *(md++) = (unsigned char)(t >> 24);
174             *(md++) = (unsigned char)(t >> 16);
175             *(md++) = (unsigned char)(t >> 8);
176             *(md++) = (unsigned char)(t);
177         }
178         break;
179     /* ... as well as make sure md_len is not abused. */
180     default:
181         __assert_unreachable();
182     }
183 }
184 
185 static int
186 ossl_sha512_update(void *c_, const void *_data, unsigned int len)
187 {
188     SHA512_CTX *c = c_;
189     SHA_LONG64 l;
190     unsigned char *p = c->u.p;
191     const unsigned char *data = (const unsigned char *)_data;
192 
193     if (len == 0)
194         return 0;
195 
196     l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff);
197     if (l < c->Nl)
198         c->Nh++;
199     if (sizeof(len) >= 8)
200         c->Nh += (((SHA_LONG64) len) >> 61);
201     c->Nl = l;
202 
203     if (c->num != 0) {
204         size_t n = sizeof(c->u) - c->num;
205 
206         if (len < n) {
207             memcpy(p + c->num, data, len), c->num += (unsigned int)len;
208             return 0;
209         } else {
210             memcpy(p + c->num, data, n), c->num = 0;
211             len -= n, data += n;
212             sha512_block_data_order(c, p, 1);
213         }
214     }
215 
216     if (len >= sizeof(c->u)) {
217 #ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
218         if ((size_t)data % sizeof(c->u.d[0]) != 0)
219             while (len >= sizeof(c->u))
220                 memcpy(p, data, sizeof(c->u)),
221                 sha512_block_data_order(c, p, 1),
222                 len -= sizeof(c->u), data += sizeof(c->u);
223         else
224 #endif
225             sha512_block_data_order(c, data, len / sizeof(c->u)),
226             data += len, len %= sizeof(c->u), data -= len;
227     }
228 
229     if (len != 0)
230         memcpy(p, data, len), c->num = (int)len;
231 
232     return 0;
233 }
234 
235 struct auth_hash ossl_hash_sha384 = {
236 	.type = CRYPTO_SHA2_384,
237 	.name = "OpenSSL-SHA2-384",
238 	.hashsize = SHA2_384_HASH_LEN,
239 	.ctxsize = sizeof(SHA512_CTX),
240 	.blocksize = SHA2_384_BLOCK_LEN,
241 	.Init = ossl_sha384_init,
242 	.Update = ossl_sha512_update,
243 	.Final = ossl_sha512_final,
244 };
245 
246 struct auth_hash ossl_hash_sha512 = {
247 	.type = CRYPTO_SHA2_512,
248 	.name = "OpenSSL-SHA2-512",
249 	.hashsize = SHA2_512_HASH_LEN,
250 	.ctxsize = sizeof(SHA512_CTX),
251 	.blocksize = SHA2_512_BLOCK_LEN,
252 	.Init = ossl_sha512_init,
253 	.Update = ossl_sha512_update,
254 	.Final = ossl_sha512_final,
255 };
256 
257 _Static_assert(sizeof(SHA512_CTX) <= sizeof(struct ossl_hash_context),
258     "ossl_hash_context too small");
259