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

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