From 6365a681c8a13df145fb40d2f9c20a975420b11e Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 22 May 2023 11:14:36 +0100 Subject: [PATCH 01/89] Prefer intrinsics over asm for AES-NI Signed-off-by: Dave Rodgman --- library/aesni.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/library/aesni.h b/library/aesni.h index 51b770f316..a054cfd5c1 100644 --- a/library/aesni.h +++ b/library/aesni.h @@ -61,14 +61,14 @@ /* Choose the implementation of AESNI, if one is available. */ #undef MBEDTLS_AESNI_HAVE_CODE -/* To minimize disruption when releasing the intrinsics-based implementation, - * favor the assembly-based implementation if it's available. We intend to - * revise this in a later release of Mbed TLS 3.x. In the long run, we will - * likely remove the assembly implementation. */ -#if defined(MBEDTLS_HAVE_X86_64) -#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly -#elif defined(MBEDTLS_AESNI_HAVE_INTRINSICS) +/* Favor the intrinsics-based implementation if it's available, for better + * maintainability. + * Performance is about the same (see #7380). + * In the long run, we will likely remove the assembly implementation. */ +#if defined(MBEDTLS_AESNI_HAVE_INTRINSICS) #define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics +#elif defined(MBEDTLS_HAVE_X86_64) +#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly #endif #if defined(MBEDTLS_AESNI_HAVE_CODE) From 76a852f8fb1421263114afe3551432055d5b64a5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 24 May 2023 09:35:26 +0200 Subject: [PATCH 02/89] Design document for storage resilience Explore possibilities for implementing stateful secure elements with storage. Choose one. Signed-off-by: Gilles Peskine --- docs/architecture/psa-storage-resilience.md | 430 ++++++++++++++++++++ 1 file changed, 430 insertions(+) create mode 100644 docs/architecture/psa-storage-resilience.md diff --git a/docs/architecture/psa-storage-resilience.md b/docs/architecture/psa-storage-resilience.md new file mode 100644 index 0000000000..7b8792f563 --- /dev/null +++ b/docs/architecture/psa-storage-resilience.md @@ -0,0 +1,430 @@ +# PSA storage resilience design + +## Introduction + +The PSA crypto subsystem includes a persistent key store. It is possible to create a persistent key and read it back later. This must work even if the underlying storage exhibits non-nominal behavior. In this document, _resilience_ means correct behavior of the key store even under if the underlying platform behaves in a non-nominal, but still partially controlled way. + +At this point, we are only concerned about one specific form of resilience: to a system crash or power loss. That is, we assume that the underlying platform behaves nominally, except that occasionally it may restart. In the field, this can happen due to a sudden loss of power. + +This document explores the problem space, defines a library design and a test design. + +## Resilience goals for API functions + +**Goal: PSA Crypto API functions are atomic and committing.** + +_Atomic_ means that when an application calls an API function, as far as the application is concerned, at any given point in time, the system is either in a state where the function has not started yet, or in a state where the function has returned. The application never needs to worry about an intermediate state. + +_Committing_ means that when a function returns, the data has been written to the persistent storage. As a consequence, if the system restarts during a sequence of storage modifications $M_1, M_2, \ldots, M_n$, we know that when the system restarts, a prefix of the sequence has been performed. For example, there will never be a situation where $M_2$ has been performed but not $M_1$. + +The committing property is important not only for sequences of operations, but also when reporting the result of an operation to an external system. For example, if a key creation function in the PSA Crypto API reports to the application that a key has been created, and the application reports to a server that the key has been created, it is guaranteed that the key exists even if the system restarts. + +## Assumptions on the underlying file storage + +PSA relies on a PSA ITS (Internal Trusted Storage) interface, which exposes a simple API. There are two functions to modify files: + +* `set()` writes a whole file (either creating it, or replacing the previous content). +* `remove()` removes a file (returning a specific error code if the file does not exist). + +**Assumption: the underlying ITS functions are atomic and committing.** + +Since the underlying functions are atomic, the content of a file is always a version that was previously passed to `set()`. We do not try to handle the case where a file might be partially written. + +## Overview of API functions + +For a transparent key, all key management operations (creation or destruction) on persistent keys rely on a single call to the underlying storage (`set()` for a key creation, `remove()` for a key destruction). This also holds for an opaque key stored in a secure element that does not have its own key store: in this case, the core stores a wrapped (i.e. encrypted) copy of the key material, but this does not impact how the core interacts with the storage. Other API functions do not modify the storage. + +The following case requires extra work related to resilience: + +* [Key management for stateful secure element keys](#designing-key-management-for-secure-element-keys). + +As a consequence, apart from the listed cases, the API calls inherit directly from the [resilience properties of the underyling storage](#assumptions-on-the-underlying-file-storage). We do not need to take any special precautions in the library design, and we do not need to perform any testing of resilience for transparent keys. + +(This section was last updated for Mbed TLS 3.4.0 implementing PSA Crypto API 1.1.) + +## Designing key management for secure element keys + +In this section, we use “(stateful) secure element key” to mean a key stored in a stateful secure element, i.e. a secure element that stores keys. This excludes keys in a stateleess secure element for which the core stores a wrapped copy of the key. We study the problem of how key management in stateful secure elements interacts with storage and explore the design space. + +### Assumptions on stateful secure elements + +**Assumption: driver calls for key management in stateful secure elements are atomic and committing.** + +(For stateless secure elements, this assumption is vacuously true.) + +### Dual management of keys: the problem + +For a secure element key, key management requires a commitment on both sites. For example, consider a successful key creation operation: + +1. The core sends a request to the secure element to create a key. +2. The secure element modifies its key store to create the key. +3. The secure element reports to the core that the key has been created. +4. The core reports to the application that the key has been created. + +If the core loses power between steps 1 and 2, the key does not exist yet. This is fine from an application's perspective since the core has not committed to the key's existence, but the core needs to take care not to leave resources in storage that are related to the non-existent key. If the core loses power between steps 2 and 3, the key exists in the secure element. From an application's perspective, the core may either report that the key exists or that it does not exist, but in the latter case, the core needs to free the key in the secure element, to avoid leaving behind inaccessible resources. + +As a consequence, the content of the storage cannot remain the same between the end of step 1 and the end of step 3, since the core must behave differently depending on whether step 2 has taken place. + +Accomplishing a transaction across system boundaries is a well-known problem in database management, with a well-known solution: two-phase commit. + +### Overview of two-phase commit with stateful secure elements + +With a key in a stateful secure element, a successful creation process goes as follows (see [“Key management in a secure element with storage” in the driver interface specification](../../proposed/psa-driver-interface.html#key-management-in-a-secure-element-with-storage)): + +1. The core calls the driver's `"allocate_key"` entry point. +2. The driver allocates a unique identifier _D_ for the key. This is unrelated to the key identifier _A_ used by the application interface. This step must not modify the state of the secure element. +3. The core updates the storage to indicate that key identifier _A_ has the identifier _D_ in the driver, and that _A_ is in a half-created state. +4. The core calls the driver's key creation entry point, passing it the driver's chosen identifier _D_. +5. The driver creates the key in the secure element. When this happens, it concludes the voting phase of the two-phase commit: effectively, the secure element decides to commit. (It is however possible to revert this commitment by giving the secure element the order to destroy the key.) +6. The core updates the storage to indicate that _A_ is now in a fully created state. This concludes the commit phase of the two-phase commit. + +If there is a loss of power: + +* Before step 3: the system state has not changed at all. As far as the world is concerned, the key creation attempt never happened. +* Between step 3 and step 6: upon restart, the core needs to find out whether the secure element completed step 5 or not, and reconcile the state of the storage with the state of the secure element. +* After step 6: the key has been created successfully. + +Key destruction goes as follows: + +1. The core updates the storage indicating that the key is being destroyed. +2. The core calls the driver's `"destroy_key"` entry point. +3. The secure element destroys the key. +4. The core updates the storage to indicate that the key has been destroyed. + +If there is a loss of power: + +* Before step 1: the system state has not changed at all. As far as the world is concerned, the key destruction attempt never happened. +* Between step 1 and step 4: upon restart, the core needs to find out whether the secure element completed step 3 or not, and reconcile the state of the storage with the state of the secure element. +* After step 4: the key has been destroyed successfully. + +In both cases, upon restart, the core needs to perform a transaction recovery. When a power loss happens, the core decides whether to commit or abort the transaction. + +Note that the analysis in this section assumes that the driver does not update its persistent state during a key management operation (or at least not in a way that is influences the key management process — for example, it might renew an authorization token). + +### Optimization considerations for transactions + +We assume that power failures are rare. Therefore we will primarily optimize for the normal case. Transaction recovery needs to be practical, but does not have to be fully optimized. + +The main quantity we will optimize for is the number of storage updates in the nominal case. This is good for performance because storage writes are likely to dominate the runtime in some hardware configurations where storage writes are slow and communication with the secure element is fast, for key management operations that require a small amount of computation. In addition, minimizing the number of storage updates is good for the longevity of flash media. + +#### Information available during recovery + +The PSA ITS API does not support enumerating files in storage: an ITS call can only access one file identifier. Therefore transaction recovery cannot be done by traversing files whose name is or encodes the key identifier. It must start by traversing a small number of files whose names are independent of the key identifiers involved. + +#### Minimum effort for a transaction + +Per the [assumptions on the underlying file storage](#assumptions-on-the-underlying-file-storage), each atomic operation in the internal storage concerns a single file: either removing it, or setting its content. Furthermore there is no way to enumerate the files in storage. + +A key creation function must transform the internal storage from a state where file `id` does not exist, to a state where file `id` exists and has its desired final content (containing the key attributes and the driver's key identifier). The situation is similar with key destruction, except that the initial and final states are exchanged. Neither the initial state nor the final state reference `id` otherwise. + +For a key that is not in a stateful element, the transaction consists of a single write operation. As discussed previously, this is not possible with a stateful secure element because the state of the internal storage needs to change both before and after the state change in the secure element. No other single-write algorithm works. + +If there is a power failure around the time of changing the state of the secure element, there must be information in the internal storage that indicates that key `id` has a transaction in progress. The file `id` cannot be used for this purpose because there is no way to enumerate all keys (and even if there was, it would not be practical). Therefore the transaction will need to modify some other file `t` with a fixed name (a name that doesn't depend on the key). Since the final system state should be identical to the initial state except for the file `id`, the minimum number of storage operations for a transaction is 3: + +* Write (create or update) a file `t` referencing `id`. +* Write the final state of `id`. +* Restore `t` to its initial state. + +The strategies discussed in the [overview above](#overview-of-two-phase-commit-with-stateful-secure-elements) follow this pattern, with `t` being the file containing the transaction list that the recovery consults. We have just proved that this pattern is optimal. + +Note that this pattern requires the state of `id` to be modified only once. In particular, if a key management involves writing an intermediate state for `id` before modifying the secure element state and writing a different state after that, this will require a total of 4 updates to internal storage. Since we want to minimize the number of storage updates, we will not explore designs that involved updating `id` twice or more. + +### Recovery strategies + +When the core starts, it needs to know about transaction(s) that need to be resumed. This information will be stored in a persistent “transaction list”, with one entry per key. In this section, we explore recovery strategies, and we determine what the transaction list needs to contain as well as when it needs to be updated. Other sections will explore the format of the transaction list, as well as how many keys it needs to contain. + +#### Exploring the recovery decision tree + +There are four cases for recovery when a transaction is in progress. In each case, the core can either decide to commit the transaction (which may require replaying the interrupted part) or abort it (which may require a rewind in the secure element). It may call the secure element driver's `"get_key_attributes"` entry point to find out whether the key is present. + +* Key creation, key not present in the secure element: + * Committing means replaying the driver call in the key creation. This requires all the input, for example the data to import. This seems impractical in general. Also, the second driver call require a new call to `"allocate_key"` which will in general changing the key's driver identifier, which complicates state management in the core. Given the likely complexity, we exclude this strategy. + * Aborting means removing any trace of the key creation. +* Key creation, key present in the secure element: + * Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted. + * Aborting means destroying the key in the secure element and removing any local storage used for that key. +* Key destruction, key not present in the secure element: + * Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted, by removing any remaining local storage used for that key. + * Aborting would mean re-creating the key in the secure element, which is impossible in general since the key material is no longer present. +* Key destruction, key present in the secure element: + * Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted, by removing any remaining local storage used for that key and destroying the key in the secure element. + * Aborting means keeping the key. This requires no action on the secure element, and is only practical locally if the local storage is intact. + +#### Comparing recovery strategies + +From the analysis above, assuming that all keys are treated in the same way, there are 4 possible strategies. + +* [Always follow the state of the secure element](#exploring-the-follow-the-secure-element-strategy). This requires the secure element to have a `"get_key_attributes"` entry point. Recovery means resuming the operation where it left off. For key creation, this means that the key metadata needs to be saved before calling the secure element's key creation entry point. +* Minimize the information processing: [always destroy the key](#exploring-the-always-destroy-strategy), i.e. abort all key creations and commit all key destructions. This does not require querying the state of the secure element. This does not require any special precautions to preserve information about the key during the transaction. It simplifies recovery in that the recovery process might not even need to know whether it's recovering a key creation or a key destruction. +* Follow the state of the secure element for key creation, but always go ahead with key destruction. This requires the secure element to have a `"get_key_attributes"` entry point. Compared to always following the state of the secure element, this has the advantage of maximizing the chance that a command to destroy key material is effective. Compared to always destroying the key, this has a performance advantage if a key creation is interrupted. These do not seem like decisive advantages, so we will not consider this strategy further. +* Always abort key creation, but follow the state of the secure element for key destruction. I can't think of a good reason to choose this strategy. + +#### Exploring the follow-the-secure-element strategy + +Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), the driver key identifier, and an indication of whether the key is being created or destroyed. + +For key creation, we have all the information to store in the key file once the `"allocate_key"` call returns. We must store all the information that will go in the key file before calling the driver's key creation entry point. Therefore the normal sequence of operations is: + +1. Call the driver's `"allocate_key"` entry point. +2. Add the key to the transaction list, indicating that it is being created. +3. Write the key file. +4. Call the driver's key creation entry point. +5. Remove the key from the transaction list. + +During recovery, for each key in the transaction list that was being created: + +* If the key exists in the secure element, just remove it from the transaction list. +* If the key does not exist in the secure element, first remove the key file if it is present, then remove the key from the transaction list. + +For key destruction, we need to preserve the key file until after the key has been destroyed. Therefore the normal sequence of operations is: + +1. Add the key to the transaction list, indicating that it is being destroyed. +2. Call the driver's `"destroy_key"` entry point. +3. Remove the key file. +4. Remove the key from the transaction list. + +During recovery, for each key in the transaction list that was being created: + +* If the key exists in the secure element, call the driver's `"destroy_key"` entry point, then remove the key file, and finally remote the key from the transaction lits. +* If the key does not exist in the secure element, remove the key file if it is still present, then remove the key from the transaction list. + +#### Exploring the always-destroy strategy + +Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), and the driver key identifier. + +For key creation, we do not need to store the key's metadata until it has been created in the secure element. Therefore the normal sequence of operations is: + +1. Call the driver's `"allocate_key"` entry point. +2. Add the key to the transaction list. +3. Call the driver's key creation entry point. +4. Write the key file. +5. Remove the key from the transaction list. + +For key destruction, we can remove the key file before contacting the secure element. Therefore the normal sequence of operations is: + +1. Add the key to the transaction list. +2. Remove the key file. +3. Call the driver's `"destroy_key"` entry point. +4. Remove the key from the transaction list. + +Recovery means removing all traces of all keys on the transaction list. This means following the destruction process, starting after the point where the key has been added to the transaction list, and ignoring any failure of a removal action if the item to remove does not exist: + +1. Remove the key file, treating `DOES_NOT_EXIST` as a success. +2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success. +3. Remove the key from the transaction list. + +#### Assisting secure element drivers with recovery + +The actions of the secure element driver may themselves be non-atomic. So the driver must be given a chance to perform recovery. + +To simplify the design of the driver, the core should guarantee that the driver will know if a transaction was in progress and the core cannot be sure about the state of the secure element. Merely calling a read-only entry point such as `"get_key_attributes"` does not provide enough information to the driver for it to know that it should actively perform recovery related to that key. + +This gives an advantage to the “always destroy” strategy. Under this strategy, if the key might be in a transitional state, the core will request a key destruction from the driver. This means that, if the driver has per-key auxiliary data to clean up, it can bundle that as part of the key's destruction. + +### Testing non-atomic processes + +In this section, we discuss how to test non-atomic processes that must implement an atomic and committing interface. As discussed in [“Overview of API functions”](#overview-of-api-functions), this concerns key management in stateful secure elements. + +#### Naive test strategy for non-atomic processes + +Non-atomic processes consist of a series of atomic, committing steps. + +Our general strategy to test them is as follows: every time there is a modification of persistent state, either in storage or in the (simulated) secure element, try both the nominal case and simulating a power loss. If a power loss occurs, restart the system (i.e. clean up and call `psa_crypto_init()`), and check that the system ends up in a consistent state. + +Note that this creates a binary tree of possibilities: after each state modification, there may or may not be a restart, and after that different state modifications may occur, each of which may or may not be followed by a restart. + +For example, consider testing of one key creation operation (see [“Overview of two-phase commit with stateful secure elements”](#overview-of-two-phase-commit-with-stateful-secure-elements), under the simplifying assumption that each storage update step, as well as the recovery after a restart, each make a single (atomic) storage modification and no secure element access. The nominal case consists of three state modifications: storage modification (start transaction), creation on the secure element, storage modification (commit transaction). We need to test the following sequences: + +* Start transaction, restart, recovery. +* Start transaction, secure element operation, restart, recovery. +* Start transaction, secure element operation, commit transaction. + +If, for example, recovery consists of two atomic steps, the tree of possibilities expands and may be infinite: + +* Start transaction, restart, recovery step 1, restart, recovery step 1, recovery step 2. +* Start transaction, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, recovery step 2. +* Start transaction, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, recovery step 2. +* etc. +* Start transaction, secure element operation, restart, ... +* Start transaction, secure element operation, commit transaction. + +In order to limit the possibilities, we need to make some assumptions about the recovery step. For example, if we have confidence that recovery step 1 is idempotent (i.e. doing it twice is the same as doing it once), we don't need to test what happens in execution sequences that take recovery step 1 more than twice in a row. + +### Splitting normal behavior and transaction recovery + +We introduce an abstraction level in transaction recovery: + +* Normal operation must maintain a certain invariant on the state of the world (internal storage and secure element). +* Transaction recovery is defined over all states of the world that satisfy this invariant. + +This separation of concerns greatly facilitates testing, since it is now split into two parts: + +* During the testing of normal operation, we can use read-only invasive testing to ensure that the invariant is maintained. No modification of normal behavior (such as simulated power failures) is necessary. +* Testing of transaction recovery is independent of how the system state was reached. We only need to artificially construct a representative sample of system states that match the invariant. Transaction recovery is itself an operation that must respect the invariant, and so we do not need any special testing for the case of an interrupted recovery. + +Another benefit of this approach is that it is easier to specify and test what happens if the library is updated on a device with leftovers from an interrupted transaction. We will require and test that the new version of the library supports recovery of the old library's states, without worrying how those states were reached. + +#### Towards an invariant for transactions + +As discussed in the section [“Recovery strategies”](#recovery-strategies), the information about active transactions is stored in a transaction list file. The name of the transaction list file does not depend on the identifiers of the keys in the list, but there may be more than one transaction list, for example one per secure element. If so, each transaction list can be considered independently. + +When no transaction is in progress, the transaction list does not exist, or is empty. The empty case must be supported because this is the initial state of the filesystem. When no transaction is in progress, the state of the secure element must be consistent with references to keys in that secure element contained in key files. More generally, if a key is not in the transaction list, then the key must be present in the secure element if and only if the key file is in the internal storage. + +For the purposes of the state invariant, it matters whether the transaction list file contains the driver key identifier, or if the driver key identifier is only stored in the key file. This is because the core needs to know the driver key id in order to access the secure element. If the transaction list does not contain the driver key identifier, and the key file does not exist, the key must not be present in the secure element. + +We thus have two scenarios, each with their own invariant: one where the transaction list contains only key identifiers, and one where it also contains the secure element's key identifier (as well as the location of the secure element if this is not encoded in the name of the transaction list file). + +#### Storage invariant if the transaction list contains application key identifiers only + +Invariants: + +* If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not. +* If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element. + +If `id` is in the transaction list and the file `id` exists, the key may or may not be present in the secure element. + +The invariant imposes constraints on the [order of operations for the two-phase commit](#overview-of-two-phase-commit-with-stateful-secure-elements): key creation must create `id` before calling the secure element's key creation entry point, and key destruction must remove `id` after calling the secure element's key destruction entry point. + +For recovery: + +* If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list. +* If the file `id` exists: + * It is correct to destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success), then remove `id`. + * It is correct to check whether the key exists in the secure element, and if it does, keep it and keep `id`. If not, remove `id` from the internal storage. + +#### Storage invariant if the transaction list contains driver key identifiers + +Invariants: + +* If `id` is not in the transaction list and the file `id` does not exist, then no resources corresponding to that key are in a secure element. +* If `id` is not in the transaction list and the file `id` exists, then the key is present in the secure element. + +If `id` is in the transaction list, neither the state of `id` in the internal storage nor the state of the key in the secure element is known. + +For recovery: + +* If the file `id` does not exist, then destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success). +* If the file `id` exists: + * It is correct to destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success), then remove `id`. + * It is correct to check whether the key exists in the secure element, and if it does, keep it and keep `id`. If not, remove `id` from the internal storage. + +#### Coverage of states that respect the invariant + +For a given key, we have to consider three a priori independent boolean states: + +* Whether the key file exists. +* Whether the key is in the secure element. +* Whether the key is in the transaction list. + +There is full coverage for one key if we have tests of recovery for the states among these $2^3 = 8$ possibilities that satisfy the storage invariant. + +In addition, testing should adequately cover the case of multiple keys in the transaction list. How much coverage is adequate depends on the layout of the list as well as white-box considerations of how the list is manipulated. + +### Choice of a transaction design + +Based on [“Optimization considerations for transactions”](#optimization-considerations-for-transactions), we choose a transaction algorithm that consists in the following operations: + +1. Add the key identifier to the transaction list. +2. Call the secure element's key creation or destruction entry point. +3. Remove the key identifier from the transaction list. + +In addition, before or after step 2, create or remove the key file in the internal storage. + +In order to conveniently support multiple transactions at the same time, we pick the simplest possible layout for the transaction list: a simple array of key identifiers. Since the transaction list does not contain the driver key identifier: + +* During key creation, create the key file in internal storage in the internal storage before calling the secure element's key creation entry point. +* During key destruction, call the secure element's key destruction entry point before removing the key file in internal storage. + +The [storage invariant](#storage-invariant-if-the-transaction-list-contains-application-key-identifiers-only) is as follows: + +* If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not. +* If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element. + +To [assist secure element drivers with recovery](#assisting-secure-element-drivers-with-recovery), we pick the [always-destroy recovery strategy](#exploring-the-always-destroy-strategy). The the recovery process is as follows: + +* If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list. +* If the file `id` exists, call the secure element's key destruction entry point (treating a `DOES_NOT_EXIST` error as a success), then remove `id`. + +## Specification of key management in stateful secure elements + +This section only concerns stateful secure elements as discussed in [“Designing key management for secure element keys”](#designing-key-management-for-secure-element-keys), i.e. secure elements with an `"allocate_key"` entry point. The design follows the general principle described in [“Overview of two-phase commit with stateful secure elements”](#overview-of-two-phase-commit-with-stateful-secure-elements) and the specific choices justified in [“Choice of a transaction design”](choice-of-a-transaction-design). + +### Transaction list file manipulation + +The transaction list is a simple array of key identifiers. + +To add a key identifier to the list: + +1. Load the current list from the transaction list if it exists and it is not already cached in memory. +2. Append the key identifier to the array. +3. Write the updated list file. + +To remove a key identifier from the list: + +1. Load the current list if it is not already cached in memory. It is an error if the file does not exist since it must contain this identifier. +2. Remove the key identifier from the array. If it wasn't the last element in array, move array elements to fill the hole. +3. If the list is now empty, remove the transaction list file. Otherwise write the updated list to the file. + +### Key creation process in the core + +Let _A_ be the application key identifier. + +1. Call the driver's `"allocate_key"` entry point, obtaining the driver key identifier _D_ chosen by the driver. +2. Add _A_ [to the transaction list file](#transaction-list-file-manipulation). +3. Create the key file _A_ in the internal storage. Note that this is done at a different time from what happens when creating a transparent key or a key in a stateless secure element: in those cases, creating the key file happens after the actual creation of the key material. +4. Call the secure element's key creation entry point. +5. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation). + +If any step fails: + +* If the secure element's key creation entry point has been called and succeeded, call the secure element's destroy entry point. +* If the key file has been created in the internal storage, remove it. +* Remove the key from the transaction list. + +Note that this process is identical to key destruction, except that the key is already in the transaction list. + +### Key destruction process in the core + +Let _A_ be the application key identifier. + +We assume that the key is loaded in a key slot in memory: the core needs to know the key's location in order to determine whether the key is in a stateful secure element, and if so to know the driver key identifier. A possible optimization would be to load only that information in local variables, without occupying a key store; this has the advantage that key destruction works even if the key store is full. + +1. Add _A_ [to the transaction list file](#transaction-list-file-manipulation). +2. Call the secure element's `"destroy_key"` entry point. +3. Remove the key file _A_ from the internal storage. +4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation). +5. Free the corresponding key slot in memory. + +If any step fails, remember the error but continue the process, to destroy the resources associated with the key as much as is practical. + +### Transaction recovery + +For each key _A_ in the transaction list file, if the file _A_ exists in the internal storage: + +1. Load the key into a key slot in memory. +2. Call the secure element's `"destroy_key"` entry point. +3. Remove the key file _A_ from the internal storage. +4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation). +5. Free the corresponding key slot in memory. + +The transaction list file can be processed in any order. + +It is correct to update the transaction list after recovering each key, or to only delete the transaction list file once the recovery is over. + +### Concrete format of the transaction list + +TODO + +### Cohabitation with transactions and dynamic secure elements + +TODO + +## Testing key management in secure elements + +### Instrumentation for checking the storage invariant + +TODO + +### Testing of transaction recovery + +TODO + From 44bbf29597cd8001461788030788adbc2f960ccd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 24 May 2023 20:35:29 +0200 Subject: [PATCH 03/89] Write up the transaction/recovery processess Still missing: details of part of the testing Signed-off-by: Gilles Peskine --- docs/architecture/psa-storage-resilience.md | 62 +++++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/docs/architecture/psa-storage-resilience.md b/docs/architecture/psa-storage-resilience.md index 7b8792f563..ee396050b2 100644 --- a/docs/architecture/psa-storage-resilience.md +++ b/docs/architecture/psa-storage-resilience.md @@ -321,6 +321,8 @@ In addition, testing should adequately cover the case of multiple keys in the tr ### Choice of a transaction design +#### Chosen transaction algorithm + Based on [“Optimization considerations for transactions”](#optimization-considerations-for-transactions), we choose a transaction algorithm that consists in the following operations: 1. Add the key identifier to the transaction list. @@ -334,11 +336,15 @@ In order to conveniently support multiple transactions at the same time, we pick * During key creation, create the key file in internal storage in the internal storage before calling the secure element's key creation entry point. * During key destruction, call the secure element's key destruction entry point before removing the key file in internal storage. +#### Chosen storage invariant + The [storage invariant](#storage-invariant-if-the-transaction-list-contains-application-key-identifiers-only) is as follows: * If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not. * If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element. +#### Chosen recovery process + To [assist secure element drivers with recovery](#assisting-secure-element-drivers-with-recovery), we pick the [always-destroy recovery strategy](#exploring-the-always-destroy-strategy). The the recovery process is as follows: * If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list. @@ -410,21 +416,65 @@ The transaction list file can be processed in any order. It is correct to update the transaction list after recovering each key, or to only delete the transaction list file once the recovery is over. -### Concrete format of the transaction list +### Concrete format of the transaction list file -TODO +The transaction list file contains a [fixed header](#transaction-list-header-format) followed by a list of [fixed-size elements](#transaction-list-element-format). -### Cohabitation with transactions and dynamic secure elements +The file uid is `PSA_CRYPTO_ITS_TRANSACTION_LIST_UID` = 0xffffff53. -TODO +#### Transaction list header format + +* Version (2 bytes): 0x0003. (Chosen to differ from the first two bytes of a [dynamic secure element transaction file](#dynamic-secure-element-transaction-file), to reduce the risk of a mix-up.) +* Key name size (2 bytes): `sizeof(psa_storage_uid_t)`. Storing this size avoids reading bad data if Mbed TLS is upgraded to a different integration that names keys differently. + +#### Transaction list element format + +In practice, there will rarely be more than one active transaction at a time, so the size of an element is not critical for efficiency. Therefore, in addition to the key identifier which is required, we add some potentially useful information in case it becomes useful later. We do not put the driver key identifier because its size is not a constant. + +* Key id: `sizeof(psa_storage_uid_t)` bytes. +* Key lifetime: 4 bytes (`sizeof(psa_key_lifetime_t)`). Currently unused during recovery. +* Operation type: 1 byte. Currently unused during recovery. + * 0: destroy key. + * 1: import key. + * 2: generate key. + * 3: derive key. + * 4: import key. +* Padding: 3 bytes. Reserved for future use. Currently unused during recovery. + +#### Dynamic secure element transaction file + +Note that the code base already references a “transaction file” (`PSA_CRYPTO_ITS_TRANSACTION_UID` = 0xffffff54), used by dynamic secure elements (feature enabled with `MBEDTLS_PSA_CRYPTO_SE_C`). This is a deprecated feature that has not been fully implemented: when this feature is enabled, the transaction file gets written during transactions, but if it exists when PSA crypto starts, `psa_crypto_init()` fails because [recovery has never been implemented](https://github.com/ARMmbed/mbed-crypto/issues/218). + +For the new kind of secure element driver, we pick a different file name to avoid any mixup. ## Testing key management in secure elements ### Instrumentation for checking the storage invariant -TODO +When `MBEDTLS_TEST_HOOKS` is enabled, each call to `psa_its_set()` or `psa_its_remove()` also calls a test hook, passing the file UID as an argument to the hook. + +When a stateful secure element driver is present in the build, we use this hook to verify that the storage respects the [storage invariant](#chosen-storage-invariant). In addition, if there is some information about key ongoing operation (set explicitly by the test function as a global variable in the test framework), the hook tests that the content of the storage is compatible with the ongoing operation. + +TODO: detail of what to validate the invariant on (the test code can't enumerate all possible keys) + +TODO: detail of how to keep track of ongoing operations ### Testing of transaction recovery -TODO +When no secure element driver is present in the build, the presence of a transaction list file during initialization is an error. +#### Recovery testing process + +When the stateful test secure element driver is present in the build, we run test cases on a representative selection of states of the internal storage and the test secure element. Each test case for transaction recovery has the following form: + +1. Create the initial state: + * Create a transaction list file with a certain content. + * Create key files that we want to have in the test. + * Call the secure element test driver to create keys without going throught the PSA API. +2. Call `psa_crypto_init()`. Expect success if the initial state satisfies the [storage invariant](#chosen-storage-invariant) and failure otherwise. +3. On success, check that the expected keys exist, and that keys that are expected to have been destroyed by recovery do not exist. +4. Clean up the storage and the secure element test driver's state. + +#### States to test recovery on + +TODO what states constitute acceptable coverage From 4e5088476e157c8306ab0102bf99af93dacb08e0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 30 May 2023 23:34:07 +0200 Subject: [PATCH 04/89] Finish test strategy Signed-off-by: Gilles Peskine --- docs/architecture/psa-storage-resilience.md | 27 ++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/architecture/psa-storage-resilience.md b/docs/architecture/psa-storage-resilience.md index ee396050b2..593c8623af 100644 --- a/docs/architecture/psa-storage-resilience.md +++ b/docs/architecture/psa-storage-resilience.md @@ -342,6 +342,7 @@ The [storage invariant](#storage-invariant-if-the-transaction-list-contains-appl * If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not. * If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element. +* If `id` is in the transaction list and a key exists by that identifier, the key's location is a stateful secure element. #### Chosen recovery process @@ -451,13 +452,23 @@ For the new kind of secure element driver, we pick a different file name to avoi ### Instrumentation for checking the storage invariant +#### Test hook locations + When `MBEDTLS_TEST_HOOKS` is enabled, each call to `psa_its_set()` or `psa_its_remove()` also calls a test hook, passing the file UID as an argument to the hook. When a stateful secure element driver is present in the build, we use this hook to verify that the storage respects the [storage invariant](#chosen-storage-invariant). In addition, if there is some information about key ongoing operation (set explicitly by the test function as a global variable in the test framework), the hook tests that the content of the storage is compatible with the ongoing operation. -TODO: detail of what to validate the invariant on (the test code can't enumerate all possible keys) +#### Test hook behavior -TODO: detail of how to keep track of ongoing operations +The storage invariant check cannot check all keys in storage, and does not need to (for example, it would be pointless to check anything about transparent keys). It checks the following keys: + +* When invoked from the test hook on a key file: on that key. +* When invoked from the test hook on the transaction file: on all the keys listed in the transaction file. +* When invoked from a test secure element: on the specified key. + +#### Test hook extra data + +Some tests set global variables to indicate which persistent keys they manipulate. We instrument at least some of these tests to also indicate what operation is in progress on the key. See the GitHub issues or the source code for details. ### Testing of transaction recovery @@ -477,4 +488,14 @@ When the stateful test secure element driver is present in the build, we run tes #### States to test recovery on -TODO what states constitute acceptable coverage +For a given key located in a secure element, the following combination of states are possible: + +* Key file: present, absent. +* Key in secure element: present, absent. +* Key in the transaction file: no, creation (import), destruction. + +We test all $2 \times 2 \times 3 = 12$ possibilities, each in its own test case. In each case, call the test function that checks the storage invariant and check that its result is as expected. Then, if the storage invariant is met, follow the [recovery testing process](#recovery-testing-process). + +In addition, have at least one positive test case for each creation method other than import, to ensure that we don't reject a valid value. + +Note: testing of a damaged filesystem (including a filesystem that doesn't meet the invariant) is out of scope of the present document. From 7d39cc410c51f1a8d8d759c68e6bf1b319f5c87e Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Fri, 9 Jun 2023 16:58:01 +0100 Subject: [PATCH 05/89] Fix crypt_and_hash decrypt issue when used with stream cipher crypt_and_hash decryption fails when used with a stream cipher mode of operation due to the input not being multiple of block size, this only applies to block cipher modes and not stream ciphers.This change exempts CTR, CFB & OFB modes from this check. Signed-off-by: Waleed Elmelegy --- programs/aes/crypt_and_hash.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c index 0187648be3..9d4b7e0cff 100644 --- a/programs/aes/crypt_and_hash.c +++ b/programs/aes/crypt_and_hash.c @@ -406,6 +406,9 @@ int main(int argc, char *argv[]) * Check the file size. */ if (mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_GCM && + mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CTR && + mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CFB && + mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_OFB && ((filesize - mbedtls_md_get_size(md_info)) % mbedtls_cipher_get_block_size(&cipher_ctx)) != 0) { mbedtls_fprintf(stderr, "File content not a multiple of the block size (%u).\n", From 46549cb5fa06351e74dcdb004d6e29ed88aebc6a Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Mon, 12 Jun 2023 14:53:02 +0100 Subject: [PATCH 06/89] Replace function calls in crypt_and_hash program with locals Signed-off-by: Waleed Elmelegy --- programs/aes/crypt_and_hash.c | 50 ++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c index 9d4b7e0cff..1d9b522a3d 100644 --- a/programs/aes/crypt_and_hash.c +++ b/programs/aes/crypt_and_hash.c @@ -88,6 +88,9 @@ int main(int argc, char *argv[]) const mbedtls_md_info_t *md_info; mbedtls_cipher_context_t cipher_ctx; mbedtls_md_context_t md_ctx; + mbedtls_cipher_mode_t cipher_mode; + unsigned int cipher_block_size; + unsigned char md_size; #if defined(_WIN32_WCE) long filesize, offset; #elif defined(_WIN32) @@ -235,6 +238,9 @@ int main(int argc, char *argv[]) goto exit; } + md_size = mbedtls_md_get_size(md_info); + cipher_block_size = mbedtls_cipher_get_block_size(&cipher_ctx); + if (mode == MODE_ENCRYPT) { /* * Generate the initialization vector as: @@ -329,9 +335,9 @@ int main(int argc, char *argv[]) /* * Encrypt and write the ciphertext. */ - for (offset = 0; offset < filesize; offset += mbedtls_cipher_get_block_size(&cipher_ctx)) { - ilen = ((unsigned int) filesize - offset > mbedtls_cipher_get_block_size(&cipher_ctx)) ? - mbedtls_cipher_get_block_size(&cipher_ctx) : (unsigned int) (filesize - offset); + for (offset = 0; offset < filesize; offset += cipher_block_size) { + ilen = ((unsigned int) filesize - offset > cipher_block_size) ? + cipher_block_size : (unsigned int) (filesize - offset); if (fread(buffer, 1, ilen, fin) != ilen) { mbedtls_fprintf(stderr, "fread(%ld bytes) failed\n", (long) ilen); @@ -376,8 +382,8 @@ int main(int argc, char *argv[]) goto exit; } - if (fwrite(digest, 1, mbedtls_md_get_size(md_info), fout) != mbedtls_md_get_size(md_info)) { - mbedtls_fprintf(stderr, "fwrite(%d bytes) failed\n", mbedtls_md_get_size(md_info)); + if (fwrite(digest, 1, md_size, fout) != md_size) { + mbedtls_fprintf(stderr, "fwrite(%d bytes) failed\n", md_size); goto exit; } } @@ -392,12 +398,12 @@ int main(int argc, char *argv[]) * N*16 .. (N+1)*16 - 1 Encrypted Block #N * (N+1)*16 .. (N+1)*16 + n Hash(ciphertext) */ - if (filesize < 16 + mbedtls_md_get_size(md_info)) { + if (filesize < 16 + md_size) { mbedtls_fprintf(stderr, "File too short to be encrypted.\n"); goto exit; } - if (mbedtls_cipher_get_block_size(&cipher_ctx) == 0) { + if (cipher_block_size == 0) { mbedtls_fprintf(stderr, "Invalid cipher block size: 0. \n"); goto exit; } @@ -405,21 +411,21 @@ int main(int argc, char *argv[]) /* * Check the file size. */ - if (mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_GCM && - mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CTR && - mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CFB && - mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_OFB && - ((filesize - mbedtls_md_get_size(md_info)) % - mbedtls_cipher_get_block_size(&cipher_ctx)) != 0) { + cipher_mode = mbedtls_cipher_info_get_mode(cipher_info); + if (cipher_mode != MBEDTLS_MODE_GCM && + cipher_mode != MBEDTLS_MODE_CTR && + cipher_mode != MBEDTLS_MODE_CFB && + cipher_mode != MBEDTLS_MODE_OFB && + ((filesize - md_size) % cipher_block_size) != 0) { mbedtls_fprintf(stderr, "File content not a multiple of the block size (%u).\n", - mbedtls_cipher_get_block_size(&cipher_ctx)); + cipher_block_size); goto exit; } /* * Subtract the IV + HMAC length. */ - filesize -= (16 + mbedtls_md_get_size(md_info)); + filesize -= (16 + md_size); /* * Read the IV and original filesize modulo 16. @@ -483,13 +489,13 @@ int main(int argc, char *argv[]) /* * Decrypt and write the plaintext. */ - for (offset = 0; offset < filesize; offset += mbedtls_cipher_get_block_size(&cipher_ctx)) { - ilen = ((unsigned int) filesize - offset > mbedtls_cipher_get_block_size(&cipher_ctx)) ? - mbedtls_cipher_get_block_size(&cipher_ctx) : (unsigned int) (filesize - offset); + for (offset = 0; offset < filesize; offset += cipher_block_size) { + ilen = ((unsigned int) filesize - offset > cipher_block_size) ? + cipher_block_size : (unsigned int) (filesize - offset); if (fread(buffer, 1, ilen, fin) != ilen) { mbedtls_fprintf(stderr, "fread(%u bytes) failed\n", - mbedtls_cipher_get_block_size(&cipher_ctx)); + cipher_block_size); goto exit; } @@ -517,14 +523,14 @@ int main(int argc, char *argv[]) goto exit; } - if (fread(buffer, 1, mbedtls_md_get_size(md_info), fin) != mbedtls_md_get_size(md_info)) { - mbedtls_fprintf(stderr, "fread(%d bytes) failed\n", mbedtls_md_get_size(md_info)); + if (fread(buffer, 1, md_size, fin) != md_size) { + mbedtls_fprintf(stderr, "fread(%d bytes) failed\n", md_size); goto exit; } /* Use constant-time buffer comparison */ diff = 0; - for (i = 0; i < mbedtls_md_get_size(md_info); i++) { + for (i = 0; i < md_size; i++) { diff |= digest[i] ^ buffer[i]; } From 3bc6feae89c4fa009123772f642ab3a1124a076f Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Mon, 12 Jun 2023 17:37:23 +0100 Subject: [PATCH 07/89] Add crypt_and_hash decrypt issue to Changelog Signed-off-by: Waleed Elmelegy --- ChangeLog.d/fix-crypt_and_hash-decrypt-issue.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/fix-crypt_and_hash-decrypt-issue.txt diff --git a/ChangeLog.d/fix-crypt_and_hash-decrypt-issue.txt b/ChangeLog.d/fix-crypt_and_hash-decrypt-issue.txt new file mode 100644 index 0000000000..ded9b2d47b --- /dev/null +++ b/ChangeLog.d/fix-crypt_and_hash-decrypt-issue.txt @@ -0,0 +1,4 @@ +Bugfix + * Fix crypt_and_hash decryption fail when used with a stream cipher + mode of operation due to the input not being multiple of block size. + Resolves #7417. From 0064484a701bf17cd699019bada172e90ee8793e Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Tue, 30 May 2023 05:45:00 -0400 Subject: [PATCH 08/89] Optimize error translation code size Introducing an intermediate function saves code size that's otherwise taken by excessive, repeated arguments in each place that was translating errors. Signed-off-by: Andrzej Kurek --- library/constant_time.c | 12 +++++++++--- library/lmots.c | 12 +++++++++--- library/lms.c | 12 +++++++++--- library/ssl_cookie.c | 12 +++++++++--- library/ssl_msg.c | 12 +++++++++--- library/ssl_ticket.c | 12 +++++++++--- library/ssl_tls.c | 23 +++++++++++++++++------ library/ssl_tls12_client.c | 12 +++++++++--- library/ssl_tls12_server.c | 12 +++++++++--- library/ssl_tls13_client.c | 13 +++++++++---- library/ssl_tls13_generic.c | 12 +++++++++--- library/ssl_tls13_keys.c | 12 +++++++++--- 12 files changed, 116 insertions(+), 40 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index c823b78894..fa0d898954 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -47,9 +47,15 @@ #include #if defined(MBEDTLS_USE_PSA_CRYPTO) -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #endif /* diff --git a/library/lmots.c b/library/lmots.c index 4061edde04..a3bfff89f8 100644 --- a/library/lmots.c +++ b/library/lmots.c @@ -45,9 +45,15 @@ #include "psa/crypto.h" -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_lms_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_lms_errors, + sizeof(psa_to_lms_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #define PUBLIC_KEY_TYPE_OFFSET (0) #define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \ diff --git a/library/lms.c b/library/lms.c index acc3523314..50595703de 100644 --- a/library/lms.c +++ b/library/lms.c @@ -46,9 +46,15 @@ #include "mbedtls/platform.h" -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_lms_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_lms_errors, + sizeof(psa_to_lms_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #define SIG_Q_LEAF_ID_OFFSET (0) #define SIG_OTS_SIG_OFFSET (SIG_Q_LEAF_ID_OFFSET + \ diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c index ae7a4204ca..371edce3a9 100644 --- a/library/ssl_cookie.c +++ b/library/ssl_cookie.c @@ -37,9 +37,15 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "md_psa.h" -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #endif /* diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 18c19f93ef..f1906570c5 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -49,9 +49,15 @@ #endif #if defined(MBEDTLS_USE_PSA_CRYPTO) -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #endif static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl); diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c index 7d07d191fd..54c00cc0c6 100644 --- a/library/ssl_ticket.c +++ b/library/ssl_ticket.c @@ -31,9 +31,15 @@ #include #if defined(MBEDTLS_USE_PSA_CRYPTO) -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #endif /* diff --git a/library/ssl_tls.c b/library/ssl_tls.c index f0067f4b2d..7601e5b117 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -51,12 +51,23 @@ #endif #if defined(MBEDTLS_USE_PSA_CRYPTO) -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) -#define PSA_TO_MD_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_md_errors, \ - psa_generic_status_to_mbedtls) +/* Define local translating functions to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) + +static int local_md_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_md_errors, + sizeof(psa_to_md_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MD_ERR(status) local_md_translation(status) #endif #if defined(MBEDTLS_TEST_HOOKS) diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index fc96dae1e2..75b79bfadf 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -33,9 +33,15 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/psa_util.h" #include "psa/crypto.h" -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #endif /* MBEDTLS_USE_PSA_CRYPTO */ #include diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 30c35f3a45..d29aa8d437 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -34,9 +34,15 @@ #include #if defined(MBEDTLS_USE_PSA_CRYPTO) -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #endif #if defined(MBEDTLS_ECP_C) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 3dffc1df4a..64d905cbea 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -35,10 +35,15 @@ #include "ssl_debug_helpers.h" #include "md_psa.h" -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) - +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) /* Write extensions */ /* diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index a59f01c3e0..48e6f76e9d 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -39,9 +39,15 @@ #include "psa/crypto.h" #include "mbedtls/psa_util.h" -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[ MBEDTLS_SERVER_HELLO_RANDOM_LEN] = diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 540f854a84..08d10a3549 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -36,9 +36,15 @@ #include "psa/crypto.h" #include "md_psa.h" -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + sizeof(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ .name = string, From 1c7a99856f965f3e2049c924446783f1094c75be Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Tue, 30 May 2023 09:21:20 -0400 Subject: [PATCH 09/89] Add missing ifdefs Make sure that the error translating functions are only defined when they're used. Signed-off-by: Andrzej Kurek --- library/constant_time.c | 4 +++- library/ssl_tls12_client.c | 2 ++ library/ssl_tls12_server.c | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/library/constant_time.c b/library/constant_time.c index fa0d898954..9b2a47758f 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -46,7 +46,9 @@ #endif #include -#if defined(MBEDTLS_USE_PSA_CRYPTO) + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) +#include "psa/crypto.h" /* Define a local translating function to save code size by not using too many * arguments in each translating place. */ static int local_err_translation(psa_status_t status) diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 75b79bfadf..ade68a9272 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -33,6 +33,7 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/psa_util.h" #include "psa/crypto.h" +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) /* Define a local translating function to save code size by not using too many * arguments in each translating place. */ static int local_err_translation(psa_status_t status) @@ -42,6 +43,7 @@ static int local_err_translation(psa_status_t status) psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ #endif /* MBEDTLS_USE_PSA_CRYPTO */ #include diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index d29aa8d437..03f9eea856 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -36,6 +36,8 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) /* Define a local translating function to save code size by not using too many * arguments in each translating place. */ +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, @@ -44,6 +46,7 @@ static int local_err_translation(psa_status_t status) } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) #endif +#endif #if defined(MBEDTLS_ECP_C) #include "mbedtls/ecp.h" From b22b9778c7aeeae70a978819dd401a874c54038c Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Tue, 30 May 2023 09:44:20 -0400 Subject: [PATCH 10/89] Move the ARRAY_LENGTH definition to common.h Reuse it in the library and tests. Signed-off-by: Andrzej Kurek --- library/common.h | 38 +++++++++++++++++++++++++++ library/psa_crypto.c | 2 -- library/psa_crypto_slot_management.c | 2 -- library/sha512.c | 2 -- library/ssl_tls.c | 2 -- tests/include/test/macros.h | 39 ---------------------------- tests/src/psa_crypto_helpers.c | 1 + 7 files changed, 39 insertions(+), 47 deletions(-) diff --git a/library/common.h b/library/common.h index eb159a7c48..68af8405ed 100644 --- a/library/common.h +++ b/library/common.h @@ -65,6 +65,44 @@ extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const cha #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) #endif /* defined(MBEDTLS_TEST_HOOKS) */ +/** \def ARRAY_LENGTH + * Return the number of elements of a static or stack array. + * + * \param array A value of array (not pointer) type. + * + * \return The number of elements of the array. + */ +/* A correct implementation of ARRAY_LENGTH, but which silently gives + * a nonsensical result if called with a pointer rather than an array. */ +#define ARRAY_LENGTH_UNSAFE(array) \ + (sizeof(array) / sizeof(*(array))) + +#if defined(__GNUC__) +/* Test if arg and &(arg)[0] have the same type. This is true if arg is + * an array but not if it's a pointer. */ +#define IS_ARRAY_NOT_POINTER(arg) \ + (!__builtin_types_compatible_p(__typeof__(arg), \ + __typeof__(&(arg)[0]))) +/* A compile-time constant with the value 0. If `const_expr` is not a + * compile-time constant with a nonzero value, cause a compile-time error. */ +#define STATIC_ASSERT_EXPR(const_expr) \ + (0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); })) + +/* Return the scalar value `value` (possibly promoted). This is a compile-time + * constant if `value` is. `condition` must be a compile-time constant. + * If `condition` is false, arrange to cause a compile-time error. */ +#define STATIC_ASSERT_THEN_RETURN(condition, value) \ + (STATIC_ASSERT_EXPR(condition) ? 0 : (value)) + +#define ARRAY_LENGTH(array) \ + (STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array), \ + ARRAY_LENGTH_UNSAFE(array))) + +#else +/* If we aren't sure the compiler supports our non-standard tricks, + * fall back to the unsafe implementation. */ +#define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array) +#endif /** Allow library to access its structs' private members. * * Although structs defined in header files are publicly available, diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 399e7f3879..f735d88aa3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -84,8 +84,6 @@ #include "mbedtls/sha512.h" #include "md_psa.h" -#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array))) - #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index a7cb9b513a..a10cb2b476 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -36,8 +36,6 @@ #include #include "mbedtls/platform.h" -#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array))) - typedef struct { psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT]; unsigned key_slots_initialized : 1; diff --git a/library/sha512.c b/library/sha512.c index b8b24854d7..ff92a1b81b 100644 --- a/library/sha512.c +++ b/library/sha512.c @@ -1001,8 +1001,6 @@ static sha_test_sum_t sha512_test_sum[] = }; #endif /* MBEDTLS_SHA512_C */ -#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) - static int mbedtls_sha512_common_self_test(int verbose, int is384) { int i, buflen, ret = 0; diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 7601e5b117..fc44dbe28c 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -759,8 +759,6 @@ void mbedtls_ssl_print_extensions(const mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) -#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(*(a))) - static const char *ticket_flag_name_table[] = { [0] = "ALLOW_PSK_RESUMPTION", diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h index ab8260b759..01eaff5c20 100644 --- a/tests/include/test/macros.h +++ b/tests/include/test/macros.h @@ -196,45 +196,6 @@ mbedtls_exit(1); \ } -/** \def ARRAY_LENGTH - * Return the number of elements of a static or stack array. - * - * \param array A value of array (not pointer) type. - * - * \return The number of elements of the array. - */ -/* A correct implementation of ARRAY_LENGTH, but which silently gives - * a nonsensical result if called with a pointer rather than an array. */ -#define ARRAY_LENGTH_UNSAFE(array) \ - (sizeof(array) / sizeof(*(array))) - -#if defined(__GNUC__) -/* Test if arg and &(arg)[0] have the same type. This is true if arg is - * an array but not if it's a pointer. */ -#define IS_ARRAY_NOT_POINTER(arg) \ - (!__builtin_types_compatible_p(__typeof__(arg), \ - __typeof__(&(arg)[0]))) -/* A compile-time constant with the value 0. If `const_expr` is not a - * compile-time constant with a nonzero value, cause a compile-time error. */ -#define STATIC_ASSERT_EXPR(const_expr) \ - (0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); })) - -/* Return the scalar value `value` (possibly promoted). This is a compile-time - * constant if `value` is. `condition` must be a compile-time constant. - * If `condition` is false, arrange to cause a compile-time error. */ -#define STATIC_ASSERT_THEN_RETURN(condition, value) \ - (STATIC_ASSERT_EXPR(condition) ? 0 : (value)) - -#define ARRAY_LENGTH(array) \ - (STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array), \ - ARRAY_LENGTH_UNSAFE(array))) - -#else -/* If we aren't sure the compiler supports our non-standard tricks, - * fall back to the unsafe implementation. */ -#define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array) -#endif - /** Return the smaller of two values. * * \param x An integer-valued expression without side effects. diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c index 77c2f89764..8f58d4dc16 100644 --- a/tests/src/psa_crypto_helpers.c +++ b/tests/src/psa_crypto_helpers.c @@ -24,6 +24,7 @@ #include #include #include +#include "common.h" #if defined(MBEDTLS_PSA_CRYPTO_C) From 1e4a030b003ef813f179d66be1fd0cd88cdfe306 Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Tue, 30 May 2023 09:45:17 -0400 Subject: [PATCH 11/89] Fix wrong array size calculation in error translation code Signed-off-by: Andrzej Kurek --- library/constant_time.c | 2 +- library/lmots.c | 2 +- library/lms.c | 2 +- library/ssl_cookie.c | 2 +- library/ssl_msg.c | 2 +- library/ssl_ticket.c | 2 +- library/ssl_tls.c | 4 ++-- library/ssl_tls12_client.c | 2 +- library/ssl_tls12_server.c | 2 +- library/ssl_tls13_client.c | 2 +- library/ssl_tls13_generic.c | 2 +- library/ssl_tls13_keys.c | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index 9b2a47758f..f1dbd04e62 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -54,7 +54,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/lmots.c b/library/lmots.c index a3bfff89f8..4ef2c5178e 100644 --- a/library/lmots.c +++ b/library/lmots.c @@ -50,7 +50,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_lms_errors, - sizeof(psa_to_lms_errors), + ARRAY_LENGTH(psa_to_lms_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/lms.c b/library/lms.c index 50595703de..823ce09f89 100644 --- a/library/lms.c +++ b/library/lms.c @@ -51,7 +51,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_lms_errors, - sizeof(psa_to_lms_errors), + ARRAY_LENGTH(psa_to_lms_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c index 371edce3a9..098acedd3b 100644 --- a/library/ssl_cookie.c +++ b/library/ssl_cookie.c @@ -42,7 +42,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index f1906570c5..e9050230b3 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -54,7 +54,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c index 54c00cc0c6..1adaa07fe2 100644 --- a/library/ssl_ticket.c +++ b/library/ssl_ticket.c @@ -36,7 +36,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index fc44dbe28c..9f3b3be3f9 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -56,7 +56,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) @@ -64,7 +64,7 @@ static int local_err_translation(psa_status_t status) static int local_md_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_md_errors, - sizeof(psa_to_md_errors), + ARRAY_LENGTH(psa_to_md_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MD_ERR(status) local_md_translation(status) diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index ade68a9272..28f9cdbff4 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -39,7 +39,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 03f9eea856..9e122d6b89 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -41,7 +41,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 64d905cbea..eb733b3a98 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -40,7 +40,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 48e6f76e9d..e58c3e5b87 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -44,7 +44,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 08d10a3549..81daf0a8b6 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -41,7 +41,7 @@ static int local_err_translation(psa_status_t status) { return psa_status_to_mbedtls(status, psa_to_ssl_errors, - sizeof(psa_to_ssl_errors), + ARRAY_LENGTH(psa_to_ssl_errors), psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) From f1b659ed62e9c9de1796d753d952a180699976a0 Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Tue, 30 May 2023 09:45:17 -0400 Subject: [PATCH 12/89] Move an include ARRAY_LENGTH macro was previously present in macros.h, so move the include there. Signed-off-by: Andrzej Kurek --- tests/include/test/macros.h | 1 + tests/src/psa_crypto_helpers.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h index 01eaff5c20..ae84ec2363 100644 --- a/tests/include/test/macros.h +++ b/tests/include/test/macros.h @@ -33,6 +33,7 @@ #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) #include "mbedtls/memory_buffer_alloc.h" #endif +#include "common.h" /** * \brief This macro tests the expression passed to it as a test step or diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c index 8f58d4dc16..77c2f89764 100644 --- a/tests/src/psa_crypto_helpers.c +++ b/tests/src/psa_crypto_helpers.c @@ -24,7 +24,6 @@ #include #include #include -#include "common.h" #if defined(MBEDTLS_PSA_CRYPTO_C) From a6033ac431503d7de23c4dfb497051715bcba1fe Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Tue, 30 May 2023 15:16:34 -0400 Subject: [PATCH 13/89] Add missing guards in tls 1.3 Error translation is only used with these defines on. Signed-off-by: Andrzej Kurek --- library/ssl_tls13_client.c | 3 +++ library/ssl_tls13_generic.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index eb733b3a98..6ec3170076 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -35,6 +35,7 @@ #include "ssl_debug_helpers.h" #include "md_psa.h" +#if defined(PSA_WANT_ALG_ECDH) /* Define a local translating function to save code size by not using too many * arguments in each translating place. */ static int local_err_translation(psa_status_t status) @@ -44,6 +45,8 @@ static int local_err_translation(psa_status_t status) psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) +#endif + /* Write extensions */ /* diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index e58c3e5b87..fa193ffb63 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -39,6 +39,8 @@ #include "psa/crypto.h" #include "mbedtls/psa_util.h" +#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) || \ + defined(PSA_WANT_ALG_ECDH) /* Define a local translating function to save code size by not using too many * arguments in each translating place. */ static int local_err_translation(psa_status_t status) @@ -48,6 +50,7 @@ static int local_err_translation(psa_status_t status) psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) +#endif const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[ MBEDTLS_SERVER_HELLO_RANDOM_LEN] = From 009c06b9731011335f9107f694c41bb256854279 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 13 Jun 2023 21:10:05 +0200 Subject: [PATCH 14/89] Discuss the cost of a get_key_attributes entry point Signed-off-by: Gilles Peskine --- docs/architecture/psa-storage-resilience.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/architecture/psa-storage-resilience.md b/docs/architecture/psa-storage-resilience.md index 593c8623af..869eb151e7 100644 --- a/docs/architecture/psa-storage-resilience.md +++ b/docs/architecture/psa-storage-resilience.md @@ -153,11 +153,13 @@ There are four cases for recovery when a transaction is in progress. In each cas From the analysis above, assuming that all keys are treated in the same way, there are 4 possible strategies. -* [Always follow the state of the secure element](#exploring-the-follow-the-secure-element-strategy). This requires the secure element to have a `"get_key_attributes"` entry point. Recovery means resuming the operation where it left off. For key creation, this means that the key metadata needs to be saved before calling the secure element's key creation entry point. +* [Always follow the state of the secure element](#exploring-the-follow-the-secure-element-strategy). This requires the secure element driver to have a `"get_key_attributes"` entry point. Recovery means resuming the operation where it left off. For key creation, this means that the key metadata needs to be saved before calling the secure element's key creation entry point. * Minimize the information processing: [always destroy the key](#exploring-the-always-destroy-strategy), i.e. abort all key creations and commit all key destructions. This does not require querying the state of the secure element. This does not require any special precautions to preserve information about the key during the transaction. It simplifies recovery in that the recovery process might not even need to know whether it's recovering a key creation or a key destruction. -* Follow the state of the secure element for key creation, but always go ahead with key destruction. This requires the secure element to have a `"get_key_attributes"` entry point. Compared to always following the state of the secure element, this has the advantage of maximizing the chance that a command to destroy key material is effective. Compared to always destroying the key, this has a performance advantage if a key creation is interrupted. These do not seem like decisive advantages, so we will not consider this strategy further. +* Follow the state of the secure element for key creation, but always go ahead with key destruction. This requires the secure element driver to have a `"get_key_attributes"` entry point. Compared to always following the state of the secure element, this has the advantage of maximizing the chance that a command to destroy key material is effective. Compared to always destroying the key, this has a performance advantage if a key creation is interrupted. These do not seem like decisive advantages, so we will not consider this strategy further. * Always abort key creation, but follow the state of the secure element for key destruction. I can't think of a good reason to choose this strategy. +Requiring the driver to have a `"get_key_attributes"` entry point is potentially problematic because some secure elements don't have room to store key attributes: a key slot always exists, and it's up to the user to remember what, if anything, they put in it. The driver has to remember anyway, so that it can find a free slot when creating a key. But with a recovery strategy that doesn't involve a `"get_key_attributes"` entry point, the driver design is easier: the driver doesn't need to protect the information about slots in use against a power failure, the core takes care of that. + #### Exploring the follow-the-secure-element strategy Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), the driver key identifier, and an indication of whether the key is being created or destroyed. @@ -336,6 +338,8 @@ In order to conveniently support multiple transactions at the same time, we pick * During key creation, create the key file in internal storage in the internal storage before calling the secure element's key creation entry point. * During key destruction, call the secure element's key destruction entry point before removing the key file in internal storage. +This choice of algorithm does not require the secure element driver to have a `"get_key_attributes"` entry point. + #### Chosen storage invariant The [storage invariant](#storage-invariant-if-the-transaction-list-contains-application-key-identifiers-only) is as follows: From 34a201774e90acbc9bdb8e8fa2797d0289611b14 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 13 Jun 2023 21:11:06 +0200 Subject: [PATCH 15/89] More about whether to have the driver key id in the transaction list Signed-off-by: Gilles Peskine --- docs/architecture/psa-storage-resilience.md | 39 ++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-storage-resilience.md b/docs/architecture/psa-storage-resilience.md index 869eb151e7..2f190d3f89 100644 --- a/docs/architecture/psa-storage-resilience.md +++ b/docs/architecture/psa-storage-resilience.md @@ -162,7 +162,7 @@ Requiring the driver to have a `"get_key_attributes"` entry point is potentially #### Exploring the follow-the-secure-element strategy -Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), the driver key identifier, and an indication of whether the key is being created or destroyed. +Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), the driver key identifier (not constant-size), and an indication of whether the key is being created or destroyed. For key creation, we have all the information to store in the key file once the `"allocate_key"` call returns. We must store all the information that will go in the key file before calling the driver's key creation entry point. Therefore the normal sequence of operations is: @@ -191,7 +191,7 @@ During recovery, for each key in the transaction list that was being created: #### Exploring the always-destroy strategy -Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), and the driver key identifier. +Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), and the driver key identifier (not constant-size). For key creation, we do not need to store the key's metadata until it has been created in the secure element. Therefore the normal sequence of operations is: @@ -214,6 +214,37 @@ Recovery means removing all traces of all keys on the transaction list. This mea 2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success. 3. Remove the key from the transaction list. +#### Always-destroy strategy with a simpler transaction file + +We can modify the [always-destroy strategy](#exploring-the-always-destroy-strategy) to make the transaction file simpler: if we ensure that the key file always exists if the key exists in the secure element, then the transaction list does not need to include the driver key identifier: it can be read from the key file. + +For key creation, we need to store the key's metadata before creating in the secure element. Therefore the normal sequence of operations is: + +1. Call the driver's `"allocate_key"` entry point. +2. Add the key to the transaction list. +3. Write the key file. +4. Call the driver's key creation entry point. +5. Remove the key from the transaction list. + +For key destruction, we need to contact the secure element before removing the key file. Therefore the normal sequence of operations is: + +1. Add the key to the transaction list. +2. Call the driver's `"destroy_key"` entry point. +3. Remove the key file. +4. Remove the key from the transaction list. + +Recovery means removing all traces of all keys on the transaction list. This means following the destruction process, starting after the point where the key has been added to the transaction list, and ignoring any failure of a removal action if the item to remove does not exist: + +1. Load the driver key identifier from the key file. If the key file does not exist, skip to step 4. +2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success. +3. Remove the key file, treating `DOES_NOT_EXIST` as a success. +4. Remove the key from the transaction list. + +Compared with the basic always-destroy strategy: + +* The transaction file handling is simpler since its entries have a fixed size. +* The flow of information is somewhat different from transparent keys and keys in stateless secure elements: we aren't just replacing “create the key material” by “tell the secure element to create the key material”, those happen at different times. But there's a different flow for stateful secure elements anyway, since the call to `"allocate_key"` has no analog in the stateless secure element or transparent cases. + #### Assisting secure element drivers with recovery The actions of the secure element driver may themselves be non-atomic. So the driver must be given a chance to perform recovery. @@ -350,7 +381,7 @@ The [storage invariant](#storage-invariant-if-the-transaction-list-contains-appl #### Chosen recovery process -To [assist secure element drivers with recovery](#assisting-secure-element-drivers-with-recovery), we pick the [always-destroy recovery strategy](#exploring-the-always-destroy-strategy). The the recovery process is as follows: +To [assist secure element drivers with recovery](#assisting-secure-element-drivers-with-recovery), we pick the [always-destroy recovery strategy with a simple transaction file](#always-destroy-strategy-with-a-simpler-transaction-file). The the recovery process is as follows: * If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list. * If the file `id` exists, call the secure element's key destruction entry point (treating a `DOES_NOT_EXIST` error as a success), then remove `id`. @@ -411,7 +442,7 @@ If any step fails, remember the error but continue the process, to destroy the r For each key _A_ in the transaction list file, if the file _A_ exists in the internal storage: -1. Load the key into a key slot in memory. +1. Load the key into a key slot in memory (to get its location and the driver key identifier, although we could get the location from the transaction list). 2. Call the secure element's `"destroy_key"` entry point. 3. Remove the key file _A_ from the internal storage. 4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation). From 15ddda9ff8a2f8e92fff104335f9afb58d129d72 Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Wed, 14 Jun 2023 07:37:46 -0400 Subject: [PATCH 16/89] Remove PSA_TO_MD_ERR from ssl_tls.c Signed-off-by: Andrzej Kurek --- library/ssl_tls.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 9f3b3be3f9..bc9f4f8ee0 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -60,14 +60,6 @@ static int local_err_translation(psa_status_t status) psa_generic_status_to_mbedtls); } #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) - -static int local_md_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_md_errors, - ARRAY_LENGTH(psa_to_md_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MD_ERR(status) local_md_translation(status) #endif #if defined(MBEDTLS_TEST_HOOKS) From 838dc46a7b3b62a6a1044e0542f1e53a4d4c305c Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 13:18:19 +0100 Subject: [PATCH 17/89] Test asm and intrinsics from all.sh Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 78666b41f2..61288511c1 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3448,6 +3448,35 @@ component_test_malloc_0_null () { tests/ssl-opt.sh -e 'proxy' } +support_test_aesni () { + # require an x64_64 target + gcc -v 2>&1 | grep Target | grep -q x86_64 +} + +component_test_aesni () { # ~ 20s + msg "build: default config with MBEDTLS_HAVE_ASM and MBEDTLS_AESNI_C enabled" + scripts/config.py set MBEDTLS_AESNI_C + scripts/config.py set MBEDTLS_HAVE_ASM + + msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=1 (asm)" + make lib tests CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_AESNI_HAVE_CODE=1' + cd tests + for t in `find . -type f -executable -name '*aes*'`; do + # Run all the suites with aes in their name + ./$t + done + cd .. + + msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=2 (intrinsics)" + make clean + make lib tests CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -mpclmul -msse2 -maes -DMBEDTLS_AESNI_HAVE_CODE=2' + cd tests + for t in `find . -type f -executable -name '*aes*'`; do + ./$t + done + cd .. +} + component_test_aes_fewer_tables () { msg "build: default config with AES_FEWER_TABLES enabled" scripts/config.py set MBEDTLS_AES_FEWER_TABLES From e07c670e4719882bdd58d0e3c7ad5ed4efb31577 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 13:21:28 +0100 Subject: [PATCH 18/89] Allow all.sh to override intrinsics vs asm selection Signed-off-by: Dave Rodgman --- library/aesni.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/library/aesni.h b/library/aesni.h index a054cfd5c1..97b3abbefc 100644 --- a/library/aesni.h +++ b/library/aesni.h @@ -59,9 +59,14 @@ #define MBEDTLS_AESNI_HAVE_INTRINSICS #endif -/* Choose the implementation of AESNI, if one is available. */ -#undef MBEDTLS_AESNI_HAVE_CODE -/* Favor the intrinsics-based implementation if it's available, for better +/* Normally MBEDTLS_AESNI_HAVE_CODE is automatically set below. It may be + * set from all.sh to ensure coverage of both asm and intrinsics, in which + * case we do not over-ride it. */ +#if !defined(MBEDTLS_AESNI_HAVE_CODE) + +/* Choose the implementation of AESNI, if one is available. + * + * Favor the intrinsics-based implementation if it's available, for better * maintainability. * Performance is about the same (see #7380). * In the long run, we will likely remove the assembly implementation. */ @@ -70,6 +75,7 @@ #elif defined(MBEDTLS_HAVE_X86_64) #define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly #endif +#endif /* !defined(MBEDTLS_AESNI_HAVE_CODE) */ #if defined(MBEDTLS_AESNI_HAVE_CODE) From c2b7264b836d6f56ddc7ada6c0646a2750d43784 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 16:24:42 +0100 Subject: [PATCH 19/89] Simplify aesni test Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 61288511c1..a15995b77b 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3453,28 +3453,17 @@ support_test_aesni () { gcc -v 2>&1 | grep Target | grep -q x86_64 } -component_test_aesni () { # ~ 20s +component_test_aesni () { # ~ 40s msg "build: default config with MBEDTLS_HAVE_ASM and MBEDTLS_AESNI_C enabled" scripts/config.py set MBEDTLS_AESNI_C scripts/config.py set MBEDTLS_HAVE_ASM msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=1 (asm)" - make lib tests CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_AESNI_HAVE_CODE=1' - cd tests - for t in `find . -type f -executable -name '*aes*'`; do - # Run all the suites with aes in their name - ./$t - done - cd .. - + make test CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_AESNI_HAVE_CODE=1' + msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=2 (intrinsics)" make clean - make lib tests CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -mpclmul -msse2 -maes -DMBEDTLS_AESNI_HAVE_CODE=2' - cd tests - for t in `find . -type f -executable -name '*aes*'`; do - ./$t - done - cd .. + make test CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -mpclmul -msse2 -maes -DMBEDTLS_AESNI_HAVE_CODE=2' } component_test_aes_fewer_tables () { From be60fcca784fe5cf502ffced2f86ca682f8059c2 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 17:04:52 +0100 Subject: [PATCH 20/89] Add test for plain C path Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index a15995b77b..39a787a865 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3454,16 +3454,24 @@ support_test_aesni () { } component_test_aesni () { # ~ 40s - msg "build: default config with MBEDTLS_HAVE_ASM and MBEDTLS_AESNI_C enabled" + msg "build: default config with different AES implementations" scripts/config.py set MBEDTLS_AESNI_C scripts/config.py set MBEDTLS_HAVE_ASM + # test asm msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=1 (asm)" make test CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_AESNI_HAVE_CODE=1' - + + # test intrinsics msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=2 (intrinsics)" make clean make test CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -mpclmul -msse2 -maes -DMBEDTLS_AESNI_HAVE_CODE=2' + + # test plain C + scripts/config.py unset MBEDTLS_AESNI_C + msg "AES tests, plain C" + make clean + make test CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra' } component_test_aes_fewer_tables () { From fa1d05ccfd0d45e2964fefbd15c14a34c32e78be Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 19:52:49 +0100 Subject: [PATCH 21/89] Remove not-needed compiler flags Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 19575998ce..00f7225904 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3515,18 +3515,18 @@ component_test_aesni () { # ~ 40s # test asm msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=1 (asm)" - make test CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -DMBEDTLS_AESNI_HAVE_CODE=1' + make test CC=gcc CFLAGS='-O2 -Werror -DMBEDTLS_AESNI_HAVE_CODE=1' # test intrinsics msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=2 (intrinsics)" make clean - make test CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra -mpclmul -msse2 -maes -DMBEDTLS_AESNI_HAVE_CODE=2' + make test CC=gcc CFLAGS='-O2 -Werror -mpclmul -msse2 -maes -DMBEDTLS_AESNI_HAVE_CODE=2' # test plain C scripts/config.py unset MBEDTLS_AESNI_C msg "AES tests, plain C" make clean - make test CC=gcc CFLAGS='-O2 -Werror -Wall -Wextra' + make test CC=gcc CFLAGS='-O2 -Werror' } component_test_aes_only_128_bit_keys () { From 96a9e6a9dd84cc549312e24ac9328751c37ee13b Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 20:18:36 +0100 Subject: [PATCH 22/89] Address test review comments Signed-off-by: Dave Rodgman --- library/aes.c | 7 +++++++ library/aesni.h | 6 ------ tests/scripts/all.sh | 35 +++++++++++++++++++++++++---------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/library/aes.c b/library/aes.c index 0a61d1b070..08e3caadd0 100644 --- a/library/aes.c +++ b/library/aes.c @@ -1824,6 +1824,13 @@ int mbedtls_aes_self_test(int verbose) } else #endif #if defined(MBEDTLS_AESNI_HAVE_CODE) +#if MBEDTLS_AESNI_HAVE_CODE == 1 + mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n"); +#elif MBEDTLS_AESNI_HAVE_CODE == 2 + mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n"); +#else +#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE +#endif if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { mbedtls_printf(" AES note: using AESNI.\n"); } else diff --git a/library/aesni.h b/library/aesni.h index 97b3abbefc..82947e4583 100644 --- a/library/aesni.h +++ b/library/aesni.h @@ -59,11 +59,6 @@ #define MBEDTLS_AESNI_HAVE_INTRINSICS #endif -/* Normally MBEDTLS_AESNI_HAVE_CODE is automatically set below. It may be - * set from all.sh to ensure coverage of both asm and intrinsics, in which - * case we do not over-ride it. */ -#if !defined(MBEDTLS_AESNI_HAVE_CODE) - /* Choose the implementation of AESNI, if one is available. * * Favor the intrinsics-based implementation if it's available, for better @@ -75,7 +70,6 @@ #elif defined(MBEDTLS_HAVE_X86_64) #define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly #endif -#endif /* !defined(MBEDTLS_AESNI_HAVE_CODE) */ #if defined(MBEDTLS_AESNI_HAVE_CODE) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 00f7225904..3ccab95e05 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3508,25 +3508,40 @@ support_test_aesni () { gcc -v 2>&1 | grep Target | grep -q x86_64 } -component_test_aesni () { # ~ 40s +component_test_aesni () { # ~ 60s + # This tests the two AESNI implementations (intrinsics and assembly), and also the plain C + # fallback. It also tests the logic that is used to select which implementation(s) to build. + # + # This test does not require the host to have support for AESNI (if it doesn't, the run-time + # AESNI detection will fallback to the plain C implementation, so the tests will instead + # exercise the plain C impl). + msg "build: default config with different AES implementations" scripts/config.py set MBEDTLS_AESNI_C scripts/config.py set MBEDTLS_HAVE_ASM - # test asm - msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=1 (asm)" - make test CC=gcc CFLAGS='-O2 -Werror -DMBEDTLS_AESNI_HAVE_CODE=1' - - # test intrinsics - msg "AES tests, MBEDTLS_AESNI_HAVE_CODE=2 (intrinsics)" + # test the intrinsics implementation + msg "AES tests, test intrinsics" make clean - make test CC=gcc CFLAGS='-O2 -Werror -mpclmul -msse2 -maes -DMBEDTLS_AESNI_HAVE_CODE=2' + make test programs/test/selftest CC=gcc CFLAGS='-Werror -Wall -Wextra -mpclmul -msse2 -maes' + # check that we built intrinsics - this should be used by default when supported by the compiler + ./programs/test/selftest | grep "AESNI code" | grep -q "intrinsics" || false "intrinsics not built when supported" - # test plain C + # test the asm implementation + msg "AES tests, test assembly" + make clean + make test programs/test/selftest CC=gcc CFLAGS='-Werror -Wall -Wextra -mno-pclmul -mno-sse2 -mno-aes' + # check that we built assembly - this should be built if the compiler does not support intrinsics + ./programs/test/selftest | grep "AESNI code" | grep -q "assembly" || false "assembly not built when intrinsics not supported" + + # test the plain C implementation scripts/config.py unset MBEDTLS_AESNI_C msg "AES tests, plain C" make clean - make test CC=gcc CFLAGS='-O2 -Werror' + make test programs/test/selftest CC=gcc CFLAGS='-O2 -Werror' + # check that there is no AESNI code present + ./programs/test/selftest | grep -q "AESNI code" && false "AESNI code built when MBEDTLS_AESNI_C unset" + } component_test_aes_only_128_bit_keys () { From 086e137dc4d9e5c00e9bb713b8858f18fdf934b9 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 20:21:39 +0100 Subject: [PATCH 23/89] code style Signed-off-by: Dave Rodgman --- library/aes.c | 4 ++-- tests/scripts/all.sh | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/library/aes.c b/library/aes.c index 08e3caadd0..bd0317c871 100644 --- a/library/aes.c +++ b/library/aes.c @@ -1825,9 +1825,9 @@ int mbedtls_aes_self_test(int verbose) #endif #if defined(MBEDTLS_AESNI_HAVE_CODE) #if MBEDTLS_AESNI_HAVE_CODE == 1 - mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n"); + mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n"); #elif MBEDTLS_AESNI_HAVE_CODE == 2 - mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n"); + mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n"); #else #error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE #endif diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 3ccab95e05..730c804ff4 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3541,7 +3541,6 @@ component_test_aesni () { # ~ 60s make test programs/test/selftest CC=gcc CFLAGS='-O2 -Werror' # check that there is no AESNI code present ./programs/test/selftest | grep -q "AESNI code" && false "AESNI code built when MBEDTLS_AESNI_C unset" - } component_test_aes_only_128_bit_keys () { From 336a4530c5e46036c5aeebc61cb5c1db6f1f6943 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 20:22:04 +0100 Subject: [PATCH 24/89] Fix typo Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 730c804ff4..23615f214b 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3504,7 +3504,7 @@ component_test_malloc_0_null () { } support_test_aesni () { - # require an x64_64 target + # require an x86_64 target gcc -v 2>&1 | grep Target | grep -q x86_64 } From 48d8e83472df5da0372a44f2c056ba3469ccf687 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 21:05:05 +0100 Subject: [PATCH 25/89] fix CI failure Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 23615f214b..369eb243fe 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3540,7 +3540,7 @@ component_test_aesni () { # ~ 60s make clean make test programs/test/selftest CC=gcc CFLAGS='-O2 -Werror' # check that there is no AESNI code present - ./programs/test/selftest | grep -q "AESNI code" && false "AESNI code built when MBEDTLS_AESNI_C unset" + ./programs/test/selftest | grep -qv "AESNI code" || false "AESNI code built when MBEDTLS_AESNI_C unset" } component_test_aes_only_128_bit_keys () { From f87e5268ec3720cc8b902c80cc69f17b8ae90aa6 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 22:03:44 +0100 Subject: [PATCH 26/89] Fix test error Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 369eb243fe..16926a5cba 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3538,9 +3538,9 @@ component_test_aesni () { # ~ 60s scripts/config.py unset MBEDTLS_AESNI_C msg "AES tests, plain C" make clean - make test programs/test/selftest CC=gcc CFLAGS='-O2 -Werror' + make test programs/test/selftest CC=x86_64-linux-gnu-gcc-10 CFLAGS='-O2 -Werror' # check that there is no AESNI code present - ./programs/test/selftest | grep -qv "AESNI code" || false "AESNI code built when MBEDTLS_AESNI_C unset" + ! ( ./programs/test/selftest | grep -q "AESNI code") || false "AESNI code built when MBEDTLS_AESNI_C unset" } component_test_aes_only_128_bit_keys () { From f18a7e1f86b085161138c047391acecb1dfc607d Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 16 Jun 2023 22:41:18 +0100 Subject: [PATCH 27/89] Fix typo Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 16926a5cba..a140f71852 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3538,7 +3538,7 @@ component_test_aesni () { # ~ 60s scripts/config.py unset MBEDTLS_AESNI_C msg "AES tests, plain C" make clean - make test programs/test/selftest CC=x86_64-linux-gnu-gcc-10 CFLAGS='-O2 -Werror' + make test programs/test/selftest CC=gcc CFLAGS='-O2 -Werror' # check that there is no AESNI code present ! ( ./programs/test/selftest | grep -q "AESNI code") || false "AESNI code built when MBEDTLS_AESNI_C unset" } From 20cc563462e2ad2d704829cb7b58ce71bae351be Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 19 Jun 2023 10:27:31 +0100 Subject: [PATCH 28/89] Improve logic for checking for presence of AESNI code Co-authored-by: Gilles Peskine Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index a140f71852..55128c2ca5 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3525,7 +3525,7 @@ component_test_aesni () { # ~ 60s make clean make test programs/test/selftest CC=gcc CFLAGS='-Werror -Wall -Wextra -mpclmul -msse2 -maes' # check that we built intrinsics - this should be used by default when supported by the compiler - ./programs/test/selftest | grep "AESNI code" | grep -q "intrinsics" || false "intrinsics not built when supported" + ./programs/test/selftest | grep "AESNI code" | grep -q "intrinsics" # test the asm implementation msg "AES tests, test assembly" @@ -3540,7 +3540,7 @@ component_test_aesni () { # ~ 60s make clean make test programs/test/selftest CC=gcc CFLAGS='-O2 -Werror' # check that there is no AESNI code present - ! ( ./programs/test/selftest | grep -q "AESNI code") || false "AESNI code built when MBEDTLS_AESNI_C unset" + ./programs/test/selftest | not grep -q "AESNI code" } component_test_aes_only_128_bit_keys () { From b9590270103b114baefc4eb57863468e5e54148a Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 19 Jun 2023 10:28:45 +0100 Subject: [PATCH 29/89] Improve logic for checking for presence of AESNI code Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 55128c2ca5..3e83ee1061 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3532,7 +3532,7 @@ component_test_aesni () { # ~ 60s make clean make test programs/test/selftest CC=gcc CFLAGS='-Werror -Wall -Wextra -mno-pclmul -mno-sse2 -mno-aes' # check that we built assembly - this should be built if the compiler does not support intrinsics - ./programs/test/selftest | grep "AESNI code" | grep -q "assembly" || false "assembly not built when intrinsics not supported" + ./programs/test/selftest | grep "AESNI code" | grep -q "assembly" # test the plain C implementation scripts/config.py unset MBEDTLS_AESNI_C From f8986e31475e97bb8b1c22f3181c816264a7b924 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 19 Jun 2023 10:55:59 +0100 Subject: [PATCH 30/89] Clarify support_test_aesni Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 3e83ee1061..56ad2a4f98 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3503,11 +3503,24 @@ component_test_malloc_0_null () { tests/ssl-opt.sh -e 'proxy' } -support_test_aesni () { - # require an x86_64 target +support_build_aesni() { + # Check that gcc targets x86_64 gcc -v 2>&1 | grep Target | grep -q x86_64 } +support_run_aesni() { + # Check for AESNI support on the host. + # + # In principle 32-bit x86 can support AESNI, but our implementation does not + # support 32-bit x86, so we check for x86-64. + # We can only grep /proc/cpuinfo on Linux, so this also checks for Linux + [[ "$HOSTTYPE" == "x86_64" && "$OSTYPE" == "linux-gnu" ]] && Date: Mon, 19 Jun 2023 11:51:33 +0100 Subject: [PATCH 31/89] Simplify aesni support test Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 56ad2a4f98..3c6530fb7c 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3503,22 +3503,19 @@ component_test_malloc_0_null () { tests/ssl-opt.sh -e 'proxy' } -support_build_aesni() { - # Check that gcc targets x86_64 - gcc -v 2>&1 | grep Target | grep -q x86_64 -} - -support_run_aesni() { - # Check for AESNI support on the host. +support_test_aesni() { + # Check that gcc targets x86_64 (we can build AESNI), and check for + # AESNI support on the host (we can run AESNI). + # + # The name of this function is possibly slightly misleading, but needs to align + # with the name of the corresponding test, component_test_aesni. # # In principle 32-bit x86 can support AESNI, but our implementation does not # support 32-bit x86, so we check for x86-64. # We can only grep /proc/cpuinfo on Linux, so this also checks for Linux - [[ "$HOSTTYPE" == "x86_64" && "$OSTYPE" == "linux-gnu" ]] && &1 | grep Target | grep -q x86_64) && + [[ "$HOSTTYPE" == "x86_64" && "$OSTYPE" == "linux-gnu" ]] && + (grep '^flags' /proc/cpuinfo | grep -w aes) } component_test_aesni () { # ~ 60s From 3d9af4734fcdb8a85094abbeb70ca7e93e33d494 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 19 Jun 2023 12:10:11 +0100 Subject: [PATCH 32/89] Fix tests? Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 3c6530fb7c..d59a0c8595 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3515,7 +3515,7 @@ support_test_aesni() { # We can only grep /proc/cpuinfo on Linux, so this also checks for Linux (gcc -v 2>&1 | grep Target | grep -q x86_64) && [[ "$HOSTTYPE" == "x86_64" && "$OSTYPE" == "linux-gnu" ]] && - (grep '^flags' /proc/cpuinfo | grep -w aes) + (grep '^flags' /proc/cpuinfo | grep -qw aes) } component_test_aesni () { # ~ 60s From 2016fa35cb0b362eca5e7ab68cd7134f86954170 Mon Sep 17 00:00:00 2001 From: Andrzej Kurek Date: Tue, 20 Jun 2023 06:14:49 -0400 Subject: [PATCH 33/89] Use DER format for x509 SAN tests This way there's no dependency on PEM parsing. Signed-off-by: Andrzej Kurek --- tests/data_files/Makefile | 20 +++++++-------- tests/data_files/parse_input/server5-fan.crt | 10 -------- .../parse_input/server5-fan.crt.der | Bin 0 -> 408 bytes .../server5-nonprintable_othername.crt | 12 --------- .../server5-nonprintable_othername.crt.der | Bin 0 -> 483 bytes .../parse_input/server5-othername.crt | 11 -------- .../parse_input/server5-othername.crt.der | Bin 0 -> 449 bytes .../server5-unsupported_othername.crt | 12 --------- .../server5-unsupported_othername.crt.der | Bin 0 -> 472 bytes tests/suites/test_suite_x509parse.data | 24 +++++++++--------- 10 files changed, 22 insertions(+), 67 deletions(-) delete mode 100644 tests/data_files/parse_input/server5-fan.crt create mode 100644 tests/data_files/parse_input/server5-fan.crt.der delete mode 100644 tests/data_files/parse_input/server5-nonprintable_othername.crt create mode 100644 tests/data_files/parse_input/server5-nonprintable_othername.crt.der delete mode 100644 tests/data_files/parse_input/server5-othername.crt create mode 100644 tests/data_files/parse_input/server5-othername.crt.der delete mode 100644 tests/data_files/parse_input/server5-unsupported_othername.crt create mode 100644 tests/data_files/parse_input/server5-unsupported_othername.crt.der diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile index 0c2fa141a6..85b2b177f3 100644 --- a/tests/data_files/Makefile +++ b/tests/data_files/Makefile @@ -428,21 +428,23 @@ server5-ss-forgeca.crt: server5.key $(FAKETIME) '2015-09-01 14:08:43' $(OPENSSL) req -x509 -new -subj "/C=UK/O=mbed TLS/CN=mbed TLS Test intermediate CA 3" -set_serial 77 -config $(test_ca_config_file) -extensions noext_ca -days 3650 -sha256 -key $< -out $@ all_final += server5-ss-forgeca.crt -server5-othername.crt: server5.key - $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions othername_san -days 3650 -sha256 -key $< -out $@ +server5-othername.crt.der: server5.key + $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions othername_san -days 3650 -sha256 -key $< -outform der -out $@ -server5-nonprintable_othername.crt: server5.key - $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS non-printable othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions nonprintable_othername_san -days 3650 -sha256 -key $< -out $@ +server5-nonprintable_othername.crt.der: server5.key + $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS non-printable othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions nonprintable_othername_san -days 3650 -sha256 -key $< -outform der -out $@ -server5-unsupported_othername.crt: server5.key - $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS unsupported othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions unsupported_othername_san -days 3650 -sha256 -key $< -out $@ +server5-unsupported_othername.crt.der: server5.key + $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS unsupported othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions unsupported_othername_san -days 3650 -sha256 -key $< -outform der -out $@ -server5-fan.crt: server5.key - $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS FAN" -set_serial 77 -config $(test_ca_config_file) -extensions fan_cert -days 3650 -sha256 -key server5.key -out $@ +server5-fan.crt.der: server5.key + $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS FAN" -set_serial 77 -config $(test_ca_config_file) -extensions fan_cert -days 3650 -sha256 -key server5.key -outform der -out $@ server5-tricky-ip-san.crt.der: server5.key $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS Tricky IP SAN" -set_serial 77 -config $(test_ca_config_file) -extensions tricky_ip_san -days 3650 -sha256 -key server5.key -outform der -out $@ +all_final += server5-tricky-ip-san.crt.der + # malformed IP length server5-tricky-ip-san-malformed-len.crt.der: server5-tricky-ip-san.crt.der hexdump -ve '1/1 "%.2X"' $< | sed "s/87046162636487106162/87056162636487106162/" | xxd -r -p > $@ @@ -485,8 +487,6 @@ server5-directoryname-seq-malformed.crt.der: server5-two-directorynames.crt.der server5-second-directoryname-oid-malformed.crt.der: server5-two-directorynames.crt.der hexdump -ve '1/1 "%.2X"' $< | sed "s/0355040A0C0A4D414C464F524D5F4D45/1555040A0C0A4D414C464F524D5F4D45/" | xxd -r -p > $@ -all_final += server5-tricky-ip-san.crt - rsa_single_san_uri.crt.der: rsa_single_san_uri.key $(OPENSSL) req -x509 -outform der -nodes -days 7300 -newkey rsa:2048 -key $< -out $@ -addext "subjectAltName = URI:urn:example.com:5ff40f78-9210-494f-8206-c2c082f0609c" -extensions 'v3_req' -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS URI SAN" diff --git a/tests/data_files/parse_input/server5-fan.crt b/tests/data_files/parse_input/server5-fan.crt deleted file mode 100644 index dc1eb380cf..0000000000 --- a/tests/data_files/parse_input/server5-fan.crt +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBdTCCARugAwIBAgIBTTAKBggqhkjOPQQDAjA3MQswCQYDVQQGEwJVSzERMA8G -A1UECgwITWJlZCBUTFMxFTATBgNVBAMMDE1iZWQgVExTIEZBTjAeFw0xOTAzMjUw -OTAzNDZaFw0yOTAzMjIwOTAzNDZaMDcxCzAJBgNVBAYTAlVLMREwDwYDVQQKDAhN -YmVkIFRMUzEVMBMGA1UEAwwMTWJlZCBUTFMgRkFOMFkwEwYHKoZIzj0CAQYIKoZI -zj0DAQcDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/ -6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/6MYMBYwFAYDVR0lBA0wCwYJKwYBBAGC -5CUBMAoGCCqGSM49BAMCA0gAMEUCIQDp/Q5FaVy3YNeJflQKLGycQZoH6V3FQnLq -ERUCeimLIAIgdyiA4KdHxkpQhC1L1KfmxG8YJqu31FBjmNw00Sv8J9k= ------END CERTIFICATE----- diff --git a/tests/data_files/parse_input/server5-fan.crt.der b/tests/data_files/parse_input/server5-fan.crt.der new file mode 100644 index 0000000000000000000000000000000000000000..db4e5bda551bc4303425c349aa7220707877d14e GIT binary patch literal 408 zcmXqLVw_^o#AvmEnTe5!iP6`9i;Y98&EuRc3p0~}xgoa!CmVAp3!5-gsJEe@0Y8Yt z#lzv7l$xRt;uCBrY9I^}V&>t22`RWa`WeWH^BNf&m>C%uSejTGn?{NA8Uwk8=1?yA z21f$zV+XsBi4p2hW=3{qCk7VtGhsK&IOU>>?2bq3{#VF*SM!r?V#$TIB3r*_C`Bes z@_Wi~Ls{_uEB#9*v9V%%yE+bKm-B|6?b71=#du=N+y9Hr4NMJ0fS!?6W#Kj8X5-Xm zV`O1$dZNl`APW-ZV-aH!2}oSpe}(<#^(IE1r>XTl$!^Pq_aTQEvj>BLE0ZF_uCy%k z?;DvaYl^oX_-8P0W1sz(TX`xb7oGAgBn4D%Ok+~uKi(|4$vi-@C%uSejTG8AOTm8Uwk8=1?y6EsQh}W@88YhlvsDF=j?~W+w&~^D|*L%Q)qt zitLU@>i$>Adsp+5ZDPrVwIW-;XDCG`P4auna6?(}|114VCb6+%d%HRgWta1Yp6$}& z`^9)-%iI5pgA4);^nsq26=cycP+OqF#-Yu|$jZvj!LmTYK#YwY$YWs?WM<(uG%{{z zWN2(KHZnAj1!>@85n~YvNL<=~h5hFBCPtp8sr5a{Zp(%DAqPIQ2ZMntlLGgv-FGCYn2(d`zY)8kWhonOA1 R%>MF~)4QYd_dHAw0swp7kCXra literal 0 HcmV?d00001 diff --git a/tests/data_files/parse_input/server5-othername.crt b/tests/data_files/parse_input/server5-othername.crt deleted file mode 100644 index 3be1a772c0..0000000000 --- a/tests/data_files/parse_input/server5-othername.crt +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBnzCCAUWgAwIBAgIBTTAKBggqhkjOPQQDAjBBMQswCQYDVQQGEwJVSzERMA8G -A1UECgwITWJlZCBUTFMxHzAdBgNVBAMMFk1iZWQgVExTIG90aGVybmFtZSBTQU4w -HhcNMTkwMzI0MDkwNjAyWhcNMjkwMzIxMDkwNjAyWjBBMQswCQYDVQQGEwJVSzER -MA8GA1UECgwITWJlZCBUTFMxHzAdBgNVBAMMFk1iZWQgVExTIG90aGVybmFtZSBT -QU4wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ3zFbZdgkeWnI+x1kt/yBu7nz5 -BpF00K0UtfdoIllikk7lANgjEf/qL9I0XV0WvYqIwmt3DVXNiioO+gHItO3/oy4w -LDAqBgNVHREEIzAhoB8GCCsGAQUFBwgEoBMwEQYHKwYBBAERAwQGMTIzNDU2MAoG -CCqGSM49BAMCA0gAMEUCIQCijdm1AfArx2p4cLCVciHCTE8UXRiTm8f85k4aNzzf -sgIgCdmLyfZB9jsSPH3A3O1GATAR3O9OTtEDC+YSc+lvxSw= ------END CERTIFICATE----- diff --git a/tests/data_files/parse_input/server5-othername.crt.der b/tests/data_files/parse_input/server5-othername.crt.der new file mode 100644 index 0000000000000000000000000000000000000000..0ef31cf143616ff108b910a49d8414dcdd9e8830 GIT binary patch literal 449 zcmXqLV%%%c#F(;xnTe5!iP6`9i;Y98&EuRc3p0~}qan8eCmVAp3!5-gsJEe@0Y8Yt z#lzv7l$xRt;uCBrZy*a2V&)Np2`S{4WTY15CFZ6o1Uvc}$cghB85@`x85md^n3xzx ziSrr*xrXLYE;X!(G!SNE2fLYx5$bqmMs{W=1{U)(VK>V-<)Vu0jz{YLSIB!;^OJ32 z$%VBdTfb*0MJ7%1d&+P_S@8cW{YxgXv0{6>Iu2!*^M;=7(&GEYcw)=j|BHPMybZK~ z9+VYiQ8rLqAkW63&Bn;e%Fe;EK-fT#jUC8iVH9L$VKX!`HZe5=2Zk&kix`VYK;qK= zE9^I~H!<=&O|9=qc3UpI4>@d^-5CsAm=t1s-cG&|>KiLzQgY~EWW%f-of9T$^&a}R wYSpfW6_->(nG~da)7!Xqn@ztbn)OeAQrVC9>vq*Y`|00kapCsacGX}P097l3%>V!Z literal 0 HcmV?d00001 diff --git a/tests/data_files/parse_input/server5-unsupported_othername.crt b/tests/data_files/parse_input/server5-unsupported_othername.crt deleted file mode 100644 index b46fc2d966..0000000000 --- a/tests/data_files/parse_input/server5-unsupported_othername.crt +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBtjCCAVygAwIBAgIBTTAKBggqhkjOPQQDAjBNMQswCQYDVQQGEwJVSzERMA8G -A1UECgwITWJlZCBUTFMxKzApBgNVBAMMIk1iZWQgVExTIHVuc3VwcG9ydGVkIG90 -aGVybmFtZSBTQU4wHhcNMTkwNTAxMDkxMDM1WhcNMjkwNDI4MDkxMDM1WjBNMQsw -CQYDVQQGEwJVSzERMA8GA1UECgwITWJlZCBUTFMxKzApBgNVBAMMIk1iZWQgVExT -IHVuc3VwcG9ydGVkIG90aGVybmFtZSBTQU4wWTATBgcqhkjOPQIBBggqhkjOPQMB -BwNCAAQ3zFbZdgkeWnI+x1kt/yBu7nz5BpF00K0UtfdoIllikk7lANgjEf/qL9I0 -XV0WvYqIwmt3DVXNiioO+gHItO3/oy0wKzApBgNVHREEIjAgoB4GAyoDBKAXDBVz -b21lIG90aGVyIGlkZW50aWZpZXIwCgYIKoZIzj0EAwIDSAAwRQIhANkj6n9qHYVi -FLfb0IRZpIsvvuNCjSgT8yBLVjJYQj3nAiBffQKZ7y/F6rfon6L1GZU0BBja8BLX -rXp8WpY7Bc8myQ== ------END CERTIFICATE----- diff --git a/tests/data_files/parse_input/server5-unsupported_othername.crt.der b/tests/data_files/parse_input/server5-unsupported_othername.crt.der new file mode 100644 index 0000000000000000000000000000000000000000..1d9c20588c682eca569ddda0d0e9b71555fd6c4d GIT binary patch literal 472 zcmXqLV!UF|#8|z6nTe5!iP6`9i;Y98&EuRc3p0~}uOYVqCmVAp3!5-gsJEe@0Y8Yt z#lzv7l$xRt;uCDBZJ-GfV&+kT2`QB36_*wiM3SMc4j9A7V|SQ8B}_evXTG z>r-JC2DO5GJ(IuncXL)TDWnx=G#oa_I3V+hAw2J;#Say6ah@_>wj`;tCWT+~6odhk Cw~RLc literal 0 HcmV?d00001 diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index edb782470e..e14075be2e 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -87,12 +87,12 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R x509_cert_info:"data_files/parse_input/server5-sha512.crt":"cert. version \: 3\nserial number \: 15\nissuer name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2013-09-24 16\:21\:27\nexpires on \: 2023-09-22 16\:21\:27\nsigned using \: ECDSA with SHA512\nEC key size \: 256 bits\nbasic constraints \: CA=false\n" X509 CRT information EC, SHA256 Digest, hardware module name SAN -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 -x509_cert_info:"data_files/parse_input/server5-othername.crt":"cert. version \: 3\nserial number \: 4D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS othername SAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS othername SAN\nissued on \: 2019-03-24 09\:06\:02\nexpires on \: 2029-03-21 09\:06\:02\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nsubject alt name \:\n otherName \:\n hardware module name \:\n hardware type \: 1.3.6.1.4.1.17.3\n hardware serial number \: 313233343536\n" +depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 +x509_cert_info:"data_files/parse_input/server5-othername.crt.der":"cert. version \: 3\nserial number \: 4D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS othername SAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS othername SAN\nissued on \: 2023-06-20 09\:04\:43\nexpires on \: 2033-06-17 09\:04\:43\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nsubject alt name \:\n otherName \:\n hardware module name \:\n hardware type \: 1.3.6.1.4.1.17.3\n hardware serial number \: 313233343536\n" X509 CRT information EC, SHA256 Digest, binary hardware module name SAN -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 -x509_cert_info:"data_files/parse_input/server5-nonprintable_othername.crt":"cert. version \: 3\nserial number \: 4D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS non-printable othername SAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS non-printable othername SAN\nissued on \: 2022-09-06 15\:56\:47\nexpires on \: 2032-09-03 15\:56\:47\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nsubject alt name \:\n otherName \:\n hardware module name \:\n hardware type \: 1.3.6.1.4.1.17.3\n hardware serial number \: 3132338081008180333231\n" +depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 +x509_cert_info:"data_files/parse_input/server5-nonprintable_othername.crt.der":"cert. version \: 3\nserial number \: 4D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS non-printable othername SAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS non-printable othername SAN\nissued on \: 2023-06-20 09\:49\:20\nexpires on \: 2033-06-17 09\:49\:20\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nsubject alt name \:\n otherName \:\n hardware module name \:\n hardware type \: 1.3.6.1.4.1.17.3\n hardware serial number \: 3132338081008180333231\n" X509 CRT information EC, SHA256 Digest, directoryName SAN depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 @@ -103,8 +103,8 @@ depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD x509_cert_info:"data_files/parse_input/server5-two-directorynames.crt.der":"cert. version \: 3\nserial number \: 4D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS directoryName SAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS directoryName SAN\nissued on \: 2023-01-12 10\:34\:11\nexpires on \: 2033-01-09 10\:34\:11\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nsubject alt name \:\n directoryName \: C=UK, O=Mbed TLS, CN=Mbed TLS directoryName SAN\n directoryName \: O=MALFORM_ME\n" X509 CRT information EC, SHA256 Digest, Wisun Fan device -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 -x509_cert_info:"data_files/parse_input/server5-fan.crt":"cert. version \: 3\nserial number \: 4D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS FAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS FAN\nissued on \: 2019-03-25 09\:03\:46\nexpires on \: 2029-03-22 09\:03\:46\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\next key usage \: Wi-SUN Alliance Field Area Network (FAN)\n" +depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 +x509_cert_info:"data_files/parse_input/server5-fan.crt.der":"cert. version \: 3\nserial number \: 4D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS FAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS FAN\nissued on \: 2023-06-20 09\:49\:35\nexpires on \: 2033-06-17 09\:49\:35\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\next key usage \: Wi-SUN Alliance Field Area Network (FAN)\n" X509 CRT information, NS Cert Type depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA1 @@ -195,12 +195,12 @@ depends_on:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_DP_SECP x509_cert_info:"data_files/server5-tricky-ip-san.crt.der":"cert. version \: 3\nserial number \: 4D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS Tricky IP SAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS Tricky IP SAN\nissued on \: 2023-06-05 11\:30\:36\nexpires on \: 2033-06-02 11\:30\:36\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nsubject alt name \:\n iPAddress \: 97.98.99.100\n iPAddress \: 6162\:6364\:2E65\:7861\:6D70\:6C65\:2E63\:6F6D\n" X509 SAN parsing otherName -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 -x509_parse_san:"data_files/parse_input/server5-othername.crt":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 313233343536\n":0 +depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 +x509_parse_san:"data_files/parse_input/server5-othername.crt.der":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 313233343536\n":0 X509 SAN parsing binary otherName -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 -x509_parse_san:"data_files/parse_input/server5-nonprintable_othername.crt":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 3132338081008180333231\n":0 +depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 +x509_parse_san:"data_files/parse_input/server5-nonprintable_othername.crt.der":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 3132338081008180333231\n":0 X509 SAN parsing directoryName depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 @@ -227,8 +227,8 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA256:MBEDTLS_PK_CA x509_parse_san:"data_files/parse_input/server4.crt":"":0 X509 SAN parsing, unsupported otherName name -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 -x509_parse_san:"data_files/parse_input/server5-unsupported_othername.crt":"":0 +depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_MD_CAN_SHA256 +x509_parse_san:"data_files/parse_input/server5-unsupported_othername.crt.der":"":0 X509 SAN parsing rfc822Name depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA256 From b19f584f2c1001ac9e4af3750fdc84d5bd53f6ca Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 20 Jun 2023 23:01:43 +0100 Subject: [PATCH 34/89] Fix for arm64_32 (aka ILP32) on Clang Signed-off-by: Dave Rodgman --- library/constant_time.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/constant_time.c b/library/constant_time.c index c823b78894..6e02f34389 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -78,8 +78,10 @@ static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsi uint32_t r; #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :); -#elif defined(__aarch64__) +#elif defined(__aarch64__) && (SIZE_MAX == 0xffffffffffffffff) asm volatile ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :); +#elif defined(__aarch64__) && (SIZE_MAX == 0xffffffff) + asm volatile ("ldr %w0, [%w1]" : "=r" (r) : "r" (p) :); #endif return r; } From 04cb9ac59ea0943b298ccb1f3db3e4d97da40dff Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 07:32:22 +0100 Subject: [PATCH 35/89] Fix for arm64_32 (aka ILP32) on Clang (attempt 2) Signed-off-by: Dave Rodgman --- library/constant_time.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index 6e02f34389..b24ebb4787 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -78,10 +78,8 @@ static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsi uint32_t r; #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :); -#elif defined(__aarch64__) && (SIZE_MAX == 0xffffffffffffffff) - asm volatile ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :); -#elif defined(__aarch64__) && (SIZE_MAX == 0xffffffff) - asm volatile ("ldr %w0, [%w1]" : "=r" (r) : "r" (p) :); +#elif defined(__aarch64__) + asm volatile ("ldr %w0, [%1]" : "=r" (r) : "p" (p) :); #endif return r; } From b67db9140ede4bf7b5f1a2bab8a31f119941f360 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 09:15:27 +0100 Subject: [PATCH 36/89] Separate ILP32 and normal-aarch64 code paths Signed-off-by: Dave Rodgman --- library/constant_time.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/constant_time.c b/library/constant_time.c index b24ebb4787..89d7b4f234 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -79,7 +79,12 @@ static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsi #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :); #elif defined(__aarch64__) +#if (SIZE_MAX == 0xffffffff) + /* ILP32: Specify the pointer operand slightly differently, as per #7787. */ asm volatile ("ldr %w0, [%1]" : "=r" (r) : "p" (p) :); +#else + asm volatile ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :); +#endif #endif return r; } From 517e891e5550cb889c5374bd8dad7e26e9f3245e Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 11:16:31 +0100 Subject: [PATCH 37/89] Changelog Signed-off-by: Dave Rodgman --- ChangeLog.d/fix-ilp32.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/fix-ilp32.txt diff --git a/ChangeLog.d/fix-ilp32.txt b/ChangeLog.d/fix-ilp32.txt new file mode 100644 index 0000000000..7c28d68f43 --- /dev/null +++ b/ChangeLog.d/fix-ilp32.txt @@ -0,0 +1,4 @@ +Bugfix + * Fix a compile failure in the constant_time module when building + for watchos (i.e. for Aarch64 ILP32). Reported by Paulo Coutinho + in #7787. From 85842b8edb1f3cf18cb525f068d9c105b09563fe Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 11:22:09 +0100 Subject: [PATCH 38/89] Be strict about pointer size in mbedtls_get_unaligned_volatile_uint32 Signed-off-by: Dave Rodgman --- library/constant_time.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/constant_time.c b/library/constant_time.c index 89d7b4f234..fb14c9cf3c 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -63,7 +63,8 @@ * only used here. */ #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && defined(MBEDTLS_HAVE_ASM) -#if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) || defined(__aarch64__) +#if ((defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) && (SIZE_MAX == 0xffffffff)) || \ + (defined(__aarch64__) && ((SIZE_MAX == 0xffffffff) || (SIZE_MAX == 0xffffffffffffffff))) #define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS #endif #endif From 63e89b46f8b6cd603bb2b73e58545f940aae9a85 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 11:55:17 +0100 Subject: [PATCH 39/89] Use UINTPTR_MAX not SIZE_MAX Signed-off-by: Dave Rodgman --- library/constant_time.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index fb14c9cf3c..f7da39f8e1 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -63,8 +63,9 @@ * only used here. */ #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && defined(MBEDTLS_HAVE_ASM) -#if ((defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) && (SIZE_MAX == 0xffffffff)) || \ - (defined(__aarch64__) && ((SIZE_MAX == 0xffffffff) || (SIZE_MAX == 0xffffffffffffffff))) +#if ((defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) && (UINTPTR_MAX == 0xfffffffful)) || \ + (defined(__aarch64__) && ((UINTPTR_MAX == 0xffffffffull) || (UINTPTR_MAX == 0xffffffffffffffffull))) +/* We check pointer sizes to avoid issues with them not matching register size requirements */ #define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS #endif #endif @@ -80,10 +81,11 @@ static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsi #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :); #elif defined(__aarch64__) -#if (SIZE_MAX == 0xffffffff) +#if (UINTPTR_MAX == 0xfffffffful) /* ILP32: Specify the pointer operand slightly differently, as per #7787. */ asm volatile ("ldr %w0, [%1]" : "=r" (r) : "p" (p) :); -#else +#elif (UINTPTR_MAX == 0xffffffffffffffffull) + /* aarch64 with 64-bit pointers */ asm volatile ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :); #endif #endif From 140fa15a7f8f56a05fda6d9c8ed6286b5bdaba27 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 12:36:52 +0100 Subject: [PATCH 40/89] Improve changelog Signed-off-by: Dave Rodgman --- ChangeLog.d/fix-ilp32.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog.d/fix-ilp32.txt b/ChangeLog.d/fix-ilp32.txt index 7c28d68f43..3f18ac5c5b 100644 --- a/ChangeLog.d/fix-ilp32.txt +++ b/ChangeLog.d/fix-ilp32.txt @@ -1,4 +1,4 @@ Bugfix - * Fix a compile failure in the constant_time module when building - for watchos (i.e. for Aarch64 ILP32). Reported by Paulo Coutinho - in #7787. + * Fix a compilation failure in the constant_time module when + building for arm64_32 (e.g., for watchos). Reported by Paulo + Coutinho in #7787. From c54f25e26cf1a2a44f78fd1bac08a1c35c691fd0 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 13:39:30 +0100 Subject: [PATCH 41/89] code style Signed-off-by: Dave Rodgman --- library/constant_time.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index f7da39f8e1..5ed087c07a 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -63,8 +63,10 @@ * only used here. */ #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && defined(MBEDTLS_HAVE_ASM) -#if ((defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) && (UINTPTR_MAX == 0xfffffffful)) || \ - (defined(__aarch64__) && ((UINTPTR_MAX == 0xffffffffull) || (UINTPTR_MAX == 0xffffffffffffffffull))) +#if ((defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) && \ + (UINTPTR_MAX == 0xfffffffful)) || \ + (defined(__aarch64__) && ((UINTPTR_MAX == 0xffffffffull) || \ + (UINTPTR_MAX == 0xffffffffffffffffull))) /* We check pointer sizes to avoid issues with them not matching register size requirements */ #define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS #endif From 0400ae2f9b2a146acf77436daf7aee0e14101b84 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 16:14:46 +0100 Subject: [PATCH 42/89] Fix pointer constraint in bn_mul.h Signed-off-by: Dave Rodgman --- library/bn_mul.h | 5 ++++- library/common.h | 18 ++++++++++++++++++ library/constant_time.c | 8 +------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/library/bn_mul.h b/library/bn_mul.h index c5994f7049..0af7ecddec 100644 --- a/library/bn_mul.h +++ b/library/bn_mul.h @@ -265,7 +265,10 @@ "str x5, [%1], #8 \n\t" #define MULADDC_X1_STOP \ - : "+r" (c), "+r" (d), "+r" (s), "+m" (*(uint64_t (*)[16]) d) \ + : "+r" (c), \ + "+" MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT (d), \ + "+" MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT (s), \ + "+m" (*(uint64_t (*)[16]) d) \ : "r" (b), "m" (*(const uint64_t (*)[16]) s) \ : "x4", "x5", "x6", "x7", "cc" \ ); diff --git a/library/common.h b/library/common.h index b48a1fc667..4ee183a3f9 100644 --- a/library/common.h +++ b/library/common.h @@ -169,6 +169,24 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned #endif /* *INDENT-ON* */ +/* + * Define the constraint used for pointer operands to asm. + * + * This is normally the usual "r", but for aarch64_32 (aka ILP32, + * as found in watchos), "p" is required to avoid warnings from clang. + */ +#if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM) +#if UINTPTR_MAX == 0xfffffffful +/* ILP32: Specify the pointer operand slightly differently, as per #7787. */ +#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "p" +#elif UINTPTR_MAX == 0xfffffffffffffffful +/* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */ +#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r" +#else +#error Unrecognised pointer size for aarch64 +#endif +#endif + /* Always provide a static assert macro, so it can be used unconditionally. * It will expand to nothing on some systems. * Can be used outside functions (but don't add a trailing ';' in that case: diff --git a/library/constant_time.c b/library/constant_time.c index 5ed087c07a..c62ec13816 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -83,13 +83,7 @@ static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsi #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :); #elif defined(__aarch64__) -#if (UINTPTR_MAX == 0xfffffffful) - /* ILP32: Specify the pointer operand slightly differently, as per #7787. */ - asm volatile ("ldr %w0, [%1]" : "=r" (r) : "p" (p) :); -#elif (UINTPTR_MAX == 0xffffffffffffffffull) - /* aarch64 with 64-bit pointers */ - asm volatile ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :); -#endif + asm volatile ("ldr %w0, [%1]" : "=r" (r) : MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT (p) :); #endif return r; } From b5b6939fc29187aa6d87395bf4b898f9bf0105b1 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 16:36:42 +0100 Subject: [PATCH 43/89] Remove redundant checks in constant_time.c Signed-off-by: Dave Rodgman --- library/constant_time.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index c62ec13816..5e1a5773ee 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -64,9 +64,7 @@ */ #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && defined(MBEDTLS_HAVE_ASM) #if ((defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) && \ - (UINTPTR_MAX == 0xfffffffful)) || \ - (defined(__aarch64__) && ((UINTPTR_MAX == 0xffffffffull) || \ - (UINTPTR_MAX == 0xffffffffffffffffull))) + (UINTPTR_MAX == 0xfffffffful)) || defined(__aarch64__) /* We check pointer sizes to avoid issues with them not matching register size requirements */ #define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS #endif From 5b5dd011d109bb4c1d5cc1edae119ea3889ce412 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 16:36:47 +0100 Subject: [PATCH 44/89] code style Signed-off-by: Dave Rodgman --- library/constant_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/constant_time.c b/library/constant_time.c index 5e1a5773ee..2faba69e45 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -81,7 +81,7 @@ static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsi #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :); #elif defined(__aarch64__) - asm volatile ("ldr %w0, [%1]" : "=r" (r) : MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT (p) :); + asm volatile ("ldr %w0, [%1]" : "=r" (r) : MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT(p) :); #endif return r; } From e6c9996d04b8b52ca4d33fbfc221024673252968 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 21 Jun 2023 21:16:23 +0100 Subject: [PATCH 45/89] Work around updating pointers from ILP32 Signed-off-by: Dave Rodgman --- library/bn_mul.h | 10 +++++----- library/common.h | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/library/bn_mul.h b/library/bn_mul.h index 0af7ecddec..93dd4b6bb5 100644 --- a/library/bn_mul.h +++ b/library/bn_mul.h @@ -248,10 +248,10 @@ #endif /* AMD64 */ -#if defined(__aarch64__) +#if defined(__aarch64__) && (UINTPTR_MAX == 0xfffffffful || UINTPTR_MAX == 0xfffffffffffffffful) #define MULADDC_X1_INIT \ - asm( + do { uintptr_t muladdc_d = (uintptr_t) d, muladdc_s = (uintptr_t) s; asm( #define MULADDC_X1_CORE \ "ldr x4, [%2], #8 \n\t" \ @@ -266,12 +266,12 @@ #define MULADDC_X1_STOP \ : "+r" (c), \ - "+" MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT (d), \ - "+" MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT (s), \ + "+r" (muladdc_d), \ + "+r" (muladdc_s), \ "+m" (*(uint64_t (*)[16]) d) \ : "r" (b), "m" (*(const uint64_t (*)[16]) s) \ : "x4", "x5", "x6", "x7", "cc" \ - ); + ); d = (mbedtls_mpi_uint *)muladdc_d; s = (mbedtls_mpi_uint *)muladdc_s; } while (0); #endif /* Aarch64 */ diff --git a/library/common.h b/library/common.h index 4ee183a3f9..ba9cb75c08 100644 --- a/library/common.h +++ b/library/common.h @@ -174,6 +174,9 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned * * This is normally the usual "r", but for aarch64_32 (aka ILP32, * as found in watchos), "p" is required to avoid warnings from clang. + * + * Note that clang does not recognise '+p' or '=p', and armclang + * does not recognise 'p' at all. */ #if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM) #if UINTPTR_MAX == 0xfffffffful From e7f21e65b6193b5fd75ec1daf0cac8691e99d272 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 12 May 2023 18:17:21 +0100 Subject: [PATCH 46/89] Change J-PAKE internal state machine Keep track of the J-PAKE internal state in a more intuitive way. Specifically, replace the current state with a struct of 5 fields: * The round of J-PAKE we are currently in, FIRST or SECOND * The 'mode' we are currently working in, INPUT or OUTPUT * The number of inputs so far this round * The number of outputs so far this round * The PAKE step we are expecting, KEY_SHARE, ZK_PUBLIC or ZK_PROOF This should improve the readability of the state-transformation code. Signed-off-by: David Horstmann --- include/psa/crypto_extra.h | 27 +- library/psa_crypto.c | 300 +++++++----------- ..._suite_psa_crypto_driver_wrappers.function | 6 +- 3 files changed, 133 insertions(+), 200 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 5529dd1c84..a3351a6d03 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -2028,14 +2028,33 @@ typedef enum psa_crypto_driver_pake_step { PSA_JPAKE_X4S_STEP_ZK_PROOF = 12 /* Round 2: input Schnorr NIZKP proof for the X4S key (from peer) */ } psa_crypto_driver_pake_step_t; +typedef enum psa_jpake_round { + FIRST = 0, + SECOND = 1, + FINISHED = 2 +} psa_jpake_round_t; + +typedef enum psa_jpake_io_mode { + INPUT = 0, + OUTPUT = 1 +} psa_jpake_io_mode_t; struct psa_jpake_computation_stage_s { - psa_jpake_state_t MBEDTLS_PRIVATE(state); - psa_jpake_sequence_t MBEDTLS_PRIVATE(sequence); - psa_jpake_step_t MBEDTLS_PRIVATE(input_step); - psa_jpake_step_t MBEDTLS_PRIVATE(output_step); + /* The J-PAKE round we are currently on */ + psa_jpake_round_t MBEDTLS_PRIVATE(round); + /* The 'mode' we are currently in (inputting or outputting) */ + psa_jpake_io_mode_t MBEDTLS_PRIVATE(mode); + /* The number of inputs so far this round */ + uint8_t MBEDTLS_PRIVATE(inputs); + /* The number of outputs so far this round */ + uint8_t MBEDTLS_PRIVATE(outputs); + /* The next expected step (KEY_SHARE, ZK_PUBLIC or ZK_PROOF) */ + psa_pake_step_t MBEDTLS_PRIVATE(step); }; +#define PSA_JPAKE_EXPECTED_INPUTS(round) (((round) == FIRST) ? 2 : 1) +#define PSA_JPAKE_EXPECTED_OUTPUTS(round) (((round) == FIRST) ? 2 : 1) + struct psa_pake_operation_s { /** Unique ID indicating which driver got assigned to do the * operation. Since driver contexts are driver-specific, swapping diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 2173483230..f86ea3e6a3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7767,10 +7767,11 @@ psa_status_t psa_pake_setup( psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - computation_stage->state = PSA_PAKE_STATE_SETUP; - computation_stage->sequence = PSA_PAKE_SEQ_INVALID; - computation_stage->input_step = PSA_PAKE_STEP_X1_X2; - computation_stage->output_step = PSA_PAKE_STEP_X1_X2; + computation_stage->round = FIRST; + computation_stage->mode = INPUT; + computation_stage->inputs = 0; + computation_stage->outputs = 0; + computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; } else #endif /* PSA_WANT_ALG_JPAKE */ { @@ -7939,57 +7940,66 @@ exit: return status; } -/* Auxiliary function to convert core computation stage(step, sequence, state) to single driver step. */ +/* Auxiliary function to convert core computation stage to single driver step. */ #if defined(PSA_WANT_ALG_JPAKE) static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_step( psa_jpake_computation_stage_t *stage) { - switch (stage->state) { - case PSA_PAKE_OUTPUT_X1_X2: - case PSA_PAKE_INPUT_X1_X2: - switch (stage->sequence) { - case PSA_PAKE_X1_STEP_KEY_SHARE: + if (stage->round == FIRST) { + int is_x1; + if (stage->mode == OUTPUT) { + is_x1 = (stage->outputs < 1); + } else { + is_x1 = (stage->inputs < 1); + } + + if (is_x1) { + switch (stage->step) { + case PSA_PAKE_STEP_KEY_SHARE: return PSA_JPAKE_X1_STEP_KEY_SHARE; - case PSA_PAKE_X1_STEP_ZK_PUBLIC: + case PSA_PAKE_STEP_ZK_PUBLIC: return PSA_JPAKE_X1_STEP_ZK_PUBLIC; - case PSA_PAKE_X1_STEP_ZK_PROOF: + case PSA_PAKE_STEP_ZK_PROOF: return PSA_JPAKE_X1_STEP_ZK_PROOF; - case PSA_PAKE_X2_STEP_KEY_SHARE: + default: + return PSA_JPAKE_STEP_INVALID; + } + } else { + switch (stage->step) { + case PSA_PAKE_STEP_KEY_SHARE: return PSA_JPAKE_X2_STEP_KEY_SHARE; - case PSA_PAKE_X2_STEP_ZK_PUBLIC: + case PSA_PAKE_STEP_ZK_PUBLIC: return PSA_JPAKE_X2_STEP_ZK_PUBLIC; - case PSA_PAKE_X2_STEP_ZK_PROOF: + case PSA_PAKE_STEP_ZK_PROOF: return PSA_JPAKE_X2_STEP_ZK_PROOF; default: return PSA_JPAKE_STEP_INVALID; } - break; - case PSA_PAKE_OUTPUT_X2S: - switch (stage->sequence) { - case PSA_PAKE_X1_STEP_KEY_SHARE: + } + } else if (stage->round == SECOND) { + if (stage->mode == OUTPUT) { + switch (stage->step) { + case PSA_PAKE_STEP_KEY_SHARE: return PSA_JPAKE_X2S_STEP_KEY_SHARE; - case PSA_PAKE_X1_STEP_ZK_PUBLIC: + case PSA_PAKE_STEP_ZK_PUBLIC: return PSA_JPAKE_X2S_STEP_ZK_PUBLIC; - case PSA_PAKE_X1_STEP_ZK_PROOF: + case PSA_PAKE_STEP_ZK_PROOF: return PSA_JPAKE_X2S_STEP_ZK_PROOF; default: return PSA_JPAKE_STEP_INVALID; } - break; - case PSA_PAKE_INPUT_X4S: - switch (stage->sequence) { - case PSA_PAKE_X1_STEP_KEY_SHARE: + } else { + switch (stage->step) { + case PSA_PAKE_STEP_KEY_SHARE: return PSA_JPAKE_X4S_STEP_KEY_SHARE; - case PSA_PAKE_X1_STEP_ZK_PUBLIC: + case PSA_PAKE_STEP_ZK_PUBLIC: return PSA_JPAKE_X4S_STEP_ZK_PUBLIC; - case PSA_PAKE_X1_STEP_ZK_PROOF: + case PSA_PAKE_STEP_ZK_PROOF: return PSA_JPAKE_X4S_STEP_ZK_PROOF; default: return PSA_JPAKE_STEP_INVALID; } - break; - default: - return PSA_JPAKE_STEP_INVALID; + } } return PSA_JPAKE_STEP_INVALID; } @@ -8032,10 +8042,11 @@ static psa_status_t psa_pake_complete_inputs( operation->stage = PSA_PAKE_OPERATION_STAGE_COMPUTATION; psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - computation_stage->state = PSA_PAKE_STATE_READY; - computation_stage->sequence = PSA_PAKE_SEQ_INVALID; - computation_stage->input_step = PSA_PAKE_STEP_X1_X2; - computation_stage->output_step = PSA_PAKE_STEP_X1_X2; + computation_stage->round = FIRST; + computation_stage->mode = INPUT; + computation_stage->inputs = 0; + computation_stage->outputs = 0; + computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; } else #endif /* PSA_WANT_ALG_JPAKE */ { @@ -8046,9 +8057,10 @@ static psa_status_t psa_pake_complete_inputs( } #if defined(PSA_WANT_ALG_JPAKE) -static psa_status_t psa_jpake_output_prologue( +static psa_status_t psa_jpake_prologue( psa_pake_operation_t *operation, - psa_pake_step_t step) + psa_pake_step_t step, + psa_jpake_io_mode_t function_mode) { if (step != PSA_PAKE_STEP_KEY_SHARE && step != PSA_PAKE_STEP_ZK_PUBLIC && @@ -8059,84 +8071,79 @@ static psa_status_t psa_jpake_output_prologue( psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - if (computation_stage->state == PSA_PAKE_STATE_INVALID) { + if (computation_stage->round != FIRST && + computation_stage->round != SECOND) { return PSA_ERROR_BAD_STATE; } - if (computation_stage->state != PSA_PAKE_STATE_READY && - computation_stage->state != PSA_PAKE_OUTPUT_X1_X2 && - computation_stage->state != PSA_PAKE_OUTPUT_X2S) { + /* Check that the step we are given is the one we were expecting */ + if (step != computation_stage->step) { return PSA_ERROR_BAD_STATE; } - if (computation_stage->state == PSA_PAKE_STATE_READY) { - if (step != PSA_PAKE_STEP_KEY_SHARE) { - return PSA_ERROR_BAD_STATE; - } - - switch (computation_stage->output_step) { - case PSA_PAKE_STEP_X1_X2: - computation_stage->state = PSA_PAKE_OUTPUT_X1_X2; - break; - case PSA_PAKE_STEP_X2S: - computation_stage->state = PSA_PAKE_OUTPUT_X2S; - break; - default: - return PSA_ERROR_BAD_STATE; - } - - computation_stage->sequence = PSA_PAKE_X1_STEP_KEY_SHARE; + if (step == PSA_PAKE_STEP_KEY_SHARE && + computation_stage->inputs == 0 && + computation_stage->outputs == 0) { + /* Start of the round, so function decides whether we are inputting + * or outputting */ + computation_stage->mode = function_mode; + } else if (computation_stage->mode != function_mode) { + /* Middle of the round so the mode we are in must match the function + * called by the user */ + return PSA_ERROR_BAD_STATE; } - /* Check if step matches current sequence */ - switch (computation_stage->sequence) { - case PSA_PAKE_X1_STEP_KEY_SHARE: - case PSA_PAKE_X2_STEP_KEY_SHARE: - if (step != PSA_PAKE_STEP_KEY_SHARE) { - return PSA_ERROR_BAD_STATE; - } - break; - - case PSA_PAKE_X1_STEP_ZK_PUBLIC: - case PSA_PAKE_X2_STEP_ZK_PUBLIC: - if (step != PSA_PAKE_STEP_ZK_PUBLIC) { - return PSA_ERROR_BAD_STATE; - } - break; - - case PSA_PAKE_X1_STEP_ZK_PROOF: - case PSA_PAKE_X2_STEP_ZK_PROOF: - if (step != PSA_PAKE_STEP_ZK_PROOF) { - return PSA_ERROR_BAD_STATE; - } - break; - - default: + /* Check that we do not already have enough inputs/outputs + * this round */ + if (function_mode == INPUT) { + if (computation_stage->inputs >= + PSA_JPAKE_EXPECTED_INPUTS(computation_stage->round)) { return PSA_ERROR_BAD_STATE; + } + } else { + if (computation_stage->outputs >= + PSA_JPAKE_EXPECTED_OUTPUTS(computation_stage->round)) { + return PSA_ERROR_BAD_STATE; + } } - return PSA_SUCCESS; } -static psa_status_t psa_jpake_output_epilogue( - psa_pake_operation_t *operation) +static psa_status_t psa_jpake_epilogue( + psa_pake_operation_t *operation, + psa_jpake_io_mode_t function_mode) { - psa_jpake_computation_stage_t *computation_stage = + psa_jpake_computation_stage_t *stage = &operation->computation_stage.jpake; - if ((computation_stage->state == PSA_PAKE_OUTPUT_X1_X2 && - computation_stage->sequence == PSA_PAKE_X2_STEP_ZK_PROOF) || - (computation_stage->state == PSA_PAKE_OUTPUT_X2S && - computation_stage->sequence == PSA_PAKE_X1_STEP_ZK_PROOF)) { - computation_stage->state = PSA_PAKE_STATE_READY; - computation_stage->output_step++; - computation_stage->sequence = PSA_PAKE_SEQ_INVALID; + if (stage->step == PSA_PAKE_STEP_ZK_PROOF) { + /* End of an input/output */ + if (function_mode == INPUT) { + stage->inputs++; + if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round)) { + stage->mode = OUTPUT; + } + } + if (function_mode == OUTPUT) { + stage->outputs++; + if (stage->outputs >= PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { + stage->mode = INPUT; + } + } + if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round) && + stage->outputs >= PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { + /* End of a round, move to the next round */ + stage->inputs = 0; + stage->outputs = 0; + stage->round++; + } + stage->step = PSA_PAKE_STEP_KEY_SHARE; } else { - computation_stage->sequence++; + stage->step++; } - return PSA_SUCCESS; } + #endif /* PSA_WANT_ALG_JPAKE */ psa_status_t psa_pake_output( @@ -8170,7 +8177,7 @@ psa_status_t psa_pake_output( switch (operation->alg) { #if defined(PSA_WANT_ALG_JPAKE) case PSA_ALG_JPAKE: - status = psa_jpake_output_prologue(operation, step); + status = psa_jpake_prologue(operation, step, OUTPUT); if (status != PSA_SUCCESS) { goto exit; } @@ -8194,7 +8201,7 @@ psa_status_t psa_pake_output( switch (operation->alg) { #if defined(PSA_WANT_ALG_JPAKE) case PSA_ALG_JPAKE: - status = psa_jpake_output_epilogue(operation); + status = psa_jpake_epilogue(operation, OUTPUT); if (status != PSA_SUCCESS) { goto exit; } @@ -8211,100 +8218,6 @@ exit: return status; } -#if defined(PSA_WANT_ALG_JPAKE) -static psa_status_t psa_jpake_input_prologue( - psa_pake_operation_t *operation, - psa_pake_step_t step) -{ - if (step != PSA_PAKE_STEP_KEY_SHARE && - step != PSA_PAKE_STEP_ZK_PUBLIC && - step != PSA_PAKE_STEP_ZK_PROOF) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - psa_jpake_computation_stage_t *computation_stage = - &operation->computation_stage.jpake; - - if (computation_stage->state == PSA_PAKE_STATE_INVALID) { - return PSA_ERROR_BAD_STATE; - } - - if (computation_stage->state != PSA_PAKE_STATE_READY && - computation_stage->state != PSA_PAKE_INPUT_X1_X2 && - computation_stage->state != PSA_PAKE_INPUT_X4S) { - return PSA_ERROR_BAD_STATE; - } - - if (computation_stage->state == PSA_PAKE_STATE_READY) { - if (step != PSA_PAKE_STEP_KEY_SHARE) { - return PSA_ERROR_BAD_STATE; - } - - switch (computation_stage->input_step) { - case PSA_PAKE_STEP_X1_X2: - computation_stage->state = PSA_PAKE_INPUT_X1_X2; - break; - case PSA_PAKE_STEP_X2S: - computation_stage->state = PSA_PAKE_INPUT_X4S; - break; - default: - return PSA_ERROR_BAD_STATE; - } - - computation_stage->sequence = PSA_PAKE_X1_STEP_KEY_SHARE; - } - - /* Check if step matches current sequence */ - switch (computation_stage->sequence) { - case PSA_PAKE_X1_STEP_KEY_SHARE: - case PSA_PAKE_X2_STEP_KEY_SHARE: - if (step != PSA_PAKE_STEP_KEY_SHARE) { - return PSA_ERROR_BAD_STATE; - } - break; - - case PSA_PAKE_X1_STEP_ZK_PUBLIC: - case PSA_PAKE_X2_STEP_ZK_PUBLIC: - if (step != PSA_PAKE_STEP_ZK_PUBLIC) { - return PSA_ERROR_BAD_STATE; - } - break; - - case PSA_PAKE_X1_STEP_ZK_PROOF: - case PSA_PAKE_X2_STEP_ZK_PROOF: - if (step != PSA_PAKE_STEP_ZK_PROOF) { - return PSA_ERROR_BAD_STATE; - } - break; - - default: - return PSA_ERROR_BAD_STATE; - } - - return PSA_SUCCESS; -} - -static psa_status_t psa_jpake_input_epilogue( - psa_pake_operation_t *operation) -{ - psa_jpake_computation_stage_t *computation_stage = - &operation->computation_stage.jpake; - - if ((computation_stage->state == PSA_PAKE_INPUT_X1_X2 && - computation_stage->sequence == PSA_PAKE_X2_STEP_ZK_PROOF) || - (computation_stage->state == PSA_PAKE_INPUT_X4S && - computation_stage->sequence == PSA_PAKE_X1_STEP_ZK_PROOF)) { - computation_stage->state = PSA_PAKE_STATE_READY; - computation_stage->input_step++; - computation_stage->sequence = PSA_PAKE_SEQ_INVALID; - } else { - computation_stage->sequence++; - } - - return PSA_SUCCESS; -} -#endif /* PSA_WANT_ALG_JPAKE */ - psa_status_t psa_pake_input( psa_pake_operation_t *operation, psa_pake_step_t step, @@ -8337,7 +8250,7 @@ psa_status_t psa_pake_input( switch (operation->alg) { #if defined(PSA_WANT_ALG_JPAKE) case PSA_ALG_JPAKE: - status = psa_jpake_input_prologue(operation, step); + status = psa_jpake_prologue(operation, step, INPUT); if (status != PSA_SUCCESS) { goto exit; } @@ -8361,7 +8274,7 @@ psa_status_t psa_pake_input( switch (operation->alg) { #if defined(PSA_WANT_ALG_JPAKE) case PSA_ALG_JPAKE: - status = psa_jpake_input_epilogue(operation); + status = psa_jpake_epilogue(operation, INPUT); if (status != PSA_SUCCESS) { goto exit; } @@ -8396,8 +8309,7 @@ psa_status_t psa_pake_get_implicit_key( if (operation->alg == PSA_ALG_JPAKE) { psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - if (computation_stage->input_step != PSA_PAKE_STEP_DERIVE || - computation_stage->output_step != PSA_PAKE_STEP_DERIVE) { + if (computation_stage->round != FINISHED) { status = PSA_ERROR_BAD_STATE; goto exit; } diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index b971f81666..87f7b37d7a 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -3127,8 +3127,10 @@ void pake_operations(data_t *pw_data, int forced_status_setup_arg, int forced_st PSA_SUCCESS); /* Simulate that we are ready to get implicit key. */ - operation.computation_stage.jpake.input_step = PSA_PAKE_STEP_DERIVE; - operation.computation_stage.jpake.output_step = PSA_PAKE_STEP_DERIVE; + operation.computation_stage.jpake.round = PSA_JPAKE_FINISHED; + operation.computation_stage.jpake.inputs = 0; + operation.computation_stage.jpake.outputs = 0; + operation.computation_stage.jpake.step = PSA_PAKE_STEP_KEY_SHARE; /* --- psa_pake_get_implicit_key --- */ mbedtls_test_driver_pake_hooks.forced_status = forced_status; From 5da9560178ee66835b9c9c572dba1d31489cefb6 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 8 Jun 2023 15:37:12 +0100 Subject: [PATCH 47/89] Properly namespace enum values within PSA_JPAKE_ Signed-off-by: David Horstmann --- include/psa/crypto_extra.h | 14 ++++++------- library/psa_crypto.c | 40 +++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index a3351a6d03..eea9ef8534 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -2029,14 +2029,14 @@ typedef enum psa_crypto_driver_pake_step { } psa_crypto_driver_pake_step_t; typedef enum psa_jpake_round { - FIRST = 0, - SECOND = 1, - FINISHED = 2 + PSA_JPAKE_FIRST = 0, + PSA_JPAKE_SECOND = 1, + PSA_JPAKE_FINISHED = 2 } psa_jpake_round_t; typedef enum psa_jpake_io_mode { - INPUT = 0, - OUTPUT = 1 + PSA_JPAKE_INPUT = 0, + PSA_JPAKE_OUTPUT = 1 } psa_jpake_io_mode_t; struct psa_jpake_computation_stage_s { @@ -2052,8 +2052,8 @@ struct psa_jpake_computation_stage_s { psa_pake_step_t MBEDTLS_PRIVATE(step); }; -#define PSA_JPAKE_EXPECTED_INPUTS(round) (((round) == FIRST) ? 2 : 1) -#define PSA_JPAKE_EXPECTED_OUTPUTS(round) (((round) == FIRST) ? 2 : 1) +#define PSA_JPAKE_EXPECTED_INPUTS(round) (((round) == PSA_JPAKE_FIRST) ? 2 : 1) +#define PSA_JPAKE_EXPECTED_OUTPUTS(round) (((round) == PSA_JPAKE_FIRST) ? 2 : 1) struct psa_pake_operation_s { /** Unique ID indicating which driver got assigned to do the diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f86ea3e6a3..2039c1d2a4 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7767,8 +7767,8 @@ psa_status_t psa_pake_setup( psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - computation_stage->round = FIRST; - computation_stage->mode = INPUT; + computation_stage->round = PSA_JPAKE_FIRST; + computation_stage->mode = PSA_JPAKE_INPUT; computation_stage->inputs = 0; computation_stage->outputs = 0; computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; @@ -7945,9 +7945,9 @@ exit: static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_step( psa_jpake_computation_stage_t *stage) { - if (stage->round == FIRST) { + if (stage->round == PSA_JPAKE_FIRST) { int is_x1; - if (stage->mode == OUTPUT) { + if (stage->mode == PSA_JPAKE_OUTPUT) { is_x1 = (stage->outputs < 1); } else { is_x1 = (stage->inputs < 1); @@ -7976,8 +7976,8 @@ static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_s return PSA_JPAKE_STEP_INVALID; } } - } else if (stage->round == SECOND) { - if (stage->mode == OUTPUT) { + } else if (stage->round == PSA_JPAKE_SECOND) { + if (stage->mode == PSA_JPAKE_OUTPUT) { switch (stage->step) { case PSA_PAKE_STEP_KEY_SHARE: return PSA_JPAKE_X2S_STEP_KEY_SHARE; @@ -8042,8 +8042,8 @@ static psa_status_t psa_pake_complete_inputs( operation->stage = PSA_PAKE_OPERATION_STAGE_COMPUTATION; psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - computation_stage->round = FIRST; - computation_stage->mode = INPUT; + computation_stage->round = PSA_JPAKE_FIRST; + computation_stage->mode = PSA_JPAKE_INPUT; computation_stage->inputs = 0; computation_stage->outputs = 0; computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; @@ -8071,8 +8071,8 @@ static psa_status_t psa_jpake_prologue( psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - if (computation_stage->round != FIRST && - computation_stage->round != SECOND) { + if (computation_stage->round != PSA_JPAKE_FIRST && + computation_stage->round != PSA_JPAKE_SECOND) { return PSA_ERROR_BAD_STATE; } @@ -8095,7 +8095,7 @@ static psa_status_t psa_jpake_prologue( /* Check that we do not already have enough inputs/outputs * this round */ - if (function_mode == INPUT) { + if (function_mode == PSA_JPAKE_INPUT) { if (computation_stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(computation_stage->round)) { return PSA_ERROR_BAD_STATE; @@ -8118,16 +8118,16 @@ static psa_status_t psa_jpake_epilogue( if (stage->step == PSA_PAKE_STEP_ZK_PROOF) { /* End of an input/output */ - if (function_mode == INPUT) { + if (function_mode == PSA_JPAKE_INPUT) { stage->inputs++; if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round)) { - stage->mode = OUTPUT; + stage->mode = PSA_JPAKE_OUTPUT; } } - if (function_mode == OUTPUT) { + if (function_mode == PSA_JPAKE_OUTPUT) { stage->outputs++; if (stage->outputs >= PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { - stage->mode = INPUT; + stage->mode = PSA_JPAKE_INPUT; } } if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round) && @@ -8177,7 +8177,7 @@ psa_status_t psa_pake_output( switch (operation->alg) { #if defined(PSA_WANT_ALG_JPAKE) case PSA_ALG_JPAKE: - status = psa_jpake_prologue(operation, step, OUTPUT); + status = psa_jpake_prologue(operation, step, PSA_JPAKE_OUTPUT); if (status != PSA_SUCCESS) { goto exit; } @@ -8201,7 +8201,7 @@ psa_status_t psa_pake_output( switch (operation->alg) { #if defined(PSA_WANT_ALG_JPAKE) case PSA_ALG_JPAKE: - status = psa_jpake_epilogue(operation, OUTPUT); + status = psa_jpake_epilogue(operation, PSA_JPAKE_OUTPUT); if (status != PSA_SUCCESS) { goto exit; } @@ -8250,7 +8250,7 @@ psa_status_t psa_pake_input( switch (operation->alg) { #if defined(PSA_WANT_ALG_JPAKE) case PSA_ALG_JPAKE: - status = psa_jpake_prologue(operation, step, INPUT); + status = psa_jpake_prologue(operation, step, PSA_JPAKE_INPUT); if (status != PSA_SUCCESS) { goto exit; } @@ -8274,7 +8274,7 @@ psa_status_t psa_pake_input( switch (operation->alg) { #if defined(PSA_WANT_ALG_JPAKE) case PSA_ALG_JPAKE: - status = psa_jpake_epilogue(operation, INPUT); + status = psa_jpake_epilogue(operation, PSA_JPAKE_INPUT); if (status != PSA_SUCCESS) { goto exit; } @@ -8309,7 +8309,7 @@ psa_status_t psa_pake_get_implicit_key( if (operation->alg == PSA_ALG_JPAKE) { psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - if (computation_stage->round != FINISHED) { + if (computation_stage->round != PSA_JPAKE_FINISHED) { status = PSA_ERROR_BAD_STATE; goto exit; } From 00ad6bfabed77c139504c9bbc4c99a89cc4ce660 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 15:44:24 +0100 Subject: [PATCH 48/89] Rename function_mode to io_mode Signed-off-by: David Horstmann --- library/psa_crypto.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 2039c1d2a4..801d35ff9f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8060,7 +8060,7 @@ static psa_status_t psa_pake_complete_inputs( static psa_status_t psa_jpake_prologue( psa_pake_operation_t *operation, psa_pake_step_t step, - psa_jpake_io_mode_t function_mode) + psa_jpake_io_mode_t io_mode) { if (step != PSA_PAKE_STEP_KEY_SHARE && step != PSA_PAKE_STEP_ZK_PUBLIC && @@ -8086,8 +8086,8 @@ static psa_status_t psa_jpake_prologue( computation_stage->outputs == 0) { /* Start of the round, so function decides whether we are inputting * or outputting */ - computation_stage->mode = function_mode; - } else if (computation_stage->mode != function_mode) { + computation_stage->mode = io_mode; + } else if (computation_stage->mode != io_mode) { /* Middle of the round so the mode we are in must match the function * called by the user */ return PSA_ERROR_BAD_STATE; @@ -8095,7 +8095,7 @@ static psa_status_t psa_jpake_prologue( /* Check that we do not already have enough inputs/outputs * this round */ - if (function_mode == PSA_JPAKE_INPUT) { + if (io_mode == PSA_JPAKE_INPUT) { if (computation_stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(computation_stage->round)) { return PSA_ERROR_BAD_STATE; @@ -8111,20 +8111,20 @@ static psa_status_t psa_jpake_prologue( static psa_status_t psa_jpake_epilogue( psa_pake_operation_t *operation, - psa_jpake_io_mode_t function_mode) + psa_jpake_io_mode_t io_mode) { psa_jpake_computation_stage_t *stage = &operation->computation_stage.jpake; if (stage->step == PSA_PAKE_STEP_ZK_PROOF) { /* End of an input/output */ - if (function_mode == PSA_JPAKE_INPUT) { + if (io_mode == PSA_JPAKE_INPUT) { stage->inputs++; if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round)) { stage->mode = PSA_JPAKE_OUTPUT; } } - if (function_mode == PSA_JPAKE_OUTPUT) { + if (io_mode == PSA_JPAKE_OUTPUT) { stage->outputs++; if (stage->outputs >= PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { stage->mode = PSA_JPAKE_INPUT; From 024e5c5f2e7978aafd959e4d4a199ff46f6ed88f Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 15:48:21 +0100 Subject: [PATCH 49/89] Rename struct member mode to io_mode Signed-off-by: David Horstmann --- include/psa/crypto_extra.h | 2 +- library/psa_crypto.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index eea9ef8534..87ab4d6b07 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -2043,7 +2043,7 @@ struct psa_jpake_computation_stage_s { /* The J-PAKE round we are currently on */ psa_jpake_round_t MBEDTLS_PRIVATE(round); /* The 'mode' we are currently in (inputting or outputting) */ - psa_jpake_io_mode_t MBEDTLS_PRIVATE(mode); + psa_jpake_io_mode_t MBEDTLS_PRIVATE(io_mode); /* The number of inputs so far this round */ uint8_t MBEDTLS_PRIVATE(inputs); /* The number of outputs so far this round */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 801d35ff9f..9deddde185 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7768,7 +7768,7 @@ psa_status_t psa_pake_setup( &operation->computation_stage.jpake; computation_stage->round = PSA_JPAKE_FIRST; - computation_stage->mode = PSA_JPAKE_INPUT; + computation_stage->io_mode = PSA_JPAKE_INPUT; computation_stage->inputs = 0; computation_stage->outputs = 0; computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; @@ -7947,7 +7947,7 @@ static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_s { if (stage->round == PSA_JPAKE_FIRST) { int is_x1; - if (stage->mode == PSA_JPAKE_OUTPUT) { + if (stage->io_mode == PSA_JPAKE_OUTPUT) { is_x1 = (stage->outputs < 1); } else { is_x1 = (stage->inputs < 1); @@ -7977,7 +7977,7 @@ static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_s } } } else if (stage->round == PSA_JPAKE_SECOND) { - if (stage->mode == PSA_JPAKE_OUTPUT) { + if (stage->io_mode == PSA_JPAKE_OUTPUT) { switch (stage->step) { case PSA_PAKE_STEP_KEY_SHARE: return PSA_JPAKE_X2S_STEP_KEY_SHARE; @@ -8043,7 +8043,7 @@ static psa_status_t psa_pake_complete_inputs( psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; computation_stage->round = PSA_JPAKE_FIRST; - computation_stage->mode = PSA_JPAKE_INPUT; + computation_stage->io_mode = PSA_JPAKE_INPUT; computation_stage->inputs = 0; computation_stage->outputs = 0; computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; @@ -8086,8 +8086,8 @@ static psa_status_t psa_jpake_prologue( computation_stage->outputs == 0) { /* Start of the round, so function decides whether we are inputting * or outputting */ - computation_stage->mode = io_mode; - } else if (computation_stage->mode != io_mode) { + computation_stage->io_mode = io_mode; + } else if (computation_stage->io_mode != io_mode) { /* Middle of the round so the mode we are in must match the function * called by the user */ return PSA_ERROR_BAD_STATE; @@ -8121,13 +8121,13 @@ static psa_status_t psa_jpake_epilogue( if (io_mode == PSA_JPAKE_INPUT) { stage->inputs++; if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round)) { - stage->mode = PSA_JPAKE_OUTPUT; + stage->io_mode = PSA_JPAKE_OUTPUT; } } if (io_mode == PSA_JPAKE_OUTPUT) { stage->outputs++; if (stage->outputs >= PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { - stage->mode = PSA_JPAKE_INPUT; + stage->io_mode = PSA_JPAKE_INPUT; } } if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round) && From 096093bac5ff65ae9f474da647fa9d6c0d24bd1f Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 17:06:07 +0100 Subject: [PATCH 50/89] Remove redundant structures from previous design Signed-off-by: David Horstmann --- include/psa/crypto_extra.h | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 87ab4d6b07..1d91da01a5 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -1984,34 +1984,6 @@ struct psa_crypto_driver_pake_inputs_s { psa_pake_cipher_suite_t MBEDTLS_PRIVATE(cipher_suite); }; -typedef enum psa_jpake_step { - PSA_PAKE_STEP_INVALID = 0, - PSA_PAKE_STEP_X1_X2 = 1, - PSA_PAKE_STEP_X2S = 2, - PSA_PAKE_STEP_DERIVE = 3, -} psa_jpake_step_t; - -typedef enum psa_jpake_state { - PSA_PAKE_STATE_INVALID = 0, - PSA_PAKE_STATE_SETUP = 1, - PSA_PAKE_STATE_READY = 2, - PSA_PAKE_OUTPUT_X1_X2 = 3, - PSA_PAKE_OUTPUT_X2S = 4, - PSA_PAKE_INPUT_X1_X2 = 5, - PSA_PAKE_INPUT_X4S = 6, -} psa_jpake_state_t; - -typedef enum psa_jpake_sequence { - PSA_PAKE_SEQ_INVALID = 0, - PSA_PAKE_X1_STEP_KEY_SHARE = 1, /* also X2S & X4S KEY_SHARE */ - PSA_PAKE_X1_STEP_ZK_PUBLIC = 2, /* also X2S & X4S ZK_PUBLIC */ - PSA_PAKE_X1_STEP_ZK_PROOF = 3, /* also X2S & X4S ZK_PROOF */ - PSA_PAKE_X2_STEP_KEY_SHARE = 4, - PSA_PAKE_X2_STEP_ZK_PUBLIC = 5, - PSA_PAKE_X2_STEP_ZK_PROOF = 6, - PSA_PAKE_SEQ_END = 7, -} psa_jpake_sequence_t; - typedef enum psa_crypto_driver_pake_step { PSA_JPAKE_STEP_INVALID = 0, /* Invalid step */ PSA_JPAKE_X1_STEP_KEY_SHARE = 1, /* Round 1: input/output key share (for ephemeral private key X1).*/ From 279d2279714d2fc167ee7f92c203b40c15044b77 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 17:13:56 +0100 Subject: [PATCH 51/89] Add "completed" clarification to struct comments Signed-off-by: David Horstmann --- include/psa/crypto_extra.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 1d91da01a5..a7d98a084a 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -2016,9 +2016,9 @@ struct psa_jpake_computation_stage_s { psa_jpake_round_t MBEDTLS_PRIVATE(round); /* The 'mode' we are currently in (inputting or outputting) */ psa_jpake_io_mode_t MBEDTLS_PRIVATE(io_mode); - /* The number of inputs so far this round */ + /* The number of completed inputs so far this round */ uint8_t MBEDTLS_PRIVATE(inputs); - /* The number of outputs so far this round */ + /* The number of completed outputs so far this round */ uint8_t MBEDTLS_PRIVATE(outputs); /* The next expected step (KEY_SHARE, ZK_PUBLIC or ZK_PROOF) */ psa_pake_step_t MBEDTLS_PRIVATE(step); From 16f0151887c034619d754241f8b4d87b99fbfac5 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 17:21:07 +0100 Subject: [PATCH 52/89] Use memset for initialization Signed-off-by: David Horstmann --- library/psa_crypto.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 9deddde185..a36bc7f05d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7767,10 +7767,7 @@ psa_status_t psa_pake_setup( psa_jpake_computation_stage_t *computation_stage = &operation->computation_stage.jpake; - computation_stage->round = PSA_JPAKE_FIRST; - computation_stage->io_mode = PSA_JPAKE_INPUT; - computation_stage->inputs = 0; - computation_stage->outputs = 0; + memset(computation_stage, 0, sizeof(*computation_stage)); computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; } else #endif /* PSA_WANT_ALG_JPAKE */ From 1b54faed67ccb1ec3981edb5c334119d8baa696d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 18:05:52 +0100 Subject: [PATCH 53/89] Remove unnecessary initialization of state The psa_jpake_computation_stage_t is already initialized in psa_pake_setup(), so does not need initializing again in psa_pake_complete_inputs(). Signed-off-by: David Horstmann --- library/psa_crypto.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a36bc7f05d..46b9129d7a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8037,13 +8037,6 @@ static psa_status_t psa_pake_complete_inputs( #if defined(PSA_WANT_ALG_JPAKE) if (operation->alg == PSA_ALG_JPAKE) { operation->stage = PSA_PAKE_OPERATION_STAGE_COMPUTATION; - psa_jpake_computation_stage_t *computation_stage = - &operation->computation_stage.jpake; - computation_stage->round = PSA_JPAKE_FIRST; - computation_stage->io_mode = PSA_JPAKE_INPUT; - computation_stage->inputs = 0; - computation_stage->outputs = 0; - computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; } else #endif /* PSA_WANT_ALG_JPAKE */ { From 5d878f6c5f7b9fe843f734d645855b505c86f6b8 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 18:09:43 +0100 Subject: [PATCH 54/89] Tweak wording for clarity "inputs this round" -> "inputs for this round" Signed-off-by: David Horstmann --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 46b9129d7a..1238680f97 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8083,7 +8083,7 @@ static psa_status_t psa_jpake_prologue( return PSA_ERROR_BAD_STATE; } - /* Check that we do not already have enough inputs/outputs + /* Check that we do not already have enough inputs/outputs for * this round */ if (io_mode == PSA_JPAKE_INPUT) { if (computation_stage->inputs >= From 74a3d8c99cfec89cd41404ea86675389b556fd34 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 18:28:19 +0100 Subject: [PATCH 55/89] Simplify logic of driver step conversion Take advantage of the contiguous nature of XYZ_KEY_SHARE, XYZ_ZK_PUBLIC and XYZ_ZK_PROOF to simplify the conversion code. Signed-off-by: David Horstmann --- library/psa_crypto.c | 58 +++++++++----------------------------------- 1 file changed, 11 insertions(+), 47 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 1238680f97..6303abbe63 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7942,63 +7942,27 @@ exit: static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_step( psa_jpake_computation_stage_t *stage) { + psa_crypto_driver_pake_step_t key_share_step; if (stage->round == PSA_JPAKE_FIRST) { int is_x1; + if (stage->io_mode == PSA_JPAKE_OUTPUT) { is_x1 = (stage->outputs < 1); } else { is_x1 = (stage->inputs < 1); } - if (is_x1) { - switch (stage->step) { - case PSA_PAKE_STEP_KEY_SHARE: - return PSA_JPAKE_X1_STEP_KEY_SHARE; - case PSA_PAKE_STEP_ZK_PUBLIC: - return PSA_JPAKE_X1_STEP_ZK_PUBLIC; - case PSA_PAKE_STEP_ZK_PROOF: - return PSA_JPAKE_X1_STEP_ZK_PROOF; - default: - return PSA_JPAKE_STEP_INVALID; - } - } else { - switch (stage->step) { - case PSA_PAKE_STEP_KEY_SHARE: - return PSA_JPAKE_X2_STEP_KEY_SHARE; - case PSA_PAKE_STEP_ZK_PUBLIC: - return PSA_JPAKE_X2_STEP_ZK_PUBLIC; - case PSA_PAKE_STEP_ZK_PROOF: - return PSA_JPAKE_X2_STEP_ZK_PROOF; - default: - return PSA_JPAKE_STEP_INVALID; - } - } + key_share_step = is_x1 ? + PSA_JPAKE_X1_STEP_KEY_SHARE : + PSA_JPAKE_X2_STEP_KEY_SHARE; } else if (stage->round == PSA_JPAKE_SECOND) { - if (stage->io_mode == PSA_JPAKE_OUTPUT) { - switch (stage->step) { - case PSA_PAKE_STEP_KEY_SHARE: - return PSA_JPAKE_X2S_STEP_KEY_SHARE; - case PSA_PAKE_STEP_ZK_PUBLIC: - return PSA_JPAKE_X2S_STEP_ZK_PUBLIC; - case PSA_PAKE_STEP_ZK_PROOF: - return PSA_JPAKE_X2S_STEP_ZK_PROOF; - default: - return PSA_JPAKE_STEP_INVALID; - } - } else { - switch (stage->step) { - case PSA_PAKE_STEP_KEY_SHARE: - return PSA_JPAKE_X4S_STEP_KEY_SHARE; - case PSA_PAKE_STEP_ZK_PUBLIC: - return PSA_JPAKE_X4S_STEP_ZK_PUBLIC; - case PSA_PAKE_STEP_ZK_PROOF: - return PSA_JPAKE_X4S_STEP_ZK_PROOF; - default: - return PSA_JPAKE_STEP_INVALID; - } - } + key_share_step = (stage->io_mode == PSA_JPAKE_OUTPUT) ? + PSA_JPAKE_X2S_STEP_KEY_SHARE : + PSA_JPAKE_X4S_STEP_KEY_SHARE; + } else { + return PSA_JPAKE_STEP_INVALID; } - return PSA_JPAKE_STEP_INVALID; + return key_share_step + stage->step - PSA_PAKE_STEP_KEY_SHARE; } #endif /* PSA_WANT_ALG_JPAKE */ From e5b374adaf88ece0c2876f12bd3bbd3be8c17026 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 14 Jun 2023 19:02:00 +0100 Subject: [PATCH 56/89] Remove comment explaining the state machine The explanation of the dispatch layer's state machine should not be in the file containing the software implementation and a better understanding can be had by reading the dispatch layer's code. Signed-off-by: David Horstmann --- library/psa_crypto_pake.c | 62 --------------------------------------- 1 file changed, 62 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 4136614f34..7140faf837 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -79,68 +79,6 @@ * psa_pake_abort() */ -/* - * The first PAKE step shares the same sequences of the second PAKE step - * but with a second set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs. - * It's simpler to share the same sequences numbers of the first - * set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs in both PAKE steps. - * - * State sequence with step, state & sequence enums: - * => Input & Output Step = PSA_PAKE_STEP_INVALID - * => state = PSA_PAKE_STATE_INVALID - * psa_pake_setup() - * => Input & Output Step = PSA_PAKE_STEP_X1_X2 - * => state = PSA_PAKE_STATE_SETUP - * => sequence = PSA_PAKE_SEQ_INVALID - * | - * |--- In any order: (First round input before or after first round output) - * | | First call of psa_pake_output() or psa_pake_input() sets - * | | state = PSA_PAKE_STATE_READY - * | | - * | |------ In Order: => state = PSA_PAKE_OUTPUT_X1_X2 - * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE - * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC - * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF - * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE - * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC - * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF - * | | | => state = PSA_PAKE_STATE_READY - * | | | => sequence = PSA_PAKE_SEQ_INVALID - * | | | => Output Step = PSA_PAKE_STEP_X2S - * | | - * | |------ In Order: => state = PSA_PAKE_INPUT_X1_X2 - * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE - * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC - * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF - * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE - * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC - * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF - * | | | => state = PSA_PAKE_STATE_READY - * | | | => sequence = PSA_PAKE_SEQ_INVALID - * | | | => Output Step = PSA_PAKE_INPUT_X4S - * | - * |--- In any order: (Second round input before or after second round output) - * | | - * | |------ In Order: => state = PSA_PAKE_OUTPUT_X2S - * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE - * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC - * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF - * | | | => state = PSA_PAKE_STATE_READY - * | | | => sequence = PSA_PAKE_SEQ_INVALID - * | | | => Output Step = PSA_PAKE_STEP_DERIVE - * | | - * | |------ In Order: => state = PSA_PAKE_INPUT_X4S - * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE - * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC - * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF - * | | | => state = PSA_PAKE_STATE_READY - * | | | => sequence = PSA_PAKE_SEQ_INVALID - * | | | => Output Step = PSA_PAKE_STEP_DERIVE - * | - * psa_pake_get_implicit_key() - * => Input & Output Step = PSA_PAKE_STEP_INVALID - */ - #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) static psa_status_t mbedtls_ecjpake_to_psa_error(int ret) { From 88d25f00758ea6aaac124ea5cfa0f8ab1cf68dfe Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 20 Jun 2023 18:21:44 +0100 Subject: [PATCH 57/89] Remove unnecessary checks in psa_jpake_prologue() These checks are not needed as long as the state is intact. Signed-off-by: David Horstmann --- library/psa_crypto.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 6303abbe63..0a549ef49d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8047,19 +8047,6 @@ static psa_status_t psa_jpake_prologue( return PSA_ERROR_BAD_STATE; } - /* Check that we do not already have enough inputs/outputs for - * this round */ - if (io_mode == PSA_JPAKE_INPUT) { - if (computation_stage->inputs >= - PSA_JPAKE_EXPECTED_INPUTS(computation_stage->round)) { - return PSA_ERROR_BAD_STATE; - } - } else { - if (computation_stage->outputs >= - PSA_JPAKE_EXPECTED_OUTPUTS(computation_stage->round)) { - return PSA_ERROR_BAD_STATE; - } - } return PSA_SUCCESS; } From a62d712cf8575cb3a5106bd79fb8cd544f945cb1 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 15 Jun 2023 17:46:56 +0100 Subject: [PATCH 58/89] Add testing for extra calls during a round Test that extra calls to psa_pake_input() and psa_pake_output() during a round return the correct error. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_pake.data | 8 +++++++ .../test_suite_psa_crypto_pake.function | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_pake.data b/tests/suites/test_suite_psa_crypto_pake.data index 9e1cc6327a..89f15623ce 100644 --- a/tests/suites/test_suite_psa_crypto_pake.data +++ b/tests/suites/test_suite_psa_crypto_pake.data @@ -210,6 +210,14 @@ PSA PAKE: inject ERR_INJECT_ROUND2_SERVER_ZK_PROOF depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_SERVER_ZK_PROOF:PSA_ERROR_DATA_INVALID +PSA PAKE: inject ERR_INJECT_EXTRA_OUTPUT +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_EXTRA_OUTPUT:PSA_ERROR_BAD_STATE + +PSA PAKE: inject ERR_INJECT_EXTRA_INPUT +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_INJECT_EXTRA_INPUT:PSA_ERROR_BAD_STATE + PSA PAKE: ecjpake size macros depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256 ecjpake_size_macros: diff --git a/tests/suites/test_suite_psa_crypto_pake.function b/tests/suites/test_suite_psa_crypto_pake.function index 52380de172..87c40f5e48 100644 --- a/tests/suites/test_suite_psa_crypto_pake.function +++ b/tests/suites/test_suite_psa_crypto_pake.function @@ -2,6 +2,7 @@ #include #include "psa/crypto.h" +#include "psa/crypto_extra.h" typedef enum { ERR_NONE = 0, @@ -39,6 +40,8 @@ typedef enum { ERR_INJECT_ROUND2_SERVER_KEY_SHARE, ERR_INJECT_ROUND2_SERVER_ZK_PUBLIC, ERR_INJECT_ROUND2_SERVER_ZK_PROOF, + ERR_INJECT_EXTRA_OUTPUT, + ERR_INJECT_EXTRA_INPUT, /* erros issued from the .data file */ ERR_IN_SETUP, ERR_IN_SET_USER, @@ -69,6 +72,13 @@ static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' }; *(buf + 7) ^= 1; \ } +#define DO_ROUND_CONDITIONAL_CHECK_FAILURE(this_stage, function) \ + if (this_stage == err_stage) \ + { \ + TEST_EQUAL(function, expected_error_arg); \ + break; \ + } + #define DO_ROUND_UPDATE_OFFSETS(main_buf_offset, step_offset, step_size) \ { \ step_offset = main_buf_offset; \ @@ -185,6 +195,12 @@ static void ecjpake_do_round(psa_algorithm_t alg, unsigned int primitive, buffer0 + buffer0_off); DO_ROUND_UPDATE_OFFSETS(buffer0_off, s_x2_pr_off, s_x2_pr_len); + size_t extra_output_len; + DO_ROUND_CONDITIONAL_CHECK_FAILURE( + ERR_INJECT_EXTRA_OUTPUT, + psa_pake_output(server, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g2_off, 512 - s_g2_off, &extra_output_len)); + (void) extra_output_len; /* * When injecting errors in inputs, the implementation is * free to detect it right away of with a delay. @@ -223,6 +239,12 @@ static void ecjpake_do_round(psa_algorithm_t alg, unsigned int primitive, s_x2_pr_len); DO_ROUND_CHECK_FAILURE(); + /* Note: Must have client_input_first == 1 to inject extra input */ + DO_ROUND_CONDITIONAL_CHECK_FAILURE( + ERR_INJECT_EXTRA_INPUT, + psa_pake_input(client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g2_off, s_g2_len)); + /* Error didn't trigger, make test fail */ if ((err_stage >= ERR_INJECT_ROUND1_SERVER_KEY_SHARE_PART1) && (err_stage <= ERR_INJECT_ROUND1_SERVER_ZK_PROOF_PART2)) { From 25c907071fbaf923651acafe98cca6221dce6209 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 20 Jun 2023 19:10:25 +0100 Subject: [PATCH 59/89] Test extra inputs and outputs at the end of J-PAKE Add tests for supplying inputs or requesting outputs when a J-PAKE computation has already completed Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_pake.data | 8 ++ .../test_suite_psa_crypto_pake.function | 75 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_pake.data b/tests/suites/test_suite_psa_crypto_pake.data index 89f15623ce..da54ad116a 100644 --- a/tests/suites/test_suite_psa_crypto_pake.data +++ b/tests/suites/test_suite_psa_crypto_pake.data @@ -218,6 +218,14 @@ PSA PAKE: inject ERR_INJECT_EXTRA_INPUT depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_INJECT_EXTRA_INPUT:PSA_ERROR_BAD_STATE +PSA PAKE: inject ERR_INJECT_EXTRA_OUTPUT_AT_END +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject_second:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_INJECT_EXTRA_OUTPUT_AT_END:PSA_ERROR_BAD_STATE + +PSA PAKE: inject ERR_INJECT_EXTRA_INPUT_AT_END +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject_second:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_EXTRA_INPUT_AT_END:PSA_ERROR_BAD_STATE + PSA PAKE: ecjpake size macros depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256 ecjpake_size_macros: diff --git a/tests/suites/test_suite_psa_crypto_pake.function b/tests/suites/test_suite_psa_crypto_pake.function index 87c40f5e48..49ca361907 100644 --- a/tests/suites/test_suite_psa_crypto_pake.function +++ b/tests/suites/test_suite_psa_crypto_pake.function @@ -42,6 +42,8 @@ typedef enum { ERR_INJECT_ROUND2_SERVER_ZK_PROOF, ERR_INJECT_EXTRA_OUTPUT, ERR_INJECT_EXTRA_INPUT, + ERR_INJECT_EXTRA_OUTPUT_AT_END, + ERR_INJECT_EXTRA_INPUT_AT_END, /* erros issued from the .data file */ ERR_IN_SETUP, ERR_IN_SET_USER, @@ -466,6 +468,16 @@ static void ecjpake_do_round(psa_algorithm_t alg, unsigned int primitive, buffer1 + buffer1_off); DO_ROUND_UPDATE_OFFSETS(buffer1_off, c_x2s_pr_off, c_x2s_pr_len); + if (client_input_first == 1) { + size_t extra_output_at_end_len; + DO_ROUND_CONDITIONAL_CHECK_FAILURE( + ERR_INJECT_EXTRA_OUTPUT_AT_END, + psa_pake_output(client, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_a_off, 512 - c_a_off, + &extra_output_at_end_len)); + (void) extra_output_at_end_len; + } + if (client_input_first == 0) { /* Client second round Input */ status = psa_pake_input(client, PSA_PAKE_STEP_KEY_SHARE, @@ -503,6 +515,12 @@ static void ecjpake_do_round(psa_algorithm_t alg, unsigned int primitive, buffer1 + c_x2s_pr_off, c_x2s_pr_len); DO_ROUND_CHECK_FAILURE(); + DO_ROUND_CONDITIONAL_CHECK_FAILURE( + ERR_INJECT_EXTRA_INPUT_AT_END, + psa_pake_input(server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_a_off, c_a_len)); + + /* Error didn't trigger, make test fail */ if ((err_stage >= ERR_INJECT_ROUND2_CLIENT_KEY_SHARE) && (err_stage <= ERR_INJECT_ROUND2_CLIENT_ZK_PROOF)) { @@ -810,6 +828,63 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ +/* Inject errors during the second round of J-PAKE */ +void ecjpake_rounds_inject_second(int alg_arg, int primitive_arg, int hash_arg, + int client_input_first, + data_t *pw_data, + int err_stage_arg, + int expected_error_arg) +{ + psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); + psa_pake_operation_t server = psa_pake_operation_init(); + psa_pake_operation_t client = psa_pake_operation_init(); + psa_algorithm_t alg = alg_arg; + psa_algorithm_t hash_alg = hash_arg; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + ecjpake_error_stage_t err_stage = err_stage_arg; + + PSA_INIT(); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD); + + PSA_ASSERT(psa_import_key(&attributes, pw_data->x, pw_data->len, + &key)); + + psa_pake_cs_set_algorithm(&cipher_suite, alg); + psa_pake_cs_set_primitive(&cipher_suite, primitive_arg); + psa_pake_cs_set_hash(&cipher_suite, hash_alg); + + PSA_ASSERT(psa_pake_setup(&server, &cipher_suite)); + PSA_ASSERT(psa_pake_setup(&client, &cipher_suite)); + + PSA_ASSERT(psa_pake_set_user(&server, jpake_server_id, sizeof(jpake_server_id))); + PSA_ASSERT(psa_pake_set_peer(&server, jpake_client_id, sizeof(jpake_client_id))); + PSA_ASSERT(psa_pake_set_user(&client, jpake_client_id, sizeof(jpake_client_id))); + PSA_ASSERT(psa_pake_set_peer(&client, jpake_server_id, sizeof(jpake_server_id))); + + PSA_ASSERT(psa_pake_set_password_key(&server, key)); + PSA_ASSERT(psa_pake_set_password_key(&client, key)); + + ecjpake_do_round(alg, primitive_arg, &server, &client, + client_input_first, PAKE_ROUND_ONE, + ERR_NONE, expected_error_arg); + + ecjpake_do_round(alg, primitive_arg, &server, &client, + client_input_first, PAKE_ROUND_TWO, + err_stage, expected_error_arg); + +exit: + psa_destroy_key(key); + psa_pake_abort(&server); + psa_pake_abort(&client); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ void ecjpake_rounds(int alg_arg, int primitive_arg, int hash_arg, int derive_alg_arg, data_t *pw_data, From 57727cd3fc728a47eaee0ac8291826859b435cd1 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 20 Jun 2023 19:40:57 +0100 Subject: [PATCH 60/89] Explain the sequence of mbedtls_psa_pake_ calls Add a comment showing the order in which the mbedtls_psa_pake_xyz() functions may be called. Signed-off-by: David Horstmann --- library/psa_crypto_pake.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 7140faf837..e22bcf825b 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -79,6 +79,40 @@ * psa_pake_abort() */ +/* + * Possible sequence of calls to implementation: + * + * |--- In any order: + * | | + * | |------ In Order + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_KEY_SHARE) + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PUBLIC) + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PROOF) + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_KEY_SHARE) + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PUBLIC) + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PROOF) + * | | + * | |------ In Order: + * | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_KEY_SHARE) + * | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PUBLIC) + * | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PROOF) + * | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_KEY_SHARE) + * | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PUBLIC) + * | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PROOF) + * | + * |--- In any order: + * | | + * | |------ In Order + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_KEY_SHARE) + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PUBLIC) + * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PROOF) + * | | + * | |------ In Order: + * | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_KEY_SHARE) + * | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PUBLIC) + * | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PROOF) + */ + #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) static psa_status_t mbedtls_ecjpake_to_psa_error(int ret) { From a5f7de1df2cb7cc3aa776e6053d4658c1c9eb946 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 21 Jun 2023 15:58:05 +0100 Subject: [PATCH 61/89] Refactor injecting errors in the second round Use a single function rather than 2 similar ones and pass the round that is desired. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_pake.data | 56 ++++++++-------- .../test_suite_psa_crypto_pake.function | 65 ++----------------- 2 files changed, 33 insertions(+), 88 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_pake.data b/tests/suites/test_suite_psa_crypto_pake.data index da54ad116a..ea39ea45fe 100644 --- a/tests/suites/test_suite_psa_crypto_pake.data +++ b/tests/suites/test_suite_psa_crypto_pake.data @@ -132,99 +132,99 @@ ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA PSA PAKE: no injected errors depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_NONE:PSA_SUCCESS +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_NONE:PSA_SUCCESS:0 PSA PAKE: no injected errors, client input first depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_NONE:PSA_SUCCESS +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_NONE:PSA_SUCCESS:0 PSA PAKE: inject ERR_INJECT_ROUND1_CLIENT_KEY_SHARE_PART1 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_KEY_SHARE_PART1:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_KEY_SHARE_PART1:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_CLIENT_ZK_PUBLIC_PART1 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_ZK_PUBLIC_PART1:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_ZK_PUBLIC_PART1:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_CLIENT_ZK_PROOF_PART1 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_ZK_PROOF_PART1:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_ZK_PROOF_PART1:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_CLIENT_KEY_SHARE_PART2 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_KEY_SHARE_PART2:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_KEY_SHARE_PART2:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_CLIENT_ZK_PUBLIC_PART2 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_ZK_PUBLIC_PART2:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_ZK_PUBLIC_PART2:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_CLIENT_ZK_PROOF_PART2 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_ZK_PROOF_PART2:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_CLIENT_ZK_PROOF_PART2:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_SERVER_KEY_SHARE_PART1 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_KEY_SHARE_PART1:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_KEY_SHARE_PART1:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_SERVER_ZK_PUBLIC_PART1 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_ZK_PUBLIC_PART1:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_ZK_PUBLIC_PART1:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_SERVER_ZK_PROOF_PART1 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_ZK_PROOF_PART1:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_ZK_PROOF_PART1:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_SERVER_KEY_SHARE_PART2 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_KEY_SHARE_PART2:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_KEY_SHARE_PART2:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_SERVER_ZK_PUBLIC_PART2 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_ZK_PUBLIC_PART2:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_ZK_PUBLIC_PART2:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND1_SERVER_ZK_PROOF_PART2 depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_ZK_PROOF_PART2:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND1_SERVER_ZK_PROOF_PART2:PSA_ERROR_DATA_INVALID:0 PSA PAKE: inject ERR_INJECT_ROUND2_CLIENT_KEY_SHARE depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_CLIENT_KEY_SHARE:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_CLIENT_KEY_SHARE:PSA_ERROR_DATA_INVALID:1 PSA PAKE: inject ERR_INJECT_ROUND2_CLIENT_ZK_PUBLIC depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_CLIENT_ZK_PUBLIC:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_CLIENT_ZK_PUBLIC:PSA_ERROR_DATA_INVALID:1 PSA PAKE: inject ERR_INJECT_ROUND2_CLIENT_ZK_PROOF depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_CLIENT_ZK_PROOF:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_CLIENT_ZK_PROOF:PSA_ERROR_DATA_INVALID:1 PSA PAKE: inject ERR_INJECT_ROUND2_SERVER_KEY_SHARE depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_SERVER_KEY_SHARE:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_SERVER_KEY_SHARE:PSA_ERROR_DATA_INVALID:1 PSA PAKE: inject ERR_INJECT_ROUND2_SERVER_ZK_PUBLIC depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_SERVER_ZK_PUBLIC:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_SERVER_ZK_PUBLIC:PSA_ERROR_DATA_INVALID:1 PSA PAKE: inject ERR_INJECT_ROUND2_SERVER_ZK_PROOF depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_SERVER_ZK_PROOF:PSA_ERROR_DATA_INVALID +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_ROUND2_SERVER_ZK_PROOF:PSA_ERROR_DATA_INVALID:1 PSA PAKE: inject ERR_INJECT_EXTRA_OUTPUT -depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_EXTRA_OUTPUT:PSA_ERROR_BAD_STATE +depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_EXTRA_OUTPUT:PSA_ERROR_BAD_STATE:0 PSA PAKE: inject ERR_INJECT_EXTRA_INPUT -depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_INJECT_EXTRA_INPUT:PSA_ERROR_BAD_STATE +depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_INJECT_EXTRA_INPUT:PSA_ERROR_BAD_STATE:0 PSA PAKE: inject ERR_INJECT_EXTRA_OUTPUT_AT_END -depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject_second:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_INJECT_EXTRA_OUTPUT_AT_END:PSA_ERROR_BAD_STATE +depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:"abcdef":ERR_INJECT_EXTRA_OUTPUT_AT_END:PSA_ERROR_BAD_STATE:1 PSA PAKE: inject ERR_INJECT_EXTRA_INPUT_AT_END -depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds_inject_second:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_EXTRA_INPUT_AT_END:PSA_ERROR_BAD_STATE +depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:"abcdef":ERR_INJECT_EXTRA_INPUT_AT_END:PSA_ERROR_BAD_STATE:1 PSA PAKE: ecjpake size macros depends_on:MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY:PSA_WANT_ECC_SECP_R1_256 diff --git a/tests/suites/test_suite_psa_crypto_pake.function b/tests/suites/test_suite_psa_crypto_pake.function index 49ca361907..f04d56fdb3 100644 --- a/tests/suites/test_suite_psa_crypto_pake.function +++ b/tests/suites/test_suite_psa_crypto_pake.function @@ -773,7 +773,8 @@ void ecjpake_rounds_inject(int alg_arg, int primitive_arg, int hash_arg, int client_input_first, data_t *pw_data, int err_stage_arg, - int expected_error_arg) + int expected_error_arg, + int inject_in_second_round) { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); psa_pake_operation_t server = psa_pake_operation_init(); @@ -810,9 +811,10 @@ void ecjpake_rounds_inject(int alg_arg, int primitive_arg, int hash_arg, ecjpake_do_round(alg, primitive_arg, &server, &client, client_input_first, PAKE_ROUND_ONE, - err_stage, expected_error_arg); + inject_in_second_round ? ERR_NONE : err_stage, + expected_error_arg); - if (err_stage != ERR_NONE) { + if (!inject_in_second_round && err_stage != ERR_NONE) { goto exit; } @@ -828,63 +830,6 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ -/* Inject errors during the second round of J-PAKE */ -void ecjpake_rounds_inject_second(int alg_arg, int primitive_arg, int hash_arg, - int client_input_first, - data_t *pw_data, - int err_stage_arg, - int expected_error_arg) -{ - psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_operation_t server = psa_pake_operation_init(); - psa_pake_operation_t client = psa_pake_operation_init(); - psa_algorithm_t alg = alg_arg; - psa_algorithm_t hash_alg = hash_arg; - mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - ecjpake_error_stage_t err_stage = err_stage_arg; - - PSA_INIT(); - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD); - - PSA_ASSERT(psa_import_key(&attributes, pw_data->x, pw_data->len, - &key)); - - psa_pake_cs_set_algorithm(&cipher_suite, alg); - psa_pake_cs_set_primitive(&cipher_suite, primitive_arg); - psa_pake_cs_set_hash(&cipher_suite, hash_alg); - - PSA_ASSERT(psa_pake_setup(&server, &cipher_suite)); - PSA_ASSERT(psa_pake_setup(&client, &cipher_suite)); - - PSA_ASSERT(psa_pake_set_user(&server, jpake_server_id, sizeof(jpake_server_id))); - PSA_ASSERT(psa_pake_set_peer(&server, jpake_client_id, sizeof(jpake_client_id))); - PSA_ASSERT(psa_pake_set_user(&client, jpake_client_id, sizeof(jpake_client_id))); - PSA_ASSERT(psa_pake_set_peer(&client, jpake_server_id, sizeof(jpake_server_id))); - - PSA_ASSERT(psa_pake_set_password_key(&server, key)); - PSA_ASSERT(psa_pake_set_password_key(&client, key)); - - ecjpake_do_round(alg, primitive_arg, &server, &client, - client_input_first, PAKE_ROUND_ONE, - ERR_NONE, expected_error_arg); - - ecjpake_do_round(alg, primitive_arg, &server, &client, - client_input_first, PAKE_ROUND_TWO, - err_stage, expected_error_arg); - -exit: - psa_destroy_key(key); - psa_pake_abort(&server); - psa_pake_abort(&client); - PSA_DONE(); -} -/* END_CASE */ - /* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ void ecjpake_rounds(int alg_arg, int primitive_arg, int hash_arg, int derive_alg_arg, data_t *pw_data, From 2ed8fb7e4fd94fc8d3a048fe073e6724cabea4d6 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 14 Jun 2023 16:01:47 +0100 Subject: [PATCH 62/89] ecp_mod_raw: Enabled fast reduction. This patch modifies `mbedtls_mpi_mod_raw_mul` to utilise fast-reduction when available. Signed-off-by: Minos Galanakis --- library/bignum_mod_raw.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c index 791921151d..11419f1e74 100644 --- a/library/bignum_mod_raw.c +++ b/library/bignum_mod_raw.c @@ -114,8 +114,6 @@ void mbedtls_mpi_mod_raw_sub(mbedtls_mpi_uint *X, (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c); } -#if defined(MBEDTLS_TEST_HOOKS) - MBEDTLS_STATIC_TESTABLE void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X, const mbedtls_mpi_mod_modulus *N) @@ -125,7 +123,6 @@ void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X, (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c); } -#endif /* MBEDTLS_TEST_HOOKS */ void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, const mbedtls_mpi_uint *A, @@ -133,8 +130,22 @@ void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, const mbedtls_mpi_mod_modulus *N, mbedtls_mpi_uint *T) { - mbedtls_mpi_core_montmul(X, A, B, N->limbs, N->p, N->limbs, - N->rep.mont.mm, T); + const size_t T_limbs = (N->limbs * 2); + switch (N->int_rep) { + case MBEDTLS_MPI_MOD_REP_MONTGOMERY: + mbedtls_mpi_core_montmul(X, A, B, N->limbs, N->p, N->limbs, + N->rep.mont.mm, T); + break; + case MBEDTLS_MPI_MOD_REP_OPT_RED: + mbedtls_mpi_core_mul(T, A, N->limbs, B, N->limbs); + (*N->rep.ored.modp)(T, T_limbs); + mbedtls_mpi_mod_raw_fix_quasi_reduction(T, N); + memcpy(X, T, N->limbs * sizeof(mbedtls_mpi_uint)); + break; + default: + break; + } + } size_t mbedtls_mpi_mod_raw_inv_prime_working_limbs(size_t AN_limbs) From fee70a5342f3449f264af309f048599254a85118 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 16 Jun 2023 11:31:57 +0100 Subject: [PATCH 63/89] test_suite_ecp: Extended `ecp_mul_inv` tests for optimised reduction. Signed-off-by: Minos Galanakis --- tests/suites/test_suite_ecp.data | 132 +++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 030cd464c7..c515877922 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -1235,6 +1235,138 @@ ecp_mul_inv #48 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_CURVE448) depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED ecp_mod_mul_inv:"0000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff01243a939d867d7e0a75a8568d4d66de88f3ecc1ad37f91a8f9d7d70":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_SCALAR +ecp_mul_inv #49 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192R1) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +ecp_mod_mul_inv:"0000000000000000000000000000152d02c7e14af67fe0bf":MBEDTLS_ECP_DP_SECP192R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #50 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192R1) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +ecp_mod_mul_inv:"4acca2d7100bad687080217babfb490d23dd6460a0007f24":MBEDTLS_ECP_DP_SECP192R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #51 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192R1) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +ecp_mod_mul_inv:"c4fd9a06df9b4efa94531578af8b5886ec0ada82884199f7":MBEDTLS_ECP_DP_SECP192R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #52 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) +depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED +ecp_mod_mul_inv:"f9c4728bef9fba3e7d856a8e2ff62f20c2a57bf64f6d707f0829a8ff":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #53 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) +depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED +ecp_mod_mul_inv:"cee8071ade3e016fd47627782f6543814dd6ab7e6f432679ddacf9ed":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #54 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) +depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED +ecp_mod_mul_inv:"326258467dcbf4d1ab1665a4c5036cb35f4c9231199b58166b3966c6":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #55 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256R1) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_mod_mul_inv:"c36eadeab80f149cd51a1ed6311270ae2e4acc6734e787135f499c3a97f1edc3":MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #56 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256R1) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_mod_mul_inv:"e384042f3130be8a796b221724cf1127a44290804cfbeb7fb6f57142a2a5cddd":MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #57 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256R1) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_mod_mul_inv:"f1d356376f03b5dbf0fd08bde5c4293115f7c7911f7a3ec3f90557602eb20147":MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #58 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP384R1) +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_mod_mul_inv:"a3137cd9b0c9e75a871f92e3ab6b284069ee06cd9c0afb2368fd8d381afcfecc553cb6b3f29216038d268a8d8fcd00f7":MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #59 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP384R1) +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_mod_mul_inv:"a340ca2e1f39f89261f20a23881cde271e36b32add90cbc1801d2375d6db664df297df2364aaafbb9ba3d4672e4fd022":MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #60 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP384R1) +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_mod_mul_inv:"491b1d169c9262fd737847c13bb7370d91825fe985cfa000d4b9bd3c22e7b63016122c53156fae4757943a819a1ced6d":MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #61 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP521R1) +depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED +ecp_mod_mul_inv:"1477156c589f498b61beb35f57662410d8821f3a1ee4a5968a8009618dbe4afda408809822eb0e994fbf9da1659c1ea21b151db97cd1f1567fa4b9327967e0aa591":MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #62 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP521R1) +depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED +ecp_mod_mul_inv:"158dd0fdd801513590d221009f2b6c212f2b30214cc3b1f80aaf9142dc9f328c8e2b0af83e1acdb102d85f287d77188c2b8e7911cf9452f5014966f28da330e1fa6":MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #63 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP521R1) +depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED +ecp_mod_mul_inv:"1e53d580521a1cff4cd72576c13fecb2cbcf39453f2b437f0c8dc78d7982a37749f099942ce693751ec43407c3acf46315132ea2a9ae5fa9253408da2375d2b58fc":MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #64 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE25519) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_mod_mul_inv:"1000000000000000000000000000000014def9dea2079cd65812631a5cf5d3ed":MBEDTLS_ECP_DP_CURVE25519:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #65 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE25519) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_mod_mul_inv:"1000000000000000000000000000000010caf49570936f75d70f03efac6c1c19":MBEDTLS_ECP_DP_CURVE25519:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #66 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE25519) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_mod_mul_inv:"468de1bfdbb20b67371bc5ad0f2bc3e70705b6d85c14ad75daafdbd1502cfd1":MBEDTLS_ECP_DP_CURVE25519:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #67 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192K1) +depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED +ecp_mod_mul_inv:"2228b202d612f2e66d8ca00b7e1c19a737ee7db2708d91cd":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #68 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192K1) +depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED +ecp_mod_mul_inv:"40c0451d06b0d622c65b8336c4c9abe8828f6fd5d5c1abde":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #69 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192K1) +depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED +ecp_mod_mul_inv:"d2a10413f48d7bcc18a9b7c53c7914c5302c9c9e48b2eb62":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #70 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) +depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED +ecp_mod_mul_inv:"0cc154fe846d6b9f51d6166a8d1bb969ff634ab9af95cc89d01669c86":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #71 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) +depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED +ecp_mod_mul_inv:"1000000000000000000000000000075ea446a83291f5136799781cfbd":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #72 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) +depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED +ecp_mod_mul_inv:"0614cf6b720cc9dcc6d3bb36bb46cf285e23a083b067be8c93b51cbb4":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #73 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) +depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED +ecp_mod_mul_inv:"1000000000000000000000000000059232050dc913da533ec71073ce3":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #74 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) +depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED +ecp_mod_mul_inv:"071b3a40f3e2b8984e8cc238b7725870da10cb2de37f430da2da68645":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #75 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) +depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED +ecp_mod_mul_inv:"10000000000000000000000000000aca628de662cdbd5cb4dc69efbb8":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #76 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256K1) +depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED +ecp_mod_mul_inv:"9fd95fed98cc1c2ef91b5dc02fa84f63597e15a3326c07f2918afb3ffd093343":MBEDTLS_ECP_DP_SECP256K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #77 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256K1) +depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED +ecp_mod_mul_inv:"5ddbd441c7037e11caaa9878216c5cfeae67864260429eab4529b56c2661f3de":MBEDTLS_ECP_DP_SECP256K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #78 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256K1) +depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED +ecp_mod_mul_inv:"f8d3f3c02fd712f711d8e30d0d4c142eb106e5f75c25f55b3f983bc5c83c568a":MBEDTLS_ECP_DP_SECP256K1:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #79 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE448) +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_mod_mul_inv:"0000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff11ca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #80 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE448) +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_mod_mul_inv:"0000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff0169d3f35081924aeaf1beac2f2720557c9bdf6b42cdceb54c6160ba":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_COORDINATE + +ecp_mul_inv #81 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE448) +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_mod_mul_inv:"0000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff01243a939d867d7e0a75a8568d4d66de88f3ecc1ad37f91a8f9d7d70":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_COORDINATE + # The following data was generated using python's standard random library, # initialised with seed(2,2) and random.getrandbits(curve bits). Curve bits are 192,256,384,520. # They must be less than the named curves' modulus. mbedtls_mpi_mod_residue_setup() From 7b1093240c7d0d937ab8fb5933c55ee8366d678e Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 16 Jun 2023 14:28:36 +0100 Subject: [PATCH 64/89] bignum_mod_raw: Updated documentation for mbedtls_mpi_mod_raw_mul Signed-off-by: Minos Galanakis --- library/bignum_mod_raw.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c index 11419f1e74..5c855d0e86 100644 --- a/library/bignum_mod_raw.c +++ b/library/bignum_mod_raw.c @@ -137,8 +137,17 @@ void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, N->rep.mont.mm, T); break; case MBEDTLS_MPI_MOD_REP_OPT_RED: + /* Standard (A * B) multiplication stored into pre-allocated T + * buffer of fixed size of ((2N + 1) * ciL) bytes. + + * The space is not fully filled by MBEDTLS_MPI_MOD_REP_OPT_RED + * which requires at max (2N * ciL) bytes. */ mbedtls_mpi_core_mul(T, A, N->limbs, B, N->limbs); + + /* Optimised Reduction */ (*N->rep.ored.modp)(T, T_limbs); + + /* Convert back to cannonical representation */ mbedtls_mpi_mod_raw_fix_quasi_reduction(T, N); memcpy(X, T, N->limbs * sizeof(mbedtls_mpi_uint)); break; From 9a3a1a6ee7e57a1a4f2f892e1d1371529e890a38 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 22 Jun 2023 16:59:09 +0100 Subject: [PATCH 65/89] Simplify directory name comparison in tests Remove custom parsing code in AuthorityKeyIdentifier tests and use mbedtls_x509_dn_gets() and strcmp() instead. Signed-off-by: David Horstmann --- tests/suites/test_suite_x509parse.data | 4 ++-- tests/suites/test_suite_x509parse.function | 19 +++++-------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index edb782470e..b3cccfc1e3 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -3323,11 +3323,11 @@ x509_crt_parse_subjectkeyid:"data_files/authorityKeyId_subjectKeyId_tag_len_malf X509 CRT parse Authority Key Id - Correct Authority Key ID depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_RSA_C -x509_crt_parse_authoritykeyid:"data_files/authorityKeyId_subjectKeyId.crt.der":"A505E864B8DCDF600F50124D60A864AF4D8B4393":"NL/PolarSSL/PolarSSL Test CA/":"680430CD074DE63FCDC051260FD042C2B512B6BA":0 +x509_crt_parse_authoritykeyid:"data_files/authorityKeyId_subjectKeyId.crt.der":"A505E864B8DCDF600F50124D60A864AF4D8B4393":"C=NL, OU=PolarSSL, CN=PolarSSL Test CA":"680430CD074DE63FCDC051260FD042C2B512B6BA":0 X509 CRT parse Authority Key Id - Correct Authority Key ID (no keyid) depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_RSA_C -x509_crt_parse_authoritykeyid:"data_files/authorityKeyId_no_keyid.crt.der":"":"NL/PolarSSL/PolarSSL Test CA/":"680430CD074DE63FCDC051260FD042C2B512B6BA":0 +x509_crt_parse_authoritykeyid:"data_files/authorityKeyId_no_keyid.crt.der":"":"C=NL, OU=PolarSSL, CN=PolarSSL Test CA":"680430CD074DE63FCDC051260FD042C2B512B6BA":0 X509 CRT parse Authority Key Id - Correct Authority Key ID (no issuer) depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_RSA_C diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index dcd44290e5..c142d42cbc 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -1578,11 +1578,8 @@ void x509_crt_parse_authoritykeyid(char *file, int ref_ret) { mbedtls_x509_crt crt; - int bufferCounter = 0; - size_t issuerCounter = 0; - unsigned int result = 0; mbedtls_x509_subject_alternative_name san; - mbedtls_x509_name *pname = NULL; + char name_buf[128]; mbedtls_x509_crt_init(&crt); @@ -1606,18 +1603,12 @@ void x509_crt_parse_authoritykeyid(char *file, TEST_EQUAL(mbedtls_x509_parse_subject_alt_name(&issuerPtr->buf, &san), 0); - pname = &san.san.directory_name; + TEST_ASSERT(mbedtls_x509_dn_gets(name_buf, sizeof(name_buf), + &san.san.directory_name) + > 0); + TEST_EQUAL(strcmp(name_buf, authorityKeyId_issuer), 0); - while (pname != NULL) { - for (issuerCounter = 0; issuerCounter < pname->val.len; issuerCounter++) { - result |= - (authorityKeyId_issuer[bufferCounter++] != pname->val.p[issuerCounter]); - } - bufferCounter++; /* Skipping the slash */ - pname = pname->next; - } mbedtls_x509_free_subject_alt_name(&san); - TEST_EQUAL(result, 0); } /* Serial test */ From 22eb82cb8dd8aa08b2d0893408a1a6972eb7e4fe Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 22 Jun 2023 19:45:01 +0200 Subject: [PATCH 66/89] Clean up subprocess invocation in get_src_files Signed-off-by: Gilles Peskine --- scripts/code_style.py | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/scripts/code_style.py b/scripts/code_style.py index c31fb2949f..cf50c8d42a 100755 --- a/scripts/code_style.py +++ b/scripts/code_style.py @@ -65,29 +65,27 @@ def list_generated_files() -> FrozenSet[str]: def get_src_files() -> List[str]: """ - Use git ls-files to get a list of the source files + Use git to get a list of the source files. + + Only C files are included, and certain files (generated, or 3rdparty) + are excluded. """ git_ls_files_cmd = ["git", "ls-files", "*.[hc]", "tests/suites/*.function", "scripts/data_files/*.fmt"] + output = subprocess.check_output(git_ls_files_cmd, + universal_newlines=True) + src_files = output.split() - result = subprocess.run(git_ls_files_cmd, stdout=subprocess.PIPE, - check=False) - - if result.returncode != 0: - print_err("git ls-files returned: " + str(result.returncode)) - return [] - else: - generated_files = list_generated_files() - src_files = str(result.stdout, "utf-8").split() - # Don't correct style for third-party files (and, for simplicity, - # companion files in the same subtree), or for automatically - # generated files (we're correcting the templates instead). - src_files = [filename for filename in src_files - if not (filename.startswith("3rdparty/") or - filename in generated_files)] - return src_files + generated_files = list_generated_files() + # Don't correct style for third-party files (and, for simplicity, + # companion files in the same subtree), or for automatically + # generated files (we're correcting the templates instead). + src_files = [filename for filename in src_files + if not (filename.startswith("3rdparty/") or + filename in generated_files)] + return src_files def get_uncrustify_version() -> str: """ From 43838b8a24ad7bce100afcb49e403cc818c4a14d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 22 Jun 2023 20:29:41 +0200 Subject: [PATCH 67/89] Add --since option to check files modified since a given commit Signed-off-by: Gilles Peskine --- scripts/code_style.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/scripts/code_style.py b/scripts/code_style.py index cf50c8d42a..4cb58babbe 100755 --- a/scripts/code_style.py +++ b/scripts/code_style.py @@ -22,7 +22,7 @@ import os import re import subprocess import sys -from typing import FrozenSet, List +from typing import FrozenSet, List, Optional UNCRUSTIFY_SUPPORTED_VERSION = "0.75.1" CONFIG_FILE = ".uncrustify.cfg" @@ -63,19 +63,31 @@ def list_generated_files() -> FrozenSet[str]: checks = re.findall(CHECK_CALL_RE, content) return frozenset(word for s in checks for word in s.split()) -def get_src_files() -> List[str]: +def get_src_files(since: Optional[str]) -> List[str]: """ Use git to get a list of the source files. + The optional argument since is a commit, indicating to only list files + that have changed since that commit. Without this argument, list all + files known to git. + Only C files are included, and certain files (generated, or 3rdparty) are excluded. """ - git_ls_files_cmd = ["git", "ls-files", - "*.[hc]", - "tests/suites/*.function", - "scripts/data_files/*.fmt"] - output = subprocess.check_output(git_ls_files_cmd, - universal_newlines=True) + if since is None: + git_ls_files_cmd = ["git", "ls-files", + "*.[hc]", + "tests/suites/*.function", + "scripts/data_files/*.fmt"] + output = subprocess.check_output(git_ls_files_cmd, + universal_newlines=True) + else: + git_ls_files_cmd = ["git", "diff", "--name-only", since, "--", + "*.[hc]", + "tests/suites/*.function", + "scripts/data_files/*.fmt"] + output = subprocess.check_output(git_ls_files_cmd, + universal_newlines=True) src_files = output.split() generated_files = list_generated_files() @@ -180,6 +192,9 @@ def main() -> int: parser.add_argument('-f', '--fix', action='store_true', help=('modify source files to fix the code style ' '(default: print diff, do not modify files)')) + parser.add_argument('-s', '--since', metavar='COMMIT', + help=('only check files modified since the specified commit' + ' (e.g. --since=HEAD~3 or --since=development)')) # --subset is almost useless: it only matters if there are no files # ('code_style.py' without arguments checks all files known to Git, # 'code_style.py --subset' does nothing). In particular, @@ -192,7 +207,7 @@ def main() -> int: args = parser.parse_args() - covered = frozenset(get_src_files()) + covered = frozenset(get_src_files(args.since)) # We only check files that are known to git if args.subset or args.operands: src_files = [f for f in args.operands if f in covered] From 4e5c63d65248f06b704a51fe794b473f41ba247d Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 23 Jun 2023 15:17:37 +0100 Subject: [PATCH 68/89] Improve documentation in bn_mul.h Co-authored-by: Tom Cosgrove Signed-off-by: Dave Rodgman --- library/bn_mul.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/bn_mul.h b/library/bn_mul.h index 93dd4b6bb5..4ccd7b4b17 100644 --- a/library/bn_mul.h +++ b/library/bn_mul.h @@ -248,6 +248,8 @@ #endif /* AMD64 */ +// The following assembly code assumes that a pointer will fit in a 64-bit register +// (including ILP32 __aarch64__ ABIs such as on watchOS, hence the 2^32 - 1) #if defined(__aarch64__) && (UINTPTR_MAX == 0xfffffffful || UINTPTR_MAX == 0xfffffffffffffffful) #define MULADDC_X1_INIT \ From 25d998b3b9961f436d5d6283008ad1ce11256acc Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 23 Jun 2023 14:26:00 +0100 Subject: [PATCH 69/89] ecp_curves: Fixed modp pointers on `mbedtls_ecp_modulus_setup`. Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 4a8f891104..e3bcc8715a 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5970,7 +5970,7 @@ int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) case MBEDTLS_ECP_DP_SECP192K1: if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p192_raw; + modp = &mbedtls_ecp_mod_p192k1_raw; p = (mbedtls_mpi_uint *) secp192k1_p; p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_p)); } else { @@ -5983,7 +5983,7 @@ int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) case MBEDTLS_ECP_DP_SECP224K1: if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p224_raw; + modp = &mbedtls_ecp_mod_p224k1_raw; p = (mbedtls_mpi_uint *) secp224k1_p; p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_p)); } else { @@ -5996,7 +5996,7 @@ int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) case MBEDTLS_ECP_DP_SECP256K1: if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p256_raw; + modp = &mbedtls_ecp_mod_p256k1_raw; p = (mbedtls_mpi_uint *) secp256k1_p; p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_p)); } else { From a984d77f3aeef1901a78ab919519c63f292cc9e8 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 23 Jun 2023 20:37:07 +0100 Subject: [PATCH 70/89] ecp_curves: Added dataset for SECP224K1 Coordinate Modulus. Signed-off-by: Minos Galanakis --- tests/suites/test_suite_ecp.data | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index c515877922..1d88916004 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -1319,29 +1319,32 @@ ecp_mul_inv #69 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192K1) depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED ecp_mod_mul_inv:"d2a10413f48d7bcc18a9b7c53c7914c5302c9c9e48b2eb62":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_COORDINATE +# For coordinate moduli of secp224K1 the values are selected as one for +# modulus - 1, and four random values, generated with +# random.getrandbits(224) % modulus with a seed(2, 2). ecp_mul_inv #70 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED -ecp_mod_mul_inv:"0cc154fe846d6b9f51d6166a8d1bb969ff634ab9af95cc89d01669c86":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"fffffffffffffffffffffffffffffffffffffffffffffffeffffe56c":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #71 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED -ecp_mod_mul_inv:"1000000000000000000000000000075ea446a83291f5136799781cfbd":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"15ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #72 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED -ecp_mod_mul_inv:"0614cf6b720cc9dcc6d3bb36bb46cf285e23a083b067be8c93b51cbb4":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"da94e3e8ab73738fcf1822ffbc6887782b491044d5e341245c6e4337":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #73 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED -ecp_mod_mul_inv:"1000000000000000000000000000059232050dc913da533ec71073ce3":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"94c9c9500925e4749b575bd13653f8dd9b1f282e4067c3584ee207f8":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #74 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED -ecp_mod_mul_inv:"071b3a40f3e2b8984e8cc238b7725870da10cb2de37f430da2da68645":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"cdbd47d364be8049a372db8f6e405d93ffed9235288bc781ae662675":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #75 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED -ecp_mod_mul_inv:"10000000000000000000000000000aca628de662cdbd5cb4dc69efbb8":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"8b4f2fc15f3f57ebf30b94fa82523e86feac7eb7dc38f519b91751da":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #76 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256K1) depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED From c7408a432e5a6ba3f251fc20ef9ee6438e304f39 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Sun, 25 Jun 2023 20:56:59 +0100 Subject: [PATCH 71/89] bignum_mod_raw: Adjusted OPT_RED limb size requirements for mod_raw_mul(). Signed-off-by: Minos Galanakis --- library/bignum_mod_raw.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c index 5c855d0e86..3de5940af0 100644 --- a/library/bignum_mod_raw.c +++ b/library/bignum_mod_raw.c @@ -130,18 +130,25 @@ void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, const mbedtls_mpi_mod_modulus *N, mbedtls_mpi_uint *T) { - const size_t T_limbs = (N->limbs * 2); + /* Standard (A * B) multiplication stored into pre-allocated T + * buffer of fixed limb size of (2N + 1). + + * The space may not not fully filled by when + * MBEDTLS_MPI_MOD_REP_OPT_RED is used, with most + * curves using (2N) limbs. + * + * The 521-bit Weierstrass curve is the only + * that which requires a limb size of (2N + 1). */ + const size_t T_limbs = (N->bits == 521) ? + BITS_TO_LIMBS(N->bits * 2) + 1 : + BITS_TO_LIMBS(N->bits * 2); + switch (N->int_rep) { case MBEDTLS_MPI_MOD_REP_MONTGOMERY: mbedtls_mpi_core_montmul(X, A, B, N->limbs, N->p, N->limbs, N->rep.mont.mm, T); break; case MBEDTLS_MPI_MOD_REP_OPT_RED: - /* Standard (A * B) multiplication stored into pre-allocated T - * buffer of fixed size of ((2N + 1) * ciL) bytes. - - * The space is not fully filled by MBEDTLS_MPI_MOD_REP_OPT_RED - * which requires at max (2N * ciL) bytes. */ mbedtls_mpi_core_mul(T, A, N->limbs, B, N->limbs); /* Optimised Reduction */ From 163ec4090e191b03bbc2cda79d4507fefbf214c1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sun, 25 Jun 2023 22:18:40 +0200 Subject: [PATCH 72/89] Handle deleted files correctly Don't attempt to run on a file that isn't present now. Signed-off-by: Gilles Peskine --- scripts/code_style.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/scripts/code_style.py b/scripts/code_style.py index 4cb58babbe..7de93b085e 100755 --- a/scripts/code_style.py +++ b/scripts/code_style.py @@ -74,21 +74,18 @@ def get_src_files(since: Optional[str]) -> List[str]: Only C files are included, and certain files (generated, or 3rdparty) are excluded. """ - if since is None: - git_ls_files_cmd = ["git", "ls-files", - "*.[hc]", - "tests/suites/*.function", - "scripts/data_files/*.fmt"] - output = subprocess.check_output(git_ls_files_cmd, - universal_newlines=True) - else: - git_ls_files_cmd = ["git", "diff", "--name-only", since, "--", - "*.[hc]", - "tests/suites/*.function", - "scripts/data_files/*.fmt"] - output = subprocess.check_output(git_ls_files_cmd, - universal_newlines=True) + file_patterns = ["*.[hc]", + "tests/suites/*.function", + "scripts/data_files/*.fmt"] + output = subprocess.check_output(["git", "ls-files"] + file_patterns, + universal_newlines=True) src_files = output.split() + if since: + output = subprocess.check_output(["git", "diff", "--name-only", + since, "--"] + + src_files, + universal_newlines=True) + src_files = output.split() generated_files = list_generated_files() # Don't correct style for third-party files (and, for simplicity, From e0c329b0cf0f61155d2bbe4ab1de9a77f6941ba0 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Sun, 25 Jun 2023 23:33:28 +0100 Subject: [PATCH 73/89] test_suite_ecp.data: Limb aligned inputs Signed-off-by: Minos Galanakis --- tests/suites/test_suite_ecp.data | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 1d88916004..44eb9ba395 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -1249,15 +1249,15 @@ ecp_mod_mul_inv:"c4fd9a06df9b4efa94531578af8b5886ec0ada82884199f7":MBEDTLS_ECP_D ecp_mul_inv #52 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED -ecp_mod_mul_inv:"f9c4728bef9fba3e7d856a8e2ff62f20c2a57bf64f6d707f0829a8ff":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"0f9c4728bef9fba3e7d856a8e2ff62f20c2a57bf64f6d707f0829a8ff":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #53 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED -ecp_mod_mul_inv:"cee8071ade3e016fd47627782f6543814dd6ab7e6f432679ddacf9ed":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"0cee8071ade3e016fd47627782f6543814dd6ab7e6f432679ddacf9ed":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #54 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED -ecp_mod_mul_inv:"326258467dcbf4d1ab1665a4c5036cb35f4c9231199b58166b3966c6":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mod_mul_inv:"00326258467dcbf4d1ab1665a4c5036cb35f4c9231199b58166b3966c6":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE ecp_mul_inv #55 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256R1) depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED From 8eb6104256890906f938391ba9263cfe6664dd8e Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 26 Jun 2023 10:03:19 +0100 Subject: [PATCH 74/89] bignum_mod_raw: Fixed a documentation typo. Signed-off-by: Minos Galanakis --- library/bignum_mod_raw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c index 3de5940af0..d29896c414 100644 --- a/library/bignum_mod_raw.c +++ b/library/bignum_mod_raw.c @@ -154,7 +154,7 @@ void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, /* Optimised Reduction */ (*N->rep.ored.modp)(T, T_limbs); - /* Convert back to cannonical representation */ + /* Convert back to canonical representation */ mbedtls_mpi_mod_raw_fix_quasi_reduction(T, N); memcpy(X, T, N->limbs * sizeof(mbedtls_mpi_uint)); break; From aafe90033cffd420a5c6e77f8a147cc45514b9d9 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 26 Jun 2023 15:23:44 +0200 Subject: [PATCH 75/89] test: enable X509 testing in no_ecp_at_all() components Signed-off-by: Valerio Setti --- tests/scripts/all.sh | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 18c2593539..45f7e982f9 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2418,9 +2418,17 @@ component_test_psa_crypto_config_reference_ecc_ecp_light_only () { # on the ECP module. config_psa_crypto_no_ecp_at_all () { DRIVER_ONLY="$1" - # start with crypto_full config for maximum coverage (also enables USE_PSA), - # but excluding X509, TLS and key exchanges - helper_libtestdriver1_adjust_config "crypto_full" + # start with full config for maximum coverage (also enables USE_PSA) + helper_libtestdriver1_adjust_config "full" + + # keep excluding TLS and key exchanges (this will be removed in #7749) + # Note: key exchanges are not explicitly disabled here because they are + # auto-disabled in build_info.h as long as the following symbols + # are not enabled. + scripts/config.py unset MBEDTLS_SSL_TLS_C + scripts/config.py unset MBEDTLS_SSL_PROTO_DTLS + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_2 + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # enable support for drivers and configuring PSA-only algorithms scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG @@ -2450,7 +2458,7 @@ config_psa_crypto_no_ecp_at_all () { # # Keep in sync with component_test_psa_crypto_config_reference_ecc_no_ecp_at_all() component_test_psa_crypto_config_accel_ecc_no_ecp_at_all () { - msg "build: crypto_full + accelerated EC algs + USE_PSA - ECP" + msg "build: full + accelerated EC algs + USE_PSA - TLS - KEY_EXCHANGE - ECP" # Algorithms and key types to accelerate loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \ @@ -2485,7 +2493,7 @@ component_test_psa_crypto_config_accel_ecc_no_ecp_at_all () { # Run the tests # ------------- - msg "test suites: crypto_full + accelerated EC algs + USE_PSA - ECP" + msg "test: full + accelerated EC algs + USE_PSA - TLS - KEY_EXCHANGE - ECP" make test } @@ -2493,13 +2501,13 @@ component_test_psa_crypto_config_accel_ecc_no_ecp_at_all () { # in conjunction with component_test_psa_crypto_config_accel_ecc_no_ecp_at_all(). # Keep in sync with its accelerated counterpart. component_test_psa_crypto_config_reference_ecc_no_ecp_at_all () { - msg "build: crypto_full + non accelerated EC algs + USE_PSA" + msg "build: full + non accelerated EC algs + USE_PSA - TLS - KEY_EXCHANGE" config_psa_crypto_no_ecp_at_all 0 make - msg "test suites: crypto_full + non accelerated EC algs + USE_PSA" + msg "test: crypto_full + non accelerated EC algs + USE_PSA - TLS - KEY_EXCHANGE" make test } From 8c3404f3e09a0ed277e9362fc5f45e14f884d4aa Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 26 Jun 2023 15:49:48 +0200 Subject: [PATCH 76/89] x509: update ECP_LIGHT dependencies to PK_HAVE_ECC_KEYS Signed-off-by: Valerio Setti --- library/x509_crt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/x509_crt.c b/library/x509_crt.c index 380b1fd0df..4508e50f54 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -106,7 +106,7 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512), 0xFFFFFFF, /* Any PK alg */ -#if defined(MBEDTLS_ECP_LIGHT) +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) /* Curves at or above 128-bit security level. Note that this selection * should be aligned with ssl_preset_default_curves in ssl_tls.c. */ MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) | @@ -116,9 +116,9 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP384R1) | MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP512R1) | 0, -#else /* MBEDTLS_ECP_LIGHT */ +#else /* MBEDTLS_PK_HAVE_ECC_KEYS */ 0, -#endif /* MBEDTLS_ECP_LIGHT */ +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 2048, }; @@ -157,13 +157,13 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = /* Only ECDSA */ MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY), -#if defined(MBEDTLS_ECP_LIGHT) +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) /* Only NIST P-256 and P-384 */ MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) | MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1), -#else /* MBEDTLS_ECP_LIGHT */ +#else /* MBEDTLS_PK_HAVE_ECC_KEYS */ 0, -#endif /* MBEDTLS_ECP_LIGHT */ +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 0, }; @@ -233,7 +233,7 @@ static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile, } #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_LIGHT) +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) if (pk_alg == MBEDTLS_PK_ECDSA || pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) { @@ -249,7 +249,7 @@ static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile, return -1; } -#endif /* MBEDTLS_ECP_LIGHT */ +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ return -1; } From 603271ce3dfe0b97053fa673efeff3a1c822c078 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 26 Jun 2023 16:02:47 +0200 Subject: [PATCH 77/89] test: solve disparities in driver coverage analysis for no_ecp_at_all() Signed-off-by: Valerio Setti --- tests/suites/test_suite_x509parse.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index edb782470e..1d6bc285f8 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -996,7 +996,7 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 x509_verify:"data_files/server5.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha256.pem":"globalhost":0:0:"":"verify_all" X509 CRT verification #93 (Suite B invalid, EC cert, RSA CA) -depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECP_LIGHT:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA1 +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA1 x509_verify:"data_files/server3.crt":"data_files/test-ca.crt":"data_files/crl.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_BAD_MD|MBEDTLS_X509_BADCERT_BAD_PK|MBEDTLS_X509_BADCERT_BAD_KEY|MBEDTLS_X509_BADCRL_BAD_MD|MBEDTLS_X509_BADCRL_BAD_PK:"suite_b":"NULL" X509 CRT verification #94 (Suite B invalid, RSA cert, EC CA) From 53a16b3fb510d4f7675c0a90197c952cb4c55e9a Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 26 Jun 2023 17:05:53 +0100 Subject: [PATCH 78/89] bignum_mod_raw: Updated documentation for mpi_mod_raw_mul Signed-off-by: Minos Galanakis --- library/bignum_mod_raw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c index d29896c414..8f7270a609 100644 --- a/library/bignum_mod_raw.c +++ b/library/bignum_mod_raw.c @@ -132,13 +132,13 @@ void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, { /* Standard (A * B) multiplication stored into pre-allocated T * buffer of fixed limb size of (2N + 1). - + * * The space may not not fully filled by when - * MBEDTLS_MPI_MOD_REP_OPT_RED is used, with most - * curves using (2N) limbs. + * MBEDTLS_MPI_MOD_REP_OPT_RED is used, where we only need + * (2N) or (2N-1) limbs (depending on limb size and curve). * * The 521-bit Weierstrass curve is the only - * that which requires a limb size of (2N + 1). */ + * that which requires a limb size of (2N). */ const size_t T_limbs = (N->bits == 521) ? BITS_TO_LIMBS(N->bits * 2) + 1 : BITS_TO_LIMBS(N->bits * 2); From 93baf390959d129f1a69561d37152d3298288235 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 26 Jun 2023 20:02:48 +0100 Subject: [PATCH 79/89] test_suite_ecp.data: Added test cases for modulo-1 in coordinate representation. Signed-off-by: Minos Galanakis --- tests/suites/test_suite_ecp.data | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 44eb9ba395..1560c54941 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -1101,6 +1101,10 @@ ecp_mul_inv #18 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP256R1) depends_on:MBEDTLS_ECP_DP_BP256R1_ENABLED ecp_mod_mul_inv:"8d9454c7494b6e08d068391c811cb23cbe9318246a6c021b0018745eb6918751":MBEDTLS_ECP_DP_BP256R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #18.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP256R1) +depends_on:MBEDTLS_ECP_DP_BP256R1_ENABLED +ecp_mod_mul_inv:"a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5376":MBEDTLS_ECP_DP_BP256R1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #19 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_BP256R1) depends_on:MBEDTLS_ECP_DP_BP256R1_ENABLED ecp_mod_mul_inv:"3aff86b1ee706d38e4995b76f6433d9173c5d3ec19b43ff0a3d53ac20965c911":MBEDTLS_ECP_DP_BP256R1:MBEDTLS_ECP_MOD_SCALAR @@ -1125,6 +1129,10 @@ ecp_mul_inv #24 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP384R1) depends_on:MBEDTLS_ECP_DP_BP384R1_ENABLED ecp_mod_mul_inv:"80acca473c3fcee61d13a0a766ed0dcd5f50277f576ff6f3461664d436e2054ad7ecc8b7c0a9424fbda1d431c540c05a":MBEDTLS_ECP_DP_BP384R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #24.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP384R1) +depends_on:MBEDTLS_ECP_DP_BP384R1_ENABLED +ecp_mod_mul_inv:"8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec52":MBEDTLS_ECP_DP_BP384R1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #25 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_BP384R1) depends_on:MBEDTLS_ECP_DP_BP384R1_ENABLED ecp_mod_mul_inv:"371851bd69a5a1734b195c6ad6b041f51d94718cb437ab4a0a14ee5fa5fccd29328f3e77bfa2e4c58195ccb55cdc6a4":MBEDTLS_ECP_DP_BP384R1:MBEDTLS_ECP_MOD_SCALAR @@ -1149,6 +1157,10 @@ ecp_mul_inv #30 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP512R1) depends_on:MBEDTLS_ECP_DP_BP512R1_ENABLED ecp_mod_mul_inv:"8be202ecb80ae3f6fe07a17b03c14997668b37d029d38943245c8a6cd1cbce3d57cfc673886a22db7ab8686570881a5dc1d9855aa6618c52df55a04510e00bba":MBEDTLS_ECP_DP_BP512R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #30.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP512R1) +depends_on:MBEDTLS_ECP_DP_BP512R1_ENABLED +ecp_mod_mul_inv:"aadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f2":MBEDTLS_ECP_DP_BP512R1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #31 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_BP512R1) depends_on:MBEDTLS_ECP_DP_BP512R1_ENABLED ecp_mod_mul_inv:"572a5522bc45566df4c7575b91fdbc74975fd59380339b5aa23cbce2204744793ca3255705f5d9ba48335f36baf462010680f1e35cca26468d7d8f4223988189":MBEDTLS_ECP_DP_BP512R1:MBEDTLS_ECP_MOD_SCALAR @@ -1247,6 +1259,10 @@ ecp_mul_inv #51 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192R1) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_mod_mul_inv:"c4fd9a06df9b4efa94531578af8b5886ec0ada82884199f7":MBEDTLS_ECP_DP_SECP192R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #51.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192R1) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +ecp_mod_mul_inv:"fffffffffffffffffffffffffffffffefffffffffffffffe":MBEDTLS_ECP_DP_SECP192R1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #52 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED ecp_mod_mul_inv:"0f9c4728bef9fba3e7d856a8e2ff62f20c2a57bf64f6d707f0829a8ff":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE @@ -1259,6 +1275,10 @@ ecp_mul_inv #54 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED ecp_mod_mul_inv:"00326258467dcbf4d1ab1665a4c5036cb35f4c9231199b58166b3966c6":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #54.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) +depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED +ecp_mod_mul_inv:"00ffffffffffffffffffffffffffffffff000000000000000000000000":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #55 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256R1) depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED ecp_mod_mul_inv:"c36eadeab80f149cd51a1ed6311270ae2e4acc6734e787135f499c3a97f1edc3":MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ECP_MOD_COORDINATE @@ -1271,6 +1291,10 @@ ecp_mul_inv #57 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256R1) depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED ecp_mod_mul_inv:"f1d356376f03b5dbf0fd08bde5c4293115f7c7911f7a3ec3f90557602eb20147":MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #57.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256R1) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_mod_mul_inv:"ffffffff00000001000000000000000000000000fffffffffffffffffffffffe":MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #58 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP384R1) depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED ecp_mod_mul_inv:"a3137cd9b0c9e75a871f92e3ab6b284069ee06cd9c0afb2368fd8d381afcfecc553cb6b3f29216038d268a8d8fcd00f7":MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_ECP_MOD_COORDINATE @@ -1283,6 +1307,10 @@ ecp_mul_inv #60 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP384R1) depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED ecp_mod_mul_inv:"491b1d169c9262fd737847c13bb7370d91825fe985cfa000d4b9bd3c22e7b63016122c53156fae4757943a819a1ced6d":MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #60.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP384R1) +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_mod_mul_inv:"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe":MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #61 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP521R1) depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED ecp_mod_mul_inv:"1477156c589f498b61beb35f57662410d8821f3a1ee4a5968a8009618dbe4afda408809822eb0e994fbf9da1659c1ea21b151db97cd1f1567fa4b9327967e0aa591":MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_ECP_MOD_COORDINATE @@ -1295,6 +1323,10 @@ ecp_mul_inv #63 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP521R1) depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED ecp_mod_mul_inv:"1e53d580521a1cff4cd72576c13fecb2cbcf39453f2b437f0c8dc78d7982a37749f099942ce693751ec43407c3acf46315132ea2a9ae5fa9253408da2375d2b58fc":MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #63.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP521R1) +depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED +ecp_mod_mul_inv:"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe":MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #64 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE25519) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED ecp_mod_mul_inv:"1000000000000000000000000000000014def9dea2079cd65812631a5cf5d3ed":MBEDTLS_ECP_DP_CURVE25519:MBEDTLS_ECP_MOD_COORDINATE @@ -1307,6 +1339,10 @@ ecp_mul_inv #66 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE25519) depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED ecp_mod_mul_inv:"468de1bfdbb20b67371bc5ad0f2bc3e70705b6d85c14ad75daafdbd1502cfd1":MBEDTLS_ECP_DP_CURVE25519:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #66.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE25519) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_mod_mul_inv:"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec":MBEDTLS_ECP_DP_CURVE25519:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #67 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192K1) depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED ecp_mod_mul_inv:"2228b202d612f2e66d8ca00b7e1c19a737ee7db2708d91cd":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_COORDINATE @@ -1319,6 +1355,10 @@ ecp_mul_inv #69 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192K1) depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED ecp_mod_mul_inv:"d2a10413f48d7bcc18a9b7c53c7914c5302c9c9e48b2eb62":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #69.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192K1) +depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED +ecp_mod_mul_inv:"fffffffffffffffffffffffffffffffffffffffeffffee36":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_COORDINATE + # For coordinate moduli of secp224K1 the values are selected as one for # modulus - 1, and four random values, generated with # random.getrandbits(224) % modulus with a seed(2, 2). @@ -1358,6 +1398,10 @@ ecp_mul_inv #78 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256K1) depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED ecp_mod_mul_inv:"f8d3f3c02fd712f711d8e30d0d4c142eb106e5f75c25f55b3f983bc5c83c568a":MBEDTLS_ECP_DP_SECP256K1:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #78.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256K1) +depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED +ecp_mod_mul_inv:"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e":MBEDTLS_ECP_DP_SECP256K1:MBEDTLS_ECP_MOD_COORDINATE + ecp_mul_inv #79 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE448) depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED ecp_mod_mul_inv:"0000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff11ca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_COORDINATE @@ -1370,6 +1414,10 @@ ecp_mul_inv #81 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE448) depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED ecp_mod_mul_inv:"0000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff01243a939d867d7e0a75a8568d4d66de88f3ecc1ad37f91a8f9d7d70":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_COORDINATE +ecp_mul_inv #81.1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE448) +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_mod_mul_inv:"000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffe":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_COORDINATE + # The following data was generated using python's standard random library, # initialised with seed(2,2) and random.getrandbits(curve bits). Curve bits are 192,256,384,520. # They must be less than the named curves' modulus. mbedtls_mpi_mod_residue_setup() From 9e868be13a04887b02c2b13fcaeb8d97a28abbd6 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 27 Jun 2023 09:27:27 +0100 Subject: [PATCH 80/89] Fix clang warning from -Wasm-operand-widths Signed-off-by: Dave Rodgman --- library/bn_mul.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/bn_mul.h b/library/bn_mul.h index 4ccd7b4b17..95265a4d06 100644 --- a/library/bn_mul.h +++ b/library/bn_mul.h @@ -256,15 +256,15 @@ do { uintptr_t muladdc_d = (uintptr_t) d, muladdc_s = (uintptr_t) s; asm( #define MULADDC_X1_CORE \ - "ldr x4, [%2], #8 \n\t" \ - "ldr x5, [%1] \n\t" \ + "ldr x4, [%x2], #8 \n\t" \ + "ldr x5, [%x1] \n\t" \ "mul x6, x4, %4 \n\t" \ "umulh x7, x4, %4 \n\t" \ "adds x5, x5, x6 \n\t" \ "adc x7, x7, xzr \n\t" \ "adds x5, x5, %0 \n\t" \ "adc %0, x7, xzr \n\t" \ - "str x5, [%1], #8 \n\t" + "str x5, [%x1], #8 \n\t" #define MULADDC_X1_STOP \ : "+r" (c), \ From 8c5fae2610fe10d687b6453de036478e906fefa4 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 27 Jun 2023 09:43:55 +0100 Subject: [PATCH 81/89] Add explanatory comment Signed-off-by: Dave Rodgman --- library/bn_mul.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/bn_mul.h b/library/bn_mul.h index 95265a4d06..43dd5c298f 100644 --- a/library/bn_mul.h +++ b/library/bn_mul.h @@ -252,6 +252,13 @@ // (including ILP32 __aarch64__ ABIs such as on watchOS, hence the 2^32 - 1) #if defined(__aarch64__) && (UINTPTR_MAX == 0xfffffffful || UINTPTR_MAX == 0xfffffffffffffffful) +/* + * There are some issues around different compilers requiring different constraint + * syntax for updating pointers from assembly code (see notes for + * MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT in common.h), especially on aarch64_32 (aka ILP32). + * + * For this reason we cast the pointers to/from uintptr_t here. + */ #define MULADDC_X1_INIT \ do { uintptr_t muladdc_d = (uintptr_t) d, muladdc_s = (uintptr_t) s; asm( From 5dbe17de36aea3646f9c0e5ce56aac3aa92dc41b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 27 Jun 2023 10:30:28 +0100 Subject: [PATCH 82/89] Add PSA_JPAKE_FINISHED to EXPECTED_{IN,OUT}PUTS() Signed-off-by: David Horstmann --- include/psa/crypto_extra.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index a7d98a084a..94def5c456 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -2024,8 +2024,10 @@ struct psa_jpake_computation_stage_s { psa_pake_step_t MBEDTLS_PRIVATE(step); }; -#define PSA_JPAKE_EXPECTED_INPUTS(round) (((round) == PSA_JPAKE_FIRST) ? 2 : 1) -#define PSA_JPAKE_EXPECTED_OUTPUTS(round) (((round) == PSA_JPAKE_FIRST) ? 2 : 1) +#define PSA_JPAKE_EXPECTED_INPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \ + ((round) == PSA_JPAKE_FIRST ? 2 : 1)) +#define PSA_JPAKE_EXPECTED_OUTPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \ + ((round) == PSA_JPAKE_FIRST ? 2 : 1)) struct psa_pake_operation_s { /** Unique ID indicating which driver got assigned to do the From 246ec5a35efcf42d8fec7861844d1c40d6c594f0 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 27 Jun 2023 10:33:06 +0100 Subject: [PATCH 83/89] Replace unnecessary '>=' with '==' Signed-off-by: David Horstmann --- library/psa_crypto.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0a549ef49d..fb20d09466 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8061,18 +8061,18 @@ static psa_status_t psa_jpake_epilogue( /* End of an input/output */ if (io_mode == PSA_JPAKE_INPUT) { stage->inputs++; - if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round)) { + if (stage->inputs == PSA_JPAKE_EXPECTED_INPUTS(stage->round)) { stage->io_mode = PSA_JPAKE_OUTPUT; } } if (io_mode == PSA_JPAKE_OUTPUT) { stage->outputs++; - if (stage->outputs >= PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { + if (stage->outputs == PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { stage->io_mode = PSA_JPAKE_INPUT; } } - if (stage->inputs >= PSA_JPAKE_EXPECTED_INPUTS(stage->round) && - stage->outputs >= PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { + if (stage->inputs == PSA_JPAKE_EXPECTED_INPUTS(stage->round) && + stage->outputs == PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { /* End of a round, move to the next round */ stage->inputs = 0; stage->outputs = 0; From c4e4958326b23f7603688a58719c87c6c8b3ea45 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 27 Jun 2023 14:03:35 +0100 Subject: [PATCH 84/89] ecp_curves: Adjusted expected_width inputs to use `BITS_TO_LIMBS` macro. Signed-off-by: Minos Galanakis --- library/bignum_mod_raw.c | 15 ++++----------- library/ecp_curves.c | 40 ++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c index 8f7270a609..bf72c18256 100644 --- a/library/bignum_mod_raw.c +++ b/library/bignum_mod_raw.c @@ -131,18 +131,11 @@ void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, mbedtls_mpi_uint *T) { /* Standard (A * B) multiplication stored into pre-allocated T - * buffer of fixed limb size of (2N + 1). + * buffer of fixed limb size of (2N + 1). * - * The space may not not fully filled by when - * MBEDTLS_MPI_MOD_REP_OPT_RED is used, where we only need - * (2N) or (2N-1) limbs (depending on limb size and curve). - * - * The 521-bit Weierstrass curve is the only - * that which requires a limb size of (2N). */ - const size_t T_limbs = (N->bits == 521) ? - BITS_TO_LIMBS(N->bits * 2) + 1 : - BITS_TO_LIMBS(N->bits * 2); - + * The space may not not fully filled by when + * MBEDTLS_MPI_MOD_REP_OPT_RED is used. */ + const size_t T_limbs = BITS_TO_LIMBS(N->bits) * 2; switch (N->int_rep) { case MBEDTLS_MPI_MOD_REP_MONTGOMERY: mbedtls_mpi_core_montmul(X, A, B, N->limbs, N->p, N->limbs, diff --git a/library/ecp_curves.c b/library/ecp_curves.c index e3bcc8715a..a4fa663a56 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -4922,7 +4922,7 @@ static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry) static int ecp_mod_p192(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * ((192 + biL - 1) / biL); + size_t expected_width = BITS_TO_LIMBS(192) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p192_raw(N->p, expected_width); @@ -4936,7 +4936,7 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn) mbedtls_mpi_uint c = 0, last_carry[WIDTH] = { 0 }; mbedtls_mpi_uint *p, *end; - if (Nn != 2*((192 + biL - 1)/biL)) { + if (Nn != BITS_TO_LIMBS(192) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -5082,7 +5082,7 @@ static inline int8_t extract_carry(int64_t cur) static int ecp_mod_p224(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * 224 / biL; + size_t expected_width = BITS_TO_LIMBS(224) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p224_raw(N->p, expected_width); cleanup: @@ -5092,7 +5092,7 @@ cleanup: MBEDTLS_STATIC_TESTABLE int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs) { - if (X_limbs != 2 * 224 / biL) { + if (X_limbs != BITS_TO_LIMBS(224) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -5135,7 +5135,7 @@ int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs) static int ecp_mod_p256(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * 256 / biL; + size_t expected_width = BITS_TO_LIMBS(256) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p256_raw(N->p, expected_width); cleanup: @@ -5145,7 +5145,7 @@ cleanup: MBEDTLS_STATIC_TESTABLE int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs) { - if (X_limbs != 2 * 256 / biL) { + if (X_limbs != BITS_TO_LIMBS(256) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -5215,7 +5215,7 @@ int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs) static int ecp_mod_p384(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * ((384 + biL - 1) / biL); + size_t expected_width = BITS_TO_LIMBS(384) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p384_raw(N->p, expected_width); cleanup: @@ -5225,7 +5225,7 @@ cleanup: MBEDTLS_STATIC_TESTABLE int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs) { - if (X_limbs != 2*((384 + biL - 1)/biL)) { + if (X_limbs != BITS_TO_LIMBS(384) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -5337,7 +5337,7 @@ int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs) static int ecp_mod_p521(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * P521_WIDTH; + size_t expected_width = BITS_TO_LIMBS(521) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p521_raw(N->p, expected_width); cleanup: @@ -5349,7 +5349,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) { mbedtls_mpi_uint carry = 0; - if (X_limbs != 2 * P521_WIDTH || X[2 * P521_WIDTH - 1] != 0) { + if (X_limbs != BITS_TO_LIMBS(521) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -5423,7 +5423,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) static int ecp_mod_p255(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * P255_WIDTH; + size_t expected_width = BITS_TO_LIMBS(255) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p255_raw(N->p, expected_width); cleanup: @@ -5434,7 +5434,7 @@ MBEDTLS_STATIC_TESTABLE int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) { - if (X_Limbs != 2 * P255_WIDTH) { + if (X_Limbs != BITS_TO_LIMBS(255) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -5492,7 +5492,7 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) static int ecp_mod_p448(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * ((448 + biL - 1) / biL); + size_t expected_width = BITS_TO_LIMBS(448) * 2; /* This is required as some tests and use cases do not pass in a Bignum of * the correct size, and expect the growth to be done automatically, which @@ -5522,7 +5522,7 @@ int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs) size_t round; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if (X_limbs <= P448_WIDTH) { + if (X_limbs != BITS_TO_LIMBS(448) * 2) { return 0; } @@ -5734,7 +5734,7 @@ cleanup: static int ecp_mod_p192k1(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * ((192 + biL - 1) / biL); + size_t expected_width = BITS_TO_LIMBS(192) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p192k1_raw(N->p, expected_width); @@ -5750,7 +5750,7 @@ int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) 0x01, 0x00, 0x00, 0x00) }; - if (X_limbs != 2 * ((192 + biL - 1) / biL)) { + if (X_limbs != BITS_TO_LIMBS(192) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -5768,7 +5768,7 @@ int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) static int ecp_mod_p224k1(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * 224 / biL; + size_t expected_width = BITS_TO_LIMBS(224) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p224k1_raw(N->p, expected_width); @@ -5784,7 +5784,7 @@ int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) 0x01, 0x00, 0x00, 0x00) }; - if (X_limbs != 2 * 224 / biL) { + if (X_limbs != BITS_TO_LIMBS(224) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } @@ -5802,7 +5802,7 @@ int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) static int ecp_mod_p256k1(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * ((256 + biL - 1) / biL); + size_t expected_width = BITS_TO_LIMBS(256) * 2; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p256k1_raw(N->p, expected_width); @@ -5818,7 +5818,7 @@ int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) 0x01, 0x00, 0x00, 0x00) }; - if (X_limbs != 2 * ((256 + biL - 1) / biL)) { + if (X_limbs != BITS_TO_LIMBS(256) * 2) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } From 28e2ca51a98fff27d33f76a7ca6bc2c3a10ee2bb Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 27 Jun 2023 15:25:38 +0100 Subject: [PATCH 85/89] Docs improvement Signed-off-by: Dave Rodgman --- library/common.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/library/common.h b/library/common.h index ba9cb75c08..ce81a14732 100644 --- a/library/common.h +++ b/library/common.h @@ -170,13 +170,20 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned /* *INDENT-ON* */ /* - * Define the constraint used for pointer operands to asm. + * Define the constraint used for read-only pointer operands to aarch64 asm. * * This is normally the usual "r", but for aarch64_32 (aka ILP32, * as found in watchos), "p" is required to avoid warnings from clang. * * Note that clang does not recognise '+p' or '=p', and armclang - * does not recognise 'p' at all. + * does not recognise 'p' at all. Therefore, to update a pointer from + * aarch64 assembly, it is necessary to use something like: + * + * uintptr_t uptr = (uintptr_t) ptr; + * asm( "ldr x4, [%x0], #8" ... : "+r" (uptr) : : ) + * ptr = (void*) uptr; + * + * Note that the "x" in "%x0" is neccessary; writing "%0" will cause warnings. */ #if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM) #if UINTPTR_MAX == 0xfffffffful From 23394b17bc750d64687e8e96960c802e759d428a Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 27 Jun 2023 16:31:59 +0100 Subject: [PATCH 86/89] test_suite_ecp: Updated ecp_mod_p_generic_raw to use the `BITS_TO_LIMBS` macro. Signed-off-by: Minos Galanakis --- tests/suites/test_suite_ecp.function | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 55ded45b4e..09349f44cc 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1296,70 +1296,70 @@ void ecp_mod_p_generic_raw(int curve_id, switch (curve_id) { #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP192R1: - limbs = 2 * limbs_N; + limbs = 2 * BITS_TO_LIMBS(192); curve_bits = 192; curve_func = &mbedtls_ecp_mod_p192_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP224R1: - limbs = 448 / biL; + limbs = 2 * BITS_TO_LIMBS(224); curve_bits = 224; curve_func = &mbedtls_ecp_mod_p224_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP256R1: - limbs = 2 * limbs_N; + limbs = 2 * BITS_TO_LIMBS(256); curve_bits = 256; curve_func = &mbedtls_ecp_mod_p256_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP384R1: - limbs = 2 * limbs_N; + limbs = 2 * BITS_TO_LIMBS(384); curve_bits = 384; curve_func = &mbedtls_ecp_mod_p384_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP521R1: - limbs = 2 * limbs_N; + limbs = 2 * BITS_TO_LIMBS(522); curve_bits = 522; curve_func = &mbedtls_ecp_mod_p521_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) case MBEDTLS_ECP_DP_SECP192K1: - limbs = 2 * limbs_N; + limbs = 2 * BITS_TO_LIMBS(192); curve_bits = 192; curve_func = &mbedtls_ecp_mod_p192k1_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) case MBEDTLS_ECP_DP_SECP224K1: - limbs = 448 / biL; + limbs = 2 * BITS_TO_LIMBS(224); curve_bits = 224; curve_func = &mbedtls_ecp_mod_p224k1_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) case MBEDTLS_ECP_DP_SECP256K1: - limbs = 2 * limbs_N; + limbs = 2 * BITS_TO_LIMBS(256); curve_bits = 256; curve_func = &mbedtls_ecp_mod_p256k1_raw; break; #endif #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) case MBEDTLS_ECP_DP_CURVE25519: - limbs = 2 * limbs_N; + limbs = 2 * BITS_TO_LIMBS(255); curve_bits = 255; curve_func = &mbedtls_ecp_mod_p255_raw; break; #endif #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) case MBEDTLS_ECP_DP_CURVE448: - limbs = 2 * limbs_N; + limbs = 2 * BITS_TO_LIMBS(448); curve_bits = 448; curve_func = &mbedtls_ecp_mod_p448_raw; break; From 80c4ae893cc0fb6beb88300ec1716d245d195fe4 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 27 Jun 2023 16:34:59 +0100 Subject: [PATCH 87/89] bignum_common.py: Added `bits_to_limbs` method. This patch introduces a rounding-error-resiliant method to calculate bits_to_limbs, and is updating `SECP224R1` and `SECP224K1` to use it. Signed-off-by: Minos Galanakis --- scripts/mbedtls_dev/bignum_common.py | 10 ++++++++-- scripts/mbedtls_dev/ecp.py | 6 ++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 51b25a3715..3bef16db68 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -19,6 +19,7 @@ import enum from typing import Iterator, List, Tuple, TypeVar, Any from copy import deepcopy from itertools import chain +from math import ceil from . import test_case from . import test_data_generation @@ -76,9 +77,14 @@ def combination_pairs(values: List[T]) -> List[Tuple[T, T]]: """Return all pair combinations from input values.""" return [(x, y) for x in values for y in values] +def bits_to_limbs(bits: int, bits_in_limb: int) -> int: + """ Return the appropriate ammount of limbs needed to store + a number contained in input bits""" + return ceil(bits / bits_in_limb) + def hex_digits_for_limb(limbs: int, bits_in_limb: int) -> int: - """ Retrun the hex digits need for a number of limbs. """ - return 2 * (limbs * bits_in_limb // 8) + """ Return the hex digits need for a number of limbs. """ + return 2 * ((limbs * bits_in_limb) // 8) def hex_digits_max_int(val: str, bits_in_limb: int) -> int: """ Return the first number exceeding maximum the limb space diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index 8a3ab281f0..ed79a073c4 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -165,7 +165,8 @@ class EcpP224R1Raw(bignum_common.ModOperationCommon, @property def arg_a(self) -> str: - hex_digits = bignum_common.hex_digits_for_limb(448 // self.bits_in_limb, self.bits_in_limb) + limbs = 2 * bignum_common.bits_to_limbs(224, self.bits_in_limb) + hex_digits = bignum_common.hex_digits_for_limb(limbs, self.bits_in_limb) return super().format_arg('{:x}'.format(self.int_a)).zfill(hex_digits) def result(self) -> List[str]: @@ -624,7 +625,8 @@ class EcpP224K1Raw(bignum_common.ModOperationCommon, @property def arg_a(self) -> str: - hex_digits = bignum_common.hex_digits_for_limb(448 // self.bits_in_limb, self.bits_in_limb) + limbs = 2 * bignum_common.bits_to_limbs(224, self.bits_in_limb) + hex_digits = bignum_common.hex_digits_for_limb(limbs, self.bits_in_limb) return super().format_arg('{:x}'.format(self.int_a)).zfill(hex_digits) def result(self) -> List[str]: From dae4c038f869c476017ac3c317ce6bd9dfffd764 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 27 Jun 2023 18:54:53 +0100 Subject: [PATCH 88/89] ecp.py: Extended EcpP224K1Raw tests for 32/64 bit architectures. Signed-off-by: Minos Galanakis --- scripts/mbedtls_dev/ecp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index ed79a073c4..410c77e115 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -574,7 +574,7 @@ class EcpP224K1Raw(bignum_common.ModOperationCommon, symbol = "-" test_function = "ecp_mod_p_generic_raw" test_name = "ecp_mod_p224k1_raw" - input_style = "fixed" + input_style = "arch_split" arity = 1 dependencies = ["MBEDTLS_ECP_DP_SECP224K1_ENABLED"] From 163d34635595fb0b89faa4afd519f6412f3629c5 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 27 Jun 2023 21:34:42 +0100 Subject: [PATCH 89/89] test_suite_ecp: Changed to BITS_TO_LIMBS(224) * 2 in `ecp_mod_p_generic_raw`. Signed-off-by: Minos Galanakis --- tests/suites/test_suite_ecp.function | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 09349f44cc..2658a432a5 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1296,70 +1296,70 @@ void ecp_mod_p_generic_raw(int curve_id, switch (curve_id) { #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP192R1: - limbs = 2 * BITS_TO_LIMBS(192); + limbs = BITS_TO_LIMBS(192) * 2; curve_bits = 192; curve_func = &mbedtls_ecp_mod_p192_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP224R1: - limbs = 2 * BITS_TO_LIMBS(224); + limbs = BITS_TO_LIMBS(224) * 2; curve_bits = 224; curve_func = &mbedtls_ecp_mod_p224_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP256R1: - limbs = 2 * BITS_TO_LIMBS(256); + limbs = BITS_TO_LIMBS(256) * 2; curve_bits = 256; curve_func = &mbedtls_ecp_mod_p256_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP384R1: - limbs = 2 * BITS_TO_LIMBS(384); + limbs = BITS_TO_LIMBS(384) * 2; curve_bits = 384; curve_func = &mbedtls_ecp_mod_p384_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM) case MBEDTLS_ECP_DP_SECP521R1: - limbs = 2 * BITS_TO_LIMBS(522); + limbs = BITS_TO_LIMBS(522) * 2; curve_bits = 522; curve_func = &mbedtls_ecp_mod_p521_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) case MBEDTLS_ECP_DP_SECP192K1: - limbs = 2 * BITS_TO_LIMBS(192); + limbs = BITS_TO_LIMBS(192) * 2; curve_bits = 192; curve_func = &mbedtls_ecp_mod_p192k1_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) case MBEDTLS_ECP_DP_SECP224K1: - limbs = 2 * BITS_TO_LIMBS(224); + limbs = BITS_TO_LIMBS(224) * 2; curve_bits = 224; curve_func = &mbedtls_ecp_mod_p224k1_raw; break; #endif #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) case MBEDTLS_ECP_DP_SECP256K1: - limbs = 2 * BITS_TO_LIMBS(256); + limbs = BITS_TO_LIMBS(256) * 2; curve_bits = 256; curve_func = &mbedtls_ecp_mod_p256k1_raw; break; #endif #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) case MBEDTLS_ECP_DP_CURVE25519: - limbs = 2 * BITS_TO_LIMBS(255); + limbs = BITS_TO_LIMBS(255) * 2; curve_bits = 255; curve_func = &mbedtls_ecp_mod_p255_raw; break; #endif #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) case MBEDTLS_ECP_DP_CURVE448: - limbs = 2 * BITS_TO_LIMBS(448); + limbs = BITS_TO_LIMBS(448) * 2; curve_bits = 448; curve_func = &mbedtls_ecp_mod_p448_raw; break;