From 1ce0b18e588e226f4e9dcc3897236ae938b9d4dd Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Wed, 18 Apr 2018 10:03:49 +0200 Subject: [PATCH 1/4] kcapi-hasher: Use consistent lib self-check params Since the various hasher tools use different HMAC parameters (hash, key) and they all need to check the libkcapi library, it is necessary to use a consistent set of parameters for the library itself. This patch changes the behavior to always check the library using the fipscheck hash and key. --- apps/kcapi-hasher.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/kcapi-hasher.c b/apps/kcapi-hasher.c index 480a019..1d76e1d 100644 --- a/apps/kcapi-hasher.c +++ b/apps/kcapi-hasher.c @@ -611,7 +611,8 @@ static int process_checkfile(const struct hash_params *params, } -static int fipscheck_self(const struct hash_params *params, int just_print) +static int fipscheck_self(const struct hash_params *params_bin, + const struct hash_params *params_lib, int just_print) { char *checkfile = NULL; uint32_t n = 0; @@ -668,7 +669,7 @@ static int fipscheck_self(const struct hash_params *params, int just_print) } if (just_print) { - ret = hash_files(params, names, 1, 0, 1); + ret = hash_files(params_bin, names, 1, 0, 1); goto out; } @@ -678,7 +679,7 @@ static int fipscheck_self(const struct hash_params *params, int just_print) goto out; } - ret = process_checkfile(params, checkfile, selfname, CHK_STATUS); + ret = process_checkfile(params_bin, checkfile, selfname, CHK_STATUS); if (ret) goto out; @@ -710,7 +711,7 @@ static int fipscheck_self(const struct hash_params *params, int just_print) goto out; } - ret = process_checkfile(params, checkfile, selfname, CHK_STATUS); + ret = process_checkfile(params_lib, checkfile, selfname, CHK_STATUS); out: if (checkfile) @@ -1010,7 +1011,8 @@ int main(int argc, char *argv[]) } } - if (fipscheck_self(params_self, print_self_hash)) { + /* library self-check must be consistent across apps: */ + if (fipscheck_self(params_self, &PARAMS_SELF_FIPSCHECK, print_self_hash)) { fprintf(stderr, "Integrity check of application %s failed\n", basen); ret = 1; From c69e77d4abd5b77a3f396abb816af1df8c9a7733 Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Wed, 18 Apr 2018 11:59:11 +0200 Subject: [PATCH 2/4] Makefile.am: Properly install checksum files --- Makefile.am | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Makefile.am b/Makefile.am index ed724fe..07e2451 100644 --- a/Makefile.am +++ b/Makefile.am @@ -139,16 +139,25 @@ EXTRA_bin_kcapi_hasher_DEPENDENCIES = libtool SCAN_FILES += $(bin_kcapi_hasher_SOURCES) -kcapi_hasher_links = sha1sum sha224sum sha256sum sha384sum sha512sum \ - md5sum fipscheck fipshmac \ - sha1hmac sha224hmac sha256hmac sha384hmac sha512hmac +hasher_links_fc = sha1sum sha224sum sha256sum sha384sum sha512sum \ + md5sum fipscheck fipshmac +hasher_links_hc = sha1hmac sha224hmac sha256hmac sha384hmac sha512hmac +hasher_links = $(hasher_links_fc) $(hasher_links_hc) + +CHECKSUM_CMD_FC = $(OPENSSL) sha256 -r -hmac orboDeJITITejsirpADONivirpUkvarP +CHECKSUM_CMD_HC = $(OPENSSL) sha512 -r -hmac FIPS-FTW-RHT2009 install-exec-hook: (cd $(DESTDIR)$(bindir) && \ - ($(foreach link, $(kcapi_hasher_links), $(LN) -f kcapi-hasher $(link);))) + ($(foreach link, $(hasher_links), $(LN) -f kcapi-hasher $(link);))) if HAVE_OPENSSL (cd $(DESTDIR)$(bindir) && \ - ($(foreach link, $(kcapi_hasher_links), $(OPENSSL) sha256 -hmac orboDeJITITejsirpADONivirpUkvarP $(link) > $(CHECK_PREFIX)$(link).$(CHECK_SUFFIX);))) + ($(foreach link, $(hasher_links_fc), \ + $(CHECKSUM_CMD_FC) $(link) > $(CHECK_PREFIX)$(link).$(CHECK_SUFFIX);) \ + $(foreach link, $(hasher_links_hc), \ + $(CHECKSUM_CMD_HC) $(link) > $(CHECK_PREFIX)$(link).$(CHECK_SUFFIX);):)) + ($(foreach lib, $(wildcard $(DESTDIR)$(libdir)/libkcapi.so*), \ + $(CHECKSUM_CMD_FC) $(lib) > $(CHECK_PREFIX)$(lib).$(CHECK_SUFFIX);):) endif endif From a90c618490385d9d6214dd4918dd679b0be0df9f Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Wed, 18 Apr 2018 12:17:59 +0200 Subject: [PATCH 3/4] kcapi-hasher: Add -L option for completeness Since kcapi-hasher also checks the checksum of the libkcapi library, add -L option to print the checksum of the library. --- apps/kcapi-hasher.c | 130 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 55 deletions(-) diff --git a/apps/kcapi-hasher.c b/apps/kcapi-hasher.c index 1d76e1d..7890060 100644 --- a/apps/kcapi-hasher.c +++ b/apps/kcapi-hasher.c @@ -114,7 +114,7 @@ static void usage(char *name, int fipscheck) const char *base = basename(name); fprintf(stderr, "\n%s - calculation of hash sum (Using Linux Kernel Crypto API)\n", basename(name)); fprintf(stderr, "\nUsage:\n"); - fprintf(stderr, "\t%s [OPTION]... -S\n", base); + fprintf(stderr, "\t%s [OPTION]... -S|-L\n", base); if (fipscheck) fprintf(stderr, "\t%s [OPTION]... FILE\n", base); else { @@ -123,6 +123,7 @@ static void usage(char *name, int fipscheck) } fprintf(stderr, "\nOptions:\n"); fprintf(stderr, "\t-S --self-sum\t\tPrint checksum of this binary and exit\n"); + fprintf(stderr, "\t-L --self-sum-lib\tPrint checksum of the libkcapi library and exit\n"); if (!fipscheck) fprintf(stderr, "\t-c --check FILE\t\tVerify hash sums from file\n"); fprintf(stderr, "\t-u --unkeyed\t\tForce unkeyed hash\n"); @@ -611,8 +612,13 @@ static int process_checkfile(const struct hash_params *params, } +/* self-check modes: */ +#define SELFCHECK_CHECK 0 +#define SELFCHECK_PRINT_SELF 1 +#define SELFCHECK_PRINT_LIB 2 + static int fipscheck_self(const struct hash_params *params_bin, - const struct hash_params *params_lib, int just_print) + const struct hash_params *params_lib, int mode) { char *checkfile = NULL; uint32_t n = 0; @@ -626,9 +632,9 @@ static int fipscheck_self(const struct hash_params *params_bin, void *dl = NULL, *sym; #ifdef HAVE_SECURE_GETENV - if (secure_getenv("KCAPI_HASHER_FORCE_FIPS") || just_print) { + if (secure_getenv("KCAPI_HASHER_FORCE_FIPS") || mode != SELFCHECK_CHECK) { #else - if (getenv("KCAPI_HASHER_FORCE_FIPS") || just_print) { + if (getenv("KCAPI_HASHER_FORCE_FIPS") || mode != SELFCHECK_CHECK) { #endif fipsflag[0] = 1; } else { @@ -660,58 +666,68 @@ static int fipscheck_self(const struct hash_params *params_bin, } /* Integrity check of our application. */ - memset(selfname, 0, sizeof(selfname)); - selfnamesize = readlink("/proc/self/exe", selfname, BUFSIZE); - if (selfnamesize >= BUFSIZE || selfnamesize < 0) { - fprintf(stderr, "Cannot obtain my filename\n"); - ret = -EFAULT; - goto out; - } + if (mode == SELFCHECK_CHECK || mode == SELFCHECK_PRINT_SELF) { + memset(selfname, 0, sizeof(selfname)); + selfnamesize = readlink("/proc/self/exe", selfname, BUFSIZE); + if (selfnamesize >= BUFSIZE || selfnamesize < 0) { + fprintf(stderr, "Cannot obtain my filename\n"); + ret = -EFAULT; + goto out; + } - if (just_print) { - ret = hash_files(params_bin, names, 1, 0, 1); - goto out; - } + if (mode == SELFCHECK_PRINT_SELF) { + ret = hash_files(params_bin, names, 1, 0, 1); + goto out; + } - checkfile = get_hmac_file(selfname); - if (!checkfile) { - ret = -ENOMEM; - goto out; - } + checkfile = get_hmac_file(selfname); + if (!checkfile) { + ret = -ENOMEM; + goto out; + } - ret = process_checkfile(params_bin, checkfile, selfname, CHK_STATUS); - if (ret) - goto out; + ret = process_checkfile(params_bin, checkfile, selfname, CHK_STATUS); + if (ret) + goto out; + } /* Integrity check of shared libkcapi.so file. */ - memset(selfname, 0, sizeof(selfname)); - snprintf(selfname, (sizeof(selfname) - 1), "libkcapi.so.%u", - KCAPI_MAJVERSION); - dl = dlopen(selfname, RTLD_NODELETE|RTLD_NOLOAD|RTLD_LAZY); - if (dl == NULL) { - fprintf(stderr, "dlopen of file %s failed\n", selfname); - ret = -EFAULT; - goto out; - } + if (mode == SELFCHECK_CHECK || mode == SELFCHECK_PRINT_LIB) { + memset(selfname, 0, sizeof(selfname)); + snprintf(selfname, (sizeof(selfname) - 1), "libkcapi.so.%u", + KCAPI_MAJVERSION); + dl = dlopen(selfname, RTLD_NODELETE|RTLD_NOLOAD|RTLD_LAZY); + if (dl == NULL) { + fprintf(stderr, "dlopen of file %s failed\n", selfname); + ret = -EFAULT; + goto out; + } - memset(selfname, 0, sizeof(selfname)); - sym = dlsym(dl, "kcapi_md_init"); - if (sym == NULL || !dladdr(sym, &info)) { - fprintf(stderr, "finding symbol kcapi_md_init failed\n"); - ret = -EFAULT; - goto out; - } + memset(selfname, 0, sizeof(selfname)); + sym = dlsym(dl, "kcapi_md_init"); + if (sym == NULL || !dladdr(sym, &info)) { + fprintf(stderr, "finding symbol kcapi_md_init failed\n"); + ret = -EFAULT; + goto out; + } - strncpy(selfname, info.dli_fname, (sizeof(selfname) - 1)); + strncpy(selfname, info.dli_fname, (sizeof(selfname) - 1)); - free(checkfile); - checkfile = get_hmac_file(selfname); - if (!checkfile) { - ret = -ENOMEM; - goto out; - } + if (mode == SELFCHECK_PRINT_LIB) { + ret = hash_files(params_lib, names, 1, 0, 1); + goto out; + } + + if (checkfile) + free(checkfile); + checkfile = get_hmac_file(selfname); + if (!checkfile) { + ret = -ENOMEM; + goto out; + } - ret = process_checkfile(params_lib, checkfile, selfname, CHK_STATUS); + ret = process_checkfile(params_lib, checkfile, selfname, CHK_STATUS); + } out: if (checkfile) @@ -753,9 +769,9 @@ int main(int argc, char *argv[]) int hmac = 0; int fipscheck = 0; int fipshmac = 0; - int print_self_hash = 0; + int selfcheck_mode = SELFCHECK_CHECK; - static const char *opts_short = "c:uh:t:Sqk:K:vbd:P"; + static const char *opts_short = "c:uh:t:SLqk:K:vbd:P"; static const struct option opts[] = { {"help", 0, 0, 0}, {"tag", 0, 0, 0}, @@ -765,6 +781,7 @@ int main(int argc, char *argv[]) {"hash", 1, 0, 'h'}, {"truncate", 1, 0, 't'}, {"self-sum", 0, 0, 'S'}, + {"self-sum-lib", 0, 0, 'L'}, {"status", 0, 0, 'q'}, {"key-file", 1, 0, 'k'}, {"key", 1, 0, 'K'}, @@ -932,7 +949,10 @@ int main(int argc, char *argv[]) params.hashlen /= 8; break; case 'S': - print_self_hash = 1; + selfcheck_mode = SELFCHECK_PRINT_SELF; + break; + case 'L': + selfcheck_mode = SELFCHECK_PRINT_LIB; break; case 'q': loglevel = CHK_STATUS; @@ -998,28 +1018,28 @@ int main(int argc, char *argv[]) } } - if (print_self_hash) { + if (selfcheck_mode != SELFCHECK_CHECK) { if (checkfile) { - fprintf(stderr, "-S and -c cannot be combined\n"); + fprintf(stderr, "-S/-L and -c cannot be combined\n"); ret = 1; goto out; } if (optind != argc) { - fprintf(stderr, "-S cannot be used with input files\n"); + fprintf(stderr, "-S/-L cannot be used with input files\n"); ret = 1; goto out; } } /* library self-check must be consistent across apps: */ - if (fipscheck_self(params_self, &PARAMS_SELF_FIPSCHECK, print_self_hash)) { + if (fipscheck_self(params_self, &PARAMS_SELF_FIPSCHECK, selfcheck_mode)) { fprintf(stderr, "Integrity check of application %s failed\n", basen); ret = 1; goto out; } - if (print_self_hash) { + if (selfcheck_mode != SELFCHECK_CHECK) { ret = 0; goto out; } From 7b176840ff60bc596a7c80685ef0a81adbc00e4b Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Thu, 19 Apr 2018 10:39:12 +0200 Subject: [PATCH 4/4] Makefile.am: Do not install kcapi-hasher binary The kcapi-hasher binary is not usable on its own so it can be removed after hard-linking the actual hasher tools. --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 07e2451..383da75 100644 --- a/Makefile.am +++ b/Makefile.am @@ -150,6 +150,7 @@ CHECKSUM_CMD_HC = $(OPENSSL) sha512 -r -hmac FIPS-FTW-RHT2009 install-exec-hook: (cd $(DESTDIR)$(bindir) && \ ($(foreach link, $(hasher_links), $(LN) -f kcapi-hasher $(link);))) + -rm -f $(DESTDIR)$(bindir)/kcapi-hasher if HAVE_OPENSSL (cd $(DESTDIR)$(bindir) && \ ($(foreach link, $(hasher_links_fc), \