Add support for CSHAKE.
Unlike SHAKE this has default values set for the xof length. CSHAKE uses either SHAKE or KECCAK[c] depending on whether custom strings are set or not. If either string is set, it encodes the strings and uses KECCAK[c], otherwise it behaves the same as SHAKE (without the default xof length problem). Reviewed-by: Paul Dale <paul.dale@oracle.com> Reviewed-by: Norbert Pocs <norbertp@openssl.org> MergeDate: Fri Jan 23 14:07:53 2026 (Merged from https://github.com/openssl/openssl/pull/28432)
This commit is contained in:
parent
3fa6bb2333
commit
9c73843141
29 changed files with 1272 additions and 428 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -163,6 +163,7 @@ providers/implementations/digests/mdc2_prov.inc
|
|||
providers/implementations/digests/sha2_prov.inc
|
||||
providers/implementations/digests/sha3_prov.inc
|
||||
providers/implementations/digests/ml_dsa_mu_prov.inc
|
||||
providers/implementations/digests/cshake_prov.inc
|
||||
providers/implementations/include/prov/blake2_params.inc
|
||||
providers/implementations/kdfs/snmpkdf.inc
|
||||
providers/implementations/kdfs/srtpkdf.inc
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ OpenSSL 4.0
|
|||
|
||||
### Changes between 3.6 and 4.0 [xx XXX xxxx]
|
||||
|
||||
* Added CSHAKE as per [SP 800-185]
|
||||
|
||||
*Shane Lontis*
|
||||
|
||||
* Added configure options to disable KDF algorithms for
|
||||
hmac-drbg-kdf, kbkdf, krb5kdf, pvkkdf, snmpkdf, sskdf, sshkdf, x942kdf and x963kdf.
|
||||
|
||||
|
|
@ -21936,3 +21940,4 @@ ndif
|
|||
[ESV]: https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations
|
||||
[SP 800-132]: https://csrc.nist.gov/pubs/sp/800/132/final
|
||||
[SP 800-208]: https://csrc.nist.gov/pubs/sp/800/208/final
|
||||
[SP 800-185]: https://csrc.nist.gov/pubs/sp/800/185/final
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ DEPEND[]=include/openssl/asn1.h \
|
|||
providers/implementations/digests/sha2_prov.inc \
|
||||
providers/implementations/digests/sha3_prov.inc \
|
||||
providers/implementations/digests/ml_dsa_mu_prov.inc \
|
||||
providers/implementations/digests/cshake_prov.inc \
|
||||
providers/implementations/include/prov/blake2_params.inc \
|
||||
providers/implementations/macs/cmac_prov.inc \
|
||||
providers/implementations/macs/gmac_prov.inc \
|
||||
|
|
@ -242,6 +243,7 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \
|
|||
providers/implementations/digests/mdc2_prov.inc \
|
||||
providers/implementations/digests/sha2_prov.inc \
|
||||
providers/implementations/digests/sha3_prov.inc \
|
||||
providers/implementations/digests/cshake_prov.inc \
|
||||
providers/implementations/include/prov/blake2_params.inc \
|
||||
providers/implementations/macs/cmac_prov.inc \
|
||||
providers/implementations/macs/gmac_prov.inc \
|
||||
|
|
@ -257,6 +259,7 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \
|
|||
providers/implementations/rands/seed_src_jitter.inc \
|
||||
providers/implementations/rands/test_rng.inc \
|
||||
include/openssl/core_names.h]=util/perl|OpenSSL/paramnames.pm
|
||||
|
||||
GENERATE[providers/implementations/asymciphers/rsa_enc.inc]=\
|
||||
providers/implementations/asymciphers/rsa_enc.inc.in
|
||||
GENERATE[providers/implementations/asymciphers/sm2_enc.inc]=\
|
||||
|
|
@ -405,6 +408,8 @@ GENERATE[providers/implementations/digests/sha2_prov.inc]=\
|
|||
providers/implementations/digests/sha2_prov.inc.in
|
||||
GENERATE[providers/implementations/digests/sha3_prov.inc]=\
|
||||
providers/implementations/digests/sha3_prov.inc.in
|
||||
GENERATE[providers/implementations/digests/cshake_prov.inc]=\
|
||||
providers/implementations/digests/cshake_prov.inc.in
|
||||
GENERATE[providers/implementations/include/prov/blake2_params.inc]=\
|
||||
providers/implementations/include/prov/blake2_params.inc.in
|
||||
GENERATE[providers/implementations/digests/ml_dsa_mu_prov.inc]=\
|
||||
|
|
|
|||
|
|
@ -1073,6 +1073,7 @@ PROV_R_INVALID_DIGEST_LENGTH:166:invalid digest length
|
|||
PROV_R_INVALID_DIGEST_SIZE:218:invalid digest size
|
||||
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION:243:\
|
||||
invalid eddsa instance for attempted operation
|
||||
PROV_R_INVALID_FUNCTION_NAME:256:invalid function name
|
||||
PROV_R_INVALID_INPUT_LENGTH:230:invalid input length
|
||||
PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count
|
||||
PROV_R_INVALID_IV_LENGTH:109:invalid iv length
|
||||
|
|
@ -1588,23 +1589,6 @@ SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES:362:srtp could not allocate profiles
|
|||
SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG:363:\
|
||||
srtp protection profile list too long
|
||||
SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE:364:srtp unknown protection profile
|
||||
SSL_R_TLS_EXT_INVALID_MAX_FRAGMENT_LENGTH:232:\
|
||||
ssl3 ext invalid max fragment length
|
||||
SSL_R_TLS_EXT_INVALID_SERVERNAME:319:ssl3 ext invalid servername
|
||||
SSL_R_TLS_EXT_INVALID_SERVERNAME_TYPE:320:ssl3 ext invalid servername type
|
||||
SSL_R_TLS_SESSION_ID_TOO_LONG:300:ssl3 session id too long
|
||||
SSL_R_TLS_ALERT_BAD_CERTIFICATE:1042:ssl/tls alert bad certificate
|
||||
SSL_R_TLS_ALERT_BAD_RECORD_MAC:1020:ssl/tls alert bad record mac
|
||||
SSL_R_TLS_ALERT_CERTIFICATE_EXPIRED:1045:ssl/tls alert certificate expired
|
||||
SSL_R_TLS_ALERT_CERTIFICATE_REVOKED:1044:ssl/tls alert certificate revoked
|
||||
SSL_R_TLS_ALERT_CERTIFICATE_UNKNOWN:1046:ssl/tls alert certificate unknown
|
||||
SSL_R_TLS_ALERT_DECOMPRESSION_FAILURE:1030:ssl/tls alert decompression failure
|
||||
SSL_R_TLS_ALERT_HANDSHAKE_FAILURE:1040:ssl/tls alert handshake failure
|
||||
SSL_R_TLS_ALERT_ILLEGAL_PARAMETER:1047:ssl/tls alert illegal parameter
|
||||
SSL_R_TLS_ALERT_NO_CERTIFICATE:1041:ssl/tls alert no certificate
|
||||
SSL_R_TLS_ALERT_UNEXPECTED_MESSAGE:1010:ssl/tls alert unexpected message
|
||||
SSL_R_TLS_ALERT_UNSUPPORTED_CERTIFICATE:1043:\
|
||||
ssl/tls alert unsupported certificate
|
||||
SSL_R_SSL_COMMAND_SECTION_EMPTY:117:ssl command section empty
|
||||
SSL_R_SSL_COMMAND_SECTION_NOT_FOUND:125:ssl command section not found
|
||||
SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION:228:ssl ctx has no default ssl version
|
||||
|
|
@ -1649,8 +1633,25 @@ SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE:1113:\
|
|||
SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE:1111:tlsv1 certificate unobtainable
|
||||
SSL_R_TLSV1_UNRECOGNIZED_NAME:1112:tlsv1 unrecognized name
|
||||
SSL_R_TLSV1_UNSUPPORTED_EXTENSION:1110:tlsv1 unsupported extension
|
||||
SSL_R_TLS_ALERT_BAD_CERTIFICATE:1042:ssl/tls alert bad certificate
|
||||
SSL_R_TLS_ALERT_BAD_RECORD_MAC:1020:ssl/tls alert bad record mac
|
||||
SSL_R_TLS_ALERT_CERTIFICATE_EXPIRED:1045:ssl/tls alert certificate expired
|
||||
SSL_R_TLS_ALERT_CERTIFICATE_REVOKED:1044:ssl/tls alert certificate revoked
|
||||
SSL_R_TLS_ALERT_CERTIFICATE_UNKNOWN:1046:ssl/tls alert certificate unknown
|
||||
SSL_R_TLS_ALERT_DECOMPRESSION_FAILURE:1030:ssl/tls alert decompression failure
|
||||
SSL_R_TLS_ALERT_HANDSHAKE_FAILURE:1040:ssl/tls alert handshake failure
|
||||
SSL_R_TLS_ALERT_ILLEGAL_PARAMETER:1047:ssl/tls alert illegal parameter
|
||||
SSL_R_TLS_ALERT_NO_CERTIFICATE:1041:ssl/tls alert no certificate
|
||||
SSL_R_TLS_ALERT_UNEXPECTED_MESSAGE:1010:ssl/tls alert unexpected message
|
||||
SSL_R_TLS_ALERT_UNSUPPORTED_CERTIFICATE:1043:\
|
||||
ssl/tls alert unsupported certificate
|
||||
SSL_R_TLS_EXT_INVALID_MAX_FRAGMENT_LENGTH:232:\
|
||||
ssl3 ext invalid max fragment length
|
||||
SSL_R_TLS_EXT_INVALID_SERVERNAME:319:ssl3 ext invalid servername
|
||||
SSL_R_TLS_EXT_INVALID_SERVERNAME_TYPE:320:ssl3 ext invalid servername type
|
||||
SSL_R_TLS_ILLEGAL_EXPORTER_LABEL:367:tls illegal exporter label
|
||||
SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST:157:tls invalid ecpointformat list
|
||||
SSL_R_TLS_SESSION_ID_TOO_LONG:300:ssl3 session id too long
|
||||
SSL_R_TOO_MANY_KEY_UPDATES:132:too many key updates
|
||||
SSL_R_TOO_MANY_WARN_ALERTS:409:too many warn alerts
|
||||
SSL_R_TOO_MUCH_EARLY_DATA:164:too much early data
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ IF[{- !$disabled{asm} -}]
|
|||
ENDIF
|
||||
ENDIF
|
||||
|
||||
$COMMON=sha1dgst.c sha256.c sha512.c sha3.c $SHA1ASM $KECCAK1600ASM
|
||||
$COMMON=sha1dgst.c sha256.c sha512.c sha3.c sha3_encode.c $SHA1ASM $KECCAK1600ASM
|
||||
SOURCE[../../libcrypto]=$COMMON sha1_one.c
|
||||
SOURCE[../../providers/libfips.a]= $COMMON
|
||||
|
||||
|
|
|
|||
158
crypto/sha/sha3_encode.c
Normal file
158
crypto/sha/sha3_encode.c
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* including crypto/sha.h requires this for SHA256_CTX */
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
/*
|
||||
* NIST.SP.800-185 Encoding/Padding Methods used for SHA3 derived functions
|
||||
* e.g. It is used by KMAC and cSHAKE
|
||||
*/
|
||||
|
||||
#include <string.h> /* memcpy */
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/proverr.h>
|
||||
#include "crypto/sha.h"
|
||||
#include "internal/common.h" /* ossl_assert */
|
||||
|
||||
/* Returns the number of bytes required to store 'bits' into a byte array */
|
||||
static unsigned int get_encode_size(size_t bits)
|
||||
{
|
||||
unsigned int cnt = 0, sz = sizeof(size_t);
|
||||
|
||||
while (bits && (cnt < sz)) {
|
||||
++cnt;
|
||||
bits >>= 8;
|
||||
}
|
||||
/* If bits is zero 1 byte is required */
|
||||
if (cnt == 0)
|
||||
cnt = 1;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an integer into bytes. The number of bytes is appended
|
||||
* to the end of the buffer.
|
||||
* Returns an array of bytes 'out' of size *out_len.
|
||||
*
|
||||
* e.g if bits = 32, out[2] = { 0x20, 0x01 }
|
||||
*/
|
||||
int ossl_sp800_185_right_encode(unsigned char *out,
|
||||
size_t out_max_len, size_t *out_len,
|
||||
size_t bits)
|
||||
{
|
||||
unsigned int len = get_encode_size(bits);
|
||||
int i;
|
||||
|
||||
if (len >= out_max_len) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MSB's are at the start of the bytes array */
|
||||
for (i = len - 1; i >= 0; --i) {
|
||||
out[i] = (unsigned char)(bits & 0xFF);
|
||||
bits >>= 8;
|
||||
}
|
||||
/* Tack the length onto the end */
|
||||
out[len] = (unsigned char)len;
|
||||
|
||||
/* The Returned length includes the tacked on byte */
|
||||
*out_len = len + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encodes a string with a left encoded length added. Note that the
|
||||
* in_len is converted to bits (* 8).
|
||||
*
|
||||
* e.g- in="KMAC" gives out[6] = { 0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43 }
|
||||
* len bits K M A C
|
||||
*/
|
||||
int ossl_sp800_185_encode_string(unsigned char *out,
|
||||
size_t out_max_len, size_t *out_len,
|
||||
const unsigned char *in, size_t in_len)
|
||||
{
|
||||
if (in == NULL) {
|
||||
*out_len = 0;
|
||||
} else {
|
||||
size_t i, bits, len, sz;
|
||||
|
||||
bits = 8 * in_len;
|
||||
len = get_encode_size(bits);
|
||||
sz = 1 + len + in_len;
|
||||
|
||||
if (sz > out_max_len) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
out[0] = (unsigned char)len;
|
||||
for (i = len; i > 0; --i) {
|
||||
out[i] = (bits & 0xFF);
|
||||
bits >>= 8;
|
||||
}
|
||||
memcpy(out + len + 1, in, in_len);
|
||||
*out_len = sz;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a zero padded encoding of the inputs in1 and an optional
|
||||
* in2 (can be NULL). The padded output must be a multiple of the blocksize 'w'.
|
||||
* The value of w is in bytes (< 256).
|
||||
*
|
||||
* The returned output is:
|
||||
* zero_padded(multiple of w, (left_encode(w) || in1 [|| in2])
|
||||
*/
|
||||
int ossl_sp800_185_bytepad(unsigned char *out, size_t out_len_max, size_t *out_len,
|
||||
const unsigned char *in1, size_t in1_len,
|
||||
const unsigned char *in2, size_t in2_len,
|
||||
size_t w)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *p = out;
|
||||
size_t sz;
|
||||
|
||||
if (!ossl_assert(w <= 255))
|
||||
return 0;
|
||||
sz = (2 + in1_len + (in2 != NULL ? in2_len : 0) + w - 1) / w * w;
|
||||
if (out_len_max != 0 && sz > out_len_max)
|
||||
return 0;
|
||||
|
||||
if (out == NULL) {
|
||||
if (out_len == NULL) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
*out_len = sz;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Left encoded w */
|
||||
*p++ = 1;
|
||||
*p++ = (unsigned char)w;
|
||||
/* || in1 */
|
||||
memcpy(p, in1, in1_len);
|
||||
p += in1_len;
|
||||
/* [ || in2 ] */
|
||||
if (in2 != NULL && in2_len > 0) {
|
||||
memcpy(p, in2, in2_len);
|
||||
p += in2_len;
|
||||
}
|
||||
/* Figure out the pad size (divisible by w) */
|
||||
len = p - out;
|
||||
/* zero pad the end of the buffer */
|
||||
if (sz != len)
|
||||
memset(p, 0, sz - len);
|
||||
if (out_len != NULL)
|
||||
*out_len = sz;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -150,8 +150,9 @@ Each Message digest algorithm (such as SHA256) produces a fixed size output
|
|||
length which is returned when EVP_DigestFinal_ex() is called.
|
||||
Extendable Output Functions (XOF) such as SHAKE256 have a variable sized output
|
||||
length I<outlen> which can be used with either EVP_DigestFinalXOF() or
|
||||
EVP_DigestSqueeze(). EVP_DigestFinal_ex() may also be used for an XOF, but the
|
||||
"xoflen" must be set beforehand (See L</PARAMETERS>).
|
||||
EVP_DigestSqueeze(). EVP_DigestFinal_ex() may also be used for XOF algorithms, but
|
||||
for XOF algorithms that do not have a default size the "xoflen" must be set
|
||||
beforehand (See L</PARAMETERS>).
|
||||
Note that EVP_MD_get_size() and EVP_MD_CTX_get_size_ex() behave differently for
|
||||
an XOF.
|
||||
|
||||
|
|
@ -386,7 +387,7 @@ L<OSSL_LIB_CTX(3)>) will be considered.
|
|||
=item EVP_MD_xof()
|
||||
|
||||
Returns 1 if I<md> is an Extendable-output Function (XOF) otherwise it returns
|
||||
0. SHAKE128 and SHAKE256 are XOF functions.
|
||||
0. SHAKE128, SHAKE256, CSHAKE128 and CSHAKE256 are XOF functions.
|
||||
It returns 0 for BLAKE2B algorithms.
|
||||
|
||||
=item EVP_MD_get0_name(),
|
||||
|
|
@ -531,7 +532,7 @@ following OSSL_PARAM keys:
|
|||
|
||||
Sets or gets the digest length for extendable output functions.
|
||||
The value should not exceed what can be given using a B<size_t>.
|
||||
It may be used by SHAKE-128 and SHAKE-256 to set the
|
||||
It may be used by SHAKE-128, CSHAKE-128, SHAKE-256 and CSHAKE-256, to set the
|
||||
output length used by EVP_DigestFinal_ex() and EVP_DigestFinal().
|
||||
|
||||
=item "size" (B<OSSL_DIGEST_PARAM_SIZE>) <unsigned integer>
|
||||
|
|
@ -552,6 +553,20 @@ EVP_MD_CTX_set_params() can be used with the following OSSL_PARAM keys:
|
|||
Sets the padding type.
|
||||
It is used by the MDC2 algorithm.
|
||||
|
||||
=item "function-name" (B<OSSL_DIGEST_PARAM_FUNCTION_NAME>)<UTF8 string>
|
||||
|
||||
Sets the function name string.
|
||||
It is used by L<EVP_MD-CSHAKE(7)>.
|
||||
|
||||
=item "customization" (B<OSSL_DIGEST_PARAM_CUSTOMIZATION>)<UTF8 string>
|
||||
|
||||
Sets a customisation string.
|
||||
It is used by L<EVP_MD-CSHAKE(7)>.
|
||||
|
||||
=item "properties" (B<OSSL_DIGEST_PARAM_PROPERTIES>)<UTF8 string>
|
||||
|
||||
Sets properties to be used when fetching algorithm implementations.
|
||||
|
||||
=back
|
||||
|
||||
EVP_MD_CTX_get_params() can be used with the following OSSL_PARAM keys:
|
||||
|
|
|
|||
|
|
@ -30,9 +30,18 @@ default provider, and includes the following varieties:
|
|||
This implementation supports the common gettable parameters described
|
||||
in L<EVP_MD-common(7)>.
|
||||
|
||||
=head1 CONFORMING TO
|
||||
|
||||
=over 4
|
||||
|
||||
=item FIPS 202
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<provider-digest(7)>, L<OSSL_PROVIDER-FIPS(7)>, L<OSSL_PROVIDER-default(7)>
|
||||
L<provider-digest(7)>, L<OSSL_PROVIDER-FIPS(7)>, L<OSSL_PROVIDER-default(7)>,
|
||||
L<EVP_MD-SHAKE(7)>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
|
|
|
|||
|
|
@ -2,17 +2,20 @@
|
|||
|
||||
=head1 NAME
|
||||
|
||||
EVP_MD-SHAKE, EVP_MD-KECCAK-KMAC
|
||||
EVP_MD-SHAKE, EVP_MD-CSHAKE, EVP_MD-CSHAKE-KECCAK,
|
||||
- The SHAKE / KECCAK family EVP_MD implementations
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Support for computing SHAKE or KECCAK-KMAC digests through the
|
||||
Support for computing SHAKE, CSHAKE or CSHAKE-KECCAK digests through the
|
||||
B<EVP_MD> API.
|
||||
|
||||
KECCAK-KMAC is an Extendable Output Function (XOF), with a definition
|
||||
similar to SHAKE, used by the KMAC EVP_MAC implementation (see
|
||||
L<EVP_MAC-KMAC(7)>).
|
||||
CSHAKE is an Extendable Output Function (XOF), that allows custom strings
|
||||
"n" and "s". If these strings are both empty then it is identical to SHAKE,
|
||||
otherwise it uses CSHAKE-KECCAK.
|
||||
|
||||
CSHAKE-KECCAK is an Extendable Output Function (XOF), with a definition
|
||||
similar to SHAKE but appends 2 extra zero bits. It is used internally by CSHAKE.
|
||||
|
||||
=head2 Identities
|
||||
|
||||
|
|
@ -21,20 +24,6 @@ provider, and includes the following varieties:
|
|||
|
||||
=over 4
|
||||
|
||||
=item KECCAK-KMAC-128
|
||||
|
||||
Known names are "KECCAK-KMAC-128" and "KECCAK-KMAC128". This is used
|
||||
by L<EVP_MAC-KMAC128(7)>. Using the notation from NIST FIPS 202
|
||||
(Section 6.2), we have S<KECCAK-KMAC-128(M, d)> = S<KECCAK[256](M || 00, d)>
|
||||
(see the description of KMAC128 in Appendix A of NIST SP 800-185).
|
||||
|
||||
=item KECCAK-KMAC-256
|
||||
|
||||
Known names are "KECCAK-KMAC-256" and "KECCAK-KMAC256". This is used
|
||||
by L<EVP_MAC-KMAC256(7)>. Using the notation from NIST FIPS 202
|
||||
(Section 6.2), we have S<KECCAK-KMAC-256(M, d)> = S<KECCAK[512](M || 00, d)>
|
||||
(see the description of KMAC256 in Appendix A of NIST SP 800-185).
|
||||
|
||||
=item SHAKE-128
|
||||
|
||||
Known names are "SHAKE-128" and "SHAKE128".
|
||||
|
|
@ -43,6 +32,28 @@ Known names are "SHAKE-128" and "SHAKE128".
|
|||
|
||||
Known names are "SHAKE-256" and "SHAKE256".
|
||||
|
||||
=item CSHAKE-128
|
||||
|
||||
Known names are "CSHAKE-128" and "CSHAKE128".
|
||||
|
||||
=item CSHAKE-256
|
||||
|
||||
Known names are "CSHAKE-256" and "CSHAKE256".
|
||||
|
||||
=item CSHAKE-KECCAK-128
|
||||
|
||||
Other known names are "KECCAK-KMAC-128" and "KECCAK-KMAC128". This is used
|
||||
by L<EVP_MAC-KMAC128(7)>. Using the notation from NIST FIPS 202
|
||||
(Section 6.2), we have S<KECCAK-KMAC-128(M, d)> = S<KECCAK[256](M || 00, d)>
|
||||
(see the description of KMAC128 in Appendix A of NIST SP 800-185).
|
||||
|
||||
=item CSHAKE-KECCAK-256
|
||||
|
||||
Other known names are "KECCAK-KMAC-256" and "KECCAK-KMAC256". This is used
|
||||
by L<EVP_MAC-KMAC256(7)>. Using the notation from NIST FIPS 202
|
||||
(Section 6.2), we have S<KECCAK-KMAC-256(M, d)> = S<KECCAK[512](M || 00, d)>
|
||||
(see the description of KMAC256 in Appendix A of NIST SP 800-185).
|
||||
|
||||
=back
|
||||
|
||||
=head2 Parameters
|
||||
|
|
@ -59,26 +70,62 @@ The length of the "xoflen" parameter should not exceed that of a B<size_t>.
|
|||
The SHAKE-128 and SHAKE-256 implementations do not have any default digest
|
||||
length.
|
||||
|
||||
This parameter must be set before calling either EVP_DigestFinal_ex() or
|
||||
EVP_DigestFinal(), since these functions were not designed to handle variable
|
||||
length output. It is recommended to either use EVP_DigestSqueeze() or
|
||||
The CSHAKE-128 and CSHAKE-256 implementations have default digest lengths of
|
||||
32 and 64 bytes respectively (which correspond to security strengths of 128 and
|
||||
256 bits respectively).
|
||||
|
||||
For SHAKE this parameter must be set before calling either EVP_DigestFinal_ex()
|
||||
or EVP_DigestFinal(), since these functions were not designed to handle
|
||||
variable length output. If it is not set CSHAKE will use the default value.
|
||||
It is recommended to either use EVP_DigestSqueeze() or
|
||||
EVP_DigestFinalXOF() instead.
|
||||
|
||||
=item "size" (B<OSSL_DIGEST_PARAM_SIZE>) <unsigned integer>
|
||||
|
||||
An alias of "xoflen".
|
||||
|
||||
=item "function-name" (B<OSSL_DIGEST_PARAM_FUNCTION_NAME>)<UTF8 string>
|
||||
|
||||
Sets the function name string used by CSHAKE that can be set to one of
|
||||
"", "TupleHash", "ParallelHash" or "KMAC". The default value is "".
|
||||
|
||||
=item "customization" (B<OSSL_DIGEST_PARAM_CUSTOMIZATION>)<UTF8 string>
|
||||
|
||||
Sets a customisation string used by CSHAKE.
|
||||
It is an optional value with a length of at most 512 bytes, and is
|
||||
empty by default.
|
||||
|
||||
=item "properties" (B<OSSL_DIGEST_PARAM_PROPERTIES>) <UTF8 string>
|
||||
|
||||
An optional property used internally by CSHAKE when fetching either
|
||||
SHAKE or KECCAK algorithms.
|
||||
|
||||
=back
|
||||
|
||||
See L<EVP_DigestInit(3)/PARAMETERS> for further information related to parameters
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
For SHAKE-128, to ensure the maximum security strength of 128 bits, the output
|
||||
length passed to EVP_DigestFinalXOF() should be at least 32.
|
||||
For SHAKE-128 and CSHAKE-128, to ensure the maximum security strength of
|
||||
128 bits, the output length passed to EVP_DigestFinalXOF() should be at least 32.
|
||||
|
||||
For SHAKE-256, to ensure the maximum security strength of 256 bits, the output
|
||||
length passed to EVP_DigestFinalXOF() should be at least 64.
|
||||
For SHAKE-256 and CSHAKE-256, to ensure the maximum security strength of
|
||||
256 bits, the output length passed to EVP_DigestFinalXOF() should be at least 64.
|
||||
|
||||
The SHA3 specification allows bit strings to be used, but OpenSSL only allows
|
||||
byte strings for inputs, and outputs.
|
||||
|
||||
=head1 CONFORMING TO
|
||||
|
||||
=over 4
|
||||
|
||||
=item FIPS 202 (SHA3 and SHAKE)
|
||||
|
||||
=item SP800-185 Section 3 cSHAKE
|
||||
|
||||
=item SP800-185 Section 4 KMAC
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
|
@ -89,6 +136,8 @@ L<EVP_MD_CTX_set_params(3)>, L<provider-digest(7)>, L<OSSL_PROVIDER-default(7)>
|
|||
Since OpenSSL 3.4 the SHAKE-128 and SHAKE-256 implementations have no default
|
||||
digest length.
|
||||
|
||||
CSHAKE-128 and CSHAKE-256 were added in OpenSSL 4.0
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
|
|
|||
|
|
@ -69,9 +69,11 @@ The OpenSSL FIPS provider supports these operations and algorithms:
|
|||
|
||||
=item SHAKE, see L<EVP_MD-SHAKE(7)>
|
||||
|
||||
=item KECCAK-KMAC, see L<EVP_MD-KECCAK-KMAC(7)>
|
||||
=item CSHAKE, see L<EVP_MD-CSHAKE(7)>
|
||||
|
||||
KECCAK-KMAC is only used internally as a sub algorithm of KMAC.
|
||||
=item CSHAKE-KECCAK, see L<EVP_MD-CSHAKE-KECCAK(7)>
|
||||
|
||||
It is used internally as a sub algorithm of CSHAKE.
|
||||
|
||||
=item ML-DSA-MU, see L<EVP_MD-ML-DSA-MU(7)>
|
||||
|
||||
|
|
@ -612,6 +614,8 @@ L<https://www.openssl.org/source/>
|
|||
|
||||
The HKDF-SHA256, HKDF-SHA384 and HKDF-SHA512 algorithms were added in OpenSSL 3.6.
|
||||
|
||||
The CSHAKE-128 and CSHAKE-256 algorithms were added in OpenSSL 4.0.
|
||||
|
||||
All other functionality was added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
|
|
|||
|
|
@ -59,10 +59,12 @@ The OpenSSL default provider supports these operations and algorithms:
|
|||
|
||||
=item KECCAK, see L<EVP_MD-KECCAK(7)>
|
||||
|
||||
=item KECCAK-KMAC, see L<EVP_MD-KECCAK-KMAC(7)>
|
||||
|
||||
=item SHAKE, see L<EVP_MD-SHAKE(7)>
|
||||
|
||||
=item CSHAKE, see L<EVP_MD-CSHAKE(7)>
|
||||
|
||||
=item CSHAKE-KECCAK, see L<EVP_MD-CSHAKE-KECCAK(7)>
|
||||
|
||||
=item BLAKE2, see L<EVP_MD-BLAKE2(7)>
|
||||
|
||||
=item SM3, see L<EVP_MD-SM3(7)>
|
||||
|
|
@ -540,6 +542,8 @@ The RIPEMD160 digest was added to the default provider in OpenSSL 3.0.7.
|
|||
|
||||
The HKDF-SHA256, HKDF-SHA384 and HKDF-SHA512 algorithms were added in OpenSSL 3.6.
|
||||
|
||||
The CSHAKE-128 and CSHAKE-256 algorithms were added in OpenSSL 4.0.
|
||||
|
||||
All other functionality was added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
|
|
|||
|
|
@ -14,10 +14,25 @@
|
|||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
/* This is inside a deprecated block because SHA256_CTX was marked deprecated */
|
||||
int ossl_sha256_192_init(SHA256_CTX *c);
|
||||
int sha512_224_init(SHA512_CTX *);
|
||||
int sha512_256_init(SHA512_CTX *);
|
||||
int ossl_sha1_ctrl(SHA_CTX *ctx, int cmd, int mslen, void *ms);
|
||||
#endif
|
||||
|
||||
unsigned char *ossl_sha1(const unsigned char *d, size_t n, unsigned char *md);
|
||||
|
||||
int ossl_sp800_185_right_encode(unsigned char *out,
|
||||
size_t out_max_len, size_t *out_len,
|
||||
size_t bits);
|
||||
int ossl_sp800_185_encode_string(unsigned char *out,
|
||||
size_t out_max_len, size_t *out_len,
|
||||
const unsigned char *in, size_t in_len);
|
||||
int ossl_sp800_185_bytepad(unsigned char *out, size_t out_len_max, size_t *out_len,
|
||||
const unsigned char *in1, size_t in1_len,
|
||||
const unsigned char *in2, size_t in2_len,
|
||||
size_t w);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#define KECCAK1600_WIDTH 1600
|
||||
#define SHA3_MDSIZE(bitlen) (bitlen / 8)
|
||||
#define KMAC_MDSIZE(bitlen) 2 * (bitlen / 8)
|
||||
#define CSHAKE_KECCAK_MDSIZE(bitlen) 2 * (bitlen / 8)
|
||||
#define SHA3_BLOCKSIZE(bitlen) (KECCAK1600_WIDTH - bitlen * 2) / 8
|
||||
|
||||
typedef struct keccak_st KECCAK1600_CTX;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
|
@ -65,6 +65,7 @@
|
|||
#define PROV_R_INVALID_DIGEST_LENGTH 166
|
||||
#define PROV_R_INVALID_DIGEST_SIZE 218
|
||||
#define PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION 243
|
||||
#define PROV_R_INVALID_FUNCTION_NAME 256
|
||||
#define PROV_R_INVALID_INPUT_LENGTH 230
|
||||
#define PROV_R_INVALID_ITERATION_COUNT 123
|
||||
#define PROV_R_INVALID_IV_LENGTH 109
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
|
@ -93,6 +93,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
|||
"invalid digest size" },
|
||||
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION),
|
||||
"invalid eddsa instance for attempted operation" },
|
||||
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_FUNCTION_NAME),
|
||||
"invalid function name" },
|
||||
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_INPUT_LENGTH),
|
||||
"invalid input length" },
|
||||
{ ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_ITERATION_COUNT),
|
||||
|
|
|
|||
|
|
@ -124,15 +124,18 @@ static const OSSL_ALGORITHM deflt_digests[] = {
|
|||
* KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for
|
||||
* the KMAC-128 and KMAC-256.
|
||||
*/
|
||||
{ PROV_NAMES_KECCAK_KMAC_128, "provider=default",
|
||||
ossl_keccak_kmac_128_functions },
|
||||
{ PROV_NAMES_KECCAK_KMAC_256, "provider=default",
|
||||
ossl_keccak_kmac_256_functions },
|
||||
{ PROV_NAMES_CSHAKE_KECCAK_128, "provider=default",
|
||||
ossl_cshake_keccak_128_functions },
|
||||
{ PROV_NAMES_CSHAKE_KECCAK_256, "provider=default",
|
||||
ossl_cshake_keccak_256_functions },
|
||||
|
||||
/* Our primary name:NIST name */
|
||||
{ PROV_NAMES_SHAKE_128, "provider=default", ossl_shake_128_functions },
|
||||
{ PROV_NAMES_SHAKE_256, "provider=default", ossl_shake_256_functions },
|
||||
|
||||
{ PROV_NAMES_CSHAKE_128, "provider=default", ossl_cshake_128_functions },
|
||||
{ PROV_NAMES_CSHAKE_256, "provider=default", ossl_cshake_256_functions },
|
||||
|
||||
#ifndef OPENSSL_NO_BLAKE2
|
||||
/*
|
||||
* https://blake2.net/ doesn't specify size variants,
|
||||
|
|
|
|||
|
|
@ -281,23 +281,25 @@ static int fips_self_test(void *provctx)
|
|||
* we have used historically.
|
||||
*/
|
||||
|
||||
#define FIPS_DIGESTS_COMMON() \
|
||||
{ PROV_NAMES_SHA1, FIPS_DEFAULT_PROPERTIES, ossl_sha1_functions }, \
|
||||
{ PROV_NAMES_SHA2_224, FIPS_DEFAULT_PROPERTIES, ossl_sha224_functions }, \
|
||||
{ PROV_NAMES_SHA2_256, FIPS_DEFAULT_PROPERTIES, ossl_sha256_functions }, \
|
||||
{ PROV_NAMES_SHA2_384, FIPS_DEFAULT_PROPERTIES, ossl_sha384_functions }, \
|
||||
{ PROV_NAMES_SHA2_512, FIPS_DEFAULT_PROPERTIES, ossl_sha512_functions }, \
|
||||
{ PROV_NAMES_SHA2_512_224, FIPS_DEFAULT_PROPERTIES, \
|
||||
ossl_sha512_224_functions }, \
|
||||
{ PROV_NAMES_SHA2_512_256, FIPS_DEFAULT_PROPERTIES, \
|
||||
ossl_sha512_256_functions }, \
|
||||
{ PROV_NAMES_SHA3_224, FIPS_DEFAULT_PROPERTIES, ossl_sha3_224_functions }, \
|
||||
{ PROV_NAMES_SHA3_256, FIPS_DEFAULT_PROPERTIES, ossl_sha3_256_functions }, \
|
||||
{ PROV_NAMES_SHA3_384, FIPS_DEFAULT_PROPERTIES, ossl_sha3_384_functions }, \
|
||||
{ PROV_NAMES_SHA3_512, FIPS_DEFAULT_PROPERTIES, ossl_sha3_512_functions }, \
|
||||
{ PROV_NAMES_SHAKE_128, FIPS_DEFAULT_PROPERTIES, ossl_shake_128_functions }, \
|
||||
{ \
|
||||
PROV_NAMES_SHAKE_256, FIPS_DEFAULT_PROPERTIES, ossl_shake_256_functions \
|
||||
#define FIPS_DIGESTS_COMMON() \
|
||||
{ PROV_NAMES_SHA1, FIPS_DEFAULT_PROPERTIES, ossl_sha1_functions }, \
|
||||
{ PROV_NAMES_SHA2_224, FIPS_DEFAULT_PROPERTIES, ossl_sha224_functions }, \
|
||||
{ PROV_NAMES_SHA2_256, FIPS_DEFAULT_PROPERTIES, ossl_sha256_functions }, \
|
||||
{ PROV_NAMES_SHA2_384, FIPS_DEFAULT_PROPERTIES, ossl_sha384_functions }, \
|
||||
{ PROV_NAMES_SHA2_512, FIPS_DEFAULT_PROPERTIES, ossl_sha512_functions }, \
|
||||
{ PROV_NAMES_SHA2_512_224, FIPS_DEFAULT_PROPERTIES, \
|
||||
ossl_sha512_224_functions }, \
|
||||
{ PROV_NAMES_SHA2_512_256, FIPS_DEFAULT_PROPERTIES, \
|
||||
ossl_sha512_256_functions }, \
|
||||
{ PROV_NAMES_SHA3_224, FIPS_DEFAULT_PROPERTIES, ossl_sha3_224_functions }, \
|
||||
{ PROV_NAMES_SHA3_256, FIPS_DEFAULT_PROPERTIES, ossl_sha3_256_functions }, \
|
||||
{ PROV_NAMES_SHA3_384, FIPS_DEFAULT_PROPERTIES, ossl_sha3_384_functions }, \
|
||||
{ PROV_NAMES_SHA3_512, FIPS_DEFAULT_PROPERTIES, ossl_sha3_512_functions }, \
|
||||
{ PROV_NAMES_SHAKE_128, FIPS_DEFAULT_PROPERTIES, ossl_shake_128_functions }, \
|
||||
{ PROV_NAMES_SHAKE_256, FIPS_DEFAULT_PROPERTIES, ossl_shake_256_functions }, \
|
||||
{ PROV_NAMES_CSHAKE_128, FIPS_DEFAULT_PROPERTIES, ossl_cshake_128_functions }, \
|
||||
{ \
|
||||
PROV_NAMES_CSHAKE_256, FIPS_DEFAULT_PROPERTIES, ossl_cshake_256_functions \
|
||||
}
|
||||
|
||||
static const OSSL_ALGORITHM fips_digests[] = {
|
||||
|
|
@ -312,14 +314,10 @@ static const OSSL_ALGORITHM fips_digests_internal[] = {
|
|||
/* Used by LMS/HSS */
|
||||
{ PROV_NAMES_SHA2_256_192, FIPS_DEFAULT_PROPERTIES,
|
||||
ossl_sha256_192_internal_functions },
|
||||
/*
|
||||
* KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for
|
||||
* KMAC128 and KMAC256.
|
||||
*/
|
||||
{ PROV_NAMES_KECCAK_KMAC_128, FIPS_DEFAULT_PROPERTIES,
|
||||
ossl_keccak_kmac_128_functions },
|
||||
{ PROV_NAMES_KECCAK_KMAC_256, FIPS_DEFAULT_PROPERTIES,
|
||||
ossl_keccak_kmac_256_functions },
|
||||
{ PROV_NAMES_CSHAKE_KECCAK_128, FIPS_DEFAULT_PROPERTIES,
|
||||
ossl_cshake_keccak_128_functions },
|
||||
{ PROV_NAMES_CSHAKE_KECCAK_256, FIPS_DEFAULT_PROPERTIES,
|
||||
ossl_cshake_keccak_256_functions },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ ENDIF
|
|||
SOURCE[$COMMON_GOAL]=digestcommon.c
|
||||
|
||||
SOURCE[$SHA2_GOAL]=sha2_prov.c
|
||||
SOURCE[$SHA3_GOAL]=sha3_prov.c
|
||||
SOURCE[$SHA3_GOAL]=sha3_prov.c cshake_prov.c
|
||||
|
||||
SOURCE[$NULL_GOAL]=null_prov.c
|
||||
|
||||
|
|
|
|||
503
providers/implementations/digests/cshake_prov.c
Normal file
503
providers/implementations/digests/cshake_prov.c
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
/*
|
||||
* Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* including crypto/sha.h requires this for SHA256_CTX */
|
||||
#include "internal/deprecated.h"
|
||||
/*
|
||||
* NOTE: By default CSHAKE sets secure xof lengths (OSSL_DIGEST_PARAM_XOFLEN)
|
||||
* that are used by EVP_DigestFinal_ex(). This differs from SHAKE where the
|
||||
* xof length MUST be set (since the initial implementation shipped with BAD
|
||||
* defaults - and the only safe way to fix it was to make the user set the value)
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/proverr.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "crypto/sha.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
#include "prov/digestcommon.h"
|
||||
#include "prov/implementations.h"
|
||||
#include "internal/common.h"
|
||||
#include "internal/sha3.h"
|
||||
#include "providers/implementations/digests/cshake_prov.inc"
|
||||
|
||||
/*
|
||||
* Length encoding will be a 1 byte size + length in bits (3 bytes max)
|
||||
* This gives a range of 0..0XFFFFFF bits = 2097151 bytes).
|
||||
*/
|
||||
#define CSHAKE_MAX_ENCODED_HEADER_LEN (1 + 3)
|
||||
|
||||
/*
|
||||
* Restrict the maximum length of the custom strings N & S.
|
||||
* This must not exceed 64 bits = 8k bytes.
|
||||
*/
|
||||
#define CSHAKE_MAX_STRING 512
|
||||
|
||||
/* Maximum size of both the encoded strings (N and S) */
|
||||
#define CSHAKE_MAX_ENCODED_STRING (CSHAKE_MAX_STRING + CSHAKE_MAX_ENCODED_HEADER_LEN)
|
||||
#define CSHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT)
|
||||
|
||||
typedef struct cshake_ctx_st {
|
||||
OSSL_LIB_CTX *libctx;
|
||||
char *propq;
|
||||
EVP_MD_CTX *mdctx;
|
||||
EVP_MD *md;
|
||||
const uint8_t *func; /* encoded N */
|
||||
uint8_t custom[CSHAKE_MAX_ENCODED_STRING]; /* encoded S */
|
||||
size_t funclen;
|
||||
size_t customlen;
|
||||
size_t bitlen;
|
||||
size_t xoflen;
|
||||
int inited;
|
||||
} CSHAKE_CTX;
|
||||
|
||||
static OSSL_FUNC_digest_freectx_fn cshake_freectx;
|
||||
static OSSL_FUNC_digest_dupctx_fn cshake_dupctx;
|
||||
static OSSL_FUNC_digest_init_fn cshake_init;
|
||||
static OSSL_FUNC_digest_update_fn cshake_update;
|
||||
static OSSL_FUNC_digest_final_fn cshake_final;
|
||||
static OSSL_FUNC_digest_squeeze_fn cshake_squeeze;
|
||||
static OSSL_FUNC_digest_set_ctx_params_fn cshake_set_ctx_params;
|
||||
static OSSL_FUNC_digest_settable_ctx_params_fn cshake_settable_ctx_params;
|
||||
static OSSL_FUNC_digest_get_ctx_params_fn cshake_get_ctx_params;
|
||||
static OSSL_FUNC_digest_gettable_ctx_params_fn cshake_gettable_ctx_params;
|
||||
|
||||
typedef struct name_encode_map_st {
|
||||
const char *name;
|
||||
const uint8_t *encoding;
|
||||
size_t encodinglen;
|
||||
} NAME_ENCODE_MAP;
|
||||
|
||||
/* Fixed value of encode_string("") */
|
||||
static const unsigned char empty_encoded_string[] = {
|
||||
0x01, 0x00
|
||||
};
|
||||
|
||||
/* Fixed value of encode_string("KMAC") */
|
||||
static const unsigned char kmac_encoded_string[] = {
|
||||
0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43
|
||||
};
|
||||
|
||||
/* Fixed value of encode_string("TupleHash") */
|
||||
static const unsigned char tuplehash_encoded_string[] = {
|
||||
0x01, 0x48, 0x54, 0x75, 0x70, 0x6C, 0x65, 0x48, 0x61, 0x73, 0x68
|
||||
};
|
||||
|
||||
/* Fixed value of encode_string("ParallelHash") */
|
||||
static const unsigned char parallelhash_encoded_string[] = {
|
||||
0x01, 0x60, 0x50, 0x61, 0x72, 0x61, 0x6C, 0x6C, 0x65, 0x6C, 0x48, 0x61, 0x73, 0x68
|
||||
};
|
||||
|
||||
static int cshake_set_func_encode_string(const char *in,
|
||||
const uint8_t **out, size_t *outlen)
|
||||
{
|
||||
/*
|
||||
* A list of valid function names to encoded string mappings
|
||||
* See NIST SP800-185 Section 3.4
|
||||
*/
|
||||
static NAME_ENCODE_MAP functionNameMap[] = {
|
||||
{ "", empty_encoded_string, sizeof(empty_encoded_string) },
|
||||
{ "KMAC", kmac_encoded_string, sizeof(kmac_encoded_string) },
|
||||
{ "TupleHash", tuplehash_encoded_string, sizeof(tuplehash_encoded_string) },
|
||||
{ "ParallelHash", parallelhash_encoded_string, sizeof(parallelhash_encoded_string) },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
*out = NULL;
|
||||
*outlen = 0;
|
||||
/*
|
||||
* Don't encode an empty string here - this is done manually later only when
|
||||
* one of the strings is not empty. If both are empty then we don't want it
|
||||
* to encode at all.
|
||||
*/
|
||||
if (in == NULL || in[0] == 0)
|
||||
return 1;
|
||||
for (int i = 1; functionNameMap[i].name != NULL; ++i) {
|
||||
if (functionNameMap[i].name[0] == in[0]) {
|
||||
if (OPENSSL_strcasecmp(functionNameMap[i].name, in) == 0) {
|
||||
*out = functionNameMap[i].encoding;
|
||||
*outlen = functionNameMap[i].encodinglen;
|
||||
return 1;
|
||||
}
|
||||
return 0; /* Name does not match a known name */
|
||||
}
|
||||
}
|
||||
return 0; /* Name not found */
|
||||
}
|
||||
|
||||
static int cshake_set_encode_string(const char *in,
|
||||
uint8_t *out, size_t outmax, size_t *outlen)
|
||||
{
|
||||
size_t inlen;
|
||||
|
||||
if (*outlen != 0)
|
||||
OPENSSL_cleanse(out, outmax);
|
||||
*outlen = 0;
|
||||
if (in == NULL)
|
||||
return 1;
|
||||
|
||||
inlen = strlen(in);
|
||||
/*
|
||||
* Don't encode an empty string here - this is done manually later only when
|
||||
* one of the strings is not empty. If both are empty then we don't want it
|
||||
* to encode at all.
|
||||
*/
|
||||
if (inlen == 0)
|
||||
return 1;
|
||||
if (inlen >= CSHAKE_MAX_STRING)
|
||||
return 0;
|
||||
return ossl_sp800_185_encode_string(out, outmax, outlen,
|
||||
(const unsigned char *)in, inlen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the xof length, note that if the digest has not been fetched yet then
|
||||
* it is just set into a variable and deferred to later.
|
||||
*/
|
||||
static int cshake_set_xoflen(CSHAKE_CTX *ctx, size_t xoflen)
|
||||
{
|
||||
OSSL_PARAM params[2];
|
||||
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &xoflen);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
ctx->xoflen = xoflen;
|
||||
if (ctx->md != NULL)
|
||||
return EVP_MD_CTX_set_params(ctx->mdctx, params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch a digest for SHAKE or KECCAK, set its xof len and init it
|
||||
* into an mdctx.
|
||||
*/
|
||||
static int cshake_set_shake_mode(CSHAKE_CTX *ctx, int shake)
|
||||
{
|
||||
OSSL_PARAM params[2];
|
||||
const char *name;
|
||||
|
||||
if (shake)
|
||||
name = (ctx->bitlen == 128 ? "SHAKE128" : "SHAKE256");
|
||||
else
|
||||
name = (ctx->bitlen == 128 ? "CSHAKE-KECCAK-128" : "CSHAKE-KECCAK-256");
|
||||
|
||||
if (ctx->md == NULL || !EVP_MD_is_a(ctx->md, name)) {
|
||||
ctx->md = EVP_MD_fetch(ctx->libctx, name, ctx->propq);
|
||||
if (ctx->md == NULL)
|
||||
return 0;
|
||||
}
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN,
|
||||
&ctx->xoflen);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
return EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params);
|
||||
}
|
||||
|
||||
static void *cshake_newctx(void *provctx, size_t bitlen)
|
||||
{
|
||||
CSHAKE_CTX *ctx;
|
||||
|
||||
if (ossl_unlikely(!ossl_prov_is_running()))
|
||||
return NULL;
|
||||
ctx = OPENSSL_zalloc(sizeof(*ctx));
|
||||
if (ctx != NULL) {
|
||||
ctx->mdctx = EVP_MD_CTX_create();
|
||||
if (ctx->mdctx == NULL) {
|
||||
OPENSSL_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
ctx->bitlen = bitlen;
|
||||
ctx->libctx = PROV_LIBCTX_OF(provctx);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void cshake_freectx(void *vctx)
|
||||
{
|
||||
CSHAKE_CTX *ctx = (CSHAKE_CTX *)vctx;
|
||||
|
||||
EVP_MD_free(ctx->md);
|
||||
EVP_MD_CTX_destroy(ctx->mdctx);
|
||||
OPENSSL_clear_free(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
static void *cshake_dupctx(void *ctx)
|
||||
{
|
||||
CSHAKE_CTX *src = (CSHAKE_CTX *)ctx;
|
||||
CSHAKE_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret))
|
||||
: NULL;
|
||||
|
||||
if (ret != NULL) {
|
||||
*ret = *src;
|
||||
ret->md = NULL;
|
||||
ret->mdctx = NULL;
|
||||
ret->propq = NULL;
|
||||
|
||||
if (src->md != NULL && !EVP_MD_up_ref(src->md))
|
||||
goto err;
|
||||
ret->md = src->md;
|
||||
|
||||
if (src->mdctx != NULL) {
|
||||
ret->mdctx = EVP_MD_CTX_new();
|
||||
if (ret->mdctx == NULL
|
||||
|| !EVP_MD_CTX_copy_ex(ret->mdctx, src->mdctx))
|
||||
goto err;
|
||||
}
|
||||
if (src->propq != NULL) {
|
||||
ret->propq = OPENSSL_strdup(src->propq);
|
||||
if (ret->propq == NULL)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
err:
|
||||
cshake_freectx(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int cshake_init(void *vctx, const OSSL_PARAM params[])
|
||||
{
|
||||
CSHAKE_CTX *ctx = (CSHAKE_CTX *)vctx;
|
||||
|
||||
if (ossl_unlikely(!ossl_prov_is_running()))
|
||||
return 0;
|
||||
ctx->inited = 0;
|
||||
ctx->xoflen = (ctx->bitlen == 128) ? 32 : 64; /* Set default values here */
|
||||
cshake_set_func_encode_string(NULL, &ctx->func, &ctx->funclen);
|
||||
cshake_set_encode_string(NULL, ctx->custom, sizeof(ctx->custom), &ctx->customlen);
|
||||
return cshake_set_ctx_params(vctx, params);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *cshake_settable_ctx_params(ossl_unused void *ctx,
|
||||
ossl_unused void *provctx)
|
||||
{
|
||||
return cshake_set_ctx_params_list;
|
||||
}
|
||||
|
||||
static int set_property_query(CSHAKE_CTX *ctx, const char *propq)
|
||||
{
|
||||
OPENSSL_free(ctx->propq);
|
||||
ctx->propq = NULL;
|
||||
if (propq != NULL) {
|
||||
ctx->propq = OPENSSL_strdup(propq);
|
||||
if (ctx->propq == NULL)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cshake_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
{
|
||||
CSHAKE_CTX *ctx = (CSHAKE_CTX *)vctx;
|
||||
struct cshake_set_ctx_params_st p;
|
||||
|
||||
if (ctx == NULL || !cshake_set_ctx_params_decoder(params, &p))
|
||||
return 0;
|
||||
|
||||
if (p.xoflen != NULL) {
|
||||
size_t xoflen;
|
||||
|
||||
if (!OSSL_PARAM_get_size_t(p.xoflen, &xoflen)
|
||||
|| !cshake_set_xoflen(ctx, xoflen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (p.func != NULL) {
|
||||
if (p.func->data_type != OSSL_PARAM_UTF8_STRING)
|
||||
return 0;
|
||||
if (!cshake_set_func_encode_string(p.func->data, &ctx->func, &ctx->funclen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_FUNCTION_NAME);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (p.custom != NULL) {
|
||||
if (p.custom->data_type != OSSL_PARAM_UTF8_STRING)
|
||||
return 0;
|
||||
if (!cshake_set_encode_string(p.custom->data, ctx->custom, sizeof(ctx->custom), &ctx->customlen))
|
||||
return 0;
|
||||
}
|
||||
if (p.propq != NULL) {
|
||||
if (p.propq->data_type != OSSL_PARAM_UTF8_STRING
|
||||
|| !set_property_query(ctx, p.propq->data))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* bytepad(encode_string(N) || encode_string(S), w)
|
||||
* See SP800-185 Section 2.3.3 Padding.
|
||||
*
|
||||
* Rather than build an array and do a single keccak operation, we use the
|
||||
* internal keccak buffer to simplify the process.
|
||||
* Note that if the strings are large enough to fill the buffer, it will handle
|
||||
* this internally by absorbing full blocks. The zero padding is also simple
|
||||
* as we just fill the buffer with zeros to make it a multiple of the blocksize.
|
||||
*/
|
||||
static int cshake_absorb_bytepad_strings(CSHAKE_CTX *ctx)
|
||||
{
|
||||
const uint8_t zeros[SHA3_BLOCKSIZE(128)] = { 0 };
|
||||
uint8_t bytepad_header[2] = { 0x01, 0x00 };
|
||||
const uint8_t *n = ctx->func, *s = ctx->custom;
|
||||
size_t nlen = ctx->funclen, slen = ctx->customlen;
|
||||
size_t zlen;
|
||||
size_t w = SHA3_BLOCKSIZE(ctx->bitlen); /* w = 168 or 136 */
|
||||
|
||||
bytepad_header[1] = (uint8_t)w;
|
||||
|
||||
/* Empty strings are still encoded */
|
||||
if (nlen == 0) {
|
||||
n = empty_encoded_string;
|
||||
nlen = sizeof(empty_encoded_string);
|
||||
}
|
||||
if (slen == 0) {
|
||||
s = empty_encoded_string;
|
||||
slen = sizeof(empty_encoded_string);
|
||||
}
|
||||
/* Calculate the number of padding zeros to fill up the block */
|
||||
zlen = ((sizeof(bytepad_header) + nlen + slen) % w);
|
||||
if (zlen != 0)
|
||||
zlen = w - zlen;
|
||||
|
||||
/* left encoded(w) || encodestring(n) || encodestring(s) || zero_padding */
|
||||
return EVP_DigestUpdate(ctx->mdctx, bytepad_header, sizeof(bytepad_header))
|
||||
&& EVP_DigestUpdate(ctx->mdctx, n, nlen)
|
||||
&& EVP_DigestUpdate(ctx->mdctx, s, slen)
|
||||
&& EVP_DigestUpdate(ctx->mdctx, zeros, zlen);
|
||||
}
|
||||
|
||||
/*
|
||||
* The setup of the EVP_MD gets deferred until after the set_ctx_params
|
||||
* which means that we need to defer to the functions that may be called
|
||||
* afterwards (i.e. The update(), final() or squeeze()).
|
||||
*
|
||||
*/
|
||||
static int check_init(CSHAKE_CTX *ctx)
|
||||
{
|
||||
/*
|
||||
* We have to defer choosing the mode EVP_MD object (SHAKE or KECCAK)
|
||||
* until the first call to either update(), final() or squeeze()
|
||||
* since the strings can be set at any time before this point.
|
||||
*/
|
||||
if (ctx->inited == 0) {
|
||||
if (ctx->funclen != 0 || ctx->customlen != 0) {
|
||||
if (!cshake_set_shake_mode(ctx, 0)
|
||||
|| !cshake_absorb_bytepad_strings(ctx))
|
||||
return 0;
|
||||
} else {
|
||||
/* Use SHAKE if N and S are both empty strings */
|
||||
if (!cshake_set_shake_mode(ctx, 1))
|
||||
return 0;
|
||||
}
|
||||
ctx->inited = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cshake_update(void *vctx, const unsigned char *in, size_t inlen)
|
||||
{
|
||||
CSHAKE_CTX *ctx = (CSHAKE_CTX *)vctx;
|
||||
|
||||
return check_init(ctx)
|
||||
&& EVP_DigestUpdate(ctx->mdctx, in, inlen);
|
||||
}
|
||||
|
||||
static int cshake_final(void *vctx, uint8_t *out, size_t *outl, size_t outsz)
|
||||
{
|
||||
CSHAKE_CTX *ctx = (CSHAKE_CTX *)vctx;
|
||||
unsigned int der = (unsigned int)(*outl);
|
||||
int ret = 1;
|
||||
|
||||
if (ossl_unlikely(!ossl_prov_is_running()))
|
||||
return 0;
|
||||
|
||||
if (outsz > 0)
|
||||
ret = check_init(ctx) && EVP_DigestFinal_ex(ctx->mdctx, out, &der);
|
||||
*outl = der;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cshake_squeeze(void *vctx, uint8_t *out, size_t *outl, size_t outsz)
|
||||
{
|
||||
CSHAKE_CTX *ctx = (CSHAKE_CTX *)vctx;
|
||||
int ret = 1;
|
||||
|
||||
if (ossl_unlikely(!ossl_prov_is_running()))
|
||||
return 0;
|
||||
|
||||
if (outsz > 0)
|
||||
ret = check_init(ctx) && EVP_DigestSqueeze(ctx->mdctx, out, outsz);
|
||||
if (ret && outl != NULL)
|
||||
*outl = outsz;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *cshake_gettable_ctx_params(ossl_unused void *ctx,
|
||||
ossl_unused void *provctx)
|
||||
{
|
||||
return cshake_get_ctx_params_list;
|
||||
}
|
||||
|
||||
static int cshake_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||
{
|
||||
CSHAKE_CTX *ctx = (CSHAKE_CTX *)vctx;
|
||||
struct cshake_get_ctx_params_st p;
|
||||
|
||||
if (ctx == NULL || !cshake_get_ctx_params_decoder(params, &p))
|
||||
return 0;
|
||||
|
||||
/* Size is an alias of xoflen */
|
||||
if (p.xoflen != NULL || p.size != NULL) {
|
||||
size_t xoflen = ctx->xoflen;
|
||||
|
||||
if (ctx->md != NULL)
|
||||
xoflen = EVP_MD_CTX_get_size_ex(ctx->mdctx);
|
||||
|
||||
if (p.size != NULL && !OSSL_PARAM_set_size_t(p.size, xoflen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (p.xoflen != NULL && !OSSL_PARAM_set_size_t(p.xoflen, xoflen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define IMPLEMENT_CSHAKE_functions(bitlen) \
|
||||
static OSSL_FUNC_digest_newctx_fn cshake_##bitlen##_newctx; \
|
||||
static void *cshake_##bitlen##_newctx(void *provctx) \
|
||||
{ \
|
||||
return cshake_newctx(provctx, bitlen); \
|
||||
} \
|
||||
PROV_FUNC_DIGEST_GET_PARAM(cshake_##bitlen, SHA3_BLOCKSIZE(bitlen), \
|
||||
CSHAKE_KECCAK_MDSIZE(bitlen), CSHAKE_FLAGS) \
|
||||
const OSSL_DISPATCH ossl_cshake_##bitlen##_functions[] = { \
|
||||
{ OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))cshake_##bitlen##_newctx }, \
|
||||
{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))cshake_init }, \
|
||||
{ OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))cshake_update }, \
|
||||
{ OSSL_FUNC_DIGEST_FINAL, (void (*)(void))cshake_final }, \
|
||||
{ OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))cshake_squeeze }, \
|
||||
{ OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))cshake_freectx }, \
|
||||
{ OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))cshake_dupctx }, \
|
||||
{ OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))cshake_set_ctx_params }, \
|
||||
{ OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cshake_settable_ctx_params }, \
|
||||
{ OSSL_FUNC_DIGEST_GET_CTX_PARAMS, (void (*)(void))cshake_get_ctx_params }, \
|
||||
{ OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cshake_gettable_ctx_params }, \
|
||||
PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(cshake_##bitlen), \
|
||||
PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
|
||||
|
||||
/* ossl_cshake_128_functions */
|
||||
IMPLEMENT_CSHAKE_functions(128)
|
||||
/* ossl_cshake_256_functions */
|
||||
IMPLEMENT_CSHAKE_functions(256)
|
||||
24
providers/implementations/digests/cshake_prov.inc.in
Normal file
24
providers/implementations/digests/cshake_prov.inc.in
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
{-
|
||||
use OpenSSL::paramnames qw(produce_param_decoder);
|
||||
-}
|
||||
|
||||
{- produce_param_decoder('cshake_set_ctx_params',
|
||||
(['OSSL_DIGEST_PARAM_XOFLEN', 'xoflen', 'size_t'],
|
||||
['OSSL_DIGEST_PARAM_SIZE', 'xoflen', 'size_t'],
|
||||
['OSSL_DIGEST_PARAM_FUNCTION_NAME', 'func', 'utf8_string'],
|
||||
['OSSL_DIGEST_PARAM_CUSTOMIZATION', 'custom', 'utf8_string'],
|
||||
['OSSL_DIGEST_PARAM_PROPERTIES', 'propq', 'utf8_string'],
|
||||
)); -}
|
||||
|
||||
{- produce_param_decoder('cshake_get_ctx_params',
|
||||
(['OSSL_DIGEST_PARAM_XOFLEN', 'xoflen', 'size_t'],
|
||||
['OSSL_DIGEST_PARAM_SIZE', 'size', 'size_t'],
|
||||
)); -}
|
||||
|
|
@ -25,7 +25,35 @@
|
|||
|
||||
#define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
|
||||
#define SHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT)
|
||||
#define KMAC_FLAGS PROV_DIGEST_FLAG_XOF
|
||||
#define CSHAKE_KECCAK_FLAGS PROV_DIGEST_FLAG_XOF
|
||||
|
||||
/*
|
||||
* FIPS 202 Section 5.1 Specifies a padding mode that is added to the last
|
||||
* block that consists of a 1 bit followed by padding zero bits and a trailing
|
||||
* 1 bit (where the bits are in LSB order)
|
||||
*
|
||||
* For a given input message special algorithm context bits are appended:
|
||||
* i.e.
|
||||
* KECCAK[c] = (No tag is used)
|
||||
* SHA3 = 01
|
||||
* SHAKE = 1111
|
||||
* CSHAKE_KECCAK = 00 (See NIST SP800-185 3.3 : i.e. it has 2 trailing zero bits)
|
||||
* Note that KMAC and TupleHash use CSHAKE_KECCAK.
|
||||
* The OpenSSL implementation only allows input messages that are in bytes,
|
||||
* so the above concatenated bits will start on a byte boundary.
|
||||
* Following these bits will be a 1 bit then the padding zeros which gives
|
||||
*
|
||||
* KECCAK[c] = 1000
|
||||
* SHA3 = 0110
|
||||
* SHAKE = 11111000
|
||||
* CSHAKE_KECCAK = 0010 (See NIST SP800-185 3.3 : i.e. KMAC uses cSHAKE with a fixed string)
|
||||
*
|
||||
* Which gives the following padding values as bytes.
|
||||
*/
|
||||
#define KECCAK_PADDING 0x01
|
||||
#define SHA3_PADDING 0x06
|
||||
#define SHAKE_PADDING 0x1f
|
||||
#define CSHAKE_KECCAK_PADDING 0x04
|
||||
|
||||
/*
|
||||
* Forward declaration of any unique methods implemented here. This is not strictly
|
||||
|
|
@ -56,7 +84,6 @@ static sha3_squeeze_fn generic_sha3_squeeze;
|
|||
#define S390_SHA3 1
|
||||
#define S390_SHA3_CAPABLE(name) \
|
||||
((OPENSSL_s390xcap_P.kimd[0] & S390X_CAPBIT(S390X_##name)) && (OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name)))
|
||||
|
||||
#endif
|
||||
|
||||
static int keccak_init(void *vctx, ossl_unused const OSSL_PARAM params[])
|
||||
|
|
@ -320,7 +347,7 @@ static int s390x_keccak_final(void *vctx, unsigned char *out, size_t outlen)
|
|||
return s390x_keccakc_final(vctx, out, outlen, 0x01);
|
||||
}
|
||||
|
||||
static int s390x_kmac_final(void *vctx, unsigned char *out, size_t outlen)
|
||||
static int s390x_cshake_keccak_final(void *vctx, unsigned char *out, size_t outlen)
|
||||
{
|
||||
return s390x_keccakc_final(vctx, out, outlen, 0x04);
|
||||
}
|
||||
|
|
@ -374,12 +401,12 @@ static int s390x_keccakc_squeeze(void *vctx, unsigned char *out, size_t outlen,
|
|||
|
||||
static int s390x_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen)
|
||||
{
|
||||
return s390x_keccakc_squeeze(vctx, out, outlen, 0x01);
|
||||
return s390x_keccakc_squeeze(vctx, out, outlen, KECCAK_PADDING);
|
||||
}
|
||||
|
||||
static int s390x_kmac_squeeze(void *vctx, unsigned char *out, size_t outlen)
|
||||
static int s390x_cshake_keccak_squeeze(void *vctx, unsigned char *out, size_t outlen)
|
||||
{
|
||||
return s390x_keccakc_squeeze(vctx, out, outlen, 0x04);
|
||||
return s390x_keccakc_squeeze(vctx, out, outlen, CSHAKE_KECCAK_PADDING);
|
||||
}
|
||||
|
||||
static PROV_SHA3_METHOD sha3_s390x_md = {
|
||||
|
|
@ -400,10 +427,10 @@ static PROV_SHA3_METHOD shake_s390x_md = {
|
|||
s390x_shake_squeeze,
|
||||
};
|
||||
|
||||
static PROV_SHA3_METHOD kmac_s390x_md = {
|
||||
static PROV_SHA3_METHOD cshake_keccak_s390x_md = {
|
||||
s390x_sha3_absorb,
|
||||
s390x_kmac_final,
|
||||
s390x_kmac_squeeze,
|
||||
s390x_cshake_keccak_final,
|
||||
s390x_cshake_keccak_squeeze,
|
||||
};
|
||||
|
||||
#define SHAKE_SET_MD(uname, typ) \
|
||||
|
|
@ -421,12 +448,12 @@ static PROV_SHA3_METHOD kmac_s390x_md = {
|
|||
} else { \
|
||||
ctx->meth = sha3_generic_md; \
|
||||
}
|
||||
#define KMAC_SET_MD(bitlen) \
|
||||
#define CSHAKE_KECCAK_SET_MD(bitlen) \
|
||||
if (S390_SHA3_CAPABLE(SHAKE_##bitlen)) { \
|
||||
ctx->pad = S390X_SHAKE_##bitlen; \
|
||||
ctx->meth = kmac_s390x_md; \
|
||||
ctx->meth = cshake_keccak_s390x_md; \
|
||||
} else { \
|
||||
ctx->meth = sha3_generic_md; \
|
||||
ctx->meth = shake_generic_md; \
|
||||
}
|
||||
#elif defined(__aarch64__) && defined(KECCAK1600_ASM)
|
||||
#include "arm_arch.h"
|
||||
|
|
@ -467,15 +494,15 @@ static PROV_SHA3_METHOD shake_ARMSHA3_md = {
|
|||
} else { \
|
||||
ctx->meth = sha3_generic_md; \
|
||||
}
|
||||
#define KMAC_SET_MD(bitlen) \
|
||||
#define CSHAKE_KECCAK_SET_MD(bitlen) \
|
||||
if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \
|
||||
ctx->meth = sha3_ARMSHA3_md; \
|
||||
ctx->meth = shake_ARMSHA3_md; \
|
||||
} else { \
|
||||
ctx->meth = sha3_generic_md; \
|
||||
ctx->meth = shake_generic_md; \
|
||||
}
|
||||
#else
|
||||
#define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;
|
||||
#define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md;
|
||||
#define CSHAKE_KECCAK_SET_MD(bitlen) ctx->meth = shake_generic_md;
|
||||
#define SHAKE_SET_MD(uname, typ) ctx->meth = shake_generic_md;
|
||||
#endif /* S390_SHA3 */
|
||||
|
||||
|
|
@ -509,7 +536,7 @@ static PROV_SHA3_METHOD shake_ARMSHA3_md = {
|
|||
return ctx; \
|
||||
}
|
||||
|
||||
#define KMAC_newctx(uname, bitlen, pad) \
|
||||
#define CSHAKE_KECCAK_newctx(uname, bitlen, pad) \
|
||||
static OSSL_FUNC_digest_newctx_fn uname##_newctx; \
|
||||
static void *uname##_newctx(void *provctx) \
|
||||
{ \
|
||||
|
|
@ -519,7 +546,7 @@ static PROV_SHA3_METHOD shake_ARMSHA3_md = {
|
|||
if (ctx == NULL) \
|
||||
return NULL; \
|
||||
ossl_keccak_init(ctx, pad, bitlen, 2 * bitlen); \
|
||||
KMAC_SET_MD(bitlen) \
|
||||
CSHAKE_KECCAK_SET_MD(bitlen) \
|
||||
return ctx; \
|
||||
}
|
||||
|
||||
|
|
@ -761,36 +788,37 @@ static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
|||
#define KECCAK_SER_ID 0x010000
|
||||
#define SHAKE_SER_ID 0x020000
|
||||
#define SHA3_SER_ID 0x040000
|
||||
#define KMAK_SER_ID 0x080000
|
||||
#define CSHAKE_KECCAK_SER_ID 0x080000
|
||||
|
||||
#define IMPLEMENT_SHA3_functions(bitlen) \
|
||||
SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, '\x06') \
|
||||
IMPLEMENT_SERIALIZE_FNS(sha3_##bitlen, SHA3_SER_ID + bitlen) \
|
||||
PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, \
|
||||
SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \
|
||||
#define IMPLEMENT_SHA3_functions(bitlen) \
|
||||
SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, (uint8_t)SHA3_PADDING) \
|
||||
IMPLEMENT_SERIALIZE_FNS(sha3_##bitlen, SHA3_SER_ID + bitlen) \
|
||||
PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, \
|
||||
SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \
|
||||
SHA3_FLAGS)
|
||||
|
||||
#define IMPLEMENT_KECCAK_functions(bitlen) \
|
||||
SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, '\x01') \
|
||||
IMPLEMENT_SERIALIZE_FNS(keccak_##bitlen, KECCAK_SER_ID + bitlen) \
|
||||
PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen, \
|
||||
SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \
|
||||
#define IMPLEMENT_KECCAK_functions(bitlen) \
|
||||
SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, (uint8_t)KECCAK_PADDING) \
|
||||
IMPLEMENT_SERIALIZE_FNS(keccak_##bitlen, KECCAK_SER_ID + bitlen) \
|
||||
PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen, \
|
||||
SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \
|
||||
SHA3_FLAGS)
|
||||
|
||||
#define IMPLEMENT_SHAKE_functions(bitlen) \
|
||||
SHAKE_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, \
|
||||
0 /* no default md length */, '\x1f') \
|
||||
0 /* no default md length */, (uint8_t)SHAKE_PADDING) \
|
||||
IMPLEMENT_SERIALIZE_FNS(shake_##bitlen, SHAKE_SER_ID + bitlen) \
|
||||
PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen, \
|
||||
SHA3_BLOCKSIZE(bitlen), 0, \
|
||||
SHAKE_FLAGS)
|
||||
|
||||
#define IMPLEMENT_KMAC_functions(bitlen) \
|
||||
KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04') \
|
||||
IMPLEMENT_SERIALIZE_FNS(keccak_kmac_##bitlen, KMAK_SER_ID + bitlen) \
|
||||
PROV_FUNC_SHAKE_DIGEST(keccak_kmac_##bitlen, bitlen, \
|
||||
SHA3_BLOCKSIZE(bitlen), KMAC_MDSIZE(bitlen), \
|
||||
KMAC_FLAGS)
|
||||
#define IMPLEMENT_CSHAKE_KECCAK_functions(bitlen) \
|
||||
CSHAKE_KECCAK_newctx(cshake_keccak_##bitlen, bitlen, (uint8_t)CSHAKE_KECCAK_PADDING) \
|
||||
IMPLEMENT_SERIALIZE_FNS(cshake_keccak_##bitlen, CSHAKE_KECCAK_SER_ID + bitlen) \
|
||||
PROV_FUNC_SHAKE_DIGEST(cshake_keccak_##bitlen, bitlen, \
|
||||
SHA3_BLOCKSIZE(bitlen), \
|
||||
CSHAKE_KECCAK_MDSIZE(bitlen), \
|
||||
CSHAKE_KECCAK_FLAGS)
|
||||
|
||||
/* ossl_sha3_224_functions */
|
||||
IMPLEMENT_SHA3_functions(224)
|
||||
|
|
@ -812,7 +840,7 @@ IMPLEMENT_KECCAK_functions(512)
|
|||
IMPLEMENT_SHAKE_functions(128)
|
||||
/* ossl_shake_256_functions */
|
||||
IMPLEMENT_SHAKE_functions(256)
|
||||
/* ossl_keccak_kmac_128_functions */
|
||||
IMPLEMENT_KMAC_functions(128)
|
||||
/* ossl_keccak_kmac_256_functions */
|
||||
IMPLEMENT_KMAC_functions(256)
|
||||
/* ossl_cshake_keccak_128_functions */
|
||||
IMPLEMENT_CSHAKE_KECCAK_functions(128)
|
||||
/* ossl_cshake_keccak_256_functions */
|
||||
IMPLEMENT_CSHAKE_KECCAK_functions(256)
|
||||
|
|
|
|||
|
|
@ -27,10 +27,12 @@ extern const OSSL_DISPATCH ossl_keccak_224_functions[];
|
|||
extern const OSSL_DISPATCH ossl_keccak_256_functions[];
|
||||
extern const OSSL_DISPATCH ossl_keccak_384_functions[];
|
||||
extern const OSSL_DISPATCH ossl_keccak_512_functions[];
|
||||
extern const OSSL_DISPATCH ossl_keccak_kmac_128_functions[];
|
||||
extern const OSSL_DISPATCH ossl_keccak_kmac_256_functions[];
|
||||
extern const OSSL_DISPATCH ossl_shake_128_functions[];
|
||||
extern const OSSL_DISPATCH ossl_shake_256_functions[];
|
||||
extern const OSSL_DISPATCH ossl_cshake_keccak_128_functions[];
|
||||
extern const OSSL_DISPATCH ossl_cshake_keccak_256_functions[];
|
||||
extern const OSSL_DISPATCH ossl_cshake_128_functions[];
|
||||
extern const OSSL_DISPATCH ossl_cshake_256_functions[];
|
||||
extern const OSSL_DISPATCH ossl_blake2s256_functions[];
|
||||
extern const OSSL_DISPATCH ossl_blake2b512_functions[];
|
||||
extern const OSSL_DISPATCH ossl_md5_functions[];
|
||||
|
|
|
|||
|
|
@ -248,12 +248,14 @@
|
|||
#define PROV_NAMES_SHAKE_128 "SHAKE-128:SHAKE128:2.16.840.1.101.3.4.2.11"
|
||||
#define PROV_NAMES_SHAKE_256 "SHAKE-256:SHAKE256:2.16.840.1.101.3.4.2.12"
|
||||
|
||||
/*
|
||||
* KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for
|
||||
* KMAC128 and KMAC256.
|
||||
*/
|
||||
#define PROV_NAMES_KECCAK_KMAC_128 "KECCAK-KMAC-128:KECCAK-KMAC128"
|
||||
#define PROV_NAMES_KECCAK_KMAC_256 "KECCAK-KMAC-256:KECCAK-KMAC256"
|
||||
#define PROV_NAMES_CSHAKE_128 "CSHAKE-128:CSHAKE128"
|
||||
#define PROV_NAMES_CSHAKE_256 "CSHAKE-256:CSHAKE256"
|
||||
|
||||
/* Internal algorithms used by CSHAKE variants */
|
||||
#define PROV_NAMES_CSHAKE_KECCAK_128 "CSHAKE-KECCAK-128:KECCAK-KMAC-128:KECCAK-KMAC128"
|
||||
#define PROV_NAMES_CSHAKE_KECCAK_256 "CSHAKE-KECCAK-256:KECCAK-KMAC-256:KECCAK-KMAC256"
|
||||
#define PROV_NAMES_KECCAK_KMAC_128 PROV_NAMES_CSHAKE_KECCAK_128
|
||||
#define PROV_NAMES_KECCAK_KMAC_256 PROV_NAMES_CSHAKE_KECCAK_256
|
||||
/*
|
||||
* https://blake2.net/ doesn't specify size variants, but mentions that
|
||||
* Bouncy Castle uses the names BLAKE2b-160, BLAKE2b-256, BLAKE2b-384, and
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@
|
|||
#include "prov/providercommon.h"
|
||||
#include "internal/cryptlib.h" /* ossl_assert */
|
||||
#include "providers/implementations/macs/kmac_prov.inc"
|
||||
#include "crypto/sha.h"
|
||||
|
||||
/*
|
||||
* Forward declaration of everything implemented here. This is not strictly
|
||||
|
|
@ -139,18 +140,8 @@ struct kmac_data_st {
|
|||
OSSL_FIPS_IND_DECLARE
|
||||
};
|
||||
|
||||
static int encode_string(unsigned char *out, size_t out_max_len, size_t *out_len,
|
||||
const unsigned char *in, size_t in_len);
|
||||
static int right_encode(unsigned char *out, size_t out_max_len, size_t *out_len,
|
||||
size_t bits);
|
||||
static int bytepad(unsigned char *out, size_t *out_len,
|
||||
const unsigned char *in1, size_t in1_len,
|
||||
const unsigned char *in2, size_t in2_len,
|
||||
size_t w);
|
||||
static int kmac_bytepad_encode_key(unsigned char *out, size_t out_max_len,
|
||||
size_t *out_len,
|
||||
const unsigned char *in, size_t in_len,
|
||||
size_t w);
|
||||
size_t *out_len, const unsigned char *in, size_t in_len, size_t w);
|
||||
|
||||
static void kmac_free(void *vmacctx)
|
||||
{
|
||||
|
|
@ -349,7 +340,7 @@ static int kmac_init(void *vmacctx, const unsigned char *key,
|
|||
(void)kmac_set_ctx_params(kctx, cparams);
|
||||
}
|
||||
|
||||
if (!bytepad(NULL, &out_len, kmac_string, sizeof(kmac_string),
|
||||
if (!ossl_sp800_185_bytepad(NULL, 0, &out_len, kmac_string, sizeof(kmac_string),
|
||||
kctx->custom, kctx->custom_len, block_len)) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
|
|
@ -357,7 +348,7 @@ static int kmac_init(void *vmacctx, const unsigned char *key,
|
|||
out = OPENSSL_malloc(out_len);
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
res = bytepad(out, NULL, kmac_string, sizeof(kmac_string),
|
||||
res = ossl_sp800_185_bytepad(out, out_len, NULL, kmac_string, sizeof(kmac_string),
|
||||
kctx->custom, kctx->custom_len, block_len)
|
||||
&& EVP_DigestUpdate(ctx, out, out_len)
|
||||
&& EVP_DigestUpdate(ctx, kctx->key, kctx->key_len);
|
||||
|
|
@ -388,7 +379,7 @@ static int kmac_final(void *vmacctx, unsigned char *out, size_t *outl,
|
|||
/* KMAC XOF mode sets the encoded length to 0 */
|
||||
lbits = (kctx->xof_mode ? 0 : (kctx->out_len * 8));
|
||||
|
||||
ok = right_encode(encoded_outlen, sizeof(encoded_outlen), &len, lbits)
|
||||
ok = ossl_sp800_185_right_encode(encoded_outlen, sizeof(encoded_outlen), &len, lbits)
|
||||
&& EVP_DigestUpdate(ctx, encoded_outlen, len)
|
||||
&& EVP_DigestFinalXOF(ctx, out, kctx->out_len);
|
||||
*outl = kctx->out_len;
|
||||
|
|
@ -493,7 +484,8 @@ static int kmac_set_ctx_params(void *vmacctx, const OSSL_PARAM *params)
|
|||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
if (!encode_string(kctx->custom, sizeof(kctx->custom), &kctx->custom_len,
|
||||
if (!ossl_sp800_185_encode_string(kctx->custom,
|
||||
sizeof(kctx->custom), &kctx->custom_len,
|
||||
p.custom->data, p.custom->data_size))
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -501,156 +493,18 @@ static int kmac_set_ctx_params(void *vmacctx, const OSSL_PARAM *params)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Encoding/Padding Methods. */
|
||||
|
||||
/* Returns the number of bytes required to store 'bits' into a byte array */
|
||||
static unsigned int get_encode_size(size_t bits)
|
||||
{
|
||||
unsigned int cnt = 0, sz = sizeof(size_t);
|
||||
|
||||
while (bits && (cnt < sz)) {
|
||||
++cnt;
|
||||
bits >>= 8;
|
||||
}
|
||||
/* If bits is zero 1 byte is required */
|
||||
if (cnt == 0)
|
||||
cnt = 1;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an integer into bytes . The number of bytes is appended
|
||||
* to the end of the buffer. Returns an array of bytes 'out' of size
|
||||
* *out_len.
|
||||
*
|
||||
* e.g if bits = 32, out[2] = { 0x20, 0x01 }
|
||||
*/
|
||||
static int right_encode(unsigned char *out, size_t out_max_len, size_t *out_len,
|
||||
size_t bits)
|
||||
{
|
||||
unsigned int len = get_encode_size(bits);
|
||||
int i;
|
||||
|
||||
if (len >= out_max_len) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MSB's are at the start of the bytes array */
|
||||
for (i = len - 1; i >= 0; --i) {
|
||||
out[i] = (unsigned char)(bits & 0xFF);
|
||||
bits >>= 8;
|
||||
}
|
||||
/* Tack the length onto the end */
|
||||
out[len] = (unsigned char)len;
|
||||
|
||||
/* The Returned length includes the tacked on byte */
|
||||
*out_len = len + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encodes a string with a left encoded length added. Note that the
|
||||
* in_len is converted to bits (*8).
|
||||
*
|
||||
* e.g- in="KMAC" gives out[6] = { 0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43 }
|
||||
* len bits K M A C
|
||||
*/
|
||||
static int encode_string(unsigned char *out, size_t out_max_len, size_t *out_len,
|
||||
const unsigned char *in, size_t in_len)
|
||||
{
|
||||
if (in == NULL) {
|
||||
*out_len = 0;
|
||||
} else {
|
||||
size_t i, bits, len, sz;
|
||||
|
||||
bits = 8 * in_len;
|
||||
len = get_encode_size(bits);
|
||||
sz = 1 + len + in_len;
|
||||
|
||||
if (sz > out_max_len) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
out[0] = (unsigned char)len;
|
||||
for (i = len; i > 0; --i) {
|
||||
out[i] = (bits & 0xFF);
|
||||
bits >>= 8;
|
||||
}
|
||||
memcpy(out + len + 1, in, in_len);
|
||||
*out_len = sz;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a zero padded encoding of the inputs in1 and an optional
|
||||
* in2 (can be NULL). The padded output must be a multiple of the blocksize 'w'.
|
||||
* The value of w is in bytes (< 256).
|
||||
*
|
||||
* The returned output is:
|
||||
* zero_padded(multiple of w, (left_encode(w) || in1 [|| in2])
|
||||
*/
|
||||
static int bytepad(unsigned char *out, size_t *out_len,
|
||||
const unsigned char *in1, size_t in1_len,
|
||||
const unsigned char *in2, size_t in2_len, size_t w)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *p = out;
|
||||
size_t sz = w;
|
||||
|
||||
if (out == NULL) {
|
||||
if (out_len == NULL) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
sz = 2 + in1_len + (in2 != NULL ? in2_len : 0);
|
||||
*out_len = (sz + w - 1) / w * w;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ossl_assert(w <= 255))
|
||||
return 0;
|
||||
|
||||
/* Left encoded w */
|
||||
*p++ = 1;
|
||||
*p++ = (unsigned char)w;
|
||||
/* || in1 */
|
||||
memcpy(p, in1, in1_len);
|
||||
p += in1_len;
|
||||
/* [ || in2 ] */
|
||||
if (in2 != NULL && in2_len > 0) {
|
||||
memcpy(p, in2, in2_len);
|
||||
p += in2_len;
|
||||
}
|
||||
/* Figure out the pad size (divisible by w) */
|
||||
len = p - out;
|
||||
sz = (len + w - 1) / w * w;
|
||||
/* zero pad the end of the buffer */
|
||||
if (sz != len)
|
||||
memset(p, 0, sz - len);
|
||||
if (out_len != NULL)
|
||||
*out_len = sz;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns out = bytepad(encode_string(in), w) */
|
||||
static int kmac_bytepad_encode_key(unsigned char *out, size_t out_max_len,
|
||||
size_t *out_len,
|
||||
const unsigned char *in, size_t in_len,
|
||||
size_t w)
|
||||
size_t *out_len, const unsigned char *in, size_t in_len, size_t w)
|
||||
{
|
||||
unsigned char tmp[KMAC_MAX_KEY + KMAC_MAX_ENCODED_HEADER_LEN];
|
||||
size_t tmp_len;
|
||||
|
||||
if (!encode_string(tmp, sizeof(tmp), &tmp_len, in, in_len))
|
||||
if (!ossl_sp800_185_encode_string(tmp, sizeof(tmp), &tmp_len, in, in_len))
|
||||
return 0;
|
||||
if (!bytepad(NULL, out_len, tmp, tmp_len, NULL, 0, w))
|
||||
if (!ossl_sp800_185_bytepad(NULL, out_max_len, out_len, tmp, tmp_len, NULL, 0, w))
|
||||
return 0;
|
||||
if (!ossl_assert(*out_len <= out_max_len))
|
||||
return 0;
|
||||
return bytepad(out, NULL, tmp, tmp_len, NULL, 0, w);
|
||||
return ossl_sp800_185_bytepad(out, out_max_len, NULL, tmp, tmp_len, NULL, 0, w);
|
||||
}
|
||||
|
||||
#define IMPLEMENT_KMAC_TABLE(size, funcname, newname) \
|
||||
|
|
|
|||
|
|
@ -712,6 +712,7 @@ typedef struct digest_data_st {
|
|||
int xof;
|
||||
/* Size for variable output length but non-XOF */
|
||||
size_t digest_size;
|
||||
STACK_OF(OPENSSL_STRING) *controls; /* collection of controls */
|
||||
} DIGEST_DATA;
|
||||
|
||||
static int digest_test_init(EVP_TEST *t, const char *alg)
|
||||
|
|
@ -738,6 +739,7 @@ static int digest_test_init(EVP_TEST *t, const char *alg)
|
|||
mdat->fetched_digest = fetched_digest;
|
||||
mdat->pad_type = 0;
|
||||
mdat->xof = 0;
|
||||
mdat->controls = sk_OPENSSL_STRING_new_null();
|
||||
if (fetched_digest != NULL)
|
||||
TEST_info("%s is fetched", alg);
|
||||
return 1;
|
||||
|
|
@ -750,6 +752,7 @@ static void digest_test_cleanup(EVP_TEST *t)
|
|||
sk_EVP_TEST_BUFFER_pop_free(mdat->input, evp_test_buffer_free);
|
||||
OPENSSL_free(mdat->output);
|
||||
EVP_MD_free(mdat->fetched_digest);
|
||||
ctrlfree(mdat->controls);
|
||||
}
|
||||
|
||||
static int digest_test_parse(EVP_TEST *t,
|
||||
|
|
@ -778,6 +781,8 @@ static int digest_test_parse(EVP_TEST *t,
|
|||
mdata->digest_size = sz;
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(keyword, "Ctrl") == 0)
|
||||
return ctrladd(mdata->controls, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -815,7 +820,9 @@ static int digest_test_run(EVP_TEST *t)
|
|||
unsigned int got_len;
|
||||
size_t size = 0;
|
||||
int xof = 0;
|
||||
OSSL_PARAM params[4], *p = ¶ms[0];
|
||||
OSSL_PARAM params[6], *p = ¶ms[0];
|
||||
size_t params_n = 0, params_allocated_n = 0;
|
||||
const OSSL_PARAM *defined_params = EVP_MD_settable_ctx_params(expected->digest);
|
||||
|
||||
t->err = "TEST_FAILURE";
|
||||
if (!TEST_ptr(mctx = EVP_MD_CTX_new()))
|
||||
|
|
@ -825,6 +832,13 @@ static int digest_test_run(EVP_TEST *t)
|
|||
if (!TEST_ptr(got))
|
||||
goto err;
|
||||
|
||||
if (sk_OPENSSL_STRING_num(expected->controls) > 0) {
|
||||
if (!ctrl2params(t, expected->controls, defined_params,
|
||||
params, OSSL_NELEM(params), ¶ms_n))
|
||||
return 0;
|
||||
p = params + params_n;
|
||||
}
|
||||
|
||||
if (expected->xof > 0) {
|
||||
xof |= 1;
|
||||
*p++ = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN,
|
||||
|
|
@ -907,6 +921,7 @@ static int digest_test_run(EVP_TEST *t)
|
|||
}
|
||||
|
||||
err:
|
||||
ctrl2params_free(params, params_n, params_allocated_n);
|
||||
OPENSSL_free(got);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "testutil.h"
|
||||
#include "internal/nelem.h"
|
||||
|
||||
static const unsigned char shake256_input[] = {
|
||||
static const uint8_t shake256_input[] = {
|
||||
0x8d, 0x80, 0x01, 0xe2, 0xc0, 0x96, 0xf1, 0xb8,
|
||||
0x8e, 0x7c, 0x92, 0x24, 0xa0, 0x86, 0xef, 0xd4,
|
||||
0x79, 0x7f, 0xbf, 0x74, 0xa8, 0x03, 0x3a, 0x2d,
|
||||
|
|
@ -24,7 +24,7 @@ static const unsigned char shake256_input[] = {
|
|||
* This KAT output is 250 bytes, which is more than
|
||||
* the SHAKE256 block size (136 bytes).
|
||||
*/
|
||||
static const unsigned char shake256_output[] = {
|
||||
static const uint8_t shake256_output[] = {
|
||||
0x2e, 0x97, 0x5f, 0x6a, 0x8a, 0x14, 0xf0, 0x70,
|
||||
0x4d, 0x51, 0xb1, 0x36, 0x67, 0xd8, 0x19, 0x5c,
|
||||
0x21, 0x9f, 0x71, 0xe6, 0x34, 0x56, 0x96, 0xc4,
|
||||
|
|
@ -59,6 +59,52 @@ static const unsigned char shake256_output[] = {
|
|||
0x66, 0x6c
|
||||
};
|
||||
|
||||
static const uint8_t cshake256_output[] = {
|
||||
0x30, 0xa6, 0x5f, 0xd5, 0xff, 0x3e, 0x49, 0xe8,
|
||||
0xa9, 0xef, 0x06, 0xa3, 0x56, 0x4b, 0x4f, 0x55,
|
||||
0x93, 0x0f, 0x4a, 0x9e, 0xe9, 0x74, 0x13, 0xf8,
|
||||
0x4a, 0x80, 0x44, 0x65, 0xec, 0x62, 0x83, 0x7a,
|
||||
0x21, 0xce, 0x96, 0x0e, 0x27, 0x1f, 0x81, 0x26,
|
||||
0xcb, 0xd8, 0x42, 0x7b, 0x7d, 0x71, 0x6a, 0xdc,
|
||||
0xaf, 0x4d, 0x13, 0x52, 0x28, 0x2b, 0xd9, 0x70,
|
||||
0xfb, 0x90, 0x96, 0xfe, 0x24, 0xd2, 0x22, 0x48,
|
||||
0x73, 0xae, 0x73, 0x1e, 0x10, 0x07, 0x4b, 0x92,
|
||||
0x2a, 0xae, 0x1e, 0x7b, 0x7d, 0x06, 0xe2, 0x0f,
|
||||
0x80, 0x08, 0xc3, 0xa5, 0x09, 0x71, 0x57, 0x84,
|
||||
0x4a, 0xa8, 0x70, 0xe7, 0x61, 0x6b, 0x0c, 0x3c
|
||||
};
|
||||
|
||||
typedef struct test_data_st {
|
||||
const char *alg;
|
||||
const uint8_t *in;
|
||||
size_t inlen;
|
||||
const uint8_t *out;
|
||||
size_t outlen;
|
||||
int default_xoflen;
|
||||
const char *param_n;
|
||||
const char *param_s;
|
||||
} TEST_DATA;
|
||||
|
||||
static const TEST_DATA xof_test_data[] = {
|
||||
{
|
||||
"SHAKE256",
|
||||
shake256_input,
|
||||
sizeof(shake256_input),
|
||||
shake256_output,
|
||||
sizeof(shake256_output),
|
||||
},
|
||||
{ "CSHAKE256",
|
||||
shake256_input, sizeof(shake256_input),
|
||||
shake256_output, sizeof(shake256_output),
|
||||
64 },
|
||||
{ "CSHAKE256",
|
||||
shake256_input, sizeof(shake256_input),
|
||||
cshake256_output, sizeof(cshake256_output),
|
||||
64,
|
||||
"KMAC",
|
||||
"Custom" },
|
||||
};
|
||||
|
||||
static const unsigned char shake256_largemsg_input[] = {
|
||||
0xb2, 0xd2, 0x38, 0x65, 0xaf, 0x8f, 0x25, 0x6e,
|
||||
0x64, 0x40, 0xe2, 0x0d, 0x49, 0x8e, 0x3e, 0x64,
|
||||
|
|
@ -149,51 +195,39 @@ static const unsigned char shake256_largemsg_input[] = {
|
|||
};
|
||||
|
||||
static const unsigned char shake256_largemsg_output[] = {
|
||||
0x64,
|
||||
0xea,
|
||||
0x24,
|
||||
0x6a,
|
||||
0xab,
|
||||
0x80,
|
||||
0x37,
|
||||
0x9e,
|
||||
0x08,
|
||||
0xe2,
|
||||
0x19,
|
||||
0x9e,
|
||||
0x09,
|
||||
0x69,
|
||||
0xe2,
|
||||
0xee,
|
||||
0x1a,
|
||||
0x5d,
|
||||
0xd1,
|
||||
0x68,
|
||||
0x68,
|
||||
0xec,
|
||||
0x8d,
|
||||
0x42,
|
||||
0xd0,
|
||||
0xf8,
|
||||
0xb8,
|
||||
0x44,
|
||||
0x74,
|
||||
0x54,
|
||||
0x87,
|
||||
0x3e,
|
||||
0x64, 0xea, 0x24, 0x6a, 0xab, 0x80, 0x37, 0x9e,
|
||||
0x08, 0xe2, 0x19, 0x9e, 0x09, 0x69, 0xe2, 0xee,
|
||||
0x1a, 0x5d, 0xd1, 0x68, 0x68, 0xec, 0x8d, 0x42,
|
||||
0xd0, 0xf8, 0xb8, 0x44, 0x74, 0x54, 0x87, 0x3e
|
||||
};
|
||||
|
||||
static EVP_MD_CTX *shake_setup(const char *name)
|
||||
static const TEST_DATA large_msg_test_data[] = {
|
||||
{
|
||||
"SHAKE256",
|
||||
shake256_largemsg_input,
|
||||
sizeof(shake256_largemsg_input),
|
||||
shake256_largemsg_output,
|
||||
sizeof(shake256_largemsg_output),
|
||||
},
|
||||
};
|
||||
|
||||
static EVP_MD_CTX *xof_digest_setup(const TEST_DATA *td)
|
||||
{
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
EVP_MD *md = NULL;
|
||||
OSSL_PARAM params[3], *p = params;
|
||||
|
||||
if (!TEST_ptr(md = EVP_MD_fetch(NULL, name, NULL)))
|
||||
if (!TEST_ptr(md = EVP_MD_fetch(NULL, td->alg, NULL)))
|
||||
return NULL;
|
||||
|
||||
if (!TEST_ptr(ctx = EVP_MD_CTX_new()))
|
||||
goto err;
|
||||
if (!TEST_true(EVP_DigestInit_ex2(ctx, md, NULL)))
|
||||
if (td->param_n != NULL)
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_FUNCTION_NAME, (char *)td->param_n, 0);
|
||||
if (td->param_s != NULL)
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_CUSTOMIZATION, (char *)td->param_s, 0);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
if (!TEST_true(EVP_DigestInit_ex2(ctx, md, params)))
|
||||
goto err;
|
||||
EVP_MD_free(md);
|
||||
return ctx;
|
||||
|
|
@ -203,23 +237,24 @@ err:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int shake_kat_test(void)
|
||||
static int xof_kat_test(int tstid)
|
||||
{
|
||||
const TEST_DATA *td = xof_test_data + tstid;
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
unsigned char out[sizeof(shake256_output)];
|
||||
uint8_t out[2048];
|
||||
|
||||
if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
|
||||
if (!TEST_size_t_le(td->outlen, sizeof(out)))
|
||||
return 0;
|
||||
if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
|
||||
sizeof(shake256_input)))
|
||||
|| !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
|
||||
|| !TEST_mem_eq(out, sizeof(out),
|
||||
shake256_output, sizeof(shake256_output))
|
||||
if (!TEST_ptr(ctx = xof_digest_setup(td)))
|
||||
return 0;
|
||||
if (!TEST_true(EVP_DigestUpdate(ctx, td->in, td->inlen))
|
||||
|| !TEST_true(EVP_DigestFinalXOF(ctx, out, td->outlen))
|
||||
|| !TEST_mem_eq(out, td->outlen, td->out, td->outlen)
|
||||
/* Test that a second call to EVP_DigestFinalXOF fails */
|
||||
|| !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
|
||||
|| !TEST_false(EVP_DigestFinalXOF(ctx, out, td->outlen))
|
||||
/* Test that a call to EVP_DigestSqueeze fails */
|
||||
|| !TEST_false(EVP_DigestSqueeze(ctx, out, sizeof(out))))
|
||||
|| !TEST_false(EVP_DigestSqueeze(ctx, out, td->outlen)))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
|
|
@ -227,37 +262,52 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int shake_kat_digestfinal_test(void)
|
||||
static int xof_kat_digestfinal_test(int tstid)
|
||||
{
|
||||
const TEST_DATA *td = xof_test_data + tstid;
|
||||
int ret = 0;
|
||||
unsigned int digest_length = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
unsigned char out[sizeof(shake256_output)];
|
||||
uint8_t out[2048];
|
||||
|
||||
/* Test that EVP_DigestFinal without setting XOFLEN fails */
|
||||
if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
|
||||
if (!TEST_size_t_le(td->outlen, sizeof(out)))
|
||||
return 0;
|
||||
if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
|
||||
sizeof(shake256_input))))
|
||||
return 0;
|
||||
ERR_set_mark();
|
||||
if (!TEST_false(EVP_DigestFinal(ctx, out, &digest_length))) {
|
||||
ERR_clear_last_mark();
|
||||
if (!TEST_ptr(ctx = xof_digest_setup(td)))
|
||||
return 0;
|
||||
if (!TEST_true(EVP_DigestUpdate(ctx, td->in, td->inlen)))
|
||||
goto err;
|
||||
if (td->default_xoflen == 0) {
|
||||
/*
|
||||
* Test that EVP_DigestFinal without setting XOFLEN fails for SHAKE
|
||||
* (The original code for SHAKE set the wrong default value which is
|
||||
* why the XOF needs to be set for this).
|
||||
*/
|
||||
ERR_set_mark();
|
||||
if (!TEST_false(EVP_DigestFinal(ctx, out, &digest_length))) {
|
||||
ERR_clear_last_mark();
|
||||
goto err;
|
||||
}
|
||||
ERR_pop_to_mark();
|
||||
} else {
|
||||
/*
|
||||
* Test that EVP_DigestFinal without setting XOFLEN passes for CSHAKE
|
||||
* and correctly returns 2 * 256 = 512 bits (64 bytes) by default.
|
||||
*/
|
||||
if (!TEST_true(EVP_DigestFinal(ctx, out, &digest_length))
|
||||
|| !TEST_uint_eq(digest_length, td->default_xoflen)
|
||||
|| !TEST_mem_eq(out, digest_length, td->out, digest_length))
|
||||
goto err;
|
||||
}
|
||||
ERR_pop_to_mark();
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
/* However EVP_DigestFinalXOF must work */
|
||||
if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
|
||||
/* EVP_DigestFinalXOF must work */
|
||||
if (!TEST_ptr(ctx = xof_digest_setup(td)))
|
||||
return 0;
|
||||
if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
|
||||
sizeof(shake256_input))))
|
||||
return 0;
|
||||
if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
|
||||
|| !TEST_mem_eq(out, sizeof(out),
|
||||
shake256_output, sizeof(shake256_output))
|
||||
|| !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
|
||||
if (!TEST_true(EVP_DigestUpdate(ctx, td->in, td->inlen)))
|
||||
goto err;
|
||||
if (!TEST_true(EVP_DigestFinalXOF(ctx, out, td->outlen))
|
||||
|| !TEST_mem_eq(out, td->outlen, td->out, td->outlen)
|
||||
|| !TEST_false(EVP_DigestFinalXOF(ctx, out, td->outlen)))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
|
|
@ -269,35 +319,37 @@ err:
|
|||
* Test that EVP_DigestFinal() returns the output length
|
||||
* set by the OSSL_DIGEST_PARAM_XOFLEN param.
|
||||
*/
|
||||
static int shake_kat_digestfinal_xoflen_test(void)
|
||||
static int xof_kat_digestfinal_xoflen_test(int tstid)
|
||||
{
|
||||
const TEST_DATA *td = xof_test_data + tstid;
|
||||
int ret = 0;
|
||||
unsigned int digest_length = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
const EVP_MD *md;
|
||||
unsigned char out[sizeof(shake256_output)];
|
||||
OSSL_PARAM params[2];
|
||||
size_t sz = 12;
|
||||
uint8_t out[2048];
|
||||
|
||||
if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
|
||||
if (!TEST_size_t_le(td->outlen, sizeof(out)))
|
||||
return 0;
|
||||
if (!TEST_ptr(ctx = xof_digest_setup(td)))
|
||||
return 0;
|
||||
|
||||
md = EVP_MD_CTX_get0_md(ctx);
|
||||
|
||||
memset(out, 0, sizeof(out));
|
||||
memset(out, 0, td->outlen);
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!TEST_int_eq(EVP_MD_CTX_size(ctx), -1)
|
||||
if (!TEST_int_eq(EVP_MD_CTX_size(ctx), td->default_xoflen == 0 ? -1 : td->default_xoflen)
|
||||
|| !TEST_int_eq(EVP_MD_CTX_set_params(ctx, params), 1)
|
||||
|| !TEST_int_eq(EVP_MD_CTX_size(ctx), (int)sz)
|
||||
|| !TEST_int_eq(EVP_MD_get_size(md), 0)
|
||||
|| !TEST_int_eq(EVP_MD_get_size(md), td->default_xoflen)
|
||||
|| !TEST_true(EVP_MD_xof(md))
|
||||
|| !TEST_true(EVP_DigestUpdate(ctx, shake256_input,
|
||||
sizeof(shake256_input)))
|
||||
|| !TEST_true(EVP_DigestUpdate(ctx, td->in, td->inlen))
|
||||
|| !TEST_true(EVP_DigestFinal(ctx, out, &digest_length))
|
||||
|| !TEST_uint_eq(digest_length, (unsigned int)sz)
|
||||
|| !TEST_mem_eq(out, digest_length,
|
||||
shake256_output, digest_length)
|
||||
|| !TEST_mem_eq(out, digest_length, td->out, digest_length)
|
||||
|| !TEST_uchar_eq(out[digest_length], 0))
|
||||
goto err;
|
||||
ret = 1;
|
||||
|
|
@ -310,15 +362,18 @@ err:
|
|||
* Test that multiple absorb calls gives the expected result.
|
||||
* This is a nested test that uses multiple strides for the input.
|
||||
*/
|
||||
static int shake_absorb_test(void)
|
||||
static int xof_absorb_test(int tstid)
|
||||
{
|
||||
const TEST_DATA *td = large_msg_test_data + tstid;
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
unsigned char out[sizeof(shake256_largemsg_output)];
|
||||
size_t total = sizeof(shake256_largemsg_input);
|
||||
unsigned char out[2048];
|
||||
size_t total = td->inlen;
|
||||
size_t i, stride, sz;
|
||||
|
||||
if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
|
||||
if (!TEST_size_t_le(td->outlen, sizeof(out)))
|
||||
return 0;
|
||||
if (!TEST_ptr(ctx = xof_digest_setup(td)))
|
||||
return 0;
|
||||
|
||||
for (stride = 1; stride < total; ++stride) {
|
||||
|
|
@ -327,14 +382,11 @@ static int shake_absorb_test(void)
|
|||
sz += stride;
|
||||
if ((i + sz) > total)
|
||||
sz = total - i;
|
||||
if (!TEST_true(EVP_DigestUpdate(ctx, shake256_largemsg_input + i,
|
||||
sz)))
|
||||
if (!TEST_true(EVP_DigestUpdate(ctx, td->in + i, sz)))
|
||||
goto err;
|
||||
}
|
||||
if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
|
||||
|| !TEST_mem_eq(out, sizeof(out),
|
||||
shake256_largemsg_output,
|
||||
sizeof(shake256_largemsg_output)))
|
||||
if (!TEST_true(EVP_DigestFinalXOF(ctx, out, td->outlen))
|
||||
|| !TEST_mem_eq(out, td->outlen, td->out, td->outlen))
|
||||
goto err;
|
||||
if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL)))
|
||||
goto err;
|
||||
|
|
@ -349,9 +401,11 @@ err:
|
|||
* Table containing the size of the output to squeeze for the
|
||||
* initially call, followed by a size for each subsequent call.
|
||||
*/
|
||||
static const struct {
|
||||
typedef struct stride_test_data_st {
|
||||
size_t startsz, incsz;
|
||||
} stride_tests[] = {
|
||||
} STRIDE_TEST_DATA;
|
||||
|
||||
static const STRIDE_TEST_DATA stride_test_data[] = {
|
||||
{ 1, 1 },
|
||||
{ 1, 136 },
|
||||
{ 1, 136 / 2 },
|
||||
|
|
@ -394,17 +448,18 @@ static const struct {
|
|||
* in and inlen represent the input to absorb. expected_out and expected_outlen
|
||||
* represent the expected output.
|
||||
*/
|
||||
static int do_shake_squeeze_test(int tst,
|
||||
const unsigned char *in, size_t inlen,
|
||||
const unsigned char *expected_out,
|
||||
static int do_xof_squeeze_test(const TEST_DATA *td,
|
||||
const STRIDE_TEST_DATA *stride,
|
||||
const uint8_t *in, size_t inlen,
|
||||
const uint8_t *expected_out,
|
||||
size_t expected_outlen)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
unsigned char *out = NULL;
|
||||
size_t i = 0, sz = stride_tests[tst].startsz;
|
||||
size_t i = 0, sz = stride->startsz;
|
||||
|
||||
if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
|
||||
if (!TEST_ptr(ctx = xof_digest_setup(td)))
|
||||
return 0;
|
||||
if (!TEST_ptr(out = OPENSSL_malloc(expected_outlen)))
|
||||
goto err;
|
||||
|
|
@ -417,7 +472,7 @@ static int do_shake_squeeze_test(int tst,
|
|||
if (!TEST_true(EVP_DigestSqueeze(ctx, out + i, sz)))
|
||||
goto err;
|
||||
i += sz;
|
||||
sz = stride_tests[tst].incsz;
|
||||
sz = stride->incsz;
|
||||
}
|
||||
if (!TEST_mem_eq(out, expected_outlen, expected_out, expected_outlen))
|
||||
goto err;
|
||||
|
|
@ -428,10 +483,12 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int shake_squeeze_kat_test(int tst)
|
||||
static int xof_squeeze_kat_test(int tstid)
|
||||
{
|
||||
return do_shake_squeeze_test(tst, shake256_input, sizeof(shake256_input),
|
||||
shake256_output, sizeof(shake256_output));
|
||||
const STRIDE_TEST_DATA *sd = stride_test_data + tstid;
|
||||
const TEST_DATA *td = xof_test_data + (tstid % (OSSL_NELEM(xof_test_data)));
|
||||
|
||||
return do_xof_squeeze_test(td, sd, td->in, td->inlen, td->out, td->outlen);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -440,42 +497,42 @@ static int shake_squeeze_kat_test(int tst)
|
|||
* output. Use this to test that multiple squeeze calls
|
||||
* on the same input gives the same output.
|
||||
*/
|
||||
static int shake_squeeze_large_test(int tst)
|
||||
static int xof_squeeze_large_test(int tstid)
|
||||
{
|
||||
const STRIDE_TEST_DATA *sd = stride_test_data + tstid;
|
||||
const TEST_DATA *td = xof_test_data + (tstid % (OSSL_NELEM(xof_test_data)));
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
unsigned char msg[16];
|
||||
unsigned char out[2000];
|
||||
|
||||
if (!TEST_int_gt(RAND_bytes(msg, sizeof(msg)), 0)
|
||||
|| !TEST_ptr(ctx = shake_setup("SHAKE256"))
|
||||
|| !TEST_ptr(ctx = xof_digest_setup(td))
|
||||
|| !TEST_true(EVP_DigestUpdate(ctx, msg, sizeof(msg)))
|
||||
|| !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
|
||||
goto err;
|
||||
|
||||
ret = do_shake_squeeze_test(tst, msg, sizeof(msg), out, sizeof(out));
|
||||
ret = do_xof_squeeze_test(td, sd, msg, sizeof(msg), out, sizeof(out));
|
||||
err:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const size_t dupoffset_tests[] = {
|
||||
static const size_t dupoffset_test_data[] = {
|
||||
1, 135, 136, 137, 136 * 3 - 1, 136 * 3, 136 * 3 + 1
|
||||
};
|
||||
|
||||
/* Helper function to test that EVP_MD_CTX_dup() copies the internal state */
|
||||
static int do_shake_squeeze_dup_test(int tst, const char *alg,
|
||||
const unsigned char *in, size_t inlen,
|
||||
const unsigned char *expected_out,
|
||||
size_t expected_outlen)
|
||||
static int do_xof_squeeze_dup_test(const TEST_DATA *td, size_t dupoffset,
|
||||
const uint8_t *in, size_t inlen,
|
||||
const uint8_t *expected_out, size_t expected_outlen)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *cur, *ctx = NULL, *dupctx = NULL;
|
||||
unsigned char *out = NULL;
|
||||
size_t i = 0, sz = 10;
|
||||
size_t dupoffset = dupoffset_tests[tst];
|
||||
|
||||
if (!TEST_ptr(ctx = shake_setup(alg)))
|
||||
if (!TEST_ptr(ctx = xof_digest_setup(td)))
|
||||
return 0;
|
||||
cur = ctx;
|
||||
if (!TEST_ptr(out = OPENSSL_malloc(expected_outlen)))
|
||||
|
|
@ -507,21 +564,22 @@ err:
|
|||
}
|
||||
|
||||
/* Test that the internal state can be copied */
|
||||
static int shake_squeeze_dup_test(int tst)
|
||||
static int xof_squeeze_dup_test(int tstid)
|
||||
{
|
||||
size_t dupoffset = dupoffset_test_data[tstid];
|
||||
const TEST_DATA *td = xof_test_data + (tstid % (OSSL_NELEM(xof_test_data)));
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
unsigned char msg[16];
|
||||
unsigned char out[1000];
|
||||
const char *alg = "SHAKE128";
|
||||
|
||||
if (!TEST_int_gt(RAND_bytes(msg, sizeof(msg)), 0)
|
||||
|| !TEST_ptr(ctx = shake_setup(alg))
|
||||
|| !TEST_ptr(ctx = xof_digest_setup(td))
|
||||
|| !TEST_true(EVP_DigestUpdate(ctx, msg, sizeof(msg)))
|
||||
|| !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
|
||||
goto err;
|
||||
|
||||
ret = do_shake_squeeze_dup_test(tst, alg, msg, sizeof(msg),
|
||||
ret = do_xof_squeeze_dup_test(td, dupoffset, msg, sizeof(msg),
|
||||
out, sizeof(out));
|
||||
err:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
|
@ -529,30 +587,29 @@ err:
|
|||
}
|
||||
|
||||
/* Test that a squeeze without a preceding absorb works */
|
||||
static int shake_squeeze_no_absorb_test(void)
|
||||
static int xof_squeeze_no_absorb_test(int tstid)
|
||||
{
|
||||
const TEST_DATA *td = xof_test_data + tstid;
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
EVP_MD_CTX *ctx = NULL, *ctx2 = NULL;
|
||||
unsigned char out[1000];
|
||||
unsigned char out2[1000];
|
||||
const char *alg = "SHAKE128";
|
||||
|
||||
if (!TEST_ptr(ctx = shake_setup(alg))
|
||||
|| !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL))
|
||||
|| !TEST_true(EVP_DigestSqueeze(ctx, out2, sizeof(out2) / 2))
|
||||
|| !TEST_true(EVP_DigestSqueeze(ctx, out2 + sizeof(out2) / 2,
|
||||
sizeof(out2) / 2)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_mem_eq(out2, sizeof(out2), out, sizeof(out)))
|
||||
memset(out, 0, sizeof(out));
|
||||
memset(out2, 0, sizeof(out2));
|
||||
if (!TEST_ptr(ctx = xof_digest_setup(td))
|
||||
|| !TEST_ptr(ctx2 = EVP_MD_CTX_dup(ctx))
|
||||
|| !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
|
||||
|| !TEST_true(EVP_DigestSqueeze(ctx2, out2, sizeof(out2) / 2))
|
||||
|| !TEST_true(EVP_DigestSqueeze(ctx2, out2 + sizeof(out2) / 2,
|
||||
sizeof(out2) / 2))
|
||||
|| !TEST_mem_eq(out2, sizeof(out2), out, sizeof(out)))
|
||||
goto err;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
EVP_MD_CTX_free(ctx2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -569,14 +626,14 @@ static int xof_fail_test(void)
|
|||
|
||||
int setup_tests(void)
|
||||
{
|
||||
ADD_TEST(shake_kat_test);
|
||||
ADD_TEST(shake_kat_digestfinal_test);
|
||||
ADD_TEST(shake_kat_digestfinal_xoflen_test);
|
||||
ADD_TEST(shake_absorb_test);
|
||||
ADD_ALL_TESTS(shake_squeeze_kat_test, OSSL_NELEM(stride_tests));
|
||||
ADD_ALL_TESTS(shake_squeeze_large_test, OSSL_NELEM(stride_tests));
|
||||
ADD_ALL_TESTS(shake_squeeze_dup_test, OSSL_NELEM(dupoffset_tests));
|
||||
ADD_ALL_TESTS(xof_kat_test, OSSL_NELEM(xof_test_data));
|
||||
ADD_ALL_TESTS(xof_kat_digestfinal_test, OSSL_NELEM(xof_test_data));
|
||||
ADD_ALL_TESTS(xof_kat_digestfinal_xoflen_test, OSSL_NELEM(xof_test_data));
|
||||
ADD_ALL_TESTS(xof_squeeze_no_absorb_test, OSSL_NELEM(xof_test_data));
|
||||
ADD_ALL_TESTS(xof_absorb_test, OSSL_NELEM(large_msg_test_data));
|
||||
ADD_ALL_TESTS(xof_squeeze_kat_test, OSSL_NELEM(stride_test_data));
|
||||
ADD_ALL_TESTS(xof_squeeze_large_test, OSSL_NELEM(stride_test_data));
|
||||
ADD_ALL_TESTS(xof_squeeze_dup_test, OSSL_NELEM(dupoffset_test_data));
|
||||
ADD_TEST(xof_fail_test);
|
||||
ADD_TEST(shake_squeeze_no_absorb_test);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -384,7 +384,93 @@ Digest = KECCAK-512
|
|||
Input = 4FBDC596508D24A2A0010E140980B809FB9C6D55EC75125891DD985D37665BD80F9BEB6A50207588ABF3CEEE8C77CD8A5AD48A9E0AA074ED388738362496D2FB2C87543BB3349EA64997CE3E7B424EA92D122F57DBB0855A803058437FE08AFB0C8B5E7179B9044BBF4D81A7163B3139E30888B536B0F957EFF99A7162F4CA5AA756A4A982DFADBF31EF255083C4B5C6C1B99A107D7D3AFFFDB89147C2CC4C9A2643F478E5E2D393AEA37B4C7CB4B5E97DADCF16B6B50AAE0F3B549ECE47746DB6CE6F67DD4406CD4E75595D5103D13F9DFA79372924D328F8DD1FCBEB5A8E2E8BF4C76DE08E3FC46AA021F989C49329C7ACAC5A688556D7BCBCB2A5D4BE69D3284E9C40EC4838EE8592120CE20A0B635ECADAA84FD5690509F54F77E35A417C584648BC9839B974E07BFAB0038E90295D0B13902530A830D1C2BDD53F1F9C9FAED43CA4EED0A8DD761BC7EDBDDA28A287C60CD42AF5F9C758E5C7250231C09A582563689AFC65E2B79A7A2B68200667752E9101746F03184E2399E4ED8835CB8E9AE90E296AF220AE234259FE0BD0BCC60F7A4A5FF3F70C5ED4DE9C8C519A10E962F673C82C5E9351786A8A3BFD570031857BD4C87F4FCA31ED4D50E14F2107DA02CB5058700B74EA241A8B41D78461658F1B2B90BFD84A4C2C9D6543861AB3C56451757DCFB9BA60333488DBDD02D601B41AAE317CA7474EB6E6DD
|
||||
Output = DEA56BDABBC6D24183CF7BDE1E1F78631B2B0230C76FF2F43075F2FDE77CF052769276CAD98DA62394EC62D77730F5761489585E093EA7315F3592717C485C84
|
||||
|
||||
# Test vectors from https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-128
|
||||
Input = 00010203
|
||||
Output = C1C36925B6409A04F1B504FCBCA9D82B4017277CB5ED2B2065FC1D3814D5AAF5
|
||||
Ctrl = function-name:
|
||||
Ctrl = customization:Email Signature
|
||||
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-128
|
||||
Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
|
||||
Output = C5221D50E4F822D96A2E8881A961420F294B7B24FE3D2094BAED2C6524CC166B
|
||||
Ctrl = customization:Email Signature
|
||||
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-256
|
||||
Input = 00010203
|
||||
Output = D008828E2B80AC9D2218FFEE1D070C48B8E4C87BFF32C9699D5B6896EEE0EDD164020E2BE0560858D9C00C037E34A96937C561A74C412BB4C746469527281C8C
|
||||
Ctrl = customization:Email Signature
|
||||
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-256
|
||||
Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
|
||||
Output = 07DC27B11E51FBAC75BC7B3C1D983E8B4B85FB1DEFAF218912AC86430273091727F42B17ED1DF63E8EC118F04B23633C1DFB1574C8FB55CB45DA8E25AFB092BB
|
||||
Ctrl = function-name:
|
||||
Ctrl = customization:Email Signature
|
||||
|
||||
# These are SHAKE test vectors from (i.e where n = s = empty string)
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE128
|
||||
Input = 49d81708d86cd59dea0ac2c1017a9712d6dffb754dde0b57a9023a39fc5f5b6be276fc176f59f6826610428fac3a0e85fcf71011db061b8fcf2bf085ccd45670effb6dc46f4e3f2ed08e981c5935187fc95b86cf46da675096b1cf9591a67842d6301116be93d8288e4d6b70f1b1db8aa5d203b774a21825665b8170351ee86801da91154570eaf80a1564945af7822df8232fd04ea65593a7f2ab1e9e84cf6ad6c494c9ec2d9d27aaad2b8f7e4f33f12a17b422bc2d4724c13ff8a8b62054d1bfb5c33b9c11183cd8df67694300165ca37637b5a781155f1c070d156339a0242374c6723b6584bffb71c02b935455f8cb086392f5e8e8cc2015956d8f19daeb6aca4476b27108387a2ce0dc5591154d0b94ddc090abe8f4363036b821062baffb7fe550ea7dcd30bfd86c84710081e1c9e450475e123c5ec41f98ff0149bbf6405b5207cad1fb2f313d0f2bcee9be3f6ebe623049640d9234ab644a172ab14ba02633a339b5b9bb38226fda5694f7ec63ebbb8238eb8219ec9c429f4bf0353383a72f2d21702f5e3c513499f04852710f33044512edc47a56bad90885e5713851a7efac694b869fa590076e844ff757d95de581c1b3fa3dd8ccd28cad4f8ae173ee1b28f98ee606dca89063fbef0f262b33053f2c854debdc9cd433ab77abb64f445aa9b981761c4761767f3b71c2646c7b0d873baae50bc9f0
|
||||
Output = c609be05458f7ab33e7b6b54bc6e8999
|
||||
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE256
|
||||
Input = dc5a100fa16df1583c79722a0d72833d3bf22c109b8889dbd35213c6bfce205813edae3242695cfd9f59b9a1c203c1b72ef1a5423147cb990b5316a85266675894e2644c3f9578cebe451a09e58c53788fe77a9e850943f8a275f830354b0593a762bac55e984db3e0661eca3cb83f67a6fb348e6177f7dee2df40c4322602f094953905681be3954fe44c4c902c8f6bba565a788b38f13411ba76ce0f9f6756a2a2687424c5435a51e62df7a8934b6e141f74c6ccf539e3782d22b5955d3baf1ab2cf7b5c3f74ec2f9447344e937957fd7f0bdfec56d5d25f61cde18c0986e244ecf780d6307e313117256948d4230ebb9ea62bb302cfe80d7dfebabc4a51d7687967ed5b416a139e974c005fff507a96
|
||||
Output = 2bac5716803a9cda8f9e84365ab0a681327b5ba34fdedfb1c12e6e807f45284b
|
||||
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE256
|
||||
Input = dc5a100fa16df1583c79722a0d72833d3bf22c109b8889dbd35213c6bfce205813edae3242695cfd9f59b9a1c203c1b72ef1a5423147cb990b5316a85266675894e2644c3f9578cebe451a09e58c53788fe77a9e850943f8a275f830354b0593a762bac55e984db3e0661eca3cb83f67a6fb348e6177f7dee2df40c4322602f094953905681be3954fe44c4c902c8f6bba565a788b38f13411ba76ce0f9f6756a2a2687424c5435a51e62df7a8934b6e141f74c6ccf539e3782d22b5955d3baf1ab2cf7b5c3f74ec2f9447344e937957fd7f0bdfec56d5d25f61cde18c0986e244ecf780d6307e313117256948d4230ebb9ea62bb302cfe80d7dfebabc4a51d7687967ed5b416a139e974c005fff507a96
|
||||
Output = 2bac5716803a9cda8f9e84365ab0a681327b5ba34fdedfb1c12e6e807f45284b
|
||||
Ctrl = function-name:
|
||||
Ctrl = customization:
|
||||
|
||||
# A test from https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/cSHAKE-128-1.0/internalProjection.json
|
||||
# where the encoding of the strings is exactly a multiple of the block size w. i.e. no zero padding is added.
|
||||
# The output length was modified to be on a byte boundary.
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-128
|
||||
Input = EA18
|
||||
Ctrl = customization:fmkctMwhBB[<Kta&RJ5r5ToA9N9~Y-,kin8y]xB}kviaDk_kPI^{o#N1|JIF5x.67pR]]fGX)6'=j.{MnLN1M0zf@'|3OzirhSJS9#.i#&rXz1FnM{WgI|g'tk=Ui5*-L4T6cH4k?d.H<Bk/`.dRC#HklD_LeV~mz
|
||||
Output = 2EEF41BD1680C16F36AE2B9C004805F7426AC9D4BB6BF7CFC78606A6E6F6F518EB6C0BE768
|
||||
|
||||
# Tests from https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/cSHAKE-128-1.0/internalProjection.json
|
||||
# and https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/cSHAKE-256-1.0/internalProjection.json which have
|
||||
# an input length that is a multiple of 8 bits, that have different known function names.
|
||||
# Where the output was not a multiple of 8 the last byte has been modified.
|
||||
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-128
|
||||
Input = CA88F708FA
|
||||
Ctrl = function-name:KMAC
|
||||
Ctrl = customization:`kiEF`&I))7]yq0?*sKa q)[jP`4R=)lV_9tyvT$kAbH$)1}p].bbeomb.
|
||||
Output = BEBB534CCFCCD300F731D2911FB4351D5FCC95AC2509E9ABAE8F9DC51106E28D7F25AE11738334
|
||||
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-256
|
||||
Input = 13D101DA
|
||||
Ctrl = function-name:TupleHash
|
||||
Ctrl = customization:q8gN}O&V*VDU4Y.^5J13tG2,1^Lw~C2rw $AB3.SX)=@z
|
||||
Output = 43163A57FC1EE8F1C501A2ADD927698CA5A4B52C0D3EF3FD6D91D8D2386765E0AE
|
||||
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-256
|
||||
Input = D5D7E7517F
|
||||
Ctrl = function-name:ParallelHash
|
||||
Ctrl = customization:vD-1>T,f.R*V%ZA<NtW0$3UZD[$X%QVQE,H6E;xqYQI4co^F#Sf:CU!dmQkbPRbZ{V1x3,v3{fTPiBvT}[UOk</o*dGrN7@(nm7,^d4v]R>[ OyJ
|
||||
Output = 442BE69B2AFD7C8282839920A8446AAF16A5049D3D018EAC87E04CF9225870EFCA6F88DB415829
|
||||
|
||||
# Test that uses an unknown function name
|
||||
FIPSversion = >=4.0.0
|
||||
Digest = CSHAKE-128
|
||||
Input = CA88F708FA
|
||||
Ctrl = function-name:BadName
|
||||
Result = DIGESTINIT_ERROR
|
||||
Reason = invalid function name
|
||||
|
||||
Title = Case insensitive digest tests
|
||||
|
||||
|
|
@ -395,4 +481,3 @@ Output = A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A
|
|||
Digest = shA512
|
||||
Input = "abc"
|
||||
Output = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,10 @@ my %params = (
|
|||
'OSSL_DIGEST_PARAM_SIZE' => "size", # size_t
|
||||
'OSSL_DIGEST_PARAM_XOF' => "xof", # int, 0 or 1
|
||||
'OSSL_DIGEST_PARAM_ALGID_ABSENT' => "algid-absent", # int, 0 or 1
|
||||
'OSSL_DIGEST_PARAM_FUNCTION_NAME' => "function-name", # utf8 string
|
||||
'OSSL_DIGEST_PARAM_CUSTOMIZATION' => "customization", # utf8 string
|
||||
'OSSL_DIGEST_PARAM_PROPERTIES' => '*OSSL_ALG_PARAM_PROPERTIES',# utf8 string
|
||||
|
||||
# external mu digest parameters
|
||||
'OSSL_DIGEST_PARAM_MU_PUB_KEY' => "pub", # octet string
|
||||
'OSSL_DIGEST_PARAM_MU_CONTEXT_STRING' => "context-string", # octet string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue