1 /* 2 * Copyright 2019-2025 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/numbers.h" 18 #include "internal/sha3.h" 19 #include "prov/digestcommon.h" 20 #include "prov/implementations.h" 21 22 #define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT 23 #define SHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT) 24 #define KMAC_FLAGS PROV_DIGEST_FLAG_XOF 25 26 /* 27 * Forward declaration of any unique methods implemented here. This is not strictly 28 * necessary for the compiler, but provides an assurance that the signatures 29 * of the functions in the dispatch table are correct. 30 */ 31 static OSSL_FUNC_digest_init_fn keccak_init; 32 static OSSL_FUNC_digest_init_fn keccak_init_params; 33 static OSSL_FUNC_digest_update_fn keccak_update; 34 static OSSL_FUNC_digest_final_fn keccak_final; 35 static OSSL_FUNC_digest_freectx_fn keccak_freectx; 36 static OSSL_FUNC_digest_copyctx_fn keccak_copyctx; 37 static OSSL_FUNC_digest_dupctx_fn keccak_dupctx; 38 static OSSL_FUNC_digest_squeeze_fn shake_squeeze; 39 static OSSL_FUNC_digest_get_ctx_params_fn shake_get_ctx_params; 40 static OSSL_FUNC_digest_gettable_ctx_params_fn shake_gettable_ctx_params; 41 static OSSL_FUNC_digest_set_ctx_params_fn shake_set_ctx_params; 42 static OSSL_FUNC_digest_settable_ctx_params_fn shake_settable_ctx_params; 43 static sha3_absorb_fn generic_sha3_absorb; 44 static sha3_final_fn generic_sha3_final; 45 static sha3_squeeze_fn generic_sha3_squeeze; 46 47 #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM) 48 /* 49 * IBM S390X support 50 */ 51 # include "s390x_arch.h" 52 # define S390_SHA3 1 53 # define S390_SHA3_CAPABLE(name) \ 54 ((OPENSSL_s390xcap_P.kimd[0] & S390X_CAPBIT(S390X_##name)) && \ 55 (OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name))) 56 57 #endif 58 59 static int keccak_init(void *vctx, ossl_unused const OSSL_PARAM params[]) 60 { 61 if (!ossl_prov_is_running()) 62 return 0; 63 /* The newctx() handles most of the ctx fixed setup. */ 64 ossl_sha3_reset((KECCAK1600_CTX *)vctx); 65 return 1; 66 } 67 68 static int keccak_init_params(void *vctx, const OSSL_PARAM params[]) 69 { 70 return keccak_init(vctx, NULL) 71 && shake_set_ctx_params(vctx, params); 72 } 73 74 static int keccak_update(void *vctx, const unsigned char *inp, size_t len) 75 { 76 KECCAK1600_CTX *ctx = vctx; 77 const size_t bsz = ctx->block_size; 78 size_t num, rem; 79 80 if (len == 0) 81 return 1; 82 83 /* Is there anything in the buffer already ? */ 84 if ((num = ctx->bufsz) != 0) { 85 /* Calculate how much space is left in the buffer */ 86 rem = bsz - num; 87 /* If the new input does not fill the buffer then just add it */ 88 if (len < rem) { 89 memcpy(ctx->buf + num, inp, len); 90 ctx->bufsz += len; 91 return 1; 92 } 93 /* otherwise fill up the buffer and absorb the buffer */ 94 memcpy(ctx->buf + num, inp, rem); 95 /* Update the input pointer */ 96 inp += rem; 97 len -= rem; 98 ctx->meth.absorb(ctx, ctx->buf, bsz); 99 ctx->bufsz = 0; 100 } 101 /* Absorb the input - rem = leftover part of the input < blocksize) */ 102 rem = ctx->meth.absorb(ctx, inp, len); 103 /* Copy the leftover bit of the input into the buffer */ 104 if (rem) { 105 memcpy(ctx->buf, inp + len - rem, rem); 106 ctx->bufsz = rem; 107 } 108 return 1; 109 } 110 111 static int keccak_final(void *vctx, unsigned char *out, size_t *outl, 112 size_t outlen) 113 { 114 int ret = 1; 115 KECCAK1600_CTX *ctx = vctx; 116 117 if (!ossl_prov_is_running()) 118 return 0; 119 if (ctx->md_size == SIZE_MAX) { 120 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); 121 return 0; 122 } 123 if (outlen > 0) 124 ret = ctx->meth.final(ctx, out, ctx->md_size); 125 126 *outl = ctx->md_size; 127 return ret; 128 } 129 130 static int shake_squeeze(void *vctx, unsigned char *out, size_t *outl, 131 size_t outlen) 132 { 133 int ret = 1; 134 KECCAK1600_CTX *ctx = vctx; 135 136 if (!ossl_prov_is_running()) 137 return 0; 138 if (ctx->meth.squeeze == NULL) 139 return 0; 140 if (outlen > 0) 141 ret = ctx->meth.squeeze(ctx, out, outlen); 142 143 *outl = outlen; 144 return ret; 145 } 146 147 /*- 148 * Generic software version of the absorb() and final(). 149 */ 150 static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len) 151 { 152 KECCAK1600_CTX *ctx = vctx; 153 154 if (!(ctx->xof_state == XOF_STATE_INIT || 155 ctx->xof_state == XOF_STATE_ABSORB)) 156 return 0; 157 ctx->xof_state = XOF_STATE_ABSORB; 158 return SHA3_absorb(ctx->A, inp, len, ctx->block_size); 159 } 160 161 static int generic_sha3_final(void *vctx, unsigned char *out, size_t outlen) 162 { 163 return ossl_sha3_final((KECCAK1600_CTX *)vctx, out, outlen); 164 } 165 166 static int generic_sha3_squeeze(void *vctx, unsigned char *out, size_t outlen) 167 { 168 return ossl_sha3_squeeze((KECCAK1600_CTX *)vctx, out, outlen); 169 } 170 171 static PROV_SHA3_METHOD sha3_generic_md = { 172 generic_sha3_absorb, 173 generic_sha3_final, 174 NULL 175 }; 176 177 static PROV_SHA3_METHOD shake_generic_md = 178 { 179 generic_sha3_absorb, 180 generic_sha3_final, 181 generic_sha3_squeeze 182 }; 183 184 #if defined(S390_SHA3) 185 186 static sha3_absorb_fn s390x_sha3_absorb; 187 static sha3_final_fn s390x_sha3_final; 188 static sha3_final_fn s390x_shake_final; 189 190 /*- 191 * The platform specific parts of the absorb() and final() for S390X. 192 */ 193 static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len) 194 { 195 KECCAK1600_CTX *ctx = vctx; 196 size_t rem = len % ctx->block_size; 197 unsigned int fc; 198 199 if (!(ctx->xof_state == XOF_STATE_INIT || 200 ctx->xof_state == XOF_STATE_ABSORB)) 201 return 0; 202 if (len - rem > 0) { 203 fc = ctx->pad; 204 fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0; 205 ctx->xof_state = XOF_STATE_ABSORB; 206 s390x_kimd(inp, len - rem, fc, ctx->A); 207 } 208 return rem; 209 } 210 211 static int s390x_sha3_final(void *vctx, unsigned char *out, size_t outlen) 212 { 213 KECCAK1600_CTX *ctx = vctx; 214 unsigned int fc; 215 216 if (!ossl_prov_is_running()) 217 return 0; 218 if (!(ctx->xof_state == XOF_STATE_INIT || 219 ctx->xof_state == XOF_STATE_ABSORB)) 220 return 0; 221 fc = ctx->pad | S390X_KLMD_DUFOP; 222 fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0; 223 ctx->xof_state = XOF_STATE_FINAL; 224 s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, fc, ctx->A); 225 memcpy(out, ctx->A, outlen); 226 return 1; 227 } 228 229 static int s390x_shake_final(void *vctx, unsigned char *out, size_t outlen) 230 { 231 KECCAK1600_CTX *ctx = vctx; 232 unsigned int fc; 233 234 if (!ossl_prov_is_running()) 235 return 0; 236 if (!(ctx->xof_state == XOF_STATE_INIT || 237 ctx->xof_state == XOF_STATE_ABSORB)) 238 return 0; 239 fc = ctx->pad | S390X_KLMD_DUFOP; 240 fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0; 241 ctx->xof_state = XOF_STATE_FINAL; 242 s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A); 243 return 1; 244 } 245 246 static int s390x_shake_squeeze(void *vctx, unsigned char *out, size_t outlen) 247 { 248 KECCAK1600_CTX *ctx = vctx; 249 unsigned int fc; 250 size_t len; 251 252 if (!ossl_prov_is_running()) 253 return 0; 254 if (ctx->xof_state == XOF_STATE_FINAL) 255 return 0; 256 /* 257 * On the first squeeze call, finish the absorb process (incl. padding). 258 */ 259 if (ctx->xof_state != XOF_STATE_SQUEEZE) { 260 fc = ctx->pad; 261 fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KLMD_NIP : 0; 262 ctx->xof_state = XOF_STATE_SQUEEZE; 263 s390x_klmd(ctx->buf, ctx->bufsz, out, outlen, fc, ctx->A); 264 ctx->bufsz = outlen % ctx->block_size; 265 /* reuse ctx->bufsz to count bytes squeezed from current sponge */ 266 return 1; 267 } 268 ctx->xof_state = XOF_STATE_SQUEEZE; 269 if (ctx->bufsz != 0) { 270 len = ctx->block_size - ctx->bufsz; 271 if (outlen < len) 272 len = outlen; 273 memcpy(out, (char *)ctx->A + ctx->bufsz, len); 274 out += len; 275 outlen -= len; 276 ctx->bufsz += len; 277 if (ctx->bufsz == ctx->block_size) 278 ctx->bufsz = 0; 279 } 280 if (outlen == 0) 281 return 1; 282 s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A); 283 ctx->bufsz = outlen % ctx->block_size; 284 285 return 1; 286 } 287 288 static int s390x_keccakc_final(void *vctx, unsigned char *out, size_t outlen, 289 int padding) 290 { 291 KECCAK1600_CTX *ctx = vctx; 292 size_t bsz = ctx->block_size; 293 size_t num = ctx->bufsz; 294 size_t needed = outlen; 295 unsigned int fc; 296 297 if (!ossl_prov_is_running()) 298 return 0; 299 if (!(ctx->xof_state == XOF_STATE_INIT || 300 ctx->xof_state == XOF_STATE_ABSORB)) 301 return 0; 302 fc = ctx->pad; 303 fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0; 304 ctx->xof_state = XOF_STATE_FINAL; 305 if (outlen == 0) 306 return 1; 307 memset(ctx->buf + num, 0, bsz - num); 308 ctx->buf[num] = padding; 309 ctx->buf[bsz - 1] |= 0x80; 310 s390x_kimd(ctx->buf, bsz, fc, ctx->A); 311 num = needed > bsz ? bsz : needed; 312 memcpy(out, ctx->A, num); 313 needed -= num; 314 if (needed > 0) 315 s390x_klmd(NULL, 0, out + bsz, needed, 316 ctx->pad | S390X_KLMD_PS | S390X_KLMD_DUFOP, ctx->A); 317 318 return 1; 319 } 320 321 static int s390x_keccak_final(void *vctx, unsigned char *out, size_t outlen) 322 { 323 return s390x_keccakc_final(vctx, out, outlen, 0x01); 324 } 325 326 static int s390x_kmac_final(void *vctx, unsigned char *out, size_t outlen) 327 { 328 return s390x_keccakc_final(vctx, out, outlen, 0x04); 329 } 330 331 static int s390x_keccakc_squeeze(void *vctx, unsigned char *out, size_t outlen, 332 int padding) 333 { 334 KECCAK1600_CTX *ctx = vctx; 335 size_t len; 336 unsigned int fc; 337 338 if (!ossl_prov_is_running()) 339 return 0; 340 if (ctx->xof_state == XOF_STATE_FINAL) 341 return 0; 342 /* 343 * On the first squeeze call, finish the absorb process 344 * by adding the trailing padding and then doing 345 * a final absorb. 346 */ 347 if (ctx->xof_state != XOF_STATE_SQUEEZE) { 348 len = ctx->block_size - ctx->bufsz; 349 memset(ctx->buf + ctx->bufsz, 0, len); 350 ctx->buf[ctx->bufsz] = padding; 351 ctx->buf[ctx->block_size - 1] |= 0x80; 352 fc = ctx->pad; 353 fc |= ctx->xof_state == XOF_STATE_INIT ? S390X_KIMD_NIP : 0; 354 s390x_kimd(ctx->buf, ctx->block_size, fc, ctx->A); 355 ctx->bufsz = 0; 356 /* reuse ctx->bufsz to count bytes squeezed from current sponge */ 357 } 358 if (ctx->bufsz != 0 || ctx->xof_state != XOF_STATE_SQUEEZE) { 359 len = ctx->block_size - ctx->bufsz; 360 if (outlen < len) 361 len = outlen; 362 memcpy(out, (char *)ctx->A + ctx->bufsz, len); 363 out += len; 364 outlen -= len; 365 ctx->bufsz += len; 366 if (ctx->bufsz == ctx->block_size) 367 ctx->bufsz = 0; 368 } 369 ctx->xof_state = XOF_STATE_SQUEEZE; 370 if (outlen == 0) 371 return 1; 372 s390x_klmd(NULL, 0, out, outlen, ctx->pad | S390X_KLMD_PS, ctx->A); 373 ctx->bufsz = outlen % ctx->block_size; 374 375 return 1; 376 } 377 378 static int s390x_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen) 379 { 380 return s390x_keccakc_squeeze(vctx, out, outlen, 0x01); 381 } 382 383 static int s390x_kmac_squeeze(void *vctx, unsigned char *out, size_t outlen) 384 { 385 return s390x_keccakc_squeeze(vctx, out, outlen, 0x04); 386 } 387 388 static PROV_SHA3_METHOD sha3_s390x_md = { 389 s390x_sha3_absorb, 390 s390x_sha3_final, 391 NULL, 392 }; 393 394 static PROV_SHA3_METHOD keccak_s390x_md = { 395 s390x_sha3_absorb, 396 s390x_keccak_final, 397 s390x_keccak_squeeze, 398 }; 399 400 static PROV_SHA3_METHOD shake_s390x_md = { 401 s390x_sha3_absorb, 402 s390x_shake_final, 403 s390x_shake_squeeze, 404 }; 405 406 static PROV_SHA3_METHOD kmac_s390x_md = { 407 s390x_sha3_absorb, 408 s390x_kmac_final, 409 s390x_kmac_squeeze, 410 }; 411 412 # define SHAKE_SET_MD(uname, typ) \ 413 if (S390_SHA3_CAPABLE(uname)) { \ 414 ctx->pad = S390X_##uname; \ 415 ctx->meth = typ##_s390x_md; \ 416 } else { \ 417 ctx->meth = shake_generic_md; \ 418 } 419 420 # define SHA3_SET_MD(uname, typ) \ 421 if (S390_SHA3_CAPABLE(uname)) { \ 422 ctx->pad = S390X_##uname; \ 423 ctx->meth = typ##_s390x_md; \ 424 } else { \ 425 ctx->meth = sha3_generic_md; \ 426 } 427 # define KMAC_SET_MD(bitlen) \ 428 if (S390_SHA3_CAPABLE(SHAKE_##bitlen)) { \ 429 ctx->pad = S390X_SHAKE_##bitlen; \ 430 ctx->meth = kmac_s390x_md; \ 431 } else { \ 432 ctx->meth = sha3_generic_md; \ 433 } 434 #elif defined(__aarch64__) && defined(KECCAK1600_ASM) 435 # include "arm_arch.h" 436 437 static sha3_absorb_fn armsha3_sha3_absorb; 438 439 size_t SHA3_absorb_cext(uint64_t A[5][5], const unsigned char *inp, size_t len, 440 size_t r); 441 /*- 442 * Hardware-assisted ARMv8.2 SHA3 extension version of the absorb() 443 */ 444 static size_t armsha3_sha3_absorb(void *vctx, const void *inp, size_t len) 445 { 446 KECCAK1600_CTX *ctx = vctx; 447 448 return SHA3_absorb_cext(ctx->A, inp, len, ctx->block_size); 449 } 450 451 static PROV_SHA3_METHOD sha3_ARMSHA3_md = { 452 armsha3_sha3_absorb, 453 generic_sha3_final 454 }; 455 static PROV_SHA3_METHOD shake_ARMSHA3_md = 456 { 457 armsha3_sha3_absorb, 458 generic_sha3_final, 459 generic_sha3_squeeze 460 }; 461 # define SHAKE_SET_MD(uname, typ) \ 462 if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \ 463 ctx->meth = shake_ARMSHA3_md; \ 464 } else { \ 465 ctx->meth = shake_generic_md; \ 466 } 467 468 # define SHA3_SET_MD(uname, typ) \ 469 if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \ 470 ctx->meth = sha3_ARMSHA3_md; \ 471 } else { \ 472 ctx->meth = sha3_generic_md; \ 473 } 474 # define KMAC_SET_MD(bitlen) \ 475 if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \ 476 ctx->meth = sha3_ARMSHA3_md; \ 477 } else { \ 478 ctx->meth = sha3_generic_md; \ 479 } 480 #else 481 # define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md; 482 # define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md; 483 # define SHAKE_SET_MD(uname, typ) ctx->meth = shake_generic_md; 484 #endif /* S390_SHA3 */ 485 486 #define SHA3_newctx(typ, uname, name, bitlen, pad) \ 487 static OSSL_FUNC_digest_newctx_fn name##_newctx; \ 488 static void *name##_newctx(void *provctx) \ 489 { \ 490 KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \ 491 : NULL; \ 492 \ 493 if (ctx == NULL) \ 494 return NULL; \ 495 ossl_sha3_init(ctx, pad, bitlen); \ 496 SHA3_SET_MD(uname, typ) \ 497 return ctx; \ 498 } 499 500 #define SHAKE_newctx(typ, uname, name, bitlen, mdlen, pad) \ 501 static OSSL_FUNC_digest_newctx_fn name##_newctx; \ 502 static void *name##_newctx(void *provctx) \ 503 { \ 504 KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\ 505 : NULL; \ 506 \ 507 if (ctx == NULL) \ 508 return NULL; \ 509 ossl_keccak_init(ctx, pad, bitlen, mdlen); \ 510 if (mdlen == 0) \ 511 ctx->md_size = SIZE_MAX; \ 512 SHAKE_SET_MD(uname, typ) \ 513 return ctx; \ 514 } 515 516 #define KMAC_newctx(uname, bitlen, pad) \ 517 static OSSL_FUNC_digest_newctx_fn uname##_newctx; \ 518 static void *uname##_newctx(void *provctx) \ 519 { \ 520 KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \ 521 : NULL; \ 522 \ 523 if (ctx == NULL) \ 524 return NULL; \ 525 ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen); \ 526 KMAC_SET_MD(bitlen) \ 527 return ctx; \ 528 } 529 530 #define PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags) \ 531 PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \ 532 const OSSL_DISPATCH ossl_##name##_functions[] = { \ 533 { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \ 534 { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update }, \ 535 { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))keccak_final }, \ 536 { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))keccak_freectx }, \ 537 { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))keccak_dupctx }, \ 538 { OSSL_FUNC_DIGEST_COPYCTX, (void (*)(void))keccak_copyctx }, \ 539 PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name) 540 541 #define PROV_FUNC_SHA3_DIGEST(name, bitlen, blksize, dgstsize, flags) \ 542 PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \ 543 { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init }, \ 544 PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END 545 546 #define PROV_FUNC_SHAKE_DIGEST(name, bitlen, blksize, dgstsize, flags) \ 547 PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \ 548 { OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))shake_squeeze }, \ 549 { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init_params }, \ 550 { OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))shake_set_ctx_params }, \ 551 { OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, \ 552 (void (*)(void))shake_settable_ctx_params }, \ 553 { OSSL_FUNC_DIGEST_GET_CTX_PARAMS, (void (*)(void))shake_get_ctx_params }, \ 554 { OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, \ 555 (void (*)(void))shake_gettable_ctx_params }, \ 556 PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END 557 558 static void keccak_freectx(void *vctx) 559 { 560 KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx; 561 562 OPENSSL_clear_free(ctx, sizeof(*ctx)); 563 } 564 565 static void keccak_copyctx(void *voutctx, void *vinctx) 566 { 567 KECCAK1600_CTX *outctx = (KECCAK1600_CTX *)voutctx; 568 KECCAK1600_CTX *inctx = (KECCAK1600_CTX *)vinctx; 569 570 *outctx = *inctx; 571 } 572 573 static void *keccak_dupctx(void *ctx) 574 { 575 KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx; 576 KECCAK1600_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret)) 577 : NULL; 578 579 if (ret != NULL) 580 *ret = *in; 581 return ret; 582 } 583 584 static const OSSL_PARAM *shake_gettable_ctx_params(ossl_unused void *ctx, 585 ossl_unused void *provctx) 586 { 587 static const OSSL_PARAM known_shake_gettable_ctx_params[] = { 588 {OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, 589 {OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, 590 OSSL_PARAM_END 591 }; 592 return known_shake_gettable_ctx_params; 593 } 594 595 static int shake_get_ctx_params(void *vctx, OSSL_PARAM params[]) 596 { 597 OSSL_PARAM *p; 598 KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx; 599 600 if (ctx == NULL) 601 return 0; 602 if (ossl_param_is_empty(params)) 603 return 1; 604 605 p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOFLEN); 606 if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) { 607 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 608 return 0; 609 } 610 /* Size is an alias of xoflen */ 611 p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE); 612 if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->md_size)) { 613 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 614 return 0; 615 } 616 return 1; 617 } 618 619 static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *ctx, 620 ossl_unused void *provctx) 621 { 622 static const OSSL_PARAM known_shake_settable_ctx_params[] = { 623 {OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, 624 {OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, 625 OSSL_PARAM_END 626 }; 627 628 return known_shake_settable_ctx_params; 629 } 630 631 static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 632 { 633 const OSSL_PARAM *p; 634 KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx; 635 636 if (ctx == NULL) 637 return 0; 638 if (ossl_param_is_empty(params)) 639 return 1; 640 641 p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN); 642 if (p == NULL) 643 p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE); 644 645 if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->md_size)) { 646 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 647 return 0; 648 } 649 return 1; 650 } 651 652 #define IMPLEMENT_SHA3_functions(bitlen) \ 653 SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, '\x06') \ 654 PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, \ 655 SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \ 656 SHA3_FLAGS) 657 658 #define IMPLEMENT_KECCAK_functions(bitlen) \ 659 SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, '\x01') \ 660 PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen, \ 661 SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \ 662 SHA3_FLAGS) 663 664 #define IMPLEMENT_SHAKE_functions(bitlen) \ 665 SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, \ 666 0 /* no default md length */, '\x1f') \ 667 PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen, \ 668 SHA3_BLOCKSIZE(bitlen), 0, \ 669 SHAKE_FLAGS) 670 671 #define IMPLEMENT_KMAC_functions(bitlen) \ 672 KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04') \ 673 PROV_FUNC_SHAKE_DIGEST(keccak_kmac_##bitlen, bitlen, \ 674 SHA3_BLOCKSIZE(bitlen), KMAC_MDSIZE(bitlen), \ 675 KMAC_FLAGS) 676 677 /* ossl_sha3_224_functions */ 678 IMPLEMENT_SHA3_functions(224) 679 /* ossl_sha3_256_functions */ 680 IMPLEMENT_SHA3_functions(256) 681 /* ossl_sha3_384_functions */ 682 IMPLEMENT_SHA3_functions(384) 683 /* ossl_sha3_512_functions */ 684 IMPLEMENT_SHA3_functions(512) 685 /* ossl_keccak_224_functions */ 686 IMPLEMENT_KECCAK_functions(224) 687 /* ossl_keccak_256_functions */ 688 IMPLEMENT_KECCAK_functions(256) 689 /* ossl_keccak_384_functions */ 690 IMPLEMENT_KECCAK_functions(384) 691 /* ossl_keccak_512_functions */ 692 IMPLEMENT_KECCAK_functions(512) 693 /* ossl_shake_128_functions */ 694 IMPLEMENT_SHAKE_functions(128) 695 /* ossl_shake_256_functions */ 696 IMPLEMENT_SHAKE_functions(256) 697 /* ossl_keccak_kmac_128_functions */ 698 IMPLEMENT_KMAC_functions(128) 699 /* ossl_keccak_kmac_256_functions */ 700 IMPLEMENT_KMAC_functions(256) 701