Check that an encrypt or decrypt call with a too small buffer correctly
returns CKR_BUFFER_TOO_SMALL, update the output buffer length to the
required size, and does not write to the output buffer beyond the
provided output buffer length. Furthermore, the operation must stay
active and a retry must be possible.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Test the PKCS#7 padding and unpadding functions to behave correctly
on various valid and invalid inputs.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
When the caller provides a too short output buffer, send back RSN_TOO_SHORT
to correctly indicate this situation.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
For CBC-PAD the output buffer size sent to ICSF was inflated to at least
cipher_text_len so the server does not send back RSN_TOO_SHORT for the
padded-then-unpadded output. Validate length against the inflated clear_len
(what we told the server) and bv_clear_data.bv_len against the caller's
real buffer. When the real buffer is too small for the unpadded result,
propagate CKR_BUFFER_TOO_SMALL so the caller can retry.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
The EP11 host library does not necessarily report the required output length
when an encrypt or decrypt update call fails with CKR_BUFFER_TOO_SMALL.
In this case, report an upper bound of the output length of the update
operation: Less than one block of data can be buffered by a previous update,
thus the output is at most the input length rounded up to a multiple of the
block size. A length already reported by the EP11 library (larger than the
passed one) is kept.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
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>
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>
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>
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>
Produce a PKCS#8 and SPKI encoding using OpenSSL and test if the ASN.1 routines
can decode that key and also if the round trip produces the exact same encoded data.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Correct the BER encoded data used for Edwards and Montgomery keys and add
tests for testing the legacy format still being accepted.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
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>
Run check_unwrap_sensitive_extractable() after the private key unwrap in
the ML-DSA and ML-KEM key transfer tests, for every test vector, and add
do_WrapUnwrapDHKey(), which wraps a generated DH private key under an AES
key with CKM_AES_CBC_PAD and runs the same check.
DSA is not covered: the soft token is built with -DNODSA, so no DSA test
runs there.
Signed-off-by: Alexandre Laroche <larochealexandre@hotmail.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Add check_unwrap_sensitive_extractable() to the common test code. It
unwraps the same data with each combination of CKA_SENSITIVE and
CKA_EXTRACTABLE, and with neither, and checks every new key: the
attributes match the template (any value is accepted when the template
does not set them, since the defaults are token specific);
CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE are FALSE; and the key
value cannot be read from a sensitive key. When the unwrapping key's
CKA_UNWRAP_TEMPLATE sets one of the attributes, a key unwrapped without
it gets that value, and a template asking for the other value must fail
with CKR_TEMPLATE_INCONSISTENT.
CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE are not checked on the
ICSF token, which unwraps on the ICSF server and takes these attributes
from it.
Run it from do_WrapUnwrapAES() for secret keys, from do_WrapUnwrapRSA()
for RSA private keys, and from both EC key transfer tests for EC private
keys, whose transport key's CKA_UNWRAP_TEMPLATE sets CKA_EXTRACTABLE =
FALSE. Add do_UnwrapTemplateAES(), which unwraps under a wrapping key
whose CKA_UNWRAP_TEMPLATE sets CKA_SENSITIVE = TRUE and CKA_EXTRACTABLE =
FALSE, for every AES wrap mechanism.
Signed-off-by: Alexandre Laroche <larochealexandre@hotmail.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
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>
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>
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>
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>
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>
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>
Trying to start the ICS mock server when another instance is already running
leads to 'Address already in use'. Stop an already running ICSF mock server
before starting it again.
Also remove the token directory of a previous ICSF token before creating a
new one at the same location. THis is the same as addslot() does for the
other tokens.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Add tests that checks if wrong AlgorithmIdentifier are detected, i.e.
cases where the OID is too short or too long, or invalid by other means.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
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>
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>
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>
Running 'make ci-installcheck' (or 'make installcheck') produces several
log files that contain the detail testcase output. Let 'make ci-cleanup'
also remove these log files.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Running 'make ci-installcheck' (or also just 'make installcheck') runs
many tests, but does not set the exit code in case a test fails. This is
because the make target should continue to run further tests, even if one
fails. Setting the exit code on a single failure would stop the make target.
In the CI a post processor script scans the log files to determine if any
tests failed. The ci-check-results make target performs the same kind of
check. It can be used right after 'make ci-installcheck' or 'make
installcheck'.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
The min and max key sizes for DES, DES3 and HMAC mechanisms were zero.
Update this to the correct key sizes.
Some mechanism do not have the CKF_HW flag set where it should be set,
or vice versa. Fix that.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Incorporate the latest changes for the ICSF token and the pkcsicsf tool
into the README.icsf_stdll.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Update ICSF mock server to behave like the real ICSF and generate as well
as require DH keys that are complaint per NIST SP 800-56A R3 5.6.2.1.2.
Fail the key derivation with 8 / 2116 if the used private key is not
compliant, just like ICSF is doing.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
ICSF enforces NIST SP 800-56A compliance for private key validation during
key agreement. The key DH_PRIVATE_B does not pass this validation.
Update the testcase to use a valid private DH key that is complaint per
NIST SP 800-56A R3 5.6.2.1.2.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
When producing the hex representation of values >= 2^52 make sure that
the value is in big endian format, so that the hex representation is
correct.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Add a check to ensure that structures are a multiple of the TTLV block
length. If thats not the case return an error early, and do not only
rely on parsing the structure elements to fail.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
if field 'tls_ca' is NULL in the connection config structure, the system's
default CA certificates are supposed to be loaded and used. This is
currently not done, leaving it with an empty certificate store and
any peer or hostname verification will fail.
Call SSL_CTX_set_default_verify_paths() to load the system's default CA
certificates.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Just resetting the OpenSSL BIO via BIO_reset() leaves the BIO in a state
where the next attempt to use it will reconnect to the server and perform
a TLS handshake freshly. However, this reconnect omits the checks done
by kmip_connection_tls_verify_server().
In case of any I/O failure tear down the connection completely to
avoid any reconnects.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
When a corrupted KMIP response contains KMIP nodes that are expected to
be of type TEXT-STRING, but they are of a different type, then function
kmip_node_get_text_string() returns NULL. Fix all callers to check
for such NULL returns and return -EBADMSG if so.
Not checking for NULL might cause NULL pointer dereferences in the
callers, or the callers further down the stack.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
With the change of the previous commit, we must not set the
CKF_INTERFACE_FORK_SAFE flag when retrieving interfaces.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
PKCS#11 states for flag CKF_INTERFACE_FORK_SAFE:
"The returned interface will have fork tolerant semantics. When the
application forks, each process will get its own copy of all session
objects, session states, login states, and encryption states. Each
process will also maintain access to token objects with their previously
supplied handles."
This is not how Opencryptoki behaves. The forked child starts as if
cryptoki has never been initialized, it needs to initialize the cryptoki
library freshly with C_Initialize if needed.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Although the fiends in 'sinfo[slot_no]' in question are usually NUL-terminated
(do_str() pads the string with NUL values), there is one case where it is not
NUL-terminated: when the string length matches the target field length.
Use the 'str' variable, which is always NUL-terminated for the checks.
Variable 'str' and the struct field are identical in value, using 'str'
is semantically equivalent, but eliminates the unterminated string usage.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
When writing the initial NVTOK.dat file fails before the file name is
set, the attempt to unlink the file uses an uninitialized variable name.
Initialize fname with zeros, and attempt the unlink only if the file name
was set before.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
When the login mechanism is not ICSF_CFG_MECH_SIMPLE, then there is no
wrap key, and thus variable 'new_wrap_key' is never set, but is later
on copied to 'user_wrap_key' in 'tokdata' (which also is never used).
Initialize the variable with zeros to silence the warning.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>