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