diff --git a/libica-rpmlintrc b/libica-rpmlintrc index bdeb306..d02edc6 100644 --- a/libica-rpmlintrc +++ b/libica-rpmlintrc @@ -2,3 +2,4 @@ addFilter("libica-tools.* shlib-policy-missing-lib") addFilter("libica-devel-static.* shlib-policy-missing-lib") addFilter("libica-tools.* devel-file-in-non-devel-package .* /usr/lib64/libica.so") addFilter("libica-tools.* files-duplicate /usr/share/doc/packages/libica-tools/COPYING /usr/share/doc/packages/libica-tools/LICENSE") +addFilter("libica*.* hidden-file-or-dir /usr/lib64/.libica.so.*.hmac") diff --git a/libica-sles15sp2-Build-with-pthread-flag.patch b/libica-sles15sp2-Build-with-pthread-flag.patch new file mode 100644 index 0000000..834eb8d --- /dev/null +++ b/libica-sles15sp2-Build-with-pthread-flag.patch @@ -0,0 +1,26 @@ +From 64ff9599a7d17a5edc534a750777536b43e9c386 Mon Sep 17 00:00:00 2001 +From: Patrick Steuer +Date: Mon, 9 Sep 2019 14:30:42 +0200 +Subject: [PATCH] Build with -pthread flag + +Signed-off-by: Patrick Steuer +--- + src/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/Makefile.am b/src/Makefile.am +index ff6bb49..5e75074 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -7,7 +7,7 @@ AM_CFLAGS = @FLAGS@ + lib_LTLIBRARIES = libica.la + + libica_la_CFLAGS = ${AM_CFLAGS} -I${srcdir}/include -I${srcdir}/../include \ +- -fvisibility=hidden ++ -fvisibility=hidden -pthread + libica_la_CCASFLAGS = ${AM_CFLAGS} + libica_la_LIBADD = @LIBS@ -lrt -lcrypto + libica_la_LDFLAGS = -Wl,--version-script=${srcdir}/../libica.map \ +-- +2.26.2 + diff --git a/libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-addon.patch b/libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-addon.patch new file mode 100644 index 0000000..fb10b28 --- /dev/null +++ b/libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-addon.patch @@ -0,0 +1,48 @@ +From 422913a4834a6bc35270d5d890cb43c84779f18d Mon Sep 17 00:00:00 2001 +From: Joerg Schmidbauer +Date: Wed, 6 May 2020 09:50:20 +0200 +Subject: [PATCH] FIPS: HMAC based library integrity check addon + +Initialize path variable with nulls by using calloc instead of +malloc, improve checking of hmac length. + +Signed-off-by: Joerg Schmidbauer +--- + src/fips.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/fips.c b/src/fips.c +index bab00db..a1c6f5f 100644 +--- a/src/fips.c ++++ b/src/fips.c +@@ -154,7 +154,7 @@ static char *make_hmac_path(const char *origpath) + char *path; + const char *fn; + +- path = malloc(sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath) + 1); ++ path = calloc(1, sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath) + 1); + if (path == NULL) + return NULL; + +@@ -184,6 +184,9 @@ static int compute_file_hmac(const char *path, void **buf, size_t *hmaclen) + size_t hlen, len; + long keylen; + ++ *buf = NULL; ++ *hmaclen = 0; ++ + keybuf = OPENSSL_hexstr2buf(hmackey, &keylen); + pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, keybuf, (int)keylen); + if (!pkey) +@@ -270,7 +273,7 @@ static int FIPSCHECK_verify(const char *path) + if (compute_file_hmac(path, &buf, &buflen) != 0) + goto end; + +- if (memcmp(buf, hmac_buf, hmaclen) != 0) ++ if (memcmp(buf, hmac_buf, buflen) != 0) + goto end; + + rc = 1; +-- +2.26.2 + diff --git a/libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-rename-variables.patch b/libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-rename-variables.patch new file mode 100644 index 0000000..5768e02 --- /dev/null +++ b/libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-rename-variables.patch @@ -0,0 +1,74 @@ +From 2078b62947d2e0f2641b48975786e839d6396be8 Mon Sep 17 00:00:00 2001 +From: Joerg Schmidbauer +Date: Wed, 6 May 2020 09:52:36 +0200 +Subject: [PATCH] FIPS: HMAC based library integrity check, rename variables + +Rename variables to more speaking names, no logic change. + +Signed-off-by: Joerg Schmidbauer +--- + src/fips.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/src/fips.c b/src/fips.c +index a1c6f5f..07310c3 100644 +--- a/src/fips.c ++++ b/src/fips.c +@@ -245,12 +245,12 @@ static int FIPSCHECK_verify(const char *path) + { + int rc = 0; + FILE *fp; +- unsigned char *hmac_buf = NULL; ++ unsigned char *known_hmac = NULL; + long hmaclen; + char *hmacpath, *p; +- char *hmac_str = NULL; +- size_t n, buflen; +- void *buf = NULL; ++ char *known_hmac_str = NULL; ++ size_t n, computed_hmac_len; ++ void *computed_hmac = NULL; + + hmacpath = make_hmac_path(path); + if (hmacpath == NULL) +@@ -262,29 +262,29 @@ static int FIPSCHECK_verify(const char *path) + goto end; + } + +- if (getline(&hmac_str, &n, fp) <= 0) ++ if (getline(&known_hmac_str, &n, fp) <= 0) + goto end; + +- if ((p = strchr(hmac_str, '\n')) != NULL) ++ if ((p = strchr(known_hmac_str, '\n')) != NULL) + *p = '\0'; + +- hmac_buf = OPENSSL_hexstr2buf(hmac_str, &hmaclen); ++ known_hmac = OPENSSL_hexstr2buf(known_hmac_str, &hmaclen); + +- if (compute_file_hmac(path, &buf, &buflen) != 0) ++ if (compute_file_hmac(path, &computed_hmac, &computed_hmac_len) != 0) + goto end; + +- if (memcmp(buf, hmac_buf, buflen) != 0) ++ if (memcmp(computed_hmac, known_hmac, computed_hmac_len) != 0) + goto end; + + rc = 1; + + end: + +- free(buf); +- free(hmac_str); ++ free(computed_hmac); ++ free(known_hmac_str); + free(hmacpath); + +- OPENSSL_free(hmac_buf); ++ OPENSSL_free(known_hmac); + + if (fp) + fclose(fp); +-- +2.26.2 + diff --git a/libica-sles15sp2-FIPS-add-SHA3-KATs-to-fips_powerup_tests.patch b/libica-sles15sp2-FIPS-add-SHA3-KATs-to-fips_powerup_tests.patch new file mode 100644 index 0000000..309a49a --- /dev/null +++ b/libica-sles15sp2-FIPS-add-SHA3-KATs-to-fips_powerup_tests.patch @@ -0,0 +1,160 @@ +From 23a647aab7b44442b63345bdf70da0696b7fcd5a Mon Sep 17 00:00:00 2001 +From: Joerg Schmidbauer +Date: Fri, 21 Aug 2020 15:29:49 +0200 +Subject: [PATCH] FIPS: add SHA3 KATs to fips_powerup_tests + +Signed-off-by: Joerg Schmidbauer +--- + src/fips.c | 26 ++++++++++++++++++- + src/include/test_vec.h | 13 ++++++++++ + src/test_vec.c | 59 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 97 insertions(+), 1 deletion(-) + +diff --git a/src/fips.c b/src/fips.c +index 2bf11f5..13a550b 100644 +--- a/src/fips.c ++++ b/src/fips.c +@@ -95,6 +95,29 @@ SHA_KAT(384, 512); + SHA_KAT(512, 512); + #undef SHA_KAT + ++#define SHA3_KAT(_sha_, _ctx_) \ ++static int sha3_##_sha_##_kat(void) { \ ++ sha3_##_ctx_##_context_t ctx; \ ++ size_t i; \ ++ unsigned char out[SHA3_##_sha_##_HASH_LENGTH]; \ ++ for (i = 0; i < SHA3_##_sha_##_TV_LEN; i++) { \ ++ if (ica_sha3_##_sha_(SHA_MSG_PART_ONLY, \ ++ SHA3_##_sha_##_TV[i].msg_len, SHA3_##_sha_##_TV[i].msg, \ ++ &ctx, out) || memcmp(SHA3_##_sha_##_TV[i].md, out, \ ++ SHA3_##_sha_##_HASH_LENGTH)) { \ ++ syslog(LOG_ERR, "Libica SHA-3%d test failed.", \ ++ _sha_); \ ++ return 1; \ ++ } \ ++ } \ ++ return 0; \ ++} ++SHA3_KAT(224, 224); ++SHA3_KAT(256, 256); ++SHA3_KAT(384, 384); ++SHA3_KAT(512, 512); ++#undef SHA3_KAT ++ + void + fips_init(void) + { +@@ -328,7 +351,8 @@ fips_powerup_tests(void) + /* Cryptographic algorithm test. */ + if (ica_drbg_health_test(ica_drbg_generate, 256, true, ICA_DRBG_SHA512) + || sha1_kat() || sha224_kat() || sha256_kat() || sha384_kat() +- || sha512_kat() || des3_ecb_kat() || des3_cbc_kat() ++ || sha512_kat() || sha3_224_kat() || sha3_256_kat() || sha3_384_kat() ++ || sha3_512_kat() || des3_ecb_kat() || des3_cbc_kat() + || des3_cbc_cs_kat() || des3_cfb_kat() || des3_ofb_kat() + || des3_ctr_kat() || des3_cmac_kat() || aes_ecb_kat() + || aes_cbc_kat() || aes_cbc_cs_kat() || aes_cfb_kat() +diff --git a/src/include/test_vec.h b/src/include/test_vec.h +index bba6ea9..692afbc 100644 +--- a/src/include/test_vec.h ++++ b/src/include/test_vec.h +@@ -366,6 +366,19 @@ extern const size_t SHA384_TV_LEN; + + extern const struct sha_tv SHA512_TV[]; + extern const size_t SHA512_TV_LEN; ++ ++extern const struct sha_tv SHA3_224_TV[]; ++extern const size_t SHA3_224_TV_LEN; ++ ++extern const struct sha_tv SHA3_256_TV[]; ++extern const size_t SHA3_256_TV_LEN; ++ ++extern const struct sha_tv SHA3_384_TV[]; ++extern const size_t SHA3_384_TV_LEN; ++ ++extern const struct sha_tv SHA3_512_TV[]; ++extern const size_t SHA3_512_TV_LEN; ++ + #endif /* ICA_FIPS */ + + #ifdef ICA_INTERNAL_TEST_EC +diff --git a/src/test_vec.c b/src/test_vec.c +index ab260dc..f282dbb 100644 +--- a/src/test_vec.c ++++ b/src/test_vec.c +@@ -2449,6 +2449,61 @@ const struct sha_tv SHA512_TV[] = { + } + }, + }; ++ ++const struct sha_tv SHA3_224_TV[] = { ++{ ++.msg_len = 3, ++.msg = (unsigned char []){ ++0x61, 0x62, 0x63, ++}, ++.md = (unsigned char []){ ++0xe6,0x42,0x82,0x4c,0x3f,0x8c,0xf2,0x4a,0xd0,0x92,0x34,0xee,0x7d,0x3c,0x76,0x6f, ++0xc9,0xa3,0xa5,0x16,0x8d,0x0c,0x94,0xad,0x73,0xb4,0x6f,0xdf, ++} ++}, ++}; ++ ++const struct sha_tv SHA3_256_TV[] = { ++{ ++.msg_len = 3, ++.msg = (unsigned char []){ ++0x61, 0x62, 0x63, ++}, ++.md = (unsigned char []){ ++0x3A,0x98,0x5D,0xA7,0x4F,0xE2,0x25,0xB2,0x04,0x5C,0x17,0x2D,0x6B,0xD3,0x90,0xBD, ++0x85,0x5F,0x08,0x6E,0x3E,0x9D,0x52,0x5B,0x46,0xBF,0xE2,0x45,0x11,0x43,0x15,0x32, ++} ++}, ++}; ++ ++const struct sha_tv SHA3_384_TV[] = { ++{ ++.msg_len = 3, ++.msg = (unsigned char []){ ++0x61, 0x62, 0x63, ++}, ++.md = (unsigned char []){ ++0xEC,0x01,0x49,0x82,0x88,0x51,0x6F,0xC9,0x26,0x45,0x9F,0x58,0xE2,0xC6,0xAD,0x8D, ++0xF9,0xB4,0x73,0xCB,0x0F,0xC0,0x8C,0x25,0x96,0xDA,0x7C,0xF0,0xE4,0x9B,0xE4,0xB2, ++0x98,0xD8,0x8C,0xEA,0x92,0x7A,0xC7,0xF5,0x39,0xF1,0xED,0xF2,0x28,0x37,0x6D,0x25, ++} ++}, ++}; ++ ++const struct sha_tv SHA3_512_TV[] = { ++{ ++.msg_len = 3, ++.msg = (unsigned char []){ ++0x61, 0x62, 0x63, ++}, ++.md = (unsigned char []){ ++0xB7,0x51,0x85,0x0B,0x1A,0x57,0x16,0x8A,0x56,0x93,0xCD,0x92,0x4B,0x6B,0x09,0x6E, ++0x08,0xF6,0x21,0x82,0x74,0x44,0xF7,0x0D,0x88,0x4F,0x5D,0x02,0x40,0xD2,0x71,0x2E, ++0x10,0xE1,0x16,0xE9,0x19,0x2A,0xF3,0xC9,0x1A,0x7E,0xC5,0x76,0x47,0xE3,0x93,0x40, ++0x57,0x34,0x0B,0x4C,0xF4,0x08,0xD5,0xA5,0x65,0x92,0xF8,0x27,0x4E,0xEC,0x53,0xF0, ++} ++}, ++}; + #endif /* ICA_FIPS */ + + #ifdef ICA_INTERNAL_TEST_EC +@@ -5759,6 +5814,10 @@ const size_t SHA224_TV_LEN = sizeof(SHA224_TV) / sizeof(SHA224_TV[0]); + const size_t SHA256_TV_LEN = sizeof(SHA256_TV) / sizeof(SHA256_TV[0]); + const size_t SHA384_TV_LEN = sizeof(SHA384_TV) / sizeof(SHA384_TV[0]); + const size_t SHA512_TV_LEN = sizeof(SHA512_TV) / sizeof(SHA512_TV[0]); ++const size_t SHA3_224_TV_LEN = sizeof(SHA3_224_TV) / sizeof(SHA3_224_TV[0]); ++const size_t SHA3_256_TV_LEN = sizeof(SHA3_256_TV) / sizeof(SHA3_256_TV[0]); ++const size_t SHA3_384_TV_LEN = sizeof(SHA3_384_TV) / sizeof(SHA3_384_TV[0]); ++const size_t SHA3_512_TV_LEN = sizeof(SHA3_512_TV) / sizeof(SHA3_512_TV[0]); + #endif /* ICA_FIPS */ + #ifdef ICA_INTERNAL_TEST_EC + const size_t ECDSA_TV_LEN = sizeof(ECDSA_TV) / sizeof(ECDSA_TV[0]); +-- +2.26.2 + diff --git a/libica-sles15sp2-FIPS-fix-inconsistent-error-handling.patch b/libica-sles15sp2-FIPS-fix-inconsistent-error-handling.patch new file mode 100644 index 0000000..3cf81f0 --- /dev/null +++ b/libica-sles15sp2-FIPS-fix-inconsistent-error-handling.patch @@ -0,0 +1,31 @@ +From 8acba8fc09a91831172658c9c0810aa45ab39245 Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Tue, 1 Sep 2020 10:03:38 +0200 +Subject: [PATCH] FIPS: fix inconsistent error handling. + +when the HMAC file is not present/readable it is also an error. + +Signed-off-by: Michal Suchanek +--- + src/fips.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/fips.c b/src/fips.c +index c0055b719bff..71a417e8de40 100644 +--- a/src/fips.c ++++ b/src/fips.c +@@ -295,10 +295,8 @@ static int FIPSCHECK_verify(const char *path) + return 0; + + fp = fopen(hmacpath, "r"); +- if (fp == NULL) { +- rc = 1; ++ if (fp == NULL) + goto end; +- } + + if (getline(&known_hmac_str, &n, fp) <= 0) + goto end; +-- +2.28.0 + diff --git a/libica-sles15sp2-FIPS-hmac-key.patch b/libica-sles15sp2-FIPS-hmac-key.patch index e57ff08..f533fa7 100644 --- a/libica-sles15sp2-FIPS-hmac-key.patch +++ b/libica-sles15sp2-FIPS-hmac-key.patch @@ -1,12 +1,13 @@ --- libica-3.6.0/src/fips.c 2020-05-04 17:01:23.238805001 -0400 +++ libica-3.6.0/src/fips.c 2020-05-04 16:58:51.352241763 -0400 @@ -45,8 +45,7 @@ - * libica.so.MAJOR.hmac in the same directory as the .so module. - */ + * .libica.so.VERSION.hmac in the same directory as the .so module. +- */ ++ /* HMAC key is hexidecimal for: "orboDeJITITejsirpADONivirpUkvarP" */ static const char hmackey[] = - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000"; -+ "orboDeJITITejsirpADONivirpUkvarP"; ++ "6f72626f44654a49544954656a7369727041444f4e6976697270556b76617250"; int fips; diff --git a/libica-sles15sp2-FIPS-hmac-key.patch.20200507 b/libica-sles15sp2-FIPS-hmac-key.patch.20200507 new file mode 100644 index 0000000..e57ff08 --- /dev/null +++ b/libica-sles15sp2-FIPS-hmac-key.patch.20200507 @@ -0,0 +1,12 @@ +--- libica-3.6.0/src/fips.c 2020-05-04 17:01:23.238805001 -0400 ++++ libica-3.6.0/src/fips.c 2020-05-04 16:58:51.352241763 -0400 +@@ -45,8 +45,7 @@ + * libica.so.MAJOR.hmac in the same directory as the .so module. + */ + static const char hmackey[] = +- "0000000000000000000000000000000000000000000000000000000000000000" +- "0000000000000000000000000000000000000000000000000000000000000000"; ++ "orboDeJITITejsirpADONivirpUkvarP"; + + int fips; + diff --git a/libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch b/libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch index d143191..30a28a9 100644 --- a/libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch +++ b/libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch @@ -13,7 +13,7 @@ Signed-off-by: Joerg Schmidbauer --- include/ica_api.h | 2 +- src/Makefile.am | 4 +- - src/fips.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + src/fips.c | 224 ++++++++++++++++++++++++++++++++++++++++++++- src/include/fips.h | 4 +- test/fips_test.c | 4 + 5 files changed, 232 insertions(+), 6 deletions(-) @@ -35,16 +35,16 @@ diff --git a/src/Makefile.am b/src/Makefile.am index 65f471f..9e4ef52 100644 --- a/src/Makefile.am +++ b/src/Makefile.am -@@ -9,7 +9,7 @@ +@@ -9,7 +9,7 @@ lib_LTLIBRARIES = libica.la libica_la_CFLAGS = ${AM_CFLAGS} -I${srcdir}/include -I${srcdir}/../include \ - -fvisibility=hidden + -fvisibility=hidden -pthread libica_la_CCASFLAGS = ${AM_CFLAGS} -libica_la_LIBADD = @LIBS@ -lrt -lcrypto +libica_la_LIBADD = @LIBS@ -lrt -lcrypto -ldl libica_la_LDFLAGS = -Wl,--version-script=${srcdir}/../libica.map \ -version-number ${VERSION} libica_la_SOURCES = ica_api.c init.c icastats_shared.c s390_rsa.c \ -@@ -53,7 +53,7 @@ +@@ -53,7 +53,7 @@ internal_tests_ec_internal_test_CFLAGS = ${AM_CFLAGS} -I${srcdir}/include \ -DICA_INTERNAL_TEST \ -DICA_INTERNAL_TEST_EC internal_tests_ec_internal_test_CCASFLAGS = ${AM_CFLAGS} @@ -133,7 +133,7 @@ index d09a553..bab00db 100644 + char *path; + const char *fn; + -+ path = calloc(1,sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath) + 1); ++ path = malloc(sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath) + 1); + if (path == NULL) + return NULL; + @@ -350,5 +350,5 @@ index 06563e3..0f1940d 100644 printf("OpenSSL version is '%s'.\n", OPENSSL_VERSION_TEXT); -- -2.16.4 +2.26.2 diff --git a/libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch.20200505 b/libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch.20200505 new file mode 100644 index 0000000..d143191 --- /dev/null +++ b/libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch.20200505 @@ -0,0 +1,354 @@ +From 231bba3b32bd246d8286f1c7dc231d836ea92bd9 Mon Sep 17 00:00:00 2001 +From: Joerg Schmidbauer +Date: Mon, 27 Apr 2020 11:18:26 +0200 +Subject: [PATCH] FIPS: introduce HMAC based library integrity check + +When in FIPS mode, perform an integrity check on libica.so by calculating +an HMAC from the file contents using a static HMAC key, and comparing it +to a pre-calculated HMAC in a separate file. The HMAC key and HMAC file +may be provided by a Distributor when building the packet. The test +succeeds if the HMAC file is not present. + +Signed-off-by: Joerg Schmidbauer +--- + include/ica_api.h | 2 +- + src/Makefile.am | 4 +- + src/fips.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + src/include/fips.h | 4 +- + test/fips_test.c | 4 + + 5 files changed, 232 insertions(+), 6 deletions(-) + +diff --git a/include/ica_api.h b/include/ica_api.h +index 91bf0be..8221f55 100644 +--- a/include/ica_api.h ++++ b/include/ica_api.h +@@ -216,7 +216,7 @@ typedef ica_adapter_handle_t ICA_ADAPTER_HANDLE; + */ + /* Cryptographic algorithm test (KAT or pair-wise consistency test) */ + #define ICA_FIPS_CRYPTOALG 2 +-/* Software/Firmware integrity test (not implemented yet) */ ++/* Software/Firmware integrity test */ + #define ICA_FIPS_INTEGRITY 4 + /* Critical functions test (N/A) */ + #define ICA_FIPS_CRITICALFUNC 8 +diff --git a/src/Makefile.am b/src/Makefile.am +index 65f471f..9e4ef52 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -9,7 +9,7 @@ + libica_la_CFLAGS = ${AM_CFLAGS} -I${srcdir}/include -I${srcdir}/../include \ + -fvisibility=hidden + libica_la_CCASFLAGS = ${AM_CFLAGS} +-libica_la_LIBADD = @LIBS@ -lrt -lcrypto ++libica_la_LIBADD = @LIBS@ -lrt -lcrypto -ldl + libica_la_LDFLAGS = -Wl,--version-script=${srcdir}/../libica.map \ + -version-number ${VERSION} + libica_la_SOURCES = ica_api.c init.c icastats_shared.c s390_rsa.c \ +@@ -53,7 +53,7 @@ + -DICA_INTERNAL_TEST \ + -DICA_INTERNAL_TEST_EC + internal_tests_ec_internal_test_CCASFLAGS = ${AM_CFLAGS} +-internal_tests_ec_internal_test_LDADD = @LIBS@ -lrt -lcrypto -lpthread ++internal_tests_ec_internal_test_LDADD = @LIBS@ -lrt -lcrypto -lpthread -ldl + internal_tests_ec_internal_test_SOURCES = \ + ica_api.c init.c icastats_shared.c s390_rsa.c \ + s390_crypto.c s390_ecc.c s390_prng.c s390_sha.c \ +diff --git a/src/fips.c b/src/fips.c +index d09a553..bab00db 100644 +--- a/src/fips.c ++++ b/src/fips.c +@@ -13,11 +13,13 @@ + + #include + #include ++#include + #include + #include + #include + #include + #include ++#include + + #include + #ifdef OPENSSL_FIPS +@@ -28,6 +30,24 @@ + #include "ica_api.h" + #include "test_vec.h" + ++#ifndef PATH_MAX ++#define PATH_MAX 4096 ++#endif ++ ++#define HMAC_PREFIX "." ++#define HMAC_SUFFIX ".hmac" ++#define READ_BUFFER_LENGTH 16384 ++ ++/* ++ * The hard-coded HMAC key to be optionally provided for the library ++ * integrity test. The recommended key size for HMAC-SHA256 is 64 bytes. ++ * The known HMAC is supposed to be provided as hex string in a file ++ * libica.so.MAJOR.hmac in the same directory as the .so module. ++ */ ++static const char hmackey[] = ++ "0000000000000000000000000000000000000000000000000000000000000000" ++ "0000000000000000000000000000000000000000000000000000000000000000"; ++ + int fips; + + static int aes_ecb_kat(void); +@@ -101,6 +121,206 @@ fips_init(void) + FIPS_mode_set(1); + } + } ++static int get_library_path(const char *libname, const char *symbolname, ++ char *path, size_t pathlen) ++{ ++ Dl_info info; ++ void *dl, *sym; ++ int rc = -1; ++ ++ dl = dlopen(libname, RTLD_LAZY); ++ if (dl == NULL) ++ goto done; ++ ++ sym = dlsym(dl, symbolname); ++ if (sym != NULL && dladdr(sym, &info)) { ++ if (strlen(info.dli_fname) < pathlen) ++ strcpy(path, info.dli_fname); ++ else ++ goto done; ++ } ++ ++ rc = 0; ++ ++done: ++ if (dl != NULL) ++ dlclose(dl); ++ ++ return rc; ++} ++ ++static char *make_hmac_path(const char *origpath) ++{ ++ char *path; ++ const char *fn; ++ ++ path = calloc(1,sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath) + 1); ++ if (path == NULL) ++ return NULL; ++ ++ fn = strrchr(origpath, '/'); ++ if (fn == NULL) { ++ fn = origpath; ++ } else { ++ ++fn; ++ } ++ ++ strncpy(path, origpath, fn - origpath); ++ strcat(path, HMAC_PREFIX); ++ strcat(path, fn); ++ strcat(path, HMAC_SUFFIX); ++ ++ return path; ++} ++ ++static int compute_file_hmac(const char *path, void **buf, size_t *hmaclen) ++{ ++ FILE *fp = NULL; ++ int rc = -1; ++ unsigned char rbuf[READ_BUFFER_LENGTH]; ++ unsigned char *keybuf; ++ EVP_MD_CTX *mdctx = NULL; ++ EVP_PKEY *pkey = NULL; ++ size_t hlen, len; ++ long keylen; ++ ++ keybuf = OPENSSL_hexstr2buf(hmackey, &keylen); ++ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, keybuf, (int)keylen); ++ if (!pkey) ++ goto end; ++ ++ mdctx = EVP_MD_CTX_create(); ++ if (!mdctx) ++ goto end; ++ ++ fp = fopen(path, "r"); ++ if (fp == NULL) ++ goto end; ++ ++ if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey) <= 0) ++ goto end; ++ ++ while ((len = fread(rbuf, 1, sizeof(rbuf), fp)) != 0) { ++ if (EVP_DigestSignUpdate(mdctx, rbuf, len) <= 0) { ++ goto end; ++ } ++ } ++ ++ if (EVP_DigestSignFinal(mdctx, rbuf, &hlen) <= 0) ++ goto end; ++ ++ *buf = malloc(hlen); ++ if (*buf == NULL) ++ goto end; ++ ++ *hmaclen = hlen; ++ ++ memcpy(*buf, rbuf, hlen); ++ ++ rc = 0; ++ ++end: ++ ++ if (pkey != NULL) ++ EVP_PKEY_free(pkey); ++ ++ free(keybuf); ++ EVP_MD_CTX_destroy(mdctx); ++ if (fp) ++ fclose(fp); ++ ++ return rc; ++} ++ ++/** ++ * Performs the FIPS check. ++ * ++ * @return 1 if check succeeded ++ * 0 otherwise ++ */ ++static int FIPSCHECK_verify(const char *path) ++{ ++ int rc = 0; ++ FILE *fp; ++ unsigned char *hmac_buf = NULL; ++ long hmaclen; ++ char *hmacpath, *p; ++ char *hmac_str = NULL; ++ size_t n, buflen; ++ void *buf = NULL; ++ ++ hmacpath = make_hmac_path(path); ++ if (hmacpath == NULL) ++ return 0; ++ ++ fp = fopen(hmacpath, "r"); ++ if (fp == NULL) { ++ rc = 1; ++ goto end; ++ } ++ ++ if (getline(&hmac_str, &n, fp) <= 0) ++ goto end; ++ ++ if ((p = strchr(hmac_str, '\n')) != NULL) ++ *p = '\0'; ++ ++ hmac_buf = OPENSSL_hexstr2buf(hmac_str, &hmaclen); ++ ++ if (compute_file_hmac(path, &buf, &buflen) != 0) ++ goto end; ++ ++ if (memcmp(buf, hmac_buf, hmaclen) != 0) ++ goto end; ++ ++ rc = 1; ++ ++end: ++ ++ free(buf); ++ free(hmac_str); ++ free(hmacpath); ++ ++ OPENSSL_free(hmac_buf); ++ ++ if (fp) ++ fclose(fp); ++ ++ return rc; ++} ++ ++static const char msg1[] = "Libica FIPS library integrity check failed. Cannot determine library path.\n"; ++static const char msg2[] = "Libica FIPS library integrity check failed. Module %s probably corrupted.\n"; ++static const char msg3[] = "Libica FIPS library integrity check passed.\n"; ++ ++/* ++ * Perform an integrity check on libica.so by calculating an HMAC from ++ * the file contents using a static HMAC key, and comparing it to a ++ * pre-calculated HMAC in a separate file. The HMAC key and HMAC file ++ * may be provided by a Distributor when building the packet. ++ */ ++static void fips_lib_integrity_check(void) ++{ ++ int rc; ++ char path[PATH_MAX]; ++ const char *libname = "libica.so"; ++ const char *symbolname = "ica_sha256"; ++ ++ rc = get_library_path(libname, symbolname, path, sizeof(path)); ++ if (rc != 0) { ++ syslog(LOG_ERR, msg1); ++ fips |= ICA_FIPS_INTEGRITY; ++ return; ++ } ++ ++ if (!FIPSCHECK_verify(path)) { ++ syslog(LOG_ERR, msg2, path); ++ fips |= ICA_FIPS_INTEGRITY; ++ return; ++ } ++ ++ syslog(LOG_INFO, msg3); ++} + + void + fips_powerup_tests(void) +@@ -117,6 +337,9 @@ fips_powerup_tests(void) + fips |= ICA_FIPS_CRYPTOALG; + return; + } ++ ++ /* Library integrity test */ ++ fips_lib_integrity_check(); + } + + static int +@@ -933,5 +1156,4 @@ _err_: + syslog(LOG_ERR, "Libica RSA test failed."); + return 1; + } +- + #endif /* FIPS_H */ +diff --git a/src/include/fips.h b/src/include/fips.h +index 421be4c..0ffdef6 100644 +--- a/src/include/fips.h ++++ b/src/include/fips.h +@@ -27,8 +27,8 @@ extern int fips; /* module status */ + void fips_init(void); + + /* +- * Powerup tests: crypto algorithm test, SW/FW integrity test (not implemented +- * yet), critical function test (no critical functions). The tests set the ++ * Powerup tests: crypto algorithm test, SW/FW integrity test, critical ++ * function test (no critical functions). The tests set the + * corresponding status flags. + */ + void fips_powerup_tests(void); +diff --git a/test/fips_test.c b/test/fips_test.c +index 06563e3..0f1940d 100644 +--- a/test/fips_test.c ++++ b/test/fips_test.c +@@ -57,6 +57,10 @@ main(void) + printf("Libica FIPS powerup test failed.\n"); + rv = EXIT_FAILURE; + } ++ if (fips & ICA_FIPS_INTEGRITY) { ++ printf("Libica FIPS integrity check failed.\n"); ++ rv = EXIT_FAILURE; ++ } + #endif /* ICA_FIPS */ + + printf("OpenSSL version is '%s'.\n", OPENSSL_VERSION_TEXT); +-- +2.16.4 + diff --git a/libica-sles15sp2-FIPS-skip-SHA3-tests-if-running-on-hardware-without-.patch b/libica-sles15sp2-FIPS-skip-SHA3-tests-if-running-on-hardware-without-.patch new file mode 100644 index 0000000..361833a --- /dev/null +++ b/libica-sles15sp2-FIPS-skip-SHA3-tests-if-running-on-hardware-without-.patch @@ -0,0 +1,44 @@ +From 54c1a5341c9a5cb5513e52548ab0490f8dafbff6 Mon Sep 17 00:00:00 2001 +From: Joerg Schmidbauer +Date: Thu, 27 Aug 2020 17:08:29 +0200 +Subject: [PATCH] FIPS: skip SHA3 tests if running on hardware without SHA3 + +Signed-off-by: Joerg Schmidbauer +--- + src/fips.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/fips.c b/src/fips.c +index 13a550b..facffee 100644 +--- a/src/fips.c ++++ b/src/fips.c +@@ -95,11 +95,26 @@ SHA_KAT(384, 512); + SHA_KAT(512, 512); + #undef SHA_KAT + ++static inline int sha3_available(void) ++{ ++ sha3_224_context_t sha3_224_context; ++ unsigned char output_hash[SHA3_224_HASH_LENGTH]; ++ unsigned char test_data[] = { 0x61,0x62,0x63 }; ++ int rc = 0; ++ ++ rc = ica_sha3_224(SHA_MSG_PART_ONLY, sizeof(test_data), test_data, ++ &sha3_224_context, output_hash); ++ ++ return (rc == ENODEV ? 0 : 1); ++} ++ + #define SHA3_KAT(_sha_, _ctx_) \ + static int sha3_##_sha_##_kat(void) { \ + sha3_##_ctx_##_context_t ctx; \ + size_t i; \ + unsigned char out[SHA3_##_sha_##_HASH_LENGTH]; \ ++ if (!sha3_available()) \ ++ return 0; \ + for (i = 0; i < SHA3_##_sha_##_TV_LEN; i++) { \ + if (ica_sha3_##_sha_(SHA_MSG_PART_ONLY, \ + SHA3_##_sha_##_TV[i].msg_len, SHA3_##_sha_##_TV[i].msg, \ +-- +2.26.2 + diff --git a/libica-sles15sp2-FIPS-use-full-library-version-for-hmac-filename.patch b/libica-sles15sp2-FIPS-use-full-library-version-for-hmac-filename.patch new file mode 100644 index 0000000..0c1c8fd --- /dev/null +++ b/libica-sles15sp2-FIPS-use-full-library-version-for-hmac-filename.patch @@ -0,0 +1,38 @@ +From 71a04ed492f6cb9dd2de91ff28d0327d17fe702a Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Fri, 28 Aug 2020 14:08:53 +0200 +Subject: [PATCH] FIPS: use full library version for hmac filename. + +Fixes: 231bba3b32bd ("FIPS: introduce HMAC based library integrity check") +Fixes: f9f148487fad ("fix library filename for FIPS integrity check") + +Signed-off-by: Michal Suchanek +--- + src/fips.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/fips.c b/src/fips.c +index facffee..c0055b7 100644 +--- a/src/fips.c ++++ b/src/fips.c +@@ -42,7 +42,7 @@ + * The hard-coded HMAC key to be optionally provided for the library + * integrity test. The recommended key size for HMAC-SHA256 is 64 bytes. + * The known HMAC is supposed to be provided as hex string in a file +- * libica.so.MAJOR.hmac in the same directory as the .so module. ++ * .libica.so.VERSION.hmac in the same directory as the .so module. + */ + static const char hmackey[] = + "0000000000000000000000000000000000000000000000000000000000000000" +@@ -344,7 +344,7 @@ static void fips_lib_integrity_check(void) + { + int rc; + char path[PATH_MAX]; +- const char *libname = "libica.so"; ++ const char *libname = "libica.so." VERSION; + const char *symbolname = "ica_sha256"; + + rc = get_library_path(libname, symbolname, path, sizeof(path)); +-- +2.26.2 + diff --git a/libica-sles15sp2-Zeroize-local-variables.patch b/libica-sles15sp2-Zeroize-local-variables.patch new file mode 100644 index 0000000..6188c42 --- /dev/null +++ b/libica-sles15sp2-Zeroize-local-variables.patch @@ -0,0 +1,99 @@ +From 47a98c0f37af62783d59699b5e10830385817ec2 Mon Sep 17 00:00:00 2001 +From: Joerg Schmidbauer +Date: Fri, 21 Aug 2020 11:29:11 +0200 +Subject: [PATCH] Zeroize local variables + +Some internal variables used to store sensitive information (keys) +were not zeroized before returning to the calling application. + +Signed-off-by: Joerg Schmidbauer +--- + src/ica_api.c | 8 ++++++++ + src/include/s390_aes.h | 4 ++++ + src/include/s390_des.h | 8 ++++++++ + 3 files changed, 20 insertions(+) + +diff --git a/src/ica_api.c b/src/ica_api.c +index eb6b154..5bdf24e 100644 +--- a/src/ica_api.c ++++ b/src/ica_api.c +@@ -1034,6 +1034,8 @@ unsigned int ica_rsa_mod_expo(ica_adapter_handle_t adapter_handle, + if (rc == 0) + stats_increment(ICA_STATS_RSA_ME, hardware, ENCRYPT); + ++ OPENSSL_cleanse(&rb, sizeof(rb)); ++ + return rc; + } + +@@ -1089,6 +1091,10 @@ unsigned int ica_rsa_crt_key_check(ica_rsa_key_crt_t *rsa_key) + + free(tmp_buf); + ++ BN_clear_free(bn_p); ++ BN_clear_free(bn_q); ++ BN_clear_free(bn_invq); ++ + return 1; + } + return 0; +@@ -1147,6 +1153,8 @@ unsigned int ica_rsa_crt(ica_adapter_handle_t adapter_handle, + if (rc == 0) + stats_increment(ICA_STATS_RSA_CRT, hardware, ENCRYPT); + ++ OPENSSL_cleanse(&rb, sizeof(rb)); ++ + return rc; + } + +diff --git a/src/include/s390_aes.h b/src/include/s390_aes.h +index 2e2f325..4a02a4c 100644 +--- a/src/include/s390_aes.h ++++ b/src/include/s390_aes.h +@@ -327,6 +327,8 @@ static inline int s390_aes_ecb_sw(unsigned int function_code, + &aes_key, direction); + } + ++ OPENSSL_cleanse(&aes_key, sizeof(aes_key)); ++ + return 0; + } + +@@ -388,6 +390,8 @@ static inline int s390_aes_cbc_sw(unsigned int function_code, + AES_cbc_encrypt(input_data, output_data, input_length, + &aes_key, (unsigned char *) iv, direction); + ++ OPENSSL_cleanse(&aes_key, sizeof(aes_key)); ++ + return 0; + } + +diff --git a/src/include/s390_des.h b/src/include/s390_des.h +index 811de4d..81d8ed0 100644 +--- a/src/include/s390_des.h ++++ b/src/include/s390_des.h +@@ -112,6 +112,10 @@ static inline int s390_des_ecb_sw(unsigned int function_code, unsigned long inpu + break; + } + ++ OPENSSL_cleanse(&key_schedule1, sizeof(key_schedule1)); ++ OPENSSL_cleanse(&key_schedule2, sizeof(key_schedule2)); ++ OPENSSL_cleanse(&key_schedule2, sizeof(key_schedule3)); ++ + return 0; + } + +@@ -193,6 +197,10 @@ static inline int s390_des_cbc_sw(unsigned int function_code, + break; + }; + ++ OPENSSL_cleanse(&key_schedule1, sizeof(key_schedule1)); ++ OPENSSL_cleanse(&key_schedule2, sizeof(key_schedule2)); ++ OPENSSL_cleanse(&key_schedule2, sizeof(key_schedule3)); ++ + return 0; + } + +-- +2.26.2 + diff --git a/libica.changes b/libica.changes index 63b18e1..9b75f65 100644 --- a/libica.changes +++ b/libica.changes @@ -1,3 +1,31 @@ +------------------------------------------------------------------- +Tue Sep 15 21:08:38 UTC 2020 - Mark Post + +- Fix lack of SHA3 KATs in "make check" processing (bsc#1175277) + * Added libica-sles15sp2-FIPS-add-SHA3-KATs-to-fips_powerup_tests.patch + * Added libica-sles15sp2-FIPS-skip-SHA3-tests-if-running-on-hardware-without-.patch +- Fix FIPS hmac check (bsc#1175356). + * Update FIPS support to upstream + - Refresh libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch + from upstream. + - Add libica-sles15sp2-Build-with-pthread-flag.patch + - Add libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-addon.patch + - Add libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-rename-variables.patch + - Add libica-sles15sp2-FIPS-use-full-library-version-for-hmac-filename.patch + * FIPS check should fail when hmac is missing + - Add libica-sles15sp2-FIPS-fix-inconsistent-error-handling.patch + - Create an hmac for the selftest + - Check that selftest fails without a hmac + - Hash libica.so.3 rather than libica.so.3.6.0 + * Fix hmac key format. It should be hexadecimal, not ASCII + - Refresh libica-sles15sp2-FIPS-hmac-key.patch +- Fix Some internal variables used to store sensitive information + (keys) were not zeroized before returning to the calling application. + (bsc#1175357) + * Added libica-sles15sp2-Zeroize-local-variables.patch +- Updated libica-rpmlintrc to eliminate the warning about the HMAC file + being a hidden file. It is supposed to be hidden. + ------------------------------------------------------------------- Thu May 7 18:01:31 UTC 2020 - Mark Post diff --git a/libica.spec b/libica.spec index 8abeef5..e8d0cfb 100644 --- a/libica.spec +++ b/libica.spec @@ -41,8 +41,16 @@ Patch1: libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-value Patch2: libica-sles15sp2-Fix-DES-and-TDES-key-length.patch Patch3: libica-sles15sp2-FIPS-provide-output-iv-as-required-by-FIPS-tests.patch Patch4: libica-sles15sp2-icainfo-bugfix-for-RSA-and-EC-related-info-for-softw.patch -Patch5: libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch -Patch6: libica-sles15sp2-FIPS-hmac-key.patch +Patch5: libica-sles15sp2-Build-with-pthread-flag.patch +Patch6: libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch +Patch7: libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-addon.patch +Patch8: libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-rename-variables.patch +Patch9: libica-sles15sp2-Zeroize-local-variables.patch +Patch10: libica-sles15sp2-FIPS-add-SHA3-KATs-to-fips_powerup_tests.patch +Patch11: libica-sles15sp2-FIPS-skip-SHA3-tests-if-running-on-hardware-without-.patch +Patch12: libica-sles15sp2-FIPS-use-full-library-version-for-hmac-filename.patch +Patch13: libica-sles15sp2-FIPS-fix-inconsistent-error-handling.patch +Patch99: libica-sles15sp2-FIPS-hmac-key.patch BuildRequires: autoconf BuildRequires: automake @@ -125,7 +133,9 @@ autoreconf --force --install %make_build clean %make_build -%{expand:%%global __os_install_post {%__os_install_post fipshmac %{buildroot}/%{_libdir}/*.so.?.* }} +%define major %(echo %{version} | sed -e 's/[.].*//') + +%{expand:%%global __os_install_post {%__os_install_post fipshmac %{buildroot}/%{_libdir}/*.so.%{major} }} %install %make_install @@ -143,6 +153,9 @@ rm -f %{buildroot}%{_datadir}/doc/libica/* rmdir %{buildroot}%{_datadir}/doc/libica %check +echo Tests should fail without a hash file +! %make_build check +fipshmac src/.libs/libica.so.%{major} %make_build check %pre tools @@ -163,8 +176,9 @@ rmdir %{buildroot}%{_datadir}/doc/libica %files -n libica3 %defattr(-,root,root) -%{_libdir}/libica.so.3* -%{_libdir}/.libica.so.3*hmac +%{_libdir}/libica.so.%{version} +%{_libdir}/libica.so.%{major} +%{_libdir}/.libica.so.%{major}.hmac %files tools %license LICENSE