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 */
23void 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
31static void
32ossl_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
50static void
51ossl_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
69static void
70ossl_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
185static int
186ossl_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
235struct 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
246struct 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