Add ABI tests for SHA*.

Bug: 181
Change-Id: Ica9299613d7fd1b803533b7e489b9ba8fe816a24
Reviewed-on: https://boringssl-review.googlesource.com/c/33968
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt
index f846f1f..2b81faa 100644
--- a/crypto/CMakeLists.txt
+++ b/crypto/CMakeLists.txt
@@ -458,6 +458,7 @@
   fipsmodule/ecdsa/ecdsa_test.cc
   fipsmodule/modes/gcm_test.cc
   fipsmodule/rand/ctrdrbg_test.cc
+  fipsmodule/sha/sha_test.cc
   hkdf/hkdf_test.cc
   hmac_extra/hmac_test.cc
   hrss/hrss_test.cc
diff --git a/crypto/fipsmodule/sha/internal.h b/crypto/fipsmodule/sha/internal.h
new file mode 100644
index 0000000..4def7f3
--- /dev/null
+++ b/crypto/fipsmodule/sha/internal.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2018, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_SHA_INTERNAL_H
+#define OPENSSL_HEADER_SHA_INTERNAL_H
+
+#include <openssl/base.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if !defined(OPENSSL_NO_ASM)
+
+#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
+    defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE)
+#define SHA1_ASM
+void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
+#endif
+
+#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
+    defined(OPENSSL_AARCH64)
+#define SHA256_ASM
+#define SHA512_ASM
+void sha256_block_data_order(uint32_t *state, const uint8_t *in, size_t num);
+void sha512_block_data_order(uint64_t *state, const uint64_t *W, size_t num);
+#endif
+
+#endif  // OPENSSL_NO_ASM
+
+
+#if defined(__cplusplus)
+}  // extern "C"
+#endif
+
+#endif  // OPENSSL_HEADER_SHA_INTERNAL_H
diff --git a/crypto/fipsmodule/sha/sha1.c b/crypto/fipsmodule/sha/sha1.c
index e5b4ba6..a3b771a 100644
--- a/crypto/fipsmodule/sha/sha1.c
+++ b/crypto/fipsmodule/sha/sha1.c
@@ -60,16 +60,10 @@
 
 #include <openssl/mem.h>
 
+#include "internal.h"
 #include "../../internal.h"
 
 
-#if (!defined(OPENSSL_NO_ASM) &&                            \
-     (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) ||    \
-      defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))) || \
-    defined(OPENSSL_PPC64LE)
-#define SHA1_ASM
-#endif
-
 int SHA1_Init(SHA_CTX *sha) {
   OPENSSL_memset(sha, 0, sizeof(SHA_CTX));
   sha->h[0] = 0x67452301UL;
@@ -120,9 +114,9 @@
   } while (0)
 
 #ifndef SHA1_ASM
-static
+static void sha1_block_data_order(uint32_t *state, const uint8_t *data,
+                                  size_t num);
 #endif
-void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
 
 #include "../digest/md32_common.h"
 
@@ -192,8 +186,8 @@
 * "find" this expectation reasonable:-( On order to make such
 * compilers generate better code I replace X[] with a bunch of
 * X0, X1, etc. See the function body below...
-*					<appro@fy.chalmers.se> */
-#define X(i)	XX##i
+*         <appro@fy.chalmers.se> */
+#define X(i)  XX##i
 
 #if !defined(SHA1_ASM)
 static void sha1_block_data_order(uint32_t *state, const uint8_t *data,
diff --git a/crypto/fipsmodule/sha/sha256.c b/crypto/fipsmodule/sha/sha256.c
index 3e9bcbc..92a5295 100644
--- a/crypto/fipsmodule/sha/sha256.c
+++ b/crypto/fipsmodule/sha/sha256.c
@@ -60,15 +60,10 @@
 
 #include <openssl/mem.h>
 
+#include "internal.h"
 #include "../../internal.h"
 
 
-#if !defined(OPENSSL_NO_ASM) &&                         \
-    (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
-     defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
-#define SHA256_ASM
-#endif
-
 int SHA224_Init(SHA256_CTX *sha) {
   OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
   sha->h[0] = 0xc1059ed8UL;
@@ -172,9 +167,9 @@
 #define HASH_FINAL SHA256_Final
 #define HASH_BLOCK_DATA_ORDER sha256_block_data_order
 #ifndef SHA256_ASM
-static
+static void sha256_block_data_order(uint32_t *state, const uint8_t *in,
+                                    size_t num);
 #endif
-void sha256_block_data_order(uint32_t *state, const uint8_t *in, size_t num);
 
 #include "../digest/md32_common.h"
 
diff --git a/crypto/fipsmodule/sha/sha512.c b/crypto/fipsmodule/sha/sha512.c
index 3902f50..a689056 100644
--- a/crypto/fipsmodule/sha/sha512.c
+++ b/crypto/fipsmodule/sha/sha512.c
@@ -60,6 +60,7 @@
 
 #include <openssl/mem.h>
 
+#include "internal.h"
 #include "../../internal.h"
 
 
@@ -75,12 +76,6 @@
 // - By supporting only a transform function that operates on *aligned* data
 //   the collector/padding function is simpler and easier to optimize.
 
-#if !defined(OPENSSL_NO_ASM) &&                         \
-    (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
-     defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
-#define SHA512_ASM
-#endif
-
 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
     defined(__ARM_FEATURE_UNALIGNED)
 #define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
@@ -140,9 +135,9 @@
 }
 
 #if !defined(SHA512_ASM)
-static
+static void sha512_block_data_order(uint64_t *state, const uint64_t *W,
+                                    size_t num);
 #endif
-void sha512_block_data_order(uint64_t *state, const uint64_t *W, size_t num);
 
 
 int SHA384_Final(uint8_t *md, SHA512_CTX *sha) {
diff --git a/crypto/fipsmodule/sha/sha_test.cc b/crypto/fipsmodule/sha/sha_test.cc
new file mode 100644
index 0000000..9cac47f
--- /dev/null
+++ b/crypto/fipsmodule/sha/sha_test.cc
@@ -0,0 +1,60 @@
+/* Copyright (c) 2018, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/sha.h>
+
+#include <gtest/gtest.h>
+
+#include "internal.h"
+#include "../../test/abi_test.h"
+
+
+#if defined(SHA1_ASM) && defined(SUPPORTS_ABI_TEST)
+TEST(SHATest, SHA1ABI) {
+  SHA_CTX ctx;
+  SHA1_Init(&ctx);
+
+  static const uint8_t kBuf[SHA_CBLOCK * 8] = {0};
+  CHECK_ABI(sha1_block_data_order, ctx.h, kBuf, 1);
+  CHECK_ABI(sha1_block_data_order, ctx.h, kBuf, 2);
+  CHECK_ABI(sha1_block_data_order, ctx.h, kBuf, 4);
+  CHECK_ABI(sha1_block_data_order, ctx.h, kBuf, 8);
+}
+#endif  // SHA1_ASM && SUPPORTS_ABI_TEST
+
+#if defined(SHA256_ASM) && defined(SUPPORTS_ABI_TEST)
+TEST(SHATest, SHA256ABI) {
+  SHA256_CTX ctx;
+  SHA256_Init(&ctx);
+
+  static const uint8_t kBuf[SHA256_CBLOCK * 8] = {0};
+  CHECK_ABI(sha256_block_data_order, ctx.h, kBuf, 1);
+  CHECK_ABI(sha256_block_data_order, ctx.h, kBuf, 2);
+  CHECK_ABI(sha256_block_data_order, ctx.h, kBuf, 4);
+  CHECK_ABI(sha256_block_data_order, ctx.h, kBuf, 8);
+}
+#endif  // SHA256_ASM && SUPPORTS_ABI_TEST
+
+#if defined(SHA512_ASM) && defined(SUPPORTS_ABI_TEST)
+TEST(SHATest, SHA512ABI) {
+  SHA512_CTX ctx;
+  SHA512_Init(&ctx);
+
+  static const uint64_t kBuf[SHA512_CBLOCK / sizeof(uint64_t) * 4] = {0};
+  CHECK_ABI(sha512_block_data_order, ctx.h, kBuf, 1);
+  CHECK_ABI(sha512_block_data_order, ctx.h, kBuf, 2);
+  CHECK_ABI(sha512_block_data_order, ctx.h, kBuf, 3);
+  CHECK_ABI(sha512_block_data_order, ctx.h, kBuf, 4);
+}
+#endif  // SHA512_ASM && SUPPORTS_ABI_TEST