]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
nettle: vendor-in SHAKE implementation
authorDaiki Ueno <ueno@gnu.org>
Wed, 29 May 2024 08:40:55 +0000 (17:40 +0900)
committerDaiki Ueno <ueno@gnu.org>
Wed, 29 May 2024 08:40:55 +0000 (17:40 +0900)
Signed-off-by: Daiki Ueno <ueno@gnu.org>
configure.ac
devel/import-from-nettle.sh
lib/nettle/Makefile.am
lib/nettle/int/sha3-shake.h [new file with mode: 0644]
lib/nettle/mac.c

index 6e34a999e655557eaea2f8c63a222c88f6aa5a0b..9d630d16b3dd26d5789100066794159aec81298d 100644 (file)
@@ -798,6 +798,13 @@ LIBS="$LIBS $NETTLE_LIBS"
 AC_CHECK_FUNCS(nettle_cbc_aes128_encrypt)
 LIBS=$save_LIBS
 
+# Check for incremental SHAKE
+save_LIBS=$LIBS
+LIBS="$LIBS $NETTLE_LIBS"
+AC_CHECK_FUNCS(nettle_sha3_128_shake_output)
+LIBS=$save_LIBS
+AM_CONDITIONAL([NEED_SHAKE_OUTPUT], [test "$ac_cv_func_nettle_sha3_128_shake_output" != yes])
+
 # Check sonames of the linked libraries needed for FIPS selftests.
 save_CFLAGS=$CFLAGS
 CFLAGS="$CFLAGS $GMP_CFLAGS"
index 90a07200d619709f17311b8671d06073bd6c93e8..9c0f9dd82d36ffe51204a3c9483cdb0689a77fbf 100755 (executable)
@@ -20,6 +20,8 @@ ghash-set-key.c
 ghash-update.c
 gmp-glue.c
 gmp-glue.h
+md-internal.h
+nettle-write.h
 oaep.c
 oaep.h
 pss-mgf1.h
@@ -35,6 +37,12 @@ siv-gcm.c
 siv-gcm.h
 siv-ghash-set-key.c
 siv-ghash-update.c
+sha3.c
+sha3-internal.h
+sha3-shake.c
+shake128.c
+shake256.c
+write-le64.c
 "
 
 PUBLIC="
@@ -54,6 +62,7 @@ nettle-types.h
 rsa.h
 sha1.h
 sha2.h
+sha3.h
 "
 
 test -d $DST || mkdir $DST
@@ -126,6 +135,15 @@ for f in $IMPORTS; do
        sed \
          -e '/^#include <nettle\/rsa\.h>/a\
 #include "int/rsa-oaep.h"
+' \
+         $dst > $dst-t && mv $dst-t $dst
+       ;;
+    esac
+    case $dst in
+      */shake*.c)
+       sed \
+         -e '/^#include <nettle\/sha3\.h>/a\
+#include "int/sha3-shake.h"
 ' \
          $dst > $dst-t && mv $dst-t $dst
        ;;
index 6a9e6ce0822250fd9dd5b8be4ed26b866d20b930..f18f48e68ec18b3c5587d1acd5e41da0e15d8e17 100644 (file)
@@ -47,7 +47,7 @@ libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c \
        int/ecdsa-compute-k.c int/ecdsa-compute-k.h \
        int/mpn-base256.c int/mpn-base256.h \
        int/block8.h backport/block-internal.h \
-       int/rsa-oaep.h int/rsa-pad.c int/nettle-internal.h
+       int/rsa-oaep.h int/rsa-pad.c int/nettle-internal.h int/sha3-shake.h
 
 if WINDOWS
 if HAVE_BCRYPT
@@ -129,3 +129,14 @@ libcrypto_la_SOURCES += \
        backport/rsa-sign-tr.c \
        $(NULL)
 endif
+
+if NEED_SHAKE_OUTPUT
+libcrypto_la_SOURCES += \
+       backport/md-internal.h \
+       backport/sha3.c \
+       backport/sha3-internal.h \
+       backport/sha3-shake.c \
+       backport/shake128.c \
+       backport/shake256.c \
+       $(NULL)
+endif
diff --git a/lib/nettle/int/sha3-shake.h b/lib/nettle/int/sha3-shake.h
new file mode 100644 (file)
index 0000000..1157683
--- /dev/null
@@ -0,0 +1,81 @@
+/* sha3.h
+
+   The sha3 hash function (aka Keccak).
+
+   Copyright (C) 2012 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef GNUTLS_LIB_NETTLE_INT_SHA3_SHAKE_H_INCLUDED
+#define GNUTLS_LIB_NETTLE_INT_SHA3_SHAKE_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define sha3_128_init nettle_sha3_128_init
+#define sha3_128_update nettle_sha3_128_update
+#define sha3_128_shake nettle_sha3_128_shake
+#define sha3_128_shake_output nettle_sha3_128_shake_output
+#define sha3_256_shake nettle_sha3_256_shake
+#define sha3_256_shake_output nettle_sha3_256_shake_output
+
+#define SHA3_128_DIGEST_SIZE 16
+#define SHA3_128_BLOCK_SIZE 168
+
+struct sha3_128_ctx {
+       struct sha3_state state;
+       unsigned index;
+       uint8_t block[SHA3_128_BLOCK_SIZE];
+};
+
+void sha3_128_init(struct sha3_128_ctx *ctx);
+
+void sha3_128_update(struct sha3_128_ctx *ctx, size_t length,
+                    const uint8_t *data);
+
+void sha3_128_shake(struct sha3_128_ctx *ctx, size_t length, uint8_t *digest);
+
+void sha3_128_shake_output(struct sha3_128_ctx *ctx, size_t length,
+                          uint8_t *digest);
+
+/* Alternative digest function implementing shake256, with arbitrary
+   digest size */
+void sha3_256_shake(struct sha3_256_ctx *ctx, size_t length, uint8_t *digest);
+
+/* Unlike sha3_256_shake, this function can be called multiple times
+   to retrieve output from shake256 in an incremental manner */
+void sha3_256_shake_output(struct sha3_256_ctx *ctx, size_t length,
+                          uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GNUTLS_LIB_NETTLE_INT_SHA3_SHAKE_H_INCLUDED */
index 61ebd0e710f747d0fec3e68f69effc346c9112e2..f4a06b190caf528143f7e402c6eebbc28e706087 100644 (file)
@@ -31,6 +31,9 @@
 #include <nettle/ripemd160.h>
 #include <nettle/sha.h>
 #include <nettle/sha3.h>
+#ifndef HAVE_NETTLE_SHA3_128_SHAKE_OUTPUT
+#include "int/sha3-shake.h"
+#endif
 #include <nettle/hmac.h>
 #include <nettle/umac.h>
 #include <nettle/hkdf.h>
@@ -77,6 +80,7 @@ struct nettle_hash_ctx {
                struct sha256_ctx sha256;
                struct sha384_ctx sha384;
                struct sha512_ctx sha512;
+               struct sha3_128_ctx sha3_128;
                struct sha3_224_ctx sha3_224;
                struct sha3_256_ctx sha3_256;
                struct sha3_384_ctx sha3_384;
@@ -608,10 +612,9 @@ static int wrap_nettle_hash_exists(gnutls_digest_algorithm_t algo)
        case GNUTLS_DIG_SHA3_256:
        case GNUTLS_DIG_SHA3_384:
        case GNUTLS_DIG_SHA3_512:
-#endif
-
        case GNUTLS_DIG_SHAKE_128:
        case GNUTLS_DIG_SHAKE_256:
+#endif
 
        case GNUTLS_DIG_MD2:
        case GNUTLS_DIG_RMD160:
@@ -732,6 +735,20 @@ static int _ctx_init(gnutls_digest_algorithm_t algo,
                ctx->ctx_ptr = &ctx->ctx.sha3_512;
                ctx->length = SHA3_512_DIGEST_SIZE;
                break;
+       case GNUTLS_DIG_SHAKE_128:
+               sha3_128_init(&ctx->ctx.sha3_128);
+               ctx->update = (update_func)sha3_128_update;
+               ctx->digest = (digest_func)sha3_128_shake_output;
+               ctx->ctx_ptr = &ctx->ctx.sha3_128;
+               ctx->length = 0; /* unused */
+               break;
+       case GNUTLS_DIG_SHAKE_256:
+               sha3_256_init(&ctx->ctx.sha3_256);
+               ctx->update = (update_func)sha3_256_update;
+               ctx->digest = (digest_func)sha3_256_shake_output;
+               ctx->ctx_ptr = &ctx->ctx.sha3_256;
+               ctx->length = 0; /* unused */
+               break;
 #endif
        case GNUTLS_DIG_MD2:
                md2_init(&ctx->ctx.md2);
@@ -845,7 +862,7 @@ static int wrap_nettle_hash_output(void *src_ctx, void *digest,
        struct nettle_hash_ctx *ctx;
        ctx = src_ctx;
 
-       if (digestsize < ctx->length) {
+       if (ctx->length > 0 && digestsize < ctx->length) {
                gnutls_assert();
                return GNUTLS_E_SHORT_MEMORY_BUFFER;
        }