summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rw-r--r--aes128-decrypt.c11
-rw-r--r--aes128-encrypt.c11
-rw-r--r--aes128-set-decrypt-key.c18
-rw-r--r--aes128-set-encrypt-key.c9
-rw-r--r--aes192-decrypt.c11
-rw-r--r--aes192-encrypt.c11
-rw-r--r--aes192-set-decrypt-key.c18
-rw-r--r--aes192-set-encrypt-key.c9
-rw-r--r--aes256-decrypt.c11
-rw-r--r--aes256-encrypt.c11
-rw-r--r--aes256-set-decrypt-key.c18
-rw-r--r--aes256-set-encrypt-key.c9
-rw-r--r--configure.ac13
-rw-r--r--fat-s390x.c385
-rw-r--r--fat-setup.h18
-rw-r--r--s390x/fat/aes128-decrypt.asm36
-rw-r--r--s390x/fat/aes128-encrypt.asm36
-rw-r--r--s390x/fat/aes128-set-decrypt-key.asm38
-rw-r--r--s390x/fat/aes128-set-encrypt-key.asm36
-rw-r--r--s390x/fat/aes192-decrypt.asm36
-rw-r--r--s390x/fat/aes192-encrypt.asm36
-rw-r--r--s390x/fat/aes192-set-decrypt-key.asm38
-rw-r--r--s390x/fat/aes192-set-encrypt-key.asm36
-rw-r--r--s390x/fat/aes256-decrypt.asm36
-rw-r--r--s390x/fat/aes256-encrypt.asm36
-rw-r--r--s390x/fat/aes256-set-decrypt-key.asm38
-rw-r--r--s390x/fat/aes256-set-encrypt-key.asm36
-rw-r--r--s390x/fat/gcm-hash.asm38
29 files changed, 1021 insertions, 20 deletions
diff --git a/Makefile.in b/Makefile.in
index 5e0ffdd7..ae85d8c8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -620,7 +620,7 @@ distdir: $(DISTFILES)
arm arm/neon arm/v6 arm/fat \
arm64 arm64/crypto arm64/fat \
powerpc64 powerpc64/p7 powerpc64/p8 powerpc64/fat \
- s390x s390x/msa_x1 s390x/msa_x2 s390x/msa_x4 ; do \
+ s390x s390x/msa_x1 s390x/msa_x2 s390x/msa_x4 s390x/msa_fat ; do \
mkdir "$(distdir)/$$d" ; \
find "$(srcdir)/$$d" -maxdepth 1 '(' -name '*.asm' -o -name '*.m4' -o -name README ')' \
-exec cp '{}' "$(distdir)/$$d" ';' ; \
diff --git a/aes128-decrypt.c b/aes128-decrypt.c
index 168d8158..436438cc 100644
--- a/aes128-decrypt.c
+++ b/aes128-decrypt.c
@@ -39,8 +39,17 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes128_decrypt
void
-aes128_decrypt(const struct aes128_ctx *ctx,
+_nettle_aes128_decrypt_c(const struct aes128_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+# define nettle_aes128_decrypt _nettle_aes128_decrypt_c
+#endif
+
+void
+nettle_aes128_decrypt(const struct aes128_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
diff --git a/aes128-encrypt.c b/aes128-encrypt.c
index 35d15b36..e20b733c 100644
--- a/aes128-encrypt.c
+++ b/aes128-encrypt.c
@@ -39,8 +39,17 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes128_encrypt
void
-aes128_encrypt(const struct aes128_ctx *ctx,
+_nettle_aes128_encrypt_c(const struct aes128_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+# define nettle_aes128_encrypt _nettle_aes128_encrypt_c
+#endif
+
+void
+nettle_aes128_encrypt(const struct aes128_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
diff --git a/aes128-set-decrypt-key.c b/aes128-set-decrypt-key.c
index d86d2b34..8be4f922 100644
--- a/aes128-set-decrypt-key.c
+++ b/aes128-set-decrypt-key.c
@@ -40,14 +40,28 @@
#include "aes-internal.h"
#include "macros.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes128_invert_key
void
-aes128_invert_key (struct aes128_ctx *dst, const struct aes128_ctx *src)
+_nettle_aes128_invert_key_c(struct aes128_ctx *dst,
+ const struct aes128_ctx *src);
+# define nettle_aes128_invert_key _nettle_aes128_invert_key_c
+#endif
+
+#if HAVE_NATIVE_aes128_set_decrypt_key
+void
+_nettle_aes128_set_decrypt_key_c(struct aes128_ctx *ctx, const uint8_t *key);
+# define nettle_aes128_set_decrypt_key _nettle_aes128_set_decrypt_key_c
+#endif
+
+void
+nettle_aes128_invert_key (struct aes128_ctx *dst, const struct aes128_ctx *src)
{
_nettle_aes_invert (_AES128_ROUNDS, dst->keys, src->keys);
}
void
-aes128_set_decrypt_key(struct aes128_ctx *ctx, const uint8_t *key)
+nettle_aes128_set_decrypt_key(struct aes128_ctx *ctx, const uint8_t *key)
{
aes128_set_encrypt_key (ctx, key);
aes128_invert_key (ctx, ctx);
diff --git a/aes128-set-encrypt-key.c b/aes128-set-encrypt-key.c
index 58f91857..bc9799b6 100644
--- a/aes128-set-encrypt-key.c
+++ b/aes128-set-encrypt-key.c
@@ -37,8 +37,15 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes128_set_encrypt_key
void
-aes128_set_encrypt_key(struct aes128_ctx *ctx, const uint8_t *key)
+_nettle_aes128_set_encrypt_key_c(struct aes128_ctx *ctx, const uint8_t *key);
+# define nettle_aes128_set_encrypt_key _nettle_aes128_set_encrypt_key_c
+#endif
+
+void
+nettle_aes128_set_encrypt_key(struct aes128_ctx *ctx, const uint8_t *key)
{
_nettle_aes_set_key (_AES128_ROUNDS, AES128_KEY_SIZE / 4, ctx->keys, key);
}
diff --git a/aes192-decrypt.c b/aes192-decrypt.c
index f97e2f6b..7746c76e 100644
--- a/aes192-decrypt.c
+++ b/aes192-decrypt.c
@@ -39,8 +39,17 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes192_decrypt
void
-aes192_decrypt(const struct aes192_ctx *ctx,
+_nettle_aes192_decrypt_c(const struct aes192_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+# define nettle_aes192_decrypt _nettle_aes192_decrypt_c
+#endif
+
+void
+nettle_aes192_decrypt(const struct aes192_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
diff --git a/aes192-encrypt.c b/aes192-encrypt.c
index efa40e45..2e848aeb 100644
--- a/aes192-encrypt.c
+++ b/aes192-encrypt.c
@@ -39,8 +39,17 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes192_encrypt
void
-aes192_encrypt(const struct aes192_ctx *ctx,
+_nettle_aes192_encrypt_c(const struct aes192_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+# define nettle_aes192_encrypt _nettle_aes192_encrypt_c
+#endif
+
+void
+nettle_aes192_encrypt(const struct aes192_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
diff --git a/aes192-set-decrypt-key.c b/aes192-set-decrypt-key.c
index ace7282c..3a1ad2dc 100644
--- a/aes192-set-decrypt-key.c
+++ b/aes192-set-decrypt-key.c
@@ -38,14 +38,28 @@
#include "aes-internal.h"
#include "macros.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes192_invert_key
void
-aes192_invert_key (struct aes192_ctx *dst, const struct aes192_ctx *src)
+_nettle_aes192_invert_key_c(struct aes192_ctx *dst,
+ const struct aes192_ctx *src);
+# define nettle_aes192_invert_key _nettle_aes192_invert_key_c
+#endif
+
+#if HAVE_NATIVE_aes192_set_decrypt_key
+void
+_nettle_aes192_set_decrypt_key_c(struct aes192_ctx *ctx, const uint8_t *key);
+# define nettle_aes192_set_decrypt_key _nettle_aes192_set_decrypt_key_c
+#endif
+
+void
+nettle_aes192_invert_key (struct aes192_ctx *dst, const struct aes192_ctx *src)
{
_nettle_aes_invert (_AES192_ROUNDS, dst->keys, src->keys);
}
void
-aes192_set_decrypt_key(struct aes192_ctx *ctx, const uint8_t *key)
+nettle_aes192_set_decrypt_key(struct aes192_ctx *ctx, const uint8_t *key)
{
aes192_set_encrypt_key (ctx, key);
aes192_invert_key (ctx, ctx);
diff --git a/aes192-set-encrypt-key.c b/aes192-set-encrypt-key.c
index 5e9c4176..4241bfd8 100644
--- a/aes192-set-encrypt-key.c
+++ b/aes192-set-encrypt-key.c
@@ -37,8 +37,15 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes192_set_encrypt_key
void
-aes192_set_encrypt_key(struct aes192_ctx *ctx, const uint8_t *key)
+_nettle_aes192_set_encrypt_key_c(struct aes192_ctx *ctx, const uint8_t *key);
+# define nettle_aes192_set_encrypt_key _nettle_aes192_set_encrypt_key_c
+#endif
+
+void
+nettle_aes192_set_encrypt_key(struct aes192_ctx *ctx, const uint8_t *key)
{
_nettle_aes_set_key (_AES192_ROUNDS, AES192_KEY_SIZE / 4, ctx->keys, key);
}
diff --git a/aes256-decrypt.c b/aes256-decrypt.c
index 42042cf6..89411c10 100644
--- a/aes256-decrypt.c
+++ b/aes256-decrypt.c
@@ -39,8 +39,17 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes256_decrypt
void
-aes256_decrypt(const struct aes256_ctx *ctx,
+_nettle_aes256_decrypt_c(const struct aes256_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+# define nettle_aes256_decrypt _nettle_aes256_decrypt_c
+#endif
+
+void
+nettle_aes256_decrypt(const struct aes256_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
diff --git a/aes256-encrypt.c b/aes256-encrypt.c
index 98474bb5..7fbaff2a 100644
--- a/aes256-encrypt.c
+++ b/aes256-encrypt.c
@@ -39,8 +39,17 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes256_encrypt
void
-aes256_encrypt(const struct aes256_ctx *ctx,
+_nettle_aes256_encrypt_c(const struct aes256_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+# define nettle_aes256_encrypt _nettle_aes256_encrypt_c
+#endif
+
+void
+nettle_aes256_encrypt(const struct aes256_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
diff --git a/aes256-set-decrypt-key.c b/aes256-set-decrypt-key.c
index 884c21af..0f37705a 100644
--- a/aes256-set-decrypt-key.c
+++ b/aes256-set-decrypt-key.c
@@ -38,14 +38,28 @@
#include "aes-internal.h"
#include "macros.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes256_invert_key
void
-aes256_invert_key (struct aes256_ctx *dst, const struct aes256_ctx *src)
+_nettle_aes256_invert_key_c(struct aes256_ctx *dst,
+ const struct aes256_ctx *src);
+# define nettle_aes256_invert_key _nettle_aes256_invert_key_c
+#endif
+
+#if HAVE_NATIVE_aes256_set_decrypt_key
+void
+_nettle_aes256_set_decrypt_key_c(struct aes256_ctx *ctx, const uint8_t *key);
+# define nettle_aes256_set_decrypt_key _nettle_aes256_set_decrypt_key_c
+#endif
+
+void
+nettle_aes256_invert_key (struct aes256_ctx *dst, const struct aes256_ctx *src)
{
_nettle_aes_invert (_AES256_ROUNDS, dst->keys, src->keys);
}
void
-aes256_set_decrypt_key(struct aes256_ctx *ctx, const uint8_t *key)
+nettle_aes256_set_decrypt_key(struct aes256_ctx *ctx, const uint8_t *key)
{
aes256_set_encrypt_key (ctx, key);
aes256_invert_key (ctx, ctx);
diff --git a/aes256-set-encrypt-key.c b/aes256-set-encrypt-key.c
index a3bd9743..6e7bf15a 100644
--- a/aes256-set-encrypt-key.c
+++ b/aes256-set-encrypt-key.c
@@ -37,8 +37,15 @@
#include "aes-internal.h"
+/* For fat builds */
+#if HAVE_NATIVE_aes256_set_encrypt_key
void
-aes256_set_encrypt_key(struct aes256_ctx *ctx, const uint8_t *key)
+_nettle_aes256_set_encrypt_key_c(struct aes256_ctx *ctx, const uint8_t *key);
+# define nettle_aes256_set_encrypt_key _nettle_aes256_set_encrypt_key_c
+#endif
+
+void
+nettle_aes256_set_encrypt_key(struct aes256_ctx *ctx, const uint8_t *key)
{
_nettle_aes_set_key (_AES256_ROUNDS, AES256_KEY_SIZE / 4, ctx->keys, key);
}
diff --git a/configure.ac b/configure.ac
index 64242bfd..be061aa8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -529,10 +529,15 @@ if test "x$enable_assembler" = xyes ; then
;;
*s390x*)
if test "$ABI" = 64 ; then
- asm_path="s390x"
- if test "$enable_s390x_msa" = yes ; then
- asm_path="s390x/msa_x1 s390x/msa_x2 s390x/msa_x4 $asm_path"
- fi
+ asm_path="s390x"
+ if test "x$enable_fat" = xyes ; then
+ asm_path="s390x/fat $asm_path"
+ OPT_NETTLE_SOURCES="fat-s390x.c $OPT_NETTLE_SOURCES"
+ else
+ if test "$enable_s390x_msa" = yes ; then
+ asm_path="s390x/msa_x1 s390x/msa_x2 s390x/msa_x4 $asm_path"
+ fi
+ fi
fi
;;
*)
diff --git a/fat-s390x.c b/fat-s390x.c
new file mode 100644
index 00000000..690b6013
--- /dev/null
+++ b/fat-s390x.c
@@ -0,0 +1,385 @@
+/* fat-s390x.c
+
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+*/
+
+#define _GNU_SOURCE
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
+# if __GLIBC_PREREQ(2, 16)
+# define USE_GETAUXVAL 1
+# include <sys/auxv.h>
+# endif
+#endif
+
+#include "nettle-types.h"
+
+#include "aes.h"
+#include "gcm.h"
+#include "gcm-internal.h"
+#include "fat-setup.h"
+
+/* Max number of doublewords returned by STFLE */
+#define FACILITY_DOUBLEWORDS_MAX 3
+#define FACILITY_INDEX(bit) ((bit) / 64)
+/* STFLE and cipher query store doublewords as bit-reversed.
+ reverse facility bit or function code in doubleword */
+#define FACILITY_BIT(bit) (1ULL << (63 - (bit) % 64))
+
+/* Define from arch/s390/include/asm/elf.h in Linux kernel */
+#ifndef HWCAP_S390_STFLE
+#define HWCAP_S390_STFLE 4
+#endif
+
+/* Facility bits */
+#define FAC_MSA 17 /* message-security assist */
+#define FAC_MSA_X4 77 /* message-security-assist extension 4 */
+
+/* Function codes */
+#define AES_128_CODE 18
+#define AES_192_CODE 19
+#define AES_256_CODE 20
+#define GHASH_CODE 65
+
+struct s390x_features
+{
+ int have_km_aes128;
+ int have_km_aes192;
+ int have_km_aes256;
+ int have_kmid_ghash;
+};
+
+#define MATCH(s, slen, literal, llen) \
+ ((slen) == (llen) && memcmp ((s), (literal), llen) == 0)
+
+static void
+get_s390x_features (struct s390x_features *features)
+{
+ features->have_km_aes128 = 0;
+ features->have_km_aes192 = 0;
+ features->have_km_aes256 = 0;
+ features->have_kmid_ghash = 0;
+
+ const char *s = secure_getenv (ENV_OVERRIDE);
+ if (s)
+ for (;;)
+ {
+ const char *sep = strchr (s, ',');
+ size_t length = sep ? (size_t) (sep - s) : strlen(s);
+
+ if (MATCH (s, length, "msa_x1", 6))
+ {
+ features->have_km_aes128 = 1;
+ }
+ else if (MATCH (s, length, "msa_x2", 6))
+ {
+ features->have_km_aes192 = 1;
+ features->have_km_aes256 = 1;
+ }
+ else if (MATCH (s, length, "msa_x4", 6))
+ {
+ features->have_kmid_ghash = 1;
+ }
+ if (!sep)
+ break;
+ s = sep + 1;
+ }
+ else
+ {
+#if USE_GETAUXVAL
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ if (hwcap & HWCAP_S390_STFLE)
+ {
+ uint64_t facilities[FACILITY_DOUBLEWORDS_MAX] = {0};
+
+ register uint64_t gr0 asm("0") = FACILITY_DOUBLEWORDS_MAX - 1;
+ asm volatile(
+ ".insn s,0xb2b00000,%1" /* stfle */
+ : "+d"(gr0), "=Q"(facilities)
+ :
+ : "cc");
+
+ if (facilities[FACILITY_INDEX(FAC_MSA)] & FACILITY_BIT(FAC_MSA))
+ {
+ uint64_t query_status[2] = {0};
+ register uint64_t *query_status_addr asm("1") = query_status;
+ asm volatile(
+ "lghi 0,0\n\t"
+ ".long 0xb92e0022" /* km %r2,%r2. Operands are ignored */
+ :
+ : "a"(query_status_addr)
+ : "memory", "cc", "r0");
+ if (query_status[FACILITY_INDEX(AES_128_CODE)] & FACILITY_BIT(AES_128_CODE))
+ features->have_km_aes128 = 1;
+ if (query_status[FACILITY_INDEX(AES_192_CODE)] & FACILITY_BIT(AES_192_CODE))
+ features->have_km_aes192 = 1;
+ if (query_status[FACILITY_INDEX(AES_256_CODE)] & FACILITY_BIT(AES_256_CODE))
+ features->have_km_aes256 = 1;
+ }
+
+ if (facilities[FACILITY_INDEX(FAC_MSA_X4)] & FACILITY_BIT(FAC_MSA_X4))
+ {
+ uint64_t query_status[2] = {0};
+ register uint64_t *query_status_addr asm("1") = query_status;
+ asm volatile(
+ "lghi 0,0\n\t"
+ ".long 0xb93e0002" /* kimd %r0,%r2. Operands are ignored */
+ :
+ : "a"(query_status_addr)
+ : "memory", "cc", "r0");
+ if (query_status[FACILITY_INDEX(GHASH_CODE)] & FACILITY_BIT(GHASH_CODE))
+ features->have_kmid_ghash = 1;
+ }
+ }
+#endif
+ }
+}
+
+/* AES128 */
+DECLARE_FAT_FUNC(nettle_aes128_set_encrypt_key, aes128_set_key_func)
+DECLARE_FAT_FUNC_VAR(aes128_set_encrypt_key, aes128_set_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes128_set_encrypt_key, aes128_set_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes128_set_decrypt_key, aes128_set_key_func)
+DECLARE_FAT_FUNC_VAR(aes128_set_decrypt_key, aes128_set_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes128_set_decrypt_key, aes128_set_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes128_invert_key, aes128_invert_key_func)
+DECLARE_FAT_FUNC_VAR(aes128_invert_key, aes128_invert_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes128_invert_key, aes128_invert_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes128_encrypt, aes128_crypt_func)
+DECLARE_FAT_FUNC_VAR(aes128_encrypt, aes128_crypt_func, c)
+DECLARE_FAT_FUNC_VAR(aes128_encrypt, aes128_crypt_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes128_decrypt, aes128_crypt_func)
+DECLARE_FAT_FUNC_VAR(aes128_decrypt, aes128_crypt_func, c)
+DECLARE_FAT_FUNC_VAR(aes128_decrypt, aes128_crypt_func, s390x)
+
+/* AES192 */
+DECLARE_FAT_FUNC(nettle_aes192_set_encrypt_key, aes192_set_key_func)
+DECLARE_FAT_FUNC_VAR(aes192_set_encrypt_key, aes192_set_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes192_set_encrypt_key, aes192_set_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes192_set_decrypt_key, aes192_set_key_func)
+DECLARE_FAT_FUNC_VAR(aes192_set_decrypt_key, aes192_set_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes192_set_decrypt_key, aes192_set_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes192_invert_key, aes192_invert_key_func)
+DECLARE_FAT_FUNC_VAR(aes192_invert_key, aes192_invert_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes192_invert_key, aes192_invert_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes192_encrypt, aes192_crypt_func)
+DECLARE_FAT_FUNC_VAR(aes192_encrypt, aes192_crypt_func, c)
+DECLARE_FAT_FUNC_VAR(aes192_encrypt, aes192_crypt_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes192_decrypt, aes192_crypt_func)
+DECLARE_FAT_FUNC_VAR(aes192_decrypt, aes192_crypt_func, c)
+DECLARE_FAT_FUNC_VAR(aes192_decrypt, aes192_crypt_func, s390x)
+
+/* AES256 */
+DECLARE_FAT_FUNC(nettle_aes256_set_encrypt_key, aes256_set_key_func)
+DECLARE_FAT_FUNC_VAR(aes256_set_encrypt_key, aes256_set_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes256_set_encrypt_key, aes256_set_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes256_set_decrypt_key, aes256_set_key_func)
+DECLARE_FAT_FUNC_VAR(aes256_set_decrypt_key, aes256_set_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes256_set_decrypt_key, aes256_set_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes256_invert_key, aes256_invert_key_func)
+DECLARE_FAT_FUNC_VAR(aes256_invert_key, aes256_invert_key_func, c)
+DECLARE_FAT_FUNC_VAR(aes256_invert_key, aes256_invert_key_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes256_encrypt, aes256_crypt_func)
+DECLARE_FAT_FUNC_VAR(aes256_encrypt, aes256_crypt_func, c)
+DECLARE_FAT_FUNC_VAR(aes256_encrypt, aes256_crypt_func, s390x)
+DECLARE_FAT_FUNC(nettle_aes256_decrypt, aes256_crypt_func)
+DECLARE_FAT_FUNC_VAR(aes256_decrypt, aes256_crypt_func, c)
+DECLARE_FAT_FUNC_VAR(aes256_decrypt, aes256_crypt_func, s390x)
+
+/* GHASH */
+#if GCM_TABLE_BITS == 8
+DECLARE_FAT_FUNC(_nettle_gcm_init_key, gcm_init_key_func)
+DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, c)
+DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, s390x)
+
+DECLARE_FAT_FUNC(_nettle_gcm_hash, gcm_hash_func)
+DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, c)
+DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, s390x)
+#endif /* GCM_TABLE_BITS == 8 */
+
+static void CONSTRUCTOR
+fat_init (void)
+{
+ struct s390x_features features;
+ int verbose;
+
+ get_s390x_features (&features);
+ verbose = getenv (ENV_VERBOSE) != NULL;
+
+ /* AES128 */
+ if (features.have_km_aes128)
+ {
+ if (verbose)
+ fprintf (stderr, "libnettle: enabling hardware accelerated AES128 EBC mode.\n");
+ nettle_aes128_set_encrypt_key_vec = _nettle_aes128_set_encrypt_key_s390x;
+ nettle_aes128_set_decrypt_key_vec = _nettle_aes128_set_decrypt_key_s390x;
+ nettle_aes128_invert_key_vec = _nettle_aes128_invert_key_s390x;
+ nettle_aes128_encrypt_vec = _nettle_aes128_encrypt_s390x;
+ nettle_aes128_decrypt_vec = _nettle_aes128_decrypt_s390x;
+ }
+ else
+ {
+ nettle_aes128_set_encrypt_key_vec = _nettle_aes128_set_encrypt_key_c;
+ nettle_aes128_set_decrypt_key_vec = _nettle_aes128_set_decrypt_key_c;
+ nettle_aes128_invert_key_vec = _nettle_aes128_invert_key_c;
+ nettle_aes128_encrypt_vec = _nettle_aes128_encrypt_c;
+ nettle_aes128_decrypt_vec = _nettle_aes128_decrypt_c;
+ }
+
+ /* AES192 */
+ if (features.have_km_aes192)
+ {
+ if (verbose)
+ fprintf (stderr, "libnettle: enabling hardware accelerated AES192 EBC mode.\n");
+ nettle_aes192_set_encrypt_key_vec = _nettle_aes192_set_encrypt_key_s390x;
+ nettle_aes192_set_decrypt_key_vec = _nettle_aes192_set_decrypt_key_s390x;
+ nettle_aes192_invert_key_vec = _nettle_aes192_invert_key_s390x;
+ nettle_aes192_encrypt_vec = _nettle_aes192_encrypt_s390x;
+ nettle_aes192_decrypt_vec = _nettle_aes192_decrypt_s390x;
+ }
+ else
+ {
+ nettle_aes192_set_encrypt_key_vec = _nettle_aes192_set_encrypt_key_c;
+ nettle_aes192_set_decrypt_key_vec = _nettle_aes192_set_decrypt_key_c;
+ nettle_aes192_invert_key_vec = _nettle_aes192_invert_key_c;
+ nettle_aes192_encrypt_vec = _nettle_aes192_encrypt_c;
+ nettle_aes192_decrypt_vec = _nettle_aes192_decrypt_c;
+ }
+
+ /* AES256 */
+ if (features.have_km_aes256)
+ {
+ if (verbose)
+ fprintf (stderr, "libnettle: enabling hardware accelerated AES256 EBC mode.\n");
+ nettle_aes256_set_encrypt_key_vec = _nettle_aes256_set_encrypt_key_s390x;
+ nettle_aes256_set_decrypt_key_vec = _nettle_aes256_set_decrypt_key_s390x;
+ nettle_aes256_invert_key_vec = _nettle_aes256_invert_key_s390x;
+ nettle_aes256_encrypt_vec = _nettle_aes256_encrypt_s390x;
+ nettle_aes256_decrypt_vec = _nettle_aes256_decrypt_s390x;
+ }
+ else
+ {
+ nettle_aes256_set_encrypt_key_vec = _nettle_aes256_set_encrypt_key_c;
+ nettle_aes256_set_decrypt_key_vec = _nettle_aes256_set_decrypt_key_c;
+ nettle_aes256_invert_key_vec = _nettle_aes256_invert_key_c;
+ nettle_aes256_encrypt_vec = _nettle_aes256_encrypt_c;
+ nettle_aes256_decrypt_vec = _nettle_aes256_decrypt_c;
+ }
+
+ /* GHASH */
+ if (features.have_kmid_ghash)
+ {
+ if (verbose)
+ fprintf (stderr, "libnettle: enabling hardware accelerated GHASH.\n");
+ _nettle_gcm_init_key_vec = _nettle_gcm_init_key_s390x;
+ _nettle_gcm_hash_vec = _nettle_gcm_hash_s390x;
+ }
+ else
+ {
+ _nettle_gcm_init_key_vec = _nettle_gcm_init_key_c;
+ _nettle_gcm_hash_vec = _nettle_gcm_hash_c;
+ }
+}
+
+/* AES128 */
+DEFINE_FAT_FUNC(nettle_aes128_set_encrypt_key, void,
+ (struct aes128_ctx *ctx, const uint8_t *key),
+ (ctx, key))
+DEFINE_FAT_FUNC(nettle_aes128_set_decrypt_key, void,
+ (struct aes128_ctx *ctx, const uint8_t *key),
+ (ctx, key))
+DEFINE_FAT_FUNC(nettle_aes128_invert_key, void,
+ (struct aes128_ctx *dst, const struct aes128_ctx *src),
+ (dst, src))
+DEFINE_FAT_FUNC(nettle_aes128_encrypt, void,
+ (const struct aes128_ctx *ctx, size_t length,
+ uint8_t *dst,const uint8_t *src),
+ (ctx, length, dst, src))
+DEFINE_FAT_FUNC(nettle_aes128_decrypt, void,
+ (const struct aes128_ctx *ctx, size_t length,
+ uint8_t *dst,const uint8_t *src),
+ (ctx, length, dst, src))
+
+/* AES192 */
+DEFINE_FAT_FUNC(nettle_aes192_set_encrypt_key, void,
+ (struct aes192_ctx *ctx, const uint8_t *key),
+ (ctx, key))
+DEFINE_FAT_FUNC(nettle_aes192_set_decrypt_key, void,
+ (struct aes192_ctx *ctx, const uint8_t *key),
+ (ctx, key))
+DEFINE_FAT_FUNC(nettle_aes192_invert_key, void,
+ (struct aes192_ctx *dst, const struct aes192_ctx *src),
+ (dst, src))
+DEFINE_FAT_FUNC(nettle_aes192_encrypt, void,
+ (const struct aes192_ctx *ctx, size_t length,
+ uint8_t *dst,const uint8_t *src),
+ (ctx, length, dst, src))
+DEFINE_FAT_FUNC(nettle_aes192_decrypt, void,
+ (const struct aes192_ctx *ctx, size_t length,
+ uint8_t *dst,const uint8_t *src),
+ (ctx, length, dst, src))
+
+/* AES256 */
+DEFINE_FAT_FUNC(nettle_aes256_set_encrypt_key, void,
+ (struct aes256_ctx *ctx, const uint8_t *key),
+ (ctx, key))
+DEFINE_FAT_FUNC(nettle_aes256_set_decrypt_key, void,
+ (struct aes256_ctx *ctx, const uint8_t *key),
+ (ctx, key))
+DEFINE_FAT_FUNC(nettle_aes256_invert_key, void,
+ (struct aes256_ctx *dst, const struct aes256_ctx *src),
+ (dst, src))
+DEFINE_FAT_FUNC(nettle_aes256_encrypt, void,
+ (const struct aes256_ctx *ctx, size_t length,
+ uint8_t *dst,const uint8_t *src),
+ (ctx, length, dst, src))
+DEFINE_FAT_FUNC(nettle_aes256_decrypt, void,
+ (const struct aes256_ctx *ctx, size_t length,
+ uint8_t *dst,const uint8_t *src),
+ (ctx, length, dst, src))
+
+/* GHASH */
+#if GCM_TABLE_BITS == 8
+DEFINE_FAT_FUNC(_nettle_gcm_init_key, void,
+ (union nettle_block16 *table),
+ (table))
+DEFINE_FAT_FUNC(_nettle_gcm_hash, void,
+ (const struct gcm_key *key, union nettle_block16 *x,
+ size_t length, const uint8_t *data),
+ (key, x, length, data))
+#endif /* GCM_TABLE_BITS == 8 */
diff --git a/fat-setup.h b/fat-setup.h
index 4e528d6b..f9337dbe 100644
--- a/fat-setup.h
+++ b/fat-setup.h
@@ -194,3 +194,21 @@ typedef void chacha_crypt_func(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src);
+
+struct aes128_ctx;
+typedef void aes128_set_key_func (struct aes128_ctx *ctx, const uint8_t *key);
+typedef void aes128_invert_key_func (struct aes128_ctx *dst, const struct aes128_ctx *src);
+typedef void aes128_crypt_func (const struct aes128_ctx *ctx, size_t length, uint8_t *dst,
+ const uint8_t *src);
+
+struct aes192_ctx;
+typedef void aes192_set_key_func (struct aes192_ctx *ctx, const uint8_t *key);
+typedef void aes192_invert_key_func (struct aes192_ctx *dst, const struct aes192_ctx *src);
+typedef void aes192_crypt_func (const struct aes192_ctx *ctx, size_t length, uint8_t *dst,
+ const uint8_t *src);
+
+struct aes256_ctx;
+typedef void aes256_set_key_func (struct aes256_ctx *ctx, const uint8_t *key);
+typedef void aes256_invert_key_func (struct aes256_ctx *dst, const struct aes256_ctx *src);
+typedef void aes256_crypt_func (const struct aes256_ctx *ctx, size_t length, uint8_t *dst,
+ const uint8_t *src);
diff --git a/s390x/fat/aes128-decrypt.asm b/s390x/fat/aes128-decrypt.asm
new file mode 100644
index 00000000..f49c9849
--- /dev/null
+++ b/s390x/fat/aes128-decrypt.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes128-decrypt.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes128_decrypt) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x1/aes128-decrypt.asm')
diff --git a/s390x/fat/aes128-encrypt.asm b/s390x/fat/aes128-encrypt.asm
new file mode 100644
index 00000000..3d60c5a4
--- /dev/null
+++ b/s390x/fat/aes128-encrypt.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes128-encrypt.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes128_encrypt) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x1/aes128-encrypt.asm')
diff --git a/s390x/fat/aes128-set-decrypt-key.asm b/s390x/fat/aes128-set-decrypt-key.asm
new file mode 100644
index 00000000..9861e091
--- /dev/null
+++ b/s390x/fat/aes128-set-decrypt-key.asm
@@ -0,0 +1,38 @@
+C s390x/fat/aes128-set-decrypt-key.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl picked up by configure
+dnl PROLOGUE(nettle_aes128_invert_key)
+dnl PROLOGUE(nettle_aes128_set_decrypt_key)
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x1/aes128-set-decrypt-key.asm')
diff --git a/s390x/fat/aes128-set-encrypt-key.asm b/s390x/fat/aes128-set-encrypt-key.asm
new file mode 100644
index 00000000..ec799ffa
--- /dev/null
+++ b/s390x/fat/aes128-set-encrypt-key.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes128-set-encrypt-key.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes128_set_encrypt_key) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x1/aes128-set-encrypt-key.asm')
diff --git a/s390x/fat/aes192-decrypt.asm b/s390x/fat/aes192-decrypt.asm
new file mode 100644
index 00000000..2889021d
--- /dev/null
+++ b/s390x/fat/aes192-decrypt.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes192-decrypt.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes192_decrypt) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x2/aes192-decrypt.asm')
diff --git a/s390x/fat/aes192-encrypt.asm b/s390x/fat/aes192-encrypt.asm
new file mode 100644
index 00000000..6a532358
--- /dev/null
+++ b/s390x/fat/aes192-encrypt.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes192-encrypt.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes192_encrypt) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x2/aes192-encrypt.asm')
diff --git a/s390x/fat/aes192-set-decrypt-key.asm b/s390x/fat/aes192-set-decrypt-key.asm
new file mode 100644
index 00000000..cabb51d1
--- /dev/null
+++ b/s390x/fat/aes192-set-decrypt-key.asm
@@ -0,0 +1,38 @@
+C s390x/fat/aes192-set-decrypt-key.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl picked up by configure
+dnl PROLOGUE(nettle_aes192_invert_key)
+dnl PROLOGUE(nettle_aes192_set_decrypt_key)
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x2/aes192-set-decrypt-key.asm')
diff --git a/s390x/fat/aes192-set-encrypt-key.asm b/s390x/fat/aes192-set-encrypt-key.asm
new file mode 100644
index 00000000..8416cc18
--- /dev/null
+++ b/s390x/fat/aes192-set-encrypt-key.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes192-set-encrypt-key.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes192_set_encrypt_key) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x2/aes192-set-encrypt-key.asm')
diff --git a/s390x/fat/aes256-decrypt.asm b/s390x/fat/aes256-decrypt.asm
new file mode 100644
index 00000000..a3e68363
--- /dev/null
+++ b/s390x/fat/aes256-decrypt.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes256-decrypt.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes256_decrypt) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x2/aes256-decrypt.asm')
diff --git a/s390x/fat/aes256-encrypt.asm b/s390x/fat/aes256-encrypt.asm
new file mode 100644
index 00000000..cfb23646
--- /dev/null
+++ b/s390x/fat/aes256-encrypt.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes256-encrypt.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes256_encrypt) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x2/aes256-encrypt.asm')
diff --git a/s390x/fat/aes256-set-decrypt-key.asm b/s390x/fat/aes256-set-decrypt-key.asm
new file mode 100644
index 00000000..ad25d3b0
--- /dev/null
+++ b/s390x/fat/aes256-set-decrypt-key.asm
@@ -0,0 +1,38 @@
+C s390x/fat/aes256-set-decrypt-key.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl picked up by configure
+dnl PROLOGUE(nettle_aes256_invert_key)
+dnl PROLOGUE(nettle_aes256_set_decrypt_key)
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x2/aes256-set-decrypt-key.asm')
diff --git a/s390x/fat/aes256-set-encrypt-key.asm b/s390x/fat/aes256-set-encrypt-key.asm
new file mode 100644
index 00000000..aeacf503
--- /dev/null
+++ b/s390x/fat/aes256-set-encrypt-key.asm
@@ -0,0 +1,36 @@
+C s390x/fat/aes256-set-encrypt-key.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl PROLOGUE(nettle_aes256_set_encrypt_key) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa_x2/aes256-set-encrypt-key.asm')
diff --git a/s390x/fat/gcm-hash.asm b/s390x/fat/gcm-hash.asm
new file mode 100644
index 00000000..17ca7342
--- /dev/null
+++ b/s390x/fat/gcm-hash.asm
@@ -0,0 +1,38 @@
+C s390x/fat/gcm-hash.asm
+
+ifelse(`
+ Copyright (C) 2020 Mamone Tarsha
+
+ 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/.
+')
+
+dnl picked up by configure
+dnl PROLOGUE(_nettle_fat_gcm_init_key)
+dnl PROLOGUE(_nettle_fat_gcm_hash)
+
+define(`fat_transform', `$1_s390x')
+include_src(`s390x/msa_x4/gcm-hash.asm')