import Oracle_OSS opencryptoki-3.26.0-2.el9_8.2

This commit is contained in:
AlmaLinux RelEng Bot 2026-06-26 07:30:00 -04:00
parent 5fcbe4e726
commit 40f91e506f
12 changed files with 2282 additions and 608 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/opencryptoki-3.25.0.tar.gz
SOURCES/opencryptoki-3.26.0.tar.gz

View File

@ -1 +1 @@
a52c4873734e8e68ae8d599e08d5a55c0b3459ad SOURCES/opencryptoki-3.25.0.tar.gz
c2e2f0fc220d106ece01dd4b4fd8091704cb8fac SOURCES/opencryptoki-3.26.0.tar.gz

View File

@ -1,43 +0,0 @@
commit 003d658322df316a352af591a3d059ca22fc40a3
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Jul 21 11:02:42 2025 +0200
Fix covscan findings
Closes: https://github.com/opencryptoki/opencryptoki/issues/879
Reported-by: Than Ngo <than@redhat.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/mech_aes.c b/usr/lib/common/mech_aes.c
index 9195ff3c..383fb775 100644
--- a/usr/lib/common/mech_aes.c
+++ b/usr/lib/common/mech_aes.c
@@ -4561,6 +4561,11 @@ static CK_RV aeskw_wrap_pad(STDLL_TokData_t *tokdata, SESSION *sess,
* contains exactly eight octets, then prepend the AIV and encrypt
* the resulting 128-bit block using AES in ECB mode.
*/
+ if (in_data_len > AES_KEY_WRAP_BLOCK_SIZE) {
+ TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
+ return CKR_DATA_LEN_RANGE;
+ }
+
memmove(buff + AES_KEY_WRAP_BLOCK_SIZE, in_data, in_data_len);
memcpy(buff, aiv, AES_KEY_WRAP_IV_SIZE);
memset(buff + AES_KEY_WRAP_IV_SIZE + in_data_len, 0, padding_len);
diff --git a/usr/sbin/p11sak/p11tool.c b/usr/sbin/p11sak/p11tool.c
index da684f79..5b72b93b 100644
--- a/usr/sbin/p11sak/p11tool.c
+++ b/usr/sbin/p11sak/p11tool.c
@@ -567,6 +567,11 @@ static void p11tool_print_options_help(const struct p11tool_opt *opts,
else
len = snprintf(tmp, sizeof(tmp),"-%c", opt->short_opt);
+ if (len >= (int)sizeof(tmp) || len < 0) {
+ warnx("Error formatting option string. Skipping.\n");
+ continue;
+ }
+
if (opt->arg.type != ARG_TYPE_PLAIN) {
if (opt->arg.required)
snprintf(&tmp[len], sizeof(tmp) - len, " %s", opt->arg.name);

View File

@ -1,116 +0,0 @@
commit ab740fd0d596914919719ecbee90b0ad5fbb7112
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Nov 10 08:54:23 2025 +0100
EP11: Fix private secure key blob import
Newer EP11 firmware versions do not allow to get attribute CKA_VALUE_LEN
for private keys, because CKA_VALUE_LEN is not defined for these
key types. This now causes error CKR_ATTRIBUTE_TYPE_INVALID.
Older firmware versions ignored that and did not fail if CKA_VALUE_LEN
was attempted to be retrieved.
Use separate templates for getting the attributes of public, private or
secret keys, and get CKA_VALUE_LEN only for secret keys.
Fixes: 169ab762c283ca341350580c2c080720e62967e8
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 4e6944e6..b6a9c014 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -5386,13 +5386,24 @@ static CK_RV import_blob(STDLL_TokData_t *tokdata, SESSION *sess, OBJECT *obj,
CK_KEY_TYPE blob_type2 = CK_UNAVAILABLE_INFORMATION;
CK_ULONG value_len, value_len2, stdcomp, stdcomp2;
CK_BYTE buf[MAX_BLOBSIZE];
- CK_ATTRIBUTE get_attr[] = {
- { CKA_KEY_TYPE, &blob_type, sizeof(blob_type) }, /* must be first */
+ CK_ATTRIBUTE get_attr_pub[] = {
+ { CKA_KEY_TYPE, &blob_type, sizeof(blob_type) },
+ };
+ CK_ULONG get_attr_pub_num = sizeof(get_attr_pub) / sizeof(CK_ATTRIBUTE);
+ CK_ATTRIBUTE get_attr_priv[] = {
+ { CKA_KEY_TYPE, &blob_type, sizeof(blob_type) },
+ { CKA_IBM_STD_COMPLIANCE1, &stdcomp, sizeof(stdcomp) },
+ { CKA_PUBLIC_KEY_INFO, &buf, sizeof(buf) },
+ };
+ CK_ULONG get_attr_priv_num = sizeof(get_attr_priv) / sizeof(CK_ATTRIBUTE);
+ CK_ATTRIBUTE get_attr_sec[] = {
+ { CKA_KEY_TYPE, &blob_type, sizeof(blob_type) },
{ CKA_VALUE_LEN, &value_len, sizeof(value_len) },
{ CKA_IBM_STD_COMPLIANCE1, &stdcomp, sizeof(stdcomp) },
- { CKA_PUBLIC_KEY_INFO, &buf, sizeof(buf) } /* SPKI must be last */
};
- CK_ULONG get_attr_num = sizeof(get_attr) / sizeof(CK_ATTRIBUTE);
+ CK_ULONG get_attr_sec_num = sizeof(get_attr_sec) / sizeof(CK_ATTRIBUTE);
+ CK_ATTRIBUTE *get_attr = NULL;
+ CK_ULONG get_attr_num = 0;
CK_ATTRIBUTE get_attr2[] = {
{ CKA_KEY_TYPE, &blob_type2, sizeof(blob_type2) },
{ CKA_VALUE_LEN, &value_len2, sizeof(value_len2) },
@@ -5629,10 +5640,22 @@ static CK_RV import_blob(STDLL_TokData_t *tokdata, SESSION *sess, OBJECT *obj,
}
}
- if (class == CKO_PUBLIC_KEY)
- get_attr_num = 1; /* get only key type for public key */
- if (class == CKO_SECRET_KEY)
- get_attr_num--; /* don't get SPKI for secret key */
+ switch (class) {
+ case CKO_PUBLIC_KEY:
+ get_attr = get_attr_pub;
+ get_attr_num = get_attr_pub_num;
+ break;
+ case CKO_PRIVATE_KEY:
+ get_attr = get_attr_priv;
+ get_attr_num = get_attr_priv_num;
+ break;
+ case CKO_SECRET_KEY:
+ get_attr = get_attr_sec;
+ get_attr_num = get_attr_sec_num;
+ break;
+ default:
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
/* Get Key type and SPKI for private keys */
blob1_len = keytype == CKK_AES_XTS ? blob_len / 2 : blob_len;
@@ -5713,8 +5736,8 @@ static CK_RV import_blob(STDLL_TokData_t *tokdata, SESSION *sess, OBJECT *obj,
case CKO_PRIVATE_KEY:
rc = import_blob_private_public(tokdata, sess, obj, keytype,
- get_attr[get_attr_num - 1].pValue,
- get_attr[get_attr_num - 1].ulValueLen,
+ get_attr_priv[get_attr_priv_num - 1].pValue,
+ get_attr_priv[get_attr_priv_num - 1].ulValueLen,
FALSE);
if (rc != CKR_OK) {
TRACE_ERROR("%s import_blob_public failed rc=0x%lx\n",
@@ -5733,15 +5756,17 @@ static CK_RV import_blob(STDLL_TokData_t *tokdata, SESSION *sess, OBJECT *obj,
break;
}
- rc = template_build_update_attribute(obj->template, CKA_IBM_STD_COMPLIANCE1,
- (CK_BYTE *)&stdcomp, sizeof(stdcomp));
- if (rc != CKR_OK) {
- TRACE_ERROR("%s template_build_update_attribute failed rc=0x%lx\n",
- __func__, rc);
- return rc;
- }
-
if (class != CKO_PUBLIC_KEY) {
+ rc = template_build_update_attribute(obj->template,
+ CKA_IBM_STD_COMPLIANCE1,
+ (CK_BYTE *)&stdcomp,
+ sizeof(stdcomp));
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s template_build_update_attribute failed rc=0x%lx\n",
+ __func__, rc);
+ return rc;
+ }
+
/* Set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE */
rc = key_mgr_apply_always_sensitive_never_extractable_attrs(tokdata,
obj);

View File

@ -1,50 +0,0 @@
commit d3dc88c720fdbf56a64f3990148387649f366aeb
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Thu Nov 6 15:27:36 2025 +0100
EP11: Fix unwrapping of attribute bound EC keys
Newer EP11 firmware versions do not allow to get attribute CKA_VALUE_LEN
for non-symmetric keys, because CKA_VALUE_LEN is not defined for these
key types. This now causes error CKR_ATTRIBUTE_TYPE_INVALID.
Older firmware versions ignored that and did not fail if CKA_VALUE_LEN
was attempted to be retrieved.
Fix this by only attempting to obtain CKA_VALUE_LEN for keys that support
this attribute.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 1baa5443..4e6944e6 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -2222,17 +2222,26 @@ static CK_RV ab_unwrap_update_template(STDLL_TokData_t * tokdata,
{CKA_KEY_TYPE, &template_keytype, sizeof(template_keytype)},
{CKA_VALUE_LEN, &valuelen, sizeof(valuelen)},
};
+ CK_ULONG num_attrs = sizeof(attrs) / sizeof(CK_ATTRIBUTE);
CK_ULONG i;
CK_ATTRIBUTE *attr;
CK_BBOOL cktrue = TRUE;
CK_BYTE *useblob;
size_t useblob_len;
+ switch (keytype) {
+ case CKK_GENERIC_SECRET:
+ case CKK_AES:
+ break;
+ default:
+ num_attrs -= 1; /* No CKA_VALUE_LEN attribute */
+ break;
+ }
+
RETRY_SESSION_SINGLE_APQN_START(rc, tokdata)
RETRY_REENC_BLOB_START(tokdata, target_info, obj, blob, blob_len,
useblob, useblob_len, rc)
- rc = dll_m_GetAttributeValue(useblob, useblob_len, attrs,
- sizeof(attrs) / sizeof(CK_ATTRIBUTE),
+ rc = dll_m_GetAttributeValue(useblob, useblob_len, attrs, num_attrs,
target_info->target);
RETRY_REENC_BLOB_END(tokdata, target_info, useblob, useblob_len, rc)
RETRY_SESSION_SINGLE_APQN_END(rc, tokdata, session)

View File

@ -1,176 +0,0 @@
commit 144456ede9897662eed35ac8415d0ecb1c5907e3
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed Aug 13 13:50:24 2025 +0200
PKCSSLOTD: Remove the use of MD5
The pkcsslotd uses MD5 to calculate kind of a checksum of the token directory
path, for easy checking if the same token directory has already been used by
other tokens.
The use of MD5 for this is just historical, and has no security relevance at
all. Still, OpenSSL running in FIPS mode might reject the use of MD5, so
pkcsslotd will fail to start.
Change the code to use SHA256 instead.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h
index ec6a489a..fa0db30f 100644
--- a/usr/sbin/pkcsslotd/pkcsslotd.h
+++ b/usr/sbin/pkcsslotd/pkcsslotd.h
@@ -42,11 +42,7 @@
#endif /* DEV */
-#define HASH_SHA1 1
-#define HASH_MD5 2
-#define compute_md5(a,b,c) compute_hash(HASH_MD5,b,a,c)
-
-int compute_hash(int hash_type, int buf_size, char *buf, char *digest);
+int compute_sha256(char *buf, int buf_size, char *digest);
/********************
* Global Variables *
diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c
index 0c1a5586..d0d85a85 100644
--- a/usr/sbin/pkcsslotd/slotmgr.c
+++ b/usr/sbin/pkcsslotd/slotmgr.c
@@ -27,7 +27,7 @@
#include "configuration.h"
#define OBJ_DIR "TOK_OBJ"
-#define MD5_HASH_SIZE 16
+#define SHA256_HASH_SIZE 32
#define DEF_MANUFID "IBM"
@@ -44,8 +44,8 @@
#define DEF_SLOTDESC "Linux"
#endif
-typedef char md5_hash_entry[MD5_HASH_SIZE];
-md5_hash_entry tokname_hash_table[NUMBER_SLOTS_MANAGED];
+typedef char sha256_hash_entry[SHA256_HASH_SIZE];
+sha256_hash_entry tokname_hash_table[NUMBER_SLOTS_MANAGED];
Slot_Mgr_Shr_t *shmp; // pointer to the shared memory region.
int shmid;
@@ -86,27 +86,19 @@ void DumpSharedMemory(void)
}
}
-int compute_hash(int hash_type, int buf_size, char *buf, char *digest)
+int compute_sha256(char *buf, int buf_size, char *digest)
{
EVP_MD_CTX *md_ctx = NULL;
unsigned int result_size;
int rc;
md_ctx = EVP_MD_CTX_create();
-
- switch (hash_type) {
- case HASH_SHA1:
- rc = EVP_DigestInit(md_ctx, EVP_sha1());
- break;
- case HASH_MD5:
- rc = EVP_DigestInit(md_ctx, EVP_md5());
- break;
- default:
- EVP_MD_CTX_destroy(md_ctx);
+ if (md_ctx == NULL) {
+ fprintf(stderr, "EVP_MD_CTX_create() failed\n");
return -1;
- break;
}
+ rc = EVP_DigestInit(md_ctx, EVP_sha256());
if (rc != 1) {
fprintf(stderr, "EVP_DigestInit() failed: rc = %d\n", rc);
return -1;
@@ -374,12 +366,12 @@ void run_sanity_checks(void)
}
}
-int is_duplicate(md5_hash_entry hash, md5_hash_entry *hash_table)
+int is_duplicate(sha256_hash_entry hash, sha256_hash_entry *hash_table)
{
int i;
for (i = 0; i < NUMBER_SLOTS_MANAGED; i++) {
- if (memcmp(hash_table[i], hash, sizeof(md5_hash_entry)) == 0)
+ if (memcmp(hash_table[i], hash, sizeof(sha256_hash_entry)) == 0)
return 1;
}
@@ -483,7 +475,7 @@ int chk_create_tokdir(Slot_Info_t_64 *psinfo)
mode_t proc_umask;
char *tokdir = psinfo->tokname;
char *tokgroup = psinfo->usergroup;
- char token_md5_hash[MD5_HASH_SIZE];
+ char token_sha256_hash[SHA256_HASH_SIZE];
if (psinfo->present == FALSE)
return 0;
@@ -517,26 +509,26 @@ int chk_create_tokdir(Slot_Info_t_64 *psinfo)
*/
if (!tokdir || strlen(tokdir) == 0) {
/*
- * Build the md5 hash from the dll name prefixed with 'dll:' to
+ * Build the SHA256 hash from the dll name prefixed with 'dll:' to
* check for duplicate tokens with no 'tokname'.
*/
snprintf(tokendir, sizeof(tokendir), "dll:%s", psinfo->dll_location);
- rc = compute_md5(tokendir, strlen(tokendir), token_md5_hash);
+ rc = compute_sha256(tokendir, strlen(tokendir), token_sha256_hash);
if (rc) {
- fprintf(stderr, "Error calculating MD5 of token name!\n");
+ fprintf(stderr, "Error calculating SHA256 of token name!\n");
return -1;
}
/* check for duplicate token names */
- if (is_duplicate(token_md5_hash, tokname_hash_table)) {
+ if (is_duplicate(token_sha256_hash, tokname_hash_table)) {
fprintf(stderr, "Duplicate token in slot %llu!\n",
psinfo->slot_number);
return -1;
}
/* add entry into hash table */
- memcpy(tokname_hash_table[psinfo->slot_number], token_md5_hash,
- MD5_HASH_SIZE);
+ memcpy(tokname_hash_table[psinfo->slot_number], token_sha256_hash,
+ SHA256_HASH_SIZE);
return 0;
}
@@ -549,21 +541,21 @@ int chk_create_tokdir(Slot_Info_t_64 *psinfo)
return -1;
}
- /* calculate md5 hash from token name */
- rc = compute_md5(tokdir, strlen(tokdir), token_md5_hash);
+ /* calculate SHA256 hash from token name */
+ rc = compute_sha256(tokdir, strlen(tokdir), token_sha256_hash);
if (rc) {
- fprintf(stderr, "Error calculating MD5 of token name!\n");
+ fprintf(stderr, "Error calculating SHA256 of token name!\n");
return -1;
}
/* check for duplicate token names */
- if (is_duplicate(token_md5_hash, tokname_hash_table)) {
+ if (is_duplicate(token_sha256_hash, tokname_hash_table)) {
fprintf(stderr, "Duplicate token name '%s'!\n", tokdir);
return -1;
}
/* add entry into hash table */
- memcpy(tokname_hash_table[psinfo->slot_number], token_md5_hash,
- MD5_HASH_SIZE);
+ memcpy(tokname_hash_table[psinfo->slot_number], token_sha256_hash,
+ SHA256_HASH_SIZE);
/* Create token specific directory */
/* sprintf checked above */

View File

@ -1,4 +1,4 @@
commit 66e5bbdc0019fdf547409152df6b7668639f65e7
commit a1aaf9f9080202f48570d3a207d0595db159f99c
Author: Pavel Kohout <pavel@aisle.com>
Date: Tue Jan 13 00:00:00 2026 +0000
@ -35,16 +35,16 @@ Date: Tue Jan 13 00:00:00 2026 +0000
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/loadsave.c b/usr/lib/common/loadsave.c
index 3b919709..e416c2b2 100644
index 18b8aa04..f9c0cc7f 100644
--- a/usr/lib/common/loadsave.c
+++ b/usr/lib/common/loadsave.c
@@ -66,9 +66,17 @@ static FILE *open_token_object_path(char *buf, size_t buflen,
STDLL_TokData_t *tokdata, char *path,
char *mode)
@@ -68,9 +68,17 @@ static FILE *open_token_object_path(char *buf, size_t buflen,
STDLL_TokData_t *tokdata, const char *path,
const char *mode)
{
+ FILE *fp;
+
if (get_token_object_path(buf, buflen, tokdata, path) < 0)
if (get_token_object_path(buf, buflen, tokdata, path, NULL) < 0)
return NULL;
- return fopen(buf, mode);
+
@ -56,14 +56,35 @@ index 3b919709..e416c2b2 100644
+ return fp;
}
static FILE *open_token_object_path_new(char *newbuf, size_t newbuflen,
@@ -78,11 +86,19 @@ static FILE *open_token_object_path_new(char *newbuf, size_t newbuflen,
STDLL_TokData_t *tokdata,
const char *path, const char *mode)
{
+ FILE *fp;
+
if (get_token_object_path(newbuf, newbuflen, tokdata, path, ".TMP") < 0)
return NULL;
if (get_token_object_path(basebuf, basebuflen, tokdata, path, NULL) < 0)
return NULL;
- return fopen(newbuf, mode);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(newbuf, mode);
+ if (fp == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", newbuf);
+
+ return fp;
}
static int get_token_data_store_path(char *buf, size_t buflen,
@@ -85,9 +93,17 @@ static FILE *open_token_data_store_path(char *buf, size_t buflen,
STDLL_TokData_t *tokdata, char *path,
char *mode)
@@ -101,9 +117,17 @@ static FILE *open_token_data_store_path(char *buf, size_t buflen,
STDLL_TokData_t *tokdata,
const char *path, const char *mode)
{
+ FILE *fp;
+
if (get_token_data_store_path(buf, buflen, tokdata, path) < 0)
if (get_token_data_store_path(buf, buflen, tokdata, path, NULL) < 0)
return NULL;
- return fopen(buf, mode);
+
@ -75,10 +96,31 @@ index 3b919709..e416c2b2 100644
+ return fp;
}
static FILE *open_token_data_store_path_new(char *newbuf, size_t newbuflen,
@@ -111,11 +135,19 @@ static FILE *open_token_data_store_path_new(char *newbuf, size_t newbuflen,
STDLL_TokData_t *tokdata,
const char *path, const char *mode)
{
+ FILE *fp;
+
if (get_token_data_store_path(newbuf, newbuflen, tokdata, path, ".TMP") < 0)
return NULL;
if (get_token_data_store_path(basebuf, basebuflen, tokdata, path, NULL) < 0)
return NULL;
- return fopen(newbuf, mode);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(newbuf, mode);
+ if (fp == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", newbuf);
+
+ return fp;
}
static FILE *open_token_object_index(char *buf, size_t buflen,
@@ -99,11 +115,19 @@ static FILE *open_token_object_index(char *buf, size_t buflen,
@@ -127,17 +159,27 @@ static FILE *open_token_object_index(char *buf, size_t buflen,
static FILE *open_token_nvdat(char *buf, size_t buflen,
STDLL_TokData_t *tokdata, char *mode)
STDLL_TokData_t *tokdata, const char *mode)
{
+ FILE *fp;
+
@ -96,8 +138,31 @@ index 3b919709..e416c2b2 100644
+ return fp;
}
char *get_pk_dir(STDLL_TokData_t *tokdata, char *fname, size_t len)
@@ -223,9 +247,12 @@ CK_RV save_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
static FILE *open_token_nvdat_new(char *newbuf, size_t newbuflen,
char *basebuf, size_t basebuflen,
STDLL_TokData_t *tokdata, const char *mode)
{
+ FILE *fp;
+
if (ock_snprintf(newbuf, newbuflen, "%s/" PK_LITE_NV ".TMP",
tokdata->data_store)) {
TRACE_ERROR("NVDAT.TOK file name buffer overflow\n");
@@ -148,7 +190,13 @@ static FILE *open_token_nvdat_new(char *newbuf, size_t newbuflen,
TRACE_ERROR("NVDAT.TOK file name buffer overflow\n");
return NULL;
}
- return fopen(newbuf, mode);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(newbuf, mode);
+ if (fp == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", newbuf);
+
+ return fp;
}
static CK_RV close_token_file_new(FILE * fp, CK_RV rc,
@@ -289,9 +337,12 @@ CK_RV save_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
// we didn't find it...either the index file doesn't exist or this
// is a new object...
//
@ -112,22 +177,7 @@ index 3b919709..e416c2b2 100644
return CKR_FUNCTION_FAILED;
}
@@ -286,8 +313,12 @@ CK_RV delete_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
fclose(fp1);
fclose(fp2);
- fp2 = fopen(objidx, "w");
- fp1 = fopen(idxtmp, "r");
+ fp2 = fopen_nofollow(objidx, "w");
+ if (fp1 == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", objidx);
+ fp1 = fopen_nofollow(idxtmp, "r");
+ if (fp2 == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", idxtmp);
if (!fp1 || !fp2) {
if (fp1)
fclose(fp1);
@@ -616,11 +647,14 @@ CK_RV load_token_data_old(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
@@ -663,11 +714,14 @@ CK_RV load_token_data_old(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
if (errno == ENOENT) {
init_token_data(tokdata, slot_id);
@ -144,52 +194,7 @@ index 3b919709..e416c2b2 100644
rc = CKR_FUNCTION_FAILED;
goto out_unlock;
}
@@ -824,9 +858,12 @@ static CK_RV save_private_token_object_old(STDLL_TokData_t *tokdata, OBJECT *obj
rc = CKR_FUNCTION_FAILED;
goto error;
}
- fp = fopen(fname, "w");
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto error;
}
@@ -1590,9 +1627,12 @@ CK_RV reload_token_object_old(STDLL_TokData_t *tokdata, OBJECT *obj)
rc = CKR_FUNCTION_FAILED;
goto done;
}
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto done;
}
@@ -1681,9 +1721,12 @@ CK_RV save_public_token_object_old(STDLL_TokData_t *tokdata, OBJECT * obj)
rc = CKR_FUNCTION_FAILED;
goto error;
}
- fp = fopen(fname, "w");
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto error;
}
@@ -2303,11 +2346,14 @@ CK_RV load_token_data(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
@@ -2345,11 +2399,14 @@ CK_RV load_token_data(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
if (errno == ENOENT) {
init_token_data(tokdata, slot_id);
@ -206,75 +211,6 @@ index 3b919709..e416c2b2 100644
rc = CKR_FUNCTION_FAILED;
goto out_unlock;
}
@@ -2481,7 +2527,7 @@ CK_RV save_private_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
goto done;
}
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (fp == NULL) {
/* create new token object */
new = 1;
@@ -2579,9 +2625,12 @@ do_work:
if (rc != CKR_OK)
goto done;
- fp = fopen(fname, "w");
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto done;
}
@@ -2778,9 +2827,12 @@ CK_RV reload_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
strncat(fname, (char *) obj->name, 8);
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto done;
}
@@ -2893,9 +2945,12 @@ CK_RV save_public_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
strncat(fname, (char *) obj->name, 8);
- fp = fopen(fname, "w");
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto done;
}
@@ -2956,9 +3011,12 @@ CK_RV load_public_token_objects(STDLL_TokData_t *tokdata)
sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
strcat(fname, tmp);
- fp2 = fopen(fname, "r");
- if (!fp2)
+ fp2 = fopen_nofollow(fname, "r");
+ if (!fp2) {
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
continue;
+ }
if (fread(header, PUB_HEADER_LEN, 1, fp2) != 1) {
fclose(fp2);
diff --git a/usr/lib/common/platform.h b/usr/lib/common/platform.h
index 799821b5..51cc1c73 100644
--- a/usr/lib/common/platform.h
@ -380,7 +316,7 @@ index 799821b5..51cc1c73 100644
+
+#endif /* PLATFORM_H */
diff --git a/usr/lib/hsm_mk_change/hsm_mk_change.c b/usr/lib/hsm_mk_change/hsm_mk_change.c
index 161ed880..492bbd83 100644
index f40dfb43..8c66546f 100644
--- a/usr/lib/hsm_mk_change/hsm_mk_change.c
+++ b/usr/lib/hsm_mk_change/hsm_mk_change.c
@@ -623,9 +623,13 @@ static FILE* hsm_mk_change_op_open(const char *id, CK_SLOT_ID slot_id,

View File

@ -0,0 +1,36 @@
commit 3a13de065de2e64a53eb6fe14e285318002bd505
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed Apr 15 08:50:05 2026 +0200
EP11: Fix syslog message printing about different CPs
Syslog message "Adapter xx.yyyy has different control points than adapter
xx.yyyy, using minimum." is erroneously issued even if the control points
are the same.
The control points of subsequent APQNs are compared against a modified
control point bit string, where the unknown CPS have already been turned
ON. Comparing this with the queried control point bit string will always
show differences, even if the used/known control points are the same.
Fix this by remembering the original, unmodified control point bit string
instead of the modified one, and compare the control point bit strings of
subsequent APQNs with that.
Fixes: 97248f73495695436f11fafd74c2ec41a5a6f796
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index facf6f58..f48946e1 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -17900,7 +17900,7 @@ static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
data->combined_cp[CP_BYTE_NO(i)] &=
(cp[CP_BYTE_NO(i)] | ~CP_BIT_MASK(i));
}
- memcpy(data->first_cp, data->combined_cp, sizeof(data->first_cp));
+ memcpy(data->first_cp, cp, sizeof(data->first_cp));
data->max_cp_index = max_cp_index;
data->first = 0;
} else {

View File

@ -1,48 +0,0 @@
commit 8209874fc0ea78079aa21c386df0f385ee0e5dca
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed Jul 9 09:09:32 2025 +0200
COMMON: Fix detection of EC curve not supported by OpenSSL
OpenSSL 3.5 recently changed the behavior in regards of error reporting
with EVP_PKEY_keygen(). When the EC curve is not supported it used to
return error EC_R_INVALID_CURVE as top most entry in the error stack.
Since commit https://github.com/openssl/openssl/commit/72351b0d18078170af270418b2d5e9fc579cb1af
this is no longer the case, instead a generic EVP_R_PROVIDER_KEYMGMT_FAILURE
error is now the top most entry, and EC_R_INVALID_CURVE is the second one.
Make the detection independent of the error reporting and check for the
curve already in curve_nid_from_params().
Closes: https://github.com/opencryptoki/opencryptoki/issues/877
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/mech_openssl.c b/usr/lib/common/mech_openssl.c
index f29b4946..e1bb6b83 100644
--- a/usr/lib/common/mech_openssl.c
+++ b/usr/lib/common/mech_openssl.c
@@ -1854,6 +1854,7 @@ static int curve_nid_from_params(const CK_BYTE *params, CK_ULONG params_len)
{
const unsigned char *oid;
ASN1_OBJECT *obj = NULL;
+ EC_GROUP *grp;
int nid;
oid = params;
@@ -1866,6 +1867,14 @@ static int curve_nid_from_params(const CK_BYTE *params, CK_ULONG params_len)
nid = OBJ_obj2nid(obj);
ASN1_OBJECT_free(obj);
+ grp = EC_GROUP_new_by_curve_name(nid);
+ if (grp == NULL) {
+ TRACE_ERROR("curve not supported by OpenSSL.\n");
+ return NID_undef;
+ }
+
+ EC_GROUP_free(grp);
+
return nid;
}

View File

@ -0,0 +1,110 @@
commit 54e1a3e9c5474a3563b48c99527f9d6966ea4746
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Thu Jan 8 10:48:29 2026 +0100
COMMON: Fix CKM_ECDH_AES_KEY_WRAP buffer size calculation with compressed keys
When a C_WrapKey with CKM_ECDH_AES_KEY_WRAP is performed, and the EC public
key used with it uses a compressed EC point, then the size of the wrapped
key material is calculated wrongly. This may lead to an out-of-bounds write
when the caller provides a buffer of that calculated size.
The temporary EC key generated internally by this mechanism is always
uses an uncompressed EC point, but the buffer size is erroneously calculated
using the EC point of the supplied EC public key. Thus, in case a compressed
EC point is supplied, the buffer size calculation results in a too short
buffer.
Fix this by calculating the buffer size using the EC point of the internally
generated EC key, because this is what is later on written to the buffer.
Fixes: 785d7577e1477d12fbe235554e7e7b24f2de34b7
Reported-by: Pavel Kohout of Aisle Research, www.aisle.com
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/mech_ec.c b/usr/lib/common/mech_ec.c
index 2399c1cf..ce031ec0 100644
--- a/usr/lib/common/mech_ec.c
+++ b/usr/lib/common/mech_ec.c
@@ -1758,6 +1758,31 @@ CK_RV ecdh_aes_key_wrap(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
+ /* Get the (raw) size of the generated EC point */
+ rc = object_mgr_find_in_map1(tokdata, ec_publ_key_handle,
+ &pub_key_obj, READ_LOCK);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to acquire key from EC public key handle.\n");
+ if (rc == CKR_OBJECT_HANDLE_INVALID)
+ rc = CKR_KEY_HANDLE_INVALID;
+ goto done;
+ }
+
+ rc = template_attribute_get_non_empty(pub_key_obj->template, CKA_EC_POINT,
+ &ec_point);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("Failed to get CKA_EC_POINT.\n");
+ goto done;
+ }
+
+ rc = ber_decode_OCTET_STRING((CK_BYTE *)ec_point->pValue,
+ &pub_ec_point, &pub_ec_point_len, &field_len);
+ if (rc != CKR_OK || field_len != ec_point->ulValueLen) {
+ rc = CKR_FUNCTION_FAILED;
+ TRACE_DEVEL("Failed to decode CKA_EC_POINT.\n");
+ goto done;
+ }
+
/* Perform ECDH to derive a shared AES key */
ecdh_params.kdf = params->kdf;
ecdh_params.pSharedData = params->pSharedData;
@@ -1813,7 +1838,7 @@ CK_RV ecdh_aes_key_wrap(STDLL_TokData_t *tokdata, SESSION *sess,
}
/* Calculate the final length of the wrapped key data */
- total_len = ecdh_params.ulPublicDataLen + wrapped_key_len;
+ total_len = pub_ec_point_len + wrapped_key_len;
if (length_only) {
*out_data_len = total_len;
@@ -1831,31 +1856,6 @@ CK_RV ecdh_aes_key_wrap(STDLL_TokData_t *tokdata, SESSION *sess,
* Copy the (raw) EC point of the public transport EC key as first part of
* the wrapped key data.
*/
- rc = object_mgr_find_in_map1(tokdata, ec_publ_key_handle,
- &pub_key_obj, READ_LOCK);
- if (rc != CKR_OK) {
- TRACE_ERROR("Failed to acquire key from EC public key handle.\n");
- if (rc == CKR_OBJECT_HANDLE_INVALID)
- return CKR_KEY_HANDLE_INVALID;
- else
- return rc;
- }
-
- rc = template_attribute_get_non_empty(pub_key_obj->template, CKA_EC_POINT,
- &ec_point);
- if (rc != CKR_OK) {
- TRACE_DEVEL("Failed to get CKA_EC_POINT.\n");
- goto done;
- }
-
- rc = ber_decode_OCTET_STRING((CK_BYTE *)ec_point->pValue,
- &pub_ec_point, &pub_ec_point_len, &field_len);
- if (rc != CKR_OK || field_len != ec_point->ulValueLen) {
- rc = CKR_FUNCTION_FAILED;
- TRACE_DEVEL("Failed to decode CKA_EC_POINT.\n");
- goto done;
- }
-
memcpy(out_data, pub_ec_point, pub_ec_point_len);
/*
@@ -1864,7 +1864,7 @@ CK_RV ecdh_aes_key_wrap(STDLL_TokData_t *tokdata, SESSION *sess,
*/
rc = encr_mgr_encrypt(tokdata, sess, FALSE, &aeskw_ctx,
in_data, in_data_len,
- out_data + ecdh_params.ulPublicDataLen,
+ out_data + pub_ec_point_len,
&wrapped_key_len);
if (rc != CKR_OK) {
TRACE_ERROR("Failed to encrypt the to-be-wrapped key: %s (0x%lx)\n",

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
Name: opencryptoki
Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0 and partially v3.1
Version: 3.25.0
Release: 4%{?dist}.2
Version: 3.26.0
Release: 2%{?dist}.2
License: CPL-1.0
URL: https://github.com/opencryptoki/opencryptoki
Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
@ -19,25 +19,12 @@ Patch2: opencryptoki-3.24.0-tmpfiles-image-mode.patch
Patch3: opencryptoki-lockdir-image-mode.patch
# upstream patches
# Fix detection of EC curve not supported by OpenSSL-3.5.x
Patch10: opencryptoki-openssl-3.5.x.patch
# Fix covscan findings, https://github.com/opencryptoki/opencryptoki/pull/880
Patch11: opencryptoki-3.25.0-covscan-findings.patch
# Remove the use of MD5, pkcsslotd crashes in FIPS mode
Patch12: opencryptoki-3.25.0-reject-using-md5-in-fips-mode.patch
# EP11: Fix unwrapping of attribute bound EC keys
# https://github.com/ifranzki/opencryptoki/commit/d3dc88c
Patch13: opencryptoki-3.25.0-fix-unwrapping-attribute-bound-EC-keys.patch
# EP11: Fix private secure key blob import
# https://github.com/ifranzki/opencryptoki/commit/ab740fd
Patch14: opencryptoki-3.25.0-fix-private-secure-key-blob-import.patch
# CVE-2026-23893, symlink-following vulnerabilities
Patch15: opencryptoki-3.25.0-CVE-2026-23893.patch
# CVE-3-2026-23893
Patch100: opencryptoki-3.26.0-CVE-3-2026-23893.patch
Patch101: opencryptoki-3.26.0-Fix-syslog-message-printing-about-different-CPs.patch
# Fix CVE-2026-40253
Patch102: opencryptoki-v3.26.0-CVE-2026-40253-part1.patch
Patch103: opencryptoki-v3.26.0-CVE-2026-40253-part2.patch
Requires(pre): coreutils
Requires: (selinux-policy >= 38.1.14-1 if selinux-policy-targeted)
@ -424,13 +411,20 @@ fi
%changelog
* Tue Mar 03 2026 Than Ngo <than@redhat.com> - 3.25.0-4.2
- Resolves: RHEL-144820, Privilege Escalation or Data Exposure via Symlink Following
* Tue May 26 2026 Than Ngo <than@redhat.com> - 3.26.0-2.2
- Resolves: RHEL-171562, Fix CVE-2026-40253, possible out-of-bounds access in BER decode functions
* Tue Feb 03 2026 Than Ngo <than@redhat.com> - 3.25.0-4.1
- Fix unwrapping of attribute bound EC keys
- Fix private secure key blob import
Resolves: RHEL-131644
* Tue Apr 28 2026 Than Ngo <than@redhat.com> - 3.26.0-2.1
- Resolves: RHEL-169586, Fix syslog message printing about different CPs
* Fri Feb 13 2026 Than Ngo <than@redhat.com> - 3.26.0-2
- Resolves: RHEL-144821, CVE-2026-23893
* Wed Dec 17 2025 Than Ngo <than@redhat.com> - 3.26.0-1
- Resolves: RHEL-75139, ep11 token BLS support
- Resolves: RHEL-85381, ep11 token: ML-KEM and ML-DSA support
- Resolves: RHEL-85384. cca token: ML-KEM and ML-DSA support
- Resolves: RHEL-100059, openCryptoki 3.26.0
* Wed Aug 13 2025 Than Ngo <than@redhat.com> - 3.25.0-4
- Fix pkcsslotd fails to start in FIPS