Blame SOURCES/0003-semodule-libsemanage-move-module-hashing-into-libsem.patch

60e324
From f77f2b70930c628b362320cbfe07833032ae9b0f Mon Sep 17 00:00:00 2001
60e324
From: Ondrej Mosnacek <omosnace@redhat.com>
60e324
Date: Thu, 3 Feb 2022 17:53:23 +0100
60e324
Subject: [PATCH] semodule,libsemanage: move module hashing into libsemanage
60e324
60e324
The main goal of this move is to have the SHA-256 implementation under
60e324
libsemanage, since upcoming patches will make use of SHA-256 for a
60e324
different (but similar) purpose in libsemanage. Having the hashing code
60e324
in libsemanage will reduce code duplication and allow for easier hash
60e324
algorithm upgrade in the future.
60e324
60e324
Note that libselinux currently also contains a hash function
60e324
implementation (for yet another different purpose). This patch doesn't
60e324
make any effort to address that duplicity yet.
60e324
60e324
This patch also changes the format of the hash string printed by
60e324
semodule to include the name of the hash. The intent is to avoid
60e324
ambiguity and potential collisions when the algorithm is potentially
60e324
changed in the future.
60e324
60e324
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
60e324
---
60e324
 libsemanage/include/semanage/modules.h        |  26 ++
60e324
 libsemanage/src/libsemanage.map               |   4 +
60e324
 libsemanage/src/modules.c                     |  59 ++++
60e324
 .../src/semanageswig_python_exception.i       |   8 +
60e324
 libsemanage/src/sha256.c                      | 294 ++++++++++++++++++
60e324
 libsemanage/src/sha256.h                      |  89 ++++++
60e324
 6 files changed, 480 insertions(+)
60e324
 create mode 100644 libsemanage/src/sha256.c
60e324
 create mode 100644 libsemanage/src/sha256.h
60e324
60e324
diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h
60e324
index b51f61f033d5..14666f6dbe00 100644
60e324
--- a/libsemanage/include/semanage/modules.h
60e324
+++ b/libsemanage/include/semanage/modules.h
60e324
@@ -282,4 +282,30 @@ extern int semanage_module_get_enabled(semanage_handle_t *sh,
60e324
 				       const semanage_module_key_t *modkey,
60e324
 				       int *enabled);
60e324
 
60e324
+/* Compute checksum for @modkey module contents.
60e324
+ *
60e324
+ * If @checksum is NULL, the function will just return the length of the
60e324
+ * checksum string in @checksum_len (checksum strings are guaranteed to
60e324
+ * have a fixed length for a given libsemanage binary). @modkey and @cil
60e324
+ * are ignored in this case and should be set to NULL and 0 (respectively).
60e324
+ *
60e324
+ * If @checksum is non-NULL, on success, @checksum will point to a buffer
60e324
+ * containing the checksum string and @checksum_len will point to the
60e324
+ * length of the string (without the null terminator). The semantics of
60e324
+ * @cil are the same as for @extract_cil in semanage_module_extract().
60e324
+ *
60e324
+ * The caller is responsible to free the buffer returned in @checksum (using
60e324
+ * free(3)).
60e324
+ *
60e324
+ * Callers may assume that if the checksum strings for two modules match,
60e324
+ * the module content is the same (collisions are theoretically possible,
60e324
+ * yet extremely unlikely).
60e324
+ *
60e324
+ * Returns 0 on success and -1 on error.
60e324
+ */
60e324
+extern int semanage_module_compute_checksum(semanage_handle_t *sh,
60e324
+					    semanage_module_key_t *modkey,
60e324
+					    int cil, char **checksum,
60e324
+					    size_t *checksum_len);
60e324
+
60e324
 #endif
60e324
diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
60e324
index 3ea7b60f97bb..00259fc817f5 100644
60e324
--- a/libsemanage/src/libsemanage.map
60e324
+++ b/libsemanage/src/libsemanage.map
60e324
@@ -345,3 +345,7 @@ LIBSEMANAGE_1.1 {
60e324
     semanage_module_remove_key;
60e324
     semanage_set_store_root;
60e324
 } LIBSEMANAGE_1.0;
60e324
+
60e324
+LIBSEMANAGE_3.4 {
60e324
+    semanage_module_compute_checksum;
60e324
+} LIBSEMANAGE_1.1;
60e324
diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
60e324
index b6dd456cac32..5dbb28fdbaa5 100644
60e324
--- a/libsemanage/src/modules.c
60e324
+++ b/libsemanage/src/modules.c
60e324
@@ -35,11 +35,13 @@
60e324
 #include <fcntl.h>
60e324
 #include <sys/types.h>
60e324
 #include <sys/stat.h>
60e324
+#include <sys/mman.h>
60e324
 #include <errno.h>
60e324
 #include <ctype.h>
60e324
 
60e324
 #include "handle.h"
60e324
 #include "modules.h"
60e324
+#include "sha256.h"
60e324
 #include "debug.h"
60e324
 
60e324
 int semanage_module_install(semanage_handle_t * sh,
60e324
@@ -975,3 +977,60 @@ int semanage_module_remove_key(semanage_handle_t *sh,
60e324
 	return sh->funcs->remove_key(sh, modkey);
60e324
 }
60e324
 
60e324
+static const char CHECKSUM_TYPE[] = "sha256";
60e324
+static const size_t CHECKSUM_CONTENT_SIZE = sizeof(CHECKSUM_TYPE) + 1 + 2 * SHA256_HASH_SIZE;
60e324
+
60e324
+static void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum)
60e324
+{
60e324
+	size_t i;
60e324
+
60e324
+	checksum += sprintf(checksum, "%s:", CHECKSUM_TYPE);
60e324
+	for (i = 0; i < SHA256_HASH_SIZE; i++) {
60e324
+		checksum += sprintf(checksum, "%02x", (unsigned)hash[i]);
60e324
+	}
60e324
+}
60e324
+
60e324
+int semanage_module_compute_checksum(semanage_handle_t *sh,
60e324
+				     semanage_module_key_t *modkey,
60e324
+				     int cil, char **checksum,
60e324
+				     size_t *checksum_len)
60e324
+{
60e324
+	semanage_module_info_t *extract_info = NULL;
60e324
+	Sha256Context context;
60e324
+	SHA256_HASH sha256_hash;
60e324
+	char *checksum_str;
60e324
+	void *data;
60e324
+	size_t data_len = 0;
60e324
+	int result;
60e324
+
60e324
+	if (!checksum_len)
60e324
+		return -1;
60e324
+
60e324
+	if (!checksum) {
60e324
+		*checksum_len = CHECKSUM_CONTENT_SIZE;
60e324
+		return 0;
60e324
+	}
60e324
+
60e324
+	result = semanage_module_extract(sh, modkey, cil, &data, &data_len, &extract_info);
60e324
+	if (result != 0)
60e324
+		return -1;
60e324
+
60e324
+	semanage_module_info_destroy(sh, extract_info);
60e324
+	free(extract_info);
60e324
+
60e324
+	Sha256Initialise(&context);
60e324
+	Sha256Update(&context, data, data_len);
60e324
+	Sha256Finalise(&context, &sha256_hash);
60e324
+
60e324
+	munmap(data, data_len);
60e324
+
60e324
+	checksum_str = malloc(CHECKSUM_CONTENT_SIZE + 1 /* '\0' */);
60e324
+	if (!checksum_str)
60e324
+		return -1;
60e324
+
60e324
+	semanage_hash_to_checksum_string(sha256_hash.bytes, checksum_str);
60e324
+
60e324
+	*checksum = checksum_str;
60e324
+	*checksum_len = CHECKSUM_CONTENT_SIZE;
60e324
+	return 0;
60e324
+}
60e324
diff --git a/libsemanage/src/semanageswig_python_exception.i b/libsemanage/src/semanageswig_python_exception.i
60e324
index 372ec948866a..0df8bbc350e2 100644
60e324
--- a/libsemanage/src/semanageswig_python_exception.i
60e324
+++ b/libsemanage/src/semanageswig_python_exception.i
60e324
@@ -351,6 +351,14 @@
60e324
   }
60e324
 }
60e324
 
60e324
+%exception semanage_module_compute_checksum {
60e324
+  $action
60e324
+  if (result < 0) {
60e324
+     PyErr_SetFromErrno(PyExc_OSError);
60e324
+     SWIG_fail;
60e324
+  }
60e324
+}
60e324
+
60e324
 %exception semanage_msg_get_level {
60e324
   $action
60e324
   if (result < 0) {
60e324
diff --git a/libsemanage/src/sha256.c b/libsemanage/src/sha256.c
60e324
new file mode 100644
60e324
index 000000000000..fe2aeef07f53
60e324
--- /dev/null
60e324
+++ b/libsemanage/src/sha256.c
60e324
@@ -0,0 +1,294 @@
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  WjCryptLib_Sha256
60e324
+//
60e324
+//  Implementation of SHA256 hash function.
60e324
+//  Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
60e324
+//  Modified by WaterJuice retaining Public Domain license.
60e324
+//
60e324
+//  This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  IMPORTS
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+#include "sha256.h"
60e324
+#include <memory.h>
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  MACROS
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
60e324
+
60e324
+#define MIN(x, y) ( ((x)<(y))?(x):(y) )
60e324
+
60e324
+#define STORE32H(x, y)                                                                     \
60e324
+     { (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255);   \
60e324
+       (y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); }
60e324
+
60e324
+#define LOAD32H(x, y)                            \
60e324
+     { x = ((uint32_t)((y)[0] & 255)<<24) | \
60e324
+           ((uint32_t)((y)[1] & 255)<<16) | \
60e324
+           ((uint32_t)((y)[2] & 255)<<8)  | \
60e324
+           ((uint32_t)((y)[3] & 255)); }
60e324
+
60e324
+#define STORE64H(x, y)                                                                     \
60e324
+   { (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255);     \
60e324
+     (y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255);     \
60e324
+     (y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255);     \
60e324
+     (y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); }
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  CONSTANTS
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+// The K array
60e324
+static const uint32_t K[64] = {
60e324
+    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
60e324
+    0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
60e324
+    0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
60e324
+    0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
60e324
+    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
60e324
+    0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
60e324
+    0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
60e324
+    0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
60e324
+    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
60e324
+    0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
60e324
+    0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
60e324
+    0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
60e324
+    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
60e324
+};
60e324
+
60e324
+#define BLOCK_SIZE          64
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  INTERNAL FUNCTIONS
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+// Various logical functions
60e324
+#define Ch( x, y, z )     (z ^ (x & (y ^ z)))
60e324
+#define Maj( x, y, z )    (((x | y) & z) | (x & y))
60e324
+#define S( x, n )         ror((x),(n))
60e324
+#define R( x, n )         (((x)&0xFFFFFFFFUL)>>(n))
60e324
+#define Sigma0( x )       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
60e324
+#define Sigma1( x )       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
60e324
+#define Gamma0( x )       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
60e324
+#define Gamma1( x )       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
60e324
+
60e324
+#define Sha256Round( a, b, c, d, e, f, g, h, i )       \
60e324
+     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
60e324
+     t1 = Sigma0(a) + Maj(a, b, c);                    \
60e324
+     d += t0;                                          \
60e324
+     h  = t0 + t1;
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  TransformFunction
60e324
+//
60e324
+//  Compress 512-bits
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+static
60e324
+void
60e324
+    TransformFunction
60e324
+    (
60e324
+        Sha256Context*      Context,
60e324
+        uint8_t const*      Buffer
60e324
+    )
60e324
+{
60e324
+    uint32_t    S[8];
60e324
+    uint32_t    W[64];
60e324
+    uint32_t    t0;
60e324
+    uint32_t    t1;
60e324
+    uint32_t    t;
60e324
+    int         i;
60e324
+
60e324
+    // Copy state into S
60e324
+    for( i=0; i<8; i++ )
60e324
+    {
60e324
+        S[i] = Context->state[i];
60e324
+    }
60e324
+
60e324
+    // Copy the state into 512-bits into W[0..15]
60e324
+    for( i=0; i<16; i++ )
60e324
+    {
60e324
+        LOAD32H( W[i], Buffer + (4*i) );
60e324
+    }
60e324
+
60e324
+    // Fill W[16..63]
60e324
+    for( i=16; i<64; i++ )
60e324
+    {
60e324
+        W[i] = Gamma1( W[i-2]) + W[i-7] + Gamma0( W[i-15] ) + W[i-16];
60e324
+    }
60e324
+
60e324
+    // Compress
60e324
+    for( i=0; i<64; i++ )
60e324
+    {
60e324
+        Sha256Round( S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i );
60e324
+        t = S[7];
60e324
+        S[7] = S[6];
60e324
+        S[6] = S[5];
60e324
+        S[5] = S[4];
60e324
+        S[4] = S[3];
60e324
+        S[3] = S[2];
60e324
+        S[2] = S[1];
60e324
+        S[1] = S[0];
60e324
+        S[0] = t;
60e324
+    }
60e324
+
60e324
+    // Feedback
60e324
+    for( i=0; i<8; i++ )
60e324
+    {
60e324
+        Context->state[i] = Context->state[i] + S[i];
60e324
+    }
60e324
+}
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  PUBLIC FUNCTIONS
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  Sha256Initialise
60e324
+//
60e324
+//  Initialises a SHA256 Context. Use this to initialise/reset a context.
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+void
60e324
+    Sha256Initialise
60e324
+    (
60e324
+        Sha256Context*      Context         // [out]
60e324
+    )
60e324
+{
60e324
+    Context->curlen = 0;
60e324
+    Context->length = 0;
60e324
+    Context->state[0] = 0x6A09E667UL;
60e324
+    Context->state[1] = 0xBB67AE85UL;
60e324
+    Context->state[2] = 0x3C6EF372UL;
60e324
+    Context->state[3] = 0xA54FF53AUL;
60e324
+    Context->state[4] = 0x510E527FUL;
60e324
+    Context->state[5] = 0x9B05688CUL;
60e324
+    Context->state[6] = 0x1F83D9ABUL;
60e324
+    Context->state[7] = 0x5BE0CD19UL;
60e324
+}
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  Sha256Update
60e324
+//
60e324
+//  Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
60e324
+//  calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+void
60e324
+    Sha256Update
60e324
+    (
60e324
+        Sha256Context*      Context,        // [in out]
60e324
+        void const*         Buffer,         // [in]
60e324
+        uint32_t            BufferSize      // [in]
60e324
+    )
60e324
+{
60e324
+    uint32_t n;
60e324
+
60e324
+    if( Context->curlen > sizeof(Context->buf) )
60e324
+    {
60e324
+       return;
60e324
+    }
60e324
+
60e324
+    while( BufferSize > 0 )
60e324
+    {
60e324
+        if( Context->curlen == 0 && BufferSize >= BLOCK_SIZE )
60e324
+        {
60e324
+           TransformFunction( Context, (uint8_t*)Buffer );
60e324
+           Context->length += BLOCK_SIZE * 8;
60e324
+           Buffer = (uint8_t*)Buffer + BLOCK_SIZE;
60e324
+           BufferSize -= BLOCK_SIZE;
60e324
+        }
60e324
+        else
60e324
+        {
60e324
+           n = MIN( BufferSize, (BLOCK_SIZE - Context->curlen) );
60e324
+           memcpy( Context->buf + Context->curlen, Buffer, (size_t)n );
60e324
+           Context->curlen += n;
60e324
+           Buffer = (uint8_t*)Buffer + n;
60e324
+           BufferSize -= n;
60e324
+           if( Context->curlen == BLOCK_SIZE )
60e324
+           {
60e324
+              TransformFunction( Context, Context->buf );
60e324
+              Context->length += 8*BLOCK_SIZE;
60e324
+              Context->curlen = 0;
60e324
+           }
60e324
+       }
60e324
+    }
60e324
+}
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  Sha256Finalise
60e324
+//
60e324
+//  Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After
60e324
+//  calling this, Sha256Initialised must be used to reuse the context.
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+void
60e324
+    Sha256Finalise
60e324
+    (
60e324
+        Sha256Context*      Context,        // [in out]
60e324
+        SHA256_HASH*        Digest          // [out]
60e324
+    )
60e324
+{
60e324
+    int i;
60e324
+
60e324
+    if( Context->curlen >= sizeof(Context->buf) )
60e324
+    {
60e324
+       return;
60e324
+    }
60e324
+
60e324
+    // Increase the length of the message
60e324
+    Context->length += Context->curlen * 8;
60e324
+
60e324
+    // Append the '1' bit
60e324
+    Context->buf[Context->curlen++] = (uint8_t)0x80;
60e324
+
60e324
+    // if the length is currently above 56 bytes we append zeros
60e324
+    // then compress.  Then we can fall back to padding zeros and length
60e324
+    // encoding like normal.
60e324
+    if( Context->curlen > 56 )
60e324
+    {
60e324
+        while( Context->curlen < 64 )
60e324
+        {
60e324
+            Context->buf[Context->curlen++] = (uint8_t)0;
60e324
+        }
60e324
+        TransformFunction(Context, Context->buf);
60e324
+        Context->curlen = 0;
60e324
+    }
60e324
+
60e324
+    // Pad up to 56 bytes of zeroes
60e324
+    while( Context->curlen < 56 )
60e324
+    {
60e324
+        Context->buf[Context->curlen++] = (uint8_t)0;
60e324
+    }
60e324
+
60e324
+    // Store length
60e324
+    STORE64H( Context->length, Context->buf+56 );
60e324
+    TransformFunction( Context, Context->buf );
60e324
+
60e324
+    // Copy output
60e324
+    for( i=0; i<8; i++ )
60e324
+    {
60e324
+        STORE32H( Context->state[i], Digest->bytes+(4*i) );
60e324
+    }
60e324
+}
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  Sha256Calculate
60e324
+//
60e324
+//  Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the
60e324
+//  buffer.
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+void
60e324
+    Sha256Calculate
60e324
+    (
60e324
+        void  const*        Buffer,         // [in]
60e324
+        uint32_t            BufferSize,     // [in]
60e324
+        SHA256_HASH*        Digest          // [in]
60e324
+    )
60e324
+{
60e324
+    Sha256Context context;
60e324
+
60e324
+    Sha256Initialise( &context );
60e324
+    Sha256Update( &context, Buffer, BufferSize );
60e324
+    Sha256Finalise( &context, Digest );
60e324
+}
60e324
diff --git a/libsemanage/src/sha256.h b/libsemanage/src/sha256.h
60e324
new file mode 100644
60e324
index 000000000000..406ed869cd82
60e324
--- /dev/null
60e324
+++ b/libsemanage/src/sha256.h
60e324
@@ -0,0 +1,89 @@
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  WjCryptLib_Sha256
60e324
+//
60e324
+//  Implementation of SHA256 hash function.
60e324
+//  Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
60e324
+//  Modified by WaterJuice retaining Public Domain license.
60e324
+//
60e324
+//  This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+#pragma once
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  IMPORTS
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+#include <stdint.h>
60e324
+#include <stdio.h>
60e324
+
60e324
+typedef struct
60e324
+{
60e324
+    uint64_t    length;
60e324
+    uint32_t    state[8];
60e324
+    uint32_t    curlen;
60e324
+    uint8_t     buf[64];
60e324
+} Sha256Context;
60e324
+
60e324
+#define SHA256_HASH_SIZE           ( 256 / 8 )
60e324
+
60e324
+typedef struct
60e324
+{
60e324
+    uint8_t      bytes [SHA256_HASH_SIZE];
60e324
+} SHA256_HASH;
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  PUBLIC FUNCTIONS
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  Sha256Initialise
60e324
+//
60e324
+//  Initialises a SHA256 Context. Use this to initialise/reset a context.
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+void
60e324
+    Sha256Initialise
60e324
+    (
60e324
+        Sha256Context*      Context         // [out]
60e324
+    );
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  Sha256Update
60e324
+//
60e324
+//  Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
60e324
+//  calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+void
60e324
+    Sha256Update
60e324
+    (
60e324
+        Sha256Context*      Context,        // [in out]
60e324
+        void const*         Buffer,         // [in]
60e324
+        uint32_t            BufferSize      // [in]
60e324
+    );
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  Sha256Finalise
60e324
+//
60e324
+//  Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After
60e324
+//  calling this, Sha256Initialised must be used to reuse the context.
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+void
60e324
+    Sha256Finalise
60e324
+    (
60e324
+        Sha256Context*      Context,        // [in out]
60e324
+        SHA256_HASH*        Digest          // [out]
60e324
+    );
60e324
+
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+//  Sha256Calculate
60e324
+//
60e324
+//  Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the
60e324
+//  buffer.
60e324
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60e324
+void
60e324
+    Sha256Calculate
60e324
+    (
60e324
+        void  const*        Buffer,         // [in]
60e324
+        uint32_t            BufferSize,     // [in]
60e324
+        SHA256_HASH*        Digest          // [in]
60e324
+    );
60e324
-- 
60e324
2.34.1
60e324