Blame SOURCES/0041-semodule-add-m-checksum-option.patch

30e25f
From e748832819b781507903838483376d308c90ca79 Mon Sep 17 00:00:00 2001
30e25f
From: Petr Lautrbach <plautrba@redhat.com>
30e25f
Date: Tue, 16 Nov 2021 14:27:11 +0100
30e25f
Subject: [PATCH] semodule: add -m | --checksum option
30e25f
30e25f
Since cil doesn't store module name and module version in module itself,
30e25f
there's no simple way how to compare that installed module is the same
30e25f
version as the module which is supposed to be installed. Even though the
30e25f
version was not used by semodule itself, it was apparently used by some
30e25f
team.
30e25f
30e25f
With `semodule -l --checksum` users get SHA256 hashes of modules and
30e25f
could compare them with their files which is faster than installing
30e25f
modules again and again.
30e25f
30e25f
E.g.
30e25f
30e25f
    # time (
30e25f
    semodule -l --checksum | grep localmodule
30e25f
    /usr/libexec/selinux/hll/pp localmodule.pp | sha256sum
30e25f
    )
30e25f
    localmodule db002f64ddfa3983257b42b54da7b182c9b2e476f47880ae3494f9099e1a42bd
30e25f
    db002f64ddfa3983257b42b54da7b182c9b2e476f47880ae3494f9099e1a42bd  -
30e25f
30e25f
    real    0m0.876s
30e25f
    user    0m0.849s
30e25f
    sys     0m0.028s
30e25f
30e25f
vs
30e25f
30e25f
    # time semodule -i localmodule.pp
30e25f
30e25f
    real    0m6.147s
30e25f
    user    0m5.800s
30e25f
    sys     0m0.231s
30e25f
30e25f
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
30e25f
Acked-by: James Carter <jwcart2@gmail.com>
30e25f
---
30e25f
 policycoreutils/semodule/Makefile   |   2 +-
30e25f
 policycoreutils/semodule/semodule.8 |   6 +
30e25f
 policycoreutils/semodule/semodule.c |  95 ++++++++-
30e25f
 policycoreutils/semodule/sha256.c   | 294 ++++++++++++++++++++++++++++
30e25f
 policycoreutils/semodule/sha256.h   |  89 +++++++++
30e25f
 5 files changed, 480 insertions(+), 6 deletions(-)
30e25f
 create mode 100644 policycoreutils/semodule/sha256.c
30e25f
 create mode 100644 policycoreutils/semodule/sha256.h
30e25f
30e25f
diff --git a/policycoreutils/semodule/Makefile b/policycoreutils/semodule/Makefile
30e25f
index 73801e487a76..9875ac383280 100644
30e25f
--- a/policycoreutils/semodule/Makefile
30e25f
+++ b/policycoreutils/semodule/Makefile
30e25f
@@ -6,7 +6,7 @@ MANDIR = $(PREFIX)/share/man
30e25f
 
30e25f
 CFLAGS ?= -Werror -Wall -W
30e25f
 override LDLIBS += -lsepol -lselinux -lsemanage
30e25f
-SEMODULE_OBJS = semodule.o
30e25f
+SEMODULE_OBJS = semodule.o sha256.o
30e25f
 
30e25f
 all: semodule genhomedircon
30e25f
 
30e25f
diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
30e25f
index 18d4f708661c..3a2fb21c2481 100644
30e25f
--- a/policycoreutils/semodule/semodule.8
30e25f
+++ b/policycoreutils/semodule/semodule.8
30e25f
@@ -95,6 +95,9 @@ only modules listed in \-\-extract after this option.
30e25f
 .B  \-H,\-\-hll
30e25f
 Extract module as an HLL file. This only affects the \-\-extract option and
30e25f
 only modules listed in \-\-extract after this option.
30e25f
+.TP
30e25f
+.B  \-m,\-\-checksum
30e25f
+Add SHA256 checksum of modules to the list output.
30e25f
 
30e25f
 .SH EXAMPLE
30e25f
 .nf
30e25f
@@ -130,6 +133,9 @@ $ semodule \-B \-S "/tmp/var/lib/selinux"
30e25f
 # Write the HLL version of puppet and the CIL version of wireshark
30e25f
 # modules at priority 400 to the current working directory
30e25f
 $ semodule \-X 400 \-\-hll \-E puppet \-\-cil \-E wireshark
30e25f
+# Check whether a module in "localmodule.pp" file is same as installed module "localmodule"
30e25f
+$ /usr/libexec/selinux/hll/pp localmodule.pp | sha256sum
30e25f
+$ semodule -l -m | grep localmodule
30e25f
 .fi
30e25f
 
30e25f
 .SH SEE ALSO
30e25f
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
30e25f
index a76797f505cd..300a97d735cc 100644
30e25f
--- a/policycoreutils/semodule/semodule.c
30e25f
+++ b/policycoreutils/semodule/semodule.c
30e25f
@@ -24,6 +24,8 @@
30e25f
 
30e25f
 #include <semanage/modules.h>
30e25f
 
30e25f
+#include "sha256.h"
30e25f
+
30e25f
 enum client_modes {
30e25f
 	NO_MODE, INSTALL_M, REMOVE_M, EXTRACT_M, CIL_M, HLL_M,
30e25f
 	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M
30e25f
@@ -56,6 +58,7 @@ static semanage_handle_t *sh = NULL;
30e25f
 static char *store;
30e25f
 static char *store_root;
30e25f
 int extract_cil = 0;
30e25f
+static int checksum = 0;
30e25f
 
30e25f
 extern char *optarg;
30e25f
 extern int optind;
30e25f
@@ -146,6 +149,7 @@ static void usage(char *progname)
30e25f
 	printf("  -S,--store-path  use an alternate path for the policy store root\n");
30e25f
 	printf("  -c, --cil extract module as cil. This only affects module extraction.\n");
30e25f
 	printf("  -H, --hll extract module as hll. This only affects module extraction.\n");
30e25f
+	printf("  -m, --checksum   print module checksum (SHA256).\n");
30e25f
 }
30e25f
 
30e25f
 /* Sets the global mode variable to new_mode, but only if no other
30e25f
@@ -199,6 +203,7 @@ static void parse_command_line(int argc, char **argv)
30e25f
 		{"disable", required_argument, NULL, 'd'},
30e25f
 		{"path", required_argument, NULL, 'p'},
30e25f
 		{"store-path", required_argument, NULL, 'S'},
30e25f
+		{"checksum", 0, NULL, 'm'},
30e25f
 		{NULL, 0, NULL, 0}
30e25f
 	};
30e25f
 	int extract_selected = 0;
30e25f
@@ -209,7 +214,7 @@ static void parse_command_line(int argc, char **argv)
30e25f
 	no_reload = 0;
30e25f
 	priority = 400;
30e25f
 	while ((i =
30e25f
-		getopt_long(argc, argv, "s:b:hi:l::vr:u:RnNBDCPX:e:d:p:S:E:cH", opts,
30e25f
+		getopt_long(argc, argv, "s:b:hi:l::vr:u:RnNBDCPX:e:d:p:S:E:cHm", opts,
30e25f
 			    NULL)) != -1) {
30e25f
 		switch (i) {
30e25f
 		case 'b':
30e25f
@@ -286,6 +291,9 @@ static void parse_command_line(int argc, char **argv)
30e25f
 		case 'd':
30e25f
 			set_mode(DISABLE_M, optarg);
30e25f
 			break;
30e25f
+		case 'm':
30e25f
+			checksum = 1;
30e25f
+			break;
30e25f
 		case '?':
30e25f
 		default:{
30e25f
 				usage(argv[0]);
30e25f
@@ -337,6 +345,61 @@ static void parse_command_line(int argc, char **argv)
30e25f
 	}
30e25f
 }
30e25f
 
30e25f
+/* Get module checksum */
30e25f
+static char *hash_module_data(const char *module_name, const int prio) {
30e25f
+	semanage_module_info_t *extract_info = NULL;
30e25f
+	semanage_module_key_t *modkey = NULL;
30e25f
+	Sha256Context context;
30e25f
+	uint8_t sha256_hash[SHA256_HASH_SIZE];
30e25f
+	char *sha256_buf = NULL;
30e25f
+	void *data;
30e25f
+	size_t data_len = 0, i;
30e25f
+	int result;
30e25f
+
30e25f
+	result = semanage_module_key_create(sh, &modkey);
30e25f
+	if (result != 0) {
30e25f
+		goto cleanup_extract;
30e25f
+	}
30e25f
+
30e25f
+	result = semanage_module_key_set_name(sh, modkey, module_name);
30e25f
+	if (result != 0) {
30e25f
+		goto cleanup_extract;
30e25f
+	}
30e25f
+
30e25f
+	result = semanage_module_key_set_priority(sh, modkey, prio);
30e25f
+	if (result != 0) {
30e25f
+		goto cleanup_extract;
30e25f
+	}
30e25f
+
30e25f
+	result = semanage_module_extract(sh, modkey, 1, &data, &data_len,
30e25f
+									 &extract_info);
30e25f
+	if (result != 0) {
30e25f
+		goto cleanup_extract;
30e25f
+	}
30e25f
+
30e25f
+	Sha256Initialise(&context);
30e25f
+	Sha256Update(&context, data, data_len);
30e25f
+
30e25f
+	Sha256Finalise(&context, (SHA256_HASH *)sha256_hash);
30e25f
+
30e25f
+	sha256_buf = calloc(1, SHA256_HASH_SIZE * 2 + 1);
30e25f
+
30e25f
+	if (sha256_buf == NULL)
30e25f
+		goto cleanup_extract;
30e25f
+
30e25f
+	for (i = 0; i < SHA256_HASH_SIZE; i++) {
30e25f
+		sprintf((&sha256_buf[i * 2]), "%02x", sha256_hash[i]);
30e25f
+	}
30e25f
+	sha256_buf[i * 2] = 0;
30e25f
+
30e25f
+cleanup_extract:
30e25f
+	semanage_module_info_destroy(sh, extract_info);
30e25f
+	free(extract_info);
30e25f
+	semanage_module_key_destroy(sh, modkey);
30e25f
+	free(modkey);
30e25f
+	return sha256_buf;
30e25f
+}
30e25f
+
30e25f
 int main(int argc, char *argv[])
30e25f
 {
30e25f
 	int i, commit = 0;
30e25f
@@ -544,6 +607,8 @@ cleanup_extract:
30e25f
 				int modinfos_len = 0;
30e25f
 				semanage_module_info_t *m = NULL;
30e25f
 				int j = 0;
30e25f
+				char *module_checksum = NULL;
30e25f
+				uint16_t pri = 0;
30e25f
 
30e25f
 				if (verbose) {
30e25f
 					printf
30e25f
@@ -568,7 +633,18 @@ cleanup_extract:
30e25f
 						result = semanage_module_info_get_name(sh, m, &name);
30e25f
 						if (result != 0) goto cleanup_list;
30e25f
 
30e25f
-						printf("%s\n", name);
30e25f
+						result = semanage_module_info_get_priority(sh, m, &pri);
30e25f
+						if (result != 0) goto cleanup_list;
30e25f
+
30e25f
+						printf("%s", name);
30e25f
+						if (checksum) {
30e25f
+							module_checksum = hash_module_data(name, pri);
30e25f
+							if (module_checksum) {
30e25f
+								printf(" %s", module_checksum);
30e25f
+								free(module_checksum);
30e25f
+							}
30e25f
+						}
30e25f
+						printf("\n");
30e25f
 					}
30e25f
 				}
30e25f
 				else if (strcmp(mode_arg, "full") == 0) {
30e25f
@@ -583,11 +659,12 @@ cleanup_extract:
30e25f
 					}
30e25f
 
30e25f
 					/* calculate column widths */
30e25f
-					size_t column[4] = { 0, 0, 0, 0 };
30e25f
+					size_t column[5] = { 0, 0, 0, 0, 0 };
30e25f
 
30e25f
 					/* fixed width columns */
30e25f
 					column[0] = sizeof("000") - 1;
30e25f
 					column[3] = sizeof("disabled") - 1;
30e25f
+					column[4] = 64; /* SHA256_HASH_SIZE * 2 */
30e25f
 
30e25f
 					/* variable width columns */
30e25f
 					const char *tmp = NULL;
30e25f
@@ -610,7 +687,6 @@ cleanup_extract:
30e25f
 
30e25f
 					/* print out each module */
30e25f
 					for (j = 0; j < modinfos_len; j++) {
30e25f
-						uint16_t pri = 0;
30e25f
 						const char *name = NULL;
30e25f
 						int enabled = 0;
30e25f
 						const char *lang_ext = NULL;
30e25f
@@ -629,11 +705,20 @@ cleanup_extract:
30e25f
 						result = semanage_module_info_get_lang_ext(sh, m, &lang_ext);
30e25f
 						if (result != 0) goto cleanup_list;
30e25f
 
30e25f
-						printf("%0*u %-*s %-*s %-*s\n",
30e25f
+						printf("%0*u %-*s %-*s %-*s",
30e25f
 							(int)column[0], pri,
30e25f
 							(int)column[1], name,
30e25f
 							(int)column[2], lang_ext,
30e25f
 							(int)column[3], enabled ? "" : "disabled");
30e25f
+						if (checksum) {
30e25f
+							module_checksum = hash_module_data(name, pri);
30e25f
+							if (module_checksum) {
30e25f
+								printf(" %-*s", (int)column[4], module_checksum);
30e25f
+								free(module_checksum);
30e25f
+							}
30e25f
+						}
30e25f
+						printf("\n");
30e25f
+
30e25f
 					}
30e25f
 				}
30e25f
 				else {
30e25f
diff --git a/policycoreutils/semodule/sha256.c b/policycoreutils/semodule/sha256.c
30e25f
new file mode 100644
30e25f
index 000000000000..fe2aeef07f53
30e25f
--- /dev/null
30e25f
+++ b/policycoreutils/semodule/sha256.c
30e25f
@@ -0,0 +1,294 @@
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  WjCryptLib_Sha256
30e25f
+//
30e25f
+//  Implementation of SHA256 hash function.
30e25f
+//  Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
30e25f
+//  Modified by WaterJuice retaining Public Domain license.
30e25f
+//
30e25f
+//  This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  IMPORTS
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+#include "sha256.h"
30e25f
+#include <memory.h>
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  MACROS
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
30e25f
+
30e25f
+#define MIN(x, y) ( ((x)<(y))?(x):(y) )
30e25f
+
30e25f
+#define STORE32H(x, y)                                                                     \
30e25f
+     { (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255);   \
30e25f
+       (y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); }
30e25f
+
30e25f
+#define LOAD32H(x, y)                            \
30e25f
+     { x = ((uint32_t)((y)[0] & 255)<<24) | \
30e25f
+           ((uint32_t)((y)[1] & 255)<<16) | \
30e25f
+           ((uint32_t)((y)[2] & 255)<<8)  | \
30e25f
+           ((uint32_t)((y)[3] & 255)); }
30e25f
+
30e25f
+#define STORE64H(x, y)                                                                     \
30e25f
+   { (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255);     \
30e25f
+     (y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255);     \
30e25f
+     (y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255);     \
30e25f
+     (y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); }
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  CONSTANTS
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+// The K array
30e25f
+static const uint32_t K[64] = {
30e25f
+    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
30e25f
+    0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
30e25f
+    0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
30e25f
+    0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
30e25f
+    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
30e25f
+    0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
30e25f
+    0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
30e25f
+    0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
30e25f
+    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
30e25f
+    0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
30e25f
+    0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
30e25f
+    0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
30e25f
+    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
30e25f
+};
30e25f
+
30e25f
+#define BLOCK_SIZE          64
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  INTERNAL FUNCTIONS
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+// Various logical functions
30e25f
+#define Ch( x, y, z )     (z ^ (x & (y ^ z)))
30e25f
+#define Maj( x, y, z )    (((x | y) & z) | (x & y))
30e25f
+#define S( x, n )         ror((x),(n))
30e25f
+#define R( x, n )         (((x)&0xFFFFFFFFUL)>>(n))
30e25f
+#define Sigma0( x )       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
30e25f
+#define Sigma1( x )       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
30e25f
+#define Gamma0( x )       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
30e25f
+#define Gamma1( x )       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
30e25f
+
30e25f
+#define Sha256Round( a, b, c, d, e, f, g, h, i )       \
30e25f
+     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
30e25f
+     t1 = Sigma0(a) + Maj(a, b, c);                    \
30e25f
+     d += t0;                                          \
30e25f
+     h  = t0 + t1;
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  TransformFunction
30e25f
+//
30e25f
+//  Compress 512-bits
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+static
30e25f
+void
30e25f
+    TransformFunction
30e25f
+    (
30e25f
+        Sha256Context*      Context,
30e25f
+        uint8_t const*      Buffer
30e25f
+    )
30e25f
+{
30e25f
+    uint32_t    S[8];
30e25f
+    uint32_t    W[64];
30e25f
+    uint32_t    t0;
30e25f
+    uint32_t    t1;
30e25f
+    uint32_t    t;
30e25f
+    int         i;
30e25f
+
30e25f
+    // Copy state into S
30e25f
+    for( i=0; i<8; i++ )
30e25f
+    {
30e25f
+        S[i] = Context->state[i];
30e25f
+    }
30e25f
+
30e25f
+    // Copy the state into 512-bits into W[0..15]
30e25f
+    for( i=0; i<16; i++ )
30e25f
+    {
30e25f
+        LOAD32H( W[i], Buffer + (4*i) );
30e25f
+    }
30e25f
+
30e25f
+    // Fill W[16..63]
30e25f
+    for( i=16; i<64; i++ )
30e25f
+    {
30e25f
+        W[i] = Gamma1( W[i-2]) + W[i-7] + Gamma0( W[i-15] ) + W[i-16];
30e25f
+    }
30e25f
+
30e25f
+    // Compress
30e25f
+    for( i=0; i<64; i++ )
30e25f
+    {
30e25f
+        Sha256Round( S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i );
30e25f
+        t = S[7];
30e25f
+        S[7] = S[6];
30e25f
+        S[6] = S[5];
30e25f
+        S[5] = S[4];
30e25f
+        S[4] = S[3];
30e25f
+        S[3] = S[2];
30e25f
+        S[2] = S[1];
30e25f
+        S[1] = S[0];
30e25f
+        S[0] = t;
30e25f
+    }
30e25f
+
30e25f
+    // Feedback
30e25f
+    for( i=0; i<8; i++ )
30e25f
+    {
30e25f
+        Context->state[i] = Context->state[i] + S[i];
30e25f
+    }
30e25f
+}
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  PUBLIC FUNCTIONS
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  Sha256Initialise
30e25f
+//
30e25f
+//  Initialises a SHA256 Context. Use this to initialise/reset a context.
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+void
30e25f
+    Sha256Initialise
30e25f
+    (
30e25f
+        Sha256Context*      Context         // [out]
30e25f
+    )
30e25f
+{
30e25f
+    Context->curlen = 0;
30e25f
+    Context->length = 0;
30e25f
+    Context->state[0] = 0x6A09E667UL;
30e25f
+    Context->state[1] = 0xBB67AE85UL;
30e25f
+    Context->state[2] = 0x3C6EF372UL;
30e25f
+    Context->state[3] = 0xA54FF53AUL;
30e25f
+    Context->state[4] = 0x510E527FUL;
30e25f
+    Context->state[5] = 0x9B05688CUL;
30e25f
+    Context->state[6] = 0x1F83D9ABUL;
30e25f
+    Context->state[7] = 0x5BE0CD19UL;
30e25f
+}
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  Sha256Update
30e25f
+//
30e25f
+//  Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
30e25f
+//  calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+void
30e25f
+    Sha256Update
30e25f
+    (
30e25f
+        Sha256Context*      Context,        // [in out]
30e25f
+        void const*         Buffer,         // [in]
30e25f
+        uint32_t            BufferSize      // [in]
30e25f
+    )
30e25f
+{
30e25f
+    uint32_t n;
30e25f
+
30e25f
+    if( Context->curlen > sizeof(Context->buf) )
30e25f
+    {
30e25f
+       return;
30e25f
+    }
30e25f
+
30e25f
+    while( BufferSize > 0 )
30e25f
+    {
30e25f
+        if( Context->curlen == 0 && BufferSize >= BLOCK_SIZE )
30e25f
+        {
30e25f
+           TransformFunction( Context, (uint8_t*)Buffer );
30e25f
+           Context->length += BLOCK_SIZE * 8;
30e25f
+           Buffer = (uint8_t*)Buffer + BLOCK_SIZE;
30e25f
+           BufferSize -= BLOCK_SIZE;
30e25f
+        }
30e25f
+        else
30e25f
+        {
30e25f
+           n = MIN( BufferSize, (BLOCK_SIZE - Context->curlen) );
30e25f
+           memcpy( Context->buf + Context->curlen, Buffer, (size_t)n );
30e25f
+           Context->curlen += n;
30e25f
+           Buffer = (uint8_t*)Buffer + n;
30e25f
+           BufferSize -= n;
30e25f
+           if( Context->curlen == BLOCK_SIZE )
30e25f
+           {
30e25f
+              TransformFunction( Context, Context->buf );
30e25f
+              Context->length += 8*BLOCK_SIZE;
30e25f
+              Context->curlen = 0;
30e25f
+           }
30e25f
+       }
30e25f
+    }
30e25f
+}
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  Sha256Finalise
30e25f
+//
30e25f
+//  Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After
30e25f
+//  calling this, Sha256Initialised must be used to reuse the context.
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+void
30e25f
+    Sha256Finalise
30e25f
+    (
30e25f
+        Sha256Context*      Context,        // [in out]
30e25f
+        SHA256_HASH*        Digest          // [out]
30e25f
+    )
30e25f
+{
30e25f
+    int i;
30e25f
+
30e25f
+    if( Context->curlen >= sizeof(Context->buf) )
30e25f
+    {
30e25f
+       return;
30e25f
+    }
30e25f
+
30e25f
+    // Increase the length of the message
30e25f
+    Context->length += Context->curlen * 8;
30e25f
+
30e25f
+    // Append the '1' bit
30e25f
+    Context->buf[Context->curlen++] = (uint8_t)0x80;
30e25f
+
30e25f
+    // if the length is currently above 56 bytes we append zeros
30e25f
+    // then compress.  Then we can fall back to padding zeros and length
30e25f
+    // encoding like normal.
30e25f
+    if( Context->curlen > 56 )
30e25f
+    {
30e25f
+        while( Context->curlen < 64 )
30e25f
+        {
30e25f
+            Context->buf[Context->curlen++] = (uint8_t)0;
30e25f
+        }
30e25f
+        TransformFunction(Context, Context->buf);
30e25f
+        Context->curlen = 0;
30e25f
+    }
30e25f
+
30e25f
+    // Pad up to 56 bytes of zeroes
30e25f
+    while( Context->curlen < 56 )
30e25f
+    {
30e25f
+        Context->buf[Context->curlen++] = (uint8_t)0;
30e25f
+    }
30e25f
+
30e25f
+    // Store length
30e25f
+    STORE64H( Context->length, Context->buf+56 );
30e25f
+    TransformFunction( Context, Context->buf );
30e25f
+
30e25f
+    // Copy output
30e25f
+    for( i=0; i<8; i++ )
30e25f
+    {
30e25f
+        STORE32H( Context->state[i], Digest->bytes+(4*i) );
30e25f
+    }
30e25f
+}
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  Sha256Calculate
30e25f
+//
30e25f
+//  Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the
30e25f
+//  buffer.
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+void
30e25f
+    Sha256Calculate
30e25f
+    (
30e25f
+        void  const*        Buffer,         // [in]
30e25f
+        uint32_t            BufferSize,     // [in]
30e25f
+        SHA256_HASH*        Digest          // [in]
30e25f
+    )
30e25f
+{
30e25f
+    Sha256Context context;
30e25f
+
30e25f
+    Sha256Initialise( &context );
30e25f
+    Sha256Update( &context, Buffer, BufferSize );
30e25f
+    Sha256Finalise( &context, Digest );
30e25f
+}
30e25f
diff --git a/policycoreutils/semodule/sha256.h b/policycoreutils/semodule/sha256.h
30e25f
new file mode 100644
30e25f
index 000000000000..406ed869cd82
30e25f
--- /dev/null
30e25f
+++ b/policycoreutils/semodule/sha256.h
30e25f
@@ -0,0 +1,89 @@
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  WjCryptLib_Sha256
30e25f
+//
30e25f
+//  Implementation of SHA256 hash function.
30e25f
+//  Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
30e25f
+//  Modified by WaterJuice retaining Public Domain license.
30e25f
+//
30e25f
+//  This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+#pragma once
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  IMPORTS
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+#include <stdint.h>
30e25f
+#include <stdio.h>
30e25f
+
30e25f
+typedef struct
30e25f
+{
30e25f
+    uint64_t    length;
30e25f
+    uint32_t    state[8];
30e25f
+    uint32_t    curlen;
30e25f
+    uint8_t     buf[64];
30e25f
+} Sha256Context;
30e25f
+
30e25f
+#define SHA256_HASH_SIZE           ( 256 / 8 )
30e25f
+
30e25f
+typedef struct
30e25f
+{
30e25f
+    uint8_t      bytes [SHA256_HASH_SIZE];
30e25f
+} SHA256_HASH;
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  PUBLIC FUNCTIONS
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  Sha256Initialise
30e25f
+//
30e25f
+//  Initialises a SHA256 Context. Use this to initialise/reset a context.
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+void
30e25f
+    Sha256Initialise
30e25f
+    (
30e25f
+        Sha256Context*      Context         // [out]
30e25f
+    );
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  Sha256Update
30e25f
+//
30e25f
+//  Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
30e25f
+//  calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+void
30e25f
+    Sha256Update
30e25f
+    (
30e25f
+        Sha256Context*      Context,        // [in out]
30e25f
+        void const*         Buffer,         // [in]
30e25f
+        uint32_t            BufferSize      // [in]
30e25f
+    );
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  Sha256Finalise
30e25f
+//
30e25f
+//  Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After
30e25f
+//  calling this, Sha256Initialised must be used to reuse the context.
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+void
30e25f
+    Sha256Finalise
30e25f
+    (
30e25f
+        Sha256Context*      Context,        // [in out]
30e25f
+        SHA256_HASH*        Digest          // [out]
30e25f
+    );
30e25f
+
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+//  Sha256Calculate
30e25f
+//
30e25f
+//  Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the
30e25f
+//  buffer.
30e25f
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30e25f
+void
30e25f
+    Sha256Calculate
30e25f
+    (
30e25f
+        void  const*        Buffer,         // [in]
30e25f
+        uint32_t            BufferSize,     // [in]
30e25f
+        SHA256_HASH*        Digest          // [in]
30e25f
+    );
30e25f
-- 
30e25f
2.33.1
30e25f