Add ABI tests for ChaCha20_ctr32.

Change-Id: I1fad7f954284000474e5723c3fa59fedceb52ad4
Reviewed-on: https://boringssl-review.googlesource.com/c/34186
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/chacha/asm/chacha-x86_64.pl b/crypto/chacha/asm/chacha-x86_64.pl
index 6b2065e..6be270e 100755
--- a/crypto/chacha/asm/chacha-x86_64.pl
+++ b/crypto/chacha/asm/chacha-x86_64.pl
@@ -228,6 +228,7 @@
 .type	ChaCha20_ctr32,\@function,5
 .align	64
 ChaCha20_ctr32:
+.cfi_startproc
 	cmp	\$0,$len
 	je	.Lno_data
 	mov	OPENSSL_ia32cap_P+4(%rip),%r10
@@ -241,12 +242,19 @@
 	jnz	.LChaCha20_ssse3
 
 	push	%rbx
+.cfi_push	rbx
 	push	%rbp
+.cfi_push	rbp
 	push	%r12
+.cfi_push	r12
 	push	%r13
+.cfi_push	r13
 	push	%r14
+.cfi_push	r14
 	push	%r15
+.cfi_push	r15
 	sub	\$64+24,%rsp
+.cfi_adjust_cfa_offset	`64+24`
 .Lctr32_body:
 
 	#movdqa	.Lsigma(%rip),%xmm0
@@ -388,14 +396,22 @@
 .Ldone:
 	lea	64+24+48(%rsp),%rsi
 	mov	-48(%rsi),%r15
+.cfi_restore	r15
 	mov	-40(%rsi),%r14
+.cfi_restore	r14
 	mov	-32(%rsi),%r13
+.cfi_restore	r13
 	mov	-24(%rsi),%r12
+.cfi_restore	r12
 	mov	-16(%rsi),%rbp
+.cfi_restore	rbp
 	mov	-8(%rsi),%rbx
+.cfi_restore	rbx
 	lea	(%rsi),%rsp
+.cfi_adjust_cfa_offset	`-64-24-48`
 .Lno_data:
 	ret
+.cfi_endproc
 .size	ChaCha20_ctr32,.-ChaCha20_ctr32
 ___
 
@@ -435,7 +451,9 @@
 .align	32
 ChaCha20_ssse3:
 .LChaCha20_ssse3:
+.cfi_startproc
 	mov	%rsp,%r9		# frame pointer
+.cfi_def_cfa_register	r9
 ___
 $code.=<<___;
 	cmp	\$128,$len		# we might throw away some data,
@@ -547,8 +565,10 @@
 ___
 $code.=<<___;
 	lea	(%r9),%rsp
+.cfi_def_cfa_register	rsp
 .Lssse3_epilogue:
 	ret
+.cfi_endproc
 .size	ChaCha20_ssse3,.-ChaCha20_ssse3
 ___
 }
@@ -691,7 +711,9 @@
 .align	32
 ChaCha20_4x:
 .LChaCha20_4x:
+.cfi_startproc
 	mov		%rsp,%r9		# frame pointer
+.cfi_def_cfa_register	r9
 	mov		%r10,%r11
 ___
 $code.=<<___	if ($avx>1);
@@ -1131,8 +1153,10 @@
 ___
 $code.=<<___;
 	lea		(%r9),%rsp
+.cfi_def_cfa_register	rsp
 .L4x_epilogue:
 	ret
+.cfi_endproc
 .size	ChaCha20_4x,.-ChaCha20_4x
 ___
 }
@@ -1266,7 +1290,9 @@
 .align	32
 ChaCha20_8x:
 .LChaCha20_8x:
+.cfi_startproc
 	mov		%rsp,%r9		# frame register
+.cfi_def_cfa_register	r9
 	sub		\$0x280+$xframe,%rsp
 	and		\$-32,%rsp
 ___
@@ -1772,8 +1798,10 @@
 ___
 $code.=<<___;
 	lea		(%r9),%rsp
+.cfi_def_cfa_register	rsp
 .L8x_epilogue:
 	ret
+.cfi_endproc
 .size	ChaCha20_8x,.-ChaCha20_8x
 ___
 }
@@ -1811,7 +1839,9 @@
 .align	32
 ChaCha20_avx512:
 .LChaCha20_avx512:
+.cfi_startproc
 	mov	%rsp,%r9		# frame pointer
+.cfi_def_cfa_register	r9
 	cmp	\$512,$len
 	ja	.LChaCha20_16x
 
@@ -1991,8 +2021,10 @@
 ___
 $code.=<<___;
 	lea	(%r9),%rsp
+.cfi_def_cfa_register	rsp
 .Lavx512_epilogue:
 	ret
+.cfi_endproc
 .size	ChaCha20_avx512,.-ChaCha20_avx512
 ___
 }
@@ -2075,7 +2107,9 @@
 .align	32
 ChaCha20_16x:
 .LChaCha20_16x:
+.cfi_startproc
 	mov		%rsp,%r9		# frame register
+.cfi_def_cfa_register	r9
 	sub		\$64+$xframe,%rsp
 	and		\$-64,%rsp
 ___
@@ -2493,8 +2527,10 @@
 ___
 $code.=<<___;
 	lea		(%r9),%rsp
+.cfi_def_cfa_register	rsp
 .L16x_epilogue:
 	ret
+.cfi_endproc
 .size	ChaCha20_16x,.-ChaCha20_16x
 ___
 }
diff --git a/crypto/chacha/chacha.c b/crypto/chacha/chacha.c
index eac51a5..b539f99 100644
--- a/crypto/chacha/chacha.c
+++ b/crypto/chacha/chacha.c
@@ -64,13 +64,7 @@
   OPENSSL_memcpy(&out[16], &x[12], sizeof(uint32_t) * 4);
 }
 
-#if !defined(OPENSSL_NO_ASM) &&                         \
-    (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
-     defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
-
-// ChaCha20_ctr32 is defined in asm/chacha-*.pl.
-void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len,
-                    const uint32_t key[8], const uint32_t counter[4]);
+#if defined(CHACHA20_ASM)
 
 void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
                       const uint8_t key[32], const uint8_t nonce[12],
diff --git a/crypto/chacha/chacha_test.cc b/crypto/chacha/chacha_test.cc
index a40653f..25313ca 100644
--- a/crypto/chacha/chacha_test.cc
+++ b/crypto/chacha/chacha_test.cc
@@ -23,7 +23,9 @@
 #include <openssl/crypto.h>
 #include <openssl/chacha.h>
 
+#include "internal.h"
 #include "../internal.h"
+#include "../test/abi_test.h"
 #include "../test/test_util.h"
 
 
@@ -234,3 +236,25 @@
     EXPECT_EQ(Bytes(kOutput, len), Bytes(buf.get(), len));
   }
 }
+
+#if defined(CHACHA20_ASM) && defined(SUPPORTS_ABI_TEST)
+TEST(ChaChaTest, ABI) {
+  uint32_t key[8];
+  OPENSSL_memcpy(key, kKey, sizeof(key));
+
+  static const uint32_t kCounterNonce[4] = {0};
+
+  std::unique_ptr<uint8_t[]> buf(new uint8_t[sizeof(kInput)]);
+  for (size_t len = 0; len <= 32; len++) {
+    SCOPED_TRACE(len);
+    CHECK_ABI(ChaCha20_ctr32, buf.get(), kInput, len, key, kCounterNonce);
+  }
+
+  for (size_t len : {32 * 2, 32 * 4, 32 * 8, 32 * 16, 32 * 24}) {
+    SCOPED_TRACE(len);
+    CHECK_ABI(ChaCha20_ctr32, buf.get(), kInput, len, key, kCounterNonce);
+    // Cover the partial block paths.
+    CHECK_ABI(ChaCha20_ctr32, buf.get(), kInput, len + 15, key, kCounterNonce);
+  }
+}
+#endif  // CHACHA20_ASM && SUPPORTS_ABI_TEST
diff --git a/crypto/chacha/internal.h b/crypto/chacha/internal.h
index 5a49811..1435e3b 100644
--- a/crypto/chacha/internal.h
+++ b/crypto/chacha/internal.h
@@ -27,6 +27,16 @@
 void CRYPTO_hchacha20(uint8_t out[32], const uint8_t key[32],
                       const uint8_t nonce[16]);
 
+#if !defined(OPENSSL_NO_ASM) &&                         \
+    (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
+     defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
+#define CHACHA20_ASM
+
+// ChaCha20_ctr32 is defined in asm/chacha-*.pl.
+void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len,
+                    const uint32_t key[8], const uint32_t counter[4]);
+#endif
+
 
 #if defined(__cplusplus)
 }  // extern C