Extract SHA224/256 from bcm

Change-Id: I953441ccf99321184a5b664cc446551fa5e295b4
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/70947
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/build.json b/build.json
index 23c0634..2e675d8 100644
--- a/build.json
+++ b/build.json
@@ -303,6 +303,7 @@
             "crypto/rsa_extra/rsa_crypt.c",
             "crypto/rsa_extra/rsa_print.c",
             "crypto/sha/sha1.c",
+            "crypto/sha/sha256.c",
             "crypto/siphash/siphash.c",
             "crypto/slhdsa/fors.c",
             "crypto/slhdsa/merkle.c",
diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c
index 81e03cb..55375ea 100644
--- a/crypto/fipsmodule/bcm.c
+++ b/crypto/fipsmodule/bcm.c
@@ -194,7 +194,7 @@
   assert_within(start, RSA_sign, end);
   assert_within(start, BCM_rand_bytes, end);
   assert_within(start, EC_GROUP_cmp, end);
-  assert_within(start, SHA256_Update, end);
+  assert_within(start, BCM_sha256_update, end);
   assert_within(start, ecdsa_verify_fixed, end);
   assert_within(start, EVP_AEAD_CTX_seal, end);
 
diff --git a/crypto/fipsmodule/bcm_interface.h b/crypto/fipsmodule/bcm_interface.h
index 8c07281..222a9db 100644
--- a/crypto/fipsmodule/bcm_interface.h
+++ b/crypto/fipsmodule/bcm_interface.h
@@ -98,7 +98,8 @@
 // BCM_SHA1_transform is a low-level function that performs a single, SHA-1
 // block transformation using the state from |sha| and |SHA_CBLOCK| bytes from
 // |block|.
-bcm_infallible BCM_sha1_transform(SHA_CTX *c, const uint8_t data[BCM_SHA_CBLOCK]);
+bcm_infallible BCM_sha1_transform(SHA_CTX *c,
+                                  const uint8_t data[BCM_SHA_CBLOCK]);
 
 // BCM_sha1_update adds |len| bytes from |data| to |sha|.
 bcm_infallible BCM_sha1_update(SHA_CTX *c, const void *data, size_t len);
@@ -125,6 +126,55 @@
                                   const uint8_t xkey[BCM_SHA_DIGEST_LENGTH]);
 
 
+// SHA-224
+
+// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest.
+#define BCM_SHA224_DIGEST_LENGTH 28
+
+// BCM_sha224_unit initialises |sha|.
+bcm_infallible BCM_sha224_init(SHA256_CTX *sha);
+
+// BCM_sha224_update adds |len| bytes from |data| to |sha|.
+bcm_infallible BCM_sha224_update(SHA256_CTX *sha, const void *data, size_t len);
+
+// BCM_sha224_Final adds the final padding to |sha| and writes the resulting
+// digest to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of
+// space. It aborts on programmer error.
+bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH],
+                                SHA256_CTX *sha);
+
+
+// SHA-256
+
+// BCM_SHA256_DIGEST_LENGTH is the length of a SHA-256 digest.
+#define BCM_SHA256_DIGEST_LENGTH 32
+
+// BCM_sha256_init initialises |sha|.
+bcm_infallible BCM_sha256_init(SHA256_CTX *sha);
+
+// BCM_sha256_update adds |len| bytes from |data| to |sha|.
+bcm_infallible BCM_sha256_update(SHA256_CTX *sha, const void *data, size_t len);
+
+// BCM_sha256_final adds the final padding to |sha| and writes the resulting
+// digest to |out|, which must have at least |BCM_SHA256_DIGEST_LENGTH| bytes of
+// space. It aborts on programmer error.
+bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH],
+                                SHA256_CTX *sha);
+
+// BCM_sha256_transform is a low-level function that performs a single, SHA-256
+// block transformation using the state from |sha| and |BCM_SHA256_CBLOCK| bytes
+// from |block|.
+bcm_infallible BCM_sha256_transform(SHA256_CTX *sha,
+                                    const uint8_t block[BCM_SHA256_CBLOCK]);
+
+// BCM_sha256_transform_blocks is a low-level function that takes |num_blocks| *
+// |BCM_SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to
+// update |state|.
+bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8],
+                                           const uint8_t *data,
+                                           size_t num_blocks);
+
+
 #if defined(__cplusplus)
 }  // extern C
 #endif
diff --git a/crypto/fipsmodule/digest/digests.c.inc b/crypto/fipsmodule/digest/digests.c.inc
index 4773a23..216af52 100644
--- a/crypto/fipsmodule/digest/digests.c.inc
+++ b/crypto/fipsmodule/digest/digests.c.inc
@@ -98,20 +98,20 @@
 
 
 static void sha224_init(EVP_MD_CTX *ctx) {
-  CHECK(SHA224_Init(ctx->md_data));
+  BCM_sha224_init(ctx->md_data);
 }
 
 static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  CHECK(SHA224_Update(ctx->md_data, data, count));
+  BCM_sha224_update(ctx->md_data, data, count);
 }
 
 static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) {
-  CHECK(SHA224_Final(md, ctx->md_data));
+  BCM_sha224_final(md, ctx->md_data);
 }
 
 DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) {
   out->type = NID_sha224;
-  out->md_size = SHA224_DIGEST_LENGTH;
+  out->md_size = BCM_SHA224_DIGEST_LENGTH;
   out->flags = 0;
   out->init = sha224_init;
   out->update = sha224_update;
@@ -122,20 +122,20 @@
 
 
 static void sha256_init(EVP_MD_CTX *ctx) {
-  CHECK(SHA256_Init(ctx->md_data));
+  BCM_sha256_init(ctx->md_data);
 }
 
 static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  CHECK(SHA256_Update(ctx->md_data, data, count));
+  BCM_sha256_update(ctx->md_data, data, count);
 }
 
 static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) {
-  CHECK(SHA256_Final(md, ctx->md_data));
+  BCM_sha256_final(md, ctx->md_data);
 }
 
 DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) {
   out->type = NID_sha256;
-  out->md_size = SHA256_DIGEST_LENGTH;
+  out->md_size = BCM_SHA256_DIGEST_LENGTH;
   out->flags = 0;
   out->init = sha256_init;
   out->update = sha256_update;
diff --git a/crypto/fipsmodule/ec/ec_key.c.inc b/crypto/fipsmodule/ec/ec_key.c.inc
index 1eef021..376fa65 100644
--- a/crypto/fipsmodule/ec/ec_key.c.inc
+++ b/crypto/fipsmodule/ec/ec_key.c.inc
@@ -75,7 +75,6 @@
 #include <openssl/err.h>
 #include <openssl/ex_data.h>
 #include <openssl/mem.h>
-#include <openssl/sha.h>
 #include <openssl/thread.h>
 
 #include "internal.h"
@@ -346,7 +345,7 @@
   }
 
   if (key->priv_key) {
-    uint8_t digest[SHA256_DIGEST_LENGTH] = {0};
+    uint8_t digest[BCM_SHA256_DIGEST_LENGTH] = {0};
     uint8_t sig[ECDSA_MAX_FIXED_LEN];
     size_t sig_len;
     if (!ecdsa_sign_fixed(digest, sizeof(digest), sig, &sig_len, sizeof(sig),
diff --git a/crypto/fipsmodule/ecdh/ecdh.c.inc b/crypto/fipsmodule/ecdh/ecdh.c.inc
index eeb591f..d16c3c1 100644
--- a/crypto/fipsmodule/ecdh/ecdh.c.inc
+++ b/crypto/fipsmodule/ecdh/ecdh.c.inc
@@ -105,12 +105,19 @@
   }
 
   FIPS_service_indicator_lock_state();
+  SHA256_CTX ctx;
   switch (out_len) {
     case SHA224_DIGEST_LENGTH:
-      SHA224(buf, buflen, out);
+      BCM_sha224_init(&ctx);
+      BCM_sha224_update(&ctx, buf, buflen);
+      BCM_sha224_final(out, &ctx);
+      OPENSSL_cleanse(&ctx, sizeof(ctx));
       break;
     case SHA256_DIGEST_LENGTH:
-      SHA256(buf, buflen, out);
+      BCM_sha256_init(&ctx);
+      BCM_sha256_update(&ctx, buf, buflen);
+      BCM_sha256_final(out, &ctx);
+      OPENSSL_cleanse(&ctx, sizeof(ctx));
       break;
     case SHA384_DIGEST_LENGTH:
       SHA384(buf, buflen, out);
diff --git a/crypto/fipsmodule/rsa/rsa.c.inc b/crypto/fipsmodule/rsa/rsa.c.inc
index 9b97655..8cb6c5d 100644
--- a/crypto/fipsmodule/rsa/rsa.c.inc
+++ b/crypto/fipsmodule/rsa/rsa.c.inc
@@ -487,14 +487,14 @@
     },
     {
      NID_sha224,
-     SHA224_DIGEST_LENGTH,
+     BCM_SHA224_DIGEST_LENGTH,
      19,
      {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
       0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
     },
     {
      NID_sha256,
-     SHA256_DIGEST_LENGTH,
+     BCM_SHA256_DIGEST_LENGTH,
      19,
      {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
       0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
diff --git a/crypto/fipsmodule/sha/sha256.c.inc b/crypto/fipsmodule/sha/sha256.c.inc
index b7c616b..91188ab 100644
--- a/crypto/fipsmodule/sha/sha256.c.inc
+++ b/crypto/fipsmodule/sha/sha256.c.inc
@@ -54,19 +54,18 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.] */
 
-#include <openssl/sha.h>
-
 #include <string.h>
 
 #include <openssl/mem.h>
 
 #include "../../internal.h"
+#include "../bcm_interface.h"
 #include "../digest/md32_common.h"
 #include "../service_indicator/internal.h"
 #include "internal.h"
 
 
-int SHA224_Init(SHA256_CTX *sha) {
+bcm_infallible BCM_sha224_init(SHA256_CTX *sha) {
   OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
   sha->h[0] = 0xc1059ed8UL;
   sha->h[1] = 0x367cd507UL;
@@ -76,11 +75,11 @@
   sha->h[5] = 0x68581511UL;
   sha->h[6] = 0x64f98fa7UL;
   sha->h[7] = 0xbefa4fa4UL;
-  sha->md_len = SHA224_DIGEST_LENGTH;
-  return 1;
+  sha->md_len = BCM_SHA224_DIGEST_LENGTH;
+  return bcm_infallible_approved;
 }
 
-int SHA256_Init(SHA256_CTX *sha) {
+bcm_infallible BCM_sha256_init(SHA256_CTX *sha) {
   OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
   sha->h[0] = 0x6a09e667UL;
   sha->h[1] = 0xbb67ae85UL;
@@ -90,28 +89,8 @@
   sha->h[5] = 0x9b05688cUL;
   sha->h[6] = 0x1f83d9abUL;
   sha->h[7] = 0x5be0cd19UL;
-  sha->md_len = SHA256_DIGEST_LENGTH;
-  return 1;
-}
-
-uint8_t *SHA224(const uint8_t *data, size_t len,
-                uint8_t out[SHA224_DIGEST_LENGTH]) {
-  SHA256_CTX ctx;
-  SHA224_Init(&ctx);
-  SHA224_Update(&ctx, data, len);
-  SHA224_Final(out, &ctx);
-  OPENSSL_cleanse(&ctx, sizeof(ctx));
-  return out;
-}
-
-uint8_t *SHA256(const uint8_t *data, size_t len,
-                uint8_t out[SHA256_DIGEST_LENGTH]) {
-  SHA256_CTX ctx;
-  SHA256_Init(&ctx);
-  SHA256_Update(&ctx, data, len);
-  SHA256_Final(out, &ctx);
-  OPENSSL_cleanse(&ctx, sizeof(ctx));
-  return out;
+  sha->md_len = BCM_SHA256_DIGEST_LENGTH;
+  return bcm_infallible_approved;
 }
 
 #if !defined(SHA256_ASM)
@@ -119,31 +98,28 @@
                                     size_t num);
 #endif
 
-void SHA256_Transform(SHA256_CTX *c, const uint8_t data[SHA256_CBLOCK]) {
+bcm_infallible BCM_sha256_transform(SHA256_CTX *c,
+                                    const uint8_t data[BCM_SHA256_CBLOCK]) {
   sha256_block_data_order(c->h, data, 1);
+  return bcm_infallible_approved;
 }
 
-int SHA256_Update(SHA256_CTX *c, const void *data, size_t len) {
-  crypto_md32_update(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK,
+bcm_infallible BCM_sha256_update(SHA256_CTX *c, const void *data, size_t len) {
+  crypto_md32_update(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK,
                      &c->num, &c->Nh, &c->Nl, data, len);
-  return 1;
+  return bcm_infallible_approved;
 }
 
-int SHA224_Update(SHA256_CTX *ctx, const void *data, size_t len) {
-  return SHA256_Update(ctx, data, len);
+bcm_infallible BCM_sha224_update(SHA256_CTX *ctx, const void *data,
+                                 size_t len) {
+  return BCM_sha256_update(ctx, data, len);
 }
 
-static int sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) {
-  crypto_md32_final(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK,
+static void sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) {
+  crypto_md32_final(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK,
                     &c->num, c->Nh, c->Nl, /*is_big_endian=*/1);
 
-  // TODO(davidben): This overflow check one of the few places a low-level hash
-  // 'final' function can fail. SHA-512 does not have a corresponding check.
-  // These functions already misbehave if the caller arbitrarily mutates |c|, so
-  // can we assume one of |SHA256_Init| or |SHA224_Init| was used?
-  if (md_len > SHA256_DIGEST_LENGTH) {
-    return 0;
-  }
+  BSSL_CHECK(md_len <= BCM_SHA256_DIGEST_LENGTH);
 
   assert(md_len % 4 == 0);
   const size_t out_words = md_len / 4;
@@ -153,23 +129,26 @@
   }
 
   FIPS_service_indicator_update_state();
-  return 1;
 }
 
-int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], SHA256_CTX *c) {
-  // Ideally we would assert |sha->md_len| is |SHA256_DIGEST_LENGTH| to match
-  // the size hint, but calling code often pairs |SHA224_Init| with
+bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH],
+                                SHA256_CTX *c) {
+  // Ideally we would assert |sha->md_len| is |BCM_SHA256_DIGEST_LENGTH| to
+  // match the size hint, but calling code often pairs |SHA224_Init| with
   // |SHA256_Final| and expects |sha->md_len| to carry the size over.
   //
   // TODO(davidben): Add an assert and fix code to match them up.
-  return sha256_final_impl(out, c->md_len, c);
+  sha256_final_impl(out, c->md_len, c);
+  return bcm_infallible_approved;
 }
 
-int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], SHA256_CTX *ctx) {
+bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH],
+                                SHA256_CTX *ctx) {
   // This function must be paired with |SHA224_Init|, which sets |ctx->md_len|
-  // to |SHA224_DIGEST_LENGTH|.
-  assert(ctx->md_len == SHA224_DIGEST_LENGTH);
-  return sha256_final_impl(out, SHA224_DIGEST_LENGTH, ctx);
+  // to |BCM_SHA224_DIGEST_LENGTH|.
+  assert(ctx->md_len == BCM_SHA224_DIGEST_LENGTH);
+  sha256_final_impl(out, BCM_SHA224_DIGEST_LENGTH, ctx);
+  return bcm_infallible_approved;
 }
 
 #if !defined(SHA256_ASM)
@@ -344,9 +323,11 @@
 #endif  // !defined(SHA256_ASM)
 
 
-void SHA256_TransformBlocks(uint32_t state[8], const uint8_t *data,
-                            size_t num_blocks) {
+bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8],
+                                           const uint8_t *data,
+                                           size_t num_blocks) {
   sha256_block_data_order(state, data, num_blocks);
+  return bcm_infallible_approved;
 }
 
 #undef Sigma0
diff --git a/crypto/sha/sha256.c b/crypto/sha/sha256.c
new file mode 100644
index 0000000..d7f30cf
--- /dev/null
+++ b/crypto/sha/sha256.c
@@ -0,0 +1,87 @@
+/* Copyright (c) 2024, 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 <openssl/mem.h>
+
+#include "../fipsmodule/bcm_interface.h"
+
+
+int SHA224_Init(SHA256_CTX *sha) {
+  BCM_sha224_init(sha);
+  return 1;
+}
+
+int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len) {
+  BCM_sha224_update(sha, data, len);
+  return 1;
+}
+
+int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], SHA256_CTX *sha) {
+  BCM_sha224_final(out, sha);
+  return 1;
+}
+
+uint8_t *SHA224(const uint8_t *data, size_t len,
+                uint8_t out[SHA224_DIGEST_LENGTH]) {
+  SHA256_CTX ctx;
+  BCM_sha224_init(&ctx);
+  BCM_sha224_update(&ctx, data, len);
+  BCM_sha224_final(out, &ctx);
+  OPENSSL_cleanse(&ctx, sizeof(ctx));
+  return out;
+}
+
+int SHA256_Init(SHA256_CTX *sha) {
+  BCM_sha256_init(sha);
+  return 1;
+}
+
+int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len) {
+  BCM_sha256_update(sha, data, len);
+  return 1;
+}
+
+int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], SHA256_CTX *sha) {
+  // TODO(bbe): This overflow check one of the few places a low-level hash
+  // 'final' function can fail. SHA-512 does not have a corresponding check.
+  // The BCM function is infallible and will abort if this is done incorrectly.
+  // we should verify nothing crashes with this removed and eliminate the 0
+  // return.
+  if (sha->md_len > SHA256_DIGEST_LENGTH) {
+    return 0;
+  }
+  BCM_sha256_final(out, sha);
+  return 1;
+}
+
+uint8_t *SHA256(const uint8_t *data, size_t len,
+                uint8_t out[SHA256_DIGEST_LENGTH]) {
+  SHA256_CTX ctx;
+  BCM_sha256_init(&ctx);
+  BCM_sha256_update(&ctx, data, len);
+  BCM_sha256_final(out, &ctx);
+  OPENSSL_cleanse(&ctx, sizeof(ctx));
+  return out;
+}
+
+void SHA256_Transform(SHA256_CTX *sha, const uint8_t block[SHA256_CBLOCK]) {
+  BCM_sha256_transform(sha, block);
+}
+
+void SHA256_TransformBlocks(uint32_t state[8], const uint8_t *data,
+                            size_t num_blocks) {
+  BCM_sha256_transform_blocks(state, data, num_blocks);
+}
diff --git a/gen/sources.bzl b/gen/sources.bzl
index 4337039..dce527b 100644
--- a/gen/sources.bzl
+++ b/gen/sources.bzl
@@ -398,6 +398,7 @@
     "crypto/rsa_extra/rsa_crypt.c",
     "crypto/rsa_extra/rsa_print.c",
     "crypto/sha/sha1.c",
+    "crypto/sha/sha256.c",
     "crypto/siphash/siphash.c",
     "crypto/slhdsa/fors.c",
     "crypto/slhdsa/merkle.c",
diff --git a/gen/sources.cmake b/gen/sources.cmake
index 1202372..cf8d5f9 100644
--- a/gen/sources.cmake
+++ b/gen/sources.cmake
@@ -412,6 +412,7 @@
   crypto/rsa_extra/rsa_crypt.c
   crypto/rsa_extra/rsa_print.c
   crypto/sha/sha1.c
+  crypto/sha/sha256.c
   crypto/siphash/siphash.c
   crypto/slhdsa/fors.c
   crypto/slhdsa/merkle.c
diff --git a/gen/sources.gni b/gen/sources.gni
index e83637f..41b4cc1 100644
--- a/gen/sources.gni
+++ b/gen/sources.gni
@@ -398,6 +398,7 @@
   "crypto/rsa_extra/rsa_crypt.c",
   "crypto/rsa_extra/rsa_print.c",
   "crypto/sha/sha1.c",
+  "crypto/sha/sha256.c",
   "crypto/siphash/siphash.c",
   "crypto/slhdsa/fors.c",
   "crypto/slhdsa/merkle.c",
diff --git a/gen/sources.json b/gen/sources.json
index 908debb..ec5a7e7 100644
--- a/gen/sources.json
+++ b/gen/sources.json
@@ -382,6 +382,7 @@
       "crypto/rsa_extra/rsa_crypt.c",
       "crypto/rsa_extra/rsa_print.c",
       "crypto/sha/sha1.c",
+      "crypto/sha/sha256.c",
       "crypto/siphash/siphash.c",
       "crypto/slhdsa/fors.c",
       "crypto/slhdsa/merkle.c",
diff --git a/include/openssl/bcm_public.h b/include/openssl/bcm_public.h
index f3797df..9bb0dbb 100644
--- a/include/openssl/bcm_public.h
+++ b/include/openssl/bcm_public.h
@@ -53,6 +53,17 @@
   unsigned num;
 };
 
+// SHA256_CBLOCK is the block size of SHA-256.
+#define BCM_SHA256_CBLOCK 64
+
+// SHA256_CTX
+struct sha256_state_st {
+  uint32_t h[8];
+  uint32_t Nl, Nh;
+  uint8_t data[BCM_SHA256_CBLOCK];
+  unsigned num, md_len;
+};
+
 
 #if defined(__cplusplus)
 }  // extern C
diff --git a/include/openssl/sha.h b/include/openssl/sha.h
index 65a996c..bfaeb78 100644
--- a/include/openssl/sha.h
+++ b/include/openssl/sha.h
@@ -130,7 +130,7 @@
 
 // SHA224_Final adds the final padding to |sha| and writes the resulting digest
 // to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It
-// returns one on success and zero on programmer error.
+// returns 1.
 OPENSSL_EXPORT int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH],
                                 SHA256_CTX *sha);
 
@@ -181,14 +181,6 @@
                                            const uint8_t *data,
                                            size_t num_blocks);
 
-struct sha256_state_st {
-  uint32_t h[8];
-  uint32_t Nl, Nh;
-  uint8_t data[SHA256_CBLOCK];
-  unsigned num, md_len;
-};
-
-
 // SHA-384.
 
 // SHA384_CBLOCK is the block size of SHA-384.