The lifetime of key attributes now encodes whether a key is
volatile/persistent or not AND its location.
Fix PSA code where the fact that the lifetime encodes
the key location was not taken into account properly.
Fix the impacted tests and add two non regression tests.
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
* #3742 After input of a key as SECRET in the derivation, allow the
derivation result to be used as key.
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
* #3741 Allow key agreement inside derivation with a key that's allowed
for the relevant agreement.
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
Test import and key generation, each followed by a key agreement. Only
good cases in this commit.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
... as opposed to PSA_ERROR_BAD_STATE.
The spec on psa_cipher_finish() states that PSA_ERROR_INVALID_ARGUMENT
should be returned when:
"The total input size passed to this operation is not valid for this
particular algorithm. For example, the algorithm is a based on block
cipher and requires a whole number of blocks, but the total input size
is not a multiple of the block size."
Currently, there is a distinction between encryption and decryption
on whether INVALID_ARGUMENT or BAD_STATE is returned, but this is not
a part of the spec.
This fix ensures that PSA_ERROR_INVALID_ARGUMENT is returned
consistently on invalid cipher input sizes.
Signed-off-by: Fredrik Strupe <fredrik.strupe@silabs.com>
To test the proper handling of owner identifier as of key
identifiers, add owner identifier(s) to tests having
key identifier(s) as test parameters. Just don't do it for
tests related to tests invalid values of key identifiers
as there is no owner identifier invalid values.
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
Fix PSA code and unit tests for the unit tests
to pass with key identifiers encoding owner
identifiers.
The changes in PSA code just make the enablement
of key identifiers encoding owner identifiers
platform independent. Previous to this commit,
such key identifiers were used only in the case
of PSA SPM platforms.
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
Since it is being dereferenced by free on exit it should be inited to NULL.
Also added a small test that would trigger the issue.
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
PSA Crypto was checking the byte length of a to-be-imported public ECP key
against the expected length for Weierstrass keys, forgetting that
Curve25519/Curve448 exists.
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
PSA_ALG_ECB_NO_PADDING came in to the PSA Crypto API spec v1.0.0, but
was not implemented yet in the mbed TLS implementation.
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
Follow the PSA Crypto specification which was updated between 1.0 beta3
and 1.0.0.
Add corresponding test cases.
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
Rename PSA_ECC_CURVE_xxx to PSA_ECC_FAMILY_xxx, also rename
PSA_KEY_TYPE_GET_CURVE to PSA_KEY_TYPE_ECC_GET_FAMILY and rename
psa_ecc_curve_t to psa_ecc_family_t. Old defines are provided in
include/crypto_compat.h for backward compatibility.
Signed-off-by: Paul Elliott <paul.elliott@arm.com>
Change the representation of psa_ecc_curve_t and psa_dh_group_t from
the IETF 16-bit encoding to a custom 24-bit encoding where the upper 8
bits represent a curve family and the lower 16 bits are the key size
in bits. Families are based on naming and mathematical similarity,
with sufficiently precise families that no two curves in a family have
the same bit size (for example SECP-R1 and SECP-R2 are two different
families).
As a consequence, the lower 16 bits of a key type value are always
either the key size or 0.
Don't rely on the bit size encoded in the PSA curve identifier, in
preparation for removing that.
For some inputs, the error code on EC key creation changes from
PSA_ERROR_INVALID_ARGUMENT to PSA_ERROR_NOT_SUPPORTED or vice versa.
There will be further such changes in subsequent commits.
psa_hash_compare is tested for good cases and invalid-signature cases
in hash_compute_compare. Also test invalid-argument cases. Also run a
few autonomous test cases with valid arguments.
Rename some macros and functions related to signature which are
changing as part of the addition of psa_sign_message and
psa_verify_message.
perl -i -pe '%t = (
PSA_KEY_USAGE_SIGN => PSA_KEY_USAGE_SIGN_HASH,
PSA_KEY_USAGE_VERIFY => PSA_KEY_USAGE_VERIFY_HASH,
PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE => PSA_SIGNATURE_MAX_SIZE,
PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE => PSA_SIGN_OUTPUT_SIZE,
psa_asymmetric_sign => psa_sign_hash,
psa_asymmetric_verify => psa_verify_hash,
); s/\b(@{[join("|", keys %t)]})\b/$t{$1}/ge' $(git ls-files . ':!:**/crypto_compat.h')
Consolidate the invalid-handle tests from test_suite_psa_crypto and
test_suite_psa_crypto_slot_management. Start with the code in
test_suite_psa_crypto_slot_management and adapt it to test one invalid
handle value per run of the test function.
Add some ECDSA test cases where the hash is shorter or longer than the
key length, to check that the API doesn't enforce a relationship
between the two.
For the sign_deterministic tests, the keys are
tests/data_files/ec_256_prv.pem and tests/data_files/ec_384_prv.pem
and the signatures were obtained with Python Cryptodome:
from binascii import hexlify, unhexlify
from Crypto.Hash import SHA256, SHA384
from Crypto.PublicKey import ECC
from Crypto.Signature import DSS
k2 = ECC.import_key(unhexlify("3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45"))
SHA384.new(b'hello').hexdigest()
hexlify(DSS.new(k2, 'deterministic-rfc6979').sign(SHA384.new(b'hello')))
k3 = ECC.import_key(unhexlify("3081a402010104303f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76aa00706052b81040022a16403620004d9c662b50ba29ca47990450e043aeaf4f0c69b15676d112f622a71c93059af999691c5680d2b44d111579db12f4a413a2ed5c45fcfb67b5b63e00b91ebe59d09a6b1ac2c0c4282aa12317ed5914f999bc488bb132e8342cc36f2ca5e3379c747"))
SHA256.new(b'hello').hexdigest()
hexlify(DSS.new(k3, 'deterministic-rfc6979').sign(SHA256.new(b'hello')))
If none of the inputs to a key derivation is a
PSA_KEY_DERIVATION_INPUT_SECRET passed with
psa_key_derivation_input_key(), forbid
psa_key_derivation_output_key(). It usually doesn't make sense to
derive a key object if the secret isn't itself a proper key.
After passing some inputs, try getting one byte of output, just to
check that this succeeds (for a valid sequence of inputs) or fails
with BAD_STATE (for an invalid sequence of inputs). Either output a
1-byte key or a 1-byte buffer depending on the test data.
The test data was expanded as follows:
* Output key type (or not a key): same as the SECRET input if success
is expected, otherwise NONE.
* Expected status: PSA_SUCCESS after valid inputs, BAD_STATE after any
invalid input.
Allow a direct input as the SECRET input step in a key derivation, in
addition to allowing DERIVE keys. This makes it easier for
applications to run a key derivation where the "secret" input is
obtained from somewhere else. This makes it possible for the "secret"
input to be empty (keys cannot be empty), which some protocols do (for
example the IV derivation in EAP-TLS).
Conversely, allow a RAW_DATA key as the INFO/LABEL/SALT/SEED input to a key
derivation, in addition to allowing direct inputs. This doesn't
improve security, but removes a step when a personalization parameter
is stored in the key store, and allows this personalization parameter
to remain opaque.
Add test cases that explore step/key-type-and-keyhood combinations.
This commit only makes derive_input more flexible so that the key
derivation API can be tested with different key types and raw data for
each input step. The behavior of the test cases remains the same.
The current test generator code accepts multiple colons as a
separator, but this is just happenstance due to how the code, it isn't
robust. Replace "::" by ":", which is more future-proof and allows
simple separator-based navigation.
Make check-test-cases.py pass.
Prior to this commit, there were many repeated test descriptions, but
none with the same test data and dependencies and comments, as checked
with the following command:
for x in tests/suites/*.data; do perl -00 -ne 'warn "$ARGV: $. = $seen{$_}\n" if $seen{$_}; $seen{$_}=$.' $x; done
Wherever a test suite contains multiple test cases with the exact same
description, add " [#1]", " [#2]", etc. to make the descriptions
unique. We don't currently use this particular arrangement of
punctuation, so all occurrences of " [#" were added by this script.
I used the following ad hoc code:
import sys
def fix_test_suite(data_file_name):
in_paragraph = False
total = {}
index = {}
lines = None
with open(data_file_name) as data_file:
lines = list(data_file.readlines())
for line in lines:
if line == '\n':
in_paragraph = False
continue
if line.startswith('#'):
continue
if not in_paragraph:
# This is a test case description line.
total[line] = total.get(line, 0) + 1
index[line] = 0
in_paragraph = True
with open(data_file_name, 'w') as data_file:
for line in lines:
if line in total and total[line] > 1:
index[line] += 1
line = '%s [#%d]\n' % (line[:-1], index[line])
data_file.write(line)
for data_file_name in sys.argv[1:]:
fix_test_suite(data_file_name)
A test case for 32+0 was present three times, evidently overeager
copy-paste. Replace the duplicates by test cases that read more than
32 bytes, which exercises HKDF a little more (32 bytes is significant
because HKDF-SHA-256 produces output in blocks of 32 bytes).
I obtained the test data by running our implementation, because we're
confident in our implementation now thanks to other test cases: this
data is useful as a non-regression test.
The signature must have exactly the same length as the key, it can't
be longer. Fix#258
If the signature doesn't have the correct size, that's an invalid
signature, not a problem with an output buffer size. Fix the error code.
Add test cases.
In psa_asymmetric_sign, immediately reject an empty signature buffer.
This can never be right.
Add test cases (one RSA and one ECDSA).
Change the SE HAL mock tests not to use an empty signature buffer.
Add tests for derivation.
Test both 7 bits and 9 bits, in case the implementation truncated the
bit size down and 7 was rejected as 0 rather than because it isn't a
multiple of 8.
There is no corresponding test for import because import determines
the key size from the key data, which is always a whole number of bytes.
Test the behavior of the getter/setter functions.
Test that psa_get_key_slot_number() reports a slot number for a key in
a secure element, and doesn't report a slot number for a key that is
not in a secure element.
Test that psa_get_key_slot_number() reports the correct slot number
for a key in a secure element.
Add tests that call psa_generate_random() (possibly via
psa_generate_key()) with a size that's larger than
MBEDTLS_CTR_DRBG_MAX_REQUEST. This causes psa_generate_random() to
fail because it calls mbedtls_ctr_drbg_random() without taking the
maximum request size of CTR_DRBG into account.
Non-regression test for #206
65528 bits is more than any reasonable key until we start supporting
post-quantum cryptography.
This limit is chosen to allow bit-sizes to be stored in 16 bits, with
65535 left to indicate an invalid value. It's a whole number of bytes,
which facilitates some calculations, in particular allowing a key of
exactly PSA_CRYPTO_MAX_STORAGE_SIZE to be created but not one bit
more.
As a resource usage limit, this is arguably too large, but that's out
of scope of the current commit.
Test that key import, generation and derivation reject overly large
sizes.
Add a few test cases to ensure that alg=0 in policy does not allow
using the key for an operation.
Add a test case to ensure that ANY_HASH does not have a wildcard
meaning for HMAC.
This change affects the psa_key_derivation_s structure. With the buffer
removed from the union, it is empty if MBEDTLS_MD_C is not defined.
We can avoid undefined behaviour by adding a new dummy field that is
always present or make the whole union conditional on MBEDTLS_MD_C.
In this latter case the initialiser macro has to depend on MBEDTLS_MD_C
as well. Furthermore the first structure would be either
psa_hkdf_key_derivation_t or psa_tls12_prf_key_derivation_t both of
which are very deep and would make the initialisation macro difficult
to maintain, therefore we go with the first option.
Part of the tests are adapted in this commit, another part is already
covered by the derive_input tests and some of them are not applicable to
the new API (the new API does not request capacity at the setup stage).
The test coverage temporarily drops with this commit, the two test cases
conserning capacity will be re-added in a later commit.
In the 1.0 API some functionality has been split from the
psa_key_derivation_setup() function and is now done with the
psa_key_derivation_input_*() functions. The new tests maintain the
existing test coverage of this functionality.
Add the compile time option PSA_PRE_1_0_KEY_DERIVATION. If this is not
turned on, then the function `psa_key_derivation()` is removed.
Most of the tests regarding key derivation haven't been adapted to the
new API yet and some of them have only been adapted partially. When this
new option is turned off, the tests using the old API and test cases
using the old API of partially adapted tests are skipped.
The sole purpose of this option is to make the transition to the new API
smoother. Once the transition is complete it can and should be removed
along with the old API and its implementation.
Add parameters to psa_copy_key tests for the enrollment algorithm (alg2).
This commit only tests with alg2=0, which is equivalent to not setting
an enrollment algorithm.
Manually cherry-picked from ca5bed742f
by taking that patch, replacing KEYPAIR by KEY_PAIR
throughout (renaming applied in this branch), and discarding parts
about import_twice in test_suite_psa_crypto (this test function was
removed from this branch).