From 6c3ab49e93b92ba7c7eee435698af7a2b5455ad1 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jan 21 2020 16:50:39 +0000 Subject: import libreswan-3.29-6.el8 --- diff --git a/SOURCES/libreswan-3.25-1724200-halfopen-shunt.patch b/SOURCES/libreswan-3.25-1724200-halfopen-shunt.patch new file mode 100644 index 0000000..839b7c3 --- /dev/null +++ b/SOURCES/libreswan-3.25-1724200-halfopen-shunt.patch @@ -0,0 +1,13 @@ +diff -Naur libreswan-3.25-orig/programs/pluto/state.c libreswan-3.25/programs/pluto/state.c +--- libreswan-3.25-orig/programs/pluto/state.c 2019-07-03 15:52:47.246474906 -0400 ++++ libreswan-3.25/programs/pluto/state.c 2019-07-03 15:54:37.671850020 -0400 +@@ -1101,7 +1101,8 @@ + #endif + + /* If we are failed OE initiator, make shunt bare */ +- if (IS_IKE_SA(st) && (c->policy & POLICY_OPPORTUNISTIC) && ++ if (IS_IKE_SA(st) && c->newest_isakmp_sa == st->st_serialno && ++ (c->policy & POLICY_OPPORTUNISTIC) && + (st->st_state == STATE_PARENT_I1 || st->st_state == STATE_PARENT_I2)) { + ipsec_spi_t failure_shunt = shunt_policy_spi(c, FALSE /* failure_shunt */); + ipsec_spi_t nego_shunt = shunt_policy_spi(c, TRUE /* negotiation shunt */); diff --git a/SOURCES/libreswan-3.29-1699318-show.patch b/SOURCES/libreswan-3.29-1699318-show.patch new file mode 100644 index 0000000..dff8604 --- /dev/null +++ b/SOURCES/libreswan-3.29-1699318-show.patch @@ -0,0 +1,38 @@ +diff -Naur libreswan-3.29-orig/programs/show/show.in libreswan-3.29/programs/show/show.in +--- libreswan-3.29-orig/programs/show/show.in 2019-07-31 20:03:51.794714920 -0400 ++++ libreswan-3.29/programs/show/show.in 2019-07-31 20:02:38.792224647 -0400 +@@ -1,7 +1,7 @@ + #!/usr/bin/python + + import sys +-import commands ++import subprocess + import argparse + try: + import ipaddress +@@ -42,14 +42,14 @@ + source = args.source + else: + getsrccmd = "ip -o ro get %s" % dest +- status, output = commands.getstatusoutput(getsrccmd) ++ output = subprocess.getoutput([getsrccmd]) + try: + source = output.split("src")[1].strip().split(" ")[0] + except Exception: + sys.exit("failed to find source ip for destination %s" % dest) + + if args.debug: +- print "Need to find matching IPsec policy for %s/32 <=> %s/32" % (source, dest) ++ print("Need to find matching IPsec policy for %s/32 <=> %s/32" % (source, dest)) + + if dest: + if "/" in source: +@@ -65,7 +65,7 @@ + sys.exit(1) + + ipxfrmcmd = 'ip -o xfrm pol | grep -v socket | grep "dir out"' +- status, output = commands.getstatusoutput(ipxfrmcmd) ++ output = subprocess.getoutput([ipxfrmcmd]) + polsrc = "" + poldst = "" + for line in output.split("\n"): diff --git a/SOURCES/libreswan-3.29-1714331-nss-kdf.patch b/SOURCES/libreswan-3.29-1714331-nss-kdf.patch new file mode 100644 index 0000000..16b8a5a --- /dev/null +++ b/SOURCES/libreswan-3.29-1714331-nss-kdf.patch @@ -0,0 +1,770 @@ +diff -Naur libreswan-3.29-orig/lib/libswan/ike_alg_aes.c libreswan-3.29/lib/libswan/ike_alg_aes.c +--- libreswan-3.29-orig/lib/libswan/ike_alg_aes.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/lib/libswan/ike_alg_aes.c 2019-08-11 13:31:13.849294693 -0400 +@@ -23,14 +23,21 @@ + + #include "constants.h" /* for BYTES_FOR_BITS() */ + #include "ietf_constants.h" ++ + #include "ike_alg.h" ++#include "ike_alg_encrypt.h" ++#include "ike_alg_integ.h" ++#include "ike_alg_prf.h" ++ + #include "ike_alg_encrypt_nss_cbc_ops.h" + #include "ike_alg_encrypt_nss_ctr_ops.h" + #include "ike_alg_encrypt_nss_gcm_ops.h" ++#ifdef CKM_AES_XCBC_MAC ++#include "ike_alg_prf_nss_ops.h" ++#else + #include "ike_alg_prf_nss_xcbc_ops.h" +-#include "ike_alg_encrypt.h" +-#include "ike_alg_integ.h" +-#include "ike_alg_prf.h" ++#endif ++ + #include "sadb.h" + + const struct encrypt_desc ike_alg_encrypt_aes_cbc = { +@@ -313,6 +320,7 @@ + .encrypt_kernel_audit_name = "AES_CCM_C", + }; + ++#ifdef USE_PRF_AES_XCBC + const struct prf_desc ike_alg_prf_aes_xcbc = { + .common = { + .name = "aes_xcbc", +@@ -326,14 +334,23 @@ + }, + .fips = false, + }, ++#ifdef CKM_AES_XCBC_MAC ++ .nss = { ++ .mechanism = CKM_AES_XCBC_MAC, ++ }, ++ .prf_ops = &ike_alg_prf_nss_ops, ++#else ++ /* XXX: NSS encryption algorithm used by custom XCBC */ + .nss = { + .mechanism = CKM_AES_ECB, + }, ++ .prf_ops = &ike_alg_prf_nss_xcbc_ops, ++#endif + .prf_key_size = BYTES_FOR_BITS(128), + .prf_output_size = BYTES_FOR_BITS(128), +- .prf_ops = &ike_alg_prf_nss_xcbc_ops, + .prf_ike_audit_name = "aes_xcbc", + }; ++#endif + + const struct integ_desc ike_alg_integ_aes_xcbc = { + .common = { +@@ -351,7 +368,7 @@ + .integ_keymat_size = AES_XCBC_DIGEST_SIZE, + .integ_output_size = AES_XCBC_DIGEST_SIZE_TRUNC, /* XXX 96 */ + .integ_ikev1_ah_transform = AH_AES_XCBC_MAC, +-#ifdef USE_XCBC ++#ifdef USE_PRF_AES_XCBC + .prf = &ike_alg_prf_aes_xcbc, + #endif + #ifdef SADB_X_AALG_AES_XCBC_MAC +diff -Naur libreswan-3.29-orig/lib/libswan/ike_alg.c libreswan-3.29/lib/libswan/ike_alg.c +--- libreswan-3.29-orig/lib/libswan/ike_alg.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/lib/libswan/ike_alg.c 2019-08-11 13:31:13.850294706 -0400 +@@ -478,7 +478,7 @@ + &ike_alg_prf_sha2_384, + &ike_alg_prf_sha2_512, + #endif +-#ifdef USE_XCBC ++#ifdef USE_PRF_AES_XCBC + &ike_alg_prf_aes_xcbc, + #endif + }; +diff -Naur libreswan-3.29-orig/lib/libswan/ike_alg_md5.c libreswan-3.29/lib/libswan/ike_alg_md5.c +--- libreswan-3.29-orig/lib/libswan/ike_alg_md5.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/lib/libswan/ike_alg_md5.c 2019-08-11 13:31:13.851294720 -0400 +@@ -26,7 +26,7 @@ + #include "ike_alg_hash.h" + #include "ike_alg_prf.h" + #include "ike_alg_hash_nss_ops.h" +-#include "ike_alg_prf_hmac_ops.h" ++#include "ike_alg_prf_nss_ops.h" + #include "sadb.h" + + const struct hash_desc ike_alg_hash_md5 = { +@@ -63,10 +63,13 @@ + [IKEv2_ALG_ID] = IKEv2_PRF_HMAC_MD5, + }, + }, ++ .nss = { ++ .mechanism = CKM_MD5_HMAC, ++ }, + .prf_key_size = MD5_DIGEST_SIZE, + .prf_output_size = MD5_DIGEST_SIZE, + .hasher = &ike_alg_hash_md5, +- .prf_ops = &ike_alg_prf_hmac_ops, ++ .prf_ops = &ike_alg_prf_nss_ops, + .prf_ike_audit_name = "md5", + }; + +diff -Naur libreswan-3.29-orig/mk/config.mk libreswan-3.29/mk/config.mk +--- libreswan-3.29-orig/mk/config.mk 2019-08-11 13:30:45.756906229 -0400 ++++ libreswan-3.29/mk/config.mk 2019-08-11 13:31:13.852294734 -0400 +@@ -239,6 +239,18 @@ + NSS_UTIL_LDFLAGS ?= -lnssutil3 + NSPR_LDFLAGS ?= -lnspr4 + ++# Use the NSS Key Derivation Function (KDF) instead of using the NSS ++# secure hash functions to build our own PRF. With this enabled, ++# libreswan itself no longer needs to be FIPS validated. ++# Requires NSS >= 3.44 ++USE_NSS_PRF?=false ++ifeq ($(USE_NSS_PRF),true) ++NSSFLAGS+=-DUSE_NSS_PRF ++USE_NSS_AVA_COPY=false ++endif ++ ++# ++# + # Use local copy of nss function CERT_CompareAVA + # See https://bugzilla.mozilla.org/show_bug.cgi?id=1336487 + # This work-around is needed with nss versions before 3.30. +diff -Naur libreswan-3.29-orig/mk/userland-cflags.mk libreswan-3.29/mk/userland-cflags.mk +--- libreswan-3.29-orig/mk/userland-cflags.mk 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/mk/userland-cflags.mk 2019-08-11 13:31:13.853294748 -0400 +@@ -269,9 +269,10 @@ + LIBTWOFISH= ${OBJDIRTOP}/lib/libcrypto/libtwofish/libtwofish.a + endif + +-USE_XCBC ?= true +-ifeq ($(USE_XCBC),true) +-USERLAND_CFLAGS += -DUSE_XCBC ++# Requires NSS >= 3.44 or backport ++USE_PRF_AES_XCBC ?= true ++ifeq ($(USE_PRF_AES_XCBC),true) ++USERLAND_CFLAGS += -DUSE_PRF_AES_XCBC + endif + + # +diff -Naur libreswan-3.29-orig/programs/pluto/crypt_symkey.c libreswan-3.29/programs/pluto/crypt_symkey.c +--- libreswan-3.29-orig/programs/pluto/crypt_symkey.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/crypt_symkey.c 2019-08-11 13:31:13.854294762 -0400 +@@ -15,7 +15,6 @@ + * for more details. + */ + +-#include "libreswan.h" + #include "lswalloc.h" + #include "lswlog.h" + #include "ike_alg.h" +@@ -23,6 +22,7 @@ + #include "crypto.h" + #include "lswfips.h" + #include "lswnss.h" ++#include "crypt_prf.h" /* hack */ + + #define SPACES " " + +@@ -590,9 +590,51 @@ + + PK11SymKey *prf_key_from_symkey_bytes(const char *name, + const struct prf_desc *prf, +- size_t symkey_start_byte, size_t sizeof_symkey, ++ size_t symkey_start_byte, size_t symkey_size, + PK11SymKey *source_key) + { ++#ifdef CKM_AES_XCBC_MAC ++ if (prf->nss.mechanism == CKM_AES_XCBC_MAC && ++ symkey_size != prf->prf_key_size) { ++ PK11SymKey *tmp = symkey_from_symkey("tmp", source_key, ++ CKM_VENDOR_DEFINED, /*flags*/0, ++ symkey_start_byte, symkey_size); ++ /* ++ * code lifted from ike_alg_prf_nss_xcbc_ops.c ++ */ ++ size_t dkey_sz = sizeof_symkey(tmp); ++ if (dkey_sz < prf->prf_key_size) { ++ DBGF(DBG_CRYPT, "XCBC: Key %zd<%zd too small, padding with zeros", ++ dkey_sz, prf->prf_key_size); ++ /* ++ * right pad with zeros ++ */ ++ chunk_t zeros = alloc_chunk(prf->prf_key_size - dkey_sz, "zeros"); ++ append_symkey_chunk(&tmp, zeros); ++ freeanychunk(zeros); ++ } else { ++ pexpect(dkey_sz > prf->prf_key_size); ++ DBGF(DBG_CRYPT, "XCBC: Key %zd>%zd too big, rehashing to size", ++ dkey_sz, prf->prf_key_size); ++ /* ++ * put the key through the mac with a zero ++ * key; recursive ++ */ ++ chunk_t zeros = alloc_chunk(prf->prf_key_size, "zeros"); ++ PK11SymKey *zero_key = prf_key_from_bytes("zeros", prf, zeros.ptr, zeros.len); ++ freeanychunk(zeros); ++ struct crypt_prf *xmac = crypt_prf_init_symkey("xmac", prf, "zero", zero_key); ++ crypt_prf_update_symkey(xmac, "tmp", tmp); ++ PK11SymKey *tmp2 = crypt_prf_final_symkey(&xmac); ++ release_symkey(name, "tmp2", &tmp); ++ tmp = tmp2; ++ } ++ PK11SymKey *key = symkey_from_symkey(name, tmp, CKM_AES_XCBC_MAC, CKF_SIGN, ++ 0, prf->prf_key_size); ++ release_symkey(name, "tmp", &tmp); ++ return key; ++ } ++#endif + /* + * NSS expects a key's mechanism to match the NSS algorithm + * the key is intended for. If this is wrong then the +@@ -614,7 +656,7 @@ + mechanism = prf->nss.mechanism; + } + return symkey_from_symkey(name, source_key, mechanism, flags, +- symkey_start_byte, sizeof_symkey); ++ symkey_start_byte, symkey_size); + } + + /* +@@ -656,9 +698,13 @@ + PK11SymKey *key_from_symkey_bytes(PK11SymKey *source_key, + size_t next_byte, size_t sizeof_key) + { +- return symkey_from_symkey("result", source_key, +- CKM_EXTRACT_KEY_FROM_KEY, +- 0, next_byte, sizeof_key); ++ if (sizeof_key == 0) { ++ return NULL; ++ } else { ++ return symkey_from_symkey("result", source_key, ++ CKM_EXTRACT_KEY_FROM_KEY, ++ 0, next_byte, sizeof_key); ++ } + } + + /* +diff -Naur libreswan-3.29-orig/programs/pluto/ikev1_prf.c libreswan-3.29/programs/pluto/ikev1_prf.c +--- libreswan-3.29-orig/programs/pluto/ikev1_prf.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/ikev1_prf.c 2019-08-11 13:31:13.855294776 -0400 +@@ -17,8 +17,11 @@ + * for more details. + */ + ++#include "lswlog.h" /* for LSWLOG_PEXPECT() */ ++ + #include "ikev1_prf.h" + ++#include "ike_alg.h" + #include "crypt_prf.h" + #include "crypt_symkey.h" + +@@ -32,6 +35,25 @@ + const chunk_t Nr, + /*const*/ PK11SymKey *dh_secret /* NSS doesn't do const */) + { ++#ifdef USE_NSS_PRF ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf_params = { ++ .prfMechanism = prf_desc->nss.mechanism, ++ .bDataAsKey = CK_TRUE, ++ .bRekey = CK_FALSE, ++ .pNi = Ni.ptr, ++ .ulNiLen = Ni.len, ++ .pNr = Nr.ptr, ++ .ulNrLen = Nr.len, ++ }; ++ SECItem params = { ++ .data = (unsigned char *)&ike_prf_params, ++ .len = sizeof(ike_prf_params), ++ }; ++ ++ return PK11_Derive(dh_secret, CKM_NSS_IKE_PRF_DERIVE, ¶ms, ++ CKM_NSS_IKE1_PRF_DERIVE, CKA_DERIVE, ++ 0); ++#else + /* key = Ni|Nr */ + chunk_t key = clone_chunk_chunk(Ni, Nr, "key = Ni|Nr"); + struct crypt_prf *prf = crypt_prf_init_chunk("SKEYID sig", +@@ -42,6 +64,7 @@ + crypt_prf_update_symkey(prf, "g^xy", dh_secret); + /* generate */ + return crypt_prf_final_symkey(&prf); ++#endif + } + + /* +@@ -51,6 +74,33 @@ + chunk_t pre_shared_key, + chunk_t Ni, chunk_t Nr) + { ++#ifdef USE_NSS_PRF ++ PK11SymKey *psk = prf_key_from_bytes("psk", prf_desc, ++ pre_shared_key.ptr, pre_shared_key.len); ++ PK11SymKey *skeyid; ++ if (psk == NULL) { ++ return NULL; ++ } ++ ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf_params = { ++ .prfMechanism = prf_desc->nss.mechanism, ++ .bDataAsKey = CK_FALSE, ++ .bRekey = CK_FALSE, ++ .pNi = Ni.ptr, ++ .ulNiLen = Ni.len, ++ .pNr = Nr.ptr, ++ .ulNrLen = Nr.len, ++ }; ++ SECItem params = { ++ .data = (unsigned char *)&ike_prf_params, ++ .len = sizeof(ike_prf_params), ++ }; ++ skeyid = PK11_Derive(psk, CKM_NSS_IKE_PRF_DERIVE, ¶ms, ++ CKM_NSS_IKE1_PRF_DERIVE, CKA_DERIVE, ++ 0 ); ++ release_symkey("SKEYID psk", "psk", &psk); ++ return skeyid; ++#else + /* key = pre-shared-key */ + struct crypt_prf *prf = crypt_prf_init_chunk("SKEYID psk", prf_desc, + "psk", pre_shared_key); +@@ -59,6 +109,7 @@ + crypt_prf_update_chunk(prf, "Nr", Nr); + /* generate */ + return crypt_prf_final_symkey(&prf); ++#endif + } + + /* +@@ -69,6 +120,26 @@ + PK11SymKey *dh_secret, + chunk_t cky_i, chunk_t cky_r) + { ++#ifdef USE_NSS_PRF ++ CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf_params = { ++ .prfMechanism = prf_desc->nss.mechanism, ++ .bHasPrevKey = CK_FALSE, ++ .hKeygxy = PK11_GetSymKeyHandle(dh_secret), ++ .pCKYi = cky_i.ptr, ++ .ulCKYiLen = cky_i.len, ++ .pCKYr = cky_r.ptr, ++ .ulCKYrLen = cky_r.len, ++ .keyNumber = 0, ++ }; ++ SECItem params = { ++ .data = (unsigned char *)&ike1_prf_params, ++ .len = sizeof(ike1_prf_params), ++ }; ++ ++ return PK11_Derive(skeyid, CKM_NSS_IKE1_PRF_DERIVE, ¶ms, ++ CKM_EXTRACT_KEY_FROM_KEY, CKA_DERIVE, ++ 0); ++#else + /* key = SKEYID */ + struct crypt_prf *prf = crypt_prf_init_symkey("SKEYID_d", prf_desc, + "SKEYID", skeyid); +@@ -79,6 +150,7 @@ + crypt_prf_update_byte(prf, "0", 0); + /* generate */ + return crypt_prf_final_symkey(&prf); ++#endif + } + + /* +@@ -89,6 +161,27 @@ + PK11SymKey *skeyid_d, PK11SymKey *dh_secret, + chunk_t cky_i, chunk_t cky_r) + { ++#ifdef USE_NSS_PRF ++ CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf_params = { ++ .prfMechanism = prf_desc->nss.mechanism, ++ .bHasPrevKey = CK_TRUE, ++ .hKeygxy = PK11_GetSymKeyHandle(dh_secret), ++ .hPrevKey = PK11_GetSymKeyHandle(skeyid_d), ++ .pCKYi = cky_i.ptr, ++ .ulCKYiLen = cky_i.len, ++ .pCKYr = cky_r.ptr, ++ .ulCKYrLen = cky_r.len, ++ .keyNumber = 1, ++ }; ++ SECItem params = { ++ .data = (unsigned char *)&ike1_prf_params, ++ .len = sizeof(ike1_prf_params), ++ }; ++ ++ return PK11_Derive(skeyid, CKM_NSS_IKE1_PRF_DERIVE, ¶ms, ++ CKM_EXTRACT_KEY_FROM_KEY, CKA_DERIVE, ++ 0); ++#else + /* key = SKEYID */ + struct crypt_prf *prf = crypt_prf_init_symkey("SKEYID_a", prf_desc, + "SKEYID", skeyid); +@@ -100,6 +193,7 @@ + crypt_prf_update_byte(prf, "1", 1); + /* generate */ + return crypt_prf_final_symkey(&prf); ++#endif + } + + /* +@@ -110,6 +204,27 @@ + PK11SymKey *skeyid_a, PK11SymKey *dh_secret, + chunk_t cky_i, chunk_t cky_r) + { ++#ifdef USE_NSS_PRF ++ CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf_params = { ++ .prfMechanism = prf_desc->nss.mechanism, ++ .bHasPrevKey = CK_TRUE, ++ .hKeygxy = PK11_GetSymKeyHandle(dh_secret), ++ .hPrevKey = PK11_GetSymKeyHandle(skeyid_a), ++ .pCKYi = cky_i.ptr, ++ .ulCKYiLen = cky_i.len, ++ .pCKYr = cky_r.ptr, ++ .ulCKYrLen = cky_r.len, ++ .keyNumber = 2, ++ }; ++ SECItem params = { ++ .data = (unsigned char *)&ike1_prf_params, ++ .len = sizeof(ike1_prf_params), ++ }; ++ ++ return PK11_Derive(skeyid, CKM_NSS_IKE1_PRF_DERIVE, ¶ms, ++ CKM_EXTRACT_KEY_FROM_KEY, CKA_DERIVE, ++ 0); ++#else + /* key = SKEYID */ + struct crypt_prf *prf = crypt_prf_init_symkey("SKEYID_e", prf_desc, + "SKEYID", skeyid); +@@ -121,6 +236,7 @@ + crypt_prf_update_byte(prf, "2", 2); + /* generate */ + return crypt_prf_final_symkey(&prf); ++#endif + } + + PK11SymKey *appendix_b_keymat_e(const struct prf_desc *prf_desc, +@@ -128,6 +244,20 @@ + PK11SymKey *skeyid_e, + unsigned required_keymat) + { ++#ifdef USE_NSS_PRF ++ CK_MECHANISM_TYPE mechanism = prf_desc->nss.mechanism; ++ CK_MECHANISM_TYPE target = encrypter->nss.mechanism; ++ SECItem params = { ++ .data = (unsigned char *)&mechanism, ++ .len = sizeof(mechanism), ++ }; ++ /* for when ENCRYPTER isn't NSS */ ++ if (target == 0) target = CKM_EXTRACT_KEY_FROM_KEY; ++ ++ return PK11_DeriveWithFlags(skeyid_e, CKM_NSS_IKE1_APP_B_PRF_DERIVE, ++ ¶ms, target, CKA_ENCRYPT, ++ required_keymat, CKF_DECRYPT); ++#else + if (sizeof_symkey(skeyid_e) >= required_keymat) { + return encrypt_key_from_symkey_bytes("keymat", encrypter, + 0, required_keymat, +@@ -160,4 +290,5 @@ + keymat); + release_symkey(__func__, "keymat", &keymat); + return cryptkey; ++#endif + } +diff -Naur libreswan-3.29-orig/programs/pluto/ikev2_prf.c libreswan-3.29/programs/pluto/ikev2_prf.c +--- libreswan-3.29-orig/programs/pluto/ikev2_prf.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/ikev2_prf.c 2019-08-11 13:33:13.680951735 -0400 +@@ -32,12 +32,44 @@ + /* + * IKEv2 - RFC4306 2.14 SKEYSEED - calculation. + */ ++#ifdef USE_NSS_PRF ++static PK11SymKey *ikev2_prfplus_key_data( ++ const struct prf_desc *prf_desc, ++ PK11SymKey *key, ++ PK11SymKey *seed_key, ++ chunk_t seed_data, ++ size_t required_keymat) ++{ ++ CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS ike_prf_plus_params = { ++ .pSeedData = seed_data.ptr, ++ .ulSeedDataLen = seed_data.len, ++ .prfMechanism = prf_desc->nss.mechanism, ++ }; ++ if (seed_key == NULL) { ++ ike_prf_plus_params.bHasSeedKey = CK_FALSE; ++ } else { ++ ike_prf_plus_params.bHasSeedKey = CK_TRUE; ++ ike_prf_plus_params.hSeedKey = PK11_GetSymKeyHandle(seed_key); ++ } ++ SECItem params = { ++ .data = (unsigned char *)&ike_prf_plus_params, ++ .len = sizeof(ike_prf_plus_params), ++ }; ++ ++ return PK11_Derive(key, CKM_NSS_IKE_PRF_PLUS_DERIVE, ¶ms, ++ CKM_EXTRACT_KEY_FROM_KEY, CKA_DERIVE, ++ required_keymat); ++} ++#endif + + PK11SymKey *ikev2_prfplus(const struct prf_desc *prf_desc, + PK11SymKey *key, + PK11SymKey *seed, + size_t required_keymat) + { ++#ifdef USE_NSS_PRF ++ return ikev2_prfplus_key_data(prf_desc, key, seed, empty_chunk, required_keymat); ++#else + uint8_t count = 1; + + /* T1(prfplus) = prf(KEY, SEED|1) */ +@@ -66,6 +98,7 @@ + } + release_symkey(__func__, "old_t[final]", &old_t); + return prfplus; ++#endif + } + + /* +@@ -77,6 +110,33 @@ + const chunk_t Ni, const chunk_t Nr, + PK11SymKey *dh_secret) + { ++ ++#ifdef USE_NSS_PRF ++ int is_aes_prf = 0; ++ switch (prf_desc->common.id[IKEv2_ALG_ID]) { ++ case IKEv2_PRF_AES128_CMAC: ++ case IKEv2_PRF_AES128_XCBC: ++ is_aes_prf = 1; ++ } ++ ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf_params = { ++ .prfMechanism = prf_desc->nss.mechanism, ++ .bDataAsKey = CK_TRUE, ++ .bRekey = CK_FALSE, ++ .pNi = Ni.ptr, ++ .ulNiLen = is_aes_prf ? BYTES_FOR_BITS(64) : Ni.len, ++ .pNr = Nr.ptr, ++ .ulNrLen = is_aes_prf ? BYTES_FOR_BITS(64) : Nr.len, ++ }; ++ SECItem params = { ++ .data = (unsigned char *)&ike_prf_params, ++ .len = sizeof(ike_prf_params), ++ }; ++ ++ return PK11_Derive(dh_secret, CKM_NSS_IKE_PRF_DERIVE, ¶ms, ++ CKM_NSS_IKE_PRF_PLUS_DERIVE, CKA_DERIVE, ++ 0); ++#else + /* + * 2.14. Generating Keying Material for the IKE SA + * +@@ -117,6 +177,7 @@ + crypt_prf_update_symkey(prf, "g^ir", dh_secret); + /* generate */ + return crypt_prf_final_symkey(&prf); ++#endif + } + + /* +@@ -127,6 +188,26 @@ + PK11SymKey *new_dh_secret, + const chunk_t Ni, const chunk_t Nr) + { ++#ifdef USE_NSS_PRF ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf_params = { ++ .prfMechanism = prf_desc->nss.mechanism, ++ .bDataAsKey = CK_FALSE, ++ .bRekey = CK_TRUE, ++ .hNewKey = PK11_GetSymKeyHandle(new_dh_secret), ++ .pNi = Ni.ptr, ++ .ulNiLen = Ni.len, ++ .pNr = Nr.ptr, ++ .ulNrLen = Nr.len, ++ }; ++ SECItem params = { ++ .data = (unsigned char *)&ike_prf_params, ++ .len = sizeof(ike_prf_params), ++ }; ++ ++ return PK11_Derive(SK_d_old, CKM_NSS_IKE_PRF_DERIVE, ¶ms, ++ CKM_NSS_IKE_PRF_PLUS_DERIVE, CKA_DERIVE, ++ 0); ++#else + /* key = SK_d (old) */ + struct crypt_prf *prf = crypt_prf_init_symkey("ike sa rekey skeyseed", prf_desc, + "SK_d (old)", SK_d_old); +@@ -141,6 +222,7 @@ + crypt_prf_update_chunk(prf, "Nr", Nr); + /* generate */ + return crypt_prf_final_symkey(&prf); ++#endif + } + + /* +@@ -152,6 +234,17 @@ + const ike_spis_t *SPIir, + size_t required_bytes) + { ++#ifdef USE_NSS_PRF ++ chunk_t seed_data; ++ PK11SymKey *prf_plus; ++ ++ seed_data = clone_chunk_chunk(Ni, Nr, "seed_data = Ni || Nr"); ++ append_chunk_bytes("seed_data = Nir || SPIi", &seed_data, &SPIir->initiator, sizeof(SPIir->initiator)); ++ append_chunk_bytes("seed_data = Nir || SPIir", &seed_data, &SPIir->responder, sizeof(SPIir->responder)); ++ prf_plus = ikev2_prfplus_key_data(prf_desc, skeyseed, NULL, seed_data, required_bytes); ++ freeanychunk(seed_data); ++ return prf_plus; ++#else + PK11SymKey *data = symkey_from_chunk("data", Ni); + append_symkey_chunk(&data, Nr); + append_symkey_bytes(&data, &SPIir->initiator, sizeof(SPIir->initiator)); +@@ -161,6 +254,7 @@ + required_bytes); + release_symkey(__func__, "data", &data); + return prfplus; ++#endif + } + + /* +@@ -172,6 +266,24 @@ + const chunk_t Ni, const chunk_t Nr, + size_t required_bytes) + { ++ if (required_bytes == 0) { ++ /* ++ * For instance esp=null-none. Caller should ++ * interpret NULL to mean empty (NSS doesn't create ++ * zero length keys). ++ */ ++ dbg("No CHILD SA KEMAT is required"); ++ return NULL; ++ } ++#ifdef USE_NSS_PRF ++ chunk_t seed_data; ++ PK11SymKey *prf_plus; ++ ++ seed_data = clone_chunk_chunk(Ni, Nr, "seed_data = Ni || Nr"); ++ prf_plus = ikev2_prfplus_key_data(prf_desc, SK_d, new_dh_secret, seed_data, required_bytes); ++ freeanychunk(seed_data); ++ return prf_plus; ++#else + PK11SymKey *data; + if (new_dh_secret == NULL) { + data = symkey_from_chunk("data", Ni); +@@ -185,4 +297,5 @@ + required_bytes); + release_symkey(__func__, "data", &data); + return prfplus; ++#endif + } +diff -Naur libreswan-3.29-orig/programs/pluto/ikev2_psk.c libreswan-3.29/programs/pluto/ikev2_psk.c +--- libreswan-3.29-orig/programs/pluto/ikev2_psk.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/ikev2_psk.c 2019-08-11 13:31:13.858294817 -0400 +@@ -181,6 +181,36 @@ + PK11SymKey *prf_psk; + + { ++ static const char psk_key_pad_str[] = "Key Pad for IKEv2"; /* RFC 4306 2:15 */ ++#ifdef USE_NSS_PRF ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf_params; ++ SECItem params; ++ CK_MECHANISM_TYPE prf_mech = st->st_oakley.ta_prf->nss.mechanism; ++ PK11SymKey *pss_key = prf_key_from_bytes("pss", st->st_oakley.ta_prf, ++ pss->ptr, pss->len); ++ if (pss_key == NULL) { ++ if (libreswan_fipsmode()) { ++ PASSERT_FAIL("FIPS: failure creating %s PRF context for digesting PSK", ++ st->st_oakley.ta_prf->common.name); ++ } ++ loglog(RC_LOG_SERIOUS, ++ "failure creating %s PRF context for digesting PSK", ++ st->st_oakley.ta_prf->common.name); ++ return FALSE; ++ } ++ ++ ike_prf_params.prfMechanism = prf_mech; ++ ike_prf_params.bDataAsKey = CK_FALSE; ++ ike_prf_params.bRekey = CK_FALSE; ++ ike_prf_params.pNi = (CK_BYTE_PTR) psk_key_pad_str; ++ ike_prf_params.ulNiLen = sizeof(psk_key_pad_str) - 1; ++ ike_prf_params.pNr = NULL; ++ ike_prf_params.ulNrLen = 0; ++ params.data = (unsigned char *)&ike_prf_params; ++ params.len = sizeof(ike_prf_params); ++ prf_psk = PK11_Derive(pss_key, CKM_NSS_IKE_PRF_DERIVE, ¶ms, prf_mech, CKA_SIGN, 0); ++ release_symkey("psk pss_key", "pss_key", &pss_key); ++#else + struct crypt_prf *prf = + crypt_prf_init_chunk(" = prf(,\"Key Pad for IKEv2\")", + st->st_oakley.ta_prf, +@@ -196,12 +226,11 @@ + return FALSE; + } + +- static const char psk_key_pad_str[] = "Key Pad for IKEv2"; /* RFC 4306 2:15 */ +- + crypt_prf_update_bytes(prf, psk_key_pad_str, /* name */ + psk_key_pad_str, + sizeof(psk_key_pad_str) - 1); + prf_psk = crypt_prf_final_symkey(&prf); ++#endif + } + + /* calculate outer prf */ +diff -Naur libreswan-3.29-orig/programs/pluto/plutomain.c libreswan-3.29/programs/pluto/plutomain.c +--- libreswan-3.29-orig/programs/pluto/plutomain.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/plutomain.c 2019-08-11 13:31:13.859294831 -0400 +@@ -189,6 +189,11 @@ + #ifdef NSS_IPSEC_PROFILE + " (IPsec profile)" + #endif ++#ifdef USE_NSS_PRF ++ " (NSS-PRF)" ++#else ++ " (native-PRF)" ++#endif + #ifdef USE_DNSSEC + " DNSSEC" + #endif +diff -Naur libreswan-3.29-orig/programs/pluto/prf_test_vectors.c libreswan-3.29/programs/pluto/prf_test_vectors.c +--- libreswan-3.29-orig/programs/pluto/prf_test_vectors.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/prf_test_vectors.c 2019-08-11 13:31:13.860294845 -0400 +@@ -34,6 +34,7 @@ + * Ref: https://tools.ietf.org/html/rfc4435: Test Vectors + */ + ++#ifdef USE_PRF_AES_XCBC + const struct prf_test_vectors aes_xcbc_prf_tests = { + .prf = &ike_alg_prf_aes_xcbc, + .tests = { +@@ -105,6 +106,10 @@ + .message = "0x000102030405060708090a0b0c0d0e0f10111213", + .prf_output = "0x47f51b4564966215b8985c63055ed308", + }, ++ /* ++ * XXX: for some reason NSS explodes when trying to ++ * create a non-standard AES_XCBC_MAC key. ++ */ + { + .description = "Test Case AES-XCBC-PRF-128 with 20-byte input (key length 10)", + .key = "0x00010203040506070809", +@@ -124,7 +129,9 @@ + } + }, + }; ++#endif + ++/* So far we only have AES_XCBC PRF test vectors :/ */ + static bool test_prf_vector(const struct prf_desc *prf, + const struct prf_test_vector *test) + { +@@ -137,7 +144,6 @@ + : alloc_chunk(test->message_size, __func__); + chunk_t prf_output = decode_to_chunk(__func__, test->prf_output); + +- + /* chunk interface */ + struct crypt_prf *chunk_prf = crypt_prf_init_chunk("PRF chunk interface", prf, + "key", chunk_key); diff --git a/SOURCES/libreswan-3.29-1723957-audit.patch b/SOURCES/libreswan-3.29-1723957-audit.patch new file mode 100644 index 0000000..785630d --- /dev/null +++ b/SOURCES/libreswan-3.29-1723957-audit.patch @@ -0,0 +1,301 @@ +diff -Naur libreswan-3.29-orig/programs/pluto/ikev1.c libreswan-3.29/programs/pluto/ikev1.c +--- libreswan-3.29-orig/programs/pluto/ikev1.c 2019-06-26 22:03:27.801184503 -0400 ++++ libreswan-3.29/programs/pluto/ikev1.c 2019-06-27 13:26:11.443969779 -0400 +@@ -2675,6 +2675,12 @@ + passert(st != NULL); + pexpect(!state_is_busy(st)); + ++ if (result > STF_OK) { ++ if (st != NULL) { ++ linux_audit_conn(md->st, IS_IKE_SA_ESTABLISHED(md->st) ? LAK_CHILD_FAIL : LAK_PARENT_FAIL); ++ } ++ } ++ + switch (result) { + case STF_OK: + { +diff -Naur libreswan-3.29-orig/programs/pluto/ikev1_quick.c libreswan-3.29/programs/pluto/ikev1_quick.c +--- libreswan-3.29-orig/programs/pluto/ikev1_quick.c 2019-06-26 22:03:27.803184531 -0400 ++++ libreswan-3.29/programs/pluto/ikev1_quick.c 2019-06-27 13:23:53.787080070 -0400 +@@ -1663,6 +1663,9 @@ + if (!install_inbound_ipsec_sa(st)) + return STF_INTERNAL_ERROR; /* ??? we may be partly committed */ + ++ /* we only audit once for IPsec SA's, we picked the inbound SA */ ++ linux_audit_conn(st, LAK_CHILD_START); ++ + /* encrypt message, except for fixed part of header */ + + if (!ikev1_encrypt_message(&rbody, st)) { +diff -Naur libreswan-3.29-orig/programs/pluto/ikev2.c libreswan-3.29/programs/pluto/ikev2.c +--- libreswan-3.29-orig/programs/pluto/ikev2.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/ikev2.c 2019-06-27 13:25:16.529215928 -0400 +@@ -3204,6 +3204,13 @@ + lswlog_v2_stf_status(buf, result); + } + ++ /* audit log failures - success is audit logged in ikev2_ike_sa_established() */ ++ if (result > STF_OK) { ++ if (st != NULL) { ++ linux_audit_conn(st, IS_IKE_SA_ESTABLISHED(st) ? LAK_CHILD_FAIL : LAK_PARENT_FAIL); ++ } ++ } ++ + switch (result) { + + case STF_SUSPEND: +diff -Naur libreswan-3.29-orig/programs/pluto/ikev2_child.c libreswan-3.29/programs/pluto/ikev2_child.c +--- libreswan-3.29-orig/programs/pluto/ikev2_child.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/ikev2_child.c 2019-06-27 13:23:53.788080084 -0400 +@@ -102,6 +102,10 @@ + return STF_OK; + } + ++/* ++ * The caller could have done the linux_audit_conn() call, except one case ++ * here deletes the state before returning an STF error ++ */ + stf_status ikev2_child_sa_respond(struct msg_digest *md, + pb_stream *outpbs, + enum isakmp_xchg_types isa_xchg) +diff -Naur libreswan-3.29-orig/programs/pluto/ikev2_parent.c libreswan-3.29/programs/pluto/ikev2_parent.c +--- libreswan-3.29-orig/programs/pluto/ikev2_parent.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/ikev2_parent.c 2019-06-27 13:23:53.789080097 -0400 +@@ -239,6 +239,7 @@ + c->newest_isakmp_sa = ike->sa.st_serialno; + v2_schedule_replace_event(&ike->sa); + ike->sa.st_viable_parent = TRUE; ++ linux_audit_conn(&ike->sa, LAK_PARENT_START); + pstat_sa_established(&ike->sa); + } + +@@ -1581,6 +1582,24 @@ + libreswan_log("IKE_AUTH response contained an unknown error notification (%d)", n); + } else { + libreswan_log("IKE_AUTH response contained the error notification %s", name); ++ /* ++ * There won't be a child state transition, so log if error is child related. ++ * see RFC 7296 Section 1.2 ++ */ ++ switch(n) { ++ case v2N_NO_PROPOSAL_CHOSEN: ++ case v2N_SINGLE_PAIR_REQUIRED: ++ case v2N_NO_ADDITIONAL_SAS: ++ case v2N_INTERNAL_ADDRESS_FAILURE: ++ case v2N_FAILED_CP_REQUIRED: ++ case v2N_TS_UNACCEPTABLE: ++ case v2N_INVALID_SELECTORS: ++ /* fallthrough */ ++ linux_audit_conn(st, LAK_CHILD_FAIL); ++ break; ++ default: ++ break; ++ } + } + } + } +@@ -3063,10 +3082,6 @@ + ikev2_ike_sa_established(pexpect_ike_sa(st), md->svm, + STATE_PARENT_R2); + +-#ifdef USE_LINUX_AUDIT +- linux_audit_conn(st, LAK_PARENT_START); +-#endif +- + if (LHAS(st->hidden_variables.st_nat_traversal, NATED_HOST)) { + /* ensure we run keepalives if needed */ + if (c->nat_keepalive) +@@ -3801,10 +3816,6 @@ + ikev2_ike_sa_established(pexpect_ike_sa(pst), md->svm, + STATE_PARENT_I3); + +-#ifdef USE_LINUX_AUDIT +- linux_audit_conn(st, LAK_PARENT_START); +-#endif +- + if (LHAS(st->hidden_variables.st_nat_traversal, NATED_HOST)) { + /* ensure we run keepalives if needed */ + if (c->nat_keepalive) +diff -Naur libreswan-3.29-orig/programs/pluto/kernel.c libreswan-3.29/programs/pluto/kernel.c +--- libreswan-3.29-orig/programs/pluto/kernel.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/kernel.c 2019-06-27 13:23:53.790080111 -0400 +@@ -3334,7 +3334,8 @@ + } + + #ifdef USE_LINUX_AUDIT +- linux_audit_conn(st, LAK_CHILD_START); ++ if (inbound_also) ++ linux_audit_conn(st, LAK_CHILD_START); + #endif + statetime_stop(&start, "%s()", __func__); + +@@ -3378,8 +3379,13 @@ + { + #ifdef USE_LINUX_AUDIT + /* XXX in IKEv2 we get a spurious call with a parent st :( */ +- if (IS_CHILD_SA(st)) +- linux_audit_conn(st, LAK_CHILD_DESTROY); ++ if (IS_CHILD_SA(st)) { ++ /* child destruction already logged for STATE_CHILDSA_DEL state */ ++ if (st->st_esp.present || st->st_ah.present) { ++ /* ESP or AH means this was an established IPsec SA */ ++ linux_audit_conn(st, LAK_CHILD_DESTROY); ++ } ++ } + #endif + switch (kern_interface) { + case USE_KLIPS: +diff -Naur libreswan-3.29-orig/programs/pluto/linux_audit.c libreswan-3.29/programs/pluto/linux_audit.c +--- libreswan-3.29-orig/programs/pluto/linux_audit.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/linux_audit.c 2019-06-27 13:24:21.474460154 -0400 +@@ -176,12 +176,16 @@ + zero(&cipher_str); /* OK: no pointer fields */ + zero(&spi_str); /* OK: no pointer fields */ + ++ ip_address_buf raddr_buf; ++ const char *raddr = ipstr(&c->spd.that.host_addr, &raddr_buf); ++ + switch (op) { + case LAK_PARENT_START: + case LAK_PARENT_DESTROY: ++ case LAK_PARENT_FAIL: + initiator = (st->st_original_role == ORIGINAL_INITIATOR) || IS_PHASE1_INIT(st->st_state); + snprintf(head, sizeof(head), "op=%s direction=%s %s connstate=%lu ike-version=%s auth=%s", +- op == LAK_PARENT_START ? "start" : "destroy", ++ op == LAK_PARENT_DESTROY ? "destroy" : "start", /* fail to start logged under op=start */ + initiator ? "initiator" : "responder", + conn_encode, + st->st_serialno, +@@ -191,7 +195,8 @@ + st->st_oakley.auth, &esb)); + + snprintf(prfname, sizeof(prfname), "%s", +- st->st_oakley.ta_prf->prf_ike_audit_name); ++ st->st_oakley.ta_prf == NULL ? "none" : ++ st->st_oakley.ta_prf->prf_ike_audit_name); + + if (st->st_oakley.ta_integ == &ike_alg_integ_none) { + if (st->st_ike_version == IKEv1) { +@@ -220,18 +225,21 @@ + } + + snprintf(cipher_str, sizeof(cipher_str), +- "cipher=%s ksize=%d integ=%s prf=%s pfs=%s", +- st->st_oakley.ta_encrypt->encrypt_ike_audit_name, ++ "cipher=%s ksize=%d integ=%s prf=%s pfs=%s raddr=%s", ++ st->st_oakley.ta_encrypt == NULL ? "none" : ++ st->st_oakley.ta_encrypt->encrypt_ike_audit_name, + st->st_oakley.enckeylen, + integname, prfname, +- st->st_oakley.ta_dh->common.name); ++ st->st_oakley.ta_dh == NULL ? "none" : ++ st->st_oakley.ta_dh->common.name, raddr); + break; + + case LAK_CHILD_START: + case LAK_CHILD_DESTROY: ++ case LAK_CHILD_FAIL: + { + snprintf(head, sizeof(head), "op=%s %s connstate=%lu, satype=%s samode=%s", +- op == LAK_CHILD_START ? "start" : "destroy", ++ op == LAK_CHILD_DESTROY ? "destroy" : "start", /* fail to start logged under op=start */ + conn_encode, + st->st_serialno, + st->st_esp.present ? "ipsec-esp" : (st->st_ah.present ? "ipsec-ah" : "ipsec-policy"), +@@ -274,7 +282,7 @@ + + /* note: each arg appears twice because it is printed two ways */ + snprintf(spi_str, sizeof(spi_str), +- "in-spi=%" PRIu32 "(0x%08" PRIu32 ") out-spi=%" PRIu32 "(0x%08" PRIu32 ") in-ipcomp=%" PRIu32 "(0x%08" PRIu32 ") out-ipcomp=%" PRIu32 "(0x%08" PRIu32 ")", ++ "in-spi=%" PRIu32 "(0x%08" PRIu32 ") out-spi=%" PRIu32 "(0x%08" PRIu32 ") in-ipcomp=%" PRIu32 "(0x%08" PRIu32 ") out-ipcomp=%" PRIu32 "(0x%08" PRIu32 ") raddr=%s", + ntohl(pi->attrs.spi), + ntohl(pi->attrs.spi), + ntohl(pi->our_spi), +@@ -282,7 +290,8 @@ + ntohl(st->st_ipcomp.attrs.spi), /* zero if missing */ + ntohl(st->st_ipcomp.attrs.spi), /* zero if missing */ + ntohl(st->st_ipcomp.our_spi), /* zero if missing */ +- ntohl(st->st_ipcomp.our_spi)); /* zero if missing */ ++ ntohl(st->st_ipcomp.our_spi), /* zero if missing */ ++ raddr); + break; + } + default: +@@ -290,21 +299,18 @@ + } + free(conn_encode); /* allocated by audit_encode_nv_string() */ + +- ip_address_buf laddr_buf; +- const char *laddr = ipstr(&c->spd.this.host_addr, &laddr_buf); +- +- ip_address_buf raddr_buf; +- const char *raddr = ipstr(&c->spd.that.host_addr, &raddr_buf); +- +- snprintf(audit_str, sizeof(audit_str), "%s %s %s laddr=%s", ++ snprintf(audit_str, sizeof(audit_str), "%s %s %s", + head, + cipher_str, +- spi_str, +- laddr); ++ spi_str); ++ ++ ip_address_buf laddr_buf; ++ const char *laddr = ipstr(&c->spd.this.host_addr, &laddr_buf); + +- linux_audit((op == LAK_CHILD_START || op == LAK_CHILD_DESTROY) ? ++ linux_audit((op == LAK_CHILD_START || op == LAK_CHILD_DESTROY || op == LAK_CHILD_FAIL) ? + AUDIT_CRYPTO_IPSEC_SA : AUDIT_CRYPTO_IKE_SA, +- audit_str, raddr, AUDIT_RESULT_OK); ++ audit_str, laddr, ++ (op == LAK_PARENT_FAIL || op == LAK_CHILD_FAIL) ? AUDIT_RESULT_FAIL : AUDIT_RESULT_OK); + } + #if __GNUC__ >= 7 + #pragma GCC diagnostic pop +diff -Naur libreswan-3.29-orig/programs/pluto/log.h libreswan-3.29/programs/pluto/log.h +--- libreswan-3.29-orig/programs/pluto/log.h 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/log.h 2019-06-27 13:23:53.791080125 -0400 +@@ -174,7 +174,9 @@ + LAK_PARENT_START, + LAK_CHILD_START, + LAK_PARENT_DESTROY, +- LAK_CHILD_DESTROY ++ LAK_CHILD_DESTROY, ++ LAK_PARENT_FAIL, ++ LAK_CHILD_FAIL + }; + extern void linux_audit_init(void); + extern void linux_audit(const int type, const char *message, +diff -Naur libreswan-3.29-orig/programs/pluto/retry.c libreswan-3.29/programs/pluto/retry.c +--- libreswan-3.29-orig/programs/pluto/retry.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/retry.c 2019-06-27 13:25:27.536367032 -0400 +@@ -123,6 +123,10 @@ + + set_cur_state(st); /* ipsecdoi_replace would reset cur_state, set it again */ + pstat_sa_failed(st, REASON_TOO_MANY_RETRANSMITS); ++ ++ /* placed here because IKEv1 doesn't do a proper state change to STF_FAIL/STF_FATAL */ ++ linux_audit_conn(st, IS_IKE_SA(st) ? LAK_PARENT_FAIL : LAK_CHILD_FAIL); ++ + delete_state(st); + /* note: no md->st to clear */ + } +diff -Naur libreswan-3.29-orig/programs/pluto/state.c libreswan-3.29/programs/pluto/state.c +--- libreswan-3.29-orig/programs/pluto/state.c 2019-06-10 10:22:04.000000000 -0400 ++++ libreswan-3.29/programs/pluto/state.c 2019-06-27 13:23:53.792080138 -0400 +@@ -875,6 +875,16 @@ + + #ifdef USE_LINUX_AUDIT + /* ++ * IKEv2 IKE failures are logged in the state transition conpletion. ++ * IKEv1 IKE failures do not go through a transition, so we catch ++ * these in delete_state() ++ */ ++ if (IS_IKE_SA(st) && st->st_ike_version == IKEv1 && ++ !IS_IKE_SA_ESTABLISHED(st)) { ++ linux_audit_conn(st, LAK_PARENT_FAIL); ++ } ++ ++ /* + * only log parent state deletes, we log children in + * ipsec_delete_sa() + */ diff --git a/SPECS/libreswan.spec b/SPECS/libreswan.spec index d98bb76..4419183 100644 --- a/SPECS/libreswan.spec +++ b/SPECS/libreswan.spec @@ -23,6 +23,8 @@ USE_SECCOMP=true \\\ USE_XAUTHPAM=true \\\ USE_KLIPS=false \\\ + USE_NSS_PRF=true \\\ + USE_PRF_AES_XCBC=true \\\ %{nil} #global prever rc1 @@ -31,7 +33,7 @@ Name: libreswan Summary: IPsec implementation with IKEv1 and IKEv2 keying protocols # version is generated in the release script Version: 3.29 -Release: %{?prever:0.}1%{?prever:.%{prever}}%{?dist} +Release: %{?prever:0.}6%{?prever:.%{prever}}%{?dist} License: GPLv2 Url: https://libreswan.org/ Source0: https://download.libreswan.org/%{?prever:with_development/}%{name}-%{version}%{?prever}.tar.gz @@ -43,6 +45,10 @@ Source3: https://download.libreswan.org/cavs/ikev2.fax.bz2 Patch1: libreswan-3.28-maintain-different-v1v2-split.patch Patch2: libreswan-3.29-CVE-2019-10155-testing.patch +Patch3: libreswan-3.29-1723957-audit.patch +Patch4: libreswan-3.25-1724200-halfopen-shunt.patch +Patch5: libreswan-3.29-1699318-show.patch +Patch6: libreswan-3.29-1714331-nss-kdf.patch Group: System Environment/Daemons BuildRequires: bison flex pkgconfig @@ -53,8 +59,8 @@ Requires(postun): systemd BuildRequires: pkgconfig hostname # minimum version for support for rhbz#1651314 -BuildRequires: nss-tools nss-devel >= 3.39.0-1.4 -Requires: nss >= 3.39.0-1.4 +BuildRequires: nss-tools nss-devel >= 3.44.0-8 +Requires: nss >= 3.44.0-8 BuildRequires: nspr-devel BuildRequires: pam-devel BuildRequires: libevent-devel @@ -94,6 +100,13 @@ Libreswan is based on Openswan-2.6.38 which in turn is based on FreeS/WAN-2.04 %prep %setup -q -n libreswan-%{version}%{?prever} +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 + pathfix.py -i %{__python3} -pn programs/verify/verify.in programs/show/show.in \ testing/cert_verify/usage_test testing/pluto/ikev1-01-fuzzer/cve-2015-3204.py \ testing/pluto/ikev2-15-fuzzer/send_bad_packets.py testing/x509/dist_certs.py \ @@ -108,9 +121,6 @@ sed -i "s/-lfreebl //" mk/config.mk # enable crypto-policies support sed -i "s:#[ ]*include \(.*\)\(/crypto-policies/back-ends/libreswan.config\)$:include \1\2:" programs/configs/ipsec.conf.in -%patch1 -p1 -%patch2 -p1 - %build %if 0%{with_efence} %global efence "-lefence" @@ -223,6 +233,21 @@ certutil -N -d sql:$tmpdir --empty-password %{_libdir}/fipscheck/pluto.hmac %changelog +* Tue Aug 13 2019 Paul Wouters - 3.29-6 +- Resolves: rhbz#1714331 support NSS based IKE KDF's [require updated nss for rhbz 1738689, memleak fix] + +* Thu Aug 08 2019 Paul Wouters - 3.29-5 +- Resolves: rhbz#1714331 support NSS based IKE KDF's so libreswan does not need FIPS certification + +* Thu Aug 01 2019 Paul Wouters - 3.29-4 +- Resolves: rhbz#1699318 'ipsec show' has python3 invalid syntax + +* Thu Jul 04 2019 Paul Wouters - 3.29-3 +- Resolves: rhbz#1725205 XFRM policy for OE/32 peer is deleted when shunts for previous half-open state expire + +* Thu Jun 27 2019 Paul Wouters - 3.29-2 +- Resolves: rhbz#1723957 libreswan is missing linux audit calls for failed IKE SAs and failed IPsec SAs required for Common Criteria + * Mon Jun 10 2019 Paul Wouters - 3.29-1 - Resolves: rhbz#1712555 libreswan rebase to 3.29