From 0f51b4d876d02f21751d1baaa252dc87f14a48ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Fri, 26 Mar 2010 15:31:07 +0100
Subject: [PATCH] * sha.h: Added declarations for sha224. Some are aliases for
 the corresponding sha256 definition.

* sha256.c (sha256_digest): Use _nettle_write_be32.
(sha224_init): New function.
(sha224_digest): New function.

Rev: nettle/sha.h:1.6
Rev: nettle/sha256.c:1.5
---
 sha.h    | 25 +++++++++++++++++++---
 sha256.c | 65 ++++++++++++++++++++++++++++----------------------------
 2 files changed, 55 insertions(+), 35 deletions(-)

diff --git a/sha.h b/sha.h
index 5dbffd7e..41afde4b 100644
--- a/sha.h
+++ b/sha.h
@@ -36,6 +36,8 @@ extern "C" {
 #define sha1_init nettle_sha1_init
 #define sha1_update nettle_sha1_update
 #define sha1_digest nettle_sha1_digest
+#define sha224_init nettle_sha224_init
+#define sha224_digest nettle_sha224_digest
 #define sha256_init nettle_sha256_init
 #define sha256_update nettle_sha256_update
 #define sha256_digest nettle_sha256_digest
@@ -114,6 +116,24 @@ sha256_digest(struct sha256_ctx *ctx,
 void
 _nettle_sha256_compress(uint32_t *state, const uint8_t *data, const uint32_t *k);
 
+
+/* SHA224, a truncated SHA256 with different initial state. */
+
+#define SHA224_DIGEST_SIZE 28
+#define SHA224_DATA_SIZE SHA256_DATA_SIZE
+#define sha224_ctx sha256_ctx
+
+void
+sha224_init(struct sha256_ctx *ctx);
+
+#define sha224_update nettle_sha256_update
+
+void
+sha224_digest(struct sha256_ctx *ctx,
+	      unsigned length,
+	      uint8_t *digest);
+
+
 /* SHA512 */
 
 #define SHA512_DIGEST_SIZE 64
@@ -149,9 +169,8 @@ sha512_digest(struct sha512_ctx *ctx,
 void
 _nettle_sha512_compress(uint64_t *state, const uint8_t *data, const uint64_t *k);
 
-/* SHA384. */
-/* This is the same algorithm as SHA512, but with different initial
-   state and truncated output. */
+
+/* SHA384, a truncated SHA512 with different initial state. */
 
 #define SHA384_DIGEST_SIZE 48
 #define SHA384_DATA_SIZE SHA512_DATA_SIZE
diff --git a/sha256.c b/sha256.c
index 9a3f1bb2..fa4f735b 100644
--- a/sha256.c
+++ b/sha256.c
@@ -38,6 +38,7 @@
 #include "sha.h"
 
 #include "macros.h"
+#include "nettle-write.h"
 
 /* Generated by the shadata program. */
 static const uint32_t
@@ -172,42 +173,42 @@ sha256_digest(struct sha256_ctx *ctx,
 	      unsigned length,
 	      uint8_t *digest)
 {
-  unsigned i;
-  unsigned words;
-  unsigned leftover;
-  
   assert(length <= SHA256_DIGEST_SIZE);
 
   sha256_final(ctx);
+  _nettle_write_be32(length, digest, ctx->state);
+  sha256_init(ctx);
+}
+
+/* sha224 variant. FIXME: Move to seperate file? */
+
+void
+sha224_init(struct sha256_ctx *ctx)
+{
+  /* Initial values. I's unclear how they are chosen. */
+  static const uint32_t H0[_SHA256_DIGEST_LENGTH] =
+  {
+    0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+    0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
+  };
+
+  memcpy(ctx->state, H0, sizeof(H0));
+
+  /* Initialize bit count */
+  ctx->count_low = ctx->count_high = 0;
   
-  words = length / 4;
-  leftover = length % 4;
+  /* Initialize buffer */
+  ctx->index = 0;
+}
 
-  for (i = 0; i < words; i++, digest += 4)
-    WRITE_UINT32(digest, ctx->state[i]);
+void
+sha224_digest(struct sha256_ctx *ctx,
+	      unsigned length,
+	      uint8_t *digest)
+{
+  assert(length <= SHA224_DIGEST_SIZE);
 
-  if (leftover)
-    {
-      uint32_t word;
-      unsigned j = leftover;
-      
-      assert(i < _SHA256_DIGEST_LENGTH);
-      
-      word = ctx->state[i];
-      
-      switch (leftover)
-	{
-	default:
-	  abort();
-	case 3:
-	  digest[--j] = (word >> 8) & 0xff;
-	  /* Fall through */
-	case 2:
-	  digest[--j] = (word >> 16) & 0xff;
-	  /* Fall through */
-	case 1:
-	  digest[--j] = (word >> 24) & 0xff;
-	}
-    }
-  sha256_init(ctx);
+  sha256_final(ctx);
+  _nettle_write_be32(length, digest, ctx->state);
+  sha224_init(ctx);
 }
-- 
GitLab