f691273bafdbe64645cb92096a344a27881976b8
[openssl.git] / providers / implementations / digests / sha3_prov.c
1 /*
2  * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 <string.h>
11 #include <openssl/core_names.h>
12 #include <openssl/crypto.h>
13 #include <openssl/evp.h>
14 #include <openssl/params.h>
15 #include <openssl/err.h>
16 #include <openssl/proverr.h>
17 #include "internal/sha3.h"
18 #include "prov/digestcommon.h"
19 #include "prov/implementations.h"
20
21 #define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
22 #define SHAKE_FLAGS PROV_DIGEST_FLAG_XOF
23 #define KMAC_FLAGS PROV_DIGEST_FLAG_XOF
24
25 /*
26  * Forward declaration of any unique methods implemented here. This is not strictly
27  * necessary for the compiler, but provides an assurance that the signatures
28  * of the functions in the dispatch table are correct.
29  */
30 static OSSL_FUNC_digest_init_fn keccak_init;
31 static OSSL_FUNC_digest_init_fn keccak_init_params;
32 static OSSL_FUNC_digest_update_fn keccak_update;
33 static OSSL_FUNC_digest_final_fn keccak_final;
34 static OSSL_FUNC_digest_freectx_fn keccak_freectx;
35 static OSSL_FUNC_digest_dupctx_fn keccak_dupctx;
36 static OSSL_FUNC_digest_squeeze_fn shake_squeeze;
37 static OSSL_FUNC_digest_set_ctx_params_fn shake_set_ctx_params;
38 static OSSL_FUNC_digest_settable_ctx_params_fn shake_settable_ctx_params;
39 static sha3_absorb_fn generic_sha3_absorb;
40 static sha3_final_fn generic_sha3_final;
41 static sha3_squeeze_fn generic_sha3_squeeze;
42
43 #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)
44 /*
45  * IBM S390X support
46  */
47 # include "s390x_arch.h"
48 # define S390_SHA3 1
49 # define S390_SHA3_CAPABLE(name) \
50     ((OPENSSL_s390xcap_P.kimd[0] & S390X_CAPBIT(S390X_##name)) && \
51      (OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name)))
52
53 #endif
54
55 static int keccak_init(void *vctx, ossl_unused const OSSL_PARAM params[])
56 {
57     if (!ossl_prov_is_running())
58         return 0;
59     /* The newctx() handles most of the ctx fixed setup. */
60     ossl_sha3_reset((KECCAK1600_CTX *)vctx);
61     return 1;
62 }
63
64 static int keccak_init_params(void *vctx, const OSSL_PARAM params[])
65 {
66     return keccak_init(vctx, NULL)
67             && shake_set_ctx_params(vctx, params);
68 }
69
70 static int keccak_update(void *vctx, const unsigned char *inp, size_t len)
71 {
72     KECCAK1600_CTX *ctx = vctx;
73     const size_t bsz = ctx->block_size;
74     size_t num, rem;
75
76     if (len == 0)
77         return 1;
78
79     /* Is there anything in the buffer already ? */
80     if ((num = ctx->bufsz) != 0) {
81         /* Calculate how much space is left in the buffer */
82         rem = bsz - num;
83         /* If the new input does not fill the buffer then just add it */
84         if (len < rem) {
85             memcpy(ctx->buf + num, inp, len);
86             ctx->bufsz += len;
87             return 1;
88         }
89         /* otherwise fill up the buffer and absorb the buffer */
90         memcpy(ctx->buf + num, inp, rem);
91         /* Update the input pointer */
92         inp += rem;
93         len -= rem;
94         ctx->meth.absorb(ctx, ctx->buf, bsz);
95         ctx->bufsz = 0;
96     }
97     /* Absorb the input - rem = leftover part of the input < blocksize) */
98     rem = ctx->meth.absorb(ctx, inp, len);
99     /* Copy the leftover bit of the input into the buffer */
100     if (rem) {
101         memcpy(ctx->buf, inp + len - rem, rem);
102         ctx->bufsz = rem;
103     }
104     return 1;
105 }
106
107 static int keccak_final(void *vctx, unsigned char *out, size_t *outl,
108                         size_t outlen)
109 {
110     int ret = 1;
111     KECCAK1600_CTX *ctx = vctx;
112
113     if (!ossl_prov_is_running())
114         return 0;
115     if (outlen > 0)
116         ret = ctx->meth.final(ctx, out, ctx->md_size);
117
118     *outl = ctx->md_size;
119     return ret;
120 }
121
122 static int shake_squeeze(void *vctx, unsigned char *out, size_t *outl,
123                          size_t outlen)
124 {
125     int ret = 1;
126     KECCAK1600_CTX *ctx = vctx;
127
128     if (!ossl_prov_is_running())
129         return 0;
130     if (ctx->meth.squeeze == NULL)
131         return 0;
132     if (outlen > 0)
133         ret = ctx->meth.squeeze(ctx, out, outlen);
134
135     *outl = outlen;
136     return ret;
137 }
138
139 /*-
140  * Generic software version of the absorb() and final().
141  */
142 static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len)
143 {
144     KECCAK1600_CTX *ctx = vctx;
145
146     if (!(ctx->xof_state == XOF_STATE_INIT ||
147           ctx->xof_state == XOF_STATE_ABSORB))
148         return 0;
149     ctx->xof_state = XOF_STATE_ABSORB;
150     return SHA3_absorb(ctx->A, inp, len, ctx->block_size);
151 }
152
153 static int generic_sha3_final(void *vctx, unsigned char *out, size_t outlen)
154 {
155     return ossl_sha3_final((KECCAK1600_CTX *)vctx, out, outlen);
156 }
157
158 static int generic_sha3_squeeze(void *vctx, unsigned char *out, size_t outlen)
159 {
160     return ossl_sha3_squeeze((KECCAK1600_CTX *)vctx, out, outlen);
161 }
162
163 static PROV_SHA3_METHOD sha3_generic_md =
164 {
165     generic_sha3_absorb,
166     generic_sha3_final,
167     NULL
168 };
169
170 static PROV_SHA3_METHOD shake_generic_md =
171 {
172     generic_sha3_absorb,
173     generic_sha3_final,
174     generic_sha3_squeeze
175 };
176
177 #if defined(S390_SHA3)
178
179 static sha3_absorb_fn s390x_sha3_absorb;
180 static sha3_final_fn s390x_sha3_final;
181 static sha3_final_fn s390x_shake_final;
182
183 /*-
184  * The platform specific parts of the absorb() and final() for S390X.
185  */
186 static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len)
187 {
188     KECCAK1600_CTX *ctx = vctx;
189     size_t rem = len % ctx->block_size;
190
191     if (!(ctx->xof_state == XOF_STATE_INIT ||
192           ctx->xof_state == XOF_STATE_ABSORB))
193         return 0;
194     ctx->xof_state = XOF_STATE_ABSORB;
195     s390x_kimd(inp, len - rem, ctx->pad, ctx->A);
196     return rem;
197 }
198
199 static int s390x_sha3_final(void *vctx, unsigned char *out, size_t outlen)
200 {
201     KECCAK1600_CTX *ctx = vctx;
202
203     if (!ossl_prov_is_running())
204         return 0;
205     if (!(ctx->xof_state == XOF_STATE_INIT ||
206           ctx->xof_state == XOF_STATE_ABSORB))
207         return 0;
208     ctx->xof_state = XOF_STATE_FINAL;
209     s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, ctx->pad, ctx->A);
210     memcpy(out, ctx->A, outlen);
211     return 1;
212 }
213
214 static int s390x_shake_final(void *vctx, unsigned char *out, size_t outlen)
215 {
216     KECCAK1600_CTX *ctx = vctx;
217
218     if (!ossl_prov_is_running())
219         return 0;
220     if (!(ctx->xof_state == XOF_STATE_INIT ||
221           ctx->xof_state == XOF_STATE_ABSORB))
222         return 0;
223     ctx->xof_state = XOF_STATE_FINAL;
224     s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, ctx->pad, ctx->A);
225     return 1;
226 }
227
228 static int s390x_keccakc_final(void *vctx, unsigned char *out, size_t outlen,
229                                int padding)
230 {
231     KECCAK1600_CTX *ctx = vctx;
232     size_t bsz = ctx->block_size;
233     size_t num = ctx->bufsz;
234     size_t needed = outlen;
235
236     if (!ossl_prov_is_running())
237         return 0;
238     if (!(ctx->xof_state == XOF_STATE_INIT ||
239           ctx->xof_state == XOF_STATE_ABSORB))
240         return 0;
241     ctx->xof_state = XOF_STATE_FINAL;
242     if (outlen == 0)
243         return 1;
244     memset(ctx->buf + num, 0, bsz - num);
245     ctx->buf[num] = padding;
246     ctx->buf[bsz - 1] |= 0x80;
247     s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A);
248     num = needed > bsz ? bsz : needed;
249     memcpy(out, ctx->A, num);
250     needed -= num;
251     if (needed > 0)
252         s390x_klmd(NULL, 0, out + bsz, needed, ctx->pad | S390X_KLMD_PS, ctx->A);
253
254     return 1;
255 }
256
257 static int s390x_keccak_final(void *vctx, unsigned char *out, size_t outlen)
258 {
259     return s390x_keccakc_final(vctx, out, outlen, 0x01);
260 }
261
262 static int s390x_kmac_final(void *vctx, unsigned char *out, size_t outlen)
263 {
264     return s390x_keccakc_final(vctx, out, outlen, 0x04);
265 }
266
267 static PROV_SHA3_METHOD sha3_s390x_md =
268 {
269     s390x_sha3_absorb,
270     s390x_sha3_final
271 };
272
273 static PROV_SHA3_METHOD keccak_s390x_md =
274 {
275     s390x_sha3_absorb,
276     s390x_keccak_final,
277 };
278
279 static PROV_SHA3_METHOD shake_s390x_md =
280 {
281     s390x_sha3_absorb,
282     s390x_shake_final
283 };
284
285 static PROV_SHA3_METHOD kmac_s390x_md =
286 {
287     s390x_sha3_absorb,
288     s390x_kmac_final
289 };
290
291 # define SHAKE_SET_MD(uname, typ)                                              \
292     if (S390_SHA3_CAPABLE(uname)) {                                            \
293         ctx->pad = S390X_##uname;                                              \
294         ctx->meth = typ##_s390x_md;                                            \
295     } else {                                                                   \
296         ctx->meth = shake_generic_md;                                          \
297     }
298
299 # define SHA3_SET_MD(uname, typ)                                               \
300     if (S390_SHA3_CAPABLE(uname)) {                                            \
301         ctx->pad = S390X_##uname;                                              \
302         ctx->meth = typ##_s390x_md;                                            \
303     } else {                                                                   \
304         ctx->meth = sha3_generic_md;                                           \
305     }
306 # define KMAC_SET_MD(bitlen)                                                   \
307     if (S390_SHA3_CAPABLE(SHAKE_##bitlen)) {                                   \
308         ctx->pad = S390X_SHAKE_##bitlen;                                       \
309         ctx->meth = kmac_s390x_md;                                             \
310     } else {                                                                   \
311         ctx->meth = sha3_generic_md;                                           \
312     }
313 #elif defined(__aarch64__) && defined(KECCAK1600_ASM)
314 # include "arm_arch.h"
315
316 static sha3_absorb_fn armsha3_sha3_absorb;
317
318 size_t SHA3_absorb_cext(uint64_t A[5][5], const unsigned char *inp, size_t len,
319                         size_t r);
320 /*-
321  * Hardware-assisted ARMv8.2 SHA3 extension version of the absorb()
322  */
323 static size_t armsha3_sha3_absorb(void *vctx, const void *inp, size_t len)
324 {
325     KECCAK1600_CTX *ctx = vctx;
326
327     return SHA3_absorb_cext(ctx->A, inp, len, ctx->block_size);
328 }
329
330 static PROV_SHA3_METHOD sha3_ARMSHA3_md =
331 {
332     armsha3_sha3_absorb,
333     generic_sha3_final
334 };
335 static PROV_SHA3_METHOD shake_ARMSHA3_md =
336 {
337     armsha3_sha3_absorb,
338     generic_sha3_final,
339     generic_sha3_squeeze
340 };
341 # define SHAKE_SET_MD(uname, typ)                                              \
342     if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) {                  \
343         ctx->meth = shake_ARMSHA3_md;                                          \
344     } else {                                                                   \
345         ctx->meth = shake_generic_md;                                          \
346     }
347
348 # define SHA3_SET_MD(uname, typ)                                               \
349     if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) {                  \
350         ctx->meth = sha3_ARMSHA3_md;                                           \
351     } else {                                                                   \
352         ctx->meth = sha3_generic_md;                                           \
353     }
354 # define KMAC_SET_MD(bitlen)                                                   \
355     if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) {                  \
356         ctx->meth = sha3_ARMSHA3_md;                                           \
357     } else {                                                                   \
358         ctx->meth = sha3_generic_md;                                           \
359     }
360 #else
361 # define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;
362 # define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md;
363 # define SHAKE_SET_MD(uname, typ) ctx->meth = shake_generic_md;
364 #endif /* S390_SHA3 */
365
366 #define SHA3_newctx(typ, uname, name, bitlen, pad)                             \
367 static OSSL_FUNC_digest_newctx_fn name##_newctx;                               \
368 static void *name##_newctx(void *provctx)                                      \
369 {                                                                              \
370     KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
371                                                 : NULL;                        \
372                                                                                \
373     if (ctx == NULL)                                                           \
374         return NULL;                                                           \
375     ossl_sha3_init(ctx, pad, bitlen);                                          \
376     SHA3_SET_MD(uname, typ)                                                    \
377     return ctx;                                                                \
378 }
379
380 #define SHAKE_newctx(typ, uname, name, bitlen, pad)                            \
381 static OSSL_FUNC_digest_newctx_fn name##_newctx;                               \
382 static void *name##_newctx(void *provctx)                                      \
383 {                                                                              \
384     KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\
385                                                 : NULL;                        \
386                                                                                \
387     if (ctx == NULL)                                                           \
388         return NULL;                                                           \
389     ossl_sha3_init(ctx, pad, bitlen);                                          \
390     SHAKE_SET_MD(uname, typ)                                                   \
391     return ctx;                                                                \
392 }
393
394 #define KMAC_newctx(uname, bitlen, pad)                                        \
395 static OSSL_FUNC_digest_newctx_fn uname##_newctx;                              \
396 static void *uname##_newctx(void *provctx)                                     \
397 {                                                                              \
398     KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \
399                                                 : NULL;                        \
400                                                                                \
401     if (ctx == NULL)                                                           \
402         return NULL;                                                           \
403     ossl_keccak_kmac_init(ctx, pad, bitlen);                                   \
404     KMAC_SET_MD(bitlen)                                                        \
405     return ctx;                                                                \
406 }
407
408 #define PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags)   \
409 PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags)                     \
410 const OSSL_DISPATCH ossl_##name##_functions[] = {                              \
411     { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx },                \
412     { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update },                \
413     { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))keccak_final },                  \
414     { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))keccak_freectx },              \
415     { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))keccak_dupctx },                \
416     PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name)
417
418 #define PROV_FUNC_SHA3_DIGEST(name, bitlen, blksize, dgstsize, flags)          \
419     PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags),      \
420     { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init },                    \
421     PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
422
423 #define PROV_FUNC_SHAKE_DIGEST(name, bitlen, blksize, dgstsize, flags)         \
424     PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags),      \
425     { OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))shake_squeeze },               \
426     { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init_params },             \
427     { OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))shake_set_ctx_params }, \
428     { OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS,                                    \
429      (void (*)(void))shake_settable_ctx_params },                              \
430     PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
431
432 static void keccak_freectx(void *vctx)
433 {
434     KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
435
436     OPENSSL_clear_free(ctx,  sizeof(*ctx));
437 }
438
439 static void *keccak_dupctx(void *ctx)
440 {
441     KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx;
442     KECCAK1600_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret))
443                                                  : NULL;
444
445     if (ret != NULL)
446         *ret = *in;
447     return ret;
448 }
449
450 static const OSSL_PARAM known_shake_settable_ctx_params[] = {
451     {OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
452     OSSL_PARAM_END
453 };
454 static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *ctx,
455                                                    ossl_unused void *provctx)
456 {
457     return known_shake_settable_ctx_params;
458 }
459
460 static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[])
461 {
462     const OSSL_PARAM *p;
463     KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
464
465     if (ctx == NULL)
466         return 0;
467     if (params == NULL)
468         return 1;
469
470     p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN);
471     if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->md_size)) {
472         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
473         return 0;
474     }
475     return 1;
476 }
477
478 #define IMPLEMENT_SHA3_functions(bitlen)                                       \
479     SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, '\x06')            \
480     PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen,                               \
481                           SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen),         \
482                           SHA3_FLAGS)
483
484 #define IMPLEMENT_KECCAK_functions(bitlen)                                     \
485     SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, '\x01')      \
486     PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen,                             \
487                           SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen),         \
488                           SHA3_FLAGS)
489
490 #define IMPLEMENT_SHAKE_functions(bitlen)                                      \
491     SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, '\x1f')        \
492     PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen,                             \
493                           SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen),         \
494                           SHAKE_FLAGS)
495 #define IMPLEMENT_KMAC_functions(bitlen)                                       \
496     KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04')                          \
497     PROV_FUNC_SHAKE_DIGEST(keccak_kmac_##bitlen, bitlen,                       \
498                            SHA3_BLOCKSIZE(bitlen), KMAC_MDSIZE(bitlen),        \
499                            KMAC_FLAGS)
500
501 /* ossl_sha3_224_functions */
502 IMPLEMENT_SHA3_functions(224)
503 /* ossl_sha3_256_functions */
504 IMPLEMENT_SHA3_functions(256)
505 /* ossl_sha3_384_functions */
506 IMPLEMENT_SHA3_functions(384)
507 /* ossl_sha3_512_functions */
508 IMPLEMENT_SHA3_functions(512)
509 /* ossl_keccak_224_functions */
510 IMPLEMENT_KECCAK_functions(224)
511 /* ossl_keccak_256_functions */
512 IMPLEMENT_KECCAK_functions(256)
513 /* ossl_keccak_384_functions */
514 IMPLEMENT_KECCAK_functions(384)
515 /* ossl_keccak_512_functions */
516 IMPLEMENT_KECCAK_functions(512)
517 /* ossl_shake_128_functions */
518 IMPLEMENT_SHAKE_functions(128)
519 /* ossl_shake_256_functions */
520 IMPLEMENT_SHAKE_functions(256)
521 /* ossl_keccak_kmac_128_functions */
522 IMPLEMENT_KMAC_functions(128)
523 /* ossl_keccak_kmac_256_functions */
524 IMPLEMENT_KMAC_functions(256)