summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMamone Tarsha <maamoun.tk@googlemail.com>2021-08-10 16:01:18 +0300
committerMamone Tarsha <maamoun.tk@googlemail.com>2021-08-10 16:01:18 +0300
commit4ea2a1f860c6883abb993fd931a776d783edf7d8 (patch)
tree0ef71455744ebb5525b54d87942a698d41a196c5
parentd351a828579f1ffd0a837d68ed3c7f1c7d808f38 (diff)
downloadnettle-4ea2a1f860c6883abb993fd931a776d783edf7d8.tar.gz
[S390x] Optimize SHA1 compress
-rw-r--r--Makefile.in2
-rw-r--r--configure.ac4
-rw-r--r--fat-s390x.c45
-rw-r--r--s390x/fat/sha1-compress-2.asm36
-rw-r--r--s390x/msa/sha1-compress.asm72
5 files changed, 147 insertions, 12 deletions
diff --git a/Makefile.in b/Makefile.in
index 3a57393c..fe2de5a8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -621,7 +621,7 @@ distdir: $(DISTFILES)
arm arm/neon arm/v6 arm/fat \
arm64 arm64/crypto arm64/fat \
powerpc64 powerpc64/p7 powerpc64/p8 powerpc64/fat \
- s390x s390x/vf s390x/msa_x1 s390x/msa_x2 s390x/msa_x4 s390x/fat ; do \
+ s390x s390x/vf s390x/msa s390x/msa_x1 s390x/msa_x2 s390x/msa_x4 s390x/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/configure.ac b/configure.ac
index a307d936..ebec8759 100644
--- a/configure.ac
+++ b/configure.ac
@@ -537,13 +537,13 @@ if test "x$enable_assembler" = xyes ; then
if test "x$enable_fat" = xyes ; then
asm_path="s390x/fat $asm_path"
OPT_NETTLE_SOURCES="fat-s390x.c $OPT_NETTLE_SOURCES"
- FAT_TEST_LIST="none vf msa_x1 msa_x2 msa_x4"
+ FAT_TEST_LIST="none vf msa msa_x1 msa_x2 msa_x4"
else
if test "$enable_s390x_vf" = yes ; then
asm_path="s390x/vf $asm_path"
fi
if test "$enable_s390x_msa" = yes ; then
- asm_path="s390x/msa_x1 s390x/msa_x2 s390x/msa_x4 $asm_path"
+ asm_path="s390x/msa s390x/msa_x1 s390x/msa_x2 s390x/msa_x4 $asm_path"
fi
fi
fi
diff --git a/fat-s390x.c b/fat-s390x.c
index 12918cf8..15fd5fcc 100644
--- a/fat-s390x.c
+++ b/fat-s390x.c
@@ -76,6 +76,7 @@
#define AES_128_CODE 18
#define AES_192_CODE 19
#define AES_256_CODE 20
+#define SHA_1_CODE 1
#define GHASH_CODE 65
struct s390x_features
@@ -84,7 +85,8 @@ struct s390x_features
int have_km_aes128;
int have_km_aes192;
int have_km_aes256;
- int have_kmid_ghash;
+ int have_kimd_sha_1;
+ int have_kimd_ghash;
};
void _nettle_stfle(uint64_t *facility, uint64_t facility_size);
@@ -101,7 +103,8 @@ 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;
+ features->have_kimd_sha_1 = 0;
+ features->have_kimd_ghash = 0;
const char *s = secure_getenv (ENV_OVERRIDE);
if (s)
@@ -112,19 +115,17 @@ get_s390x_features (struct s390x_features *features)
if (MATCH (s, length, "vf", 2))
features->have_vector_facility = 1;
+ else if (MATCH (s, length, "msa", 3))
+ features->have_kimd_sha_1 = 1;
else 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;
- }
+ features->have_kimd_ghash = 1;
if (!sep)
break;
s = sep + 1;
@@ -151,6 +152,11 @@ get_s390x_features (struct s390x_features *features)
features->have_km_aes192 = 1;
if (query_status[FACILITY_INDEX(AES_256_CODE)] & FACILITY_BIT(AES_256_CODE))
features->have_km_aes256 = 1;
+
+ memset(query_status, 0, sizeof(query_status));
+ _nettle_kimd_status(query_status);
+ if (query_status[FACILITY_INDEX(SHA_1_CODE)] & FACILITY_BIT(SHA_1_CODE))
+ features->have_kimd_sha_1 = 1;
}
if (facilities[FACILITY_INDEX(FAC_MSA_X4)] & FACILITY_BIT(FAC_MSA_X4))
@@ -158,7 +164,7 @@ get_s390x_features (struct s390x_features *features)
uint64_t query_status[2] = {0};
_nettle_kimd_status(query_status);
if (query_status[FACILITY_INDEX(GHASH_CODE)] & FACILITY_BIT(GHASH_CODE))
- features->have_kmid_ghash = 1;
+ features->have_kimd_ghash = 1;
}
}
#endif
@@ -232,6 +238,10 @@ 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 */
+DECLARE_FAT_FUNC(nettle_sha1_compress, sha1_compress_func)
+DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, c)
+DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, s390x)
+
static void CONSTRUCTOR
fat_init (void)
{
@@ -314,7 +324,7 @@ fat_init (void)
}
/* GHASH */
- if (features.have_kmid_ghash)
+ if (features.have_kimd_ghash)
{
if (verbose)
fprintf (stderr, "libnettle: enabling hardware accelerated GHASH.\n");
@@ -326,6 +336,18 @@ fat_init (void)
_nettle_gcm_init_key_vec = _nettle_gcm_init_key_c;
_nettle_gcm_hash_vec = _nettle_gcm_hash_c;
}
+
+ /* SHA1 */
+ if (features.have_kimd_sha_1)
+ {
+ if (verbose)
+ fprintf (stderr, "libnettle: enabling hardware accelerated SHA1 compress code.\n");
+ nettle_sha1_compress_vec = _nettle_sha1_compress_s390x;
+ }
+ else
+ {
+ nettle_sha1_compress_vec = _nettle_sha1_compress_c;
+ }
}
/* MEMXOR3 */
@@ -400,3 +422,8 @@ DEFINE_FAT_FUNC(_nettle_gcm_hash, void,
size_t length, const uint8_t *data),
(key, x, length, data))
#endif /* GCM_TABLE_BITS == 8 */
+
+/* SHA1 */
+DEFINE_FAT_FUNC(nettle_sha1_compress, void,
+ (uint32_t *state, const uint8_t *input),
+ (state, input))
diff --git a/s390x/fat/sha1-compress-2.asm b/s390x/fat/sha1-compress-2.asm
new file mode 100644
index 00000000..0796c93f
--- /dev/null
+++ b/s390x/fat/sha1-compress-2.asm
@@ -0,0 +1,36 @@
+C s390x/fat/sha1-compress-2.asm
+
+ifelse(`
+ Copyright (C) 2021 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_sha1_compress) picked up by configure
+
+define(`fat_transform', `_$1_s390x')
+include_src(`s390x/msa/sha1-compress.asm')
diff --git a/s390x/msa/sha1-compress.asm b/s390x/msa/sha1-compress.asm
new file mode 100644
index 00000000..38023afc
--- /dev/null
+++ b/s390x/msa/sha1-compress.asm
@@ -0,0 +1,72 @@
+C s390x/msa/sha1-compress.asm
+
+ifelse(`
+ Copyright (C) 2021 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/.
+')
+
+C KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) is specefied in
+C "z/Architecture Principles of Operation SA22-7832-12" as follows:
+C A function specified by the function code in general register 0 is performed.
+C General register 1 contains the logical address of the leftmost byte of the parameter block in storage.
+C the second operand is processed as specified by the function code using an initial chaining value in
+C the parameter block, and the result replaces the chaining value.
+
+C This implementation uses KIMD-SHA-1 function.
+C The parameter block used for the KIMD-SHA-1 function has the following format:
+C *----------------------------------------------*
+C | H0 (4 bytes) |
+C |----------------------------------------------|
+C | H1 (4 bytes) |
+C |----------------------------------------------|
+C | H2 (4 bytes) |
+C |----------------------------------------------|
+C | H3 (4 bytes) |
+C |----------------------------------------------|
+C | H4 (4 bytes) |
+C *----------------------------------------------*
+
+.file "sha1-compress.asm"
+
+.text
+
+C SHA function code
+define(`SHA1_FUNCTION_CODE', `1')
+C Size of block
+define(`SHA1_BLOCK_SIZE', `64')
+
+C void nettle_sha1_compress(uint32_t *state, const uint8_t *input)
+
+PROLOGUE(nettle_sha1_compress)
+ lghi %r0,SHA1_FUNCTION_CODE C FUNCTION_CODE
+ lgr %r1,%r2
+ lgr %r4,%r3
+ lghi %r5,SHA1_BLOCK_SIZE
+1: .long 0xb93e0004 C kimd %r0,%r4. perform KIMD-SHA operation on data
+ brc 1,1b
+ br RA
+EPILOGUE(nettle_sha1_compress)