Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libzpc for openSUSE:Factory checked in at 2023-09-21 22:23:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libzpc (Old) and /work/SRC/openSUSE:Factory/.libzpc.new.1770 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libzpc" Thu Sep 21 22:23:10 2023 rev:5 rq:1112737 version:1.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/libzpc/libzpc.changes 2023-02-11 21:57:38.951744239 +0100 +++ /work/SRC/openSUSE:Factory/.libzpc.new.1770/libzpc.changes 2023-09-21 22:23:37.626125418 +0200 @@ -1,0 +2,6 @@ +Wed Sep 20 06:46:33 UTC 2023 - Nikolay Gueorguiev <nikolay.gueorgu...@suse.com> + +- Version 1.1.1 (jsc#PED-5214) + * Exploit PKEY_KBLOB2PROTK2 for AES EP11 version 6 keys + +------------------------------------------------------------------- Old: ---- libzpc-1.1.0.tar.gz New: ---- libzpc-1.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libzpc.spec ++++++ --- /var/tmp/diff_new_pack.o1qoLc/_old 2023-09-21 22:23:38.814168529 +0200 +++ /var/tmp/diff_new_pack.o1qoLc/_new 2023-09-21 22:23:38.818168675 +0200 @@ -1,7 +1,7 @@ # # spec file for package libzpc # -# Copyright (c) 2022-2023 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: libzpc -Version: 1.1.0 +Version: 1.1.1 Release: 0 Summary: IBM Z Protected-key Crypto library License: Apache-2.0 ++++++ libzpc-1.1.0.tar.gz -> libzpc-1.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzpc-1.1.0/CHANGES.md new/libzpc-1.1.1/CHANGES.md --- old/libzpc-1.1.0/CHANGES.md 2023-02-02 17:07:17.000000000 +0100 +++ new/libzpc-1.1.1/CHANGES.md 2023-09-15 12:52:28.000000000 +0200 @@ -1,6 +1,10 @@ Changelog {#changes} === +**Version 1.1.1** + +- Exploit PKEY_KBLOB2PROTK2 for AES EP11 version 6 keys + **Version 1.1.0** - Implements an ECC-KEY API : `zpc/ecc_key.h`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzpc-1.1.0/CMakeLists.txt new/libzpc-1.1.1/CMakeLists.txt --- old/libzpc-1.1.0/CMakeLists.txt 2023-02-02 17:07:17.000000000 +0100 +++ new/libzpc-1.1.1/CMakeLists.txt 2023-09-15 12:52:28.000000000 +0200 @@ -3,7 +3,7 @@ set(ZPC_DESCRIPTION "IBM Z Protected-key Crypto library") set(ZPC_VERSION_MAJOR 1 ) set(ZPC_VERSION_MINOR 1 ) -set(ZPC_VERSION_PATCH 0 ) +set(ZPC_VERSION_PATCH 1 ) ########################################################### cmake_minimum_required( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzpc-1.1.0/libzpc.spec new/libzpc-1.1.1/libzpc.spec --- old/libzpc-1.1.0/libzpc.spec 2023-02-02 17:07:17.000000000 +0100 +++ new/libzpc-1.1.1/libzpc.spec 2023-09-15 12:52:28.000000000 +0200 @@ -1,5 +1,5 @@ Name: libzpc -Version: 1.1.0 +Version: 1.1.1 Release: 1%{?dist} Summary: Open Source library for the IBM Z Protected-key crypto feature @@ -88,6 +88,9 @@ %changelog +* Fri Sep 15 2023 Joerg Schmidbauer <jschm...@de.ibm.com> - 1.1.1 +- Exploit PKEY_KBLOB2PROTK2 for AES EP11 version 6 keys. + * Thu Feb 02 2023 Joerg Schmidbauer <jschm...@de.ibm.com> - 1.1.0 - Support for ECC keys and ECDSA signatures. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzpc-1.1.0/src/aes_key.c new/libzpc-1.1.1/src/aes_key.c --- old/libzpc-1.1.0/src/aes_key.c 2023-02-02 17:07:17.000000000 +0100 +++ new/libzpc-1.1.1/src/aes_key.c 2023-09-15 12:52:28.000000000 +0200 @@ -1024,6 +1024,34 @@ key = &aes_key->old; assert(key != NULL); + /* + * First try the ioctl with the version 6 key blob. This also sends the + * session id to the pkey kernel module. + */ + memset(&io, 0, sizeof(io)); + io.key = key->sec; + io.keylen = key->seclen; + io.apqns = aes_key->apqns; + io.apqn_entries = aes_key->napqns; + + rc = ioctl(pkeyfd, PKEY_KBLOB2PROTK2, &io); + if (rc == 0) + goto done; + + /* + * Version 6 key blob ioctl failed, most likely there is no kernel support + * for type 6 keys. Now check if this key is session bound: if it has a + * session id, then we cannot convert this key without overlaying, i.e. + * destroying, the session id. If not, retry the ioctl with a type 3 key + * blob by overlaying the session id. + */ + if (is_session_bound(key->sec, key->seclen)) + return ZPC_ERROR_IOCTLBLOB2PROTK2; + + /* + * This key is not session bound. Retry as version 3 key blob by overlaying + * the session id field with the key header. + */ memcpy(temp, key->sec + 16, 16); // save first 16 bytes session id memcpy(key->sec + 16, key->sec, 16); // overlay hdr in session id hdr = (struct ep11kblob_header *)(key->sec + 16); @@ -1043,6 +1071,7 @@ if (rc != 0) return ZPC_ERROR_IOCTLBLOB2PROTK2; +done: memcpy(&aes_key->prot, &io.protkey, sizeof(aes_key->prot)); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzpc-1.1.0/src/zkey/pkey.c new/libzpc-1.1.1/src/zkey/pkey.c --- old/libzpc-1.1.0/src/zkey/pkey.c 2023-02-02 17:07:17.000000000 +0100 +++ new/libzpc-1.1.1/src/zkey/pkey.c 2023-09-15 12:52:28.000000000 +0200 @@ -149,7 +149,34 @@ } /** - * Check if the specified key is a EP11 AES key token. + * Check if the specified EP11 type 6 (TOKVER_EP11_AES_WITH_HEADER) AES key + * token is session bound, i.e. has a non-zero session id. + * + * @param[in] key the type 6 secure key token + * @param[in] key_size the size of the secure key + * + * @returns true if the key is a session-bound type 6 EP11 AES key token + */ +bool is_session_bound(const u8 *key, size_t key_size) +{ + const unsigned char null_session[32] = { 0, }; + + if (!is_ep11_aes_key_with_header(key, key_size)) + return false; + + if (memcmp(key + sizeof(struct ep11kblob_header), + null_session, sizeof(null_session)) == 0) + return false; + + return true; +} + +/** + * Check if the specified key is a type 3 (TOKVER_EP11_AES) EP11 AES key token. + * Type 3 keys always have their session id field overlayed by the key token + * header, so they cannot contain a valid session id. Let's require that the + * 2nd 16 bytes of the session id field are always zero, otherwise consider + * the key as corrupted. * * @param[in] key the secure key token * @param[in] key_size the size of the secure key @@ -159,6 +186,7 @@ bool is_ep11_aes_key(const u8 *key, size_t key_size) { struct ep11keytoken *ep11key = (struct ep11keytoken *)key; + const unsigned char nulls[16] = { 0, }; if (key == NULL || key_size < (EP11_KEY_SIZE - sizeof(ep11key->padding))) return false; @@ -173,6 +201,9 @@ if (ep11key->version != EP11_STRUCT_MAGIC) return false; + if (memcmp(key + 16, nulls, 16) != 0) + return false; + return true; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzpc-1.1.0/src/zkey/pkey.h new/libzpc-1.1.1/src/zkey/pkey.h --- old/libzpc-1.1.0/src/zkey/pkey.h 2023-02-02 17:07:17.000000000 +0100 +++ new/libzpc-1.1.1/src/zkey/pkey.h 2023-09-15 12:52:28.000000000 +0200 @@ -470,6 +470,7 @@ bool is_cca_aes_data_key(const u8 *key, size_t key_size); bool is_cca_aes_cipher_key(const u8 *key, size_t key_size); +bool is_session_bound(const u8 *key, size_t key_size); bool is_ep11_aes_key(const u8 *key, size_t key_size); bool is_ep11_aes_key_with_header(const u8 *key, size_t key_size); bool is_xts_key(const u8 *key, size_t key_size); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzpc-1.1.0/test/t_aes_key.cc new/libzpc-1.1.1/test/t_aes_key.cc --- old/libzpc-1.1.0/test/t_aes_key.cc 2023-02-02 17:07:17.000000000 +0100 +++ new/libzpc-1.1.1/test/t_aes_key.cc 2023-09-15 12:52:28.000000000 +0200 @@ -714,6 +714,20 @@ EXPECT_EQ(buf2len, buflen); EXPECT_TRUE(memcmp(buf2, buf, buflen) == 0); + /* Now try a TOKVER_EP11_AES key that has an overlayed header, but the + * remaining 16 bytes of the session id field are not zero. This key + * is considered as corrupted. */ + memset(buf3 + 16, 0x5c, 16); + rc = zpc_aes_key_import(aes_key2, buf3, buf3len); + EXPECT_EQ(rc, ZPC_ERROR_AES_NO_EP11_SECUREKEY_TOKEN); + + /* Now try a TOKVER_EP11_AES key that is session-bound, i.e. + * has a 32 byte session id instead of an overlayed header. This key + * cannot be recognized, because of missing header information. */ + memset(buf3, 0x5c, 32); /* fake a 32-byte session id */ + rc = zpc_aes_key_import(aes_key2, buf3, buf3len); + EXPECT_EQ(rc, ZPC_ERROR_AES_NO_EP11_SECUREKEY_TOKEN); + zpc_aes_key_free(&aes_key); EXPECT_EQ(aes_key, nullptr); zpc_aes_key_free(&aes_key2); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzpc-1.1.0/test/testlib.h new/libzpc-1.1.1/test/testlib.h --- old/libzpc-1.1.0/test/testlib.h 2023-02-02 17:07:17.000000000 +0100 +++ new/libzpc-1.1.1/test/testlib.h 2023-09-15 12:52:28.000000000 +0200 @@ -27,36 +27,36 @@ * GTEST_SKIP_ assumes the caller to be the test function that is to * be skipped. So this one has to be implemented as a macro. */ -# define TESTLIB_ENV_AES_KEY_CHECK() \ -do { \ - const char *apqns[257]; \ - const char *mkvp; \ - int size, type, rc; \ - \ - size = testlib_env_aes_key_size(); \ - switch (size) { \ - case 128: /* fall-through */ \ - case 192: /* fall-through */ \ - case 256: /* fall-through */ \ - break; \ - case -1: \ - GTEST_SKIP_("ZPC_TEST_AES_KEY_SIZE environment variable not set."); \ - break; \ - default: \ +# define TESTLIB_ENV_AES_KEY_CHECK() \ +do { \ + const char *apqns[257]; \ + const char *mkvp; \ + int size, type, rc; \ + \ + size = testlib_env_aes_key_size(); \ + switch (size) { \ + case 128: /* fall-through */ \ + case 192: /* fall-through */ \ + case 256: /* fall-through */ \ + break; \ + case -1: \ + GTEST_SKIP_("ZPC_TEST_AES_KEY_SIZE environment variable not set."); \ + break; \ + default: \ GTEST_SKIP_("ZPC_TEST_AES_KEY_SIZE environment variable set to invalid key-size."); \ - break; \ - } \ - \ - type = testlib_env_aes_key_type(); \ - if (type == -1) \ - GTEST_SKIP_("ZPC_TEST_AES_KEY_TYPE environment variable not set."); \ - \ - mkvp = testlib_env_aes_key_mkvp(); \ - rc = testlib_env_aes_key_apqns(apqns); \ - if (rc == 0 && mkvp != NULL) \ - GTEST_SKIP_("Both ZPC_TEST_AES_KEY_MKVP and ZPC_TEST_AES_KEY_APQNS environment variables set."); \ - if (rc != 0 && mkvp == NULL) \ - GTEST_SKIP_("ZPC_TEST_AES_KEY_MKVP and ZPC_TEST_AES_KEY_APQNS environment variables unset."); \ + break; \ + } \ + \ + type = testlib_env_aes_key_type(); \ + if (type == -1) \ + GTEST_SKIP_("ZPC_TEST_AES_KEY_TYPE environment variable not set."); \ + \ + mkvp = testlib_env_aes_key_mkvp(); \ + rc = testlib_env_aes_key_apqns(apqns); \ + if (rc == 0 && mkvp != NULL) \ + GTEST_SKIP_("Both ZPC_TEST_AES_KEY_MKVP and ZPC_TEST_AES_KEY_APQNS environment variables set."); \ + if (rc != 0 && mkvp == NULL) \ + GTEST_SKIP_("ZPC_TEST_AES_KEY_MKVP and ZPC_TEST_AES_KEY_APQNS environment variables unset."); \ } while (0) # define TESTLIB_AES_ECB_HW_CAPS_CHECK() \ @@ -302,38 +302,38 @@ zpc_aes_key_free(&aes_key); \ } while (0) -# define TESTLIB_ENV_EC_KEY_CHECK() \ -do { \ - const char *apqns[257]; \ - const char *mkvp; \ - int type, rc; \ - int curve = testlib_env_ec_key_curve(); \ - \ - switch (curve) { \ - case ZPC_EC_CURVE_P256: /* fall-through */ \ - case ZPC_EC_CURVE_P384: /* fall-through */ \ - case ZPC_EC_CURVE_P521: /* fall-through */ \ - case ZPC_EC_CURVE_ED25519: /* fall-through */ \ - case ZPC_EC_CURVE_ED448: /* fall-through */ \ - break; \ - case ZPC_EC_CURVE_INVALID: \ - GTEST_SKIP_("ZPC_TEST_EC_KEY_CURVE environment variable set to invalid value."); \ - break; \ - default: \ - GTEST_SKIP_("ZPC_TEST_EC_KEY_CURVE environment variable not set."); \ - break; \ - } \ - \ - type = testlib_env_ec_key_type(); \ - if (type == -1) \ - GTEST_SKIP_("ZPC_TEST_EC_KEY_TYPE environment variable not set."); \ - \ - mkvp = testlib_env_ec_key_mkvp(); \ - rc = testlib_env_ec_key_apqns(apqns); \ - if (rc == 0 && mkvp != NULL) \ - GTEST_SKIP_("Both ZPC_TEST_EC_KEY_MKVP and ZPC_TEST_EC_KEY_APQNS environment variables set."); \ - if (rc != 0 && mkvp == NULL) \ - GTEST_SKIP_("ZPC_TEST_EC_KEY_MKVP and ZPC_TEST_EC_KEY_APQNS environment variables unset."); \ +# define TESTLIB_ENV_EC_KEY_CHECK() \ +do { \ + const char *apqns[257]; \ + const char *mkvp; \ + int type, rc; \ + int curve = testlib_env_ec_key_curve(); \ + \ + switch (curve) { \ + case ZPC_EC_CURVE_P256: /* fall-through */ \ + case ZPC_EC_CURVE_P384: /* fall-through */ \ + case ZPC_EC_CURVE_P521: /* fall-through */ \ + case ZPC_EC_CURVE_ED25519: /* fall-through */ \ + case ZPC_EC_CURVE_ED448: /* fall-through */ \ + break; \ + case ZPC_EC_CURVE_INVALID: \ + GTEST_SKIP_("ZPC_TEST_EC_KEY_CURVE environment variable set to invalid value."); \ + break; \ + default: \ + GTEST_SKIP_("ZPC_TEST_EC_KEY_CURVE environment variable not set."); \ + break; \ + } \ + \ + type = testlib_env_ec_key_type(); \ + if (type == -1) \ + GTEST_SKIP_("ZPC_TEST_EC_KEY_TYPE environment variable not set."); \ + \ + mkvp = testlib_env_ec_key_mkvp(); \ + rc = testlib_env_ec_key_apqns(apqns); \ + if (rc == 0 && mkvp != NULL) \ + GTEST_SKIP_("Both ZPC_TEST_EC_KEY_MKVP and ZPC_TEST_EC_KEY_APQNS environment variables set."); \ + if (rc != 0 && mkvp == NULL) \ + GTEST_SKIP_("ZPC_TEST_EC_KEY_MKVP and ZPC_TEST_EC_KEY_APQNS environment variables unset."); \ } while (0) # define TESTLIB_EC_HW_CAPS_CHECK() \