Merge pull request #115 from gilles-peskine-arm/psa-error-compatibility_aliases
Improve how generate_psa_constants handles compatibility aliases
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 16d7197..81fa6cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -137,8 +137,8 @@
set(CMAKE_C_FLAGS_RELEASE "-O2")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
- set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -O3")
- set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
+ set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3")
+ set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
endif(CMAKE_COMPILER_IS_GNU)
@@ -149,7 +149,7 @@
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3")
- set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
+ set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(CMAKE_C_FLAGS_MEMSAN "-Werror -fsanitize=memory -O3")
set(CMAKE_C_FLAGS_MEMSANDBG "-Werror -fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
diff --git a/docs/architecture/Makefile b/docs/architecture/Makefile
index f763c9c..258abcd 100644
--- a/docs/architecture/Makefile
+++ b/docs/architecture/Makefile
@@ -4,6 +4,7 @@
all_markdown = \
mbed-crypto-storage-specification.md \
+ testing/driver-interface-test-strategy.md \
# This line is intentionally left blank
html: $(all_markdown:.md=.html)
@@ -17,3 +18,6 @@
$(PANDOC) -o $@ $<
.md.pdf:
$(PANDOC) -o $@ $<
+
+clean:
+ rm -f *.html *.pdf
diff --git a/docs/architecture/testing/driver-interface-test-strategy.md b/docs/architecture/testing/driver-interface-test-strategy.md
new file mode 100644
index 0000000..d6769da
--- /dev/null
+++ b/docs/architecture/testing/driver-interface-test-strategy.md
@@ -0,0 +1,115 @@
+# Mbed Crypto driver interface test strategy
+
+This document describes the test strategy for the driver interfaces in Mbed Crypto. Mbed Crypto has interfaces for secure element drivers, accelerator drivers and entropy drivers. This document is about testing Mbed Crypto itself; testing drivers is out of scope.
+
+The driver interfaces are standardized through PSA Cryptography functional specifications.
+
+## Secure element driver interface
+
+The secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed Crypto and one or more third-party drivers.
+
+The SE interface consists of one function provided by Mbed Crypto (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed Crypto, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function.
+
+### SE driver interface unit tests
+
+This section describes unit tests that must be implemented to validate the secure element driver interface. Note that a test case may cover multiple requirements; for example a “good case” test can validate that the proper function is called, that it receives the expected inputs and that it produces the expected outputs.
+
+Many SE driver interface unit tests could be covered by running the existing API tests with a key in a secure element.
+
+#### SE driver registration
+
+* Test `psa_register_se_driver` with valid and with invalid arguments.
+* Make at least one failing call to `psa_register_se_driver` followed by a successful call.
+* Make at least one test that successfully registers the maximum number of drivers and fails to register one more.
+
+#### Dispatch to SE driver
+
+For each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent):
+
+* Make at least one test with a key in a secure element that checks that the driver method is called. A few API functions involve multiple driver methods; these should validate that all the expected driver methods are called.
+* Make at least one test with a key that is not in a secure element that checks that the driver method is not called.
+* Make at least one test with a key in a secure element with a driver that does not have the requisite method (i.e. the method pointer is `NULL`) but has the substructure containing that method, and check that the return value is `PSA_ERROR_NOT_SUPPORTED`.
+* Make at least one test with a key in a secure element with a driver that does not have the substructure containing that method (i.e. the pointer to the substructure is `NULL`), and check that the return value is `PSA_ERROR_NOT_SUPPORTED`.
+* At least one test should register multiple drivers with a key in each driver and check that the expected driver is called. This does not need to be done for all operations (use a white-box approach to determine if operations may use different code paths to choose the driver).
+* At least one test should register the same driver structure with multiple lifetime values and check that the driver receives the expected lifetime value.
+
+Some methods only make sense as a group (for example a driver that provides the MAC methods must provide all or none). In those cases, test with all of them null and none of them null.
+
+#### SE driver inputs
+
+For each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent):
+
+* Wherever the specification guarantees parameters that satisfy certain preconditions, check these preconditions whenever practical.
+* If the API function can take parameters that are invalid and must not reach the driver, call the API function with such parameters and verify that the driver method is not called.
+* Check that the expected inputs reach the driver. This may be implicit in a test that checks the outputs if the only realistic way to obtain the correct outputs is to start from the expected inputs (as is often the case for cryptographic material, but not for metadata).
+
+#### SE driver outputs
+
+For each API function that leads to a driver call, call it with parameters that cause a driver to be invoked and check how Mbed Crypto handles the outputs.
+
+* Correct outputs.
+* Incorrect outputs such as an invalid output length.
+* Expected errors (e.g. `PSA_ERROR_INVALID_SIGNATURE` from a signature verification method).
+* Unexpected errors. At least test that if the driver returns `PSA_ERROR_GENERIC_ERROR`, this is propagated correctly.
+
+Key creation functions invoke multiple methods and need more complex error handling:
+
+* Check the consequence of errors detected at each stage (slot number allocation or validation, key creation method, storage accesses).
+* Check that the storage ends up in the expected state. At least make sure that no intermediate file remains after a failure.
+
+#### Persistence of SE keys
+
+The following tests must be performed at least one for each key creation method (import, generate, ...).
+
+* Test that keys in a secure element survive `psa_close_key(); psa_open_key()`.
+* Test that keys in a secure element survive `mbedtls_psa_crypto_free(); psa_crypto_init()`.
+* Test that the driver's persistent data survives `mbedtls_psa_crypto_free(); psa_crypto_init()`.
+* Test that `psa_destroy_key()` does not leave any trace of the key.
+
+#### Resilience for SE drivers
+
+Creating or removing a key in a secure element involves multiple storage modifications (M<sub>1</sub>, ..., M<sub>n</sub>). If the operation is interrupted by a reset at any point, it must be either rolled back or completed.
+
+* For each potential interruption point (before M<sub>1</sub>, between M<sub>1</sub> and M<sub>2</sub>, ..., after M<sub>n</sub>), call `mbedtls_psa_crypto_free(); psa_crypto_init()` at that point and check that this either rolls back or completes the operation that was started.
+* This must be done for each key creation method and for key destruction.
+* This must be done for each possible flow, including error cases (e.g. a key creation that fails midway due to `OUT_OF_MEMORY`).
+* The recovery during `psa_crypto_init` can itself be interrupted. Test those interruptions too.
+* Two things need to be tested: the key that is being created or destroyed, and the driver's persistent storage.
+* Check both that the storage has the expected content (this can be done by e.g. using a key that is supposed to be present) and does not have any unexpected content (for keys, this can be done by checking that `psa_open_key` fails with `PSA_ERRROR_DOES_NOT_EXIST`).
+
+This requires instrumenting the storage implementation, either to force it to fail at each point or to record successive storage states and replay each of them. Each `psa_its_xxx` function call is assumed to be atomic.
+
+### SE driver system tests
+
+#### Real-world use case
+
+We must have at least one driver that is close to real-world conditions:
+
+* With its own source tree.
+* Running on actual hardware.
+* Run the full driver validation test suite (which does not yet exist).
+* Run at least one test application (e.g. the Mbed OS TLS example).
+
+This requirement shall be fulfilled by the [Microchip ATECC508A driver](https://github.com/ARMmbed/mbed-os-atecc608a/).
+
+#### Complete driver
+
+We should have at least one driver that covers the whole interface:
+
+* With its own source tree.
+* Implementing all the methods.
+* Run the full driver validation test suite (which does not yet exist).
+
+A PKCS#11 driver would be a good candidate. It would be useful as part of our product offering.
+
+## Accelerator driver interface
+
+The accelerator driver interface is defined by [`psa/crypto_accel_driver.h`](../../../include/psa/crypto_accel_driver.h).
+
+TODO
+
+## Entropy driver interface
+
+The entropy driver interface is defined by [`psa/crypto_entropy_driver.h`](../../../include/psa/crypto_entropy_driver.h).
+
+TODO
diff --git a/docs/getting_started.md b/docs/getting_started.md
index 4d380e0..236c1a2 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -18,7 +18,7 @@
#### Platform Security Architecture (PSA)
Arm's Platform Security Architecture (PSA) is a holistic set of threat models,
-security analyses, hardware and firmware architecture specifications, and an open source firmware reference implementation. PSA provides a recipe, based on industry best practice, that allows security to be consistently designed in, at both a hardware and firmware level. Part of the API provided by PSA is the cryptography interface, which provides access to a set of primitives.
+security analyses, hardware and firmware architecture specifications, and an open source firmware reference implementation. PSA provides a recipe, based on industry best practice, that enables you to design security into both hardware and firmware consistently. Part of the API provided by PSA is the cryptography interface, which provides access to a set of primitives.
### Using Mbed Crypto
@@ -37,11 +37,11 @@
### Getting the Mbed Crypto library
-Mbed Crypto releases are available in the [public Github repository]( https://github.com/ARMmbed/mbed-crypto).
+Mbed Crypto releases are available in the [public GitHub repository](https://github.com/ARMmbed/mbed-crypto).
### Building the Mbed Crypto library
-You need the following tools to build the library with the provided makefiles:
+**Prerequisites to building the library with the provided makefiles:**
* GNU Make.
* A C toolchain (compiler, linker, archiver).
* Python 2 or Python 3 (either works) to generate the test code.
@@ -49,7 +49,7 @@
If you have a C compiler such as GCC or Clang, just run `make` in the top-level directory to build the library, a set of unit tests and some sample programs.
-To select a different compiler, set the `CC` variable to name or path of the compiler and linker (default: `cc`) and set `AR` to a compatible archiver (default: `ar`), such as:
+To select a different compiler, set the `CC` variable to the name or path of the compiler and linker (default: `cc`) and set `AR` to a compatible archiver (default: `ar`); for example:
```
make CC=arm-linux-gnueabi-gcc AR=arm-linux-gnueabi-ar
```
@@ -64,13 +64,13 @@
### Importing a key
To use a key for cryptography operations in Mbed Crypto, you need to first
-import it. Upon importing, you'll be given a handle to refer to the key for use
+import it. Importing the key creates a handle that refers to the key for use
with other function calls.
-Prerequisites for importing keys:
-* Initialize the library with a successful call to `psa_crypto_init`.
+**Prerequisites to importing keys:**
+* Initialize the library with a successful call to `psa_crypto_init()`.
-Importing a key:
+This example shows how to import a key:
```C
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -112,23 +112,24 @@
### Signing a message using RSA
-Mbed Crypto provides support for encrypting, decrypting, signing and verifying messages using public key signature algorithms (such as RSA or ECDSA).
+Mbed Crypto supports encrypting, decrypting, signing and verifying messages using public key signature algorithms, such as RSA or ECDSA.
-Prerequisites for performing asymmetric signature operations:
-* Initialize the library with a successful call to `psa_crypto_init`.
+**Prerequisites to performing asymmetric signature operations:**
+* Initialize the library with a successful call to `psa_crypto_init()`.
* Have a valid key with appropriate attributes set:
* Usage flag `PSA_KEY_USAGE_SIGN` to allow signing.
* Usage flag `PSA_KEY_USAGE_VERIFY` to allow signature verification.
- * Algorithm set to desired signature algorithm.
+ * Algorithm set to the desired signature algorithm.
-To sign a given `hash` using RSA:
-1. Call `psa_asymmetric_sign()` and get the output buffer that contains the
- signature:
+This example shows how to sign a hash that has already been calculated:
```C
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
uint8_t key[] = RSA_KEY;
- uint8_t hash[] = "INPUT_FOR_SIGN";
+ uint8_t hash[32] = {0x50, 0xd8, 0x58, 0xe0, 0x98, 0x5e, 0xcc, 0x7f,
+ 0x60, 0x41, 0x8a, 0xaf, 0x0c, 0xc5, 0xab, 0x58,
+ 0x7f, 0x42, 0xc2, 0x57, 0x0a, 0x88, 0x40, 0x95,
+ 0xa9, 0xe8, 0xcc, 0xac, 0xd0, 0xf6, 0x54, 0x5c};
uint8_t signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
size_t signature_length;
psa_key_handle_t handle;
@@ -179,21 +180,21 @@
### Using symmetric ciphers
-Mbed Crypto provides support for encrypting and decrypting messages using various symmetric cipher algorithms (both block and stream ciphers).
+Mbed Crypto supports encrypting and decrypting messages using various symmetric cipher algorithms (both block and stream ciphers).
-Prerequisites to working with the symmetric cipher API:
-* Initialize the library with a successful call to `psa_crypto_init`.
-* Configure the key policy accordingly (`PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to allow decryption).
-* Have a valid key in the key slot.
+**Prerequisites to working with the symmetric cipher API:**
+* Initialize the library with a successful call to `psa_crypto_init()`.
+* Have a handle to a symmetric key. This key's usage flags must include `PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to allow decryption.
-Encrypting a message with a symmetric cipher:
+**To encrypt a message with a symmetric cipher:**
1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
-1. Call `psa_cipher_encrypt_setup` to initialize the operation structure and specify the algorithm and the key to be used.
-1. Call either `psa_cipher_generate_iv` or `psa_cipher_set_iv` to generate or set the initialization vector (IV). We recommended `psa_cipher_generate_iv`, unless you require a specific IV value.
-1. Call `psa_cipher_update` one or more times, passing either the whole or only a fragment of the message each time.
-1. Call `psa_cipher_finish` to end the operation and output the encrypted message.
+1. Initialize the operation structure to zero or to `PSA_CIPHER_OPERATION_INIT`.
+1. Call `psa_cipher_encrypt_setup()` to specify the algorithm and the key to be used.
+1. Call either `psa_cipher_generate_iv()` or `psa_cipher_set_iv()` to generate or set the initialization vector (IV). We recommend calling `psa_cipher_generate_iv()`, unless you require a specific IV value.
+1. Call `psa_cipher_update()` with the message to encrypt. You may call this function multiple times, passing successive fragments of the message on successive calls.
+1. Call `psa_cipher_finish()` to end the operation and output the encrypted message.
-Encrypting data using an AES key in cipher block chain (CBC) mode with no padding (assuming all prerequisites have been fulfilled):
+This example shows how to encrypt data using an AES (Advanced Encryption Standard) key in CBC (Cipher Block Chaining) mode with no padding (assuming all prerequisites have been fulfilled):
```c
enum {
block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES),
@@ -267,14 +268,15 @@
mbedtls_psa_crypto_free();
```
-Decrypting a message with a symmetric cipher:
+**To decrypt a message with a symmetric cipher:**
1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
-1. Call `psa_cipher_decrypt_setup` to initialize the operation structure and to specify the algorithm and the key to be used.
-1. Call `psa_cipher_set_iv` with the IV for the decryption.
-1. Call `psa_cipher_update` one or more times passing either the whole or only a fragment of the message each time.
-1. Call `psa_cipher_finish` to end the operation and output the decrypted message.
+1. Initialize the operation structure to zero or to `PSA_CIPHER_OPERATION_INIT`.
+1. Call `psa_cipher_decrypt_setup()` to specify the algorithm and the key to be used.
+1. Call `psa_cipher_set_iv()` with the IV for the decryption.
+1. Call `psa_cipher_update()` with the message to encrypt. You may call this function multiple times, passing successive fragments of the message on successive calls.
+1. Call `psa_cipher_finish()` to end the operation and output the decrypted message.
-Decrypting encrypted data using an AES key in CBC mode with no padding
+This example shows how to decrypt encrypted data using an AES key in CBC mode with no padding
(assuming all prerequisites have been fulfilled):
```c
enum {
@@ -350,33 +352,36 @@
#### Handling cipher operation contexts
-Once you've initialized the operation structure with a successful call to `psa_cipher_encrypt_setup` or `psa_cipher_decrypt_setup`, you can terminate the operation at any time by calling `psa_cipher_abort`.
+After you've initialized the operation structure with a successful call to `psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()`, you can terminate the operation at any time by calling `psa_cipher_abort()`.
-The call to `psa_cipher_abort` frees any resources associated with the operation (except for the operation structure itself). An implicit call to `psa_cipher_abort` occurs when any of these conditions occur:
-* A call to `psa_cipher_generate_iv`, `psa_cipher_set_iv` or `psa_cipher_update` has failed (returning any status other than `PSA_SUCCESS`).
-* Either a successful or failed call to `psa_cipher_finish`.
+The call to `psa_cipher_abort()` frees any resources associated with the operation, except for the operation structure itself.
-Once `psa_cipher_abort` has been called (either implicitly by the implementation or explicitly by the user), the operation structure is invalidated and may not be reused for the same operation. However, the operation structure may be reused for a different operation by calling either `psa_cipher_encrypt_setup` or `psa_cipher_decrypt_setup` again.
+Mbed Crypto implicitly calls `psa_cipher_abort()` when:
+* A call to `psa_cipher_generate_iv()`, `psa_cipher_set_iv()` or `psa_cipher_update()` fails (returning any status other than `PSA_SUCCESS`).
+* A call to `psa_cipher_finish()` succeeds or fails.
-For an operation that has been initialized successfully (by a successful call to `psa_cipher_encrypt_setup` or `psa_cipher_decrypt_setup`) it is imperative that at some time `psa_cipher_abort` is called.
+After an implicit or explicit call to `psa_cipher_abort()`, the operation structure is invalidated; in other words, you cannot reuse the operation structure for the same operation. You can, however, reuse the operation structure for a different operation by calling either `psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()` again.
-Multiple sequential calls to `psa_cipher_abort` on an operation that has already been terminated (either implicitly or explicitly) are safe and have no effect.
+You must call `psa_cipher_abort()` at some point for any operation that is initialized successfully (by a successful call to `psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()`).
+
+Making multiple sequential calls to `psa_cipher_abort()` on an operation that is terminated (either implicitly or explicitly) is safe and has no effect.
### Hashing a message
Mbed Crypto lets you compute and verify hashes using various hashing
algorithms.
-Prerequisites to working with the hash APIs:
-* Initialize the library with a successful call to `psa_crypto_init`.
+**Prerequisites to working with the hash APIs:**
+* Initialize the library with a successful call to `psa_crypto_init()`.
-To calculate a hash:
+**To calculate a hash:**
1. Allocate an operation structure (`psa_hash_operation_t`) to pass to the hash functions.
-1. Call `psa_hash_setup` to initialize the operation structure and specify the hash algorithm.
-1. Call `psa_hash_update` one or more times, passing either the whole or only a fragment of the message each time.
-1. Call `psa_hash_finish` to calculate the hash, or `psa_hash_verify` to compare the computed hash with an expected hash value.
+1. Initialize the operation structure to zero or to `PSA_HASH_OPERATION_INIT`.
+1. Call `psa_hash_setup()` to specify the hash algorithm.
+1. Call `psa_hash_update()` with the message to encrypt. You may call this function multiple times, passing successive fragments of the message on successive calls.
+1. Call `psa_hash_finish()` to calculate the hash, or `psa_hash_verify()` to compare the computed hash with an expected hash value.
-Calculate the `SHA-256` hash of a message:
+This example shows how to calculate the SHA-256 hash of a message:
```c
psa_status_t status;
psa_algorithm_t alg = PSA_ALG_SHA_256;
@@ -421,7 +426,7 @@
mbedtls_psa_crypto_free();
```
-Verify the `SHA-256` hash of a message:
+This example shows how to verify the SHA-256 hash of a message:
```c
psa_status_t status;
psa_algorithm_t alg = PSA_ALG_SHA_256;
@@ -473,29 +478,29 @@
#### Handling hash operation contexts
-Once the operation structure has been successfully initialized by a successful call to `psa_hash_setup`, it's possible to terminate the operation at any time by calling `psa_hash_abort`. The call to `psa_hash_abort` frees any resources associated with the operation (except for the operation structure itself).
+After a successful call to `psa_hash_setup()`, you can terminate the operation at any time by calling `psa_hash_abort()`. The call to `psa_hash_abort()` frees any resources associated with the operation, except for the operation structure itself.
-An implicit call to `psa_hash_abort` occurs when any of these conditions occur:
-1. A call to `psa_hash_update` has failed (returning any status other than `PSA_SUCCESS`).
-1. Either a successful or failed call to `psa_hash_finish`.
-1. Either a successful or failed call to `psa_hash_verify`.
+Mbed Crypto implicitly calls `psa_hash_abort()` when:
+1. A call to `psa_hash_update()` fails (returning any status other than `PSA_SUCCESS`).
+1. A call to `psa_hash_finish()` succeeds or fails.
+1. A call to `psa_hash_verify()` succeeds or fails.
-Once `psa_hash_abort` has been called (either implicitly by the implementation or explicitly by the user), the operation structure is invalidated and may not be reused for the same operation. However, the operation structure may be reused for a different operation by calling `psa_hash_setup` again.
+After an implicit or explicit call to `psa_hash_abort()`, the operation structure is invalidated; in other words, you cannot reuse the operation structure for the same operation. You can, however, reuse the operation structure for a different operation by calling `psa_hash_setup()` again.
-For an operation that has been initialized successfully (by a successful call to `psa_hash_setup`) it is imperative that at some time `psa_hash_abort` is called.
+You must call `psa_hash_abort()` at some point for any operation that is initialized successfully (by a successful call to `psa_hash_setup()`) .
-Multiple sequential calls to `psa_hash_abort` on an operation that has already been terminated (either implicitly or explicitly) is safe and has no effect.
+Making multiple sequential calls to `psa_hash_abort()` on an operation that has already been terminated (either implicitly or explicitly) is safe and has no effect.
### Generating a random value
-Mbed Crypto can generate random data. To generate a random key, use
-`psa_generate_key()` instead of `psa_generate_random()`
+Mbed Crypto can generate random data.
-Prerequisites to random generation:
+**Prerequisites to generating random data:**
* Initialize the library with a successful call to `psa_crypto_init()`.
-Generate a random, ten-byte piece of data:
-1. Generate random bytes by calling `psa_generate_random()`:
+<span class="notes">**Note:** To generate a random key, use `psa_generate_key()` instead of `psa_generate_random()`.</span>
+
+This example shows how to generate ten bytes of random data by calling `psa_generate_random()`:
```C
psa_status_t status;
uint8_t random[10] = { 0 };
@@ -527,35 +532,38 @@
Mbed Crypto provides a key derivation API that lets you derive new keys from
existing ones. The key derivation API has functions to take inputs, including
other keys and data, and functions to generate outputs, such as new keys or
-other data. A key derivation context must first be initialized and set up,
-provided with a key and optionally other data, and then derived data can be
-read from it either to a buffer or directly sent to a key slot. Refer to the
-documentation for the particular algorithm (such as HKDF or the TLS1.2 PRF) for
-information on which inputs to pass when and when you can obtain which outputs.
+other data.
-Prerequisites to working with the key derivation APIs:
-* Initialize the library with a successful call to `psa_crypto_init`.
+You must first initialize and set up a key derivation context,
+provided with a key and, optionally, other data. Then, use the key derivation context to either read derived data to a buffer or send derived data directly to a key slot.
+
+See the documentation for the particular algorithm (such as HKDF or the TLS1.2 PRF) for
+information about which inputs to pass when, and when you can obtain which outputs.
+
+**Prerequisites to working with the key derivation APIs:**
+* Initialize the library with a successful call to `psa_crypto_init()`.
* Use a key with the appropriate attributes set:
* Usage flags set for key derivation (`PSA_KEY_USAGE_DERIVE`)
* Key type set to `PSA_KEY_TYPE_DERIVE`.
* Algorithm set to a key derivation algorithm
- (`PSA_ALG_HKDF(PSA_ALG_SHA_256)`).
+ (for example, `PSA_ALG_HKDF(PSA_ALG_SHA_256)`).
-Deriving a new AES-CTR 128-bit encryption key into a given key slot using HKDF
-with a given key, salt and info:
-1. Set up the key derivation context using the `psa_key_derivation_setup`
+**To derive a new AES-CTR 128-bit encryption key into a given key slot using HKDF
+with a given key, salt and info:**
+
+1. Set up the key derivation context using the `psa_key_derivation_setup()`
function, specifying the derivation algorithm `PSA_ALG_HKDF(PSA_ALG_SHA_256)`.
-1. Provide an optional salt with `psa_key_derivation_input_bytes`.
-1. Provide info with `psa_key_derivation_input_bytes`.
-1. Provide secret with `psa_key_derivation_input_key`, referencing a key that
+1. Provide an optional salt with `psa_key_derivation_input_bytes()`.
+1. Provide info with `psa_key_derivation_input_bytes()`.
+1. Provide a secret with `psa_key_derivation_input_key()`, referencing a key that
can be used for key derivation.
1. Set the key attributes desired for the new derived key. We'll set
- `PSA_KEY_USAGE_ENCRYPT` parameter and the algorithm `PSA_ALG_CTR` for this
+ the `PSA_KEY_USAGE_ENCRYPT` usage flag and the `PSA_ALG_CTR` algorithm for this
example.
1. Derive the key by calling `psa_key_derivation_output_key()`.
1. Clean up the key derivation context.
-At this point the derived key slot holds a new 128-bit AES-CTR encryption key
+At this point, the derived key slot holds a new 128-bit AES-CTR encryption key
derived from the key, salt and info provided:
```C
psa_status_t status;
@@ -659,14 +667,13 @@
### Authenticating and encrypting or decrypting a message
-Mbed Crypto provides a simple way for authenticate and encrypt with associated data (AEAD) supporting `PSA_ALG_CCM` algorithm.
+Mbed Crypto provides a simple way to authenticate and encrypt with associated data (AEAD), supporting the `PSA_ALG_CCM` algorithm.
-Prerequisites to working with the AEAD ciphers APIs:
-* Initialize the library with a successful call to `psa_crypto_init`.
-* The key attributes for the key used for derivation must have usage flags
- `PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT`.
+**Prerequisites to working with the AEAD cipher APIs:**
+* Initialize the library with a successful call to `psa_crypto_init()`.
+* The key attributes for the key used for derivation must have the `PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT` usage flags.
-To authenticate and encrypt a message:
+This example shows how to authenticate and encrypt a message:
```C
psa_status_t status;
static const uint8_t key[] = {
@@ -737,7 +744,7 @@
mbedtls_psa_crypto_free();
```
-To authenticate and decrypt a message:
+This example shows how to authenticate and decrypt a message:
```C
psa_status_t status;
@@ -816,18 +823,15 @@
Mbed Crypto provides a simple way to generate a key or key pair.
-Prerequisites to using key generation and export APIs:
-* Initialize the library with a successful call to `psa_crypto_init`.
+**Prerequisites to using key generation and export APIs:**
+* Initialize the library with a successful call to `psa_crypto_init()`.
-Generate an ECDSA key:
+**To generate an ECDSA key:**
1. Set the desired key attributes for key generation by calling
`psa_set_key_algorithm()` with the chosen ECDSA algorithm (such as
- `PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)`). We don't set
- `PSA_KEY_USAGE_EXPORT` as we only want to export the public key, not the key
- pair (or private key).
+ `PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)`). You only want to export the public key, not the key pair (or private key); therefore, do not set `PSA_KEY_USAGE_EXPORT`.
1. Generate a key by calling `psa_generate_key()`.
-1. Export the generated public key by calling `psa_export_public_key()`
-:
+1. Export the generated public key by calling `psa_export_public_key()`:
```C
enum {
key_bits = 256,
@@ -877,8 +881,6 @@
mbedtls_psa_crypto_free();
```
-### More about the Mbed Crypto library
+### More about the PSA Crypto API
-More information on [Mbed Crypto](https://github.com/ARMmbed/mbed-crypto/).
-
-More information on [PSA Crypto](https://github.com/ARMmbed/mbed-crypto/blob/development/docs/PSA_Crypto_API_Overview.pdf).
+For more information about the PSA Crypto API, please see the [PSA Cryptography API Specification](https://armmbed.github.io/mbed-crypto/html/index.html).
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 3c1430c..e14fc74 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -441,6 +441,16 @@
* dependencies on them, and considering stronger message digests
* and ciphers instead.
*
+ * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are
+ * enabled, then the deterministic ECDH signature functions pass the
+ * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore
+ * alternative implementations should use the RNG only for generating
+ * the ephemeral key and nothing else. If this is not possible, then
+ * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative
+ * implementation should be provided for mbedtls_ecdsa_sign_det_ext()
+ * (and for mbedtls_ecdsa_sign_det() too if backward compatibility is
+ * desirable).
+ *
*/
//#define MBEDTLS_MD2_PROCESS_ALT
//#define MBEDTLS_MD4_PROCESS_ALT
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index ad51188..b009e73 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -176,6 +176,12 @@
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, deterministic version.
@@ -190,6 +196,19 @@
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
+ * \warning Since the output of the internal RNG is always the same for
+ * the same key and message, this limits the efficiency of
+ * blinding and leaks information through side channels. For
+ * secure behavior use mbedtls_ecdsa_sign_det_ext() instead.
+ *
+ * (Optimally the blinding is a random value that is different
+ * on every execution. In this case the blinding is still
+ * random from the attackers perspective, but is the same on
+ * each execution. This means that this blinding does not
+ * prevent attackers from recovering secrets by combining
+ * several measurement traces, but may prevent some attacks
+ * that exploit relationships between secret data.)
+ *
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
@@ -214,7 +233,55 @@
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
- mbedtls_md_type_t md_alg );
+ mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED;
+#undef MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief This function computes the ECDSA signature of a
+ * previously-hashed message, deterministic version.
+ *
+ * For more information, see <em>RFC-6979: Deterministic
+ * Usage of the Digital Signature Algorithm (DSA) and Elliptic
+ * Curve Digital Signature Algorithm (ECDSA)</em>.
+ *
+ * \note If the bitlength of the message hash is larger than the
+ * bitlength of the group order, then the hash is truncated as
+ * defined in <em>Standards for Efficient Cryptography Group
+ * (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ * 4.1.3, step 5.
+ *
+ * \see ecp.h
+ *
+ * \param grp The context for the elliptic curve to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ * \param r The MPI context in which to store the first part
+ * the signature. This must be initialized.
+ * \param s The MPI context in which to store the second part
+ * the signature. This must be initialized.
+ * \param d The private signing key. This must be initialized
+ * and setup, for example through mbedtls_ecp_gen_privkey().
+ * \param buf The hashed content to be signed. This must be a readable
+ * buffer of length \p blen Bytes. It may be \c NULL if
+ * \p blen is zero.
+ * \param blen The length of \p buf in Bytes.
+ * \param md_alg The hash algorithm used to hash the original data.
+ * \param f_rng_blind The RNG function used for blinding. This must not be
+ * \c NULL.
+ * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
+ * \c NULL if \p f_rng doesn't need a context parameter.
+ *
+ * \return \c 0 on success.
+ * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ * error code on failure.
+ */
+int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+ mbedtls_mpi *s, const mbedtls_mpi *d,
+ const unsigned char *buf, size_t blen,
+ mbedtls_md_type_t md_alg,
+ int (*f_rng_blind)(void *, unsigned char *, size_t),
+ void *p_rng_blind );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
@@ -293,7 +360,8 @@
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
- * it is unused and may be set to \c NULL.
+ * it is used only for blinding and may be set to \c NULL, but
+ * doing so is DEPRECATED.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
*
diff --git a/include/mbedtls/md_internal.h b/include/mbedtls/md_internal.h
index 267ceba..bb876ef 100644
--- a/include/mbedtls/md_internal.h
+++ b/include/mbedtls/md_internal.h
@@ -46,42 +46,17 @@
*/
struct mbedtls_md_info_t
{
- /** Digest identifier */
- mbedtls_md_type_t type;
-
/** Name of the message digest */
const char * name;
+ /** Digest identifier */
+ mbedtls_md_type_t type;
+
/** Output length of the digest function in bytes */
- int size;
+ unsigned char size;
/** Block length of the digest function in bytes */
- int block_size;
-
- /** Digest initialisation function */
- int (*starts_func)( void *ctx );
-
- /** Digest update function */
- int (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
-
- /** Digest finalisation function */
- int (*finish_func)( void *ctx, unsigned char *output );
-
- /** Generic digest function */
- int (*digest_func)( const unsigned char *input, size_t ilen,
- unsigned char *output );
-
- /** Allocate a new context */
- void * (*ctx_alloc_func)( void );
-
- /** Free the given context */
- void (*ctx_free_func)( void *ctx );
-
- /** Clone state from a context */
- void (*clone_func)( void *dst, const void *src );
-
- /** Internal use only */
- int (*process_func)( void *ctx, const unsigned char *input );
+ unsigned char block_size;
};
#if defined(MBEDTLS_MD2_C)
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 0d8cbfa..89392da 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -226,7 +226,14 @@
/** Declare the permitted algorithm policy for a key.
*
* The permitted algorithm policy of a key encodes which algorithm or
- * algorithms are permitted to be used with this key.
+ * algorithms are permitted to be used with this key. The following
+ * algorithm policies are supported:
+ * - 0 does not allow any cryptographic operation with the key. The key
+ * may be used for non-cryptographic actions such as exporting (if
+ * permitted by the usage flags).
+ * - An algorithm value permits this particular algorithm.
+ * - An algorithm wildcard built from #PSA_ALG_ANY_HASH allows the specified
+ * signature scheme with any hash algorithm.
*
* This function overwrites any algorithm policy
* previously set in \p attributes.
@@ -266,6 +273,8 @@
*
* \param[out] attributes The attribute structure to write to.
* \param type The key type to write.
+ * If this is 0, the key type in \p attributes
+ * becomes unspecified.
*/
static void psa_set_key_type(psa_key_attributes_t *attributes,
psa_key_type_t type);
@@ -281,6 +290,9 @@
*
* \param[out] attributes The attribute structure to write to.
* \param bits The key size in bits.
+ * If this is 0, the key size in \p attributes
+ * becomes unspecified. Keys of size 0 are
+ * not supported.
*/
static void psa_set_key_bits(psa_key_attributes_t *attributes,
size_t bits);
@@ -328,6 +340,12 @@
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_get_key_attributes(psa_key_handle_t handle,
psa_key_attributes_t *attributes);
@@ -361,15 +379,18 @@
* keys that can be opened with psa_open_key(). Such keys have a key identifier
* in the vendor range, as documented in the description of #psa_key_id_t.
*
- * The application must eventually close the handle with psa_close_key()
- * to release associated resources. If the application dies without calling
- * psa_close_key(), the implementation should perform the equivalent of a
- * call to psa_close_key().
+ * The application must eventually close the handle with psa_close_key() or
+ * psa_destroy_key() to release associated resources. If the application dies
+ * without calling one of these functions, the implementation should perform
+ * the equivalent of a call to psa_close_key().
*
* Some implementations permit an application to open the same key multiple
- * times. Applications that rely on this behavior will not be portable to
- * implementations that only permit a single key handle to be opened. See
- * also :ref:\`key-handles\`.
+ * times. If this is successful, each call to psa_open_key() will return a
+ * different key handle.
+ *
+ * \note Applications that rely on opening a key multiple times will not be
+ * portable to implementations that only permit a single key handle to be
+ * opened. See also :ref:\`key-handles\`.
*
* \param id The persistent identifier of the key.
* \param[out] handle On success, a handle to the key.
@@ -392,7 +413,12 @@
* define any way to create such a key, but it may be possible
* through implementation-specific means.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_open_key(psa_key_id_t id,
psa_key_handle_t *handle);
@@ -411,289 +437,24 @@
* Closing the key handle makes the handle invalid, and the key handle
* must not be used again by the application.
*
- * If the key is currently in use in a multipart operation, then closing the
- * last remaining handle to the key will abort the multipart operation.
+ * \note If the key handle was used to set up an active
+ * :ref:\`multipart operation <multipart-operations>\`, then closing the
+ * key handle can cause the multipart operation to fail. Applications should
+ * maintain the key handle until after the multipart operation has finished.
*
* \param handle The key handle to close.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_close_key(psa_key_handle_t handle);
-/**@}*/
-
-/** \defgroup import_export Key import and export
- * @{
- */
-
-/**
- * \brief Import a key in binary format.
- *
- * This function supports any output from psa_export_key(). Refer to the
- * documentation of psa_export_public_key() for the format of public keys
- * and to the documentation of psa_export_key() for the format for
- * other key types.
- *
- * This specification supports a single format for each key type.
- * Implementations may support other formats as long as the standard
- * format is supported. Implementations that support other formats
- * should ensure that the formats are clearly unambiguous so as to
- * minimize the risk that an invalid input is accidentally interpreted
- * according to a different format.
- *
-
- * \param[in] attributes The attributes for the new key.
- * The key size is always determined from the
- * \p data buffer.
- * If the key size in \p attributes is nonzero,
- * it must be equal to the size from \p data.
- * \param[out] handle On success, a handle to the newly created key.
- * \c 0 on failure.
- * \param[in] data Buffer containing the key data. The content of this
- * buffer is interpreted according to the type declared
- * in \p attributes.
- * All implementations must support at least the format
- * described in the documentation
- * of psa_export_key() or psa_export_public_key() for
- * the chosen type. Implementations may allow other
- * formats, but should be conservative: implementations
- * should err on the side of rejecting content if it
- * may be erroneous (e.g. wrong type or truncated data).
- * \param data_length Size of the \p data buffer in bytes.
- *
- * \retval #PSA_SUCCESS
- * Success.
- * If the key is persistent, the key material and the key's metadata
- * have been saved to persistent storage.
- * \retval #PSA_ERROR_ALREADY_EXISTS
- * This is an attempt to create a persistent key, and there is
- * already a persistent key with the given identifier.
- * \retval #PSA_ERROR_NOT_SUPPORTED
- * The key type or key size is not supported, either by the
- * implementation in general or in this particular persistent location.
- * \retval #PSA_ERROR_INVALID_ARGUMENT
- * The key attributes, as a whole, are invalid.
- * \retval #PSA_ERROR_INVALID_ARGUMENT
- * The key data is not correctly formatted.
- * \retval #PSA_ERROR_INVALID_ARGUMENT
- * The size in \p attributes is nonzero and does not match the size
- * of the key data.
- * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
- * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_STORAGE_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_CORRUPTION_DETECTED
- * \retval #PSA_ERROR_BAD_STATE
- * The library has not been previously initialized by psa_crypto_init().
- * It is implementation-dependent whether a failure to initialize
- * results in this error code.
- */
-psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
- const uint8_t *data,
- size_t data_length,
- psa_key_handle_t *handle);
-
-/**
- * \brief Destroy a key.
- *
- * This function destroys a key from both volatile
- * memory and, if applicable, non-volatile storage. Implementations shall
- * make a best effort to ensure that that the key material cannot be recovered.
- *
- * This function also erases any metadata such as policies and frees all
- * resources associated with the key.
- *
- * Destroying a key will invalidate all existing handles to the key.
- *
- * If the key is currently in use in a multipart operation, then destroying the
- * key will abort the multipart operation.
- *
- * \param handle Handle to the key to erase.
- *
- * \retval #PSA_SUCCESS
- * The key material has been erased.
- * \retval #PSA_ERROR_NOT_PERMITTED
- * The key cannot be erased because it is
- * read-only, either due to a policy or due to physical restrictions.
- * \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * There was an failure in communication with the cryptoprocessor.
- * The key material may still be present in the cryptoprocessor.
- * \retval #PSA_ERROR_STORAGE_FAILURE
- * The storage is corrupted. Implementations shall make a best effort
- * to erase key material even in this stage, however applications
- * should be aware that it may be impossible to guarantee that the
- * key material is not recoverable in such cases.
- * \retval #PSA_ERROR_CORRUPTION_DETECTED
- * An unexpected condition which is not a storage corruption or
- * a communication failure occurred. The cryptoprocessor may have
- * been compromised.
- * \retval #PSA_ERROR_BAD_STATE
- * The library has not been previously initialized by psa_crypto_init().
- * It is implementation-dependent whether a failure to initialize
- * results in this error code.
- */
-psa_status_t psa_destroy_key(psa_key_handle_t handle);
-
-/**
- * \brief Export a key in binary format.
- *
- * The output of this function can be passed to psa_import_key() to
- * create an equivalent object.
- *
- * If the implementation of psa_import_key() supports other formats
- * beyond the format specified here, the output from psa_export_key()
- * must use the representation specified here, not the original
- * representation.
- *
- * For standard key types, the output format is as follows:
- *
- * - For symmetric keys (including MAC keys), the format is the
- * raw bytes of the key.
- * - For DES, the key data consists of 8 bytes. The parity bits must be
- * correct.
- * - For Triple-DES, the format is the concatenation of the
- * two or three DES keys.
- * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEY_PAIR), the format
- * is the non-encrypted DER encoding of the representation defined by
- * PKCS\#1 (RFC 8017) as `RSAPrivateKey`, version 0.
- * ```
- * RSAPrivateKey ::= SEQUENCE {
- * version INTEGER, -- must be 0
- * modulus INTEGER, -- n
- * publicExponent INTEGER, -- e
- * privateExponent INTEGER, -- d
- * prime1 INTEGER, -- p
- * prime2 INTEGER, -- q
- * exponent1 INTEGER, -- d mod (p-1)
- * exponent2 INTEGER, -- d mod (q-1)
- * coefficient INTEGER, -- (inverse of q) mod p
- * }
- * ```
- * - For elliptic curve key pairs (key types for which
- * #PSA_KEY_TYPE_IS_ECC_KEY_PAIR is true), the format is
- * a representation of the private value as a `ceiling(m/8)`-byte string
- * where `m` is the bit size associated with the curve, i.e. the bit size
- * of the order of the curve's coordinate field. This byte string is
- * in little-endian order for Montgomery curves (curve types
- * `PSA_ECC_CURVE_CURVEXXX`), and in big-endian order for Weierstrass
- * curves (curve types `PSA_ECC_CURVE_SECTXXX`, `PSA_ECC_CURVE_SECPXXX`
- * and `PSA_ECC_CURVE_BRAINPOOL_PXXX`).
- * This is the content of the `privateKey` field of the `ECPrivateKey`
- * format defined by RFC 5915.
- * - For Diffie-Hellman key exchange key pairs (key types for which
- * #PSA_KEY_TYPE_IS_DH_KEY_PAIR is true), the
- * format is the representation of the private key `x` as a big-endian byte
- * string. The length of the byte string is the private key size in bytes
- * (leading zeroes are not stripped).
- * - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is
- * true), the format is the same as for psa_export_public_key().
- *
- * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set.
- *
- * \param handle Handle to the key to export.
- * \param[out] data Buffer where the key data is to be written.
- * \param data_size Size of the \p data buffer in bytes.
- * \param[out] data_length On success, the number of bytes
- * that make up the key data.
- *
- * \retval #PSA_SUCCESS
- * \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
- * \retval #PSA_ERROR_NOT_PERMITTED
- * The key does not have the #PSA_KEY_USAGE_EXPORT flag.
- * \retval #PSA_ERROR_NOT_SUPPORTED
- * \retval #PSA_ERROR_BUFFER_TOO_SMALL
- * The size of the \p data buffer is too small. You can determine a
- * sufficient buffer size by calling
- * #PSA_KEY_EXPORT_MAX_SIZE(\c type, \c bits)
- * where \c type is the key type
- * and \c bits is the key size in bits.
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_CORRUPTION_DETECTED
- * \retval #PSA_ERROR_BAD_STATE
- * The library has not been previously initialized by psa_crypto_init().
- * It is implementation-dependent whether a failure to initialize
- * results in this error code.
- */
-psa_status_t psa_export_key(psa_key_handle_t handle,
- uint8_t *data,
- size_t data_size,
- size_t *data_length);
-
-/**
- * \brief Export a public key or the public part of a key pair in binary format.
- *
- * The output of this function can be passed to psa_import_key() to
- * create an object that is equivalent to the public key.
- *
- * This specification supports a single format for each key type.
- * Implementations may support other formats as long as the standard
- * format is supported. Implementations that support other formats
- * should ensure that the formats are clearly unambiguous so as to
- * minimize the risk that an invalid input is accidentally interpreted
- * according to a different format.
- *
- * For standard key types, the output format is as follows:
- * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of
- * the representation defined by RFC 3279 §2.3.1 as `RSAPublicKey`.
- * ```
- * RSAPublicKey ::= SEQUENCE {
- * modulus INTEGER, -- n
- * publicExponent INTEGER } -- e
- * ```
- * - For elliptic curve public keys (key types for which
- * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed
- * representation defined by SEC1 §2.3.3 as the content of an ECPoint.
- * Let `m` be the bit size associated with the curve, i.e. the bit size of
- * `q` for a curve over `F_q`. The representation consists of:
- * - The byte 0x04;
- * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
- * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
- * - For Diffie-Hellman key exchange public keys (key types for which
- * #PSA_KEY_TYPE_IS_DH_PUBLIC_KEY is true),
- * the format is the representation of the public key `y = g^x mod p` as a
- * big-endian byte string. The length of the byte string is the length of the
- * base prime `p` in bytes.
- *
- * Exporting a public key object or the public part of a key pair is
- * always permitted, regardless of the key's usage flags.
- *
- * \param handle Handle to the key to export.
- * \param[out] data Buffer where the key data is to be written.
- * \param data_size Size of the \p data buffer in bytes.
- * \param[out] data_length On success, the number of bytes
- * that make up the key data.
- *
- * \retval #PSA_SUCCESS
- * \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
- * \retval #PSA_ERROR_INVALID_ARGUMENT
- * The key is neither a public key nor a key pair.
- * \retval #PSA_ERROR_NOT_SUPPORTED
- * \retval #PSA_ERROR_BUFFER_TOO_SMALL
- * The size of the \p data buffer is too small. You can determine a
- * sufficient buffer size by calling
- * #PSA_KEY_EXPORT_MAX_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits)
- * where \c type is the key type
- * and \c bits is the key size in bits.
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_CORRUPTION_DETECTED
- * \retval #PSA_ERROR_BAD_STATE
- * The library has not been previously initialized by psa_crypto_init().
- * It is implementation-dependent whether a failure to initialize
- * results in this error code.
- */
-psa_status_t psa_export_public_key(psa_key_handle_t handle,
- uint8_t *data,
- size_t data_size,
- size_t *data_length);
-
/** Make a copy of a key.
*
* Copy key material from one location to another.
@@ -771,12 +532,307 @@
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_copy_key(psa_key_handle_t source_handle,
const psa_key_attributes_t *attributes,
psa_key_handle_t *target_handle);
+
+/**
+ * \brief Destroy a key.
+ *
+ * This function destroys a key from both volatile
+ * memory and, if applicable, non-volatile storage. Implementations shall
+ * make a best effort to ensure that that the key material cannot be recovered.
+ *
+ * This function also erases any metadata such as policies and frees
+ * resources associated with the key. To free all resources associated with
+ * the key, all handles to the key must be closed or destroyed.
+ *
+ * Destroying the key makes the handle invalid, and the key handle
+ * must not be used again by the application. Using other open handles to the
+ * destroyed key in a cryptographic operation will result in an error.
+ *
+ * If a key is currently in use in a multipart operation, then destroying the
+ * key will cause the multipart operation to fail.
+ *
+ * \param handle Handle to the key to erase.
+ *
+ * \retval #PSA_SUCCESS
+ * The key material has been erased.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key cannot be erased because it is
+ * read-only, either due to a policy or due to physical restrictions.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * There was an failure in communication with the cryptoprocessor.
+ * The key material may still be present in the cryptoprocessor.
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The storage is corrupted. Implementations shall make a best effort
+ * to erase key material even in this stage, however applications
+ * should be aware that it may be impossible to guarantee that the
+ * key material is not recoverable in such cases.
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * An unexpected condition which is not a storage corruption or
+ * a communication failure occurred. The cryptoprocessor may have
+ * been compromised.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_destroy_key(psa_key_handle_t handle);
+
+/**@}*/
+
+/** \defgroup import_export Key import and export
+ * @{
+ */
+
+/**
+ * \brief Import a key in binary format.
+ *
+ * This function supports any output from psa_export_key(). Refer to the
+ * documentation of psa_export_public_key() for the format of public keys
+ * and to the documentation of psa_export_key() for the format for
+ * other key types.
+ *
+ * The key data determines the key size. The attributes may optionally
+ * specify a key size; in this case it must match the size determined
+ * from the key data. A key size of 0 in \p attributes indicates that
+ * the key size is solely determined by the key data.
+ *
+ * Implementations must reject an attempt to import a key of size 0.
+ *
+ * This specification supports a single format for each key type.
+ * Implementations may support other formats as long as the standard
+ * format is supported. Implementations that support other formats
+ * should ensure that the formats are clearly unambiguous so as to
+ * minimize the risk that an invalid input is accidentally interpreted
+ * according to a different format.
+ *
+ * \param[in] attributes The attributes for the new key.
+ * The key size is always determined from the
+ * \p data buffer.
+ * If the key size in \p attributes is nonzero,
+ * it must be equal to the size from \p data.
+ * \param[out] handle On success, a handle to the newly created key.
+ * \c 0 on failure.
+ * \param[in] data Buffer containing the key data. The content of this
+ * buffer is interpreted according to the type declared
+ * in \p attributes.
+ * All implementations must support at least the format
+ * described in the documentation
+ * of psa_export_key() or psa_export_public_key() for
+ * the chosen type. Implementations may allow other
+ * formats, but should be conservative: implementations
+ * should err on the side of rejecting content if it
+ * may be erroneous (e.g. wrong type or truncated data).
+ * \param data_length Size of the \p data buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * If the key is persistent, the key material and the key's metadata
+ * have been saved to persistent storage.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ * This is an attempt to create a persistent key, and there is
+ * already a persistent key with the given identifier.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The key type or key size is not supported, either by the
+ * implementation in general or in this particular persistent location.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key attributes, as a whole, are invalid.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key data is not correctly formatted.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The size in \p attributes is nonzero and does not match the size
+ * of the key data.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * \p operation is either not initialized or is in use
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data,
+ size_t data_length,
+ psa_key_handle_t *handle);
+
+
+
+/**
+ * \brief Export a key in binary format.
+ *
+ * The output of this function can be passed to psa_import_key() to
+ * create an equivalent object.
+ *
+ * If the implementation of psa_import_key() supports other formats
+ * beyond the format specified here, the output from psa_export_key()
+ * must use the representation specified here, not the original
+ * representation.
+ *
+ * For standard key types, the output format is as follows:
+ *
+ * - For symmetric keys (including MAC keys), the format is the
+ * raw bytes of the key.
+ * - For DES, the key data consists of 8 bytes. The parity bits must be
+ * correct.
+ * - For Triple-DES, the format is the concatenation of the
+ * two or three DES keys.
+ * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEY_PAIR), the format
+ * is the non-encrypted DER encoding of the representation defined by
+ * PKCS\#1 (RFC 8017) as `RSAPrivateKey`, version 0.
+ * ```
+ * RSAPrivateKey ::= SEQUENCE {
+ * version INTEGER, -- must be 0
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * privateExponent INTEGER, -- d
+ * prime1 INTEGER, -- p
+ * prime2 INTEGER, -- q
+ * exponent1 INTEGER, -- d mod (p-1)
+ * exponent2 INTEGER, -- d mod (q-1)
+ * coefficient INTEGER, -- (inverse of q) mod p
+ * }
+ * ```
+ * - For elliptic curve key pairs (key types for which
+ * #PSA_KEY_TYPE_IS_ECC_KEY_PAIR is true), the format is
+ * a representation of the private value as a `ceiling(m/8)`-byte string
+ * where `m` is the bit size associated with the curve, i.e. the bit size
+ * of the order of the curve's coordinate field. This byte string is
+ * in little-endian order for Montgomery curves (curve types
+ * `PSA_ECC_CURVE_CURVEXXX`), and in big-endian order for Weierstrass
+ * curves (curve types `PSA_ECC_CURVE_SECTXXX`, `PSA_ECC_CURVE_SECPXXX`
+ * and `PSA_ECC_CURVE_BRAINPOOL_PXXX`).
+ * This is the content of the `privateKey` field of the `ECPrivateKey`
+ * format defined by RFC 5915.
+ * - For Diffie-Hellman key exchange key pairs (key types for which
+ * #PSA_KEY_TYPE_IS_DH_KEY_PAIR is true), the
+ * format is the representation of the private key `x` as a big-endian byte
+ * string. The length of the byte string is the private key size in bytes
+ * (leading zeroes are not stripped).
+ * - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is
+ * true), the format is the same as for psa_export_public_key().
+ *
+ * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set.
+ *
+ * \param handle Handle to the key to export.
+ * \param[out] data Buffer where the key data is to be written.
+ * \param data_size Size of the \p data buffer in bytes.
+ * \param[out] data_length On success, the number of bytes
+ * that make up the key data.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key does not have the #PSA_KEY_USAGE_EXPORT flag.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p data buffer is too small. You can determine a
+ * sufficient buffer size by calling
+ * #PSA_KEY_EXPORT_MAX_SIZE(\c type, \c bits)
+ * where \c type is the key type
+ * and \c bits is the key size in bits.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_export_key(psa_key_handle_t handle,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length);
+
+/**
+ * \brief Export a public key or the public part of a key pair in binary format.
+ *
+ * The output of this function can be passed to psa_import_key() to
+ * create an object that is equivalent to the public key.
+ *
+ * This specification supports a single format for each key type.
+ * Implementations may support other formats as long as the standard
+ * format is supported. Implementations that support other formats
+ * should ensure that the formats are clearly unambiguous so as to
+ * minimize the risk that an invalid input is accidentally interpreted
+ * according to a different format.
+ *
+ * For standard key types, the output format is as follows:
+ * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of
+ * the representation defined by RFC 3279 §2.3.1 as `RSAPublicKey`.
+ * ```
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER } -- e
+ * ```
+ * - For elliptic curve public keys (key types for which
+ * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed
+ * representation defined by SEC1 §2.3.3 as the content of an ECPoint.
+ * Let `m` be the bit size associated with the curve, i.e. the bit size of
+ * `q` for a curve over `F_q`. The representation consists of:
+ * - The byte 0x04;
+ * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
+ * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
+ * - For Diffie-Hellman key exchange public keys (key types for which
+ * #PSA_KEY_TYPE_IS_DH_PUBLIC_KEY is true),
+ * the format is the representation of the public key `y = g^x mod p` as a
+ * big-endian byte string. The length of the byte string is the length of the
+ * base prime `p` in bytes.
+ *
+ * Exporting a public key object or the public part of a key pair is
+ * always permitted, regardless of the key's usage flags.
+ *
+ * \param handle Handle to the key to export.
+ * \param[out] data Buffer where the key data is to be written.
+ * \param data_size Size of the \p data buffer in bytes.
+ * \param[out] data_length On success, the number of bytes
+ * that make up the key data.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key is neither a public key nor a key pair.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p data buffer is too small. You can determine a
+ * sufficient buffer size by calling
+ * #PSA_KEY_EXPORT_MAX_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits)
+ * where \c type is the key type
+ * and \c bits is the key size in bits.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_export_public_key(psa_key_handle_t handle,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length);
+
+
+
/**@}*/
/** \defgroup hash Message digests
@@ -802,10 +858,18 @@
* Success.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported or is not a hash algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p hash_size is too small
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_hash_compute(psa_algorithm_t alg,
const uint8_t *input,
@@ -831,10 +895,17 @@
* differs from the expected hash.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported or is not a hash algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p input_length or \p hash_length do not match the hash size for \p alg
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_hash_compare(psa_algorithm_t alg,
const uint8_t *input,
@@ -921,7 +992,9 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_NOT_SUPPORTED
- * \p alg is not supported or is not a hash algorithm.
+ * \p alg is not a supported hash algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p alg is not a hash algorithm.
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (already set up and not
* subsequently completed).
@@ -929,6 +1002,12 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * \p operation is either not initialized or is in use
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
psa_algorithm_t alg);
@@ -951,6 +1030,12 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_hash_update(psa_hash_operation_t *operation,
const uint8_t *input,
@@ -992,6 +1077,12 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
uint8_t *hash,
@@ -1028,6 +1119,12 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
const uint8_t *hash,
@@ -1059,6 +1156,12 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_hash_abort(psa_hash_operation_t *operation);
@@ -1085,6 +1188,15 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is either not initialized or has already been setup.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is either not initialized or has already been setup.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation);
@@ -1123,10 +1235,14 @@
* \p handle is not compatible with \p alg.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported or is not a MAC algorithm.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p mac_size is too small
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The key could not be retrieved from storage.
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@@ -1165,6 +1281,12 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The key could not be retrieved from storage.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_mac_verify(psa_key_handle_t handle,
psa_algorithm_t alg,
@@ -1258,7 +1380,6 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p handle is not compatible with \p alg.
@@ -1268,6 +1389,8 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The key could not be retrieved from storage.
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (already set up and not
* subsequently completed).
@@ -1318,7 +1441,6 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \c key is not compatible with \c alg.
@@ -1328,6 +1450,8 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The key could not be retrieved from storage
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (already set up and not
* subsequently completed).
@@ -1360,6 +1484,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_mac_update(psa_mac_operation_t *operation,
const uint8_t *input,
@@ -1402,6 +1531,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
uint8_t *mac,
@@ -1438,6 +1572,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
const uint8_t *mac,
@@ -1470,6 +1609,10 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_mac_abort(psa_mac_operation_t *operation);
@@ -1512,6 +1655,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_cipher_encrypt(psa_key_handle_t handle,
psa_algorithm_t alg,
@@ -1552,7 +1700,12 @@
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_cipher_decrypt(psa_key_handle_t handle,
psa_algorithm_t alg,
@@ -1648,7 +1801,6 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p handle is not compatible with \p alg.
@@ -1658,6 +1810,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (already set up and not
* subsequently completed).
@@ -1710,7 +1863,6 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p handle is not compatible with \p alg.
@@ -1720,6 +1872,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (already set up and not
* subsequently completed).
@@ -1759,6 +1912,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
uint8_t *iv,
@@ -1794,6 +1952,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
const uint8_t *iv,
@@ -1830,6 +1993,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
const uint8_t *input,
@@ -1859,6 +2027,14 @@
*
* \retval #PSA_SUCCESS
* Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * 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.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ * This is a decryption operation for an algorithm that includes
+ * padding, and the ciphertext does not contain valid padding.
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (not set up, IV required but
* not set, or already completed).
@@ -1868,6 +2044,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
uint8_t *output,
@@ -1901,6 +2082,10 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation);
@@ -1941,16 +2126,18 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p handle is not compatible with \p alg.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported or is not an AEAD algorithm.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p ciphertext_size is too small
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@@ -1997,7 +2184,6 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The ciphertext is not authentic.
* \retval #PSA_ERROR_NOT_PERMITTED
@@ -2006,9 +2192,12 @@
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported or is not an AEAD algorithm.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p plaintext_size or \p nonce_length is too small
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@@ -2127,6 +2316,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@@ -2188,6 +2378,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@@ -2225,6 +2416,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
uint8_t *nonce,
@@ -2259,6 +2455,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
const uint8_t *nonce,
@@ -2297,6 +2498,10 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
size_t ad_length,
@@ -2339,6 +2544,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
const uint8_t *input,
@@ -2411,6 +2621,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_aead_update(psa_aead_operation_t *operation,
const uint8_t *input,
@@ -2480,6 +2695,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
uint8_t *ciphertext,
@@ -2493,13 +2713,25 @@
*
* The operation must have been set up with psa_aead_decrypt_setup().
*
- * This function finishes the authentication of the additional data
- * formed by concatenating the inputs passed to preceding calls to
- * psa_aead_update_ad() with the ciphertext formed by concatenating the
- * inputs passed to preceding calls to psa_aead_update().
+ * This function finishes the authenticated decryption of the message
+ * components:
+ *
+ * - The additional data consisting of the concatenation of the inputs
+ * passed to preceding calls to psa_aead_update_ad().
+ * - The ciphertext consisting of the concatenation of the inputs passed to
+ * preceding calls to psa_aead_update().
+ * - The tag passed to this function call.
+ *
+ * If the authentication tag is correct, this function outputs any remaining
+ * plaintext and reports success. If the authentication tag is not correct,
+ * this function returns #PSA_ERROR_INVALID_SIGNATURE.
*
* When this function returns, the operation becomes inactive.
*
+ * \note Implementations shall make the best effort to ensure that the
+ * comparison between the actual tag and the expected tag is performed
+ * in constant time.
+ *
* \param[in,out] operation Active AEAD operation.
* \param[out] plaintext Buffer where the last part of the plaintext
* is to be written. This is the remaining data
@@ -2518,6 +2750,9 @@
*
* \retval #PSA_SUCCESS
* Success.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The calculations were successful, but the authentication tag is
+ * not correct.
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (not set up, nonce not set,
* encryption, or already completed).
@@ -2538,6 +2773,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
uint8_t *plaintext,
@@ -2573,6 +2813,10 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_aead_abort(psa_aead_operation_t *operation);
@@ -2603,6 +2847,8 @@
* that make up the returned signature value.
*
* \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling
@@ -2615,6 +2861,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
@@ -2650,6 +2897,8 @@
*
* \retval #PSA_SUCCESS
* The signature is valid.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was perfomed successfully, but the passed
* signature is not a valid signature.
@@ -2659,6 +2908,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@@ -2700,6 +2950,8 @@
* that make up the returned output.
*
* \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p output buffer is too small. You can
* determine a sufficient buffer size by calling
@@ -2712,6 +2964,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
@@ -2756,6 +3009,8 @@
* that make up the returned output.
*
* \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p output buffer is too small. You can
* determine a sufficient buffer size by calling
@@ -2768,6 +3023,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_INVALID_PADDING
* \retval #PSA_ERROR_BAD_STATE
@@ -2864,6 +3120,8 @@
* - Clean up the key derivation operation object with
* psa_key_derivation_abort().
*
+ * Implementations must reject an attempt to derive a key of size 0.
+ *
* \param[in,out] operation The key derivation operation object
* to set up. It must
* have been initialized but not set up yet.
@@ -2881,7 +3139,13 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
+ * The operation state is either not initialized or has already been setup.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_key_derivation_setup(
psa_key_derivation_operation_t *operation,
@@ -2897,8 +3161,15 @@
* \param[out] capacity On success, the capacity of the operation.
*
* \retval #PSA_SUCCESS
- * \retval #PSA_ERROR_BAD_STATE
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_key_derivation_get_capacity(
const psa_key_derivation_operation_t *operation,
@@ -2920,7 +3191,14 @@
* In this case, the operation object remains valid and its capacity
* remains unchanged.
* \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_key_derivation_set_capacity(
psa_key_derivation_operation_t *operation,
@@ -2963,6 +3241,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The value of \p step is not valid given the state of \p operation.
* \retval #PSA_ERROR_BAD_STATE
@@ -2999,7 +3278,6 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \c step is not compatible with the operation's algorithm.
@@ -3009,6 +3287,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The value of \p step is not valid given the state of \p operation.
* \retval #PSA_ERROR_BAD_STATE
@@ -3061,7 +3340,6 @@
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
- * \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \c private_key is not compatible with \c alg,
@@ -3073,6 +3351,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_key_derivation_key_agreement(
psa_key_derivation_operation_t *operation,
@@ -3107,6 +3390,11 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_key_derivation_output_bytes(
psa_key_derivation_operation_t *operation,
@@ -3117,6 +3405,9 @@
*
* This function calculates output bytes from a key derivation algorithm
* and uses those bytes to generate a key deterministically.
+ * The key's location, usage policy, type and size are taken from
+ * \p attributes.
+ *
* If you view the key derivation's output as a stream of bytes, this
* function destructively reads as many bytes as required from the
* stream.
@@ -3224,6 +3515,7 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@@ -3255,6 +3547,10 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_key_derivation_abort(
psa_key_derivation_operation_t *operation);
@@ -3295,12 +3591,19 @@
* \p private_key is not compatible with \p alg,
* or \p peer_key is not valid for \p alg or not compatible with
* \p private_key.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p output_size is too small
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not a supported key agreement algorithm.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
*/
psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
psa_key_handle_t private_key,
@@ -3331,6 +3634,7 @@
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
@@ -3346,7 +3650,9 @@
* \brief Generate a key or key pair.
*
* The key is generated randomly.
- * Its location, policy, type and size are taken from \p attributes.
+ * Its location, usage policy, type and size are taken from \p attributes.
+ *
+ * Implementations must reject an attempt to generate a key of size 0.
*
* The following type-specific considerations apply:
* - For RSA keys (#PSA_KEY_TYPE_RSA_KEY_PAIR),
@@ -3373,6 +3679,8 @@
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
+ * \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index b79c3b5..b6b6198 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -206,11 +206,12 @@
* values:
*
* - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
- * - key identifier: unspecified.
- * - type: \c 0.
- * - key size: \c 0.
- * - usage flags: \c 0.
- * - algorithm: \c 0.
+ * - key identifier: 0 (which is not a valid key identifier).
+ * - type: \c 0 (meaning that the type is unspecified).
+ * - key size: \c 0 (meaning that the size is unspecified).
+ * - usage flags: \c 0 (which allows no usage except exporting a public key).
+ * - algorithm: \c 0 (which allows no cryptographic usage, but allows
+ * exporting).
*
* A typical sequence to create a key is as follows:
* -# Create and initialize an attribute structure.
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index b53e1c7..fc0f963 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -149,7 +149,7 @@
*
* \warning If a function returns this error, it is undetermined
* whether the requested action has completed or not. Implementations
- * should return #PSA_SUCCESS on successful completion whenver
+ * should return #PSA_SUCCESS on successful completion whenever
* possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE
* if the requested action was completed successfully in an external
* cryptoprocessor but there was a breakdown of communication before
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index f4bb472..5c5ddc2 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -45,7 +45,6 @@
md2.c
md4.c
md5.c
- md_wrap.c
memory_buffer_alloc.c
nist_kw.c
oid.c
diff --git a/library/Makefile b/library/Makefile
index 8e27694..d7c1567 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -74,7 +74,7 @@
gcm.o havege.o \
hkdf.o \
hmac_drbg.o md.o md2.o \
- md4.o md5.o md_wrap.o \
+ md4.o md5.o \
memory_buffer_alloc.o nist_kw.o \
oid.o padlock.o pem.o \
pk.o pk_wrap.o pkcs12.o \
diff --git a/library/bignum.c b/library/bignum.c
index 5f5df78..d5bde8b 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -742,10 +742,15 @@
static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
{
uint8_t i;
+ unsigned char *x_ptr;
mbedtls_mpi_uint tmp = 0;
- /* This works regardless of the endianness. */
- for( i = 0; i < ciL; i++, x >>= 8 )
- tmp |= ( x & 0xFF ) << ( ( ciL - 1 - i ) << 3 );
+
+ for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ )
+ {
+ tmp <<= CHAR_BIT;
+ tmp |= (mbedtls_mpi_uint) *x_ptr;
+ }
+
return( tmp );
}
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 5c30380..bda9262 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -254,6 +254,8 @@
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+ int (*f_rng_blind)(void *, unsigned char *, size_t),
+ void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret, key_tries, sign_tries;
@@ -323,7 +325,9 @@
mul:
#endif
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G,
- f_rng, p_rng, ECDSA_RS_ECP ) );
+ f_rng_blind,
+ p_rng_blind,
+ ECDSA_RS_ECP ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) );
}
while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 );
@@ -349,7 +353,8 @@
* Generate a random value to blind inv_mod in next step,
* avoiding a potential timing leak.
*/
- MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng_blind,
+ p_rng_blind ) );
/*
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
@@ -406,8 +411,9 @@
ECDSA_VALIDATE_RET( f_rng != NULL );
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+ /* Use the same RNG for both blinding and ephemeral key generation */
return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
- f_rng, p_rng, NULL ) );
+ f_rng, p_rng, f_rng, p_rng, NULL ) );
}
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
@@ -419,6 +425,8 @@
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
+ int (*f_rng_blind)(void *, unsigned char *, size_t),
+ void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret;
@@ -465,8 +473,69 @@
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, p_rng );
#else
- ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
- mbedtls_hmac_drbg_random, p_rng, rs_ctx );
+ if( f_rng_blind != NULL )
+ ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
+ mbedtls_hmac_drbg_random, p_rng,
+ f_rng_blind, p_rng_blind, rs_ctx );
+ else
+ {
+ mbedtls_hmac_drbg_context *p_rng_blind_det;
+
+#if !defined(MBEDTLS_ECP_RESTARTABLE)
+ /*
+ * To avoid reusing rng_ctx and risking incorrect behavior we seed a
+ * second HMAC-DRBG with the same seed. We also apply a label to avoid
+ * reusing the bits of the ephemeral key for blinding and eliminate the
+ * risk that they leak this way.
+ */
+ const char* blind_label = "BLINDING CONTEXT";
+ mbedtls_hmac_drbg_context rng_ctx_blind;
+
+ mbedtls_hmac_drbg_init( &rng_ctx_blind );
+ p_rng_blind_det = &rng_ctx_blind;
+ mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info,
+ data, 2 * grp_len );
+ ret = mbedtls_hmac_drbg_update_ret( p_rng_blind_det,
+ (const unsigned char*) blind_label,
+ strlen( blind_label ) );
+ if( ret != 0 )
+ {
+ mbedtls_hmac_drbg_free( &rng_ctx_blind );
+ goto cleanup;
+ }
+#else
+ /*
+ * In the case of restartable computations we would either need to store
+ * the second RNG in the restart context too or set it up at every
+ * restart. The first option would penalize the correct application of
+ * the function and the second would defeat the purpose of the
+ * restartable feature.
+ *
+ * Therefore in this case we reuse the original RNG. This comes with the
+ * price that the resulting signature might not be a valid deterministic
+ * ECDSA signature with a very low probability (same magnitude as
+ * successfully guessing the private key). However even then it is still
+ * a valid ECDSA signature.
+ */
+ p_rng_blind_det = p_rng;
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+ /*
+ * Since the output of the RNGs is always the same for the same key and
+ * message, this limits the efficiency of blinding and leaks information
+ * through side channels. After mbedtls_ecdsa_sign_det() is removed NULL
+ * won't be a valid value for f_rng_blind anymore. Therefore it should
+ * be checked by the caller and this branch and check can be removed.
+ */
+ ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
+ mbedtls_hmac_drbg_random, p_rng,
+ mbedtls_hmac_drbg_random, p_rng_blind_det,
+ rs_ctx );
+
+#if !defined(MBEDTLS_ECP_RESTARTABLE)
+ mbedtls_hmac_drbg_free( &rng_ctx_blind );
+#endif
+ }
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
cleanup:
@@ -479,11 +548,14 @@
}
/*
- * Deterministic signature wrapper
+ * Deterministic signature wrappers
*/
-int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
- const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
- mbedtls_md_type_t md_alg )
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+ mbedtls_mpi *s, const mbedtls_mpi *d,
+ const unsigned char *buf, size_t blen,
+ mbedtls_md_type_t md_alg )
{
ECDSA_VALIDATE_RET( grp != NULL );
ECDSA_VALIDATE_RET( r != NULL );
@@ -491,7 +563,28 @@
ECDSA_VALIDATE_RET( d != NULL );
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
- return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) );
+ return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
+ NULL, NULL, NULL ) );
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+ mbedtls_mpi *s, const mbedtls_mpi *d,
+ const unsigned char *buf, size_t blen,
+ mbedtls_md_type_t md_alg,
+ int (*f_rng_blind)(void *, unsigned char *,
+ size_t),
+ void *p_rng_blind )
+{
+ ECDSA_VALIDATE_RET( grp != NULL );
+ ECDSA_VALIDATE_RET( r != NULL );
+ ECDSA_VALIDATE_RET( s != NULL );
+ ECDSA_VALIDATE_RET( d != NULL );
+ ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+ ECDSA_VALIDATE_RET( f_rng_blind != NULL );
+
+ return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
+ f_rng_blind, p_rng_blind, NULL ) );
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@@ -670,11 +763,9 @@
mbedtls_mpi_init( &s );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
- (void) f_rng;
- (void) p_rng;
-
MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d,
- hash, hlen, md_alg, rs_ctx ) );
+ hash, hlen, md_alg, f_rng,
+ p_rng, rs_ctx ) );
#else
(void) md_alg;
@@ -682,8 +773,10 @@
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, f_rng, p_rng ) );
#else
+ /* Use the same RNG for both blinding and ephemeral key generation */
MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d,
- hash, hlen, f_rng, p_rng, rs_ctx ) );
+ hash, hlen, f_rng, p_rng, f_rng,
+ p_rng, rs_ctx ) );
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
diff --git a/library/ecjpake.c b/library/ecjpake.c
index b276514..1845c93 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -226,7 +226,7 @@
p += id_len;
/* Compute hash */
- mbedtls_md( md_info, buf, p - buf, hash );
+ MBEDTLS_MPI_CHK( mbedtls_md( md_info, buf, p - buf, hash ) );
/* Turn it into an integer mod n */
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 282481d..dcc7073 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -836,7 +836,7 @@
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
default:
- mbedtls_ecp_group_free( grp );
+ grp->id = MBEDTLS_ECP_DP_NONE;
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
}
}
diff --git a/library/md.c b/library/md.c
index ac8fac5..e1b5183 100644
--- a/library/md.c
+++ b/library/md.c
@@ -35,6 +35,14 @@
#include "mbedtls/md_internal.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/md2.h"
+#include "mbedtls/md4.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/ripemd160.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -49,6 +57,83 @@
#include <stdio.h>
#endif
+#if defined(MBEDTLS_MD2_C)
+const mbedtls_md_info_t mbedtls_md2_info = {
+ "MD2",
+ MBEDTLS_MD_MD2,
+ 16,
+ 16,
+};
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+const mbedtls_md_info_t mbedtls_md4_info = {
+ "MD4",
+ MBEDTLS_MD_MD4,
+ 16,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+const mbedtls_md_info_t mbedtls_md5_info = {
+ "MD5",
+ MBEDTLS_MD_MD5,
+ 16,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+const mbedtls_md_info_t mbedtls_ripemd160_info = {
+ "RIPEMD160",
+ MBEDTLS_MD_RIPEMD160,
+ 20,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+const mbedtls_md_info_t mbedtls_sha1_info = {
+ "SHA1",
+ MBEDTLS_MD_SHA1,
+ 20,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+const mbedtls_md_info_t mbedtls_sha224_info = {
+ "SHA224",
+ MBEDTLS_MD_SHA224,
+ 28,
+ 64,
+};
+
+const mbedtls_md_info_t mbedtls_sha256_info = {
+ "SHA256",
+ MBEDTLS_MD_SHA256,
+ 32,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+const mbedtls_md_info_t mbedtls_sha384_info = {
+ "SHA384",
+ MBEDTLS_MD_SHA384,
+ 48,
+ 128,
+};
+
+const mbedtls_md_info_t mbedtls_sha512_info = {
+ "SHA512",
+ MBEDTLS_MD_SHA512,
+ 64,
+ 128,
+};
+#endif
+
/*
* Reminder: update profiles in Mbed TLS's x509_crt.c when adding a new hash!
*/
@@ -185,7 +270,52 @@
return;
if( ctx->md_ctx != NULL )
- ctx->md_info->ctx_free_func( ctx->md_ctx );
+ {
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ mbedtls_md2_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ mbedtls_md4_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ mbedtls_md5_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ mbedtls_ripemd160_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ mbedtls_sha1_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ mbedtls_sha256_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ case MBEDTLS_MD_SHA512:
+ mbedtls_sha512_free( ctx->md_ctx );
+ break;
+#endif
+ default:
+ /* Shouldn't happen */
+ break;
+ }
+ mbedtls_free( ctx->md_ctx );
+ }
if( ctx->hmac_ctx != NULL )
{
@@ -207,7 +337,48 @@
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
}
- dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
+ switch( src->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ mbedtls_md2_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ mbedtls_md4_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ case MBEDTLS_MD_SHA512:
+ mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
return( 0 );
}
@@ -219,20 +390,69 @@
}
#endif
+#define ALLOC( type ) \
+ do { \
+ ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
+ if( ctx->md_ctx == NULL ) \
+ return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \
+ mbedtls_##type##_init( ctx->md_ctx ); \
+ } \
+ while( 0 )
+
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
{
if( md_info == NULL || ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
- return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+ switch( md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ ALLOC( md2 );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ ALLOC( md4 );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ ALLOC( md5 );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ ALLOC( ripemd160 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ ALLOC( sha1 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ ALLOC( sha256 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ case MBEDTLS_MD_SHA512:
+ ALLOC( sha512 );
+ break;
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
if( hmac != 0 )
{
ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
if( ctx->hmac_ctx == NULL )
{
- md_info->ctx_free_func( ctx->md_ctx );
+ mbedtls_md_free( ctx );
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
}
}
@@ -241,13 +461,50 @@
return( 0 );
}
+#undef ALLOC
int mbedtls_md_starts( mbedtls_md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->starts_func( ctx->md_ctx ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@@ -255,7 +512,43 @@
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@@ -263,7 +556,43 @@
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
@@ -272,7 +601,43 @@
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( md_info->digest_func( input, ilen, output ) );
+ switch( md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
#if defined(MBEDTLS_FS_IO)
@@ -295,17 +660,17 @@
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
goto cleanup;
- if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
goto cleanup;
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
- if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
+ if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
goto cleanup;
if( ferror( f ) != 0 )
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
else
- ret = md_info->finish_func( ctx.md_ctx, output );
+ ret = mbedtls_md_finish( &ctx, output );
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -328,11 +693,11 @@
if( keylen > (size_t) ctx->md_info->block_size )
{
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
goto cleanup;
keylen = ctx->md_info->size;
@@ -351,10 +716,10 @@
opad[i] = (unsigned char)( opad[i] ^ key[i] );
}
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
- ctx->md_info->block_size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, ipad,
+ ctx->md_info->block_size ) ) != 0 )
goto cleanup;
cleanup:
@@ -368,7 +733,7 @@
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+ return( mbedtls_md_update( ctx, input, ilen ) );
}
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@@ -382,17 +747,17 @@
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
- if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
- ctx->md_info->block_size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, opad,
+ ctx->md_info->block_size ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
- ctx->md_info->size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, tmp,
+ ctx->md_info->size ) ) != 0 )
return( ret );
- return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+ return( mbedtls_md_finish( ctx, output ) );
}
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
@@ -405,10 +770,9 @@
ipad = (unsigned char *) ctx->hmac_ctx;
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
return( ret );
- return( ctx->md_info->update_func( ctx->md_ctx, ipad,
- ctx->md_info->block_size ) );
+ return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
}
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
@@ -445,7 +809,43 @@
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->process_func( ctx->md_ctx, data ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_internal_md2_process( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_internal_md4_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
diff --git a/library/md_wrap.c b/library/md_wrap.c
deleted file mode 100644
index 32f0871..0000000
--- a/library/md_wrap.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/**
- * \file md_wrap.c
- *
- * \brief Generic message digest wrapper for mbed TLS
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_MD_C)
-
-#include "mbedtls/md_internal.h"
-
-#if defined(MBEDTLS_MD2_C)
-#include "mbedtls/md2.h"
-#endif
-
-#if defined(MBEDTLS_MD4_C)
-#include "mbedtls/md4.h"
-#endif
-
-#if defined(MBEDTLS_MD5_C)
-#include "mbedtls/md5.h"
-#endif
-
-#if defined(MBEDTLS_RIPEMD160_C)
-#include "mbedtls/ripemd160.h"
-#endif
-
-#if defined(MBEDTLS_SHA1_C)
-#include "mbedtls/sha1.h"
-#endif
-
-#if defined(MBEDTLS_SHA256_C)
-#include "mbedtls/sha256.h"
-#endif
-
-#if defined(MBEDTLS_SHA512_C)
-#include "mbedtls/sha512.h"
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#endif
-
-#if defined(MBEDTLS_MD2_C)
-
-static int md2_starts_wrap( void *ctx )
-{
- return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
-}
-
-static int md2_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
-}
-
-static int md2_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
-}
-
-static void *md2_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) );
-
- if( ctx != NULL )
- mbedtls_md2_init( (mbedtls_md2_context *) ctx );
-
- return( ctx );
-}
-
-static void md2_ctx_free( void *ctx )
-{
- mbedtls_md2_free( (mbedtls_md2_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md2_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md2_clone( (mbedtls_md2_context *) dst,
- (const mbedtls_md2_context *) src );
-}
-
-static int md2_process_wrap( void *ctx, const unsigned char *data )
-{
- ((void) data);
-
- return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
-}
-
-const mbedtls_md_info_t mbedtls_md2_info = {
- MBEDTLS_MD_MD2,
- "MD2",
- 16,
- 16,
- md2_starts_wrap,
- md2_update_wrap,
- md2_finish_wrap,
- mbedtls_md2_ret,
- md2_ctx_alloc,
- md2_ctx_free,
- md2_clone_wrap,
- md2_process_wrap,
-};
-
-#endif /* MBEDTLS_MD2_C */
-
-#if defined(MBEDTLS_MD4_C)
-
-static int md4_starts_wrap( void *ctx )
-{
- return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
-}
-
-static int md4_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
-}
-
-static int md4_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
-}
-
-static void *md4_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) );
-
- if( ctx != NULL )
- mbedtls_md4_init( (mbedtls_md4_context *) ctx );
-
- return( ctx );
-}
-
-static void md4_ctx_free( void *ctx )
-{
- mbedtls_md4_free( (mbedtls_md4_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md4_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md4_clone( (mbedtls_md4_context *) dst,
- (const mbedtls_md4_context *) src );
-}
-
-static int md4_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_md4_info = {
- MBEDTLS_MD_MD4,
- "MD4",
- 16,
- 64,
- md4_starts_wrap,
- md4_update_wrap,
- md4_finish_wrap,
- mbedtls_md4_ret,
- md4_ctx_alloc,
- md4_ctx_free,
- md4_clone_wrap,
- md4_process_wrap,
-};
-
-#endif /* MBEDTLS_MD4_C */
-
-#if defined(MBEDTLS_MD5_C)
-
-static int md5_starts_wrap( void *ctx )
-{
- return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
-}
-
-static int md5_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
-}
-
-static int md5_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
-}
-
-static void *md5_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) );
-
- if( ctx != NULL )
- mbedtls_md5_init( (mbedtls_md5_context *) ctx );
-
- return( ctx );
-}
-
-static void md5_ctx_free( void *ctx )
-{
- mbedtls_md5_free( (mbedtls_md5_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md5_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md5_clone( (mbedtls_md5_context *) dst,
- (const mbedtls_md5_context *) src );
-}
-
-static int md5_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_md5_info = {
- MBEDTLS_MD_MD5,
- "MD5",
- 16,
- 64,
- md5_starts_wrap,
- md5_update_wrap,
- md5_finish_wrap,
- mbedtls_md5_ret,
- md5_ctx_alloc,
- md5_ctx_free,
- md5_clone_wrap,
- md5_process_wrap,
-};
-
-#endif /* MBEDTLS_MD5_C */
-
-#if defined(MBEDTLS_RIPEMD160_C)
-
-static int ripemd160_starts_wrap( void *ctx )
-{
- return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
-}
-
-static int ripemd160_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
- input, ilen ) );
-}
-
-static int ripemd160_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
- output ) );
-}
-
-static void *ripemd160_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) );
-
- if( ctx != NULL )
- mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx );
-
- return( ctx );
-}
-
-static void ripemd160_ctx_free( void *ctx )
-{
- mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void ripemd160_clone_wrap( void *dst, const void *src )
-{
- mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst,
- (const mbedtls_ripemd160_context *) src );
-}
-
-static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_ripemd160_process(
- (mbedtls_ripemd160_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_ripemd160_info = {
- MBEDTLS_MD_RIPEMD160,
- "RIPEMD160",
- 20,
- 64,
- ripemd160_starts_wrap,
- ripemd160_update_wrap,
- ripemd160_finish_wrap,
- mbedtls_ripemd160_ret,
- ripemd160_ctx_alloc,
- ripemd160_ctx_free,
- ripemd160_clone_wrap,
- ripemd160_process_wrap,
-};
-
-#endif /* MBEDTLS_RIPEMD160_C */
-
-#if defined(MBEDTLS_SHA1_C)
-
-static int sha1_starts_wrap( void *ctx )
-{
- return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
-}
-
-static int sha1_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
- input, ilen ) );
-}
-
-static int sha1_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
-}
-
-static void *sha1_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) );
-
- if( ctx != NULL )
- mbedtls_sha1_init( (mbedtls_sha1_context *) ctx );
-
- return( ctx );
-}
-
-static void sha1_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha1_clone( (mbedtls_sha1_context *) dst,
- (const mbedtls_sha1_context *) src );
-}
-
-static void sha1_ctx_free( void *ctx )
-{
- mbedtls_sha1_free( (mbedtls_sha1_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static int sha1_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha1_info = {
- MBEDTLS_MD_SHA1,
- "SHA1",
- 20,
- 64,
- sha1_starts_wrap,
- sha1_update_wrap,
- sha1_finish_wrap,
- mbedtls_sha1_ret,
- sha1_ctx_alloc,
- sha1_ctx_free,
- sha1_clone_wrap,
- sha1_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA1_C */
-
-/*
- * Wrappers for generic message digests
- */
-#if defined(MBEDTLS_SHA256_C)
-
-static int sha224_starts_wrap( void *ctx )
-{
- return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
-}
-
-static int sha224_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
- input, ilen ) );
-}
-
-static int sha224_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
- output ) );
-}
-
-static int sha224_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
-}
-
-static void *sha224_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
-
- if( ctx != NULL )
- mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
-
- return( ctx );
-}
-
-static void sha224_ctx_free( void *ctx )
-{
- mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void sha224_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
- (const mbedtls_sha256_context *) src );
-}
-
-static int sha224_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha224_info = {
- MBEDTLS_MD_SHA224,
- "SHA224",
- 28,
- 64,
- sha224_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha224_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
-};
-
-static int sha256_starts_wrap( void *ctx )
-{
- return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
-}
-
-static int sha256_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha256_info = {
- MBEDTLS_MD_SHA256,
- "SHA256",
- 32,
- 64,
- sha256_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha256_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA512_C)
-
-static int sha384_starts_wrap( void *ctx )
-{
- return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
-}
-
-static int sha384_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
- input, ilen ) );
-}
-
-static int sha384_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
- output ) );
-}
-
-static int sha384_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
-}
-
-static void *sha384_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) );
-
- if( ctx != NULL )
- mbedtls_sha512_init( (mbedtls_sha512_context *) ctx );
-
- return( ctx );
-}
-
-static void sha384_ctx_free( void *ctx )
-{
- mbedtls_sha512_free( (mbedtls_sha512_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void sha384_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha512_clone( (mbedtls_sha512_context *) dst,
- (const mbedtls_sha512_context *) src );
-}
-
-static int sha384_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha384_info = {
- MBEDTLS_MD_SHA384,
- "SHA384",
- 48,
- 128,
- sha384_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha384_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
-};
-
-static int sha512_starts_wrap( void *ctx )
-{
- return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
-}
-
-static int sha512_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha512_info = {
- MBEDTLS_MD_SHA512,
- "SHA512",
- 64,
- 128,
- sha512_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha512_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA512_C */
-
-#endif /* MBEDTLS_MD_C */
diff --git a/library/platform_util.c b/library/platform_util.c
index 756e226..b1f7450 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -72,7 +72,10 @@
void mbedtls_platform_zeroize( void *buf, size_t len )
{
- memset_func( buf, 0, len );
+ MBEDTLS_INTERNAL_VALIDATE( len == 0 || buf != NULL );
+
+ if( len > 0 )
+ memset_func( buf, 0, len );
}
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index ef2d50e..fe737d2 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -451,13 +451,6 @@
switch( type )
{
case PSA_KEY_TYPE_RAW_DATA:
- if( bits == 0 )
- {
- raw->bytes = 0;
- raw->data = NULL;
- return( PSA_SUCCESS );
- }
- break;
#if defined(MBEDTLS_MD_C)
case PSA_KEY_TYPE_HMAC:
#endif
@@ -1281,6 +1274,12 @@
if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
return( PSA_ERROR_INVALID_ARGUMENT );
+ /* Reject a zero-length output buffer now, since this can never be a
+ * valid key representation. This way we know that data must be a valid
+ * pointer and we can do things like memset(data, ..., data_size). */
+ if( data_size == 0 )
+ return( PSA_ERROR_BUFFER_TOO_SMALL );
+
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
{
@@ -1302,12 +1301,9 @@
{
if( slot->data.raw.bytes > data_size )
return( PSA_ERROR_BUFFER_TOO_SMALL );
- if( data_size != 0 )
- {
- memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
- memset( data + slot->data.raw.bytes, 0,
- data_size - slot->data.raw.bytes );
- }
+ memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
+ memset( data + slot->data.raw.bytes, 0,
+ data_size - slot->data.raw.bytes );
*data_length = slot->data.raw.bytes;
return( PSA_SUCCESS );
}
@@ -1366,10 +1362,7 @@
}
if( ret < 0 )
{
- /* If data_size is 0 then data may be NULL and then the
- * call to memset would have undefined behavior. */
- if( data_size != 0 )
- memset( data, 0, data_size );
+ memset( data, 0, data_size );
return( mbedtls_to_psa_error( ret ) );
}
/* The mbedtls_pk_xxx functions write to the end of the buffer.
@@ -1676,7 +1669,7 @@
slot->attr.bits );
uint8_t *buffer = mbedtls_calloc( 1, buffer_size );
size_t length = 0;
- if( buffer == NULL && buffer_size != 0 )
+ if( buffer == NULL )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
status = psa_internal_export_key( slot,
buffer, buffer_size, &length,
@@ -1685,8 +1678,7 @@
status = psa_save_persistent_key( &slot->attr,
buffer, length );
- if( buffer_size != 0 )
- mbedtls_platform_zeroize( buffer, buffer_size );
+ mbedtls_platform_zeroize( buffer, buffer_size );
mbedtls_free( buffer );
}
}
@@ -1826,6 +1818,12 @@
psa_key_slot_t *slot = NULL;
psa_se_drv_table_entry_t *driver = NULL;
+ /* Reject zero-length symmetric keys (including raw data key objects).
+ * This also rejects any key which might be encoded as an empty string,
+ * which is never valid. */
+ if( data_length == 0 )
+ return( PSA_ERROR_INVALID_ARGUMENT );
+
status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes,
handle, &slot, &driver );
if( status != PSA_SUCCESS )
@@ -1957,7 +1955,7 @@
buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->attr.type,
psa_get_key_slot_bits( source ) );
buffer = mbedtls_calloc( 1, buffer_size );
- if( buffer == NULL && buffer_size != 0 )
+ if( buffer == NULL )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 );
if( status != PSA_SUCCESS )
@@ -1966,8 +1964,7 @@
status = psa_import_key_into_slot( target, buffer, length );
exit:
- if( buffer_size != 0 )
- mbedtls_platform_zeroize( buffer, buffer_size );
+ mbedtls_platform_zeroize( buffer, buffer_size );
mbedtls_free( buffer );
return( status );
}
@@ -2735,7 +2732,7 @@
status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
cleanup:
- mbedtls_platform_zeroize( ipad, key_length );
+ mbedtls_platform_zeroize( ipad, sizeof(ipad) );
return( status );
}
@@ -3194,8 +3191,8 @@
if( status != PSA_SUCCESS )
return( status );
- if( signature_length < mbedtls_rsa_get_len( rsa ) )
- return( PSA_ERROR_BUFFER_TOO_SMALL );
+ if( signature_length != mbedtls_rsa_get_len( rsa ) )
+ return( PSA_ERROR_INVALID_SIGNATURE );
#if defined(MBEDTLS_PKCS1_V15)
if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
@@ -3271,9 +3268,11 @@
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
- MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
- hash, hash_length,
- md_alg ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det_ext( &ecp->grp, &r, &s,
+ &ecp->d, hash,
+ hash_length, md_alg,
+ mbedtls_ctr_drbg_random,
+ &global_data.ctr_drbg ) );
}
else
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@@ -3348,6 +3347,12 @@
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
*signature_length = signature_size;
+ /* Immediately reject a zero-length signature buffer. This guarantees
+ * that signature must be a valid pointer. (On the other hand, the hash
+ * buffer can in principle be empty since it doesn't actually have
+ * to be a hash.) */
+ if( signature_size == 0 )
+ return( PSA_ERROR_BUFFER_TOO_SMALL );
status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
if( status != PSA_SUCCESS )
@@ -3423,7 +3428,7 @@
if( status == PSA_SUCCESS )
memset( signature + *signature_length, '!',
signature_size - *signature_length );
- else if( signature_size != 0 )
+ else
memset( signature, '!', signature_size );
/* If signature_size is 0 then we have nothing to do. We must not call
* memset because signature may be NULL in this case. */
@@ -4776,6 +4781,12 @@
psa_status_t status;
psa_key_slot_t *slot = NULL;
psa_se_drv_table_entry_t *driver = NULL;
+
+ /* Reject any attempt to create a zero-length key so that we don't
+ * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
+ if( psa_get_key_bits( attributes ) == 0 )
+ return( PSA_ERROR_INVALID_ARGUMENT );
+
status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE,
attributes, handle, &slot, &driver );
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@@ -5510,6 +5521,11 @@
psa_key_slot_t *slot = NULL;
psa_se_drv_table_entry_t *driver = NULL;
+ /* Reject any attempt to create a zero-length key so that we don't
+ * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
+ if( psa_get_key_bits( attributes ) == 0 )
+ return( PSA_ERROR_INVALID_ARGUMENT );
+
status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE,
attributes, handle, &slot, &driver );
if( status != PSA_SUCCESS )
diff --git a/library/psa_its_file.c b/library/psa_its_file.c
index 05ca8af..0935b27 100644
--- a/library/psa_its_file.c
+++ b/library/psa_its_file.c
@@ -214,9 +214,12 @@
n = fwrite( &header, 1, sizeof( header ), stream );
if( n != sizeof( header ) )
goto exit;
- n = fwrite( p_data, 1, data_length, stream );
- if( n != data_length )
- goto exit;
+ if( data_length != 0 )
+ {
+ n = fwrite( p_data, 1, data_length, stream );
+ if( n != data_length )
+ goto exit;
+ }
status = PSA_SUCCESS;
exit:
diff --git a/tests/.gitignore b/tests/.gitignore
index 3c9b0cf..fbbd0df 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -7,3 +7,5 @@
data_files/hmac_drbg_seed
data_files/ctr_drbg_seed
data_files/entropy_seed
+
+/instrument_record_status.h
diff --git a/tests/Makefile b/tests/Makefile
index 4eb9142..f7505b6 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -28,6 +28,10 @@
LOCAL_CFLAGS += -g3
endif
+ifdef RECORD_PSA_STATUS_COVERAGE_LOG
+LOCAL_CFLAGS += -Werror -DRECORD_PSA_STATUS_COVERAGE_LOG
+endif
+
# if we're running on Windows, build for Windows
ifdef WINDOWS
WINDOWS_BUILD=1
@@ -163,3 +167,9 @@
endef
$(foreach app, $(APPS), $(foreach file, $(wildcard *.h), \
$(eval $(call copy_header_to_target,$(app),$(file)))))
+
+ifdef RECORD_PSA_STATUS_COVERAGE_LOG
+$(BINARIES): instrument_record_status.h
+instrument_record_status.h: ../include/psa/crypto.h Makefile
+ sed <../include/psa/crypto.h >$@ -n 's/^psa_status_t \([A-Za-z0-9_]*\)(.*/#define \1(...) RECORD_STATUS("\1", \1(__VA_ARGS__))/p'
+endif
diff --git a/tests/psa_crypto_helpers.h b/tests/psa_crypto_helpers.h
index 3780d16..19303de 100644
--- a/tests/psa_crypto_helpers.h
+++ b/tests/psa_crypto_helpers.h
@@ -72,4 +72,59 @@
*/
#define PSA_DONE( ) test_helper_psa_done( __LINE__, __FILE__ )
+
+
+#if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
+#include <psa/crypto.h>
+
+/** Name of the file where return statuses are logged by #RECORD_STATUS. */
+#define STATUS_LOG_FILE_NAME "statuses.log"
+
+static psa_status_t record_status( psa_status_t status,
+ const char *func,
+ const char *file, int line,
+ const char *expr )
+{
+ /* We open the log file on first use.
+ * We never close the log file, so the record_status feature is not
+ * compatible with resource leak detectors such as Asan.
+ */
+ static FILE *log;
+ if( log == NULL )
+ log = fopen( STATUS_LOG_FILE_NAME, "a" );
+ fprintf( log, "%d:%s:%s:%d:%s\n", (int) status, func, file, line, expr );
+ return( status );
+}
+
+/** Return value logging wrapper macro.
+ *
+ * Evaluate \p expr. Write a line recording its value to the log file
+ * #STATUS_LOG_FILE_NAME and return the value. The line is a colon-separated
+ * list of fields:
+ * ```
+ * value of expr:string:__FILE__:__LINE__:expr
+ * ```
+ *
+ * The test code does not call this macro explicitly because that would
+ * be very invasive. Instead, we instrument the source code by defining
+ * a bunch of wrapper macros like
+ * ```
+ * #define psa_crypto_init() RECORD_STATUS("psa_crypto_init", psa_crypto_init())
+ * ```
+ * These macro definitions must be present in `instrument_record_status.h`
+ * when building the test suites.
+ *
+ * \param string A string, normally a function name.
+ * \param expr An expression to evaluate, normally a call of the function
+ * whose name is in \p string. This expression must return
+ * a value of type #psa_status_t.
+ * \return The value of \p expr.
+ */
+#define RECORD_STATUS( string, expr ) \
+ record_status( ( expr ), string, __FILE__, __LINE__, #expr )
+
+#include "instrument_record_status.h"
+
+#endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */
+
#endif /* PSA_CRYPTO_HELPERS_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 244fdc3..e3a8c0e 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -629,6 +629,16 @@
make test
}
+component_test_psa_collect_statuses () {
+ msg "build+test: psa_collect_statuses" # ~30s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # slow and irrelevant
+ record_status tests/scripts/psa_collect_statuses.py
+ # Check that psa_crypto_init() succeeded at least once
+ record_status grep -q '^0:psa_crypto_init:' tests/statuses.log
+ rm -f tests/statuses.log
+}
+
component_test_full_cmake_clang () {
msg "build: cmake, full config, clang" # ~ 50s
scripts/config.pl full
@@ -701,7 +711,7 @@
# full minus MBEDTLS_USE_PSA_CRYPTO: run the same set of tests as basic-build-test.sh
msg "build: cmake, full config + MBEDTLS_USE_PSA_CRYPTO, ASan"
scripts/config.pl full
- scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
scripts/config.pl set MBEDTLS_ECP_RESTARTABLE # not using PSA, so enable restartable ECC
scripts/config.pl set MBEDTLS_PSA_CRYPTO_C
scripts/config.pl unset MBEDTLS_USE_PSA_CRYPTO
diff --git a/tests/scripts/psa_collect_statuses.py b/tests/scripts/psa_collect_statuses.py
new file mode 100755
index 0000000..e38beea
--- /dev/null
+++ b/tests/scripts/psa_collect_statuses.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python3
+"""Describe the test coverage of PSA functions in terms of return statuses.
+
+1. Build Mbed Crypto with -DRECORD_PSA_STATUS_COVERAGE_LOG
+2. Run psa_collect_statuses.py
+
+The output is a series of line of the form "psa_foo PSA_ERROR_XXX". Each
+function/status combination appears only once.
+
+This script must be run from the top of an Mbed Crypto source tree.
+The build command is "make -DRECORD_PSA_STATUS_COVERAGE_LOG", which is
+only supported with make (as opposed to CMake or other build methods).
+"""
+
+import argparse
+import os
+import subprocess
+import sys
+
+DEFAULT_STATUS_LOG_FILE = 'tests/statuses.log'
+DEFAULT_PSA_CONSTANT_NAMES = 'programs/psa/psa_constant_names'
+
+class Statuses:
+ """Information about observed return statues of API functions."""
+
+ def __init__(self):
+ self.functions = {}
+ self.codes = set()
+ self.status_names = {}
+
+ def collect_log(self, log_file_name):
+ """Read logs from RECORD_PSA_STATUS_COVERAGE_LOG.
+
+ Read logs produced by running Mbed Crypto test suites built with
+ -DRECORD_PSA_STATUS_COVERAGE_LOG.
+ """
+ with open(log_file_name) as log:
+ for line in log:
+ value, function, tail = line.split(':', 2)
+ if function not in self.functions:
+ self.functions[function] = {}
+ fdata = self.functions[function]
+ if value not in self.functions[function]:
+ fdata[value] = []
+ fdata[value].append(tail)
+ self.codes.add(int(value))
+
+ def get_constant_names(self, psa_constant_names):
+ """Run psa_constant_names to obtain names for observed numerical values."""
+ values = [str(value) for value in self.codes]
+ cmd = [psa_constant_names, 'status'] + values
+ output = subprocess.check_output(cmd).decode('ascii')
+ for value, name in zip(values, output.rstrip().split('\n')):
+ self.status_names[value] = name
+
+ def report(self):
+ """Report observed return values for each function.
+
+ The report is a series of line of the form "psa_foo PSA_ERROR_XXX".
+ """
+ for function in sorted(self.functions.keys()):
+ fdata = self.functions[function]
+ names = [self.status_names[value] for value in fdata.keys()]
+ for name in sorted(names):
+ sys.stdout.write('{} {}\n'.format(function, name))
+
+def collect_status_logs(options):
+ """Build and run unit tests and report observed function return statuses.
+
+ Build Mbed Crypto with -DRECORD_PSA_STATUS_COVERAGE_LOG, run the
+ test suites and display information about observed return statuses.
+ """
+ rebuilt = False
+ if not options.use_existing_log and os.path.exists(options.log_file):
+ os.remove(options.log_file)
+ if not os.path.exists(options.log_file):
+ if options.clean_before:
+ subprocess.check_call(['make', 'clean'],
+ cwd='tests',
+ stdout=sys.stderr)
+ with open(os.devnull, 'w') as devnull:
+ make_q_ret = subprocess.call(['make', '-q', 'lib', 'tests'],
+ stdout=devnull, stderr=devnull)
+ if make_q_ret != 0:
+ subprocess.check_call(['make', 'RECORD_PSA_STATUS_COVERAGE_LOG=1'],
+ stdout=sys.stderr)
+ rebuilt = True
+ subprocess.check_call(['make', 'test'],
+ stdout=sys.stderr)
+ data = Statuses()
+ data.collect_log(options.log_file)
+ data.get_constant_names(options.psa_constant_names)
+ if rebuilt and options.clean_after:
+ subprocess.check_call(['make', 'clean'],
+ cwd='tests',
+ stdout=sys.stderr)
+ return data
+
+def main():
+ parser = argparse.ArgumentParser(description=globals()['__doc__'])
+ parser.add_argument('--clean-after',
+ action='store_true',
+ help='Run "make clean" after rebuilding')
+ parser.add_argument('--clean-before',
+ action='store_true',
+ help='Run "make clean" before regenerating the log file)')
+ parser.add_argument('--log-file', metavar='FILE',
+ default=DEFAULT_STATUS_LOG_FILE,
+ help='Log file location (default: {})'.format(
+ DEFAULT_STATUS_LOG_FILE
+ ))
+ parser.add_argument('--psa-constant-names', metavar='PROGRAM',
+ default=DEFAULT_PSA_CONSTANT_NAMES,
+ help='Path to psa_constant_names (default: {})'.format(
+ DEFAULT_PSA_CONSTANT_NAMES
+ ))
+ parser.add_argument('--use-existing-log', '-e',
+ action='store_true',
+ help='Don\'t regenerate the log file if it exists')
+ options = parser.parse_args()
+ data = collect_status_logs(options)
+ data.report()
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index 22d92b6..ab3db3a 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -55,25 +55,30 @@
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
- mbedtls_ecdsa_sign_det( NULL, &m, &m, &m,
- buf, sizeof( buf ),
- valid_md ) );
+ mbedtls_ecdsa_sign_det_ext( NULL, &m, &m, &m,
+ buf, sizeof( buf ),
+ valid_md,
+ rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
- mbedtls_ecdsa_sign_det( &grp, NULL, &m, &m,
- buf, sizeof( buf ),
- valid_md ) );
+ mbedtls_ecdsa_sign_det_ext( &grp, NULL, &m, &m,
+ buf, sizeof( buf ),
+ valid_md,
+ rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
- mbedtls_ecdsa_sign_det( &grp, &m, NULL, &m,
- buf, sizeof( buf ),
- valid_md ) );
+ mbedtls_ecdsa_sign_det_ext( &grp, &m, NULL, &m,
+ buf, sizeof( buf ),
+ valid_md,
+ rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
- mbedtls_ecdsa_sign_det( &grp, &m, &m, NULL,
- buf, sizeof( buf ),
- valid_md ) );
+ mbedtls_ecdsa_sign_det_ext( &grp, &m, &m, NULL,
+ buf, sizeof( buf ),
+ valid_md,
+ rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
- mbedtls_ecdsa_sign_det( &grp, &m, &m, &m,
- NULL, sizeof( buf ),
- valid_md ) );
+ mbedtls_ecdsa_sign_det_ext( &grp, &m, &m, &m,
+ NULL, sizeof( buf ),
+ valid_md,
+ rnd_std_rand, NULL ) );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
@@ -325,7 +330,10 @@
TEST_ASSERT( mbedtls_md( md_info, (const unsigned char *) msg,
strlen( msg ), hash ) == 0 );
- TEST_ASSERT( mbedtls_ecdsa_sign_det( &grp, &r, &s, &d, hash, hlen, md_alg ) == 0 );
+ TEST_ASSERT(
+ mbedtls_ecdsa_sign_det_ext( &grp, &r, &s, &d, hash, hlen,
+ md_alg, rnd_std_rand, NULL )
+ == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &r, &r_check ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &s, &s_check ) == 0 );
diff --git a/tests/suites/test_suite_ecjpake.data b/tests/suites/test_suite_ecjpake.data
index 84c99c9..ffa59e5 100644
--- a/tests/suites/test_suite_ecjpake.data
+++ b/tests/suites/test_suite_ecjpake.data
@@ -4,6 +4,9 @@
ECJPAKE selftest
ecjpake_selftest:
+ECJPAKE fail read corrupt MD
+read_bad_md:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51620934d74eb43e54df424fd96306c0117bf131afabf90a9d33d1198d905193735144104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb12"
+
ECJPAKE round one: client, valid
read_round_one:MBEDTLS_ECJPAKE_CLIENT:"41047ea6e3a4487037a9e0dbd79262b2cc273e779930fc18409ac5361c5fe669d702e147790aeb4ce7fd6575ab0f6c7fd1c335939aa863ba37ec91b7e32bb013bb2b410409f85b3d20ebd7885ce464c08d056d6428fe4dd9287aa365f131f4360ff386d846898bc4b41583c2a5197f65d78742746c12a5ec0a4ffe2f270a750a1d8fb51620934d74eb43e54df424fd96306c0117bf131afabf90a9d33d1198d905193735144104190a07700ffa4be6ae1d79ee0f06aeb544cd5addaabedf70f8623321332c54f355f0fbfec783ed359e5d0bf7377a0fc4ea7ace473c9c112b41ccd41ac56a56124104360a1cea33fce641156458e0a4eac219e96831e6aebc88b3f3752f93a0281d1bf1fb106051db9694a8d6e862a5ef1324a3d9e27894f1ee4f7c59199965a8dd4a2091847d2d22df3ee55faa2a3fb33fd2d1e055a07a7c61ecfb8d80ec00c2c9eb12":0
diff --git a/tests/suites/test_suite_ecjpake.function b/tests/suites/test_suite_ecjpake.function
index d267295..38f190d 100644
--- a/tests/suites/test_suite_ecjpake.function
+++ b/tests/suites/test_suite_ecjpake.function
@@ -237,6 +237,27 @@
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */
+void read_bad_md( data_t *msg )
+{
+ mbedtls_ecjpake_context corrupt_ctx;
+ const unsigned char * pw = NULL;
+ const size_t pw_len = 0;
+ int any_role = MBEDTLS_ECJPAKE_CLIENT;
+
+ mbedtls_ecjpake_init( &corrupt_ctx );
+ TEST_ASSERT( mbedtls_ecjpake_setup( &corrupt_ctx, any_role,
+ MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, pw, pw_len ) == 0 );
+ corrupt_ctx.md_info = NULL;
+
+ TEST_ASSERT( mbedtls_ecjpake_read_round_one( &corrupt_ctx, msg->x,
+ msg->len ) == MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+exit:
+ mbedtls_ecjpake_free( &corrupt_ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */
void read_round_one( int role, data_t * msg, int ref_ret )
{
mbedtls_ecjpake_context ctx;
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 8eee989..18159e7 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -22,9 +22,6 @@
PSA key attributes: slot number
slot_number_attribute:
-PSA import/export raw: 0 bytes
-import_export:"":PSA_KEY_TYPE_RAW_DATA:PSA_KEY_USAGE_EXPORT:0:0:0:PSA_SUCCESS:1
-
PSA import/export raw: 1 bytes
import_export:"2a":PSA_KEY_TYPE_RAW_DATA:PSA_KEY_USAGE_EXPORT:0:8:0:PSA_SUCCESS:1
@@ -266,6 +263,18 @@
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C
import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b2400":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1024:0:PSA_SUCCESS:0
+PSA import: reject raw data key of length 0
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+import_with_data:"":PSA_KEY_TYPE_RAW_DATA:0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import: reject raw data key of length 0 and declared size 1 bit
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+import_with_data:"":PSA_KEY_TYPE_RAW_DATA:1:PSA_ERROR_INVALID_ARGUMENT
+
+PSA import: reject raw data key of length 0 and declared size 8 bits
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+import_with_data:"":PSA_KEY_TYPE_RAW_DATA:8:PSA_ERROR_INVALID_ARGUMENT
+
PSA import EC keypair: DER format
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
import_with_data:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT
@@ -568,8 +577,8 @@
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_ECDSA_C
key_policy_alg2:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDH:PSA_ALG_ECDSA_ANY
-Copy key: raw, 0 bytes
-copy_success:PSA_KEY_USAGE_COPY:0:0:PSA_KEY_TYPE_RAW_DATA:"":1:-1:-1:0:PSA_KEY_USAGE_COPY:0:0
+Copy key: raw, 1 byte
+copy_success:PSA_KEY_USAGE_COPY:0:0:PSA_KEY_TYPE_RAW_DATA:"2a":1:-1:-1:0:PSA_KEY_USAGE_COPY:0:0
Copy key: AES, copy attributes
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
@@ -799,6 +808,14 @@
# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_ERROR_NOT_SUPPORTED
+PSA MAC setup: algorithm known but not supported, long key
+depends_on:!MBEDTLS_MD5_C
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f":PSA_ALG_HMAC(PSA_ALG_MD5):PSA_ERROR_NOT_SUPPORTED
+
+PSA MAC setup: algorithm known but not supported, short key
+depends_on:!MBEDTLS_MD5_C
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708":PSA_ALG_HMAC(PSA_ALG_MD5):PSA_ERROR_NOT_SUPPORTED
+
PSA MAC: bad order function calls
depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
mac_bad_order:
@@ -1552,6 +1569,14 @@
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C
sign_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":63:PSA_ERROR_BUFFER_TOO_SMALL
+PSA sign: RSA PKCS#1 v1.5 SHA-256, empty output buffer
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+sign_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":0:PSA_ERROR_BUFFER_TOO_SMALL
+
+PSA sign: deterministic ECDSA SECP256R1 SHA-256, empty output buffer
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C
+sign_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":0:PSA_ERROR_BUFFER_TOO_SMALL
+
PSA sign: deterministic ECDSA SECP256R1, invalid hash algorithm (0)
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_DETERMINISTIC
sign_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( 0 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":72:PSA_ERROR_INVALID_ARGUMENT
@@ -1604,14 +1629,30 @@
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
asymmetric_verify:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311"
-PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong hash
+PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong hash length
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C
asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_1):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_ARGUMENT
-PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong signature
+PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong signature (same size)
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"111164d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_SIGNATURE
+PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong signature (empty)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong signature (truncated)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc73":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong signature (trailing junk)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc731121":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: RSA PKCS#1 v1.5 SHA-256, wrong signature (leading junk)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA256_C
+asymmetric_verify_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"21a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_SIGNATURE
+
PSA verify: RSA PSS SHA-256, good signature, 0 bytes
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
asymmetric_verify:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"34c011b625c32d992f4ab8fcfa52b616ea66270b5b75a4fc71af712f9b8806bcdd374ce50eafcbb489562b93347885f93c2de1d404c45cacccefceb112ff6ffdfe4264f91d66320bbbe09304b851b8ad6280bbccc571eebcd49c7db5dfa399a6289e1978407904598751613d9870770cdd8507e3dc7b46851dbf05ae1df2988d"
@@ -1640,6 +1681,22 @@
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_C
asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50e":PSA_ERROR_INVALID_SIGNATURE
+PSA verify: ECDSA SECP256R1, wrong signature (empty)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C
+asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: ECDSA SECP256R1, wrong signature (truncated)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C
+asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f5":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: ECDSA SECP256R1, wrong signature (trailing junk)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C
+asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f21":PSA_ERROR_INVALID_SIGNATURE
+
+PSA verify: ECDSA SECP256R1, wrong signature (leading junk)
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C
+asymmetric_verify_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"216a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE
+
PSA verify: invalid algorithm for ECC key
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21
asymmetric_verify_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"":PSA_ERROR_INVALID_ARGUMENT
@@ -2127,6 +2184,23 @@
depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_CATEGORY_MASK:128:PSA_ERROR_INVALID_ARGUMENT
+PSA key derivation: invalid length (0)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_RAW_DATA:0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: invalid length (7 bits)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_RAW_DATA:7:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: raw data, 8 bits
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_RAW_DATA:8:PSA_SUCCESS
+
+PSA key derivation: invalid length (9 bits)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_RAW_DATA:9:PSA_ERROR_INVALID_ARGUMENT
+
# This test assumes that PSA_MAX_KEY_BITS (currently 65536-8 bits = 8191 bytes
# and not expected to be raised any time soon) is less than the maximum
# output from HKDF-SHA512 (255*64 = 16320 bytes).
@@ -2254,8 +2328,9 @@
PSA generate key: bad type (RSA public key)
generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:512:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED
-PSA generate key: raw data, 0 bits
-generate_key:PSA_KEY_TYPE_RAW_DATA:128:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+PSA generate key: raw data, 0 bits: invalid argument
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+generate_key:PSA_KEY_TYPE_RAW_DATA:0:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT
PSA generate key: raw data, 7 bits: invalid argument
generate_key:PSA_KEY_TYPE_RAW_DATA:7:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT
@@ -2263,6 +2338,9 @@
PSA generate key: raw data, 8 bits
generate_key:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+PSA generate key: raw data, 9 bits: invalid argument
+generate_key:PSA_KEY_TYPE_RAW_DATA:9:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT
+
PSA generate key: raw data, (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
generate_key:PSA_KEY_TYPE_RAW_DATA:(MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
@@ -2320,6 +2398,11 @@
depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C
generate_key:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):PSA_SUCCESS
+PSA generate key: RSA, 0 bits: invalid
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+generate_key:PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_INVALID_ARGUMENT
+
PSA generate key: RSA, 1022 bits: not supported
depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
generate_key:PSA_KEY_TYPE_RSA_KEY_PAIR:1022:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED
@@ -2358,9 +2441,9 @@
PSA generate key: RSA, e=2
generate_key_rsa:512:"01":PSA_ERROR_INVALID_ARGUMENT
-PSA import persistent key: raw data, 0 bits
+PSA import persistent key: raw data, 8 bits
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PSA_CRYPTO_STORAGE_C
-persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_RAW_DATA:0:PSA_KEY_USAGE_EXPORT:0:IMPORT_KEY
+persistent_key_load_key_from_storage:"2a":PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:IMPORT_KEY
PSA import persistent key: AES, 128 bits, exportable
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PSA_CRYPTO_STORAGE_C
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data
index 3f40d35..f228b26 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.data
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.data
@@ -44,9 +44,6 @@
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
persistent_key_import:1:PSA_KEY_TYPE_RSA_KEY_PAIR:"11111111":0:PSA_ERROR_INVALID_ARGUMENT
-import/export persistent raw key: 0 byte
-import_export_persistent_key:"":PSA_KEY_TYPE_RAW_DATA:0:0:0
-
import/export persistent raw key: 1 byte
import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:0:0
@@ -73,9 +70,6 @@
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
import_export_persistent_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:0:0
-import/export persistent raw key with restart: 0 byte
-import_export_persistent_key:"":PSA_KEY_TYPE_RAW_DATA:0:1:0
-
import/export persistent raw key with restart: 1 byte
import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:1:0
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
index e364178..e6b3f7b 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
@@ -396,6 +396,7 @@
psa_set_key_lifetime( &attributes, lifetime );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
+ psa_set_key_bits( &attributes, 8 );
TEST_ASSERT( psa_generate_key( &attributes, &handle ) == expected_result );
TEST_ASSERT( mock_allocate_data.called == 1 );
TEST_ASSERT( mock_generate_data.called ==
@@ -482,6 +483,8 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
const uint8_t key_material[3] = {0xfa, 0xca, 0xde};
psa_algorithm_t algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
+ const uint8_t hash[1] = {'H'};
+ uint8_t signature[1] = {'S'};
size_t signature_length;
mock_sign_data.return_value = mock_sign_return_value;
@@ -512,7 +515,9 @@
key_material, sizeof( key_material ),
&handle ) );
- TEST_ASSERT( psa_asymmetric_sign( handle, algorithm, NULL, 0, NULL, 0,
+ TEST_ASSERT( psa_asymmetric_sign( handle, algorithm,
+ hash, sizeof( hash ),
+ signature, sizeof( signature ),
&signature_length)
== expected_result );
TEST_ASSERT( mock_sign_data.called == 1 );
@@ -538,6 +543,8 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
const uint8_t key_material[3] = {0xfa, 0xca, 0xde};
psa_algorithm_t algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
+ const uint8_t hash[1] = {'H'};
+ const uint8_t signature[1] = {'S'};
mock_verify_data.return_value = mock_verify_return_value;
memset( &driver, 0, sizeof( driver ) );
@@ -567,7 +574,9 @@
key_material, sizeof( key_material ),
&handle ) );
- TEST_ASSERT( psa_asymmetric_verify( handle, algorithm, NULL, 0, NULL, 0)
+ TEST_ASSERT( psa_asymmetric_verify( handle, algorithm,
+ hash, sizeof( hash ),
+ signature, sizeof( signature ) )
== expected_result );
TEST_ASSERT( mock_verify_data.called == 1 );
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index 0456bc2..7f71a5a 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -269,7 +269,6 @@
<ClCompile Include="..\..\library\md2.c" />
<ClCompile Include="..\..\library\md4.c" />
<ClCompile Include="..\..\library\md5.c" />
- <ClCompile Include="..\..\library\md_wrap.c" />
<ClCompile Include="..\..\library\memory_buffer_alloc.c" />
<ClCompile Include="..\..\library\nist_kw.c" />
<ClCompile Include="..\..\library\oid.c" />