Add ABI tests for HRSS assembly.
The last instruction did not unwind correctly. Also add .type and .size
annotations so that errors show up properly.
Change-Id: Id18e12b4ed51bdabb90bd5ac66631fd989649eec
Reviewed-on: https://boringssl-review.googlesource.com/c/34190
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/hrss/asm/poly_rq_mul.S b/crypto/hrss/asm/poly_rq_mul.S
index 0ad0fb5..ebaabd3 100644
--- a/crypto/hrss/asm/poly_rq_mul.S
+++ b/crypto/hrss/asm/poly_rq_mul.S
@@ -312,6 +312,7 @@
.text
.global poly_Rq_mul
.hidden poly_Rq_mul
+.type poly_Rq_mul, @function
.att_syntax prefix
poly_Rq_mul:
.cfi_startproc
@@ -8450,8 +8451,13 @@
vmovdqu %ymm11, 1320(%rdi)
mov %r8, %rsp
pop %r12
+.cfi_restore r12
pop %rbp
+.cfi_restore rbp
+.cfi_def_cfa_register rsp
+.cfi_adjust_cfa_offset -8
ret
.cfi_endproc
+.size poly_Rq_mul,.-poly_Rq_mul
#endif
diff --git a/crypto/hrss/hrss.c b/crypto/hrss/hrss.c
index 13bfa08..71fa5e3 100644
--- a/crypto/hrss/hrss.c
+++ b/crypto/hrss/hrss.c
@@ -1387,23 +1387,12 @@
OPENSSL_memset(&out->v[N], 0, 3 * sizeof(uint16_t));
}
-// On x86-64, we can use the AVX2 code from [HRSS]. (The authors have given
-// explicit permission for this and signed a CLA.) However it's 57KB of object
-// code, so it's not used if |OPENSSL_SMALL| is defined.
-#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && \
- defined(OPENSSL_X86_64) && defined(OPENSSL_LINUX)
-// poly_Rq_mul is defined in assembly.
-extern void poly_Rq_mul(struct poly *r, const struct poly *a,
- const struct poly *b);
-#endif
-
static void poly_mul(struct poly *r, const struct poly *a,
const struct poly *b) {
-#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && \
- defined(OPENSSL_X86_64) && defined(OPENSSL_LINUX)
+#if defined(POLY_RQ_MUL_ASM)
const int has_avx2 = (OPENSSL_ia32cap_P[2] & (1 << 5)) != 0;
if (has_avx2) {
- poly_Rq_mul(r, a, b);
+ poly_Rq_mul(r->v, a->v, b->v);
return;
}
#endif
diff --git a/crypto/hrss/hrss_test.cc b/crypto/hrss/hrss_test.cc
index ee0400e..596db07 100644
--- a/crypto/hrss/hrss_test.cc
+++ b/crypto/hrss/hrss_test.cc
@@ -14,9 +14,11 @@
#include <gtest/gtest.h>
+#include <openssl/cpu.h>
#include <openssl/hrss.h>
#include <openssl/rand.h>
+#include "../test/abi_test.h"
#include "../test/test_util.h"
#include "internal.h"
@@ -477,3 +479,18 @@
};
EXPECT_EQ(Bytes(shared_key), Bytes(kExpectedFailureKey));
}
+
+#if defined(POLY_RQ_MUL_ASM) && defined(SUPPORTS_ABI_TEST)
+TEST(HRSS, ABI) {
+ const bool has_avx2 = (OPENSSL_ia32cap_P[2] & (1 << 5)) != 0;
+ if (!has_avx2) {
+ fprintf(stderr, "Skipping ABI test due to lack of AVX2 support.\n");
+ return;
+ }
+
+ alignas(16) uint16_t r[N + 3];
+ alignas(16) uint16_t a[N + 3] = {0};
+ alignas(16) uint16_t b[N + 3] = {0};
+ CHECK_ABI(poly_Rq_mul, r, a, b);
+}
+#endif // POLY_RQ_MUL_ASM && SUPPORTS_ABI_TEST
diff --git a/crypto/hrss/internal.h b/crypto/hrss/internal.h
index 70218b8..7cfe010 100644
--- a/crypto/hrss/internal.h
+++ b/crypto/hrss/internal.h
@@ -42,6 +42,18 @@
OPENSSL_EXPORT void HRSS_poly3_invert(struct poly3 *out,
const struct poly3 *in);
+// On x86-64, we can use the AVX2 code from [HRSS]. (The authors have given
+// explicit permission for this and signed a CLA.) However it's 57KB of object
+// code, so it's not used if |OPENSSL_SMALL| is defined.
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && \
+ defined(OPENSSL_X86_64) && defined(OPENSSL_LINUX)
+#define POLY_RQ_MUL_ASM
+// poly_Rq_mul is defined in assembly. Inputs and outputs must be 16-byte-
+// aligned.
+extern void poly_Rq_mul(uint16_t r[N + 3], const uint16_t a[N + 3],
+ const uint16_t b[N + 3]);
+#endif
+
#if defined(__cplusplus)
} // extern "C"