From 562c04ef8939e47e9d3f58bed416e508cb5b4e1d384f9ca3dd2b59a3c369fb7c Mon Sep 17 00:00:00 2001 From: Pedro Monreal Gonzalez Date: Tue, 21 May 2019 22:05:39 +0000 Subject: [PATCH 1/6] Accepting request 704541 from home:vitezslav_cizek:branches:security:tls - Fix a crash caused by long locale messages (bsc#1135550) * add openssl-fix_underflow_in_errstr_handling.patch OBS-URL: https://build.opensuse.org/request/show/704541 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=34 --- openssl-1_1.changes | 6 +++++ openssl-1_1.spec | 1 + openssl-fix-handling-of-GNU-strerror_r.patch | 14 +++++------ ...ssl-fix_underflow_in_errstr_handling.patch | 24 +++++++++++++++++++ 4 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 openssl-fix_underflow_in_errstr_handling.patch diff --git a/openssl-1_1.changes b/openssl-1_1.changes index eaa4251..158d0c2 100644 --- a/openssl-1_1.changes +++ b/openssl-1_1.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Mon May 20 16:21:01 UTC 2019 - Vítězslav Čížek + +- Fix a crash caused by long locale messages (bsc#1135550) + * add openssl-fix_underflow_in_errstr_handling.patch + ------------------------------------------------------------------- Mon Mar 4 13:01:18 UTC 2019 - Dominique Leuenberger diff --git a/openssl-1_1.spec b/openssl-1_1.spec index 7080663..b08fe6f 100644 --- a/openssl-1_1.spec +++ b/openssl-1_1.spec @@ -50,6 +50,7 @@ Patch8: 0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch Patch9: 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch # PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/8371 Patch10: openssl-fix-handling-of-GNU-strerror_r.patch +Patch11: openssl-fix_underflow_in_errstr_handling.patch BuildRequires: pkgconfig Conflicts: ssl Provides: ssl diff --git a/openssl-fix-handling-of-GNU-strerror_r.patch b/openssl-fix-handling-of-GNU-strerror_r.patch index 39b751a..1624159 100644 --- a/openssl-fix-handling-of-GNU-strerror_r.patch +++ b/openssl-fix-handling-of-GNU-strerror_r.patch @@ -1,8 +1,8 @@ -diff --git a/crypto/o_str.c b/crypto/o_str.c -index 02578dbf0d..3b271e745b 100644 ---- a/crypto/o_str.c -+++ b/crypto/o_str.c -@@ -223,7 +223,26 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen) +Index: openssl-1.1.1b/crypto/o_str.c +=================================================================== +--- openssl-1.1.1b.orig/crypto/o_str.c 2019-02-26 15:15:30.000000000 +0100 ++++ openssl-1.1.1b/crypto/o_str.c 2019-05-20 17:06:07.956663953 +0200 +@@ -223,7 +223,26 @@ int openssl_strerror_r(int errnum, char #if defined(_MSC_VER) && _MSC_VER>=1400 return !strerror_s(buf, buflen, errnum); #elif defined(_GNU_SOURCE) @@ -30,7 +30,7 @@ index 02578dbf0d..3b271e745b 100644 #elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) /* -@@ -234,6 +253,7 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen) +@@ -234,6 +253,7 @@ int openssl_strerror_r(int errnum, char return !strerror_r(errnum, buf, buflen); #else char *err; @@ -38,7 +38,7 @@ index 02578dbf0d..3b271e745b 100644 /* Fall back to non-thread safe strerror()...its all we can do */ if (buflen < 2) return 0; -@@ -241,8 +261,7 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen) +@@ -241,8 +261,7 @@ int openssl_strerror_r(int errnum, char /* Can this ever happen? */ if (err == NULL) return 0; diff --git a/openssl-fix_underflow_in_errstr_handling.patch b/openssl-fix_underflow_in_errstr_handling.patch new file mode 100644 index 0000000..557b994 --- /dev/null +++ b/openssl-fix_underflow_in_errstr_handling.patch @@ -0,0 +1,24 @@ +Index: openssl-1.1.1b/crypto/err/err.c +=================================================================== +--- openssl-1.1.1b.orig/crypto/err/err.c 2019-02-26 15:15:30.000000000 +0100 ++++ openssl-1.1.1b/crypto/err/err.c 2019-05-21 21:14:31.211536069 +0200 +@@ -185,7 +185,7 @@ static ERR_STRING_DATA *int_err_get_item + + #ifndef OPENSSL_NO_ERR + /* A measurement on Linux 2018-11-21 showed about 3.5kib */ +-# define SPACE_SYS_STR_REASONS 4 * 1024 ++# define SPACE_SYS_STR_REASONS 8 * 1024 + # define NUM_SYS_STR_REASONS 127 + + static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; +@@ -225,8 +225,8 @@ static void build_SYS_str_reasons(void) + + str->string = cur; + cnt += l; +- if (cnt > sizeof(strerror_pool)) +- cnt = sizeof(strerror_pool); ++ if (cnt >= sizeof(strerror_pool)) ++ cnt = sizeof(strerror_pool) - 1; + cur += l; + + /* From 19ebb7106f1fe5e47721b6999cd820b1db3d4c15574f4e7551339f5a5849c98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Tue, 28 May 2019 08:34:19 +0000 Subject: [PATCH 2/6] Accepting request 705828 from home:jirislaby:branches:security:tls - add 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch (bnc#1136522) OBS-URL: https://build.opensuse.org/request/show/705828 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=35 --- ..._get_mem_ptr-and-related-regressions.patch | 120 ++++++++++++++++++ openssl-1_1.changes | 6 + openssl-1_1.spec | 2 + 3 files changed, 128 insertions(+) create mode 100644 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch diff --git a/0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch b/0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch new file mode 100644 index 0000000..61b2312 --- /dev/null +++ b/0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch @@ -0,0 +1,120 @@ +From: Tomas Mraz +Date: Wed, 3 Apr 2019 12:31:32 +0200 +Subject: Fix for BIO_get_mem_ptr and related regressions +Patch-mainline: yes +Git-commit: b238fb79709a180ba9b4d837101c9f75e2978dc0 +References: bnc#1136522 + +Reviewed-by: Bernd Edlinger +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/8649) + +Signed-off-by: Jiri Slaby +--- + crypto/bio/bss_mem.c | 40 ++++++++++++++++++++++++++++------------ + 1 file changed, 28 insertions(+), 12 deletions(-) + +diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c +index 89c54b2d53df..51fae3b2f0b9 100644 +--- a/crypto/bio/bss_mem.c ++++ b/crypto/bio/bss_mem.c +@@ -57,7 +57,12 @@ static const BIO_METHOD secmem_method = { + NULL, /* mem_callback_ctrl */ + }; + +-/* BIO memory stores buffer and read pointer */ ++/* ++ * BIO memory stores buffer and read pointer ++ * however the roles are different for read only BIOs. ++ * In that case the readp just stores the original state ++ * to be used for reset. ++ */ + typedef struct bio_buf_mem_st { + struct buf_mem_st *buf; /* allocated buffer */ + struct buf_mem_st *readp; /* read pointer */ +@@ -192,6 +197,8 @@ static int mem_read(BIO *b, char *out, int outl) + BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; + BUF_MEM *bm = bbm->readp; + ++ if (b->flags & BIO_FLAGS_MEM_RDONLY) ++ bm = bbm->buf; + BIO_clear_retry_flags(b); + ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl; + if ((out != NULL) && (ret > 0)) { +@@ -241,29 +248,36 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) + BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; + BUF_MEM *bm; + ++ if (b->flags & BIO_FLAGS_MEM_RDONLY) ++ bm = bbm->buf; ++ else ++ bm = bbm->readp; ++ + switch (cmd) { + case BIO_CTRL_RESET: + bm = bbm->buf; + if (bm->data != NULL) { +- /* For read only case reset to the start again */ +- if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) { +- bm->length = bm->max; ++ if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) { ++ if (b->flags & BIO_FLAGS_NONCLEAR_RST) { ++ bm->length = bm->max; ++ } else { ++ memset(bm->data, 0, bm->max); ++ bm->length = 0; ++ } ++ *bbm->readp = *bbm->buf; + } else { +- memset(bm->data, 0, bm->max); +- bm->length = 0; ++ /* For read only case just reset to the start again */ ++ *bbm->buf = *bbm->readp; + } +- *bbm->readp = *bbm->buf; + } + break; + case BIO_CTRL_EOF: +- bm = bbm->readp; + ret = (long)(bm->length == 0); + break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + b->num = (int)num; + break; + case BIO_CTRL_INFO: +- bm = bbm->readp; + ret = (long)bm->length; + if (ptr != NULL) { + pptr = (char **)ptr; +@@ -278,8 +292,9 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) + break; + case BIO_C_GET_BUF_MEM_PTR: + if (ptr != NULL) { +- mem_buf_sync(b); +- bm = bbm->readp; ++ if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) ++ mem_buf_sync(b); ++ bm = bbm->buf; + pptr = (char **)ptr; + *pptr = (char *)bm; + } +@@ -294,7 +309,6 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) + ret = 0L; + break; + case BIO_CTRL_PENDING: +- bm = bbm->readp; + ret = (long)bm->length; + break; + case BIO_CTRL_DUP: +@@ -318,6 +332,8 @@ static int mem_gets(BIO *bp, char *buf, int size) + BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr; + BUF_MEM *bm = bbm->readp; + ++ if (bp->flags & BIO_FLAGS_MEM_RDONLY) ++ bm = bbm->buf; + BIO_clear_retry_flags(bp); + j = bm->length; + if ((size - 1) < j) +-- +2.21.0 + diff --git a/openssl-1_1.changes b/openssl-1_1.changes index 158d0c2..f6dd3da 100644 --- a/openssl-1_1.changes +++ b/openssl-1_1.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue May 28 08:21:52 UTC 2019 - Jiri Slaby + +- add 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch + (bnc#1136522) + ------------------------------------------------------------------- Mon May 20 16:21:01 UTC 2019 - Vítězslav Čížek diff --git a/openssl-1_1.spec b/openssl-1_1.spec index b08fe6f..2de9d0d 100644 --- a/openssl-1_1.spec +++ b/openssl-1_1.spec @@ -51,6 +51,8 @@ Patch9: 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch # PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/8371 Patch10: openssl-fix-handling-of-GNU-strerror_r.patch Patch11: openssl-fix_underflow_in_errstr_handling.patch +# PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/8649 bnc#1136522 +Patch11: 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch BuildRequires: pkgconfig Conflicts: ssl Provides: ssl From cc18b66076571109de720c3ce0e0d785dc81925fd1174a0fe3087cad5e8e9edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Tue, 28 May 2019 08:41:16 +0000 Subject: [PATCH 3/6] Accepting request 705842 from home:jirislaby:branches:security:tls fix typo during spec file merge OBS-URL: https://build.opensuse.org/request/show/705842 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=36 --- openssl-1_1.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl-1_1.spec b/openssl-1_1.spec index 2de9d0d..287c4ed 100644 --- a/openssl-1_1.spec +++ b/openssl-1_1.spec @@ -52,7 +52,7 @@ Patch9: 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch Patch10: openssl-fix-handling-of-GNU-strerror_r.patch Patch11: openssl-fix_underflow_in_errstr_handling.patch # PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/8649 bnc#1136522 -Patch11: 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch +Patch12: 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch BuildRequires: pkgconfig Conflicts: ssl Provides: ssl From 0bd53d7b5ff5b48bb2194ab1bebeca473dcbaae0a579bfe48c21a37d210e2346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Thu, 30 May 2019 12:30:15 +0000 Subject: [PATCH 4/6] Accepting request 706506 from home:vitezslav_cizek:branches:o11 - Update openssl-fix_underflow_in_errstr_handling.patch to use upstream approved code * https://github.com/openssl/openssl/pull/8966 - update openssl.keyring to include Richard Levitte's key - Update to 1.1.1c * Prevent over long nonces in ChaCha20-Poly1305 (CVE-2019-1543) ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input for every encryption operation. RFC 7539 specifies that the nonce value (IV) should be 96 bits (12 bytes). OpenSSL allows a variable nonce length and front pads the nonce with 0 bytes if it is less than 12 bytes. However it also incorrectly allows a nonce to be set of up to 16 bytes. In this case only the last 12 bytes are significant and any additional leading bytes are ignored. * Add build tests for C++. These are generated files that only do one thing, to include one public OpenSSL head file each. This tests that the public header files can be usefully included in a C++ application. * Enable SHA3 pre-hashing for ECDSA and DSA. * Change the default RSA, DSA and DH size to 2048 bit instead of 1024. This changes the size when using the genpkey app when no size is given. It fixes an omission in earlier changes that changed all RSA, DSA and DH generation apps to use 2048 bits by default. * Reorganize the manual pages to consistently have RETURN VALUES, EXAMPLES, SEE ALSO and HISTORY come in that order, and adjust util/fix-doc-nits accordingly. * Add the missing accessor EVP_PKEY_get0_engine() * Have apps like 's_client' and 's_server' output the signature scheme along with other cipher suite parameters when debugging. * Make OPENSSL_config() error agnostic again. * Do the error handling in RSA decryption constant time. OBS-URL: https://build.opensuse.org/request/show/706506 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=37 --- ..._get_mem_ptr-and-related-regressions.patch | 120 ---- ...asm-chacha-s390x.pl-add-vx-code-path.patch | 18 +- openssl-1.1.1b.tar.gz | 3 - openssl-1.1.1b.tar.gz.asc | 11 - openssl-1.1.1c.tar.gz | 3 + openssl-1.1.1c.tar.gz.asc | 16 + openssl-1_1.changes | 42 ++ openssl-1_1.spec | 7 +- openssl-fix-handling-of-GNU-strerror_r.patch | 50 -- ...ssl-fix_underflow_in_errstr_handling.patch | 52 +- openssl.keyring | 559 +++++++++++++++++- 11 files changed, 663 insertions(+), 218 deletions(-) delete mode 100644 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch delete mode 100644 openssl-1.1.1b.tar.gz delete mode 100644 openssl-1.1.1b.tar.gz.asc create mode 100644 openssl-1.1.1c.tar.gz create mode 100644 openssl-1.1.1c.tar.gz.asc delete mode 100644 openssl-fix-handling-of-GNU-strerror_r.patch diff --git a/0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch b/0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch deleted file mode 100644 index 61b2312..0000000 --- a/0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch +++ /dev/null @@ -1,120 +0,0 @@ -From: Tomas Mraz -Date: Wed, 3 Apr 2019 12:31:32 +0200 -Subject: Fix for BIO_get_mem_ptr and related regressions -Patch-mainline: yes -Git-commit: b238fb79709a180ba9b4d837101c9f75e2978dc0 -References: bnc#1136522 - -Reviewed-by: Bernd Edlinger -Reviewed-by: Matt Caswell -(Merged from https://github.com/openssl/openssl/pull/8649) - -Signed-off-by: Jiri Slaby ---- - crypto/bio/bss_mem.c | 40 ++++++++++++++++++++++++++++------------ - 1 file changed, 28 insertions(+), 12 deletions(-) - -diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c -index 89c54b2d53df..51fae3b2f0b9 100644 ---- a/crypto/bio/bss_mem.c -+++ b/crypto/bio/bss_mem.c -@@ -57,7 +57,12 @@ static const BIO_METHOD secmem_method = { - NULL, /* mem_callback_ctrl */ - }; - --/* BIO memory stores buffer and read pointer */ -+/* -+ * BIO memory stores buffer and read pointer -+ * however the roles are different for read only BIOs. -+ * In that case the readp just stores the original state -+ * to be used for reset. -+ */ - typedef struct bio_buf_mem_st { - struct buf_mem_st *buf; /* allocated buffer */ - struct buf_mem_st *readp; /* read pointer */ -@@ -192,6 +197,8 @@ static int mem_read(BIO *b, char *out, int outl) - BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; - BUF_MEM *bm = bbm->readp; - -+ if (b->flags & BIO_FLAGS_MEM_RDONLY) -+ bm = bbm->buf; - BIO_clear_retry_flags(b); - ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl; - if ((out != NULL) && (ret > 0)) { -@@ -241,29 +248,36 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) - BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; - BUF_MEM *bm; - -+ if (b->flags & BIO_FLAGS_MEM_RDONLY) -+ bm = bbm->buf; -+ else -+ bm = bbm->readp; -+ - switch (cmd) { - case BIO_CTRL_RESET: - bm = bbm->buf; - if (bm->data != NULL) { -- /* For read only case reset to the start again */ -- if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) { -- bm->length = bm->max; -+ if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) { -+ if (b->flags & BIO_FLAGS_NONCLEAR_RST) { -+ bm->length = bm->max; -+ } else { -+ memset(bm->data, 0, bm->max); -+ bm->length = 0; -+ } -+ *bbm->readp = *bbm->buf; - } else { -- memset(bm->data, 0, bm->max); -- bm->length = 0; -+ /* For read only case just reset to the start again */ -+ *bbm->buf = *bbm->readp; - } -- *bbm->readp = *bbm->buf; - } - break; - case BIO_CTRL_EOF: -- bm = bbm->readp; - ret = (long)(bm->length == 0); - break; - case BIO_C_SET_BUF_MEM_EOF_RETURN: - b->num = (int)num; - break; - case BIO_CTRL_INFO: -- bm = bbm->readp; - ret = (long)bm->length; - if (ptr != NULL) { - pptr = (char **)ptr; -@@ -278,8 +292,9 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) - break; - case BIO_C_GET_BUF_MEM_PTR: - if (ptr != NULL) { -- mem_buf_sync(b); -- bm = bbm->readp; -+ if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) -+ mem_buf_sync(b); -+ bm = bbm->buf; - pptr = (char **)ptr; - *pptr = (char *)bm; - } -@@ -294,7 +309,6 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) - ret = 0L; - break; - case BIO_CTRL_PENDING: -- bm = bbm->readp; - ret = (long)bm->length; - break; - case BIO_CTRL_DUP: -@@ -318,6 +332,8 @@ static int mem_gets(BIO *bp, char *buf, int size) - BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr; - BUF_MEM *bm = bbm->readp; - -+ if (bp->flags & BIO_FLAGS_MEM_RDONLY) -+ bm = bbm->buf; - BIO_clear_retry_flags(bp); - j = bm->length; - if ((size - 1) < j) --- -2.21.0 - diff --git a/0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch b/0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch index bc453fd..9c47bed 100644 --- a/0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch +++ b/0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch @@ -13,10 +13,10 @@ Reviewed-by: Richard Levitte crypto/chacha/build.info | 1 + 2 files changed, 558 insertions(+), 259 deletions(-) -Index: openssl-1.1.1a/crypto/chacha/asm/chacha-s390x.pl +Index: openssl-1.1.1c/crypto/chacha/asm/chacha-s390x.pl =================================================================== ---- openssl-1.1.1a.orig/crypto/chacha/asm/chacha-s390x.pl 2018-11-20 14:35:37.000000000 +0100 -+++ openssl-1.1.1a/crypto/chacha/asm/chacha-s390x.pl 2019-01-10 16:19:39.942838273 +0100 +--- openssl-1.1.1c.orig/crypto/chacha/asm/chacha-s390x.pl 2019-05-30 11:52:55.786294410 +0200 ++++ openssl-1.1.1c/crypto/chacha/asm/chacha-s390x.pl 2019-05-30 11:52:58.122308974 +0200 @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. @@ -872,15 +872,3 @@ Index: openssl-1.1.1a/crypto/chacha/asm/chacha-s390x.pl +ALIGN (4); + +PERLASM_END(); -Index: openssl-1.1.1a/crypto/chacha/build.info -=================================================================== ---- openssl-1.1.1a.orig/crypto/chacha/build.info 2018-11-20 14:35:37.000000000 +0100 -+++ openssl-1.1.1a/crypto/chacha/build.info 2019-01-10 16:19:39.942838273 +0100 -@@ -9,6 +9,7 @@ GENERATE[chacha-armv4.S]=asm/chacha-armv - INCLUDE[chacha-armv4.o]=.. - GENERATE[chacha-armv8.S]=asm/chacha-armv8.pl $(PERLASM_SCHEME) - INCLUDE[chacha-armv8.o]=.. -+INCLUDE[chacha-s390x.o]=.. - - BEGINRAW[Makefile(unix)] - ##### CHACHA assembler implementations diff --git a/openssl-1.1.1b.tar.gz b/openssl-1.1.1b.tar.gz deleted file mode 100644 index 4f23d9f..0000000 --- a/openssl-1.1.1b.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5c557b023230413dfb0756f3137a13e6d726838ccd1430888ad15bfb2b43ea4b -size 8213737 diff --git a/openssl-1.1.1b.tar.gz.asc b/openssl-1.1.1b.tar.gz.asc deleted file mode 100644 index 28a5b3d..0000000 --- a/openssl-1.1.1b.tar.gz.asc +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQEzBAABCgAdFiEEhlersmDwVrHlGQg52cTSbQ5gRJEFAlx1SgkACgkQ2cTSbQ5g -RJHsWwf7BqLAjJhHHU5aBqHCZgvn24wwGjiOsGjo0uNkjigM/1aZafB10CVhhTDA -kHrZddEd6ZmC7b71WIn/2rVGNycHkSxzcpnLMZ0n6Y7/aqg/5ZeGj3sHPqBjIUWv -A/uzRnaAxOXQC8bw1RgNKcQr/bP0ZTqWI5uaQR87fQ7Bh1TbKwc+ClvMZ679kx9S -MHrcxjGmtlbxdkvMuKQMLqGNeaJAPgTAWNLTovawyq4HsFrM52etpAvqqb9MhHoR -J7zi+PLY+9MUMuwEDVjnK6fCawMLr459c/VPzVcN0v6B5iAZQMVfuFu1INYAqxMC -8tRz6DYabN1mpTCVTs6OV7IAzNYbjg== -=B/je ------END PGP SIGNATURE----- diff --git a/openssl-1.1.1c.tar.gz b/openssl-1.1.1c.tar.gz new file mode 100644 index 0000000..61f257f --- /dev/null +++ b/openssl-1.1.1c.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6fb3079ad15076154eda9413fed42877d668e7069d9b87396d0804fdb3f4c90 +size 8864262 diff --git a/openssl-1.1.1c.tar.gz.asc b/openssl-1.1.1c.tar.gz.asc new file mode 100644 index 0000000..b4a4677 --- /dev/null +++ b/openssl-1.1.1c.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEeVOsH7w9yLOykjk+1enkP3357owFAlztM8IACgkQ1enkP335 +7oxQwQ/9G4kkoJC0pat5P4uNBgVyxmXso63Eea91QYGC39BABSL+KpEzfyJtFwqR +36EAI8f5L5iGRKuBKerWtP8YUZ9Jc0Yf/a1R7sPGKh/0hor6dWhU1fh5x3HCatBC +TanYbgXgAQhNHQcwVG6qdvHIwtb9so5NtDB0cKNcegoH6D0IOUtQmYrqXiovsc3K +DwqgUL2ctUvDmroJVE4lQ6zpz239D3UoeSiTWAVGy/GudpQgx/9v6fqwO91/tyWk +Grlpf2v320dLCbCXrbbW4lPq7IeoIkTgPwnVlyLMrm4Ht+Ck6KPgbUyRaVpSuJum +6geA9Miczekv3PhPkF2/ltKwRLUt1TmujBdNTAxYXX6VWw32oh5YSQ2wTVZgvCN/ +HJvSW5N2fuEsO8jYX/0RxZjGrbsGyCXtXqElwmETO8JX+wuc6Rd1IFdDKDszUbLh +HEtMBdb/Dhv//gNkEwrPHw9tLH8nd+B4dCJNC/4+Au54t6SpRT2sV6FVNA4Ytkpu +O1OCs2cmIuGFBylDDZCSCWG+1U/dUVoqRh0ufg9PcFDdeicp6Q6cqyBNEVNXG7HU +g7c5zf0XOT7m3+G+d+pPvvzOsZrTKVlOcsAlI7aiqTFFtUUGpHtjm03OP2SKrakb +bPjVbZWzjvRe3st8+GXdv2/i0SuVZW0mTE+6+pPd1/6VlRGOqmI= +=+39w +-----END PGP SIGNATURE----- diff --git a/openssl-1_1.changes b/openssl-1_1.changes index f6dd3da..ebbe5d3 100644 --- a/openssl-1_1.changes +++ b/openssl-1_1.changes @@ -1,3 +1,45 @@ +------------------------------------------------------------------- +Thu May 30 12:19:51 UTC 2019 - Vítězslav Čížek + +- Update openssl-fix_underflow_in_errstr_handling.patch to use + upstream approved code + * https://github.com/openssl/openssl/pull/8966 +- update openssl.keyring to include Richard Levitte's key + +------------------------------------------------------------------- +Thu May 30 09:55:01 UTC 2019 - Vítězslav Čížek + +- Update to 1.1.1c + * Prevent over long nonces in ChaCha20-Poly1305 (CVE-2019-1543) + ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input + for every encryption operation. RFC 7539 specifies that the nonce value + (IV) should be 96 bits (12 bytes). OpenSSL allows a variable nonce length + and front pads the nonce with 0 bytes if it is less than 12 + bytes. However it also incorrectly allows a nonce to be set of up to 16 + bytes. In this case only the last 12 bytes are significant and any + additional leading bytes are ignored. + * Add build tests for C++. These are generated files that only do one + thing, to include one public OpenSSL head file each. This tests that + the public header files can be usefully included in a C++ application. + * Enable SHA3 pre-hashing for ECDSA and DSA. + * Change the default RSA, DSA and DH size to 2048 bit instead of 1024. + This changes the size when using the genpkey app when no size is given. It + fixes an omission in earlier changes that changed all RSA, DSA and DH + generation apps to use 2048 bits by default. + * Reorganize the manual pages to consistently have RETURN VALUES, + EXAMPLES, SEE ALSO and HISTORY come in that order, and adjust + util/fix-doc-nits accordingly. + * Add the missing accessor EVP_PKEY_get0_engine() + * Have apps like 's_client' and 's_server' output the signature scheme + along with other cipher suite parameters when debugging. + * Make OPENSSL_config() error agnostic again. + * Do the error handling in RSA decryption constant time. + * Ensure that SM2 only uses SM3 as digest algorithm +- drop upstream integrated patches + * openssl-fix-handling-of-GNU-strerror_r.patch + * 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch +- refresh 0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch + ------------------------------------------------------------------- Tue May 28 08:21:52 UTC 2019 - Jiri Slaby diff --git a/openssl-1_1.spec b/openssl-1_1.spec index 287c4ed..221f7ce 100644 --- a/openssl-1_1.spec +++ b/openssl-1_1.spec @@ -21,7 +21,7 @@ %define _rname openssl Name: openssl-1_1 # Don't forget to update the version in the "openssl" package! -Version: 1.1.1b +Version: 1.1.1c Release: 0 Summary: Secure Sockets and Transport Layer Security License: OpenSSL @@ -32,7 +32,6 @@ Source: https://www.%{_rname}.org/source/%{_rname}-%{version}.tar.gz Source1: %{name}.changes Source2: baselibs.conf Source3: https://www.%{_rname}.org/source/%{_rname}-%{version}.tar.gz.asc -# https://www.openssl.org/about/ # http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xA2D29B7BF295C759#/openssl.keyring Source4: %{_rname}.keyring Source5: showciphers.c @@ -48,11 +47,7 @@ Patch7: 0001-s390x-assembly-pack-perlasm-support.patch Patch8: 0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch # PATCH-FIX-UPSTREAM FATE#326351 Add vectorized poly1305 implementation for s390x (https://github.com/openssl/openssl/pull/7991) Patch9: 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch -# PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/8371 -Patch10: openssl-fix-handling-of-GNU-strerror_r.patch Patch11: openssl-fix_underflow_in_errstr_handling.patch -# PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/8649 bnc#1136522 -Patch12: 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch BuildRequires: pkgconfig Conflicts: ssl Provides: ssl diff --git a/openssl-fix-handling-of-GNU-strerror_r.patch b/openssl-fix-handling-of-GNU-strerror_r.patch deleted file mode 100644 index 1624159..0000000 --- a/openssl-fix-handling-of-GNU-strerror_r.patch +++ /dev/null @@ -1,50 +0,0 @@ -Index: openssl-1.1.1b/crypto/o_str.c -=================================================================== ---- openssl-1.1.1b.orig/crypto/o_str.c 2019-02-26 15:15:30.000000000 +0100 -+++ openssl-1.1.1b/crypto/o_str.c 2019-05-20 17:06:07.956663953 +0200 -@@ -223,7 +223,26 @@ int openssl_strerror_r(int errnum, char - #if defined(_MSC_VER) && _MSC_VER>=1400 - return !strerror_s(buf, buflen, errnum); - #elif defined(_GNU_SOURCE) -- return strerror_r(errnum, buf, buflen) != NULL; -+ char *err; -+ -+ /* -+ * GNU strerror_r may not actually set buf. -+ * It can return a pointer to some (immutable) static string in which case -+ * buf is left unused. -+ */ -+ err = strerror_r(errnum, buf, buflen); -+ if (err == NULL) -+ return 0; -+ /* -+ * If err is statically allocated, err != buf and we need to copy the data. -+ * If err points somewhere inside buf, OPENSSL_strlcpy can handle this, -+ * since src and dest are not annotated with __restrict and the function -+ * reads src byte for byte and writes to dest. -+ * If err == buf we do not have to copy anything. -+ */ -+ if (err != buf) -+ OPENSSL_strlcpy(buf, err, buflen); -+ return 1; - #elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \ - (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) - /* -@@ -234,6 +253,7 @@ int openssl_strerror_r(int errnum, char - return !strerror_r(errnum, buf, buflen); - #else - char *err; -+ - /* Fall back to non-thread safe strerror()...its all we can do */ - if (buflen < 2) - return 0; -@@ -241,8 +261,7 @@ int openssl_strerror_r(int errnum, char - /* Can this ever happen? */ - if (err == NULL) - return 0; -- strncpy(buf, err, buflen - 1); -- buf[buflen - 1] = '\0'; -+ OPENSSL_strlcpy(buf, err, buflen); - return 1; - #endif - } diff --git a/openssl-fix_underflow_in_errstr_handling.patch b/openssl-fix_underflow_in_errstr_handling.patch index 557b994..ac635bb 100644 --- a/openssl-fix_underflow_in_errstr_handling.patch +++ b/openssl-fix_underflow_in_errstr_handling.patch @@ -1,24 +1,56 @@ -Index: openssl-1.1.1b/crypto/err/err.c -=================================================================== ---- openssl-1.1.1b.orig/crypto/err/err.c 2019-02-26 15:15:30.000000000 +0100 -+++ openssl-1.1.1b/crypto/err/err.c 2019-05-21 21:14:31.211536069 +0200 -@@ -185,7 +185,7 @@ static ERR_STRING_DATA *int_err_get_item +diff --git a/crypto/err/err.c b/crypto/err/err.c +index 345d230206..84ef2fa3d4 100644 +--- a/crypto/err/err.c ++++ b/crypto/err/err.c +@@ -187,8 +187,8 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) + } #ifndef OPENSSL_NO_ERR - /* A measurement on Linux 2018-11-21 showed about 3.5kib */ +-/* A measurement on Linux 2018-11-21 showed about 3.5kib */ -# define SPACE_SYS_STR_REASONS 4 * 1024 -+# define SPACE_SYS_STR_REASONS 8 * 1024 ++/* 2019-05-21: Russian and Ukrainian locales on Linux require more than 6,5 kB */ ++# define SPACE_SYS_STR_REASONS 4 * 1024 # define NUM_SYS_STR_REASONS 127 static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; -@@ -225,8 +225,8 @@ static void build_SYS_str_reasons(void) +@@ -222,26 +222,30 @@ static void build_SYS_str_reasons(void) + ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; + + str->error = ERR_PACK(ERR_LIB_SYS, 0, i); +- if (str->string == NULL) { ++ /* ++ * If we have used up all the space in strerror_pool, ++ * there's no point in calling openssl_strerror_r() ++ */ ++ if (str->string == NULL && cnt < sizeof(strerror_pool)) { + if (openssl_strerror_r(i, cur, sizeof(strerror_pool) - cnt)) { +- size_t l = strlen(cur); ++ size_t l = strlen(cur) + 1; str->string = cur; cnt += l; - if (cnt > sizeof(strerror_pool)) - cnt = sizeof(strerror_pool); -+ if (cnt >= sizeof(strerror_pool)) -+ cnt = sizeof(strerror_pool) - 1; cur += l; /* + * VMS has an unusual quirk of adding spaces at the end of +- * some (most? all?) messages. Lets trim them off. ++ * some (most? all?) messages. Lets trim them off. + */ +- while (ossl_isspace(cur[-1])) { +- cur--; +- cnt--; ++ if (cur > strerror_pool && ossl_isspace(cur[-1])) { ++ while (cur > strerror_pool && ossl_isspace(cur[-1])) { ++ cur--; ++ cnt--; ++ } ++ *cur++ = '\0'; ++ cnt++; + } +- *cur++ = '\0'; +- cnt++; + } + } + if (str->string == NULL) diff --git a/openssl.keyring b/openssl.keyring index bba5399..b09e9e0 100644 --- a/openssl.keyring +++ b/openssl.keyring @@ -1,5 +1,4 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2 mQENBFGALsIBCADBkh6zfxbewW2KJjaMaishSrpxuiVaUyvWgpe6Moae7JNCW8ay hJbwAtsQ69SGA4gUkyrR6PBvDMVYEiYqZwXB/3IErStESjcu+gkbmsa0XcwHpkE3 @@ -153,6 +152,560 @@ Y611daA12AMXscpli8cGvqnK20sAw/sF9YG9Tthjn24qZRJzm+XQ3OxpJvHk8NJA SRIgIsj7+EjC4Rc5vpnuA6tfsXW7LzdOYcU46MPaYuXmKxTMWFotWTR9lJj6YKCD f+KdvBvyDfX3VhuTYt9ead1oSx0TMwutPSDrAiCbJvPpR1W5U99I8aXLRVZUAbWw 084KkC4mk1Xr5XGt1WIDHe9A9vHdfOoMVLUhKWd3SpL/tFfAy4UOlUf8EO/NByiK -RaelFj+Wg8aRKDhMHto= -=m5FY +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 +ExXybKkE2NY= +=B5lM -----END PGP PUBLIC KEY BLOCK----- From 949eaaafb4eaf87b2bd7676091ac1e82a335397024d268ffe4ff8db384e64c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Thu, 6 Jun 2019 11:11:21 +0000 Subject: [PATCH 5/6] Accepting request 708112 from home:vitezslav_cizek:branches:factory - Use upstream patch for the locale crash (bsc#1135550) - delete openssl-fix_underflow_in_errstr_handling.patch - add 0001-build_SYS_str_reasons-Fix-a-crash-caused-by-overlong.patch - Add s390x vectorized support for ChaCha20 and Poly1305 (jsc#SLE-6126, jsc#SLE-6129) * 0001-s390x-assembly-pack-perlasm-support.patch * 0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch * 0003-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch * 0004-s390x-assembly-pack-fix-formal-interface-bug-in-chac.patch * 0005-s390x-assembly-pack-import-chacha-from-cryptogams-re.patch * 0006-s390x-assembly-pack-import-poly-from-cryptogams-repo.patch - Update to 1.1.1c (bsc#1133925, jsc#SLE-6430) - drop upstreamed patches: - update keyring by including Richard Levitte's key OBS-URL: https://build.opensuse.org/request/show/708112 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=38 --- ...asons-Fix-a-crash-caused-by-overlong.patch | 79 + ...-s390x-assembly-pack-perlasm-support.patch | 2 +- ...asm-chacha-s390x.pl-add-vx-code-path.patch | 4 +- ...asm-poly1305-s390x.pl-add-vx-code-pa.patch | 2 +- ...ack-fix-formal-interface-bug-in-chac.patch | 31 + ...ack-import-chacha-from-cryptogams-re.patch | 1094 +++++++++++ ...ack-import-poly-from-cryptogams-repo.patch | 1631 +++++++++++++++++ openssl-1_1.changes | 26 +- openssl-1_1.spec | 16 +- ...ssl-fix_underflow_in_errstr_handling.patch | 56 - 10 files changed, 2868 insertions(+), 73 deletions(-) create mode 100644 0001-build_SYS_str_reasons-Fix-a-crash-caused-by-overlong.patch rename 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch => 0003-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch (99%) create mode 100644 0004-s390x-assembly-pack-fix-formal-interface-bug-in-chac.patch create mode 100644 0005-s390x-assembly-pack-import-chacha-from-cryptogams-re.patch create mode 100644 0006-s390x-assembly-pack-import-poly-from-cryptogams-repo.patch delete mode 100644 openssl-fix_underflow_in_errstr_handling.patch diff --git a/0001-build_SYS_str_reasons-Fix-a-crash-caused-by-overlong.patch b/0001-build_SYS_str_reasons-Fix-a-crash-caused-by-overlong.patch new file mode 100644 index 0000000..d3af960 --- /dev/null +++ b/0001-build_SYS_str_reasons-Fix-a-crash-caused-by-overlong.patch @@ -0,0 +1,79 @@ +From fac9200a881a83bef038ebed628ebd409786a1a6 Mon Sep 17 00:00:00 2001 +From: Vitezslav Cizek +Date: Tue, 4 Jun 2019 13:24:59 +0200 +Subject: [PATCH] build_SYS_str_reasons: Fix a crash caused by overlong locales + +The 4 kB SPACE_SYS_STR_REASONS in crypto/err/err.c isn't enough for some locales. +The Russian locales consume 6856 bytes, Ukrainian even 7000. + +build_SYS_str_reasons() contains an overflow check: + +if (cnt > sizeof(strerror_pool)) + cnt = sizeof(strerror_pool); + +But since commit 9f15e5b911ba6053e09578f190354568e01c07d7 it no longer +works as cnt is incremented once more after the condition. + +cnt greater than sizeof(strerror_pool) results in an unbounded +OPENSSL_strlcpy() in openssl_strerror_r(), eventually causing a crash. + +When the first received error string was empty or contained only +spaces, cur would move in front of the start of the strerror_pool. + +Also don't call openssl_strerror_r when the pool is full. + +Reviewed-by: Bernd Edlinger +Reviewed-by: Richard Levitte +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/8966) +--- + crypto/err/err.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/crypto/err/err.c b/crypto/err/err.c +index 57399f82ad..cf3ae4d3b3 100644 +--- a/crypto/err/err.c ++++ b/crypto/err/err.c +@@ -188,8 +188,8 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) + } + + #ifndef OPENSSL_NO_ERR +-/* A measurement on Linux 2018-11-21 showed about 3.5kib */ +-# define SPACE_SYS_STR_REASONS 4 * 1024 ++/* 2019-05-21: Russian and Ukrainian locales on Linux require more than 6,5 kB */ ++# define SPACE_SYS_STR_REASONS 8 * 1024 + # define NUM_SYS_STR_REASONS 127 + + static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; +@@ -223,21 +223,23 @@ static void build_SYS_str_reasons(void) + ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; + + str->error = ERR_PACK(ERR_LIB_SYS, 0, i); +- if (str->string == NULL) { ++ /* ++ * If we have used up all the space in strerror_pool, ++ * there's no point in calling openssl_strerror_r() ++ */ ++ if (str->string == NULL && cnt < sizeof(strerror_pool)) { + if (openssl_strerror_r(i, cur, sizeof(strerror_pool) - cnt)) { + size_t l = strlen(cur); + + str->string = cur; + cnt += l; +- if (cnt > sizeof(strerror_pool)) +- cnt = sizeof(strerror_pool); + cur += l; + + /* + * VMS has an unusual quirk of adding spaces at the end of +- * some (most? all?) messages. Lets trim them off. ++ * some (most? all?) messages. Lets trim them off. + */ +- while (ossl_isspace(cur[-1])) { ++ while (cur > strerror_pool && ossl_isspace(cur[-1])) { + cur--; + cnt--; + } +-- +2.21.0 + diff --git a/0001-s390x-assembly-pack-perlasm-support.patch b/0001-s390x-assembly-pack-perlasm-support.patch index fa57d43..e4f3a16 100644 --- a/0001-s390x-assembly-pack-perlasm-support.patch +++ b/0001-s390x-assembly-pack-perlasm-support.patch @@ -3085,5 +3085,5 @@ index 0000000000..5f3a49dd0c + +1; -- -2.20.1 +2.21.0 diff --git a/0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch b/0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch index 9c47bed..8e5fca6 100644 --- a/0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch +++ b/0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch @@ -15,8 +15,8 @@ Reviewed-by: Richard Levitte Index: openssl-1.1.1c/crypto/chacha/asm/chacha-s390x.pl =================================================================== ---- openssl-1.1.1c.orig/crypto/chacha/asm/chacha-s390x.pl 2019-05-30 11:52:55.786294410 +0200 -+++ openssl-1.1.1c/crypto/chacha/asm/chacha-s390x.pl 2019-05-30 11:52:58.122308974 +0200 +--- openssl-1.1.1c.orig/crypto/chacha/asm/chacha-s390x.pl 2019-06-06 12:15:57.271195550 +0200 ++++ openssl-1.1.1c/crypto/chacha/asm/chacha-s390x.pl 2019-06-06 12:16:43.787489780 +0200 @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. diff --git a/0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch b/0003-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch similarity index 99% rename from 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch rename to 0003-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch index 6b0c509..a1097e8 100644 --- a/0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch +++ b/0003-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch @@ -1002,5 +1002,5 @@ index 21ca86055e..390f9eefe7 100755 + +PERLASM_END(); -- -2.20.1 +2.21.0 diff --git a/0004-s390x-assembly-pack-fix-formal-interface-bug-in-chac.patch b/0004-s390x-assembly-pack-fix-formal-interface-bug-in-chac.patch new file mode 100644 index 0000000..d2d623d --- /dev/null +++ b/0004-s390x-assembly-pack-fix-formal-interface-bug-in-chac.patch @@ -0,0 +1,31 @@ +From b2b580fe445e064da50c13d3e00f71022da16ece Mon Sep 17 00:00:00 2001 +From: Patrick Steuer +Date: Fri, 15 Feb 2019 22:59:09 +0100 +Subject: [PATCH] s390x assembly pack: fix formal interface bug in chacha + module + +Signed-off-by: Patrick Steuer + +Reviewed-by: Tim Hudson +Reviewed-by: Richard Levitte +(Merged from https://github.com/openssl/openssl/pull/8257) +--- + crypto/chacha/asm/chacha-s390x.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/crypto/chacha/asm/chacha-s390x.pl b/crypto/chacha/asm/chacha-s390x.pl +index 005c810e20..abf7283dd8 100755 +--- a/crypto/chacha/asm/chacha-s390x.pl ++++ b/crypto/chacha/asm/chacha-s390x.pl +@@ -225,7 +225,7 @@ LABEL ("ChaCha20_ctr32"); + larl ("%r1","OPENSSL_s390xcap_P"); + + lghi ("%r0",64); +-&{$z? \&cgr:\&cr} ($len,"%r0"); ++&{$z? \&clgr:\&clr} ($len,"%r0"); + jle ("_s390x_chacha_novx"); + + lg ("%r0","S390X_STFLE+16(%r1)"); +-- +2.21.0 + diff --git a/0005-s390x-assembly-pack-import-chacha-from-cryptogams-re.patch b/0005-s390x-assembly-pack-import-chacha-from-cryptogams-re.patch new file mode 100644 index 0000000..5f70331 --- /dev/null +++ b/0005-s390x-assembly-pack-import-chacha-from-cryptogams-re.patch @@ -0,0 +1,1094 @@ +From d1229190bfbb19439589557e4d65f9bccab09b2d Mon Sep 17 00:00:00 2001 +From: Patrick Steuer +Date: Mon, 25 Feb 2019 18:55:04 +0100 +Subject: [PATCH] s390x assembly pack: import chacha from cryptogams repo + +featuring 6x"horizontal" code path which is up to 25% +faster than present 4x"vertical" for larger blocks. + +Signed-off-by: Patrick Steuer + +Reviewed-by: Matt Caswell +Reviewed-by: Richard Levitte +(Merged from https://github.com/openssl/openssl/pull/8287) +--- + crypto/chacha/asm/chacha-s390x.pl | 1006 +++++++++++++++++++++-------- + 1 file changed, 719 insertions(+), 287 deletions(-) + +diff --git a/crypto/chacha/asm/chacha-s390x.pl b/crypto/chacha/asm/chacha-s390x.pl +index abf7283dd8..51efe64408 100755 +--- a/crypto/chacha/asm/chacha-s390x.pl ++++ b/crypto/chacha/asm/chacha-s390x.pl +@@ -23,11 +23,20 @@ + # + # August 2018 + # +-# Add vx code path. ++# Add vx code path: 4x"vertical". + # + # Copyright IBM Corp. 2018 + # Author: Patrick Steuer + ++# ++# February 2019 ++# ++# Add 6x"horizontal" VX implementation. It's ~25% faster than IBM's ++# 4x"vertical" submission [on z13] and >3 faster than scalar code. ++# But to harness overheads revert to transliteration of VSX code path ++# from chacha-ppc module, which is also 4x"vertical", to handle inputs ++# not longer than 256 bytes. ++ + use strict; + use FindBin qw($Bin); + use lib "$Bin/../.."; +@@ -50,11 +59,9 @@ while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} + my $sp="%r15"; + my $stdframe=16*$SIZE_T+4*8; + ++sub ROUND { + my @x=map("%r$_",(0..7,"x","x","x","x",(10..13))); + my @t=map("%r$_",(8,9)); +-my @v=map("%v$_",(16..31)); +- +-sub ROUND { + my ($a0,$b0,$c0,$d0)=@_; + my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0)); + my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1)); +@@ -143,63 +150,92 @@ my ($xc,$xc_)=map("$_",@t); + rll (@x[$b3],@x[$b3],7); + } + +-sub VX_ROUND { ++sub VX_lane_ROUND { + my ($a0,$b0,$c0,$d0)=@_; + my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0)); + my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1)); + my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2)); ++my @x=map("%v$_",(0..15)); ++ ++ vaf (@x[$a0],@x[$a0],@x[$b0]); # Q1 ++ vx (@x[$d0],@x[$d0],@x[$a0]); ++ verllf (@x[$d0],@x[$d0],16); ++ vaf (@x[$a1],@x[$a1],@x[$b1]); # Q2 ++ vx (@x[$d1],@x[$d1],@x[$a1]); ++ verllf (@x[$d1],@x[$d1],16); ++ vaf (@x[$a2],@x[$a2],@x[$b2]); # Q3 ++ vx (@x[$d2],@x[$d2],@x[$a2]); ++ verllf (@x[$d2],@x[$d2],16); ++ vaf (@x[$a3],@x[$a3],@x[$b3]); # Q4 ++ vx (@x[$d3],@x[$d3],@x[$a3]); ++ verllf (@x[$d3],@x[$d3],16); ++ ++ vaf (@x[$c0],@x[$c0],@x[$d0]); ++ vx (@x[$b0],@x[$b0],@x[$c0]); ++ verllf (@x[$b0],@x[$b0],12); ++ vaf (@x[$c1],@x[$c1],@x[$d1]); ++ vx (@x[$b1],@x[$b1],@x[$c1]); ++ verllf (@x[$b1],@x[$b1],12); ++ vaf (@x[$c2],@x[$c2],@x[$d2]); ++ vx (@x[$b2],@x[$b2],@x[$c2]); ++ verllf (@x[$b2],@x[$b2],12); ++ vaf (@x[$c3],@x[$c3],@x[$d3]); ++ vx (@x[$b3],@x[$b3],@x[$c3]); ++ verllf (@x[$b3],@x[$b3],12); ++ ++ vaf (@x[$a0],@x[$a0],@x[$b0]); ++ vx (@x[$d0],@x[$d0],@x[$a0]); ++ verllf (@x[$d0],@x[$d0],8); ++ vaf (@x[$a1],@x[$a1],@x[$b1]); ++ vx (@x[$d1],@x[$d1],@x[$a1]); ++ verllf (@x[$d1],@x[$d1],8); ++ vaf (@x[$a2],@x[$a2],@x[$b2]); ++ vx (@x[$d2],@x[$d2],@x[$a2]); ++ verllf (@x[$d2],@x[$d2],8); ++ vaf (@x[$a3],@x[$a3],@x[$b3]); ++ vx (@x[$d3],@x[$d3],@x[$a3]); ++ verllf (@x[$d3],@x[$d3],8); ++ ++ vaf (@x[$c0],@x[$c0],@x[$d0]); ++ vx (@x[$b0],@x[$b0],@x[$c0]); ++ verllf (@x[$b0],@x[$b0],7); ++ vaf (@x[$c1],@x[$c1],@x[$d1]); ++ vx (@x[$b1],@x[$b1],@x[$c1]); ++ verllf (@x[$b1],@x[$b1],7); ++ vaf (@x[$c2],@x[$c2],@x[$d2]); ++ vx (@x[$b2],@x[$b2],@x[$c2]); ++ verllf (@x[$b2],@x[$b2],7); ++ vaf (@x[$c3],@x[$c3],@x[$d3]); ++ vx (@x[$b3],@x[$b3],@x[$c3]); ++ verllf (@x[$b3],@x[$b3],7); ++} + +- vaf (@v[$a0],@v[$a0],@v[$b0]); +- vaf (@v[$a1],@v[$a1],@v[$b1]); +- vaf (@v[$a2],@v[$a2],@v[$b2]); +- vaf (@v[$a3],@v[$a3],@v[$b3]); +- vx (@v[$d0],@v[$d0],@v[$a0]); +- vx (@v[$d1],@v[$d1],@v[$a1]); +- vx (@v[$d2],@v[$d2],@v[$a2]); +- vx (@v[$d3],@v[$d3],@v[$a3]); +- verllf (@v[$d0],@v[$d0],16); +- verllf (@v[$d1],@v[$d1],16); +- verllf (@v[$d2],@v[$d2],16); +- verllf (@v[$d3],@v[$d3],16); +- +- vaf (@v[$c0],@v[$c0],@v[$d0]); +- vaf (@v[$c1],@v[$c1],@v[$d1]); +- vaf (@v[$c2],@v[$c2],@v[$d2]); +- vaf (@v[$c3],@v[$c3],@v[$d3]); +- vx (@v[$b0],@v[$b0],@v[$c0]); +- vx (@v[$b1],@v[$b1],@v[$c1]); +- vx (@v[$b2],@v[$b2],@v[$c2]); +- vx (@v[$b3],@v[$b3],@v[$c3]); +- verllf (@v[$b0],@v[$b0],12); +- verllf (@v[$b1],@v[$b1],12); +- verllf (@v[$b2],@v[$b2],12); +- verllf (@v[$b3],@v[$b3],12); +- +- vaf (@v[$a0],@v[$a0],@v[$b0]); +- vaf (@v[$a1],@v[$a1],@v[$b1]); +- vaf (@v[$a2],@v[$a2],@v[$b2]); +- vaf (@v[$a3],@v[$a3],@v[$b3]); +- vx (@v[$d0],@v[$d0],@v[$a0]); +- vx (@v[$d1],@v[$d1],@v[$a1]); +- vx (@v[$d2],@v[$d2],@v[$a2]); +- vx (@v[$d3],@v[$d3],@v[$a3]); +- verllf (@v[$d0],@v[$d0],8); +- verllf (@v[$d1],@v[$d1],8); +- verllf (@v[$d2],@v[$d2],8); +- verllf (@v[$d3],@v[$d3],8); +- +- vaf (@v[$c0],@v[$c0],@v[$d0]); +- vaf (@v[$c1],@v[$c1],@v[$d1]); +- vaf (@v[$c2],@v[$c2],@v[$d2]); +- vaf (@v[$c3],@v[$c3],@v[$d3]); +- vx (@v[$b0],@v[$b0],@v[$c0]); +- vx (@v[$b1],@v[$b1],@v[$c1]); +- vx (@v[$b2],@v[$b2],@v[$c2]); +- vx (@v[$b3],@v[$b3],@v[$c3]); +- verllf (@v[$b0],@v[$b0],7); +- verllf (@v[$b1],@v[$b1],7); +- verllf (@v[$b2],@v[$b2],7); +- verllf (@v[$b3],@v[$b3],7); ++sub VX_ROUND { ++my @a=@_[0..5]; ++my @b=@_[6..11]; ++my @c=@_[12..17]; ++my @d=@_[18..23]; ++my $odd=@_[24]; ++ ++ vaf (@a[$_],@a[$_],@b[$_]) for (0..5); ++ vx (@d[$_],@d[$_],@a[$_]) for (0..5); ++ verllf (@d[$_],@d[$_],16) for (0..5); ++ ++ vaf (@c[$_],@c[$_],@d[$_]) for (0..5); ++ vx (@b[$_],@b[$_],@c[$_]) for (0..5); ++ verllf (@b[$_],@b[$_],12) for (0..5); ++ ++ vaf (@a[$_],@a[$_],@b[$_]) for (0..5); ++ vx (@d[$_],@d[$_],@a[$_]) for (0..5); ++ verllf (@d[$_],@d[$_],8) for (0..5); ++ ++ vaf (@c[$_],@c[$_],@d[$_]) for (0..5); ++ vx (@b[$_],@b[$_],@c[$_]) for (0..5); ++ verllf (@b[$_],@b[$_],7) for (0..5); ++ ++ vsldb (@c[$_],@c[$_],@c[$_],8) for (0..5); ++ vsldb (@b[$_],@b[$_],@b[$_],$odd?12:4) for (0..5); ++ vsldb (@d[$_],@d[$_],@d[$_],$odd?4:12) for (0..5); + } + + PERLASM_BEGIN($output); +@@ -210,13 +246,11 @@ TEXT (); + ################ + # void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, + # const unsigned int key[8], const unsigned int counter[4]) +-{ + my ($out,$inp,$len,$key,$counter)=map("%r$_",(2..6)); +- +-# VX CODE PATH + { +-my $off=$z*8*16+8; # offset(initial state) +-my $frame=$stdframe+4*16+$off; ++my $frame=$stdframe+4*20; ++my @x=map("%r$_",(0..7,"x","x","x","x",(10..13))); ++my @t=map("%r$_",(8,9)); + + GLOBL ("ChaCha20_ctr32"); + TYPE ("ChaCha20_ctr32","\@function"); +@@ -225,230 +259,16 @@ LABEL ("ChaCha20_ctr32"); + larl ("%r1","OPENSSL_s390xcap_P"); + + lghi ("%r0",64); ++&{$z? \<gr:\<r} ($len,$len); # len==0? ++ bzr ("%r14"); ++ lg ("%r1","S390X_STFLE+16(%r1)"); + &{$z? \&clgr:\&clr} ($len,"%r0"); +- jle ("_s390x_chacha_novx"); +- +- lg ("%r0","S390X_STFLE+16(%r1)"); +- tmhh ("%r0",0x4000); # check for vector facility +- jz ("_s390x_chacha_novx"); +- +-if (!$z) { +- llgfr ($len,$len); +- std ("%f4","16*$SIZE_T+2*8($sp)"); +- std ("%f6","16*$SIZE_T+3*8($sp)"); +-} +-&{$z? \&stmg:\&stm} ("%r6","%r7","6*$SIZE_T($sp)"); ++ jle (".Lshort"); + +- lghi ("%r1",-$frame); +- lgr ("%r0",$sp); +- la ($sp,"0(%r1,$sp)"); # allocate stack frame ++ tmhh ("%r1",0x4000); # check for vx bit ++ jnz (".LChaCha20_ctr32_vx"); + +- larl ("%r7",".Lsigma"); +-&{$z? \&stg:\&st} ("%r0","0($sp)"); # backchain +- +- vstm ("%v8","%v15","8($sp)") if ($z); +- +- vlm ("%v1","%v2","0($key)"); # load key +- vl ("%v0","0(%r7)"); # load sigma constant +- vl ("%v3","0($counter)"); # load iv (counter||nonce) +- l ("%r0","0($counter)"); # load counter +- vstm ("%v0","%v3","$off($sp)"); # copy initial state to stack +- +- srlg ("%r1",$len,8); +- ltgr ("%r1","%r1"); +- jz (".Lvx_4x_done"); +- +-ALIGN (16); # process 4 64-byte blocks +-LABEL (".Lvx_4x"); +- vlrepf ("%v$_",($_*4)."+$off($sp)") for (0..15); # load initial +- # state +- vl ("%v31","16(%r7)"); +- vaf ("%v12","%v12","%v31"); # increment counter +- +- vlr (@v[$_],"%v$_") for (0..15); # copy initial state +- +- lhi ("%r6",10); +- j (".Loop_vx_4x"); +- +-ALIGN (16); +-LABEL (".Loop_vx_4x"); +- VX_ROUND( 0, 4, 8,12); # column round +- VX_ROUND( 0, 5,10,15); # diagonal round +- brct ("%r6",".Loop_vx_4x"); +- +- vaf (@v[$_],@v[$_],"%v$_") for (0..15); # state += initial +- # state (mod 32) +- vlm ("%v6","%v7","32(%r7)"); # load vperm operands +- +-for (0..3) { # blocks 1,2 +- vmrhf ("%v0",@v[$_*4+0],@v[$_*4+1]); # ks = serialize(state) +- vmrhf ("%v1",@v[$_*4+2],@v[$_*4+3]); +- vperm ("%v".($_+ 8),"%v0","%v1","%v6"); +- vperm ("%v".($_+12),"%v0","%v1","%v7"); +-} +- vlm ("%v0","%v7","0($inp)"); # load in +- vx ("%v$_","%v$_","%v".($_+8)) for (0..7); # out = in ^ ks +- vstm ("%v0","%v7","0($out)"); # store out +- +- vlm ("%v6","%v7","32(%r7)"); # restore vperm operands +- +-for (0..3) { # blocks 2,3 +- vmrlf ("%v0",@v[$_*4+0],@v[$_*4+1]); # ks = serialize(state) +- vmrlf ("%v1",@v[$_*4+2],@v[$_*4+3]); +- vperm ("%v".($_+ 8),"%v0","%v1","%v6"); +- vperm ("%v".($_+12),"%v0","%v1","%v7"); +-} +- vlm ("%v0","%v7","128($inp)"); # load in +- vx ("%v$_","%v$_","%v".($_+8)) for (0..7); # out = in ^ ks +- vstm ("%v0","%v7","128($out)"); # store out +- +- ahi ("%r0",4); +- st ("%r0","48+$off($sp)"); # update initial state +- +- la ($inp,"256($inp)"); +- la ($out,"256($out)"); +- brctg ("%r1",".Lvx_4x"); +- +-ALIGN (16); +-LABEL (".Lvx_4x_done"); +- lghi ("%r1",0xff); +- ngr ($len,"%r1"); +- jnz (".Lvx_rem"); +- +-ALIGN (16); +-LABEL (".Lvx_done"); +- vzero ("%v$_") for (16..31); # wipe ks and key copy +- vstm ("%v16","%v17","16+$off($sp)"); +- vlm ("%v8","%v15","8($sp)") if ($z); +- +- la ($sp,"$frame($sp)"); +-&{$z? \&lmg:\&lm} ("%r6","%r7","6*$SIZE_T($sp)"); +- +-if (!$z) { +- ld ("%f4","16*$SIZE_T+2*8($sp)"); +- ld ("%f6","16*$SIZE_T+3*8($sp)"); +- vzero ("%v$_") for (8..15); +-} +- br ("%r14"); +-ALIGN (16); +-LABEL (".Lvx_rem"); +- lhi ("%r0",64); +- +- sr ($len,"%r0"); +- brc (2,".Lvx_rem_g64"); # cc==2? +- +- lghi ("%r1",-$stdframe); +- +- la ($counter,"48+$off($sp)"); # load updated iv +- ar ($len,"%r0"); # restore len +- +- lgr ("%r7",$counter); +-&{$z? \&stg:\&st} ("%r14","14*$SIZE_T+$frame($sp)"); +- la ($sp,"0(%r1,$sp)"); +- +- bras ("%r14","_s390x_chacha_novx"); +- +- la ($sp,"$stdframe($sp)"); +-&{$z? \&lg:\&l} ("%r14","14*$SIZE_T+$frame($sp)"); +- lgr ($counter,"%r7"); +- j (".Lvx_done"); +- +-ALIGN (16); +-LABEL (".Lvx_rem_g64"); +- vlrepf ("%v$_",($_*4)."+$off($sp)") for (0..15); # load initial +- # state +- vl ("%v31","16(%r7)"); +- vaf ("%v12","%v12","%v31"); # increment counter +- +- vlr (@v[$_],"%v$_") for (0..15); # state = initial state +- +- lhi ("%r6",10); +- j (".Loop_vx_rem"); +- +-ALIGN (16); +-LABEL (".Loop_vx_rem"); +- VX_ROUND( 0, 4, 8,12); # column round +- VX_ROUND( 0, 5,10,15); # diagonal round +- brct ("%r6",".Loop_vx_rem"); +- +- vaf (@v[$_],@v[$_],"%v$_") for (0..15); # state += initial +- # state (mod 32) +- vlm ("%v6","%v7","32(%r7)"); # load vperm operands +- +-for (0..3) { # blocks 1,2 +- vmrhf ("%v0",@v[$_*4+0],@v[$_*4+1]); # ks = serialize(state) +- vmrhf ("%v1",@v[$_*4+2],@v[$_*4+3]); +- vperm ("%v".($_+8),"%v0","%v1","%v6"); +- vperm ("%v".($_+12),"%v0","%v1","%v7"); +-} +- vlm ("%v0","%v3","0($inp)"); # load in +- vx ("%v$_","%v$_","%v".($_+8)) for (0..3); # out = in ^ ks +- vstm ("%v0","%v3","0($out)"); # store out +- +- la ($inp,"64($inp)"); +- la ($out,"64($out)"); +- +- sr ($len,"%r0"); +- brc (4,".Lvx_tail"); # cc==4? +- +- vlm ("%v0","%v3","0($inp)"); # load in +- vx ("%v$_","%v$_","%v".($_+12)) for (0..3); # out = in ^ ks +- vstm ("%v0","%v3","0($out)"); # store out +- jz (".Lvx_done"); +- +-for (0..3) { # blocks 3,4 +- vmrlf ("%v0",@v[$_*4+0],@v[$_*4+1]); # ks = serialize(state) +- vmrlf ("%v1",@v[$_*4+2],@v[$_*4+3]); +- vperm ("%v".($_+12),"%v0","%v1","%v6"); +- vperm ("%v".($_+8),"%v0","%v1","%v7"); +-} +- la ($inp,"64($inp)"); +- la ($out,"64($out)"); +- +- sr ($len,"%r0"); +- brc (4,".Lvx_tail"); # cc==4? +- +- vlm ("%v0","%v3","0($inp)"); # load in +- vx ("%v$_","%v$_","%v".($_+12)) for (0..3); # out = in ^ ks +- vstm ("%v0","%v3","0($out)"); # store out +- jz (".Lvx_done"); +- +- la ($inp,"64($inp)"); +- la ($out,"64($out)"); +- +- sr ($len,"%r0"); +- vlr ("%v".($_+4),"%v$_") for (8..11); +- j (".Lvx_tail"); +- +-ALIGN (16); +-LABEL (".Lvx_tail"); +- ar ($len,"%r0"); # restore $len +- ahi ($len,-1); +- +- lhi ("%r0",16); +-for (0..2) { +- vll ("%v0",$len,($_*16)."($inp)"); +- vx ("%v0","%v0","%v".($_+12)); +- vstl ("%v0",$len,($_*16)."($out)"); +- sr ($len,"%r0"); +- brc (4,".Lvx_done"); # cc==4? +-} +- vll ("%v0",$len,"3*16($inp)"); +- vx ("%v0","%v0","%v15"); +- vstl ("%v0",$len,"3*16($out)"); +- j (".Lvx_done"); +-SIZE ("ChaCha20_ctr32",".-ChaCha20_ctr32"); +-} +- +-# NOVX CODE PATH +-{ +-my $frame=$stdframe+4*20; +- +-TYPE ("_s390x_chacha_novx","\@function"); +-ALIGN (32); +-LABEL ("_s390x_chacha_novx"); +-&{$z? \<gr:\<r} ($len,$len); # $len==0? +- bzr ("%r14"); ++LABEL (".Lshort"); + &{$z? \&aghi:\&ahi} ($len,-64); + &{$z? \&lghi:\&lhi} ("%r1",-$frame); + &{$z? \&stmg:\&stm} ("%r6","%r15","6*$SIZE_T($sp)"); +@@ -607,17 +427,629 @@ LABEL (".Loop_tail"); + brct (@t[1],".Loop_tail"); + + j (".Ldone"); +-SIZE ("_s390x_chacha_novx",".-_s390x_chacha_novx"); ++SIZE ("ChaCha20_ctr32",".-ChaCha20_ctr32"); ++} ++ ++######################################################################## ++# 4x"vertical" layout minimizes amount of instructions, but pipeline ++# runs underutilized [because of vector instructions' high latency]. ++# On the other hand minimum amount of data it takes to fully utilize ++# the pipeline is higher, so that effectively, short inputs would be ++# processed slower. Hence this code path targeting <=256 bytes lengths. ++# ++{ ++my ($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3, ++ $xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3)=map("%v$_",(0..15)); ++my @K=map("%v$_",(16..19)); ++my $CTR="%v26"; ++my ($xt0,$xt1,$xt2,$xt3)=map("%v$_",(27..30)); ++my $beperm="%v31"; ++my ($x00,$x10,$x20,$x30)=(0,map("r$_",(8..10))); ++my $FRAME=$stdframe+4*16; ++ ++ALIGN (32); ++LABEL ("ChaCha20_ctr32_4x"); ++LABEL (".LChaCha20_ctr32_4x"); ++&{$z? \&stmg:\&stm} ("%r6","%r7","6*$SIZE_T($sp)"); ++if (!$z) { ++ std ("%f4","16*$SIZE_T+2*8($sp)"); ++ std ("%f6","16*$SIZE_T+3*8($sp)"); ++} ++&{$z? \&lghi:\&lhi} ("%r1",-$FRAME); ++ lgr ("%r0",$sp); ++ la ($sp,"0(%r1,$sp)"); ++&{$z? \&stg:\&st} ("%r0","0($sp)"); # back-chain ++if ($z) { ++ std ("%f8","$stdframe+8*0($sp)"); ++ std ("%f9","$stdframe+8*1($sp)"); ++ std ("%f10","$stdframe+8*2($sp)"); ++ std ("%f11","$stdframe+8*3($sp)"); ++ std ("%f12","$stdframe+8*4($sp)"); ++ std ("%f13","$stdframe+8*5($sp)"); ++ std ("%f14","$stdframe+8*6($sp)"); ++ std ("%f15","$stdframe+8*7($sp)"); ++} ++ larl ("%r7",".Lsigma"); ++ lhi ("%r0",10); ++ lhi ("%r1",0); ++ ++ vl (@K[0],"0(%r7)"); # load sigma ++ vl (@K[1],"0($key)"); # load key ++ vl (@K[2],"16($key)"); ++ vl (@K[3],"0($counter)"); # load counter ++ ++ vl ($beperm,"0x40(%r7)"); ++ vl ($xt1,"0x50(%r7)"); ++ vrepf ($CTR,@K[3],0); ++ vlvgf (@K[3],"%r1",0); # clear @K[3].word[0] ++ vaf ($CTR,$CTR,$xt1); ++ ++#LABEL (".Loop_outer_4x"); ++ vlm ($xa0,$xa3,"0x60(%r7)"); # load [smashed] sigma ++ ++ vrepf ($xb0,@K[1],0); # smash the key ++ vrepf ($xb1,@K[1],1); ++ vrepf ($xb2,@K[1],2); ++ vrepf ($xb3,@K[1],3); ++ ++ vrepf ($xc0,@K[2],0); ++ vrepf ($xc1,@K[2],1); ++ vrepf ($xc2,@K[2],2); ++ vrepf ($xc3,@K[2],3); ++ ++ vlr ($xd0,$CTR); ++ vrepf ($xd1,@K[3],1); ++ vrepf ($xd2,@K[3],2); ++ vrepf ($xd3,@K[3],3); ++ ++LABEL (".Loop_4x"); ++ VX_lane_ROUND(0, 4, 8,12); ++ VX_lane_ROUND(0, 5,10,15); ++ brct ("%r0",".Loop_4x"); ++ ++ vaf ($xd0,$xd0,$CTR); ++ ++ vmrhf ($xt0,$xa0,$xa1); # transpose data ++ vmrhf ($xt1,$xa2,$xa3); ++ vmrlf ($xt2,$xa0,$xa1); ++ vmrlf ($xt3,$xa2,$xa3); ++ vpdi ($xa0,$xt0,$xt1,0b0000); ++ vpdi ($xa1,$xt0,$xt1,0b0101); ++ vpdi ($xa2,$xt2,$xt3,0b0000); ++ vpdi ($xa3,$xt2,$xt3,0b0101); ++ ++ vmrhf ($xt0,$xb0,$xb1); ++ vmrhf ($xt1,$xb2,$xb3); ++ vmrlf ($xt2,$xb0,$xb1); ++ vmrlf ($xt3,$xb2,$xb3); ++ vpdi ($xb0,$xt0,$xt1,0b0000); ++ vpdi ($xb1,$xt0,$xt1,0b0101); ++ vpdi ($xb2,$xt2,$xt3,0b0000); ++ vpdi ($xb3,$xt2,$xt3,0b0101); ++ ++ vmrhf ($xt0,$xc0,$xc1); ++ vmrhf ($xt1,$xc2,$xc3); ++ vmrlf ($xt2,$xc0,$xc1); ++ vmrlf ($xt3,$xc2,$xc3); ++ vpdi ($xc0,$xt0,$xt1,0b0000); ++ vpdi ($xc1,$xt0,$xt1,0b0101); ++ vpdi ($xc2,$xt2,$xt3,0b0000); ++ vpdi ($xc3,$xt2,$xt3,0b0101); ++ ++ vmrhf ($xt0,$xd0,$xd1); ++ vmrhf ($xt1,$xd2,$xd3); ++ vmrlf ($xt2,$xd0,$xd1); ++ vmrlf ($xt3,$xd2,$xd3); ++ vpdi ($xd0,$xt0,$xt1,0b0000); ++ vpdi ($xd1,$xt0,$xt1,0b0101); ++ vpdi ($xd2,$xt2,$xt3,0b0000); ++ vpdi ($xd3,$xt2,$xt3,0b0101); ++ ++ #vrepif ($xt0,4); ++ #vaf ($CTR,$CTR,$xt0); # next counter value ++ ++ vaf ($xa0,$xa0,@K[0]); ++ vaf ($xb0,$xb0,@K[1]); ++ vaf ($xc0,$xc0,@K[2]); ++ vaf ($xd0,$xd0,@K[3]); ++ ++ vperm ($xa0,$xa0,$xa0,$beperm); ++ vperm ($xb0,$xb0,$xb0,$beperm); ++ vperm ($xc0,$xc0,$xc0,$beperm); ++ vperm ($xd0,$xd0,$xd0,$beperm); ++ ++ #&{$z? \&clgfi:\&clfi} ($len,0x40); ++ #jl (".Ltail_4x"); ++ ++ vlm ($xt0,$xt3,"0($inp)"); ++ ++ vx ($xt0,$xt0,$xa0); ++ vx ($xt1,$xt1,$xb0); ++ vx ($xt2,$xt2,$xc0); ++ vx ($xt3,$xt3,$xd0); ++ ++ vstm ($xt0,$xt3,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ #je (".Ldone_4x"); ++ ++ vaf ($xa0,$xa1,@K[0]); ++ vaf ($xb0,$xb1,@K[1]); ++ vaf ($xc0,$xc1,@K[2]); ++ vaf ($xd0,$xd1,@K[3]); ++ ++ vperm ($xa0,$xa0,$xa0,$beperm); ++ vperm ($xb0,$xb0,$xb0,$beperm); ++ vperm ($xc0,$xc0,$xc0,$beperm); ++ vperm ($xd0,$xd0,$xd0,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_4x"); ++ ++ vlm ($xt0,$xt3,"0($inp)"); ++ ++ vx ($xt0,$xt0,$xa0); ++ vx ($xt1,$xt1,$xb0); ++ vx ($xt2,$xt2,$xc0); ++ vx ($xt3,$xt3,$xd0); ++ ++ vstm ($xt0,$xt3,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ je (".Ldone_4x"); ++ ++ vaf ($xa0,$xa2,@K[0]); ++ vaf ($xb0,$xb2,@K[1]); ++ vaf ($xc0,$xc2,@K[2]); ++ vaf ($xd0,$xd2,@K[3]); ++ ++ vperm ($xa0,$xa0,$xa0,$beperm); ++ vperm ($xb0,$xb0,$xb0,$beperm); ++ vperm ($xc0,$xc0,$xc0,$beperm); ++ vperm ($xd0,$xd0,$xd0,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_4x"); ++ ++ vlm ($xt0,$xt3,"0($inp)"); ++ ++ vx ($xt0,$xt0,$xa0); ++ vx ($xt1,$xt1,$xb0); ++ vx ($xt2,$xt2,$xc0); ++ vx ($xt3,$xt3,$xd0); ++ ++ vstm ($xt0,$xt3,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ je (".Ldone_4x"); ++ ++ vaf ($xa0,$xa3,@K[0]); ++ vaf ($xb0,$xb3,@K[1]); ++ vaf ($xc0,$xc3,@K[2]); ++ vaf ($xd0,$xd3,@K[3]); ++ ++ vperm ($xa0,$xa0,$xa0,$beperm); ++ vperm ($xb0,$xb0,$xb0,$beperm); ++ vperm ($xc0,$xc0,$xc0,$beperm); ++ vperm ($xd0,$xd0,$xd0,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_4x"); ++ ++ vlm ($xt0,$xt3,"0($inp)"); ++ ++ vx ($xt0,$xt0,$xa0); ++ vx ($xt1,$xt1,$xb0); ++ vx ($xt2,$xt2,$xc0); ++ vx ($xt3,$xt3,$xd0); ++ ++ vstm ($xt0,$xt3,"0($out)"); ++ ++ #la $inp,0x40($inp)); ++ #la $out,0x40($out)); ++ #lhi %r0,10); ++ #&{$z? \&aghi:\&ahi} $len,-0x40); ++ #jne .Loop_outer_4x); ++ ++LABEL (".Ldone_4x"); ++if (!$z) { ++ ld ("%f4","$FRAME+16*$SIZE_T+2*8($sp)"); ++ ld ("%f6","$FRAME+16*$SIZE_T+3*8($sp)"); ++} else { ++ ld ("%f8","$stdframe+8*0($sp)"); ++ ld ("%f9","$stdframe+8*1($sp)"); ++ ld ("%f10","$stdframe+8*2($sp)"); ++ ld ("%f11","$stdframe+8*3($sp)"); ++ ld ("%f12","$stdframe+8*4($sp)"); ++ ld ("%f13","$stdframe+8*5($sp)"); ++ ld ("%f14","$stdframe+8*6($sp)"); ++ ld ("%f15","$stdframe+8*7($sp)"); ++} ++&{$z? \&lmg:\&lm} ("%r6","%r7","$FRAME+6*$SIZE_T($sp)"); ++ la ($sp,"$FRAME($sp)"); ++ br ("%r14"); ++ ++ALIGN (16); ++LABEL (".Ltail_4x"); ++if (!$z) { ++ vlr ($xt0,$xb0); ++ ld ("%f4","$FRAME+16*$SIZE_T+2*8($sp)"); ++ ld ("%f6","$FRAME+16*$SIZE_T+3*8($sp)"); ++ ++ vst ($xa0,"$stdframe+0x00($sp)"); ++ vst ($xt0,"$stdframe+0x10($sp)"); ++ vst ($xc0,"$stdframe+0x20($sp)"); ++ vst ($xd0,"$stdframe+0x30($sp)"); ++} else { ++ vlr ($xt0,$xc0); ++ ld ("%f8","$stdframe+8*0($sp)"); ++ ld ("%f9","$stdframe+8*1($sp)"); ++ ld ("%f10","$stdframe+8*2($sp)"); ++ ld ("%f11","$stdframe+8*3($sp)"); ++ vlr ($xt1,$xd0); ++ ld ("%f12","$stdframe+8*4($sp)"); ++ ld ("%f13","$stdframe+8*5($sp)"); ++ ld ("%f14","$stdframe+8*6($sp)"); ++ ld ("%f15","$stdframe+8*7($sp)"); ++ ++ vst ($xa0,"$stdframe+0x00($sp)"); ++ vst ($xb0,"$stdframe+0x10($sp)"); ++ vst ($xt0,"$stdframe+0x20($sp)"); ++ vst ($xt1,"$stdframe+0x30($sp)"); + } ++ lghi ("%r1",0); ++ ++LABEL (".Loop_tail_4x"); ++ llgc ("%r5","0(%r1,$inp)"); ++ llgc ("%r6","$stdframe(%r1,$sp)"); ++ xr ("%r6","%r5"); ++ stc ("%r6","0(%r1,$out)"); ++ la ("%r1","1(%r1)"); ++ brct ($len,".Loop_tail_4x"); ++ ++&{$z? \&lmg:\&lm} ("%r6","%r7","$FRAME+6*$SIZE_T($sp)"); ++ la ($sp,"$FRAME($sp)"); ++ br ("%r14"); ++SIZE ("ChaCha20_ctr32_4x",".-ChaCha20_ctr32_4x"); ++} ++ ++######################################################################## ++# 6x"horizontal" layout is optimal fit for the platform in its current ++# shape, more specifically for given vector instructions' latency. Well, ++# computational part of 8x"vertical" would be faster, but it consumes ++# all registers and dealing with that will diminish the return... ++# ++{ ++my ($a0,$b0,$c0,$d0, $a1,$b1,$c1,$d1, ++ $a2,$b2,$c2,$d2, $a3,$b3,$c3,$d3, ++ $a4,$b4,$c4,$d4, $a5,$b5,$c5,$d5)=map("%v$_",(0..23)); ++my @K=map("%v$_",(27,24..26)); ++my ($t0,$t1,$t2,$t3)=map("%v$_",27..30); ++my $beperm="%v31"; ++my $FRAME=$stdframe + 4*16; ++ ++GLOBL ("ChaCha20_ctr32_vx"); ++ALIGN (32); ++LABEL ("ChaCha20_ctr32_vx"); ++LABEL (".LChaCha20_ctr32_vx"); ++&{$z? \&clgfi:\&clfi} ($len,256); ++ jle (".LChaCha20_ctr32_4x"); ++&{$z? \&stmg:\&stm} ("%r6","%r7","6*$SIZE_T($sp)"); ++if (!$z) { ++ std ("%f4","16*$SIZE_T+2*8($sp)"); ++ std ("%f6","16*$SIZE_T+3*8($sp)"); ++} ++&{$z? \&lghi:\&lhi} ("%r1",-$FRAME); ++ lgr ("%r0",$sp); ++ la ($sp,"0(%r1,$sp)"); ++&{$z? \&stg:\&st} ("%r0","0($sp)"); # back-chain ++if ($z) { ++ std ("%f8","$FRAME-8*8($sp)"); ++ std ("%f9","$FRAME-8*7($sp)"); ++ std ("%f10","$FRAME-8*6($sp)"); ++ std ("%f11","$FRAME-8*5($sp)"); ++ std ("%f12","$FRAME-8*4($sp)"); ++ std ("%f13","$FRAME-8*3($sp)"); ++ std ("%f14","$FRAME-8*2($sp)"); ++ std ("%f15","$FRAME-8*1($sp)"); ++} ++ larl ("%r7",".Lsigma"); ++ lhi ("%r0",10); ++ ++ vlm (@K[1],@K[2],"0($key)"); # load key ++ vl (@K[3],"0($counter)"); # load counter ++ ++ vlm (@K[0],"$beperm","0(%r7)"); # load sigma, increments, ... ++ ++LABEL (".Loop_outer_vx"); ++ vlr ($a0,@K[0]); ++ vlr ($b0,@K[1]); ++ vlr ($a1,@K[0]); ++ vlr ($b1,@K[1]); ++ vlr ($a2,@K[0]); ++ vlr ($b2,@K[1]); ++ vlr ($a3,@K[0]); ++ vlr ($b3,@K[1]); ++ vlr ($a4,@K[0]); ++ vlr ($b4,@K[1]); ++ vlr ($a5,@K[0]); ++ vlr ($b5,@K[1]); ++ ++ vlr ($d0,@K[3]); ++ vaf ($d1,@K[3],$t1); # K[3]+1 ++ vaf ($d2,@K[3],$t2); # K[3]+2 ++ vaf ($d3,@K[3],$t3); # K[3]+3 ++ vaf ($d4,$d2,$t2); # K[3]+4 ++ vaf ($d5,$d2,$t3); # K[3]+5 ++ ++ vlr ($c0,@K[2]); ++ vlr ($c1,@K[2]); ++ vlr ($c2,@K[2]); ++ vlr ($c3,@K[2]); ++ vlr ($c4,@K[2]); ++ vlr ($c5,@K[2]); ++ ++ vlr ($t1,$d1); ++ vlr ($t2,$d2); ++ vlr ($t3,$d3); ++ ++ALIGN (4); ++LABEL (".Loop_vx"); ++ ++ VX_ROUND($a0,$a1,$a2,$a3,$a4,$a5, ++ $b0,$b1,$b2,$b3,$b4,$b5, ++ $c0,$c1,$c2,$c3,$c4,$c5, ++ $d0,$d1,$d2,$d3,$d4,$d5, ++ 0); ++ ++ VX_ROUND($a0,$a1,$a2,$a3,$a4,$a5, ++ $b0,$b1,$b2,$b3,$b4,$b5, ++ $c0,$c1,$c2,$c3,$c4,$c5, ++ $d0,$d1,$d2,$d3,$d4,$d5, ++ 1); ++ ++ brct ("%r0",".Loop_vx"); ++ ++ vaf ($a0,$a0,@K[0]); ++ vaf ($b0,$b0,@K[1]); ++ vaf ($c0,$c0,@K[2]); ++ vaf ($d0,$d0,@K[3]); ++ vaf ($a1,$a1,@K[0]); ++ vaf ($d1,$d1,$t1); # +K[3]+1 ++ ++ vperm ($a0,$a0,$a0,$beperm); ++ vperm ($b0,$b0,$b0,$beperm); ++ vperm ($c0,$c0,$c0,$beperm); ++ vperm ($d0,$d0,$d0,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_vx"); ++ ++ vaf ($d2,$d2,$t2); # +K[3]+2 ++ vaf ($d3,$d3,$t3); # +K[3]+3 ++ vlm ($t0,$t3,"0($inp)"); ++ ++ vx ($a0,$a0,$t0); ++ vx ($b0,$b0,$t1); ++ vx ($c0,$c0,$t2); ++ vx ($d0,$d0,$t3); ++ ++ vlm (@K[0],$t3,"0(%r7)"); # re-load sigma and increments ++ ++ vstm ($a0,$d0,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ je (".Ldone_vx"); ++ ++ vaf ($b1,$b1,@K[1]); ++ vaf ($c1,$c1,@K[2]); ++ ++ vperm ($a0,$a1,$a1,$beperm); ++ vperm ($b0,$b1,$b1,$beperm); ++ vperm ($c0,$c1,$c1,$beperm); ++ vperm ($d0,$d1,$d1,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_vx"); ++ ++ vlm ($a1,$d1,"0($inp)"); ++ ++ vx ($a0,$a0,$a1); ++ vx ($b0,$b0,$b1); ++ vx ($c0,$c0,$c1); ++ vx ($d0,$d0,$d1); ++ ++ vstm ($a0,$d0,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ je (".Ldone_vx"); ++ ++ vaf ($a2,$a2,@K[0]); ++ vaf ($b2,$b2,@K[1]); ++ vaf ($c2,$c2,@K[2]); ++ ++ vperm ($a0,$a2,$a2,$beperm); ++ vperm ($b0,$b2,$b2,$beperm); ++ vperm ($c0,$c2,$c2,$beperm); ++ vperm ($d0,$d2,$d2,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_vx"); ++ ++ vlm ($a1,$d1,"0($inp)"); ++ ++ vx ($a0,$a0,$a1); ++ vx ($b0,$b0,$b1); ++ vx ($c0,$c0,$c1); ++ vx ($d0,$d0,$d1); ++ ++ vstm ($a0,$d0,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ je (".Ldone_vx"); ++ ++ vaf ($a3,$a3,@K[0]); ++ vaf ($b3,$b3,@K[1]); ++ vaf ($c3,$c3,@K[2]); ++ vaf ($d2,@K[3],$t3); # K[3]+3 ++ ++ vperm ($a0,$a3,$a3,$beperm); ++ vperm ($b0,$b3,$b3,$beperm); ++ vperm ($c0,$c3,$c3,$beperm); ++ vperm ($d0,$d3,$d3,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_vx"); ++ ++ vaf ($d3,$d2,$t1); # K[3]+4 ++ vlm ($a1,$d1,"0($inp)"); ++ ++ vx ($a0,$a0,$a1); ++ vx ($b0,$b0,$b1); ++ vx ($c0,$c0,$c1); ++ vx ($d0,$d0,$d1); ++ ++ vstm ($a0,$d0,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ je (".Ldone_vx"); ++ ++ vaf ($a4,$a4,@K[0]); ++ vaf ($b4,$b4,@K[1]); ++ vaf ($c4,$c4,@K[2]); ++ vaf ($d4,$d4,$d3); # +K[3]+4 ++ vaf ($d3,$d3,$t1); # K[3]+5 ++ vaf (@K[3],$d2,$t3); # K[3]+=6 ++ ++ vperm ($a0,$a4,$a4,$beperm); ++ vperm ($b0,$b4,$b4,$beperm); ++ vperm ($c0,$c4,$c4,$beperm); ++ vperm ($d0,$d4,$d4,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_vx"); ++ ++ vlm ($a1,$d1,"0($inp)"); ++ ++ vx ($a0,$a0,$a1); ++ vx ($b0,$b0,$b1); ++ vx ($c0,$c0,$c1); ++ vx ($d0,$d0,$d1); ++ ++ vstm ($a0,$d0,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ je (".Ldone_vx"); ++ ++ vaf ($a5,$a5,@K[0]); ++ vaf ($b5,$b5,@K[1]); ++ vaf ($c5,$c5,@K[2]); ++ vaf ($d5,$d5,$d3); # +K[3]+5 ++ ++ vperm ($a0,$a5,$a5,$beperm); ++ vperm ($b0,$b5,$b5,$beperm); ++ vperm ($c0,$c5,$c5,$beperm); ++ vperm ($d0,$d5,$d5,$beperm); ++ ++&{$z? \&clgfi:\&clfi} ($len,0x40); ++ jl (".Ltail_vx"); ++ ++ vlm ($a1,$d1,"0($inp)"); ++ ++ vx ($a0,$a0,$a1); ++ vx ($b0,$b0,$b1); ++ vx ($c0,$c0,$c1); ++ vx ($d0,$d0,$d1); ++ ++ vstm ($a0,$d0,"0($out)"); ++ ++ la ($inp,"0x40($inp)"); ++ la ($out,"0x40($out)"); ++ lhi ("%r0",10); ++&{$z? \&aghi:\&ahi} ($len,-0x40); ++ jne (".Loop_outer_vx"); ++ ++LABEL (".Ldone_vx"); ++if (!$z) { ++ ld ("%f4","$FRAME+16*$SIZE_T+2*8($sp)"); ++ ld ("%f6","$FRAME+16*$SIZE_T+3*8($sp)"); ++} else { ++ ld ("%f8","$FRAME-8*8($sp)"); ++ ld ("%f9","$FRAME-8*7($sp)"); ++ ld ("%f10","$FRAME-8*6($sp)"); ++ ld ("%f11","$FRAME-8*5($sp)"); ++ ld ("%f12","$FRAME-8*4($sp)"); ++ ld ("%f13","$FRAME-8*3($sp)"); ++ ld ("%f14","$FRAME-8*2($sp)"); ++ ld ("%f15","$FRAME-8*1($sp)"); ++} ++&{$z? \&lmg:\&lm} ("%r6","%r7","$FRAME+6*$SIZE_T($sp)"); ++ la ($sp,"$FRAME($sp)"); ++ br ("%r14"); ++ ++ALIGN (16); ++LABEL (".Ltail_vx"); ++if (!$z) { ++ ld ("%f4","$FRAME+16*$SIZE_T+2*8($sp)"); ++ ld ("%f6","$FRAME+16*$SIZE_T+3*8($sp)"); ++} else { ++ ld ("%f8","$FRAME-8*8($sp)"); ++ ld ("%f9","$FRAME-8*7($sp)"); ++ ld ("%f10","$FRAME-8*6($sp)"); ++ ld ("%f11","$FRAME-8*5($sp)"); ++ ld ("%f12","$FRAME-8*4($sp)"); ++ ld ("%f13","$FRAME-8*3($sp)"); ++ ld ("%f14","$FRAME-8*2($sp)"); ++ ld ("%f15","$FRAME-8*1($sp)"); ++} ++ vstm ($a0,$d0,"$stdframe($sp)"); ++ lghi ("%r1",0); ++ ++LABEL (".Loop_tail_vx"); ++ llgc ("%r5","0(%r1,$inp)"); ++ llgc ("%r6","$stdframe(%r1,$sp)"); ++ xr ("%r6","%r5"); ++ stc ("%r6","0(%r1,$out)"); ++ la ("%r1","1(%r1)"); ++ brct ($len,".Loop_tail_vx"); ++ ++&{$z? \&lmg:\&lm} ("%r6","%r7","$FRAME+6*$SIZE_T($sp)"); ++ la ($sp,"$FRAME($sp)"); ++ br ("%r14"); ++SIZE ("ChaCha20_ctr32_vx",".-ChaCha20_ctr32_vx"); + } + ################ + +-ALIGN (64); ++ALIGN (32); + LABEL (".Lsigma"); + LONG (0x61707865,0x3320646e,0x79622d32,0x6b206574); # endian-neutral sigma +-LONG (0x00000000,0x00000001,0x00000002,0x00000003); # vaf counter increment +-LONG (0x03020100,0x07060504,0x13121110,0x17161514); # vperm serialization +-LONG (0x0b0a0908,0x0f0e0d0c,0x1b1a1918,0x1f1e1d1c); # vperm serialization ++LONG (1,0,0,0); ++LONG (2,0,0,0); ++LONG (3,0,0,0); ++LONG (0x03020100,0x07060504,0x0b0a0908,0x0f0e0d0c); # byte swap ++ ++LONG (0,1,2,3); ++LONG (0x61707865,0x61707865,0x61707865,0x61707865); # smashed sigma ++LONG (0x3320646e,0x3320646e,0x3320646e,0x3320646e); ++LONG (0x79622d32,0x79622d32,0x79622d32,0x79622d32); ++LONG (0x6b206574,0x6b206574,0x6b206574,0x6b206574); ++ + ASCIZ ("\"ChaCha20 for s390x, CRYPTOGAMS by \""); + ALIGN (4); + +-- +2.21.0 + diff --git a/0006-s390x-assembly-pack-import-poly-from-cryptogams-repo.patch b/0006-s390x-assembly-pack-import-poly-from-cryptogams-repo.patch new file mode 100644 index 0000000..ceec91a --- /dev/null +++ b/0006-s390x-assembly-pack-import-poly-from-cryptogams-repo.patch @@ -0,0 +1,1631 @@ +From 2e6b615f795e8ca8ae830a00079c4ea064eaae42 Mon Sep 17 00:00:00 2001 +From: Patrick Steuer +Date: Sat, 23 Mar 2019 00:03:24 +0100 +Subject: [PATCH] s390x assembly pack: import poly from cryptogams repo + +>=20% faster than present code. + +Signed-off-by: Patrick Steuer + +Reviewed-by: Matt Caswell +Reviewed-by: Richard Levitte +(Merged from https://github.com/openssl/openssl/pull/8560) +--- + crypto/poly1305/asm/poly1305-s390x.pl | 1455 ++++++++++++++----------- + crypto/poly1305/build.info | 1 + + 2 files changed, 799 insertions(+), 657 deletions(-) + +Index: openssl-1.1.1c/crypto/poly1305/asm/poly1305-s390x.pl +=================================================================== +--- openssl-1.1.1c.orig/crypto/poly1305/asm/poly1305-s390x.pl 2019-06-06 12:18:53.384309579 +0200 ++++ openssl-1.1.1c/crypto/poly1305/asm/poly1305-s390x.pl 2019-06-06 12:18:54.556316994 +0200 +@@ -32,10 +32,20 @@ + # Copyright IBM Corp. 2019 + # Author: Patrick Steuer + ++# ++# January 2019 ++# ++# Add vector base 2^26 implementation. It's problematic to accurately ++# measure performance, because reference system is hardly idle. But ++# it's sub-cycle, i.e. less than 1 cycle per processed byte, and it's ++# >=20% faster than IBM's submission on long inputs, and much faster on ++# short ones, because calculation of key powers is postponed till we ++# know that input is long enough to justify the additional overhead. ++ + use strict; + use FindBin qw($Bin); + use lib "$Bin/../.."; +-use perlasm::s390x qw(:DEFAULT :VX AUTOLOAD LABEL); ++use perlasm::s390x qw(:DEFAULT :VX AUTOLOAD LABEL INCLUDE); + + my $flavour = shift; + +@@ -51,666 +61,98 @@ if ($flavour =~ /3[12]/) { + my $output; + while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} + ++my $stdframe=16*$SIZE_T+4*8; + my $sp="%r15"; + +-# novx code path ctx layout +-# --------------------------------- +-# var value base off +-# --------------------------------- +-# u64 h[3] hash 2^64 0 +-# u32 pad[2] +-# u64 r[2] key 2^64 32 +- +-# vx code path ctx layout +-# --------------------------------- +-# var value base off +-# --------------------------------- +-# u32 acc1[5] r^2-acc 2^26 0 +-# u32 pad +-# u32 acc2[5] r-acc 2^26 24 +-# u32 pad +-# u32 r1[5] r 2^26 48 +-# u32 r15[5] 5*r 2^26 68 +-# u32 r2[5] r^2 2^26 88 +-# u32 r25[5] 5*r^2 2^26 108 +-# u32 r4[5] r^4 2^26 128 +-# u32 r45[5] 5*r^4 2^26 148 ++my ($ctx,$inp,$len,$padbit) = map("%r$_",(2..5)); + + PERLASM_BEGIN($output); + ++INCLUDE ("s390x_arch.h"); + TEXT (); + + ################ + # static void poly1305_init(void *ctx, const unsigned char key[16]) + { +-my ($ctx,$key)=map("%r$_",(2..3)); +-my ($r0,$r1,$r2)=map("%r$_",(9,11,13)); +- +-sub MUL_RKEY { # r*=key +-my ($d0hi,$d0lo,$d1hi,$d1lo)=map("%r$_",(4..7)); +-my ($t0,$t1,$s1)=map("%r$_",(8,10,12)); +- +- lg ("%r0","32($ctx)"); +- lg ("%r1","40($ctx)"); +- +- srlg ($s1,"%r1",2); +- algr ($s1,"%r1"); +- +- lgr ($d0lo,$r0); +- lgr ($d1lo,$r1); +- +- mlgr ($d0hi,"%r0"); +- lgr ($r1,$d1lo); +- mlgr ($d1hi,$s1); +- +- mlgr ($t0,"%r1"); +- mlgr ($t1,"%r0"); +- +- algr ($d0lo,$d1lo); +- lgr ($d1lo,$r2); +- alcgr ($d0hi,$d1hi); +- lghi ($d1hi,0); +- +- algr ($r1,$r0); +- alcgr ($t1,$t0); +- +- msgr ($d1lo,$s1); +- msgr ($r2,"%r0"); +- +- algr ($r1,$d1lo); +- alcgr ($t1,$d1hi); +- +- algr ($r1,$d0hi); +- alcgr ($r2,$t1); +- +- lghi ($r0,-4); +- ngr ($r0,$r2); +- srlg ($t0,$r2,2); +- algr ($r0,$t0); +- lghi ($t1,3); +- ngr ($r2,$t1); +- +- algr ($r0,$d0lo); +- alcgr ($r1,$d1hi); +- alcgr ($r2,$d1hi); +-} +- +-sub ST_R5R { # store r,5*r -> base 2^26 +-my @d=map("%r$_",(4..8)); +-my @off=@_; +- +- lgr (@d[2],$r0); +- lr ("%r1",@d[2]); +- nilh ("%r1",1023); +- lgr (@d[3],$r1); +- lr (@d[0],"%r1"); +- srlg ("%r1",@d[2],52); +- lgr (@d[4],$r2); +- srlg ("%r0",@d[2],26); +- sll (@d[4],24); +- lr (@d[2],@d[3]); +- nilh ("%r0",1023); +- sll (@d[2],12); +- lr (@d[1],"%r0"); +- &or (@d[2],"%r1"); +- srlg ("%r1",@d[3],40); +- nilh (@d[2],1023); +- &or (@d[4],"%r1"); +- srlg (@d[3],@d[3],14); +- nilh (@d[4],1023); +- nilh (@d[3],1023); +- +- stm (@d[0],@d[4],"@off[0]($ctx)"); +- mhi (@d[$_],5) for (0..4); +- stm (@d[0],@d[4],"@off[1]($ctx)"); +-} +- + GLOBL ("poly1305_init"); + TYPE ("poly1305_init","\@function"); + ALIGN (16); + LABEL ("poly1305_init"); + lghi ("%r0",0); + lghi ("%r1",-1); +- stg ("%r0","0($ctx)"); # zero hash value / acc1 ++ stg ("%r0","0($ctx)"); # zero hash value + stg ("%r0","8($ctx)"); + stg ("%r0","16($ctx)"); ++ st ("%r0","24($ctx)"); # clear is_base2_26 ++ lgr ("%r5",$ctx); # reassign $ctx ++ lghi ("%r2",0); + +-&{$z? \&clgr:\&clr} ($key,"%r0"); +- je (".Ldone"); ++&{$z? \&clgr:\&clr} ($inp,"%r0"); ++ je (".Lno_key"); + +- lrvg ("%r4","0($key)"); # load little-endian key +- lrvg ("%r5","8($key)"); ++ lrvg ("%r2","0($inp)"); # load little-endian key ++ lrvg ("%r3","8($inp)"); + +- nihl ("%r1",0xffc0); # 0xffffffc0ffffffff +- srlg ("%r0","%r1",4); # 0x0ffffffc0fffffff ++ nihl ("%r1",0xffc0); # 0xffffffc0ffffffff ++ srlg ("%r0","%r1",4); # 0x0ffffffc0fffffff + srlg ("%r1","%r1",4); +- nill ("%r1",0xfffc); # 0x0ffffffc0ffffffc ++ nill ("%r1",0xfffc); # 0x0ffffffc0ffffffc + +- ngr ("%r4","%r0"); +- ngr ("%r5","%r1"); ++ ngr ("%r2","%r0"); ++ ngr ("%r3","%r1"); + +- stg ("%r4","32($ctx)"); +- stg ("%r5","40($ctx)"); ++ stmg ("%r2","%r3","32(%r5)"); + + larl ("%r1","OPENSSL_s390xcap_P"); + lg ("%r0","16(%r1)"); +- tmhh ("%r0",0x4000); # check for vector facility +- jz (".Ldone"); +- +- larl ("%r4","poly1305_blocks_vx"); +- larl ("%r5","poly1305_emit_vx"); +- +-&{$z? \&stmg:\&stm} ("%r6","%r13","6*$SIZE_T($sp)"); +-&{$z? \&stmg:\&stm} ("%r4","%r5","4*$z+228($ctx)"); +- +- lg ($r0,"32($ctx)"); +- lg ($r1,"40($ctx)"); +- lghi ($r2,0); +- +- ST_R5R (48,68); # store r,5*r +- +- MUL_RKEY(); +- ST_R5R (88,108); # store r^2,5*r^2 +- +- MUL_RKEY(); +- MUL_RKEY(); +- ST_R5R (128,148); # store r^4,5*r^4 +- +- lghi ("%r0",0); +- stg ("%r0","24($ctx)"); # zero acc2 +- stg ("%r0","32($ctx)"); +- stg ("%r0","40($ctx)"); +- +-&{$z? \&lmg:\&lm} ("%r6","%r13","6*$SIZE_T($sp)"); ++ srlg ("%r0","%r0",62); ++ nill ("%r0",1); # extract vx bit ++ lcgr ("%r0","%r0"); ++ larl ("%r1",".Lpoly1305_blocks"); ++ larl ("%r2",".Lpoly1305_blocks_vx"); ++ larl ("%r3",".Lpoly1305_emit"); ++&{$z? \&xgr:\&xr} ("%r2","%r1"); # select between scalar and vector ++&{$z? \&ngr:\&nr} ("%r2","%r0"); ++&{$z? \&xgr:\&xr} ("%r2","%r1"); ++&{$z? \&stmg:\&stm} ("%r2","%r3","0(%r4)"); + lghi ("%r2",1); +- br ("%r14"); +- +-LABEL (".Ldone"); +- lghi ("%r2",0); ++LABEL (".Lno_key"); + br ("%r14"); + SIZE ("poly1305_init",".-poly1305_init"); + } + +-# VX CODE PATH +-{ +-my $frame=8*16; +-my @m01=map("%v$_",(0..4)); +-my @m23=map("%v$_",(5..9)); +-my @tmp=@m23; +-my @acc=map("%v$_",(10..14)); +-my @r=map("%v$_",(15..19)); +-my @r5=map("%v$_",(20..24)); +-my $padvec="%v26"; +-my $mask4="%v27"; +-my @vperm=map("%v$_",(28..30)); +-my $mask="%v31"; +- +-sub REDUCE { +- vesrlg (@tmp[0],@acc[0],26); +- vesrlg (@tmp[3],@acc[3],26); +- vn (@acc[0],@acc[0],$mask); +- vn (@acc[3],@acc[3],$mask); +- vag (@acc[1],@acc[1],@tmp[0]); # carry 0->1 +- vag (@acc[4],@acc[4],@tmp[3]); # carry 3->4 +- +- vesrlg (@tmp[1],@acc[1],26); +- vesrlg (@tmp[4],@acc[4],26); +- vn (@acc[1],@acc[1],$mask); +- vn (@acc[4],@acc[4],$mask); +- veslg (@tmp[0],@tmp[4],2); +- vag (@tmp[4],@tmp[4],@tmp[0]); # h[4]*=5 +- vag (@acc[2],@acc[2],@tmp[1]); # carry 1->2 +- vag (@acc[0],@acc[0],@tmp[4]); # carry 4->0 +- +- vesrlg (@tmp[2],@acc[2],26); +- vesrlg (@tmp[0],@acc[0],26); +- vn (@acc[2],@acc[2],$mask); +- vn (@acc[0],@acc[0],$mask); +- vag (@acc[3],@acc[3],@tmp[2]); # carry 2->3 +- vag (@acc[1],@acc[1],@tmp[0]); # carry 0->1 +- +- vesrlg (@tmp[3],@acc[3],26); +- vn (@acc[3],@acc[3],$mask); +- vag (@acc[4],@acc[4],@tmp[3]); # carry 3->4 +-} +- + ################ +-# static void poly1305_blocks_vx(void *ctx, const unsigned char *inp, +-# size_t len, u32 padbit) ++# static void poly1305_blocks(void *ctx, const unsigned char *inp, ++# size_t len, u32 padbit) + { +-my ($ctx,$inp,$len) = map("%r$_",(2..4)); +-my $padbit="%r0"; +- +-GLOBL ("poly1305_blocks_vx"); +-TYPE ("poly1305_blocks_vx","\@function"); +-ALIGN (16); +-LABEL ("poly1305_blocks_vx"); +-if ($z) { +- aghi ($sp,-$frame); +- vstm ("%v8","%v15","0($sp)"); +-} else { +- std ("%f4","16*$SIZE_T+2*8($sp)"); +- std ("%f6","16*$SIZE_T+3*8($sp)"); +- llgfr ($len,$len); +-} +- llgfr ($padbit,"%r5"); +- vlef (@acc[$_],"4*$_($ctx)",1) for (0..4); # load acc1 +- larl ("%r5",".Lconst"); +- vlef (@acc[$_],"24+4*$_($ctx)",3) for (0..4); # load acc2 +- sllg ($padbit,$padbit,24); +- vlm (@vperm[0],$mask,"0(%r5)"); # load vperm ops, mask +- vgbm ($mask4,0x0707); +- vlvgp ($padvec,$padbit,$padbit); +- +- srlg ("%r1",$len,6); +- ltgr ("%r1","%r1"); +- jz (".Lvx_4x_done"); +- +-ALIGN (16); +-LABEL (".Lvx_4x"); +- vlm ("%v20","%v23","0($inp)"); # load m0,m1,m2,m3 +- +- # m01,m23 -> base 2^26 +- +- vperm (@m01[0],"%v20","%v21",@vperm[0]); +- vperm (@m23[0],"%v22","%v23",@vperm[0]); +- vperm (@m01[2],"%v20","%v21",@vperm[1]); +- vperm (@m23[2],"%v22","%v23",@vperm[1]); +- vperm (@m01[4],"%v20","%v21",@vperm[2]); +- vperm (@m23[4],"%v22","%v23",@vperm[2]); +- +- vesrlg (@m01[1],@m01[0],26); +- vesrlg (@m23[1],@m23[0],26); +- vesrlg (@m01[3],@m01[2],30); +- vesrlg (@m23[3],@m23[2],30); +- vesrlg (@m01[2],@m01[2],4); +- vesrlg (@m23[2],@m23[2],4); +- +- vn (@m01[4],@m01[4],$mask4); +- vn (@m23[4],@m23[4],$mask4); +-for (0..3) { +- vn (@m01[$_],@m01[$_],$mask); +- vn (@m23[$_],@m23[$_],$mask); +-} +- vaf (@m01[4],@m01[4],$padvec); # pad m01 +- vaf (@m23[4],@m23[4],$padvec); # pad m23 +- +- # acc = acc * r^4 + m01 * r^2 + m23 +- +- vlrepf (@r5[$_],"4*$_+108($ctx)") for (0..4); # load 5*r^2 +- vlrepf (@r[$_],"4*$_+88($ctx)") for (0..4); # load r^2 +- +- vmalof (@tmp[0],@m01[4],@r5[1],@m23[0]); +- vmalof (@tmp[1],@m01[4],@r5[2],@m23[1]); +- vmalof (@tmp[2],@m01[4],@r5[3],@m23[2]); +- vmalof (@tmp[3],@m01[4],@r5[4],@m23[3]); +- vmalof (@tmp[4],@m01[4],@r[0],@m23[4]); +- +- vmalof (@tmp[0],@m01[3],@r5[2],@tmp[0]); +- vmalof (@tmp[1],@m01[3],@r5[3],@tmp[1]); +- vmalof (@tmp[2],@m01[3],@r5[4],@tmp[2]); +- vmalof (@tmp[3],@m01[3],@r[0],@tmp[3]); +- vmalof (@tmp[4],@m01[3],@r[1],@tmp[4]); +- +- vmalof (@tmp[0],@m01[2],@r5[3],@tmp[0]); +- vmalof (@tmp[1],@m01[2],@r5[4],@tmp[1]); +- vmalof (@tmp[2],@m01[2],@r[0],@tmp[2]); +- vmalof (@tmp[3],@m01[2],@r[1],@tmp[3]); +- vmalof (@tmp[4],@m01[2],@r[2],@tmp[4]); +- +- vmalof (@tmp[0],@m01[1],@r5[4],@tmp[0]); +- vmalof (@tmp[1],@m01[1],@r[0],@tmp[1]); +- vmalof (@tmp[2],@m01[1],@r[1],@tmp[2]); +- vmalof (@tmp[3],@m01[1],@r[2],@tmp[3]); +- vmalof (@tmp[4],@m01[1],@r[3],@tmp[4]); +- +- vmalof (@tmp[0],@m01[0],@r[0],@tmp[0]); +- vmalof (@tmp[1],@m01[0],@r[1],@tmp[1]); +- vmalof (@tmp[2],@m01[0],@r[2],@tmp[2]); +- vmalof (@tmp[3],@m01[0],@r[3],@tmp[3]); +- vmalof (@tmp[4],@m01[0],@r[4],@tmp[4]); +- +- vlrepf (@r5[$_],"4*$_+148($ctx)") for (0..4); # load 5*r^4 +- vlrepf (@r[$_],"4*$_+128($ctx)") for (0..4); # load r^4 +- +- vmalof (@tmp[0],@acc[4],@r5[1],@tmp[0]); +- vmalof (@tmp[1],@acc[4],@r5[2],@tmp[1]); +- vmalof (@tmp[2],@acc[4],@r5[3],@tmp[2]); +- vmalof (@tmp[3],@acc[4],@r5[4],@tmp[3]); +- vmalof (@tmp[4],@acc[4],@r[0],@tmp[4]); +- +- vmalof (@tmp[0],@acc[3],@r5[2],@tmp[0]); +- vmalof (@tmp[1],@acc[3],@r5[3],@tmp[1]); +- vmalof (@tmp[2],@acc[3],@r5[4],@tmp[2]); +- vmalof (@tmp[3],@acc[3],@r[0],@tmp[3]); +- vmalof (@tmp[4],@acc[3],@r[1],@tmp[4]); +- +- vmalof (@tmp[0],@acc[2],@r5[3],@tmp[0]); +- vmalof (@tmp[1],@acc[2],@r5[4],@tmp[1]); +- vmalof (@tmp[2],@acc[2],@r[0],@tmp[2]); +- vmalof (@tmp[3],@acc[2],@r[1],@tmp[3]); +- vmalof (@tmp[4],@acc[2],@r[2],@tmp[4]); +- +- vmalof (@tmp[0],@acc[1],@r5[4],@tmp[0]); +- vmalof (@tmp[1],@acc[1],@r[0],@tmp[1]); +- vmalof (@tmp[2],@acc[1],@r[1],@tmp[2]); +- vmalof (@tmp[3],@acc[1],@r[2],@tmp[3]); +- vmalof (@tmp[4],@acc[1],@r[3],@tmp[4]); +- +- vmalof (@acc[1],@acc[0],@r[1],@tmp[1]); +- vmalof (@acc[2],@acc[0],@r[2],@tmp[2]); +- vmalof (@acc[3],@acc[0],@r[3],@tmp[3]); +- vmalof (@acc[4],@acc[0],@r[4],@tmp[4]); +- vmalof (@acc[0],@acc[0],@r[0],@tmp[0]); +- +- REDUCE (); +- +- la ($inp,"64($inp)"); +- brctg ("%r1",".Lvx_4x"); +- +-ALIGN (16); +-LABEL (".Lvx_4x_done"); +- tml ($len,32); +- jz (".Lvx_2x_done"); +- +- vlm ("%v20","%v21","0($inp)"); # load m0,m1 +- +- # m01 -> base 2^26 +- +- vperm (@m01[0],"%v20","%v21",@vperm[0]); +- vperm (@m01[2],"%v20","%v21",@vperm[1]); +- vperm (@m01[4],"%v20","%v21",@vperm[2]); +- +- vesrlg (@m01[1],@m01[0],26); +- vesrlg (@m01[3],@m01[2],30); +- vesrlg (@m01[2],@m01[2],4); +- +- vn (@m01[4],@m01[4],$mask4); +- vn (@m01[$_],@m01[$_],$mask) for (0..3); +- +- vaf (@m01[4],@m01[4],$padvec); # pad m01 +- +- # acc = acc * r^2+ m01 +- +- vlrepf (@r5[$_],"4*$_+108($ctx)") for (0..4); # load 5*r^2 +- vlrepf (@r[$_],"4*$_+88($ctx)") for (0..4); # load r^2 +- +- vmalof (@tmp[0],@acc[4],@r5[1],@m01[0]); +- vmalof (@tmp[1],@acc[4],@r5[2],@m01[1]); +- vmalof (@tmp[2],@acc[4],@r5[3],@m01[2]); +- vmalof (@tmp[3],@acc[4],@r5[4],@m01[3]); +- vmalof (@tmp[4],@acc[4],@r[0],@m01[4]); +- +- vmalof (@tmp[0],@acc[3],@r5[2],@tmp[0]); +- vmalof (@tmp[1],@acc[3],@r5[3],@tmp[1]); +- vmalof (@tmp[2],@acc[3],@r5[4],@tmp[2]); +- vmalof (@tmp[3],@acc[3],@r[0],@tmp[3]); +- vmalof (@tmp[4],@acc[3],@r[1],@tmp[4]); +- +- vmalof (@tmp[0],@acc[2],@r5[3],@tmp[0]); +- vmalof (@tmp[1],@acc[2],@r5[4],@tmp[1]); +- vmalof (@tmp[2],@acc[2],@r[0],@tmp[2]); +- vmalof (@tmp[3],@acc[2],@r[1],@tmp[3]); +- vmalof (@tmp[4],@acc[2],@r[2],@tmp[4]); +- +- vmalof (@tmp[0],@acc[1],@r5[4],@tmp[0]); +- vmalof (@tmp[1],@acc[1],@r[0],@tmp[1]); +- vmalof (@tmp[2],@acc[1],@r[1],@tmp[2]); +- vmalof (@tmp[3],@acc[1],@r[2],@tmp[3]); +- vmalof (@tmp[4],@acc[1],@r[3],@tmp[4]); +- +- vmalof (@acc[1],@acc[0],@r[1],@tmp[1]); +- vmalof (@acc[2],@acc[0],@r[2],@tmp[2]); +- vmalof (@acc[3],@acc[0],@r[3],@tmp[3]); +- vmalof (@acc[4],@acc[0],@r[4],@tmp[4]); +- vmalof (@acc[0],@acc[0],@r[0],@tmp[0]); +- +- REDUCE (); +- +- la ($inp,"32($inp)"); +- +-ALIGN (16); +-LABEL (".Lvx_2x_done"); +- tml ($len,16); +- jz (".Lvx_done"); +- +- vleig ($padvec,0,0); +- +- vzero ("%v20"); +- vl ("%v21","0($inp)"); # load m0 +- +- # m0 -> base 2^26 +- +- vperm (@m01[0],"%v20","%v21",@vperm[0]); +- vperm (@m01[2],"%v20","%v21",@vperm[1]); +- vperm (@m01[4],"%v20","%v21",@vperm[2]); +- +- vesrlg (@m01[1],@m01[0],26); +- vesrlg (@m01[3],@m01[2],30); +- vesrlg (@m01[2],@m01[2],4); +- +- vn (@m01[4],@m01[4],$mask4); +- vn (@m01[$_],@m01[$_],$mask) for (0..3); +- +- vaf (@m01[4],@m01[4],$padvec); # pad m0 +- +- # acc = acc * r + m01 +- +- vlrepf (@r5[$_],"4*$_+68($ctx)") for (0..4); # load 5*r +- vlrepf (@r[$_],"4*$_+48($ctx)") for (0..4); # load r +- +- vmalof (@tmp[0],@acc[4],@r5[1],@m01[0]); +- vmalof (@tmp[1],@acc[4],@r5[2],@m01[1]); +- vmalof (@tmp[2],@acc[4],@r5[3],@m01[2]); +- vmalof (@tmp[3],@acc[4],@r5[4],@m01[3]); +- vmalof (@tmp[4],@acc[4],@r[0],@m01[4]); +- +- vmalof (@tmp[0],@acc[3],@r5[2],@tmp[0]); +- vmalof (@tmp[1],@acc[3],@r5[3],@tmp[1]); +- vmalof (@tmp[2],@acc[3],@r5[4],@tmp[2]); +- vmalof (@tmp[3],@acc[3],@r[0],@tmp[3]); +- vmalof (@tmp[4],@acc[3],@r[1],@tmp[4]); +- +- vmalof (@tmp[0],@acc[2],@r5[3],@tmp[0]); +- vmalof (@tmp[1],@acc[2],@r5[4],@tmp[1]); +- vmalof (@tmp[2],@acc[2],@r[0],@tmp[2]); +- vmalof (@tmp[3],@acc[2],@r[1],@tmp[3]); +- vmalof (@tmp[4],@acc[2],@r[2],@tmp[4]); +- +- vmalof (@tmp[0],@acc[1],@r5[4],@tmp[0]); +- vmalof (@tmp[1],@acc[1],@r[0],@tmp[1]); +- vmalof (@tmp[2],@acc[1],@r[1],@tmp[2]); +- vmalof (@tmp[3],@acc[1],@r[2],@tmp[3]); +- vmalof (@tmp[4],@acc[1],@r[3],@tmp[4]); +- +- vmalof (@acc[1],@acc[0],@r[1],@tmp[1]); +- vmalof (@acc[2],@acc[0],@r[2],@tmp[2]); +- vmalof (@acc[3],@acc[0],@r[3],@tmp[3]); +- vmalof (@acc[4],@acc[0],@r[4],@tmp[4]); +- vmalof (@acc[0],@acc[0],@r[0],@tmp[0]); +- +- REDUCE (); +- +-ALIGN (16); +-LABEL (".Lvx_done"); +- vstef (@acc[$_],"4*$_($ctx)",1) for (0..4); # store acc +- vstef (@acc[$_],"24+4*$_($ctx)",3) for (0..4); +- +-if ($z) { +- vlm ("%v8","%v15","0($sp)"); +- la ($sp,"$frame($sp)"); +-} else { +- ld ("%f4","16*$SIZE_T+2*8($sp)"); +- ld ("%f6","16*$SIZE_T+3*8($sp)"); +-} +- br ("%r14"); +-SIZE ("poly1305_blocks_vx",".-poly1305_blocks_vx"); +-} +- +-################ +-# static void poly1305_emit_vx(void *ctx, unsigned char mac[16], +-# const u32 nonce[4]) +-{ +-my ($ctx,$mac,$nonce) = map("%r$_",(2..4)); +- +-GLOBL ("poly1305_emit_vx"); +-TYPE ("poly1305_emit_vx","\@function"); +-ALIGN (16); +-LABEL ("poly1305_emit_vx"); +-if ($z) { +- aghi ($sp,-$frame); +- vstm ("%v8","%v15","0($sp)"); +-} else { +- std ("%f4","16*$SIZE_T+2*8($sp)"); +- std ("%f6","16*$SIZE_T+3*8($sp)"); +-} +- larl ("%r5",".Lconst"); +- +- vlef (@acc[$_],"4*$_($ctx)",1) for (0..4); # load acc1 +- vlef (@acc[$_],"24+4*$_($ctx)",3) for (0..4); # load acc2 +- vlef (@r5[$_],"108+4*$_($ctx)",1) for (0..4); # load 5*r^2 +- vlef (@r[$_],"88+4*$_($ctx)",1) for (0..4); # load r^2 +- vlef (@r5[$_],"68+4*$_($ctx)",3) for (0..4); # load 5*r +- vlef (@r[$_],"48+4*$_($ctx)",3) for (0..4); # load r +- vl ($mask,"48(%r5)"); # load mask +- +- # acc = acc1 * r^2 + acc2 * r +- +- vmlof (@tmp[0],@acc[4],@r5[1]); +- vmlof (@tmp[1],@acc[4],@r5[2]); +- vmlof (@tmp[2],@acc[4],@r5[3]); +- vmlof (@tmp[3],@acc[4],@r5[4]); +- vmlof (@tmp[4],@acc[4],@r[0]); +- +- vmalof (@tmp[0],@acc[3],@r5[2],@tmp[0]); +- vmalof (@tmp[1],@acc[3],@r5[3],@tmp[1]); +- vmalof (@tmp[2],@acc[3],@r5[4],@tmp[2]); +- vmalof (@tmp[3],@acc[3],@r[0],@tmp[3]); +- vmalof (@tmp[4],@acc[3],@r[1],@tmp[4]); +- +- vmalof (@tmp[0],@acc[2],@r5[3],@tmp[0]); +- vmalof (@tmp[1],@acc[2],@r5[4],@tmp[1]); +- vmalof (@tmp[2],@acc[2],@r[0],@tmp[2]); +- vmalof (@tmp[3],@acc[2],@r[1],@tmp[3]); +- vmalof (@tmp[4],@acc[2],@r[2],@tmp[4]); +- +- vmalof (@tmp[0],@acc[1],@r5[4],@tmp[0]); +- vmalof (@tmp[1],@acc[1],@r[0],@tmp[1]); +- vmalof (@tmp[2],@acc[1],@r[1],@tmp[2]); +- vmalof (@tmp[3],@acc[1],@r[2],@tmp[3]); +- vmalof (@tmp[4],@acc[1],@r[3],@tmp[4]); +- +- vmalof (@acc[1],@acc[0],@r[1],@tmp[1]); +- vmalof (@acc[2],@acc[0],@r[2],@tmp[2]); +- vmalof (@acc[3],@acc[0],@r[3],@tmp[3]); +- vmalof (@acc[4],@acc[0],@r[4],@tmp[4]); +- vmalof (@acc[0],@acc[0],@r[0],@tmp[0]); +- +- vzero ("%v27"); +- vsumqg (@acc[$_],@acc[$_],"%v27") for (0..4); +- +- REDUCE (); +- +- vesrlg (@tmp[1],@acc[1],26); +- vn (@acc[1],@acc[1],$mask); +- vag (@acc[2],@acc[2],@tmp[1]); # carry 1->2 +- +- vesrlg (@tmp[2],@acc[2],26); +- vn (@acc[2],@acc[2],$mask); +- vag (@acc[3],@acc[3],@tmp[2]); # carry 2->3 +- +- vesrlg (@tmp[3],@acc[3],26); +- vn (@acc[3],@acc[3],$mask); +- vag (@acc[4],@acc[4],@tmp[3]); # carry 3->4 +- +- # acc -> base 2^64 +- vleib ("%v30",6*8,7); +- vleib ("%v29",13*8,7); +- vleib ("%v28",3*8,7); +- +- veslg (@acc[1],@acc[1],26); +- veslg (@acc[3],@acc[3],26); +- vo (@acc[0],@acc[0],@acc[1]); +- vo (@acc[2],@acc[2],@acc[3]); +- +- veslg (@acc[2],@acc[2],4); +- vslb (@acc[2],@acc[2],"%v30"); # <<52 +- vo (@acc[0],@acc[0],@acc[2]); +- +- vslb (@tmp[4],@acc[4],"%v29"); # <<104 +- vo (@acc[0],@acc[0],@tmp[4]); +- +- vsrlb (@acc[1],@acc[4],"%v28"); # >>24 +- +- # acc %= 2^130-5 +- vone ("%v26"); +- vleig ("%v27",5,1); +- vone ("%v29"); +- vleig ("%v26",-4,1); +- +- vaq (@tmp[0],@acc[0],"%v27"); +- vaccq (@tmp[1],@acc[0],"%v27"); +- +- vaq (@tmp[1],@tmp[1],"%v26"); +- vaccq (@tmp[1],@tmp[1],@acc[1]); +- +- vaq (@tmp[1],@tmp[1],"%v29"); +- +- vn (@tmp[2],@tmp[1],@acc[0]); +- vnc (@tmp[3],@tmp[0],@tmp[1]); +- vo (@acc[0],@tmp[2],@tmp[3]); +- +- # acc += nonce +- vl (@vperm[0],"64(%r5)"); +- vlef (@tmp[0],"4*$_($nonce)",3-$_) for (0..3); +- +- vaq (@acc[0],@acc[0],@tmp[0]); +- +- vperm (@acc[0],@acc[0],@acc[0],@vperm[0]); +- vst (@acc[0],"0($mac)"); # store mac +- +-if ($z) { +- vlm ("%v8","%v15","0($sp)"); +- la ($sp,"$frame($sp)"); +-} else { +- ld ("%f4","16*$SIZE_T+2*8($sp)"); +- ld ("%f6","16*$SIZE_T+3*8($sp)"); +-} +- br ("%r14"); +-SIZE ("poly1305_emit_vx",".-poly1305_emit_vx"); +-} +-} +- +-# NOVX CODE PATH +-{ +-################ +-# static void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, +-# u32 padbit) +-{ +-my ($ctx,$inp,$len,$padbit) = map("%r$_",(2..5)); +- + my ($d0hi,$d0lo,$d1hi,$d1lo,$t0,$h0,$t1,$h1,$h2) = map("%r$_",(6..14)); + my ($r0,$r1,$s1) = map("%r$_",(0..2)); ++ + GLOBL ("poly1305_blocks"); + TYPE ("poly1305_blocks","\@function"); + ALIGN (16); + LABEL ("poly1305_blocks"); +-$z? srlg ($len,$len,4) :srl ($len,4); +- lghi ("%r0",0); +-&{$z? \&clgr:\&clr} ($len,"%r0"); +- je (".Lno_data"); ++LABEL (".Lpoly1305_blocks"); ++&{$z? \<gr:\<r} ("%r0",$len); ++ jz (".Lno_data"); + + &{$z? \&stmg:\&stm} ("%r6","%r14","6*$SIZE_T($sp)"); + +- llgfr ($padbit,$padbit); # clear upper half, much needed with +- # non-64-bit ABI +- lg ($r0,"32($ctx)"); # load key +- lg ($r1,"40($ctx)"); +- +- lg ($h0,"0($ctx)"); # load hash value ++ lg ($h0,"0($ctx)"); # load hash value + lg ($h1,"8($ctx)"); + lg ($h2,"16($ctx)"); + ++LABEL (".Lpoly1305_blocks_entry"); ++if ($z) { ++ srlg ($len,$len,4); ++} else { ++ srl ($len,4); ++} ++ llgfr ($padbit,$padbit); # clear upper half, much needed with ++ # non-64-bit ABI ++ lg ($r0,"32($ctx)"); # load key ++ lg ($r1,"40($ctx)"); ++ + &{$z? \&stg:\&st} ($ctx,"2*$SIZE_T($sp)"); # off-load $ctx + srlg ($s1,$r1,2); + algr ($s1,$r1); # s1 = r1 + r1>>2 +@@ -718,21 +160,21 @@ $z? srlg ($len,$len,4) :srl ($len,4); + + ALIGN (16); + LABEL (".Loop"); +- lrvg ($d0lo,"0($inp)"); # load little-endian input ++ lrvg ($d0lo,"0($inp)"); # load little-endian input + lrvg ($d1lo,"8($inp)"); + la ($inp,"16($inp)"); + +- algr ($d0lo,$h0); # accumulate input ++ algr ($d0lo,$h0); # accumulate input + alcgr ($d1lo,$h1); ++ alcgr ($h2,$padbit); + + lgr ($h0,$d0lo); +- mlgr ($d0hi,$r0); # h0*r0 -> $d0hi:$d0lo ++ mlgr ($d0hi,$r0); # h0*r0 -> $d0hi:$d0lo + lgr ($h1,$d1lo); +- mlgr ($d1hi,$s1); # h1*5*r1 -> $d1hi:$d1lo ++ mlgr ($d1hi,$s1); # h1*5*r1 -> $d1hi:$d1lo + +- mlgr ($t0,$r1); # h0*r1 -> $t0:$h0 +- mlgr ($t1,$r0); # h1*r0 -> $t1:$h1 +- alcgr ($h2,$padbit); ++ mlgr ($t0,$r1); # h0*r1 -> $t0:$h0 ++ mlgr ($t1,$r0); # h1*r0 -> $t1:$h1 + + algr ($d0lo,$d1lo); + lgr ($d1lo,$h2); +@@ -742,16 +184,16 @@ LABEL (".Loop"); + algr ($h1,$h0); + alcgr ($t1,$t0); + +- msgr ($d1lo,$s1); # h2*s1 +- msgr ($h2,$r0); # h2*r0 ++ msgr ($d1lo,$s1); # h2*s1 ++ msgr ($h2,$r0); # h2*r0 + + algr ($h1,$d1lo); +- alcgr ($t1,$d1hi); # $d1hi is zero ++ alcgr ($t1,$d1hi); # $d1hi is zero + + algr ($h1,$d0hi); + alcgr ($h2,$t1); + +- lghi ($h0,-4); # final reduction step ++ lghi ($h0,-4); # final reduction step + ngr ($h0,$h2); + srlg ($t0,$h2,2); + algr ($h0,$t0); +@@ -759,14 +201,14 @@ LABEL (".Loop"); + ngr ($h2,$t1); + + algr ($h0,$d0lo); +- alcgr ($h1,$d1hi); # $d1hi is still zero +- alcgr ($h2,$d1hi); # $d1hi is still zero ++ alcgr ($h1,$d1hi); # $d1hi is still zero ++ alcgr ($h2,$d1hi); # $d1hi is still zero + + &{$z? \&brctg:\&brct} ($len,".Loop"); + + &{$z? \&lg:\&l} ($ctx,"2*$SIZE_T($sp)");# restore $ctx + +- stg ($h0,"0($ctx)"); # store hash value ++ stg ($h0,"0($ctx)"); # store hash value + stg ($h1,"8($ctx)"); + stg ($h2,"16($ctx)"); + +@@ -777,67 +219,766 @@ SIZE ("poly1305_blocks",".-poly1305_bloc + } + + ################ ++# static void poly1305_blocks_vx(void *ctx, const unsigned char *inp, ++# size_t len, u32 padbit) ++{ ++my ($H0, $H1, $H2, $H3, $H4) = map("%v$_",(0..4)); ++my ($I0, $I1, $I2, $I3, $I4) = map("%v$_",(5..9)); ++my ($R0, $R1, $S1, $R2, $S2) = map("%v$_",(10..14)); ++my ($R3, $S3, $R4, $S4) = map("%v$_",(15..18)); ++my ($ACC0, $ACC1, $ACC2, $ACC3, $ACC4) = map("%v$_",(19..23)); ++my ($T1, $T2, $T3, $T4) = map("%v$_",(24..27)); ++my ($mask26,$bswaplo,$bswaphi,$bswapmi) = map("%v$_",(28..31)); ++ ++my ($d2,$d0,$h0,$d1,$h1,$h2)=map("%r$_",(9..14)); ++ ++TYPE ("poly1305_blocks_vx","\@function"); ++ALIGN (16); ++LABEL ("poly1305_blocks_vx"); ++LABEL (".Lpoly1305_blocks_vx"); ++&{$z? \&clgfi:\&clfi} ($len,128); ++ jhe ("__poly1305_blocks_vx"); ++ ++&{$z? \&stmg:\&stm} ("%r6","%r14","6*$SIZE_T($sp)"); ++ ++ lg ($d0,"0($ctx)"); ++ lg ($d1,"8($ctx)"); ++ lg ($d2,"16($ctx)"); ++ ++ llgfr ("%r0",$d0); # base 2^26 -> base 2^64 ++ srlg ($h0,$d0,32); ++ llgfr ("%r1",$d1); ++ srlg ($h1,$d1,32); ++ srlg ($h2,$d2,32); ++ ++ sllg ("%r0","%r0",26); ++ algr ($h0,"%r0"); ++ sllg ("%r0",$h1,52); ++ srlg ($h1,$h1,12); ++ sllg ("%r1","%r1",14); ++ algr ($h0,"%r0"); ++ alcgr ($h1,"%r1"); ++ sllg ("%r0",$h2,40); ++ srlg ($h2,$h2,24); ++ lghi ("%r1",0); ++ algr ($h1,"%r0"); ++ alcgr ($h2,"%r1"); ++ ++ llgf ("%r0","24($ctx)"); # is_base2_26 ++ lcgr ("%r0","%r0"); ++ ++ xgr ($h0,$d0); # choose between radixes ++ xgr ($h1,$d1); ++ xgr ($h2,$d2); ++ ngr ($h0,"%r0"); ++ ngr ($h1,"%r0"); ++ ngr ($h2,"%r0"); ++ xgr ($h0,$d0); ++ xgr ($h1,$d1); ++ xgr ($h2,$d2); ++ ++ lhi ("%r0",0); ++ st ("%r0","24($ctx)"); # clear is_base2_26 ++ ++ j (".Lpoly1305_blocks_entry"); ++SIZE ("poly1305_blocks_vx",".-poly1305_blocks_vx"); ++ ++TYPE ("__poly1305_mul","\@function"); ++ALIGN (16); ++LABEL ("__poly1305_mul"); ++ vmlof ($ACC0,$H0,$R0); ++ vmlof ($ACC1,$H0,$R1); ++ vmlof ($ACC2,$H0,$R2); ++ vmlof ($ACC3,$H0,$R3); ++ vmlof ($ACC4,$H0,$R4); ++ ++ vmalof ($ACC0,$H1,$S4,$ACC0); ++ vmalof ($ACC1,$H1,$R0,$ACC1); ++ vmalof ($ACC2,$H1,$R1,$ACC2); ++ vmalof ($ACC3,$H1,$R2,$ACC3); ++ vmalof ($ACC4,$H1,$R3,$ACC4); ++ ++ vmalof ($ACC0,$H2,$S3,$ACC0); ++ vmalof ($ACC1,$H2,$S4,$ACC1); ++ vmalof ($ACC2,$H2,$R0,$ACC2); ++ vmalof ($ACC3,$H2,$R1,$ACC3); ++ vmalof ($ACC4,$H2,$R2,$ACC4); ++ ++ vmalof ($ACC0,$H3,$S2,$ACC0); ++ vmalof ($ACC1,$H3,$S3,$ACC1); ++ vmalof ($ACC2,$H3,$S4,$ACC2); ++ vmalof ($ACC3,$H3,$R0,$ACC3); ++ vmalof ($ACC4,$H3,$R1,$ACC4); ++ ++ vmalof ($ACC0,$H4,$S1,$ACC0); ++ vmalof ($ACC1,$H4,$S2,$ACC1); ++ vmalof ($ACC2,$H4,$S3,$ACC2); ++ vmalof ($ACC3,$H4,$S4,$ACC3); ++ vmalof ($ACC4,$H4,$R0,$ACC4); ++ ++ ################################################################ ++ # lazy reduction ++ ++ vesrlg ($H4,$ACC3,26); ++ vesrlg ($H1,$ACC0,26); ++ vn ($H3,$ACC3,$mask26); ++ vn ($H0,$ACC0,$mask26); ++ vag ($H4,$H4,$ACC4); # h3 -> h4 ++ vag ($H1,$H1,$ACC1); # h0 -> h1 ++ ++ vesrlg ($ACC4,$H4,26); ++ vesrlg ($ACC1,$H1,26); ++ vn ($H4,$H4,$mask26); ++ vn ($H1,$H1,$mask26); ++ vag ($H0,$H0,$ACC4); ++ vag ($H2,$ACC2,$ACC1); # h1 -> h2 ++ ++ veslg ($ACC4,$ACC4,2); # <<2 ++ vesrlg ($ACC2,$H2,26); ++ vn ($H2,$H2,$mask26); ++ vag ($H0,$H0,$ACC4); # h4 -> h0 ++ vag ($H3,$H3,$ACC2); # h2 -> h3 ++ ++ vesrlg ($ACC0,$H0,26); ++ vesrlg ($ACC3,$H3,26); ++ vn ($H0,$H0,$mask26); ++ vn ($H3,$H3,$mask26); ++ vag ($H1,$H1,$ACC0); # h0 -> h1 ++ vag ($H4,$H4,$ACC3); # h3 -> h4 ++ br ("%r14"); ++SIZE ("__poly1305_mul",".-__poly1305_mul"); ++ ++TYPE ("__poly1305_blocks_vx","\@function"); ++ALIGN (16); ++LABEL ("__poly1305_blocks_vx"); ++&{$z? \&lgr:\&lr} ("%r0",$sp); ++&{$z? \&stmg:\&stm} ("%r10","%r15","10*$SIZE_T($sp)"); ++if (!$z) { ++ std ("%f4","16*$SIZE_T+2*8($sp)"); ++ std ("%f6","16*$SIZE_T+3*8($sp)"); ++ ahi ($sp,-$stdframe); ++ st ("%r0","0($sp)"); # back-chain ++ ++ llgfr ($len,$len); # so that srlg works on $len ++} else { ++ aghi ($sp,"-($stdframe+8*8)"); ++ stg ("%r0","0($sp)"); # back-chain ++ ++ std ("%f8","$stdframe+0*8($sp)"); ++ std ("%f9","$stdframe+1*8($sp)"); ++ std ("%f10","$stdframe+2*8($sp)"); ++ std ("%f11","$stdframe+3*8($sp)"); ++ std ("%f12","$stdframe+4*8($sp)"); ++ std ("%f13","$stdframe+5*8($sp)"); ++ std ("%f14","$stdframe+6*8($sp)"); ++ std ("%f15","$stdframe+7*8($sp)"); ++} ++ larl ("%r1",".Lconst"); ++ vgmg ($mask26,38,63); ++ vlm ($bswaplo,$bswapmi,"16(%r1)"); ++ ++ < ("%r0","24($ctx)"); # is_base2_26? ++ jnz (".Lskip_init"); ++ ++ lg ($h0,"32($ctx)"); # load key base 2^64 ++ lg ($h1,"40($ctx)"); ++ ++ risbg ($d0,$h0,38,0x80+63,38); # base 2^64 -> 2^26 ++ srlg ($d1,$h0,52); ++ risbg ($h0,$h0,38,0x80+63,0); ++ vlvgg ($R0,$h0,0); ++ risbg ($d1,$h1,38,51,12); ++ vlvgg ($R1,$d0,0); ++ risbg ($d0,$h1,38,63,50); ++ vlvgg ($R2,$d1,0); ++ srlg ($d1,$h1,40); ++ vlvgg ($R3,$d0,0); ++ vlvgg ($R4,$d1,0); ++ ++ veslg ($S1,$R1,2); ++ veslg ($S2,$R2,2); ++ veslg ($S3,$R3,2); ++ veslg ($S4,$R4,2); ++ vlr ($H0,$R0); ++ vlr ($H1,$R1); ++ vlr ($H2,$R2); ++ vlr ($H3,$R3); ++ vlr ($H4,$R4); ++ vag ($S1,$S1,$R1); # * 5 ++ vag ($S2,$S2,$R2); ++ vag ($S3,$S3,$R3); ++ vag ($S4,$S4,$R4); ++ ++ brasl ("%r14","__poly1305_mul"); # r^1:- * r^1:- ++ ++ vpdi ($R0,$H0,$R0,0); # r^2:r^1 ++ vpdi ($R1,$H1,$R1,0); ++ vpdi ($R2,$H2,$R2,0); ++ vpdi ($R3,$H3,$R3,0); ++ vpdi ($R4,$H4,$R4,0); ++ vpdi ($H0,$H0,$H0,0); # r^2:r^2 ++ vpdi ($H1,$H1,$H1,0); ++ vpdi ($H2,$H2,$H2,0); ++ vpdi ($H3,$H3,$H3,0); ++ vpdi ($H4,$H4,$H4,0); ++ veslg ($S1,$R1,2); ++ veslg ($S2,$R2,2); ++ veslg ($S3,$R3,2); ++ veslg ($S4,$R4,2); ++ vag ($S1,$S1,$R1); # * 5 ++ vag ($S2,$S2,$R2); ++ vag ($S3,$S3,$R3); ++ vag ($S4,$S4,$R4); ++ ++ brasl ("%r14,__poly1305_mul"); # r^2:r^2 * r^2:r^1 ++ ++ vl ($I0,"0(%r1)"); # borrow $I0 ++ vperm ($R0,$R0,$H0,$I0); # r^2:r^4:r^1:r^3 ++ vperm ($R1,$R1,$H1,$I0); ++ vperm ($R2,$R2,$H2,$I0); ++ vperm ($R3,$R3,$H3,$I0); ++ vperm ($R4,$R4,$H4,$I0); ++ veslf ($S1,$R1,2); ++ veslf ($S2,$R2,2); ++ veslf ($S3,$R3,2); ++ veslf ($S4,$R4,2); ++ vaf ($S1,$S1,$R1); # * 5 ++ vaf ($S2,$S2,$R2); ++ vaf ($S3,$S3,$R3); ++ vaf ($S4,$S4,$R4); ++ ++ lg ($h0,"0($ctx)"); # load hash base 2^64 ++ lg ($h1,"8($ctx)"); ++ lg ($h2,"16($ctx)"); ++ ++ vzero ($H0); ++ vzero ($H1); ++ vzero ($H2); ++ vzero ($H3); ++ vzero ($H4); ++ ++ risbg ($d0,$h0,38,0x80+63,38); # base 2^64 -> 2^26 ++ srlg ($d1,$h0,52); ++ risbg ($h0,$h0,38,0x80+63,0); ++ vlvgg ($H0,$h0,0); ++ risbg ($d1,$h1,38,51,12); ++ vlvgg ($H1,$d0,0); ++ risbg ($d0,$h1,38,63,50); ++ vlvgg ($H2,$d1,0); ++ srlg ($d1,$h1,40); ++ vlvgg ($H3,$d0,0); ++ risbg ($d1,$h2,37,39,24); ++ vlvgg ($H4,$d1,0); ++ ++ lhi ("%r0",1); ++ st ("%r0","24($ctx)"); # set is_base2_26 ++ ++ vstm ($R0,$S4,"48($ctx)"); # save key schedule base 2^26 ++ ++ vpdi ($R0,$R0,$R0,0); # broadcast r^2:r^4 ++ vpdi ($R1,$R1,$R1,0); ++ vpdi ($S1,$S1,$S1,0); ++ vpdi ($R2,$R2,$R2,0); ++ vpdi ($S2,$S2,$S2,0); ++ vpdi ($R3,$R3,$R3,0); ++ vpdi ($S3,$S3,$S3,0); ++ vpdi ($R4,$R4,$R4,0); ++ vpdi ($S4,$S4,$S4,0); ++ ++ j (".Loaded_hash"); ++ ++ALIGN (16); ++LABEL (".Lskip_init"); ++ vllezf ($H0,"0($ctx)"); # load hash base 2^26 ++ vllezf ($H1,"4($ctx)"); ++ vllezf ($H2,"8($ctx)"); ++ vllezf ($H3,"12($ctx)"); ++ vllezf ($H4,"16($ctx)"); ++ ++ vlrepg ($R0,"0x30($ctx)"); # broadcast r^2:r^4 ++ vlrepg ($R1,"0x40($ctx)"); ++ vlrepg ($S1,"0x50($ctx)"); ++ vlrepg ($R2,"0x60($ctx)"); ++ vlrepg ($S2,"0x70($ctx)"); ++ vlrepg ($R3,"0x80($ctx)"); ++ vlrepg ($S3,"0x90($ctx)"); ++ vlrepg ($R4,"0xa0($ctx)"); ++ vlrepg ($S4,"0xb0($ctx)"); ++ ++LABEL (".Loaded_hash"); ++ vzero ($I1); ++ vzero ($I3); ++ ++ vlm ($T1,$T4,"0x00($inp)"); # load first input block ++ la ($inp,"0x40($inp)"); ++ vgmg ($mask26,6,31); ++ vgmf ($I4,5,5); # padbit<<2 ++ ++ vperm ($I0,$T3,$T4,$bswaplo); ++ vperm ($I2,$T3,$T4,$bswapmi); ++ vperm ($T3,$T3,$T4,$bswaphi); ++ ++ verimg ($I1,$I0,$mask26,6); # >>26 ++ veslg ($I0,$I0,32); ++ veslg ($I2,$I2,28); # >>4 ++ verimg ($I3,$T3,$mask26,18); # >>14 ++ verimg ($I4,$T3,$mask26,58); # >>38 ++ vn ($I0,$I0,$mask26); ++ vn ($I2,$I2,$mask26); ++ vesrlf ($I4,$I4,2); # >>2 ++ ++ vgmg ($mask26,38,63); ++ vperm ($T3,$T1,$T2,$bswaplo); ++ vperm ($T4,$T1,$T2,$bswaphi); ++ vperm ($T2,$T1,$T2,$bswapmi); ++ ++ verimg ($I0,$T3,$mask26,0); ++ verimg ($I1,$T3,$mask26,38); # >>26 ++ verimg ($I2,$T2,$mask26,60); # >>4 ++ verimg ($I3,$T4,$mask26,50); # >>14 ++ vesrlg ($T4,$T4,40); ++ vo ($I4,$I4,$T4); ++ ++ srlg ("%r0",$len,6); ++&{$z? \&aghi:\&ahi} ("%r0",-1); ++ ++ALIGN (16); ++LABEL (".Loop_vx"); ++ vmlef ($ACC0,$I0,$R0); ++ vmlef ($ACC1,$I0,$R1); ++ vmlef ($ACC2,$I0,$R2); ++ vmlef ($ACC3,$I0,$R3); ++ vmlef ($ACC4,$I0,$R4); ++ ++ vmalef ($ACC0,$I1,$S4,$ACC0); ++ vmalef ($ACC1,$I1,$R0,$ACC1); ++ vmalef ($ACC2,$I1,$R1,$ACC2); ++ vmalef ($ACC3,$I1,$R2,$ACC3); ++ vmalef ($ACC4,$I1,$R3,$ACC4); ++ ++ vaf ($H2,$H2,$I2); ++ vaf ($H0,$H0,$I0); ++ vaf ($H3,$H3,$I3); ++ vaf ($H1,$H1,$I1); ++ vaf ($H4,$H4,$I4); ++ ++ vmalef ($ACC0,$I2,$S3,$ACC0); ++ vmalef ($ACC1,$I2,$S4,$ACC1); ++ vmalef ($ACC2,$I2,$R0,$ACC2); ++ vmalef ($ACC3,$I2,$R1,$ACC3); ++ vmalef ($ACC4,$I2,$R2,$ACC4); ++ ++ vlm ($T1,$T4,"0x00($inp)"); # load next input block ++ la ($inp,"0x40($inp)"); ++ vgmg ($mask26,6,31); ++ ++ vmalef ($ACC0,$I3,$S2,$ACC0); ++ vmalef ($ACC1,$I3,$S3,$ACC1); ++ vmalef ($ACC2,$I3,$S4,$ACC2); ++ vmalef ($ACC3,$I3,$R0,$ACC3); ++ vmalef ($ACC4,$I3,$R1,$ACC4); ++ ++ vperm ($I0,$T3,$T4,$bswaplo); ++ vperm ($I2,$T3,$T4,$bswapmi); ++ vperm ($T3,$T3,$T4,$bswaphi); ++ ++ vmalef ($ACC0,$I4,$S1,$ACC0); ++ vmalef ($ACC1,$I4,$S2,$ACC1); ++ vmalef ($ACC2,$I4,$S3,$ACC2); ++ vmalef ($ACC3,$I4,$S4,$ACC3); ++ vmalef ($ACC4,$I4,$R0,$ACC4); ++ ++ verimg ($I1,$I0,$mask26,6); # >>26 ++ veslg ($I0,$I0,32); ++ veslg ($I2,$I2,28); # >>4 ++ verimg ($I3,$T3,$mask26,18); # >>14 ++ ++ vmalof ($ACC0,$H0,$R0,$ACC0); ++ vmalof ($ACC1,$H0,$R1,$ACC1); ++ vmalof ($ACC2,$H0,$R2,$ACC2); ++ vmalof ($ACC3,$H0,$R3,$ACC3); ++ vmalof ($ACC4,$H0,$R4,$ACC4); ++ ++ vgmf ($I4,5,5); # padbit<<2 ++ verimg ($I4,$T3,$mask26,58); # >>38 ++ vn ($I0,$I0,$mask26); ++ vn ($I2,$I2,$mask26); ++ vesrlf ($I4,$I4,2); # >>2 ++ ++ vmalof ($ACC0,$H1,$S4,$ACC0); ++ vmalof ($ACC1,$H1,$R0,$ACC1); ++ vmalof ($ACC2,$H1,$R1,$ACC2); ++ vmalof ($ACC3,$H1,$R2,$ACC3); ++ vmalof ($ACC4,$H1,$R3,$ACC4); ++ ++ vgmg ($mask26,38,63); ++ vperm ($T3,$T1,$T2,$bswaplo); ++ vperm ($T4,$T1,$T2,$bswaphi); ++ vperm ($T2,$T1,$T2,$bswapmi); ++ ++ vmalof ($ACC0,$H2,$S3,$ACC0); ++ vmalof ($ACC1,$H2,$S4,$ACC1); ++ vmalof ($ACC2,$H2,$R0,$ACC2); ++ vmalof ($ACC3,$H2,$R1,$ACC3); ++ vmalof ($ACC4,$H2,$R2,$ACC4); ++ ++ verimg ($I0,$T3,$mask26,0); ++ verimg ($I1,$T3,$mask26,38); # >>26 ++ verimg ($I2,$T2,$mask26,60); # >>4 ++ ++ vmalof ($ACC0,$H3,$S2,$ACC0); ++ vmalof ($ACC1,$H3,$S3,$ACC1); ++ vmalof ($ACC2,$H3,$S4,$ACC2); ++ vmalof ($ACC3,$H3,$R0,$ACC3); ++ vmalof ($ACC4,$H3,$R1,$ACC4); ++ ++ verimg ($I3,$T4,$mask26,50); # >>14 ++ vesrlg ($T4,$T4,40); ++ vo ($I4,$I4,$T4); ++ ++ vmalof ($ACC0,$H4,$S1,$ACC0); ++ vmalof ($ACC1,$H4,$S2,$ACC1); ++ vmalof ($ACC2,$H4,$S3,$ACC2); ++ vmalof ($ACC3,$H4,$S4,$ACC3); ++ vmalof ($ACC4,$H4,$R0,$ACC4); ++ ++ ################################################################ ++ # lazy reduction as discussed in "NEON crypto" by D.J. Bernstein ++ # and P. Schwabe ++ ++ vesrlg ($H4,$ACC3,26); ++ vesrlg ($H1,$ACC0,26); ++ vn ($H3,$ACC3,$mask26); ++ vn ($H0,$ACC0,$mask26); ++ vag ($H4,$H4,$ACC4); # h3 -> h4 ++ vag ($H1,$H1,$ACC1); # h0 -> h1 ++ ++ vesrlg ($ACC4,$H4,26); ++ vesrlg ($ACC1,$H1,26); ++ vn ($H4,$H4,$mask26); ++ vn ($H1,$H1,$mask26); ++ vag ($H0,$H0,$ACC4); ++ vag ($H2,$ACC2,$ACC1); # h1 -> h2 ++ ++ veslg ($ACC4,$ACC4,2); # <<2 ++ vesrlg ($ACC2,$H2,26); ++ vn ($H2,$H2,$mask26); ++ vag ($H0,$H0,$ACC4); # h4 -> h0 ++ vag ($H3,$H3,$ACC2); # h2 -> h3 ++ ++ vesrlg ($ACC0,$H0,26); ++ vesrlg ($ACC3,$H3,26); ++ vn ($H0,$H0,$mask26); ++ vn ($H3,$H3,$mask26); ++ vag ($H1,$H1,$ACC0); # h0 -> h1 ++ vag ($H4,$H4,$ACC3); # h3 -> h4 ++ ++&{$z? \&brctg:\&brct} ("%r0",".Loop_vx"); ++ ++ vlm ($R0,$S4,"48($ctx)"); # load all powers ++ ++ lghi ("%r0",0x30); ++&{$z? \&lcgr:\&lcr} ($len,$len); ++&{$z? \&ngr:\&nr} ($len,"%r0"); ++&{$z? \&slgr:\&slr} ($inp,$len); ++ ++LABEL (".Last"); ++ vmlef ($ACC0,$I0,$R0); ++ vmlef ($ACC1,$I0,$R1); ++ vmlef ($ACC2,$I0,$R2); ++ vmlef ($ACC3,$I0,$R3); ++ vmlef ($ACC4,$I0,$R4); ++ ++ vmalef ($ACC0,$I1,$S4,$ACC0); ++ vmalef ($ACC1,$I1,$R0,$ACC1); ++ vmalef ($ACC2,$I1,$R1,$ACC2); ++ vmalef ($ACC3,$I1,$R2,$ACC3); ++ vmalef ($ACC4,$I1,$R3,$ACC4); ++ ++ vaf ($H0,$H0,$I0); ++ vaf ($H1,$H1,$I1); ++ vaf ($H2,$H2,$I2); ++ vaf ($H3,$H3,$I3); ++ vaf ($H4,$H4,$I4); ++ ++ vmalef ($ACC0,$I2,$S3,$ACC0); ++ vmalef ($ACC1,$I2,$S4,$ACC1); ++ vmalef ($ACC2,$I2,$R0,$ACC2); ++ vmalef ($ACC3,$I2,$R1,$ACC3); ++ vmalef ($ACC4,$I2,$R2,$ACC4); ++ ++ vmalef ($ACC0,$I3,$S2,$ACC0); ++ vmalef ($ACC1,$I3,$S3,$ACC1); ++ vmalef ($ACC2,$I3,$S4,$ACC2); ++ vmalef ($ACC3,$I3,$R0,$ACC3); ++ vmalef ($ACC4,$I3,$R1,$ACC4); ++ ++ vmalef ($ACC0,$I4,$S1,$ACC0); ++ vmalef ($ACC1,$I4,$S2,$ACC1); ++ vmalef ($ACC2,$I4,$S3,$ACC2); ++ vmalef ($ACC3,$I4,$S4,$ACC3); ++ vmalef ($ACC4,$I4,$R0,$ACC4); ++ ++ vmalof ($ACC0,$H0,$R0,$ACC0); ++ vmalof ($ACC1,$H0,$R1,$ACC1); ++ vmalof ($ACC2,$H0,$R2,$ACC2); ++ vmalof ($ACC3,$H0,$R3,$ACC3); ++ vmalof ($ACC4,$H0,$R4,$ACC4); ++ ++ vmalof ($ACC0,$H1,$S4,$ACC0); ++ vmalof ($ACC1,$H1,$R0,$ACC1); ++ vmalof ($ACC2,$H1,$R1,$ACC2); ++ vmalof ($ACC3,$H1,$R2,$ACC3); ++ vmalof ($ACC4,$H1,$R3,$ACC4); ++ ++ vmalof ($ACC0,$H2,$S3,$ACC0); ++ vmalof ($ACC1,$H2,$S4,$ACC1); ++ vmalof ($ACC2,$H2,$R0,$ACC2); ++ vmalof ($ACC3,$H2,$R1,$ACC3); ++ vmalof ($ACC4,$H2,$R2,$ACC4); ++ ++ vmalof ($ACC0,$H3,$S2,$ACC0); ++ vmalof ($ACC1,$H3,$S3,$ACC1); ++ vmalof ($ACC2,$H3,$S4,$ACC2); ++ vmalof ($ACC3,$H3,$R0,$ACC3); ++ vmalof ($ACC4,$H3,$R1,$ACC4); ++ ++ vmalof ($ACC0,$H4,$S1,$ACC0); ++ vmalof ($ACC1,$H4,$S2,$ACC1); ++ vmalof ($ACC2,$H4,$S3,$ACC2); ++ vmalof ($ACC3,$H4,$S4,$ACC3); ++ vmalof ($ACC4,$H4,$R0,$ACC4); ++ ++ ################################################################ ++ # horizontal addition ++ ++ vzero ($H0); ++ vsumqg ($ACC0,$ACC0,$H0); ++ vsumqg ($ACC1,$ACC1,$H0); ++ vsumqg ($ACC2,$ACC2,$H0); ++ vsumqg ($ACC3,$ACC3,$H0); ++ vsumqg ($ACC4,$ACC4,$H0); ++ ++ ################################################################ ++ # lazy reduction ++ ++ vesrlg ($H4,$ACC3,26); ++ vesrlg ($H1,$ACC0,26); ++ vn ($H3,$ACC3,$mask26); ++ vn ($H0,$ACC0,$mask26); ++ vag ($H4,$H4,$ACC4); # h3 -> h4 ++ vag ($H1,$H1,$ACC1); # h0 -> h1 ++ ++ vesrlg ($ACC4,$H4,26); ++ vesrlg ($ACC1,$H1,26); ++ vn ($H4,$H4,$mask26); ++ vn ($H1,$H1,$mask26); ++ vag ($H0,$H0,$ACC4); ++ vag ($H2,$ACC2,$ACC1); # h1 -> h2 ++ ++ veslg ($ACC4,$ACC4,2); # <<2 ++ vesrlg ($ACC2,$H2,26); ++ vn ($H2,$H2,$mask26); ++ vag ($H0,$H0,$ACC4); # h4 -> h0 ++ vag ($H3,$H3,$ACC2); # h2 -> h3 ++ ++ vesrlg ($ACC0,$H0,26); ++ vesrlg ($ACC3,$H3,26); ++ vn ($H0,$H0,$mask26); ++ vn ($H3,$H3,$mask26); ++ vag ($H1,$H1,$ACC0); # h0 -> h1 ++ vag ($H4,$H4,$ACC3); # h3 -> h4 ++ ++&{$z? \&clgfi:\&clfi} ($len,0); ++ je (".Ldone"); ++ ++ vlm ($T1,$T4,"0x00($inp)"); # load last partial block ++ vgmg ($mask26,6,31); ++ vgmf ($I4,5,5); # padbit<<2 ++ ++ vperm ($I0,$T3,$T4,$bswaplo); ++ vperm ($I2,$T3,$T4,$bswapmi); ++ vperm ($T3,$T3,$T4,$bswaphi); ++ ++ vl ($ACC0,"0x30($len,%r1)"); # borrow $ACC0,1 ++ vl ($ACC1,"0x60($len,%r1)"); ++ ++ verimg ($I1,$I0,$mask26,6); # >>26 ++ veslg ($I0,$I0,32); ++ veslg ($I2,$I2,28); # >>4 ++ verimg ($I3,$T3,$mask26,18); # >>14 ++ verimg ($I4,$T3,$mask26,58); # >>38 ++ vn ($I0,$I0,$mask26); ++ vn ($I2,$I2,$mask26); ++ vesrlf ($I4,$I4,2); # >>2 ++ ++ vgmg ($mask26,38,63); ++ vperm ($T3,$T1,$T2,$bswaplo); ++ vperm ($T4,$T1,$T2,$bswaphi); ++ vperm ($T2,$T1,$T2,$bswapmi); ++ ++ verimg ($I0,$T3,$mask26,0); ++ verimg ($I1,$T3,$mask26,38); # >>26 ++ verimg ($I2,$T2,$mask26,60); # >>4 ++ verimg ($I3,$T4,$mask26,50); # >>14 ++ vesrlg ($T4,$T4,40); ++ vo ($I4,$I4,$T4); ++ ++ vperm ($H0,$H0,$H0,$ACC0); # move hash to right lane ++ vn ($I0,$I0,$ACC1); # mask redundant lane[s] ++ vperm ($H1,$H1,$H1,$ACC0); ++ vn ($I1,$I1,$ACC1); ++ vperm ($H2,$H2,$H2,$ACC0); ++ vn ($I2,$I2,$ACC1); ++ vperm ($H3,$H3,$H3,$ACC0); ++ vn ($I3,$I3,$ACC1); ++ vperm ($H4,$H4,$H4,$ACC0); ++ vn ($I4,$I4,$ACC1); ++ ++ vaf ($I0,$I0,$H0); # accumulate hash ++ vzero ($H0); # wipe hash value ++ vaf ($I1,$I1,$H1); ++ vzero ($H1); ++ vaf ($I2,$I2,$H2); ++ vzero ($H2); ++ vaf ($I3,$I3,$H3); ++ vzero ($H3); ++ vaf ($I4,$I4,$H4); ++ vzero ($H4); ++ ++&{$z? \&lghi:\&lhi} ($len,0); ++ j (".Last"); ++ # I don't bother to tell apart cases when only one multiplication ++ # pass is sufficient, because I argue that mispredicted branch ++ # penalties are comparable to overhead of sometimes redundant ++ # multiplication pass... ++ ++LABEL (".Ldone"); ++ vstef ($H0,"0($ctx)",3); # store hash base 2^26 ++ vstef ($H1,"4($ctx)",3); ++ vstef ($H2,"8($ctx)",3); ++ vstef ($H3,"12($ctx)",3); ++ vstef ($H4,"16($ctx)",3); ++ ++if ($z) { ++ ld ("%f8","$stdframe+0*8($sp)"); ++ ld ("%f9","$stdframe+1*8($sp)"); ++ ld ("%f10","$stdframe+2*8($sp)"); ++ ld ("%f11","$stdframe+3*8($sp)"); ++ ld ("%f12","$stdframe+4*8($sp)"); ++ ld ("%f13","$stdframe+5*8($sp)"); ++ ld ("%f14","$stdframe+6*8($sp)"); ++ ld ("%f15","$stdframe+7*8($sp)"); ++&{$z? \&lmg:\&lm} ("%r10","%r15","$stdframe+8*8+10*$SIZE_T($sp)"); ++} else { ++ ld ("%f4","$stdframe+16*$SIZE_T+2*8($sp)"); ++ ld ("%f6","$stdframe+16*$SIZE_T+3*8($sp)"); ++&{$z? \&lmg:\&lm} ("%r10","%r15","$stdframe+10*$SIZE_T($sp)"); ++} ++ br ("%r14"); ++SIZE ("__poly1305_blocks_vx",".-__poly1305_blocks_vx"); ++} ++ ++################ + # static void poly1305_emit(void *ctx, unsigned char mac[16], + # const u32 nonce[4]) + { +-my ($ctx,$mac,$nonce) = map("%r$_",(2..4)); +-my ($h0,$h1,$h2,$d0,$d1)=map("%r$_",(5..9)); ++my ($mac,$nonce)=($inp,$len); ++my ($h0,$h1,$h2,$d0,$d1,$d2)=map("%r$_",(5..10)); + + GLOBL ("poly1305_emit"); + TYPE ("poly1305_emit","\@function"); + ALIGN (16); + LABEL ("poly1305_emit"); +-&{$z? \&stmg:\&stm} ("%r6","%r9","6*$SIZE_T($sp)"); ++LABEL (".Lpoly1305_emit"); ++&{$z? \&stmg:\&stm} ("%r6","%r10","6*$SIZE_T($sp)"); + +- lg ($h0,"0($ctx)"); +- lg ($h1,"8($ctx)"); +- lg ($h2,"16($ctx)"); ++ lg ($d0,"0($ctx)"); ++ lg ($d1,"8($ctx)"); ++ lg ($d2,"16($ctx)"); ++ ++ llgfr ("%r0",$d0); # base 2^26 -> base 2^64 ++ srlg ($h0,$d0,32); ++ llgfr ("%r1",$d1); ++ srlg ($h1,$d1,32); ++ srlg ($h2,$d2,32); ++ ++ sllg ("%r0","%r0",26); ++ algr ($h0,"%r0"); ++ sllg ("%r0",$h1,52); ++ srlg ($h1,$h1,12); ++ sllg ("%r1","%r1",14); ++ algr ($h0,"%r0"); ++ alcgr ($h1,"%r1"); ++ sllg ("%r0",$h2,40); ++ srlg ($h2,$h2,24); ++ lghi ("%r1",0); ++ algr ($h1,"%r0"); ++ alcgr ($h2,"%r1"); ++ ++ llgf ("%r0","24($ctx)"); # is_base2_26 ++ lcgr ("%r0","%r0"); ++ ++ xgr ($h0,$d0); # choose between radixes ++ xgr ($h1,$d1); ++ xgr ($h2,$d2); ++ ngr ($h0,"%r0"); ++ ngr ($h1,"%r0"); ++ ngr ($h2,"%r0"); ++ xgr ($h0,$d0); ++ xgr ($h1,$d1); ++ xgr ($h2,$d2); + + lghi ("%r0",5); +- lghi ("%r1",0); + lgr ($d0,$h0); + lgr ($d1,$h1); + +- algr ($h0,"%r0"); # compare to modulus ++ algr ($h0,"%r0"); # compare to modulus + alcgr ($h1,"%r1"); + alcgr ($h2,"%r1"); + +- srlg ($h2,$h2,2); # did it borrow/carry? +- slgr ("%r1",$h2); # 0-$h2>>2 +- lg ($h2,"0($nonce)"); # load nonce +- lghi ("%r0",-1); ++ srlg ($h2,$h2,2); # did it borrow/carry? ++ slgr ("%r1",$h2); # 0-$h2>>2 ++ lg ($d2,"0($nonce)"); # load nonce + lg ($ctx,"8($nonce)"); +- xgr ("%r0","%r1"); # ~%r1 + ++ xgr ($h0,$d0); ++ xgr ($h1,$d1); + ngr ($h0,"%r1"); +- ngr ($d0,"%r0"); + ngr ($h1,"%r1"); +- ngr ($d1,"%r0"); +- ogr ($h0,$d0); +- rllg ($d0,$h2,32); # flip nonce words +- ogr ($h1,$d1); ++ xgr ($h0,$d0); ++ rllg ($d0,$d2,32); # flip nonce words ++ xgr ($h1,$d1); + rllg ($d1,$ctx,32); + +- algr ($h0,$d0); # accumulate nonce ++ algr ($h0,$d0); # accumulate nonce + alcgr ($h1,$d1); + +- strvg ($h0,"0($mac)"); # write little-endian result ++ strvg ($h0,"0($mac)"); # write little-endian result + strvg ($h1,"8($mac)"); + +-&{$z? \&lmg:\&lm} ("%r6","%r9","6*$SIZE_T($sp)"); ++&{$z? \&lmg:\&lm} ("%r6","%r10","6*$SIZE_T($sp)"); + br ("%r14"); + SIZE ("poly1305_emit",".-poly1305_emit"); + } +-} ++ + ################ + +-ALIGN (128); ++ALIGN (16); + LABEL (".Lconst"); +-LONG (0x00060504,0x03020100,0x00161514,0x13121110); # vperm op[m[1],m[0]] +-LONG (0x000c0b0a,0x09080706,0x001c1b1a,0x19181716); # vperm op[m[3],m[2]] +-LONG (0x00000000,0x000f0e0d,0x00000000,0x001f1e1d); # vperm op[ - ,m[4]] +-LONG (0x00000000,0x03ffffff,0x00000000,0x03ffffff); # [0,2^26-1,0,2^26-1] +-LONG (0x0f0e0d0c,0x0b0a0908,0x07060504,0x03020100); # vperm op endian ++LONG (0x04050607,0x14151617,0x0c0d0e0f,0x1c1d1e1f); # merge odd ++LONG (0x07060504,0x03020100,0x17161514,0x13121110); # byte swap masks ++LONG (0x0f0e0d0c,0x0b0a0908,0x1f1e1d1c,0x1b1a1918); ++LONG (0x00000000,0x09080706,0x00000000,0x19181716); ++ ++LONG (0x00000000,0x00000000,0x00000000,0x0c0d0e0f); # magic tail masks ++LONG (0x0c0d0e0f,0x00000000,0x00000000,0x00000000); ++LONG (0x00000000,0x00000000,0x0c0d0e0f,0x00000000); ++ ++LONG (0xffffffff,0x00000000,0xffffffff,0xffffffff); ++LONG (0xffffffff,0x00000000,0xffffffff,0x00000000); ++LONG (0x00000000,0x00000000,0xffffffff,0x00000000); ++ + STRING ("\"Poly1305 for s390x, CRYPTOGAMS by \""); + + PERLASM_END(); +Index: openssl-1.1.1c/crypto/poly1305/build.info +=================================================================== +--- openssl-1.1.1c.orig/crypto/poly1305/build.info 2019-06-06 12:18:54.556316994 +0200 ++++ openssl-1.1.1c/crypto/poly1305/build.info 2019-06-06 12:19:24.232504722 +0200 +@@ -17,6 +17,7 @@ GENERATE[poly1305-armv8.S]=asm/poly1305- + INCLUDE[poly1305-armv8.o]=.. + GENERATE[poly1305-mips.S]=asm/poly1305-mips.pl $(PERLASM_SCHEME) + INCLUDE[poly1305-mips.o]=.. ++INCLUDE[poly1305-s390x.o]=.. + GENERATE[poly1305-s390x.S]=asm/poly1305-s390x.pl $(PERLASM_SCHEME) + + BEGINRAW[Makefile(unix)] diff --git a/openssl-1_1.changes b/openssl-1_1.changes index ebbe5d3..88d9d0a 100644 --- a/openssl-1_1.changes +++ b/openssl-1_1.changes @@ -1,15 +1,27 @@ ------------------------------------------------------------------- -Thu May 30 12:19:51 UTC 2019 - Vítězslav Čížek +Thu Jun 6 10:06:45 UTC 2019 - Vítězslav Čížek -- Update openssl-fix_underflow_in_errstr_handling.patch to use - upstream approved code +- Use upstream patch for the locale crash (bsc#1135550) * https://github.com/openssl/openssl/pull/8966 -- update openssl.keyring to include Richard Levitte's key +- delete openssl-fix_underflow_in_errstr_handling.patch +- add 0001-build_SYS_str_reasons-Fix-a-crash-caused-by-overlong.patch + +------------------------------------------------------------------- +Thu Jun 6 10:03:03 UTC 2019 - Vítězslav Čížek + +- Add s390x vectorized support for ChaCha20 and Poly1305 + (jsc#SLE-6126, jsc#SLE-6129) + * 0001-s390x-assembly-pack-perlasm-support.patch + * 0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch + * 0003-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch + * 0004-s390x-assembly-pack-fix-formal-interface-bug-in-chac.patch + * 0005-s390x-assembly-pack-import-chacha-from-cryptogams-re.patch + * 0006-s390x-assembly-pack-import-poly-from-cryptogams-repo.patch ------------------------------------------------------------------- Thu May 30 09:55:01 UTC 2019 - Vítězslav Čížek -- Update to 1.1.1c +- Update to 1.1.1c (bsc#1133925, jsc#SLE-6430) * Prevent over long nonces in ChaCha20-Poly1305 (CVE-2019-1543) ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input for every encryption operation. RFC 7539 specifies that the nonce value @@ -35,10 +47,10 @@ Thu May 30 09:55:01 UTC 2019 - Vítězslav Čížek * Make OPENSSL_config() error agnostic again. * Do the error handling in RSA decryption constant time. * Ensure that SM2 only uses SM3 as digest algorithm -- drop upstream integrated patches +- drop upstreamed patches: * openssl-fix-handling-of-GNU-strerror_r.patch * 0001-Fix-for-BIO_get_mem_ptr-and-related-regressions.patch -- refresh 0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch +- update keyring by including Richard Levitte's key ------------------------------------------------------------------- Tue May 28 08:21:52 UTC 2019 - Jiri Slaby diff --git a/openssl-1_1.spec b/openssl-1_1.spec index 221f7ce..0a55219 100644 --- a/openssl-1_1.spec +++ b/openssl-1_1.spec @@ -32,6 +32,7 @@ Source: https://www.%{_rname}.org/source/%{_rname}-%{version}.tar.gz Source1: %{name}.changes Source2: baselibs.conf Source3: https://www.%{_rname}.org/source/%{_rname}-%{version}.tar.gz.asc +# https://www.openssl.org/about/ # http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xA2D29B7BF295C759#/openssl.keyring Source4: %{_rname}.keyring Source5: showciphers.c @@ -42,12 +43,15 @@ Patch3: openssl-pkgconfig.patch Patch4: openssl-DEFAULT_SUSE_cipher.patch Patch5: openssl-ppc64-config.patch Patch6: openssl-no-date.patch -# PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/6919 fate#326561 -Patch7: 0001-s390x-assembly-pack-perlasm-support.patch -Patch8: 0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch -# PATCH-FIX-UPSTREAM FATE#326351 Add vectorized poly1305 implementation for s390x (https://github.com/openssl/openssl/pull/7991) -Patch9: 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch -Patch11: openssl-fix_underflow_in_errstr_handling.patch +# PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/8966 +Patch7: 0001-build_SYS_str_reasons-Fix-a-crash-caused-by-overlong.patch +# PATCH-FIX-UPSTREAM jsc#SLE-6126 and jsc#SLE-6129 +Patch8: 0001-s390x-assembly-pack-perlasm-support.patch +Patch9: 0002-crypto-chacha-asm-chacha-s390x.pl-add-vx-code-path.patch +Patch10: 0003-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch +Patch11: 0004-s390x-assembly-pack-fix-formal-interface-bug-in-chac.patch +Patch12: 0005-s390x-assembly-pack-import-chacha-from-cryptogams-re.patch +Patch13: 0006-s390x-assembly-pack-import-poly-from-cryptogams-repo.patch BuildRequires: pkgconfig Conflicts: ssl Provides: ssl diff --git a/openssl-fix_underflow_in_errstr_handling.patch b/openssl-fix_underflow_in_errstr_handling.patch deleted file mode 100644 index ac635bb..0000000 --- a/openssl-fix_underflow_in_errstr_handling.patch +++ /dev/null @@ -1,56 +0,0 @@ -diff --git a/crypto/err/err.c b/crypto/err/err.c -index 345d230206..84ef2fa3d4 100644 ---- a/crypto/err/err.c -+++ b/crypto/err/err.c -@@ -187,8 +187,8 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) - } - - #ifndef OPENSSL_NO_ERR --/* A measurement on Linux 2018-11-21 showed about 3.5kib */ --# define SPACE_SYS_STR_REASONS 4 * 1024 -+/* 2019-05-21: Russian and Ukrainian locales on Linux require more than 6,5 kB */ -+# define SPACE_SYS_STR_REASONS 4 * 1024 - # define NUM_SYS_STR_REASONS 127 - - static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; -@@ -222,26 +222,30 @@ static void build_SYS_str_reasons(void) - ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; - - str->error = ERR_PACK(ERR_LIB_SYS, 0, i); -- if (str->string == NULL) { -+ /* -+ * If we have used up all the space in strerror_pool, -+ * there's no point in calling openssl_strerror_r() -+ */ -+ if (str->string == NULL && cnt < sizeof(strerror_pool)) { - if (openssl_strerror_r(i, cur, sizeof(strerror_pool) - cnt)) { -- size_t l = strlen(cur); -+ size_t l = strlen(cur) + 1; - - str->string = cur; - cnt += l; -- if (cnt > sizeof(strerror_pool)) -- cnt = sizeof(strerror_pool); - cur += l; - - /* - * VMS has an unusual quirk of adding spaces at the end of -- * some (most? all?) messages. Lets trim them off. -+ * some (most? all?) messages. Lets trim them off. - */ -- while (ossl_isspace(cur[-1])) { -- cur--; -- cnt--; -+ if (cur > strerror_pool && ossl_isspace(cur[-1])) { -+ while (cur > strerror_pool && ossl_isspace(cur[-1])) { -+ cur--; -+ cnt--; -+ } -+ *cur++ = '\0'; -+ cnt++; - } -- *cur++ = '\0'; -- cnt++; - } - } - if (str->string == NULL) From 79f711b66ac89cf9bac9e0865e32bd28368839ff8ea941025fdfa358d4e3f912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=C4=9Bzslav=20=C4=8C=C3=AD=C5=BEek?= Date: Thu, 6 Jun 2019 11:24:07 +0000 Subject: [PATCH 6/6] Accepting request 708116 from home:vitezslav_cizek:branches:security:tls - delete 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch OBS-URL: https://build.opensuse.org/request/show/708116 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=39 --- openssl-1_1.changes | 1 + 1 file changed, 1 insertion(+) diff --git a/openssl-1_1.changes b/openssl-1_1.changes index 88d9d0a..cd8f1d2 100644 --- a/openssl-1_1.changes +++ b/openssl-1_1.changes @@ -17,6 +17,7 @@ Thu Jun 6 10:03:03 UTC 2019 - Vítězslav Čížek * 0004-s390x-assembly-pack-fix-formal-interface-bug-in-chac.patch * 0005-s390x-assembly-pack-import-chacha-from-cryptogams-re.patch * 0006-s390x-assembly-pack-import-poly-from-cryptogams-repo.patch +- delete 0001-crypto-poly1305-asm-poly1305-s390x.pl-add-vx-code-pa.patch ------------------------------------------------------------------- Thu May 30 09:55:01 UTC 2019 - Vítězslav Čížek