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

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