1
0
mirror of https://github.com/opencryptoki/opencryptoki.git synced 2026-10-24 05:39:17 +03:00

612 Commits

Author SHA1 Message Date
Ingo Franzki
5dcf5ef3d2 COMMON: Return required output size on CKR_BUFFER_TOO_SMALL
ECB, XTS encrypt and decrypt as well as CBC decrypt check that the buffer
is at least as large as the input and return CKR_BUFFER_TOO_SMALL if not,
but they do not update *out_data_len with the required buffer size.
This applies in the same way to to AES, DES, and DES3.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-22 12:53:13 +02:00
Ingo Franzki
6887ee91a4 COMMON: Cleanse output buffer in case of unpadding errors
In aes_key_wrap_decrypt() when the PKCS#7 unpadding fails, cleanse the
output buffer to not leak decrypted data in case of a failure.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-22 12:53:13 +02:00
Ingo Franzki
d5beecc9ca COMMON: Fix AES/DES/DES3-CBC-PAD PKCS#7 unpadding
As per PKCS#7, the pad bytes must all equal the padding value, i.e. the number
of bytes to pad. Every byte that could be padding is examined, so the time
taken does not depend on the padding. Also make sure that the padding
value is not larger than the block size.

Suggested-by: Alexandre Laroche <larochealexandre@hotmail.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-22 12:53:13 +02:00
Ingo Franzki
f14f7a916f COMMON: Fix out-of-bounds access with AES/DES/DES3-CBC-PAD decryption
Fix the AES/DES/DES3-CBC-PAD decryption handling to not produce more output
than allowed as per output buffer length.

Also check for errors during strip_pkcs_padding() to detect padding errors
and fail the operation.

With the buffer size checking, the IV must be saved before the actual
operations and must be restored in case of a CKR_BUFFER_TOO_SMALL error.
The operation might update the running IV in the context. However, the
caller must be able to retry with the original IV intact using a large
enough output buffer.

Suggested-by: Alexandre Laroche <larochealexandre@hotmail.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-22 12:53:13 +02:00
Ingo Franzki
595ca62ada COMMON: Fix BER encoding and decoding of Edwards and Montgomery private keys
For Edwards and Montgomery private keys RFC 8410 defines that the private
key is an OCTET-STRING, and not a SEQUENCE as for EC keys (RFC 5915).

Fix this by encoding and decoding the correct PKCS#8 format. For decoding,
Edwards and Montgomery private keys encoded using the wrong EC-key style are
still accepted for backward compatibility.

Fixes: 3fd5120a41

Reported-by: Alexandre Laroche <larochealexandre@hotmail.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-20 14:31:37 +02:00
Alexandre Laroche
2345b3c7e9 COMMON: Honour CKA_SENSITIVE and CKA_EXTRACTABLE from the unwrap template
secret_key_unwrap() and priv_key_unwrap() set CKA_SENSITIVE to FALSE and
CKA_EXTRACTABLE to TRUE on every unwrapped key, after the caller's
template, and the unwrapping key's CKA_UNWRAP_TEMPLATE, had already been
validated and merged into the new object. Both were silently overwritten:

 - a template asking for CKA_SENSITIVE = TRUE and CKA_EXTRACTABLE = FALSE
   gave a key whose value could be read in clear with
   C_GetAttributeValue(CKA_VALUE) and wrapped out again;
 - an unwrapping key whose CKA_UNWRAP_TEMPLATE requires CKA_SENSITIVE =
   TRUE or CKA_EXTRACTABLE = FALSE did not get that policy applied to the
   keys unwrapped with it.

C_UnwrapKey returned CKR_OK in both cases.

Stop overwriting these two attributes. object_create_skel() already
starts the object from the class defaults (CKA_SENSITIVE = FALSE,
CKA_EXTRACTABLE = TRUE), lets the token's t_set_attrs_for_new_object()
supply its own defaults, and merges the template over them. CKA_LOCAL,
CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE are still set to FALSE, as
PKCS#11 requires for an unwrapped key.

For a template that does not specify the two attributes, under an
unwrapping key without a CKA_UNWRAP_TEMPLATE, tokens that keep the class
defaults give the same key as before. Tokens that default CKA_SENSITIVE
to TRUE (EP11 and CCA for private keys, and for secret keys when
FORCE_SENSITIVE is enabled) now apply that default to unwrapped keys
too, as they already do for generated and derived keys; until now the
unwrap path overwrote it with FALSE.

Signed-off-by: Alexandre Laroche <larochealexandre@hotmail.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-19 13:52:53 +02:00
Ingo Franzki
0d2e914258 COMMON: NULLify pContext and ulContextLen in ML-DSA mechanism parameter copy
If the source has an empty context, then also set the context to empty on the
target before returning early. Any left over context pointers in the target
might otherwise be freed later when the copy is freed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-14 16:56:25 +02:00
Ingo Franzki
ebab4b48e0 COMMON: Cleanup operation in init failure
In case *_mgr_init() fails, call *_mgr_cleanup() to free all already allocated
context buffers.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-14 16:56:25 +02:00
Ingo Franzki
2acb7a25bf EP11: Fix cleanup in case EC-AGGREGATE mechanism parameter deep-copy fails
When the deep-copy if the EC-AGGREGATE mechanism parameter fails, cleanup
the operation before returning.

The EC-AGGREGATE deep-copy function must NULLify the pAggrElements field
before attempting to copy. The destination starts as a shallow memcpy of
the source, so it held the caller's pointers. If a malloc failed partway
through, it would have freed those caller-owned buffers.

While at it, move the deep-copy case into the already existing switch
above inside the mechanism parameter guard. Also check the size of the
mechanism parameter to be the expected length before deep-copying it.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-14 16:56:25 +02:00
Ingo Franzki
350f61c775 COMMON: Fix error handling when deep-copy a mechanism parameter fails
In case deep-copying the ML-DSA mechanism parameter fails, don't continue,
but go to the done label.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-14 16:56:25 +02:00
Ingo Franzki
f9e05e3742 COMMON/EP11: Reject saving the state for mechanisms with deep-copied parameters
Saving the operation state via C_SetOperationState() only works for
mechanisms with mechanism parameters that can be serialized. Thus, mechanisms
that use a mechanism parameter that gets deep-copied into the context can
not be saved. Set the state_unsaveable flag for those mechanisms. This
will cause C_SetOperationState() to fail with with CKR_STATE_UNSAVEABLE.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-14 16:56:25 +02:00
Ingo Franzki
b663eaa8f3 COMMON: Fix memory leak of deep-copied mechanism parameters on session close
Some mechanisms keep a deep copy of its mechanism parameter in the operation
context. Normal operation cleanup deep-frees them properly, but session_free()
and session_mgr_close_session() do not deep-free them, but just free the outer
structure, leaking any inner allocations. This happens when a session is
closed that has a still active operation with such a mechanism.

Fix this by directing the cleanup to the regular operation cleanup helpers
that already do it right.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-14 16:56:25 +02:00
Ingo Franzki
137c741923 COMMON: Decoding EC public and private keys must check the OID
Functions der_decode_ECPrivateKey() and der_decode_ECPublicKey() can be called
to decode a EC, Edwards, or Montgomery key. For EC, the OID of the curve is
the param in the AlgorithmIdentifier, and for Edwards and Montgomery the OID
in the AlgorithmIdentifier specifies the curve OID directly. Check that the
OID is one of the known curves for EC, and one of the expected Edwards or
Montgomery OIDs for Edwards and Montgomery respectively.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-13 11:56:12 +02:00
Ingo Franzki
bab7e26028 COMMON: Fix ber_decode_SPKI to not assume a single byte OID length
Function ber_decode_SPKI() extracts the OID and the parameters from the
AlgorithmIdentifier. It assumes that the BER encoded OID has a single byte
length field. While this is the case for all used OIDs, an malformed
SPKI could have an AlgorithmIdentifier that has a multi-byte length
OID. Decode the field length and do not assume a single byte length.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-13 11:56:12 +02:00
Ingo Franzki
849d1363ac COMMON: Fix out-of-bounds read when decoding public or private keys
The decoding functions for public and private keys compare the decoded
AlgorithmIdentifier from the key material with constants to check for valid
key types. This check does not check the length of the decoded
AlgorithmIdentifier and thus might overrun the buffer producing an
out-of-bounds read for too short AlgorithmIdentifiers.

Reported-by: Stuart Thomas <stuart.thomas@triageforge.co.uk>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-10-13 11:56:12 +02:00
Ingo Franzki
e7fc2734e9 ICSF: Convert compressed or raw EC points to uncompressed
ICSF only accepts uncompressed EC Points when creating an EC public key
object, as well as for ECDH derive as public data.

Convert compressed or raw EC points to the uncompressed form before passing
it to ICSF.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-09-23 13:25:13 +02:00
Ingo Franzki
ca7f1645a4 COMMON/EP11/ICSF: Make C_Login, C_Set/InitPIN, C_InitToken fully thread save
Make sure that C_Login, C_SetPIN, C_InitPIN, C_InitToken do not read or
update any token files or any field in the token shared memory without
holding the XProcLock.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-09-23 13:25:13 +02:00
Ingo Franzki
784fcb1871 COMMON: Refactor the public key encoding functions
Use a common SPKI encoding function for all public key encoding functions,
instead of having each public key encoding function manually encode the
SPKI.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-09-07 11:11:06 +02:00
Ingo Franzki
745c8068d8 COMMON: Add overflow checks for BER encoding functions
Avoid an integer overflow when encoding keys with very large and/or multiple
components.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-09-07 11:11:06 +02:00
Ingo Franzki
8cb0e36c2a COMMON: Refactor BER primitive encoding and decoding
Refactor the code to encode and decode the BER primitives. There was lots of
duplicated code in these functions. This is now refactored out into separate
helper functions.

Also the TLV encoding and decoding in these helpers have been refactored to
use a more streamlined implementation without many similar looking if cases.

With this, encoding and decoding data with more than 3 length octets (16 MB)
is now supported.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-09-07 11:11:06 +02:00
Ingo Franzki
90df45fe70 COMMON: Remove dependency on liblber in common code
The use of liblber has been eliminated for most of the cases already.
The only leftover cases are in RSA, DSA, and DH public key encoding
functions for encoding BIT STRINGs.

Update these leftover places and use the already existing
ber_encode_BIT_STRING() function instead.

With this, '-lber' can be removed from the make files for most of
the tokens and tools. The ICSF token still requires liblber for its
LDAP communication.

Also adjust the configure script and example RPM spec accordingly.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-09-07 11:11:06 +02:00
Ingo Franzki
643a646201 COMMON: Use file descriptor operations relative to the directory
Refactor the code to use file descriptor operations relative to the directory
(e.g. openat(), unlinkat(), fstatat(), renameat()) instead of path based
operations. This is safer against TOCTOU issues and symlink-following
attacks where the files or directories are replaced after the check, but
before the path based operation on it.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:58 +02:00
Ingo Franzki
10f48c5cb0 COMMON: Allow CKA_EXTRACTABLE and CKA_SENSITIVE to be set during unwrap
As per PKCS#11, CKA_EXTRACTABLE and CKA_SENSITIVE can be set to any
value during an unwrap operation. The current code does not allow this.

Also make sure to set CKA_NEVER_EXTRACTABLE to FALSE when CKA_EXTRACTABLE
is set to TRUE. This was already fixed for private keys in commit
0462717a8d but was missed for secret keys.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:58 +02:00
Ingo Franzki
f2ca5c7394 COMMON/PKCSCCA: Check fwrite() failures when saving old token objects
Check for failures during fwrite() and handle this error situation properly.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:46 +02:00
Ingo Franzki
bf8cf2fbaa COMMON/PKCSCCA/PKCSTOK_MIGRATE: Prevent overflow when reading old token objects
Check that the decrypted data is large enough to also hold the digest.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:45 +02:00
Ingo Franzki
3b287144b2 COMMON: Restrict token name and config name to allowed characters
Restrict the token name (tokname) and config name (confname) that is
specified in opencryptoki.conf to only contain certain characters.
They must not be '.' or '..', and must not contain '/'.
If the confname specified an absolute path, no restriction is applied.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:41 +02:00
Ingo Franzki
24dbc97561 PKCSICSF/ICSF: Restrict token name to allowed characters
The ICSF token name is retrieved from LPAP, and could theoretically contain
characters like '..' or '/' that could cause the config file name to be
created outside of the config directory. The token name must not be '.' or
'..', and must not contain '/'.

Create relative names for the confname field in the config entry.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:33 +02:00
Ingo Franzki
782771bb8f COMMON: Cleanse sensitive BIGNUMs in mech_openssl.c
Allocate them using BN_secure_new() and cleans them using BN_clear_free().

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:22 +02:00
Ingo Franzki
6e4f8cebcb COMMON: Fix signed/unsigned mismatch in encode_eme_oaep()
Make ps_len an CK_ULONG, and check for overflows before doing the calculation.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:22 +02:00
Ingo Franzki
50a910dea0 COMMON: Check for overflows in BER encoding functions
Prevent integer overflows when calculating the length of a buffer to allocate.
An overflow would cause a too short buffer to be allocated causing an
out of bounds access later.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:19 +02:00
Ingo Franzki
d26e582c9c COMMON: Fix AES-CTR mechanism parameter checking
Check the range of the ulCounterBits field in the CK_AES_CTR_PARAMS
mechanism parameter structure to be 0 < ulCounterBits < 128.

Remove a bogus overflow check for ulCounterBits in the final functions.
This does not make any sense, because ulCounterBits is not modified,
and thus can not overflow, especially not when it is in range.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:18 +02:00
Ingo Franzki
f42f3665c0 COMMON: Refuse too large token objects from being written to disk
The old data format only allows to store encrypted object data up to
UINT32_MAX - 5 bytes. Refuse to save if the data is larger.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:17 +02:00
Ingo Franzki
0b3b56c65b COMMON: Use freshly decoded length in ber_encode_DSA/DHPublicKey
The pub_len is determined at the length-only first pass, but is then reused
for the second pass as well. Use the length from the freshly decoded BITSTRING
instead of reusing pub_len from above for the final ber_encode_SEQUENCE call.

It should result in the same value, but it is clearer to anywhere use the
same value.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:17 +02:00
Ingo Franzki
e2a07d6753 COMMON: Cleanse sensitive keys when no longer used in mech functions
Cleanse sensitive key material used during mechanism handling
when no longer used.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:16 +02:00
Ingo Franzki
363bc1fe30 COMMON: Cleanse protected keys on stack/heap when no longer used
Cleanse protected keys or CPACF param blocks containing protected keys
on stack when no longer used.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:15 +02:00
Ingo Franzki
6da5f48128 COMMON: Cleanse sensitive data when no longer used in loadsave.c
Cleanse sensitive data like encryption keys used for loading and saving
key objects to disk.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:15 +02:00
Ingo Franzki
a431062e86 COMMON/ICSF/TPM: Cleanse sensitive PIN related data when no longer used
Cleanse sensitive data like pin hashes and keys used for PKCS#11 USER
and SO pin handling.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:15 +02:00
Ingo Franzki
2d6ad3bf05 COMMON/PKCSTOK_ADMIN/PKCSTOK_MIGRATE: Prevent symlink-following for directories
When opening a directory for iterating over the files contained in it, use
open() with O_DIRECTORY and O_NOFOLLOW, followed by fdopendir() instead of
the plain opendir() to protect from symlink-following on the directory itself.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:14 +02:00
Ingo Franzki
5c31aea809 COMMON/PKCSSLOTD/TPM: Create lock files with O_NOFOLLOW to prevent symlink-following
Create the lock files using O_NOFOLLOW to prevent symlink-following.
Lock files are just opened but no data is written to it or read from it.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:13 +02:00
Ingo Franzki
a1ba8a5b81 COMMON: Prevent symlink-following attacks with trace files
Open the trace file with O_NOFOLLOW to prevent symlink-following attacks.
An attacker who can create a symlink at /var/log/opencryptoki/trace.<pid>
before the process opens it can redirect arbitrary writes.

However, trace is only written when it is enabled via environment variable
OPENCRYPTOKI_TRACE_LEVEL, and is disabled by default. Thus an attack is
not practically possible.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:10 +02:00
Ingo Franzki
c39c69820f COMMON: Silence erroneously pushed OpenSSL error
On some versions of OpenSSL, EVP_CIPHER_CTX_get_updated_iv() might push
an error like "000003FF8C3F3EA0:error:07800081:common libcrypto routines:
set_ptr_internal:param of incompatible type:crypto/params.c:1506:" to
the OpenSSL error stack, see https://github.com/openssl/openssl/issues/27117

This has been fixed in OpenSSL, but in case we are running with an OpenSSL
version that still has the bug, remove the error entry in case
EVP_CIPHER_CTX_get_updated_iv() returned success.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:09 +02:00
Ingo Franzki
be4ffb065d COMMON: Check EC prime len calculations
Make sure that the EC curve prime value is in range and does not cause any
overflows.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:09 +02:00
Ingo Franzki
c85de7d326 COMMON: Correct ber_encode_RSAPublicKey and avoid overflow
The public key material is a BIT STRING, so use the correct function to
determine its length. This avoids the opaque +1 to account for the
unused-bits byte that is part of a BIT STRING. Also check for overflows
when adding up the length.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:09 +02:00
Ingo Franzki
65c51ef599 COMMON: Avoid overflow in ssl3_key_and_mac_derive()
Check the user supplied ul*SizeInBits values to be within the allowed range.
This avoids overflow errors.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:08 +02:00
Ingo Franzki
b0e1751250 COMMON: Avoid overflow in ecdh_pkcs_derive()
Check the length of the to be derived key and the shared data to not
overflow when allocating a buffer.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:08 +02:00
Ingo Franzki
ab4a8945b8 COMMON: Avoid overflow in ckm_kdf_X9_63() and ckm_kdf_sp800_56c()
Check the length of the derived key and the shared data to not overflow when
building the hash context.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:08 +02:00
Ingo Franzki
68d9e8866d COMMON: Check length in ber_encode_INTEGER/BIT_STRING to avoid overflow
A very large data length in the encoding functions might cause an overflow.
Both INTEGER as well as BIT_STRING add padding as part of the encoding, so
the data length must be small enough that also the padding fits.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:08 +02:00
Ingo Franzki
fdfeb75328 COMMON: Check input length for ckm_aes_wrap_format
The calculation for the len2 might overflow, so check the input
length (len1) before the calculation to avoid such overflows.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:07 +02:00
Ingo Franzki
152c55ad37 COMMON: Avoid an overflow during length checking in rsa_format_block
Check the length using subtraction instead of addition to avoid unsigned
overflow during addition.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:07 +02:00
Ingo Franzki
7277674d9e COMMON: Check length in RSA PSS encode and verify functions
Avoid overflows by checking the length of the input message carefully
before doing calculations.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2026-08-19 08:27:07 +02:00