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