Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libzpc for openSUSE:Factory checked 
in at 2024-01-15 22:20:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libzpc (Old)
 and      /work/SRC/openSUSE:Factory/.libzpc.new.21961 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libzpc"

Mon Jan 15 22:20:19 2024 rev:6 rq:1138764 version:1.2.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libzpc/libzpc.changes    2023-09-21 
22:23:37.626125418 +0200
+++ /work/SRC/openSUSE:Factory/.libzpc.new.21961/libzpc.changes 2024-01-15 
22:20:45.594219730 +0100
@@ -1,0 +2,9 @@
+Mon Jan 15 07:16:57 UTC 2024 - Nikolay Gueorguiev <nikolay.gueorgu...@suse.com>
+
+- Upgrade libzpc to version 1.2.0 (jsc#PED-3335)
+  * Support for get/set intermediate iv for CBC and XTS
+  * Support for internal iv for GCM
+  * Exploit KBLOB2PROTK3 ioctl for clear AES and EC keys
+  * Fix AES EP11 version 6 key support for generate and import_clear
+
+-------------------------------------------------------------------

Old:
----
  libzpc-1.1.1.tar.gz

New:
----
  libzpc-1.2.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libzpc.spec ++++++
--- /var/tmp/diff_new_pack.ddMcbG/_old  2024-01-15 22:20:46.834265303 +0100
+++ /var/tmp/diff_new_pack.ddMcbG/_new  2024-01-15 22:20:46.834265303 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package libzpc
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 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.1
+Version:        1.2.0
 Release:        0
 Summary:        IBM Z Protected-key Crypto library
 License:        Apache-2.0

++++++ libzpc-1.1.1.tar.gz -> libzpc-1.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/.travis.yml new/libzpc-1.2.0/.travis.yml
--- old/libzpc-1.1.1/.travis.yml        2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/.travis.yml        2024-01-12 10:26:07.000000000 +0100
@@ -1,6 +1,6 @@
 arch:     s390x
 os:       linux
-dist:     bionic
+dist:     focal
 language: cpp
 sudo:     required
 env:      |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/CHANGES.md new/libzpc-1.2.0/CHANGES.md
--- old/libzpc-1.1.1/CHANGES.md 2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/CHANGES.md 2024-01-12 10:26:07.000000000 +0100
@@ -1,6 +1,13 @@
 Changelog {#changes}
 ===
 
+**Version 1.2.0**
+
+- Support for get/set intermediate iv for CBC and XTS
+- Support for internal iv for GCM
+- Fix AES EP11 version 6 key support for generate and import_clear
+- Exploit KBLOB2PROTK3 ioctl for clear AES and EC keys
+
 **Version 1.1.1**
 
 - Exploit PKEY_KBLOB2PROTK2 for AES EP11 version 6 keys
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/CMakeLists.txt 
new/libzpc-1.2.0/CMakeLists.txt
--- old/libzpc-1.1.1/CMakeLists.txt     2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/CMakeLists.txt     2024-01-12 10:26:07.000000000 +0100
@@ -2,8 +2,8 @@
 set(ZPC_NAME          "libzpc"                            )
 set(ZPC_DESCRIPTION   "IBM Z Protected-key Crypto library")
 set(ZPC_VERSION_MAJOR 1                                   )
-set(ZPC_VERSION_MINOR 1                                   )
-set(ZPC_VERSION_PATCH 1                                   )
+set(ZPC_VERSION_MINOR 2                                   )
+set(ZPC_VERSION_PATCH 0                                   )
 ###########################################################
 
 cmake_minimum_required(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/include/zpc/aes_cbc.h 
new/libzpc-1.2.0/include/zpc/aes_cbc.h
--- old/libzpc-1.1.1/include/zpc/aes_cbc.h      2023-09-15 12:52:28.000000000 
+0200
+++ new/libzpc-1.2.0/include/zpc/aes_cbc.h      2024-01-12 10:26:07.000000000 
+0100
@@ -53,6 +53,26 @@
 __attribute__((visibility("default")))
 int zpc_aes_cbc_set_iv(struct zpc_aes_cbc *ctx, const unsigned char *iv);
 /**
+ * Get the intermediate initialization vector to be used in the context
+ * of an AES-CBC operation.
+ * \param[in,out] ctx AES-CBC context
+ * \param[out] iv application provided buffer with 16 bytes size to
+ * receive the 16 byte intermediate iv
+ * \return 0 on success. Otherwise, a non-zero error code is returned.
+ */
+__attribute__((visibility("default")))
+int zpc_aes_cbc_get_intermediate_iv(struct zpc_aes_cbc *ctx, unsigned char 
iv[16]);
+/**
+ * Set the intermediate initialization vector to be used in the context
+ * of an AES-CBC operation. An initial iv must be set before via
+ * zpc_aes_cbc_set_iv.
+ * \param[in,out] ctx AES-CBC context
+ * \param[in] iv 16 byte intermediate iv
+ * \return 0 on success. Otherwise, a non-zero error code is returned.
+ */
+__attribute__((visibility("default")))
+int zpc_aes_cbc_set_intermediate_iv(struct zpc_aes_cbc *ctx, const unsigned 
char iv[16]);
+/**
  * Do an AES-CBC encryption operation.
  * \param[in,out] ctx AES-CBC context
  * \param[out] ct ciphertext
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/include/zpc/aes_gcm.h 
new/libzpc-1.2.0/include/zpc/aes_gcm.h
--- old/libzpc-1.1.1/include/zpc/aes_gcm.h      2023-09-15 12:52:28.000000000 
+0200
+++ new/libzpc-1.2.0/include/zpc/aes_gcm.h      2024-01-12 10:26:07.000000000 
+0100
@@ -43,6 +43,18 @@
 __attribute__((visibility("default")))
 int zpc_aes_gcm_set_key(struct zpc_aes_gcm *ctx, struct zpc_aes_key *key);
 /**
+ * Create the initialization vector to be used in the context
+ * of an AES-GCM operation. The minimum and recommended iv length is 12 bytes.
+ * \param[in,out] ctx AES-GCM context
+ * \param[in/out] iv application provided buffer of at least ivlen bytes to
+ * receive the internally created initialization vector
+ * \param[in] ivlen initialization vector length [bytes]
+ * \return 0 on success. Otherwise, a non-zero error code is returned.
+ */
+__attribute__((visibility("default")))
+int zpc_aes_gcm_create_iv(struct zpc_aes_gcm *ctx, unsigned char *iv,
+    size_t ivlen);
+/**
  * Set the initialization vector to be used in the context
  * of an AES-GCM operation.
  * \param[in,out] ctx AES-GCM context
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/include/zpc/aes_xts.h 
new/libzpc-1.2.0/include/zpc/aes_xts.h
--- old/libzpc-1.1.1/include/zpc/aes_xts.h      2023-09-15 12:52:28.000000000 
+0200
+++ new/libzpc-1.2.0/include/zpc/aes_xts.h      2024-01-12 10:26:07.000000000 
+0100
@@ -55,6 +55,26 @@
 __attribute__((visibility("default")))
 int zpc_aes_xts_set_iv(struct zpc_aes_xts *ctx, const unsigned char *iv);
 /**
+ * Get the intermediate initialization vector to be used in the context
+ * of an AES-XTS operation.
+ * \param[in,out] ctx AES-XTS context
+ * \param[out] iv application provided buffer with 16 bytes size to
+ * receive the 16 byte intermediate iv 
+ * \return 0 on success. Otherwise, a non-zero error code is returned.
+ */
+__attribute__((visibility("default")))
+int zpc_aes_xts_get_intermediate_iv(struct zpc_aes_xts *ctx, unsigned char 
iv[16]);
+/**
+ * Set the intermediate initialization vector to be used in the context
+ * of an AES-XTS operation. An initial iv must be set before via
+ * zpc_aes_xts_set_iv.
+ * \param[in,out] ctx AES-XTS context
+ * \param[in] iv 16 byte intermediate iv
+ * \return 0 on success. Otherwise, a non-zero error code is returned.
+ */
+__attribute__((visibility("default")))
+int zpc_aes_xts_set_intermediate_iv(struct zpc_aes_xts *ctx, const unsigned 
char iv[16]);
+/**
  * Do an AES-XTS encryption operation.
  * \param[in,out] ctx AES-XTS context
  * \param[out] ct ciphertext
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/include/zpc/error.h 
new/libzpc-1.2.0/include/zpc/error.h
--- old/libzpc-1.1.1/include/zpc/error.h        2023-09-15 12:52:28.000000000 
+0200
+++ new/libzpc-1.2.0/include/zpc/error.h        2024-01-12 10:26:07.000000000 
+0100
@@ -458,6 +458,18 @@
 # define ZPC_ERROR_AES_NO_CCA_CIPHERKEY_TOKEN  75
 
 /**
+ * \def ZPC_ERROR_RNDGEN
+ * \brief error creating random bytes.
+ */
+# define ZPC_ERROR_RNDGEN  76
+
+/**
+ * \def ZPC_ERROR_GCM_IV_CREATED_INTERNALLY
+ * \brief invalid usage of a gcm context with an internally created iv.
+ */
+# define ZPC_ERROR_GCM_IV_CREATED_INTERNALLY  77
+
+/**
  * \fn const char *zpc_error_string(int err)
  * \brief Map an error code to the corresponding error string.
  * \param[in] err An error code.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/libzpc.map new/libzpc-1.2.0/libzpc.map
--- old/libzpc-1.1.1/libzpc.map 2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/libzpc.map 2024-01-12 10:26:07.000000000 +0100
@@ -84,3 +84,15 @@
 local: *;
 } ZPC_1.0;
 
+ZPC_1.2.0 {
+global:
+       zpc_aes_xts_get_intermediate_iv;
+       zpc_aes_xts_set_intermediate_iv;
+       zpc_aes_cbc_get_intermediate_iv;
+       zpc_aes_cbc_set_intermediate_iv;
+       zpc_aes_gcm_create_iv;
+
+local: *;
+} ZPC_1.1.0;
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/libzpc.spec new/libzpc-1.2.0/libzpc.spec
--- old/libzpc-1.1.1/libzpc.spec        2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/libzpc.spec        2024-01-12 10:26:07.000000000 +0100
@@ -1,5 +1,5 @@
 Name:          libzpc
-Version:       1.1.1
+Version:       1.2.0
 Release:       1%{?dist}
 Summary:       Open Source library for the IBM Z Protected-key crypto feature
 
@@ -88,6 +88,10 @@
 
 
 %changelog
+* Thu Dec 07 2023 Joerg Schmidbauer <jschm...@de.ibm.com> - 1.2.0
+- Support for get/set intermediate iv for CBC and XTS.
+- Support for internal iv for GCM.
+
 * Fri Sep 15 2023 Joerg Schmidbauer <jschm...@de.ibm.com> - 1.1.1
 - Exploit PKEY_KBLOB2PROTK2 for AES EP11 version 6 keys.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/aes_cbc.c 
new/libzpc-1.2.0/src/aes_cbc.c
--- old/libzpc-1.1.1/src/aes_cbc.c      2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/aes_cbc.c      2024-01-12 10:26:07.000000000 +0100
@@ -24,7 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-static void __aes_cbc_set_iv(struct zpc_aes_cbc *, const u8 *);
+static void __aes_cbc_set_iv(struct zpc_aes_cbc *, const u8 iv[16]);
 static int __aes_cbc_crypt(struct zpc_aes_cbc *, u8 *, const u8 *, size_t,
     unsigned long);
 static void __aes_cbc_reset(struct zpc_aes_cbc *);
@@ -188,6 +188,83 @@
 }
 
 int
+zpc_aes_cbc_get_intermediate_iv(struct zpc_aes_cbc *aes_cbc, unsigned char 
iv[16])
+{
+       int rc;
+
+       if (pkeyfd < 0) {
+               rc = ZPC_ERROR_DEVPKEY;
+               goto ret;
+       }
+       if (!hwcaps.aes_cbc) {
+               rc = ZPC_ERROR_HWCAPS;
+               goto ret;
+       }
+       if (aes_cbc == NULL) {
+               rc = ZPC_ERROR_ARG1NULL;
+               goto ret;
+       }
+
+       if (iv == NULL) {
+               rc = ZPC_ERROR_ARG2NULL;
+               goto ret;
+       }
+
+       if (aes_cbc->iv_set != 1) {
+               rc = ZPC_ERROR_IVNOTSET;
+               goto ret;
+       }
+
+       memcpy(iv, aes_cbc->param.cv, 16);
+       rc = 0;
+
+ret:
+       DEBUG("return %d (%s)", rc, zpc_error_string(rc));
+       return rc;
+}
+
+int
+zpc_aes_cbc_set_intermediate_iv(struct zpc_aes_cbc *aes_cbc, const unsigned 
char iv[16])
+{
+       int rc;
+
+       if (pkeyfd < 0) {
+               rc = ZPC_ERROR_DEVPKEY;
+               goto ret;
+       }
+       if (!hwcaps.aes_cbc) {
+               rc = ZPC_ERROR_HWCAPS;
+               goto ret;
+       }
+       if (aes_cbc == NULL) {
+               rc = ZPC_ERROR_ARG1NULL;
+               goto ret;
+       }
+       if (iv == NULL) {
+               rc = ZPC_ERROR_ARG2NULL;
+               goto ret;
+       }
+
+       if (aes_cbc->key_set != 1) {
+               rc = ZPC_ERROR_KEYNOTSET;
+               goto ret;
+       }
+
+       if (aes_cbc->iv_set != 1) {
+               rc = ZPC_ERROR_IVNOTSET;
+               goto ret;
+       }
+
+       __aes_cbc_set_iv(aes_cbc, iv);
+       DEBUG("aes-cbc context at %p: intermediate iv set", aes_cbc);
+       aes_cbc->iv_set = 1;
+       rc = 0;
+ret:
+       DEBUG("return %d (%s)", rc, zpc_error_string(rc));
+       return rc;
+}
+
+int
 zpc_aes_cbc_encrypt(struct zpc_aes_cbc *aes_cbc, u8 * c, const u8 * m,
     size_t mlen)
 {
@@ -392,7 +469,7 @@
 }
 
 static void
-__aes_cbc_set_iv(struct zpc_aes_cbc *aes_cbc, const u8 * iv)
+__aes_cbc_set_iv(struct zpc_aes_cbc *aes_cbc, const u8 iv[16])
 {
        assert(aes_cbc != NULL);
        assert(iv != NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/aes_gcm.c 
new/libzpc-1.2.0/src/aes_gcm.c
--- old/libzpc-1.1.1/src/aes_gcm.c      2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/aes_gcm.c      2024-01-12 10:26:07.000000000 +0100
@@ -150,6 +150,68 @@
 }
 
 int
+zpc_aes_gcm_create_iv(struct zpc_aes_gcm *aes_gcm, u8 *iv, size_t ivlen)
+{
+       u8 *iv_tmp = NULL;
+       int rc;
+
+       if (pkeyfd < 0) {
+               rc = ZPC_ERROR_DEVPKEY;
+               goto ret;
+       }
+       if (!hwcaps.aes_gcm) {
+               rc = ZPC_ERROR_HWCAPS;
+               goto ret;
+       }
+       if (aes_gcm == NULL) {
+               rc = ZPC_ERROR_ARG1NULL;
+               goto ret;
+       }
+       if (iv == NULL) {
+               rc = ZPC_ERROR_ARG2NULL;
+               goto ret;
+       }
+
+       /* 12 <= iv bit-length <= 2^64 - 1, iv bit-length % 8 == 0 */
+       if (ivlen < GCM_RECOMMENDED_IV_LENGTH || ivlen > GCM_MAX_IV_LENGTH) {
+               rc = ZPC_ERROR_IVSIZE;
+               goto ret;
+       }
+       if (aes_gcm->key_set != 1) {
+               rc = ZPC_ERROR_KEYNOTSET;
+               goto ret;
+       }
+
+       iv_tmp = calloc(ivlen, 1);
+       if (!iv_tmp) {
+               rc = ZPC_ERROR_MALLOC;
+               goto ret;
+       }
+
+       if (local_rng(iv_tmp, ivlen) != 0) {
+               rc = ZPC_ERROR_RNDGEN;
+               goto ret;
+       }
+
+       aes_gcm->iv_created = 0;
+       rc = zpc_aes_gcm_set_iv(aes_gcm, iv_tmp, ivlen);
+       if (rc != 0)
+               goto ret;
+
+       DEBUG("aes-gcm context at %p: iv created and set", aes_gcm);
+       aes_gcm->iv_set = 1;
+       aes_gcm->iv_created = 1;
+       memcpy(iv, iv_tmp, ivlen);
+       rc = 0;
+
+ret:
+       if (iv_tmp != NULL)
+               free(iv_tmp);
+       DEBUG("return %d (%s)", rc, zpc_error_string(rc));
+       return rc;
+}
+
+int
 zpc_aes_gcm_set_iv(struct zpc_aes_gcm *aes_gcm, const u8 * iv, size_t ivlen)
 {
        struct cpacf_kma_gcm_aes_param *param;
@@ -179,7 +241,7 @@
                goto ret;
        }
        /* 1 <= iv bit-length <= 2^64 - 1, iv bit-length % 8 == 0 */
-       if (ivlen < 1 || ivlen > SIZE_MAX - 16) {
+       if (ivlen < 1 || ivlen > GCM_MAX_IV_LENGTH) {
                rc = ZPC_ERROR_IVSIZE;
                goto ret;
        }
@@ -188,6 +250,10 @@
                rc = ZPC_ERROR_KEYNOTSET;
                goto ret;
        }
+       if (aes_gcm->iv_created == 1) {
+               rc = ZPC_ERROR_GCM_IV_CREATED_INTERNALLY;
+               goto ret;
+       }
 
        rc = -1;
        for (i = 0; i < 2 && rc != 0; i++) {
@@ -282,7 +348,7 @@
                rc = ZPC_ERROR_ARG5NULL;
                goto ret;
        }
-       if (aadlen > (2ULL << 61) - 1) {
+       if (aes_gcm->param.taadl / 8 + aadlen > GCM_MAX_TOTAL_AAD_LENGTH) {
                rc = ZPC_ERROR_AADLEN;
                goto ret;
        }
@@ -295,7 +361,7 @@
                rc = ZPC_ERROR_ARG7NULL;
                goto ret;
        }
-       if (mlen > (2ULL << 36) - 256) {
+       if (aes_gcm->param.tpcl / 8 + mlen > GCM_MAX_TOTAL_PLAINTEXT_LENGTH) {
                rc = ZPC_ERROR_MLEN;
                goto ret;
        }
@@ -411,7 +477,7 @@
                rc = ZPC_ERROR_ARG5NULL;
                goto ret;
        }
-       if (aadlen > (2ULL << 61) - 1) {
+       if (aes_gcm->param.taadl / 8 + aadlen > GCM_MAX_TOTAL_AAD_LENGTH) {
                rc = ZPC_ERROR_AADLEN;
                goto ret;
        }
@@ -424,7 +490,7 @@
                rc = ZPC_ERROR_ARG7NULL;
                goto ret;
        }
-       if (clen > (2ULL << 36) - 256) {
+       if (aes_gcm->param.tpcl / 8 + clen > GCM_MAX_TOTAL_PLAINTEXT_LENGTH) {
                rc = ZPC_ERROR_CLEN;
                goto ret;
        }
@@ -441,6 +507,10 @@
                rc = ZPC_ERROR_IVNOTSET;
                goto ret;
        }
+       if (aes_gcm->iv_created) {
+               rc = ZPC_ERROR_GCM_IV_CREATED_INTERNALLY;
+               goto ret;
+       }
 
        if ((m != NULL && c != NULL) || tag != NULL) {
                flags |= CPACF_KMA_LAAD;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/aes_gcm_local.h 
new/libzpc-1.2.0/src/aes_gcm_local.h
--- old/libzpc-1.1.1/src/aes_gcm_local.h        2023-09-15 12:52:28.000000000 
+0200
+++ new/libzpc-1.2.0/src/aes_gcm_local.h        2024-01-12 10:26:07.000000000 
+0100
@@ -17,6 +17,27 @@
  * Internal aes_gcm interface.
  */
 
+#define GCM_RECOMMENDED_IV_LENGTH           12
+
+/*
+ * NIST SP 800-38d: 1 <= bitlen(iv) <= 2^64 - 1
+ *   => 1 <= bytelen(iv) <= 2^61 - 1
+ */
+#define GCM_MAX_IV_LENGTH                   ((2ULL << 61) - 1)
+
+/*
+ * NIST SP 800-38d: bitlen(A) <= 2^64 - 1
+ *   => 0 <= bytelen(A) <= 2^61 - 1
+ */
+#define GCM_MAX_TOTAL_AAD_LENGTH            ((2ULL << 61) - 1)
+
+/*
+ * NIST SP 800-38d: bitlen(P) <= 2^39 - 256;
+ *   => 0 <= bytelen(P) <= 2^36 - 32
+ */
+#define GCM_MAX_TOTAL_PLAINTEXT_LENGTH      ((2ULL << 36) - 32)
+
+
 struct zpc_aes_gcm {
        struct cpacf_kma_gcm_aes_param param;
        struct zpc_aes_key *aes_key;
@@ -25,6 +46,7 @@
 
        int key_set;
        int iv_set;
+       int iv_created;
 };
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/aes_key.c 
new/libzpc-1.2.0/src/aes_key.c
--- old/libzpc-1.1.1/src/aes_key.c      2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/aes_key.c      2024-01-12 10:26:07.000000000 +0100
@@ -30,6 +30,7 @@
 static int aes_key_blob_is_pkey_extractable(struct zpc_aes_key *aes_key,
                                                                const unsigned 
char *buf, size_t buflen);
 static int aes_key_add_ep11_header(struct zpc_aes_key *aes_key);
+static int aes_key_blob_has_a_session(struct zpc_aes_key *aes_key);
 
 int
 zpc_aes_key_alloc(struct zpc_aes_key **aes_key)
@@ -418,7 +419,7 @@
 zpc_aes_key_import_clear(struct zpc_aes_key *aes_key, const unsigned char *key)
 {
        struct pkey_clr2seck2 clr2seck2;
-       unsigned int flags;
+       unsigned int flags, hdr_to_add = 0;
        int rc, rv;
 
        UNUSED(rv);
@@ -469,31 +470,62 @@
        clr2seck2.apqns = aes_key->apqns;
        clr2seck2.apqn_entries = aes_key->napqns;
        clr2seck2.type = aes_key->type;
+       if (aes_key->type == ZPC_AES_KEY_TYPE_EP11)
+               clr2seck2.type = TOKVER_EP11_AES_WITH_HEADER; /* 0x06 */
        clr2seck2.size = aes_key->keysize;
        clr2seck2.keygenflags = flags;
        memcpy(&clr2seck2.clrkey, key, aes_key->keysize / 8);
        clr2seck2.key = aes_key->cur.sec;
        clr2seck2.keylen = sizeof(aes_key->cur.sec);
 
+       /*
+        * If it's an EP11 key, we first try to import the clear key as a type 
6 key
+        * (TOKVER_EP11_AES_WITH_HEADER). This may fail on older kernels. If it
+        * fails, we try to import as a type 3 (TOKVER_EP11_AES) key and add the
+        * type 6 header manually below. If successful, we end up with a type 6
+        * key in both cases.
+        */
        rc = ioctl(pkeyfd, PKEY_CLR2SECK2, &clr2seck2);
+       DEBUG("ioctl PKEY_CLR2SECK2 as aes ep11 type 6 key returned %d", rc);
        if (rc != 0) {
-               rc = ZPC_ERROR_IOCTLCLR2SECK2;
-               goto ret;
+               if (aes_key->type == ZPC_AES_KEY_TYPE_EP11) {
+                       DEBUG("ioctl PKEY_CLR2SECK2 as aes ep11 type 6 key 
returned %d", rc);
+                       /* Retry with a type 3 key */
+                       clr2seck2.type = TOKVER_EP11_AES; /* 0x03 */
+                       rc = ioctl(pkeyfd, PKEY_CLR2SECK2, &clr2seck2);
+                       DEBUG("ioctl PKEY_CLR2SECK2 as aes ep11 type 3 key 
returned %d", rc);
+                       if (rc != 0) {
+                               rc = ZPC_ERROR_IOCTLCLR2SECK2;
+                               goto ret;
+                       }
+                       hdr_to_add = 1;
+               } else {
+                       rc = ZPC_ERROR_IOCTLCLR2SECK2;
+                       goto ret;
+               }
        }
 
        aes_key->cur.seclen = clr2seck2.keylen;
 
-       rc = aes_key_sec2prot(aes_key, AES_KEY_SEC_CUR);
+       rc = aes_key_clr2prot(aes_key, key, aes_key->keysize / 8);
        if (rc) {
-               goto ret;
+               rc = aes_key_sec2prot(aes_key, AES_KEY_SEC_CUR);
+               if (rc) {
+                       goto ret;
+               }
        }
 
-       if (aes_key->type == ZPC_AES_KEY_TYPE_EP11) {
+       if (aes_key->type == ZPC_AES_KEY_TYPE_EP11 && hdr_to_add) {
                rc = aes_key_add_ep11_header(aes_key);
                if (rc)
                        goto ret;
        }
 
+       if (aes_key->type == ZPC_AES_KEY_TYPE_EP11 && 
aes_key_blob_has_a_session(aes_key))
+               DEBUG("This aes ep11 key has a session id");
+       else
+               DEBUG("This aes ep11 key has no session id");
+
        DEBUG("aes key at %p: key set", aes_key);
        aes_key->key_set = 1;
        rc = 0;
@@ -656,7 +688,7 @@
 {
        struct pkey_genseck2 genseck2;
        struct pkey_genprotk genprotk;
-       unsigned int flags;
+       unsigned int flags, hdr_to_add = 0;
        int rc, rv;
 
        UNUSED(rv);
@@ -733,15 +765,38 @@
        genseck2.apqns = aes_key->apqns;
        genseck2.apqn_entries = aes_key->napqns;
        genseck2.type = aes_key->type;
+       if (aes_key->type == ZPC_AES_KEY_TYPE_EP11)
+               genseck2.type = TOKVER_EP11_AES_WITH_HEADER; /* 0x06 */
        genseck2.size = aes_key->keysize;
        genseck2.keygenflags = flags;
        genseck2.key = aes_key->cur.sec;
        genseck2.keylen = sizeof(aes_key->cur.sec);
 
+       /*
+        * If it's an EP11 key, we first try to generate a type 6 key
+        * (TOKVER_EP11_AES_WITH_HEADER). This may fail on older kernels. If it
+        * fails, we try to generate a type 3 (TOKVER_EP11_AES) key and add the
+        * type 6 header manually below. If successful, we end up with a type 6
+        * key in both cases.
+        */
        rc = ioctl(pkeyfd, PKEY_GENSECK2, &genseck2);
+       DEBUG("ioctl PKEY_GENSECK2 as aes ep11 type 6 key returned %d", rc);
        if (rc != 0) {
-               rc = ZPC_ERROR_IOCTLGENSECK2;
-               goto ret;
+               if (aes_key->type == ZPC_AES_KEY_TYPE_EP11) {
+                       DEBUG("ioctl PKEY_GENSECK2 as aes ep11 type 6 key 
returned %d", rc);
+                       /* Retry to generate a type 3 key */
+                       genseck2.type = TOKVER_EP11_AES; /* 0x03 */;
+                       rc = ioctl(pkeyfd, PKEY_GENSECK2, &genseck2);
+                       DEBUG("ioctl PKEY_GENSECK2 as aes ep11 type 3 key 
returned %d", rc);
+                       if (rc != 0) {
+                               rc = ZPC_ERROR_IOCTLGENSECK2;
+                               goto ret;
+                       }
+                       hdr_to_add = 1;
+               } else {
+                       rc = ZPC_ERROR_IOCTLGENSECK2;
+                       goto ret;
+               }
        }
 
        aes_key->cur.seclen = genseck2.keylen;
@@ -750,12 +805,17 @@
        if (rc)
                goto ret;
 
-       if (aes_key->type == ZPC_AES_KEY_TYPE_EP11) {
+       if (aes_key->type == ZPC_AES_KEY_TYPE_EP11 && hdr_to_add) {
                rc = aes_key_add_ep11_header(aes_key);
                if (rc)
                        goto ret;
        }
 
+       if (aes_key->type == ZPC_AES_KEY_TYPE_EP11 && 
aes_key_blob_has_a_session(aes_key))
+               DEBUG("This aes ep11 key has a session id");
+       else
+               DEBUG("This aes ep11 key has no session id");
+
        DEBUG("aes key at %p: key set to generated secure key", aes_key);
        aes_key->key_set = 1;
        rc = 0;
@@ -1101,6 +1161,47 @@
        return aes_key_sec2prot_without_header(aes_key, sec);
 }
 
+int aes_key_clr2prot(struct zpc_aes_key *aes_key, const unsigned char *key,
+                                       unsigned int keylen)
+{
+       struct pkey_kblob2pkey3 io;
+       unsigned char buf[sizeof(struct clearkeytoken) + 32];
+       struct clearkeytoken *clrtok = (struct clearkeytoken *)&buf;
+       int rc;
+
+       memset(buf, 0, sizeof(buf));
+       clrtok->version = 0x02;
+       switch (keylen) {
+       case 16:
+               clrtok->keytype = PKEY_KEYTYPE_AES_128;
+               break;
+       case 24:
+               clrtok->keytype = PKEY_KEYTYPE_AES_192;
+               break;
+       default:
+               clrtok->keytype = PKEY_KEYTYPE_AES_256;
+               break;
+       }
+       memcpy(clrtok->clearkey, key, keylen);
+       clrtok->len = keylen;
+
+       memset(&io, 0, sizeof(io));
+       io.key = buf;
+       io.keylen = sizeof(struct clearkeytoken) + keylen;
+       io.apqns = aes_key->apqns;
+       io.apqn_entries = aes_key->napqns;
+       io.pkeytype = aes_key->type;
+       io.pkeylen = sizeof(aes_key->prot.protkey);
+       io.pkey = (unsigned char *)&aes_key->prot.protkey;
+
+       rc = ioctl(pkeyfd, PKEY_KBLOB2PROTK3, &io);
+       if (rc != 0) {
+               return ZPC_ERROR_IOCTLBLOB2PROTK3;
+       }
+
+       return 0;
+}
+
 int
 aes_key_check(const struct zpc_aes_key *aes_key)
 {
@@ -1198,7 +1299,18 @@
        ep11hdr = (struct ep11kblob_header *)aes_key->cur.sec;
        ep11hdr->len = sizeof(struct ep11kblob_header) + aes_key->cur.seclen;
        ep11hdr->version = TOKVER_EP11_AES_WITH_HEADER;
+       ep11hdr->bitlen = aes_key->keysize;
        aes_key->cur.seclen = ep11hdr->len;
 
        return 0;
 }
+
+static int aes_key_blob_has_a_session(struct zpc_aes_key *aes_key)
+{
+       u8 session[32] = { 0, };
+
+       if (memcmp(aes_key->cur.sec + sizeof(struct ep11kblob_header), session, 
32) == 0)
+               return 0;
+
+       return 1;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/aes_key_local.h 
new/libzpc-1.2.0/src/aes_key_local.h
--- old/libzpc-1.1.1/src/aes_key_local.h        2023-09-15 12:52:28.000000000 
+0200
+++ new/libzpc-1.2.0/src/aes_key_local.h        2024-01-12 10:26:07.000000000 
+0100
@@ -62,5 +62,7 @@
 
 int aes_key_sec2prot(struct zpc_aes_key *, enum aes_key_sec sec);
 int aes_key_check(const struct zpc_aes_key *);
+int aes_key_clr2prot(struct zpc_aes_key *, const unsigned char *key,
+                       unsigned int keylen);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/aes_xts.c 
new/libzpc-1.2.0/src/aes_xts.c
--- old/libzpc-1.1.1/src/aes_xts.c      2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/aes_xts.c      2024-01-12 10:26:07.000000000 +0100
@@ -25,6 +25,7 @@
 #include <string.h>
 
 static int __aes_xts_set_iv(struct zpc_aes_xts *, const u8 *);
+static int __aes_xts_set_intermediate_iv(struct zpc_aes_xts *, const u8 
iv[16]);
 static int __aes_xts_crypt(struct zpc_aes_xts *, u8 *, const u8 *, size_t,
     unsigned long);
 static void __aes_xts_reset(struct zpc_aes_xts *);
@@ -260,6 +261,87 @@
 }
 
 int
+zpc_aes_xts_get_intermediate_iv(struct zpc_aes_xts *aes_xts, unsigned char 
iv[16])
+{
+       int rc, off1;
+
+       if (pkeyfd < 0) {
+               rc = ZPC_ERROR_DEVPKEY;
+               goto ret;
+       }
+       if (!hwcaps.aes_xts) {
+               rc = ZPC_ERROR_HWCAPS;
+               goto ret;
+       }
+       if (aes_xts == NULL) {
+               rc = ZPC_ERROR_ARG1NULL;
+               goto ret;
+       }
+
+       if (iv == NULL) {
+               rc = ZPC_ERROR_ARG2NULL;
+               goto ret;
+       }
+
+       if (aes_xts->iv_set != 1) {
+               rc = ZPC_ERROR_IVNOTSET;
+               goto ret;
+       }
+
+       off1 = AES_XTS_KM_XTSPARAM(aes_xts->aes_key1->keysize);
+       memcpy(iv, aes_xts->param_km + off1, 16);
+       rc = 0;
+
+ret:
+       DEBUG("return %d (%s)", rc, zpc_error_string(rc));
+       return rc;
+}
+
+int
+zpc_aes_xts_set_intermediate_iv(struct zpc_aes_xts *aes_xts, const unsigned 
char iv[16])
+{
+       int rc;
+
+       if (pkeyfd < 0) {
+               rc = ZPC_ERROR_DEVPKEY;
+               goto ret;
+       }
+       if (!hwcaps.aes_xts) {
+               rc = ZPC_ERROR_HWCAPS;
+               goto ret;
+       }
+       if (aes_xts == NULL) {
+               rc = ZPC_ERROR_ARG1NULL;
+               goto ret;
+       }
+       if (iv == NULL) {
+               rc = ZPC_ERROR_ARG2NULL;
+               goto ret;
+       }
+
+       if (aes_xts->key_set != 1) {
+               rc = ZPC_ERROR_KEYNOTSET;
+               goto ret;
+       }
+
+       if (aes_xts->iv_set != 1) {
+               rc = ZPC_ERROR_IVNOTSET;
+               goto ret;
+       }
+
+       rc = __aes_xts_set_intermediate_iv(aes_xts, iv);
+       if (rc)
+               goto ret;
+
+       aes_xts->iv_set = 1;
+
+       DEBUG("aes-xts context at %p: intermediate iv set", aes_xts);
+ret:
+       DEBUG("return %d (%s)", rc, zpc_error_string(rc));
+       return rc;
+}
+
+int
 zpc_aes_xts_encrypt(struct zpc_aes_xts *aes_xts, u8 * c, const u8 * m,
     size_t mlen)
 {
@@ -503,6 +585,24 @@
        return rc;
 }
 
+static int
+__aes_xts_set_intermediate_iv(struct zpc_aes_xts *aes_xts, const u8 iv[16])
+{
+       int rc, off1;
+
+       assert(aes_xts != NULL);
+       assert(iv != NULL);
+       assert(aes_xts->aes_key1 != NULL);
+       assert(aes_xts->aes_key2 != NULL);
+       assert(aes_xts->key_set == 1);
+
+       off1 = AES_XTS_KM_XTSPARAM(aes_xts->aes_key1->keysize);
+       memcpy(aes_xts->param_km + off1, iv, 16);
+       rc = 0;
+
+       return rc;
+}
+
 static int
 __aes_xts_crypt(struct zpc_aes_xts *aes_xts, u8 * out, const u8 * in,
     size_t inlen, unsigned long flags)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/ecc_key.c 
new/libzpc-1.2.0/src/ecc_key.c
--- old/libzpc-1.1.1/src/ecc_key.c      2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/ecc_key.c      2024-01-12 10:26:07.000000000 +0100
@@ -30,6 +30,7 @@
 extern const size_t curve2puboffset[];
 extern const size_t curve2macedspkilen[];
 extern const size_t curve2rawspkilen[];
+extern const u32 curve2pkey_keytype[];
 
 static void __ec_key_reset(struct zpc_ec_key *);
 static int ec_key_check_ep11_spki(const struct zpc_ec_key *ec_key,
@@ -811,9 +812,12 @@
                        goto ret;
                }
 
-               rc = ec_key_sec2prot(ec_key, EC_KEY_SEC_CUR);
+               rc = ec_key_clr2prot(ec_key, privkey, privlen);
                if (rc) {
-                       goto ret;
+                       rc = ec_key_sec2prot(ec_key, EC_KEY_SEC_CUR);
+                       if (rc) {
+                               goto ret;
+                       }
                }
 
                DEBUG("ec key at %p: private/protected key set", ec_key);
@@ -1269,6 +1273,68 @@
        io.apqns = ec_key->apqns;
        io.apqn_entries = ec_key->napqns;
        io.pkeytype = (ec_key->type == ZPC_EC_KEY_TYPE_CCA ? PKEY_TYPE_CCA_ECC 
: PKEY_TYPE_EP11_ECC);
+       io.pkeylen = sizeof(ec_key->prot.protkey);
+       io.pkey = (unsigned char *)&ec_key->prot.protkey;
+
+       rc = ioctl(pkeyfd, PKEY_KBLOB2PROTK3, &io);
+       if (rc != 0) {
+               return ZPC_ERROR_IOCTLBLOB2PROTK3;
+       }
+
+       return 0;
+}
+
+int ec_key_clr2prot(struct zpc_ec_key *ec_key, const unsigned char *privkey,
+                                       unsigned int privlen)
+{
+       struct pkey_kblob2pkey3 io;
+       unsigned char buf[sizeof(struct clearkeytoken) + 80];
+       struct clearkeytoken *clrtok = (struct clearkeytoken *)&buf;
+       int rc;
+
+       memset(buf, 0, sizeof(buf));
+       clrtok->version = 0x02;
+       clrtok->keytype = curve2pkey_keytype[ec_key->curve];
+       switch (clrtok->keytype) {
+       case PKEY_KEYTYPE_ECC_P256:
+       case PKEY_KEYTYPE_ECC_P384:
+       case PKEY_KEYTYPE_ECC_ED25519:
+               memcpy(clrtok->clearkey, privkey, privlen);
+               clrtok->len = privlen;
+               break;
+       case PKEY_KEYTYPE_ECC_P521:
+               memcpy(clrtok->clearkey + 80 - privlen, privkey, privlen);
+               clrtok->len = 80;
+               break;
+       case PKEY_KEYTYPE_ECC_ED448:
+               memcpy(clrtok->clearkey + 64 - privlen, privkey, privlen);
+               clrtok->len = 64;
+               break;
+       default: /* should not occur */
+               return ZPC_ERROR_EC_INVALID_CURVE;
+       }
+
+       memset(&io, 0, sizeof(io));
+       io.key = buf;
+       switch (clrtok->keytype) {
+       case PKEY_KEYTYPE_ECC_P256:
+       case PKEY_KEYTYPE_ECC_P384:
+       case PKEY_KEYTYPE_ECC_ED25519:
+               io.keylen = sizeof(struct clearkeytoken) + privlen;
+               break;
+       case PKEY_KEYTYPE_ECC_P521:
+               io.keylen = sizeof(struct clearkeytoken) + 80;
+               break;
+       case PKEY_KEYTYPE_ECC_ED448:
+               io.keylen = sizeof(struct clearkeytoken) + 64;
+               break;
+       default: /* should not occur */
+               return ZPC_ERROR_EC_INVALID_CURVE;
+       }
+
+       io.apqns = ec_key->apqns;
+       io.apqn_entries = ec_key->napqns;
+       io.pkeytype = (ec_key->type == ZPC_EC_KEY_TYPE_CCA ? PKEY_TYPE_CCA_ECC 
: PKEY_TYPE_EP11_ECC);
        io.pkeylen = sizeof(ec_key->prot.protkey);
        io.pkey = (unsigned char *)&ec_key->prot.protkey;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/ecc_key_local.h 
new/libzpc-1.2.0/src/ecc_key_local.h
--- old/libzpc-1.1.1/src/ecc_key_local.h        2023-09-15 12:52:28.000000000 
+0200
+++ new/libzpc-1.2.0/src/ecc_key_local.h        2024-01-12 10:26:07.000000000 
+0100
@@ -63,4 +63,6 @@
                        const unsigned char *privkey, unsigned int privlen);
 int ec_key_sec2prot(struct zpc_ec_key *, enum ec_key_sec sec);
 int ec_key_check(const struct zpc_ec_key *);
+int ec_key_clr2prot(struct zpc_ec_key *ec_key, const unsigned char *privkey,
+                       unsigned int privlen);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/error.c new/libzpc-1.2.0/src/error.c
--- old/libzpc-1.1.1/src/error.c        2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/error.c        2024-01-12 10:26:07.000000000 +0100
@@ -93,6 +93,8 @@
                "The given buffer does not contain a valid EP11 AES secure key 
token.",
                "The given buffer does not contain a valid CCA datakey token",
                "The given buffer does not contain a valid CCA cipherkey token",
+               "Error creating random bytes",
+               "Invalid usage of a gcm context with an internally created iv"
                "LAST"
        };
        const char *rc;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/misc.c new/libzpc-1.2.0/src/misc.c
--- old/libzpc-1.1.1/src/misc.c 2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/misc.c 2024-01-12 10:26:07.000000000 +0100
@@ -10,12 +10,36 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 static int ishexdigit(const char);
 static unsigned char hexdigit2byte(char);
 static char byte2hexdigit(unsigned char);
 
 int
+local_rng(u8 *output, size_t bytes)
+{
+       int ranfd;
+       int rlen;
+       unsigned int totallen = 0;
+
+       ranfd = open("/dev/prandom", O_RDONLY);
+       if (ranfd < 0)
+               ranfd = open("/dev/urandom", O_RDONLY);
+       if (ranfd >= 0) {
+               do {
+                       rlen = read(ranfd, output + totallen, bytes - totallen);
+                       totallen += rlen;
+               } while (totallen < bytes);
+               close(ranfd);
+               return 0;
+       }
+
+       return -1;
+}
+
+int
 hexstr2buf(u8 * buf, size_t *buflen, const char *hex)
 {
        size_t i;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/misc.h new/libzpc-1.2.0/src/misc.h
--- old/libzpc-1.1.1/src/misc.h 2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/misc.h 2024-01-12 10:26:07.000000000 +0100
@@ -27,5 +27,6 @@
 int memcmp_consttime(const void *, const void *, size_t);
 int hexstr2buf(u8 *, size_t *, const char *);
 void buf2hexstr(char *, size_t, const unsigned char *, size_t);
+int local_rng(u8 *output, size_t bytes);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/zkey/pkey.c 
new/libzpc-1.2.0/src/zkey/pkey.c
--- old/libzpc-1.1.1/src/zkey/pkey.c    2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/zkey/pkey.c    2024-01-12 10:26:07.000000000 +0100
@@ -418,3 +418,11 @@
        sizeof(ed25519_maced_spki_t) - EP11_SPKI_MACLEN,
        sizeof(ed448_maced_spki_t) - EP11_SPKI_MACLEN,
 };
+
+const u32 curve2pkey_keytype[] = {
+       PKEY_KEYTYPE_ECC_P256,
+       PKEY_KEYTYPE_ECC_P384,
+       PKEY_KEYTYPE_ECC_P521,
+       PKEY_KEYTYPE_ECC_ED25519,
+       PKEY_KEYTYPE_ECC_ED448,
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/src/zkey/pkey.h 
new/libzpc-1.2.0/src/zkey/pkey.h
--- old/libzpc-1.1.1/src/zkey/pkey.h    2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/src/zkey/pkey.h    2024-01-12 10:26:07.000000000 +0100
@@ -259,6 +259,22 @@
 #define PKEY_KEYTYPE_AES_192   2
 #define PKEY_KEYTYPE_AES_256   3
 #define PKEY_KEYTYPE_ECC               4
+#define PKEY_KEYTYPE_ECC_P256         5
+#define PKEY_KEYTYPE_ECC_P384         6
+#define PKEY_KEYTYPE_ECC_P521         7
+#define PKEY_KEYTYPE_ECC_ED25519      8
+#define PKEY_KEYTYPE_ECC_ED448        9
+
+/* inside view of a clear key token (type 0x00 version 0x02) */
+struct clearkeytoken {
+       u8 type; /* 0x00 for PAES specific key tokens */
+       u8 res0[3];
+       u8 version; /* 0x02 for clear key token */
+       u8 res1[3];
+       u32 keytype; /* key type, one of the PKEY_KEYTYPE_* values */
+       u32 len; /* bytes actually stored in clearkey[] */
+       u8 clearkey[]; /* clear key value */
+} __packed;
 
 struct pkey_genseck {
        u16 cardnr;                     /* in: card to use or FFFF for any */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/test/t_aes_cbc.cc 
new/libzpc-1.2.0/test/t_aes_cbc.cc
--- old/libzpc-1.1.1/test/t_aes_cbc.cc  2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/test/t_aes_cbc.cc  2024-01-12 10:26:07.000000000 +0100
@@ -690,6 +690,128 @@
        free(ct);
 }
 
+TEST(aes_cbc, stream_inplace_kat3)
+{
+       TESTLIB_ENV_AES_KEY_CHECK();
+
+       TESTLIB_AES_CBC_HW_CAPS_CHECK();
+
+       TESTLIB_AES_KERNEL_CAPS_CHECK();
+
+       size_t keylen, ivlen, msglen, ctlen;
+       unsigned char buf[4096], iv2[16];
+       const char *mkvp, *apqns[257];
+       struct zpc_aes_key *aes_key;
+       struct zpc_aes_cbc *aes_cbc1, *aes_cbc2;
+       unsigned int flags;
+       int type, rc;
+
+       const char *keystr = "b6f9afbfe5a1562bba1368fc72ac9d9c";
+       const char *ivstr = "3f9d5ebe250ee7ce384b0d00ee849322";
+       const char *msgstr = 
"db397ec22718dbffb9c9d13de0efcd4611bf792be4fce0dc5f25d4f577ed8cdbd4eb9208d593dda3d4653954ab64f05676caa3ce9bfa795b08b67ceebc923fdc89a8c431188e9e482d8553982cf304d1";
+       const char *ctstr = 
"10ea27b19e16b93af169c4a88e06e35c99d8b420980b058e34b4b8f132b13766f72728202b089f428fecdb41c79f8aa0d0ef68f5786481cca29e2126f69bc14160f1ae2187878ba5c49cf3961e1b7ee9";
+
+       type = testlib_env_aes_key_type();
+       flags = testlib_env_aes_key_flags();
+       mkvp = testlib_env_aes_key_mkvp();
+       (void)testlib_env_aes_key_apqns(apqns);
+
+       TESTLIB_AES_SW_CAPS_CHECK(type);
+
+       u8 *key = testlib_hexstr2buf(keystr, &keylen);
+       ASSERT_NE(key, nullptr);
+       u8 *iv = testlib_hexstr2buf(ivstr, &ivlen);
+       ASSERT_NE(iv, nullptr);
+       u8 *msg = testlib_hexstr2buf(msgstr, &msglen);
+       ASSERT_NE(msg, nullptr);
+       u8 *ct = testlib_hexstr2buf(ctstr, &ctlen);
+       ASSERT_NE(ct, nullptr);
+
+       rc = zpc_aes_key_alloc(&aes_key);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_alloc(&aes_cbc1);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_alloc(&aes_cbc2);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_key_set_type(aes_key, type);
+       EXPECT_EQ(rc, 0);
+       if (mkvp != NULL) {
+               rc = zpc_aes_key_set_mkvp(aes_key, mkvp);
+               EXPECT_EQ(rc, 0);
+       } else {
+               rc = zpc_aes_key_set_apqns(aes_key, apqns);
+               EXPECT_EQ(rc, 0);
+       }
+       rc = zpc_aes_key_set_flags(aes_key, flags);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_key_set_size(aes_key, keylen * 8);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_key_import_clear(aes_key, key);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_cbc_set_key(aes_cbc1, aes_key);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_set_key(aes_cbc2, aes_key);
+       EXPECT_EQ(rc, 0);
+
+       /* Encrypt first chunk with first ctx */
+       memcpy(buf, msg, msglen);
+       rc = zpc_aes_cbc_set_iv(aes_cbc1, iv);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_encrypt(aes_cbc1, buf, buf, 16);
+       EXPECT_EQ(rc, 0);
+
+       /* Get intermediate iv from first ctx */
+       rc = zpc_aes_cbc_get_intermediate_iv(aes_cbc1, iv2);
+       EXPECT_EQ(rc, 0);
+
+       /* Encrypt a 2nd chunk with 2nd ctx */
+       rc = zpc_aes_cbc_set_iv(aes_cbc2, iv);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_set_intermediate_iv(aes_cbc2, iv2);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_encrypt(aes_cbc2, buf + 16, buf + 16, msglen - 16);
+       EXPECT_EQ(rc, 0);
+
+       EXPECT_TRUE(memcmp(buf, ct, ctlen) == 0);
+
+       /* Decrypt first chunk with first ctx */
+       memcpy(buf, ct, ctlen);
+       rc = zpc_aes_cbc_set_iv(aes_cbc1, iv);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_decrypt(aes_cbc1, buf, buf, 16);
+       EXPECT_EQ(rc, 0);
+
+       /* Get intermediate iv from first ctx */
+       rc = zpc_aes_cbc_get_intermediate_iv(aes_cbc1, iv2);
+       EXPECT_EQ(rc, 0);
+
+       /* Decrypt remaining chunk with 2nd ctx */
+       rc = zpc_aes_cbc_set_iv(aes_cbc2, iv);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_set_intermediate_iv(aes_cbc2, iv2);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_cbc_decrypt(aes_cbc2, buf + 16, buf + 16, msglen - 16);
+       EXPECT_EQ(rc, 0);
+
+       EXPECT_TRUE(memcmp(buf, msg, msglen) == 0);
+
+       zpc_aes_cbc_free(&aes_cbc1);
+       EXPECT_EQ(aes_cbc1, nullptr);
+       zpc_aes_cbc_free(&aes_cbc2);
+       EXPECT_EQ(aes_cbc2, nullptr);
+       zpc_aes_key_free(&aes_key);
+       EXPECT_EQ(aes_key, nullptr);
+
+       free(key);
+       free(iv);
+       free(msg);
+       free(ct);
+}
+
 TEST(aes_cbc, nist_kat)
 {
        TESTLIB_ENV_AES_KEY_CHECK();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/test/t_aes_gcm.cc 
new/libzpc-1.2.0/test/t_aes_gcm.cc
--- old/libzpc-1.1.1/test/t_aes_gcm.cc  2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/test/t_aes_gcm.cc  2024-01-12 10:26:07.000000000 +0100
@@ -210,6 +210,109 @@
        EXPECT_EQ(aes_key, nullptr);
 }
 
+TEST(aes_gcm, create_iv)
+{
+       struct zpc_aes_key *aes_key;
+       struct zpc_aes_gcm *aes_gcm1, *aes_gcm2;
+       const char *mkvp, *apqns[257];
+       u8 aad[99], m[99], tag[16], tmp_tag[16], buf[99], pt[99];
+       u8 iv_buf[4096];
+       int rc, size, type;
+       unsigned int flags;
+
+       TESTLIB_ENV_AES_KEY_CHECK();
+
+       TESTLIB_AES_GCM_HW_CAPS_CHECK();
+
+       TESTLIB_AES_KERNEL_CAPS_CHECK();
+
+       size = testlib_env_aes_key_size();
+       type = testlib_env_aes_key_type();
+       flags = testlib_env_aes_key_flags();
+       mkvp = testlib_env_aes_key_mkvp();
+       (void)testlib_env_aes_key_apqns(apqns);
+
+       TESTLIB_AES_SW_CAPS_CHECK(type);
+
+       rc = zpc_aes_key_alloc(&aes_key);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_gcm_alloc(&aes_gcm1);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_gcm_alloc(&aes_gcm2);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_gcm_create_iv(aes_gcm1, iv_buf, 0);
+       EXPECT_EQ(rc, ZPC_ERROR_IVSIZE);
+       rc = zpc_aes_gcm_create_iv(aes_gcm1, iv_buf, 1234);
+       EXPECT_EQ(rc, ZPC_ERROR_KEYNOTSET);
+
+       rc = zpc_aes_key_set_size(aes_key, size);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_key_set_type(aes_key, type);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_key_set_flags(aes_key, flags);
+       EXPECT_EQ(rc, 0);
+       if (mkvp != NULL) {
+               rc = zpc_aes_key_set_mkvp(aes_key, mkvp);
+               EXPECT_EQ(rc, 0);
+       } else {
+               rc = zpc_aes_key_set_apqns(aes_key, apqns);
+               EXPECT_EQ(rc, 0);
+       }
+
+       rc = zpc_aes_key_generate(aes_key);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_gcm_set_key(aes_gcm1, aes_key);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_gcm_set_key(aes_gcm2, aes_key);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_gcm_create_iv(aes_gcm1, iv_buf, SIZE_MAX);
+       EXPECT_EQ(rc, ZPC_ERROR_IVSIZE);
+       rc = zpc_aes_gcm_create_iv(aes_gcm1, iv_buf, 11);
+       EXPECT_EQ(rc, ZPC_ERROR_IVSIZE);
+       rc = zpc_aes_gcm_create_iv(aes_gcm1, iv_buf, 12);
+       EXPECT_EQ(rc, 0);
+
+       /* Create internal iv for encrypt/decrypt */
+       rc = zpc_aes_gcm_create_iv(aes_gcm1, iv_buf, 1234);
+       EXPECT_EQ(rc, 0);
+
+       /* Encrypt in-place with internally created iv */
+       rc = zpc_aes_gcm_encrypt(aes_gcm1, buf, tag, sizeof(tag), aad, 
sizeof(aad), m, sizeof(m));
+       EXPECT_EQ(rc, 0);
+
+       /*
+        * Try to use set_iv on first ctx with already created internal iv. This
+        * fails because it is not allowed to overwrite an internal iv.
+        */
+       rc = zpc_aes_gcm_set_iv(aes_gcm1, iv_buf, 78);
+       EXPECT_EQ(rc, ZPC_ERROR_GCM_IV_CREATED_INTERNALLY);
+
+       /*
+        * Try to use same ctx for decrypt: this fails, because the initial iv
+        * is not available because set_iv is not allowed on this ctx after
+        * creating an internal iv.
+        */
+       memcpy(tmp_tag, tag, sizeof(tag));
+       rc = zpc_aes_gcm_decrypt(aes_gcm1, pt, tmp_tag, sizeof(tmp_tag), aad, 
sizeof(aad), buf, sizeof(buf));
+       EXPECT_EQ(rc, ZPC_ERROR_GCM_IV_CREATED_INTERNALLY);
+
+       /* Decrypt in-place with internally created iv and 2nd ctx */
+       rc = zpc_aes_gcm_set_iv(aes_gcm2, iv_buf, 1234);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_gcm_decrypt(aes_gcm2, pt, tag, sizeof(tag), aad, 
sizeof(aad), buf, sizeof(buf));
+       EXPECT_EQ(rc, 0);
+       EXPECT_TRUE(memcmp(pt, m, sizeof(m)) == 0);
+
+       zpc_aes_gcm_free(&aes_gcm1);
+       EXPECT_EQ(aes_gcm1, nullptr);
+       zpc_aes_gcm_free(&aes_gcm2);
+       EXPECT_EQ(aes_gcm2, nullptr);
+       zpc_aes_key_free(&aes_key);
+       EXPECT_EQ(aes_key, nullptr);
+}
+
 TEST(aes_gcm, encrypt)
 {
        struct zpc_aes_key *aes_key;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/test/t_aes_key.cc 
new/libzpc-1.2.0/test/t_aes_key.cc
--- old/libzpc-1.1.1/test/t_aes_key.cc  2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/test/t_aes_key.cc  2024-01-12 10:26:07.000000000 +0100
@@ -628,7 +628,8 @@
 {
        struct zpc_aes_key *aes_key, *aes_key2;
        u8 buf[1000], buf2[1000], buf3[1000];
-       unsigned int flags;
+       u8 session[32];
+       unsigned int flags, key_had_a_session = 0;
        const char *apqns[257];
        int rc, size, type;
        size_t buflen = sizeof(buf);
@@ -692,15 +693,27 @@
        rc = zpc_aes_key_export(aes_key, buf, &buflen);
        EXPECT_EQ(rc, 0);
 
+       /* Check if the key contains a session id. In this case let's save the
+        * session before converting the blob into an "old style" key. */
+       memset(session, 0, 32);
+       ep11hdr = (struct ep11kblob_header *)buf;
+       if (ep11hdr->version == 0x06 &&
+               memcmp(buf + sizeof(struct ep11kblob_header), session, 32) != 
0) {
+               memcpy(session, buf + sizeof(struct ep11kblob_header), 32);
+               key_had_a_session = 1;
+       }
+
        /* Convert blob into an "old style" TOKVER_EP11_AES without header. For
         * backward compatibility such keys are still accepted, but internally
         * converted into "new style" keys with header. */
        memset(buf3, 0, sizeof(buf3));
        buf3len = buflen - sizeof(struct ep11kblob_header);
        memcpy(buf3, buf + sizeof(struct ep11kblob_header), buf3len);
+       memset(buf3, 0, 32);
        ep11hdr = (struct ep11kblob_header *)buf3;
        ep11hdr->version = 0x03; /* TOKVER_EP11_AES */
        ep11hdr->len = buf3len;
+       ep11hdr->bitlen = size;
 
        /* Import "old style" key */
        rc = zpc_aes_key_import(aes_key2, buf3, buf3len);
@@ -711,13 +724,17 @@
        rc = zpc_aes_key_export(aes_key2, buf2, &buf2len);
        EXPECT_EQ(rc, 0);
 
+       /* If the original key had a session id, restore it now */
+       if (key_had_a_session)
+               memcpy(buf2 + sizeof(struct ep11kblob_header), session, 32);
+
        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);
+       memset(buf3 + 16, 0x5c, sizeof(struct ep11kblob_header));
        rc = zpc_aes_key_import(aes_key2, buf3, buf3len);
        EXPECT_EQ(rc, ZPC_ERROR_AES_NO_EP11_SECUREKEY_TOKEN);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/test/t_aes_xts.cc 
new/libzpc-1.2.0/test/t_aes_xts.cc
--- old/libzpc-1.1.1/test/t_aes_xts.cc  2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/test/t_aes_xts.cc  2024-01-12 10:26:07.000000000 +0100
@@ -842,6 +842,166 @@
        free(ct);
 }
 
+TEST(aes_xts, stream_inplace_kat3)
+{
+       TESTLIB_ENV_AES_KEY_CHECK();
+
+       TESTLIB_AES_XTS_HW_CAPS_CHECK();
+
+       TESTLIB_AES_KERNEL_CAPS_CHECK();
+
+       size_t keylen, ivlen, msglen, ctlen;
+       unsigned char buf[4096], iv2[16];
+       const char *mkvp, *apqns[257];
+       struct zpc_aes_key *aes_key1, *aes_key2;
+       struct zpc_aes_xts *aes_xts1, *aes_xts2;
+       unsigned int flags;
+       int type, rc, size, i;
+
+       const char *keystr[] = {
+               
"63f36e9c397c6523c99f1644ecb1a5d9bc0f2f55fbe324444c390fae752ad4d7",
+               
"88dfd7c83cb121968feb417520555b36c0f63b662570eac12ea96cbe188ad5b1a44db23ac6470316cba0041cadf248f6d9a7713f454e663f3e3987585cebbf96",
+       };
+       const char *ivstr[] = {
+               "cdb1bd3486f353cc160a840beadf0329",
+               "0ee84632b838dd528f1d96c76439805c",
+       };
+       const char *msgstr[] = {
+               
"9a0149888bf76160a81428bc9140eccd26ed18368e24d49b9cc512929a88ad1e66c763f4f56b63bb9dd9508c5d4df465",
+               
"ec36551c70efcdf85de7a39988978263ad261e83996dad219a0058e02187384f2d0754ff9cfa000bec448fafd2cfa738",
+       };
+       const char *ctstr[] = {
+               
"0eeef28ca159b805f5c215610551678ab772f279374fb140ab550768db42cf6cb73637641934195ffc08cf5a9188b82b",
+               
"a55d533c9c5885562b92d4582ea69db8e2ba9c0b967a9f0167700b043525a47bafe7d630774eaf4a1dc9fbcf94a1fda4",
+       };
+
+       size = testlib_env_aes_key_size();
+       type = testlib_env_aes_key_type();
+       flags = testlib_env_aes_key_flags();
+       mkvp = testlib_env_aes_key_mkvp();
+       (void)testlib_env_aes_key_apqns(apqns);
+
+       TESTLIB_AES_SW_CAPS_CHECK(type);
+
+       TESTLIB_AES_XTS_KEY_SIZE_CHECK(size);
+
+       i = size == 128 ? 0 : 1;
+
+       u8 *key1 = testlib_hexstr2buf(keystr[i], &keylen);
+       ASSERT_NE(key1, nullptr);
+       keylen /= 2;
+       u8 *key2 = key1 + keylen;
+       u8 *iv = testlib_hexstr2buf(ivstr[i], &ivlen);
+       ASSERT_NE(iv, nullptr);
+       u8 *msg = testlib_hexstr2buf(msgstr[i], &msglen);
+       ASSERT_NE(msg, nullptr);
+       u8 *ct = testlib_hexstr2buf(ctstr[i], &ctlen);
+       ASSERT_NE(ct, nullptr);
+
+       rc = zpc_aes_key_alloc(&aes_key1);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_key_alloc(&aes_key2);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_xts_alloc(&aes_xts1);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_xts_alloc(&aes_xts2);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_key_set_type(aes_key1, type);
+       EXPECT_EQ(rc, 0);
+       if (mkvp != NULL) {
+               rc = zpc_aes_key_set_mkvp(aes_key1, mkvp);
+               EXPECT_EQ(rc, 0);
+       } else {
+               rc = zpc_aes_key_set_apqns(aes_key1, apqns);
+               EXPECT_EQ(rc, 0);
+       }
+       rc = zpc_aes_key_set_flags(aes_key1, flags);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_key_set_size(aes_key1, keylen * 8);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_key_import_clear(aes_key1, key1);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_key_set_type(aes_key2, type);
+       EXPECT_EQ(rc, 0);
+       if (mkvp != NULL) {
+               rc = zpc_aes_key_set_mkvp(aes_key2, mkvp);
+               EXPECT_EQ(rc, 0);
+       } else {
+               rc = zpc_aes_key_set_apqns(aes_key2, apqns);
+               EXPECT_EQ(rc, 0);
+       }
+       rc = zpc_aes_key_set_flags(aes_key2, flags);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_key_set_size(aes_key2, keylen * 8);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_key_import_clear(aes_key2, key2);
+       EXPECT_EQ(rc, 0);
+
+       rc = zpc_aes_xts_set_key(aes_xts1, aes_key1, aes_key2);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_xts_set_key(aes_xts2, aes_key1, aes_key2);
+       EXPECT_EQ(rc, 0);
+
+       /* Encrypt first chunk with first ctx */
+       memcpy(buf, msg, msglen);
+       rc = zpc_aes_xts_set_iv(aes_xts1, iv);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_xts_encrypt(aes_xts1, buf, buf, 16);
+       EXPECT_EQ(rc, 0);
+
+       /* Get intermediate iv from first ctx */
+       rc = zpc_aes_xts_get_intermediate_iv(aes_xts1, iv2);
+       EXPECT_EQ(rc, 0);
+
+       /* Encrypt a 2nd chunk with 2nd ctx */
+       rc = zpc_aes_xts_set_iv(aes_xts2, iv);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_xts_set_intermediate_iv(aes_xts2, iv2);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_xts_encrypt(aes_xts2, buf + 16, buf + 16, msglen - 16);
+       EXPECT_EQ(rc, 0);
+
+       EXPECT_TRUE(memcmp(buf, ct, msglen) == 0);
+
+       /* Decrypt first chunk with first ctx */
+       memcpy(buf, ct, ctlen);
+       rc = zpc_aes_xts_set_iv(aes_xts1, iv);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_xts_decrypt(aes_xts1, buf, buf, 16);
+       EXPECT_EQ(rc, 0);
+
+       /* Get intermediate iv from first ctx */
+       rc = zpc_aes_xts_get_intermediate_iv(aes_xts1, iv2);
+       EXPECT_EQ(rc, 0);
+
+       /* Decrypt remaining chunk with 2nd ctx */
+       rc = zpc_aes_xts_set_iv(aes_xts2, iv);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_xts_set_intermediate_iv(aes_xts2, iv2);
+       EXPECT_EQ(rc, 0);
+       rc = zpc_aes_xts_decrypt(aes_xts2, buf + 16, buf + 16, msglen - 16);
+       EXPECT_EQ(rc, 0);
+
+       EXPECT_TRUE(memcmp(buf, msg, msglen) == 0);
+
+       zpc_aes_xts_free(&aes_xts1);
+       EXPECT_EQ(aes_xts1, nullptr);
+       zpc_aes_xts_free(&aes_xts2);
+       EXPECT_EQ(aes_xts2, nullptr);
+       zpc_aes_key_free(&aes_key1);
+       EXPECT_EQ(aes_key1, nullptr);
+       zpc_aes_key_free(&aes_key2);
+       EXPECT_EQ(aes_key2, nullptr);
+
+       free(key1);
+       free(iv);
+       free(msg);
+       free(ct);
+}
+
 TEST(aes_xts, nist_kat)
 {
        TESTLIB_ENV_AES_KEY_CHECK();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzpc-1.1.1/test/t_error.cc 
new/libzpc-1.2.0/test/t_error.cc
--- old/libzpc-1.1.1/test/t_error.cc    2023-09-15 12:52:28.000000000 +0200
+++ new/libzpc-1.2.0/test/t_error.cc    2024-01-12 10:26:07.000000000 +0100
@@ -21,6 +21,6 @@
        errstr = zpc_error_string(-1);
        EXPECT_TRUE(strcmp(errstr, "undefined error code") == 0);
 
-       errstr = zpc_error_string(76);
+       errstr = zpc_error_string(78);
        EXPECT_TRUE(strcmp(errstr, "LAST") == 0);
 }

Reply via email to