Merge branch 'development' into sha3

This commit is contained in:
Pol Henarejos 2023-03-04 00:03:06 +01:00
commit f61d6c0a2b
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3
169 changed files with 13042 additions and 2729 deletions

View file

@ -52,8 +52,8 @@ jobs:
- programs/test/selftest
- tests/scripts/test_psa_constant_names.py
- tests/ssl-opt.sh
# Modern OpenSSL does not support fixed ECDH or null ciphers.
- tests/compat.sh -p OpenSSL -e 'NULL\|ECDH_'
# Modern OpenSSL does not support null ciphers.
- tests/compat.sh -p OpenSSL -e 'NULL'
- tests/scripts/travis-log-failure.sh
# GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
- tests/compat.sh -p GnuTLS -e 'CAMELLIA'
@ -80,6 +80,58 @@ jobs:
- sleep 5
- scripts/windows_msbuild.bat v141 # Visual Studio 2017
- name: full configuration on arm64
os: linux
dist: focal
arch: arm64
addons:
apt:
packages:
- gcc
script:
# Do a manual build+test sequence rather than using all.sh, because
# there's no all.sh component that does what we want. We should set
# CFLAGS for arm64 host CC.
- scripts/config.py full
- scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
- scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
- scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
- scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
- make generated_files
- make CFLAGS='-march=armv8-a+crypto -O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
- make test
- programs/test/selftest
- tests/scripts/test_psa_constant_names.py
# Modern OpenSSL does not support fixed ECDH or null ciphers.
- tests/compat.sh -p OpenSSL -e 'NULL\|ECDH_'
- tests/scripts/travis-log-failure.sh
- tests/context-info.sh
- name: full configuration(GnuTLS compat tests) on arm64
os: linux
dist: focal
arch: arm64
addons:
apt:
packages:
- clang
- gnutls-bin
script:
# Do a manual build+test sequence rather than using all.sh, because
# there's no all.sh component that does what we want. We should set
# CFLAGS for arm64 host CC.
- scripts/config.py full
- scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
- scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
- scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
- scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
- make generated_files
- make CC=clang CFLAGS='-march=armv8-a+crypto -O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
# GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
- tests/compat.sh -p GnuTLS -e 'CAMELLIA'
- tests/scripts/travis-log-failure.sh
- tests/context-info.sh
after_failure:
- tests/scripts/travis-log-failure.sh

View file

@ -14,8 +14,8 @@ More details on all of these points may be found in the sections below.
Coding Standards
----------------
- We would ask that contributions conform to [our coding standards](https://mbed-tls.readthedocs.io/en/latest/kb/development/mbedtls-coding-standards/), and that contributions are fully tested before submission, as mentioned in the [Tests](#tests) and [Continuous Integration](#continuous-integration-tests) sections.
- The code should be written in a clean and readable style.
- Contributions should include tests, as mentioned in the [Tests](#tests) and [Continuous Integration](#continuous-integration-tests) sections. Please check that your contribution passes basic tests before submission, and check the CI results after making a pull request.
- The code should be written in a clean and readable style, and must follow [our coding standards](https://mbed-tls.readthedocs.io/en/latest/kb/development/mbedtls-coding-standards/).
- The code should be written in a portable generic way, that will benefit the whole community, and not only your own needs.
- The code should be secure, and will be reviewed from a security point of view as well.

View file

@ -0,0 +1,3 @@
Features
* Add parsing of uniformResourceIdentifier subtype for subjectAltName
extension in x509 certificates.

View file

@ -0,0 +1,5 @@
Features
* Add an interruptible version of sign and verify hash to the PSA interface,
backed by internal library support for ECDSA signing and verification.

View file

@ -0,0 +1,5 @@
Changes
* The C code follows a new coding style. This is transparent for users but
affects contributors and maintainers of local patches. For more
information, see
https://mbed-tls.readthedocs.io/en/latest/kb/how-to/rewrite-branch-for-coding-style/

View file

@ -0,0 +1,3 @@
Bugfix
* Silence warnings from clang -Wdocumentation about empty \retval
descriptions, which started appearing with Clang 15. Fixes #6960.

View file

@ -1,2 +1,2 @@
Bugfix
* Fix IAR compiler warnings. Contributed by Glenn Strauss in #3835.
* Fix IAR compiler warnings. Fixes #6924.

View file

@ -0,0 +1,6 @@
Bugfix
* Fix bug in conversion from OID to string in
mbedtls_oid_get_numeric_string(). OIDs such as 2.40.0.25 are now printed
correctly.
* Reject OIDs with overlong-encoded subidentifiers when converting
OID-to-string.

View file

@ -0,0 +1,7 @@
Changes
* Changed the default MBEDTLS_ECP_WINDOW_SIZE from 6 to 2.
As tested in issue 6790, the correlation between this define and
RSA decryption performance has changed lately due to security fixes.
To fix the performance degradation when using default values the
window was reduced from 6 to 2, a value that gives the best or close
to best results when tested on Cortex-M4 and Intel i7.

View file

@ -0,0 +1,4 @@
Bugfix
* Make the fields of mbedtls_pk_rsassa_pss_options public. This makes it
possible to verify RSA PSS signatures with the pk module, which was
inadvertently broken since Mbed TLS 3.0.

View file

@ -0,0 +1,4 @@
Features
* The configuration macros MBEDTLS_PSA_CRYPTO_PLATFORM_FILE and
MBEDTLS_PSA_CRYPTO_STRUCT_FILE specify alternative locations for
the headers "psa/crypto_platform.h" and "psa/crypto_struct.h".

View file

@ -0,0 +1,3 @@
Features
* Add parsing of rfc822Name subtype for subjectAltName
extension in x509 certificates.

View file

@ -0,0 +1,5 @@
Bugfix
* Fix the handling of renegotiation attempts in TLS 1.3. They are now
systematically rejected.
* Fix an unused-variable warning in TLS 1.3-only builds if
MBEDTLS_SSL_RENEGOTIATION was enabled. Fixes #6200.

View file

@ -0,0 +1,5 @@
Bugfix
* Fix parsing of X.509 SubjectAlternativeName extension. Previously,
malformed alternative name components were not caught during initial
certificate parsing, but only on subsequent calls to
mbedtls_x509_parse_subject_alt_name(). Fixes #2838.

View file

@ -264,6 +264,7 @@ Mbed TLS is mostly written in portable C99; however, it has a few platform requi
- `int` and `size_t` must be at least 32 bits wide.
- The types `uint8_t`, `uint16_t`, `uint32_t` and their signed equivalents must be available.
- Mixed-endian platforms are not supported.
- SIZE_MAX must be at least as big as INT_MAX and UINT_MAX.
PSA cryptography API
--------------------

View file

@ -0,0 +1,481 @@
PSA migration strategy for hashes and ciphers
=============================================
## Introduction
This document discusses a migration strategy for code that is not subject to `MBEDTLS_USE_PSA_CRYPTO`, is currently using legacy cryptography APIs, and should transition to PSA, without a major version change.
### Relationship with the main strategy document
This is complementary to the main [strategy document](strategy.html) and is intended as a refinement. However, at this stage, there may be contradictions between the strategy proposed here and some of the earlier strategy.
A difference between the original strategy and the current one is that in this work, we are not treating PSA as a black box. We can change experimental features, and we can call internal interfaces.
## Requirements
### User stories
#### Backward compatibility user story
As a developer of an application that uses Mbed TLS's interfaces (including legacy crypto),
I want Mbed TLS to preserve backward compatibility,
so that my code keeps working in new minor versions of Mbed TLS.
#### Interface design user story
As a developer of library code that uses Mbed TLS to perform cryptographic operations,
I want to know which functions to call and which feature macros to check,
so that my code works in all Mbed TLS configurations.
Note: this is the same problem we face in X.509 and TLS.
#### Hardware accelerator vendor user stories
As a vendor of a platform with hardware acceleration for some crypto,
I want to build Mbed TLS in a way that uses my hardware wherever relevant,
so that my customers maximally benefit from my hardware.
As a vendor of a platform with hardware acceleration for some crypto,
I want to build Mbed TLS without software that replicates what my hardware does,
to minimize the code size.
#### Maintainer user stories
As a maintainer of Mbed TLS,
I want to have clear rules for when to use which interface,
to avoid bugs in “unusual” configurations.
As a maintainer of Mbed TLS,
I want to avoid duplicating code,
because this is inefficient and error-prone.
### Use PSA more
In the long term, all code using cryptography should use PSA interfaces, to benefit from PSA drivers, allow eliminating legacy interfaces (less code size, less maintenance). However, this can't be done without breaking [backward compatibility](#backward-compatibility).
The goal of this work is to arrange for more non-PSA interfaces to use PSA interfaces under the hood, without breaking code in the cases where this doesn't work. Using PSA interfaces has two benefits:
* Where a PSA driver is available, it likely has better performance, and sometimes better security, than the built-in software implementation.
* In many scenarios, where a PSA driver is available, this allows removing the software implementation altogether.
* We may be able to get rid of some redundancies, for example the duplication between the implementations of HMAC in `md.c` and in `psa_crypto_mac.c`, and HKDF in `hkdf.c` and `psa_crypto.c`.
### Correct dependencies
Traditionally, to determine whether a cryptographic mechanism was available, you had to check whether the corresponding Mbed TLS module or submodule was present: `MBEDTLS_SHA256_C` for SHA256, `MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC` for AES-CBC, etc. In code that uses the PSA interfaces, this needs to change to `PSA_WANT_xxx` symbols.
### Backward compatibility
All documented behavior must be preserved, except for interfaces currently described as experimental or unstable. Those interfaces can change, but we should minimize disruption by providing a transition path for reasonable use cases.
#### Changeable configuration options
The following configuration options are described as experimental, and are likely to change at least marginally:
* `MBEDTLS_PSA_CRYPTO_CLIENT`: “This interface is experimental and may change or be removed without notice.” In practice we don't want to remove this, but we may constrain how it's used.
* `MBEDTLS_PSA_CRYPTO_DRIVERS`: “This interface is experimental. We intend to maintain backward compatibility with application code that relies on drivers, but the driver interfaces may change without notice.” In practice, this may mean constraints not only on how to write drivers, but also on how to integrate drivers into code that is platform code more than application code.
* `MBEDTLS_PSA_CRYPTO_CONFIG`: “This feature is still experimental and is not ready for production since it is not completed.” We may want to change this, for example, to automatically enable more mechanisms (although this wouldn't be considered a backward compatibility break anyway, since we don't promise that you will not get a feature if you don't enable its `PSA_WANT_xxx`).
### Non-goals
It is not a goal at this stage to make more code directly call `psa_xxx` functions. Rather, the goal is to make more code call PSA drivers where available. How dispatch is done is secondary.
## Problem analysis
### Scope analysis
#### Limitations of `MBEDTLS_USE_PSA_CRYPTO`
The option `MBEDTLS_USE_PSA_CRYPTO` causes parts of the library to call the PSA API instead of legacy APIs for cryptographic calculations. `MBEDTLS_USE_PSA_CRYPTO` only applies to `pk.h`, X.509 and TLS. When this option is enabled, applications must call `psa_crypto_init()` before calling any of the functions in these modules.
In this work, we want two things:
* Make non-covered modules call PSA, but only [when this will actually work](#why-psa-is-not-always-possible). This effectively brings those modules to a partial use-PSA behavior (benefiting from PSA accelerators when they're usable) regardless of whether the option is enabled.
* Call PSA when a covered module calls a non-covered module which calls another module, for example X.509 calling pk for PSS verification which calls RSA which calculates a hash ([see issue \#6497](https://github.com/Mbed-TLS/mbedtls/issues/6497)). This effectively extends the option to modules that aren't directly covered.
#### Classification of callers
We can classify code that implements or uses cryptographic mechanisms into several groups:
* Software implementations of primitive cryptographic mechanisms. These are not expected to change.
* Software implementations of constructed cryptographic mechanisms (e.g. HMAC, CTR_DRBG, RSA (calling a hash for PSS/OAEP, and needing to know the hash length in PKCS1v1.5 sign/verify), …). These need to keep working whenever a legacy implementation of the auxiliary mechanism is available, regardless of whether a PSA implementation is also available.
* Code implementing the PSA crypto interface. This is not expected to change, except perhaps to expose some internal functionality to overhauled glue code.
* Code that's subject to `MBEDTLS_USE_PSA_CRYPTO`: `pk.h`, X.509, TLS (excluding TLS 1.3).
* Code that always uses PSA for crypto: TLS 1.3, LMS.
For the purposes of this work, three domains emerge:
* **Legacy domain**: does not interact with PSA. Implementations of hashes, of cipher primitives, of arithmetic.
* **Mixed domain**: does not currently use PSA, but should [when possible](#why-psa-is-not-always-possible). This consists of the constructed cryptographic primitives (except LMS), as well as pk, X.509 and TLS when `MBEDTLS_USE_PSA_CRYPTO` is disabled.
* **PSA domain**: includes pk, X.509 and TLS when `MBEDTLS_USE_PSA_CRYPTO` is enabled. Also TLS 1.3, LMS.
#### Non-use-PSA modules
The following modules in Mbed TLS call another module to perform cryptographic operations which, in the long term, will be provided through a PSA interface, but cannot make any PSA-related assumption:
* CCM (block cipher in ECB mode; interdependent with cipher)
* cipher (cipher and AEAD algorithms)
* CMAC (AES-ECB and DES-ECB, but could be extended to the other block ciphers; interdependent with cipher)
* CTR\_DRBG (AES-ECB, but could be extended to the other block ciphers)
* entropy (hashes via low-level)
* ECDSA (HMAC\_DRBG; `md.h` exposed through API)
* ECJPAKE (hashes via md; `md.h` exposed through API)
* GCM (block cipher in ECB mode; interdependent with cipher)
* md (hashes and HMAC)
* NIST\_KW (AES-ECB; interdependent with cipher)
* HMAC\_DRBG (hashes and HMAC via `md.h`; `md.h` exposed through API)
* PEM (AES and DES in CBC mode without padding; MD5 hash via low-level)
* PKCS12 (cipher, generically, selected from ASN.1 or function parameters; hashes via md; `cipher.h` exposed through API)
* PKCS5 (cipher, generically, selected from ASN.1; HMAC via `md.h`; `md.h` exposed through API)
* RSA (hash via md for PSS and OAEP; `md.h` exposed through API)
### Difficulties
#### Why PSA is not always possible
Here are some reasons why calling `psa_xxx()` to perform a hash or cipher calculation might not be desirable in some circumstances, explaining why the application would arrange to call the legacy software implementation instead.
* `MBEDTLS_PSA_CRYPTO_C` is disabled.
* There is a PSA driver which has not been initialized (this happens in `psa_crypto_init()`).
* For ciphers, the keystore is not initialized yet, and Mbed TLS uses a custom implementation of PSA ITS where the file system is not accessible yet (because something else needs to happen first, and the application takes care that it happens before it calls `psa_crypto_init()`). A possible workaround may be to dispatch to the internal functions that are called after the keystore lookup, rather than to the PSA API functions (but this is incompatible with `MBEDTLS_PSA_CRYPTO_CLIENT`).
* The requested mechanism is enabled in the legacy interface but not in the PSA interface. This was not really intended, but is possible, for example, if you enable `MBEDTLS_MD5_C` for PEM decoding with PBKDF1 but don't want `PSA_ALG_WANT_MD5` because it isn't supported for `PSA_ALG_RSA_PSS` and `PSA_ALG_DETERMINISTIC_ECDSA`.
* `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, and the client has not yet activated the connection to the server (this happens in `psa_crypto_init()`).
* `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, but the operation is part of the implementation of an encrypted communication with the crypto service, or the local implementation is faster because it avoids a costly remote procedure call.
#### Indirect knowledge
Consider for example the code in `rsa.c` to perform an RSA-PSS signature. It needs to calculate a hash. If `mbedtls_rsa_rsassa_pss_sign()` is called directly by application code, it is supposed to call the built-in implementation: calling a PSA accelerator would be a behavior change, acceptable only if this does not add a risk of failure or performance degradation ([PSA is impossible or undesirable in some circumstances](#why-psa-is-not-always-possible)). Note that this holds regardless of the state of `MBEDTLS_USE_PSA_CRYPTO`, since `rsa.h` is outside the scope of `MBEDTLS_USE_PSA_CRYPTO`. On the other hand, if `mbedtls_rsa_rsassa_pss_sign()` is called from X.509 code, it should use PSA to calculate hashes. It doesn't, currently, which is [bug \#6497](https://github.com/Mbed-TLS/mbedtls/issues/6497).
Generally speaking, modules in the mixed domain:
* must call PSA if called by a module in the PSA domain;
* must not call PSA (or must have a fallback) if their caller is not in the PSA domain and the PSA call is not guaranteed to work.
#### Non-support guarantees: requirements
Generally speaking, just because some feature is not enabled in `mbedtls_config.h` or `psa_config.h` doesn't guarantee that it won't be enabled in the build. We can enable additional features through `build_info.h`.
If `PSA_WANT_xxx` is disabled, this should guarantee that attempting xxx through the PSA API will fail. This is generally guaranteed by the test suite `test_suite_psa_crypto_not_supported` with automatically enumerated test cases, so it would be inconvenient to carve out an exception.
### Technical requirements
Based on the preceding analysis, the core of the problem is: for code in the mixed domain (see [“Classification of callers”](#classification-of-callers)), how do we handle a cryptographic mechanism? This has several related subproblems:
* How the mechanism is encoded (e.g. `mbedtls_md_type_t` vs `const *mbedtls_md_info_t` vs `psa_algorithm_t` for hashes).
* How to decide whether a specific algorithm or key type is supported (eventually based on `MBEDTLS_xxx_C` vs `PSA_WANT_xxx`).
* How to obtain metadata about algorithms (e.g. hash/MAC/tag size, key size).
* How to perform the operation (context type, which functions to call).
We need a way to decide this based on the available information:
* Who's the ultimate caller — see [indirect knowledge](#indirect-knowledge) — which is not actually available.
* Some parameter indicating which algorithm to use.
* The available cryptographic implementations, based on preprocessor symbols (`MBEDTLS_xxx_C`, `PSA_WANT_xxx`, `MBEDTLS_PSA_ACCEL_xxx`, etc.).
* Possibly additional runtime state (for example, we might check whether `psa_crypto_init` has been called).
And we need to take care of the [the cases where PSA is not possible](#why-psa-is-not-always-possible): either make sure the current behavior is preserved, or (where allowed by backward compatibility) document a behavior change and, preferably, a workaround.
### Working through an example: RSA-PSS
Let us work through the example of RSA-PSS which calculates a hash, as in [see issue \#6497](https://github.com/Mbed-TLS/mbedtls/issues/6497).
RSA is in the [mixed domain](#classification-of-callers). So:
* When called from `psa_sign_hash` and other PSA functions, it must call the PSA hash accelerator if there is one.
* When called from user code, it must call the built-in hash implementation if PSA is not available (regardless of whether this is because `MBEDTLS_PSA_CRYPTO_C` is disabled, or because `PSA_WANT_ALG_xxx` is disabled for this hash, or because there is an accelerator driver which has not been initialized yet).
RSA knows which hash algorithm to use based on a parameter of type `mbedtls_md_type_t`. (More generally, all mixed-domain modules that take an algorithm specification as a parameter take it via a numerical type, except HMAC\_DRBG and HKDF which take a `const mbedtls_md_info_t*` instead, and CMAC which takes a `const mbedtls_cipher_info_t *`.)
#### Double encoding solution
A natural solution is to double up the encoding of hashes in `mbedtls_md_type_t`. Pass `MBEDTLS_MD_SHA256` and `md` will dispatch to the legacy code, pass a new constant `MBEDTLS_MD_SHA256_USE_PSA` and `md` will dispatch through PSA.
This maximally preserves backward compatibility, but then no non-PSA code benefits from PSA accelerators, and there's little potential for removing the software implementation.
#### Availability of hashes in RSA-PSS
Here we try to answer the question: As a caller of RSA-PSS via `rsa.h`, how do I know whether it can use a certain hash?
* For a caller in the legacy domain: if e.g. `MBEDTLS_SHA256_C` is enabled, then I want RSA-PSS to support SHA-256. I don't care about negative support. So `MBEDTLS_SHA256_C` must imply support for RSA-PSS-SHA-256. It must work at all times, regardless of the state of PSA (e.g. drivers not initialized).
* For a caller in the PSA domain: if e.g. `PSA_WANT_ALG_SHA_256` is enabled, then I want RSA-PSS to support SHA-256, provided that `psa_crypto_init()` has been called. In some limited cases, such as `test_suite_psa_crypto_not_supported` when PSA implements RSA-PSS in software, we care about negative support: if `PSA_WANT_ALG_SHA_256` is disabled then `psa_verify_hash` must reject `PSA_WANT_ALG_SHA_256`. This can be done at the level of PSA before it calls the RSA module, though, so it doesn't have any implication on the RSA module. As far as `rsa.c` is concerned, what matters is that `PSA_WANT_ALG_SHA_256` implies that SHA-256 is supported after `psa_crypto_init()` has been called.
* For a caller in the mixed domain: requirements depend on the caller. Whatever solution RSA has to determine the availability of algorithms will apply to its caller as well.
Conclusion so far: RSA must be able to do SHA-256 if either `MBEDTLS_SHA256_C` or `PSA_WANT_ALG_SHA_256` is enabled. If only `PSA_WANT_ALG_SHA_256` and not `MBEDTLS_SHA256_C` is enabled (which implies that PSA's SHA-256 comes from an accelerator driver), then SHA-256 only needs to work if `psa_crypto_init()` has been called.
#### More in-depth discussion of compile-time availability determination
The following combinations of compile-time support are possible:
* `MBEDTLS_PSA_CRYPTO_CLIENT`. Then calling PSA may or may not be desirable for performance. There are plausible use cases where only the server has access to an accelerator so it's best to call the server, and plausible use cases where calling the server has overhead that negates the savings from using acceleration, if there are savings at all. In any case, calling PSA only works if the connection to the server has been established, meaning `psa_crypto_init` has been called successfully. In the rest of this case enumeration, assume `MBEDTLS_PSA_CRYPTO_CLIENT` is disabled.
* No PSA accelerator. Then just call `mbedtls_sha256`, it's all there is, and it doesn't matter (from an API perspective) exactly what call chain leads to it.
* PSA accelerator, no software implementation. Then we might as well call the accelerator, unless it's important that the call fails. At the time of writing, I can't think of a case where we would want to guarantee that if `MBEDTLS_xxx_C` is not enabled, but xxx is enabled through PSA, then a request to use algorithm xxx through some legacy interface must fail.
* Both PSA acceleration and the built-in implementation. In this case, we would prefer PSA for the acceleration, but we can only do this if the accelerator driver is working. For hashes, it's enough to assume the driver is initialized; we've [considered requiring hash drivers to work without initialization](https://github.com/Mbed-TLS/mbedtls/pull/6470). For ciphers, this is more complicated because the cipher functions require the keystore, and plausibly a cipher accelerator might want entropy (for side channel countermeasures) which might not be available at boot time.
Note that it's a bit tricky to determine which algorithms are available. In the case where there is a PSA accelerator but no software implementation, we don't want the preprocessor symbols to indicate that the algorithm is available through the legacy domain, only through the PSA domain. What does this mean for the interfaces in the mixed domain? They can't guarantee the availability of the algorithm, but they must try if requested.
### Designing an interface for hashes
In this section, we specify a hash metadata and calculation for the [mixed domain](#classification-of-callers), i.e. code that can be called both from legacy code and from PSA code.
#### Availability of hashes
Generalizing the analysis in [“Availability of hashes in RSA-PSS”](#availability-of-hashes-in-RSA-PSS):
A hash is available through the mixed-domain interface iff either of the following conditions is true:
* A legacy hash interface is available and the hash algorithm is implemented in software.
* PSA crypto is enabled and the hash algorithm is implemented via PSA.
We could go further and make PSA accelerators available to legacy callers that call any legacy hash interface, e.g. `md.h` or `shaX.h`. There is little point in doing this, however: callers should just use the mixed-domain interface.
#### Implications between legacy availability and PSA availability
* When `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled, all legacy mechanisms are automatically enabled through PSA. Users can manually enable PSA mechanisms that are available through accelerators but not through legacy, but this is not officially supported (users are not supposed to manually define PSA configuration symbols when `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled).
* When `MBEDTLS_PSA_CRYPTO_CONFIG` is enabled, there is no mandatory relationship between PSA support and legacy support for a mechanism. Users can configure legacy support and PSA support independently. Legacy support is automatically enabled if PSA support is requested, but only if there is no accelerator.
It is strongly desirable to allow mechanisms available through PSA but not legacy: this allows saving code size when an accelerator is present.
There is no strong reason to allow mechanisms available through legacy but not PSA when `MBEDTLS_PSA_CRYPTO_C` is enabled. This would only save at best a very small amount of code size in the PSA dispatch code. This may be more desirable when `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled (having a mechanism available only locally and not in the crypto service), but we do not have an explicit request for this and it would be entirely reasonable to forbid it.
In this analysis, we have not found a compelling reason to require all legacy mechanisms to also be available through PSA. However, this can simplify both the implementation and the use of dispatch code thanks to some simplifying properties:
* Mixed-domain code can call PSA code if it knows that `psa_crypto_init()` has been called, without having to inspect the specifics of algorithm support.
* Mixed-domain code can assume that PSA buffer calculations work correctly for all algorithms that it supports.
#### Shape of the mixed-domain hash interface
We now need to create an abstraction for mixed-domain hash calculation. (We could not create an abstraction, but that would require every piece of mixed-domain code to replicate the logic here. We went that route in Mbed TLS 3.3, but it made it effectively impossible to get something that works correctly.)
Requirements: given a hash algorithm,
* Obtain some metadata about it (size, block size).
* Calculate the hash.
* Set up a multipart operation to calculate the hash. The operation must support update, finish, reset, abort, clone.
The existing interface in `md.h` is close to what we want, but not perfect. What's wrong with it?
* It has an extra step of converting from `mbedtls_md_type_t` to `const mbedtls_md_info_t *`.
* It includes extra fluff such as names and HMAC. This costs code size.
* The md module has some legacy baggage dating from when it was more open, which we don't care about anymore. This may cost code size.
These problems are easily solvable.
* `mbedtls_md_info_t` can become a very thin type. We can't remove the extra function call from the source code of callers, but we can make it a very thin abstraction that compilers can often optimize.
* We can make names and HMAC optional. The mixed-domain hash interface won't be the full `MBEDTLS_MD_C` but a subset.
* We can optimize `md.c` without making API changes to `md.h`.
## Specification
### MD light
https://github.com/Mbed-TLS/mbedtls/pull/6474 implements part of this specification, but it's based on Mbed TLS 3.2, so it needs to be rewritten for 3.3.
#### Definition of MD light
MD light is a subset of `md.h` that implements the hash calculation interface described in ”[Designing an interface for hashes](#designing-an-interface-for-hashes)”. It is activated by `MBEDTLS_MD_LIGHT` in `mbedtls_config.h`.
The following things enable MD light automatically in `build_info.h`:
* A [mixed-domain](#classification-of-callers) module that needs to calculate hashes is enabled.
* `MBEDTLS_MD_C` is enabled.
MD light includes the following types:
* `mbedtls_md_type_t`
* `mbedtls_md_info_t`
* `mbedtls_md_context_t`
MD light includes the following functions:
* `mbedtls_md_info_from_type`
* `mbedtls_md_init`
* `mbedtls_md_free`
* `mbedtls_md_setup` — but `hmac` must be 0 if `MBEDTLS_MD_C` is disabled.
* `mbedtls_md_clone`
* `mbedtls_md_get_size`
* `mbedtls_md_get_type`
* `mbedtls_md_starts`
* `mbedtls_md_update`
* `mbedtls_md_finish`
* `mbedtls_md`
Unlike the full MD, MD light does not support null pointers as `mbedtls_md_context_t *`. At least some functions still need to support null pointers as `const mbedtls_md_info_t *` because this arises when you try to use an unsupported algorithm (`mbedtls_md_info_from_type` returns `NULL`).
#### MD algorithm support macros
For each hash algorithm, `md.h` defines a macro `MBEDTLS_MD_CAN_xxx` whenever the corresponding hash is available through MD light. These macros are only defined when `MBEDTLS_MD_LIGHT` is enabled. Per “[Availability of hashes](#availability-of-hashes)”, `MBEDTLS_MD_CAN_xxx` is enabled if:
* the corresponding `MBEDTLS_xxx_C` is defined; or
* one of `MBEDTLS_PSA_CRYPTO_C` or `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, and the corresponding `PSA_WANT_ALG_xxx` is enabled.
Note that some algorithms have different spellings in legacy and PSA. Since MD is a legacy interface, we'll use the legacy names. Thus, for example:
```
#if defined(MBEDTLS_MD_LIGHT)
#if defined(MBEDTLS_SHA256_C) || \
((defined(MBEDTLS_PSA_CRYPTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)) && \
PSA_WANT_ALG_SHA_256)
#define MBEDTLS_MD_CAN_SHA256
#endif
#endif
```
#### MD light internal support macros
* If at least one hash has a PSA driver, define `MBEDTLS_MD_SOME_PSA`.
* If at least one hash has a legacy implementation, defined `MBEDTLS_MD_SOME_LEGACY`.
#### Support for PSA in the MD context
An MD context needs to contain either a legacy module's context (or a pointer to one, as is the case now), or a PSA context (or a pointer to one).
I am inclined to remove the pointer indirection, but this means that an MD context would always be as large as the largest supported hash context. So for the time being, this specification keeps a pointer. For uniformity, PSA will also have a pointer (we may simplify this later).
```
enum {
MBEDTLS_MD_ENGINE_LEGACY,
MBEDTLS_MD_ENGINE_PSA,
} mbedtls_md_engine_t; // private type
typedef struct mbedtls_md_context_t {
const mbedtls_md_type_t type;
const mbedtls_md_engine_t engine;
union {
#if defined(MBEDTLS_MD_SOME_LEGACY)
void *legacy; // used if engine == LEGACY
#endif
#if defined(MBEDTLS_MD_SOME_PSA)
psa_hash_operation_t *psa; // used if engine == PSA
#endif
} digest;
#if defined(MBEDTLS_MD_C)
void *hmac_ctx;
#endif
} mbedtls_md_context_t;
```
All fields are private.
The `engine` field is almost redundant with knowledge about `type`. However, when an algorithm is available both via a legacy module and a PSA accelerator, we will choose based on the runtime availability of the accelerator when the context is set up. This choice needs to be recorded in the context structure.
#### Inclusion of MD info structures
MD light needs to support hashes that are only enabled through PSA. Therefore the `mbedtls_md_info_t` structures must be included based on `MBEDTLS_MD_CAN_xxx` instead of just the legacy module.
The same criterion applies in `mbedtls_md_info_from_type`.
#### Conversion to PSA encoding
The implementation needs to convert from a legacy type encoding to a PSA encoding.
```
static inline psa_algorithm_t psa_alg_of_md_info(
const mbedtls_md_info_t *md_info );
```
#### Determination of PSA support at runtime
```
int psa_can_do_hash(psa_algorithm_t hash_alg);
```
The job of this private function is to return 1 if `hash_alg` can be performed through PSA now, and 0 otherwise. It is only defined on algorithms that are enabled via PSA.
As a starting point, return 1 if PSA crypto has been initialized. This will be refined later (to return 1 if the [accelerator subsystem](https://github.com/Mbed-TLS/mbedtls/issues/6007) has been initialized).
Usage note: for algorithms that are not enabled via PSA, calling `psa_can_do_hash` is generally safe: whether it returns 0 or 1, you can call a PSA hash function on the algorithm and it will return `PSA_ERROR_NOT_SUPPORTED`.
#### Support for PSA dispatch in hash operations
Each function that performs some hash operation or context management needs to know whether to dispatch via PSA or legacy.
If given an established context, use its `engine` field.
If given an algorithm as an `mbedtls_md_type_t type` (possibly being the `type` field of a `const mbedtls_md_info_t *`):
* If there is a PSA accelerator for this hash and `psa_can_do_hash(alg)`, call the corresponding PSA function, and if applicable set the engine to `MBEDTLS_MD_ENGINE_PSA`. (Skip this is `MBEDTLS_MD_SOME_PSA` is not defined.)
* Otherwise dispatch to the legacy module based on the type as currently done. (Skip this is `MBEDTLS_MD_SOME_LEGACY` is not defined.)
* If no dispatch is possible, return `MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE`.
Note that this assumes that an operation that has been started via PSA can be completed. This implies that `mbedtls_psa_crypto_free` must not be called while an operation using PSA is in progress. Document this.
#### Error code conversion
After calling a PSA function, call `mbedtls_md_error_from_psa` to convert its status code. This function is currently defined in `hash_info.c`.
### Migration to MD light
#### Migration of modules that used to call MD and now do the legacy-or-PSA dance
Get rid of the case where `MBEDTLS_MD_C` is undefined. Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
#### Migration of modules that used to call a low-level hash module and now do the legacy-or-PSA dance
Switch to calling MD (light) unconditionally. Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
#### Migration of modules that call a low-level hash module
Switch to calling MD (light). Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
#### Migration of use-PSA mixed code
Instead of calling `hash_info.h` functions to obtain metadata, get it from `md.h`.
Optionally, code that currently tests on `MBEDTLS_USE_PSA_CRYPTO` just to determine whether to call MD or PSA to calculate hashes can switch to just having the MD variant.
#### Remove `legacy_or_psa.h`
It's no longer used.
### Support all legacy algorithms in PSA
As discussed in [“Implications between legacy availability and PSA availability”](#implications-between-legacy-availability-and-psa-availability), we require the following property:
> If an algorithm has a legacy implementation, it is also available through PSA.
When `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled, this is already the case. When is enabled, we will now make it so as well. Change `include/mbedtls/config_psa.h` accordingly.
### MD light optimizations
This section is not necessary to implement MD light, but will cut down its code size.
#### Split names out of MD light
Remove hash names from `mbedtls_md_info_t`. Use a simple switch-case or a separate list to implement `mbedtls_md_info_from_string` and `mbedtls_md_get_name`.
#### Remove metadata from the info structure
In `mbedtls_md_get_size` and in modules that want a hash's block size, instead of looking up hash metadata in the info structure, call the PSA macros.
#### Optimize type conversions
To allow optimizing conversions between `mbedtls_md_type_t` and `psa_algorithm_t`, renumber the `mbedtls_md_type_t` enum so that the values are the 8 lower bits of the PSA encoding.
With this optimization,
```
static inline psa_algorithm_t psa_alg_of_md_info(
const mbedtls_md_info_t *md_info )
{
if( md_info == NULL )
return( PSA_ALG_NONE );
return( PSA_ALG_CATEGORY_HASH | md_info->type );
}
```
Work in progress on this conversion is at https://github.com/gilles-peskine-arm/mbedtls/tree/hash-unify-ids-wip-1
#### Get rid of the hash_info module
The hash_info module is redundant with MD light. Move `mbedtls_md_error_from_psa` to `md.c`, defined only when `MBEDTLS_MD_SOME_PSA` is defined. The rest is no longer used.
#### Unify HMAC with PSA
PSA has its own HMAC implementation. In builds with both `MBEDTLS_MD_C` and `PSA_WANT_ALG_HMAC` not fully provided by drivers, we should have a single implementation. Replace the one in `md.h` by calls to the PSA driver interface. This will also give mixed-domain modules access to HMAC accelerated directly by a PSA driver (eliminating the need to a HMAC interface in software if all supported hashes have an accelerator that includes HMAC support).
### Improving support for `MBEDTLS_PSA_CRYPTO_CLIENT`
So far, MD light only dispatches to PSA if an algorithm is available via `MBEDTLS_PSA_CRYPTO_C`, not if it's available via `MBEDTLS_PSA_CRYPTO_CLIENT`. This is acceptable because `MBEDTLS_USE_PSA_CRYPTO` requires `MBEDTLS_PSA_CRYPTO_C`, hence mixed-domain code never invokes PSA.
The architecture can be extended to support `MBEDTLS_PSA_CRYPTO_CLIENT` with a little extra work. Here is an overview of the task breakdown, which should be fleshed up after we've done the first [migration](#migration-to-md-light):
* Compile-time dependencies: instead of checking `defined(MBEDTLS_PSA_CRYPTO_C)`, check `defined(MBEDTLS_PSA_CRYPTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)`.
* Implementers of `MBEDTLS_PSA_CRYPTO_CLIENT` will need to provide `psa_can_do_hash()` (or a more general function `psa_can_do`) alongside `psa_crypto_init()`. Note that at this point, it will become a public interface, hence we won't be able to change it at a whim.

View file

@ -27,3 +27,18 @@ HAVE_DOT = YES
DOT_GRAPH_MAX_NODES = 200
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = YES
# We mostly use \retval declarations to document which error codes a function
# can return. The reader can follow the hyperlink to the definition of the
# constant to get the generic documentation of that error code. If we don't
# have anything to say about the specific error code for the specific
# function, we can leave the description part of the \retval command blank.
# This is perfectly valid as far as Doxygen is concerned. However, with
# Clang >=15, the -Wdocumentation option emits a warning for empty
# descriptions.
# https://github.com/Mbed-TLS/mbedtls/issues/6960
# https://github.com/llvm/llvm-project/issues/60315
# As a workaround, you can write something like
# \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
# This avoids writing redundant text and keeps Clang happy.
ALIASES += emptydescription=""

View file

@ -63,7 +63,7 @@
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
/*
* Maximum window size used for modular exponentiation. Default: 6
* Maximum window size used for modular exponentiation. Default: 2
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
@ -71,7 +71,7 @@
*
* Reduction in size, reduces speed.
*/
#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */
#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)

View file

@ -80,26 +80,22 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
* is defined as well to include all PSA code.
*/
#if defined(MBEDTLS_PSA_CRYPTO_C)
#define MBEDTLS_PSA_CRYPTO_CLIENT
#endif /* MBEDTLS_PSA_CRYPTO_C */
/* The PK wrappers need pk_write functions to format RSA key objects
* when they are dispatching to the PSA API. This happens under USE_PSA_CRYPTO,
* and also even without USE_PSA_CRYPTO for mbedtls_pk_sign_ext().
* PSA crypto also needs pk_write to export RSA keys (otherwise the build
* goes through but psa_export_key() and psa_export_public_key() fail on
* RSA keys), and pk_parse to work with RSA keys in almost any way.
*/
* and also even without USE_PSA_CRYPTO for mbedtls_pk_sign_ext(). */
#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_RSA_C)
#define MBEDTLS_PK_C
#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_PK_PARSE_C
#endif
/* Under MBEDTLS_USE_PSA_CRYPTO, the pk module needs pk_write functions
* to pass ECC keys to PSA. */
#if defined(MBEDTLS_PK_C) && \
defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECP_C)
#define MBEDTLS_PK_WRITE_C
#endif
#if !defined(MBEDTLS_SSL_PROTO_TLS1_2)
#undef MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED

View file

@ -70,6 +70,10 @@
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_AESCE_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_AESCE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
@ -708,41 +712,6 @@
#if defined(MBEDTLS_SHA512_ALT) || defined(MBEDTLS_SHA512_PROCESS_ALT)
#error "MBEDTLS_SHA512_*ALT can't be used with MBEDTLS_SHA512_USE_A64_CRYPTO_*"
#endif
/*
* Best performance comes from most recent compilers, with intrinsics and -O3.
* Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
* can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
*
* GCC < 8 won't work at all (lacks the sha512 instructions)
* GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
*
* Clang < 7 won't work at all (lacks the sha512 instructions)
* Clang 7-12 don't have intrinsics (but we work around that with inline
* assembler) or __ARM_FEATURE_SHA512
* Clang == 13.0.0 same as clang 12 (only seen on macOS)
* Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
*/
#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512)
/* Test Clang first, as it defines __GNUC__ */
# if defined(__clang__)
# if __clang_major__ < 7
# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
# elif __clang_major__ < 13 || \
(__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0)
/* We implement the intrinsics with inline assembler, so don't error */
# else
# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
# endif
# elif defined(__GNUC__)
# if __GNUC__ < 8
# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
# else
# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
# endif
# else
# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
# endif
#endif
#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
@ -763,9 +732,7 @@
#if defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA256_PROCESS_ALT)
#error "MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_A64_CRYPTO_*"
#endif
#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO)
#error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
#endif
#endif
#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) && \
@ -932,6 +899,11 @@
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_RENEGOTIATION) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_RENEGOTIATION defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TICKET_C) && ( !defined(MBEDTLS_CIPHER_C) && \
!defined(MBEDTLS_USE_PSA_CRYPTO) )
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"

View file

@ -71,6 +71,11 @@ extern "C" {
* \warning Performing multiple operations concurrently on the same
* ECDSA context is not supported; objects of this type
* should not be shared between multiple threads.
*
* \note pk_wrap module assumes that "ecdsa_context" is identical
* to "ecp_keypair" (see for example structure
* "mbedtls_eckey_info" where ECDSA sign/verify functions
* are used also for EC key)
*/
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
@ -217,6 +222,134 @@ int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r,
void *p_rng_blind);
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, in a restartable way.
*
* \note The deterministic version implemented in
* mbedtls_ecdsa_sign_det_restartable() is usually
* preferred.
*
* \note This function is like \c mbedtls_ecdsa_sign() but
* it can return early and restart according to the
* limit set with \c mbedtls_ecp_set_max_ops() to
* reduce blocking.
*
* \note If the bitlength of the message hash is larger
* than the bitlength of the group order, then the
* hash is truncated as defined in <em>Standards for
* Efficient Cryptography Group (SECG): SEC1 Elliptic
* Curve Cryptography</em>, section 4.1.3, step 5.
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through
* mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param f_rng The RNG function. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
* \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
* \param rs_ctx The restart context to use. This may be \c NULL
* to disable restarting. If it is not \c NULL, it
* must point to an initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c
* mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c
* MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX
* error code on failure.
*/
int mbedtls_ecdsa_sign_restartable(
mbedtls_ecp_group *grp,
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int (*f_rng_blind)(void *, unsigned char *, size_t),
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx);
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, in a restartable way.
*
* \note This function is like \c
* mbedtls_ecdsa_sign_det_ext() but it can return
* early and restart according to the limit set with
* \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \note If the bitlength of the message hash is larger
* than the bitlength of the group order, then the
* hash is truncated as defined in <em>Standards for
* Efficient Cryptography Group (SECG): SEC1 Elliptic
* Curve Cryptography</em>, section 4.1.3, step 5.
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through
* mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
* \param rs_ctx The restart context to use. This may be \c NULL
* to disable restarting. If it is not \c NULL, it
* must point to an initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c
* mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c
* MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX
* error code on failure.
*/
int mbedtls_ecdsa_sign_det_restartable(
mbedtls_ecp_group *grp,
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
int (*f_rng_blind)(void *, unsigned char *, size_t),
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx);
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
/**
* \brief This function verifies the ECDSA signature of a
* previously-hashed message.
@ -252,6 +385,51 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
const mbedtls_mpi *s);
#if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
/**
* \brief This function verifies the ECDSA signature of a
* previously-hashed message, in a restartable manner
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.4, step 3.
*
* \see ecp.h
*
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param buf The hashed content that was signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param Q The public key to use for verification. This must be
* initialized and setup.
* \param r The first integer of the signature.
* This must be initialized.
* \param s The second integer of the signature.
* This must be initialized.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*/
int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *r,
const mbedtls_mpi *s,
mbedtls_ecdsa_restart_ctx *rs_ctx);
#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
/**
* \brief This function computes the ECDSA signature and writes it
* to a buffer, serialized as defined in <em>RFC-4492:

View file

@ -141,6 +141,15 @@ typedef enum {
MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
} mbedtls_ecp_curve_type;
/*
* Curve modulus types
*/
typedef enum {
MBEDTLS_ECP_MOD_NONE = 0,
MBEDTLS_ECP_MOD_COORDINATE,
MBEDTLS_ECP_MOD_SCALAR
} mbedtls_ecp_modulus_type;
/**
* Curve information, for use by other modules.
*
@ -419,11 +428,22 @@ typedef struct mbedtls_ecp_keypair {
}
mbedtls_ecp_keypair;
/*
* Point formats, from RFC 4492's enum ECPointFormat
/**
* The uncompressed point format for Short Weierstrass curves
* (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX).
*/
#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format. */
#define MBEDTLS_ECP_PF_COMPRESSED 1 /**< Compressed point format. */
#define MBEDTLS_ECP_PF_UNCOMPRESSED 0
/**
* The compressed point format for Short Weierstrass curves
* (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX).
*
* \warning While this format is supported for all concerned curves for
* writing, when it comes to parsing, it is not supported for all
* curves. Specifically, parsing compressed points on
* MBEDTLS_ECP_DP_SECP224R1 and MBEDTLS_ECP_DP_SECP224K1 is not
* supported.
*/
#define MBEDTLS_ECP_PF_COMPRESSED 1
/*
* Some other constants from RFC 4492
@ -461,6 +481,12 @@ mbedtls_ecp_keypair;
* only enabled for specific sides and key exchanges
* (currently only for clients and ECDHE-ECDSA).
*
* \warning Using the PSA interruptible interfaces with keys in local
* storage and no accelerator driver will also call this
* function to set the values specified via those interfaces,
* overwriting values previously set. Care should be taken if
* mixing these two interfaces.
*
* \param max_ops Maximum number of basic operations done in a row.
* Default: 0 (unlimited).
* Lower (non-zero) values mean ECC functions will block for
@ -752,6 +778,9 @@ int mbedtls_ecp_point_write_binary(const mbedtls_ecp_group *grp,
* belongs to the given group, see mbedtls_ecp_check_pubkey()
* for that.
*
* \note For compressed points, see #MBEDTLS_ECP_PF_COMPRESSED for
* limitations.
*
* \param grp The group to which the point should belong.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().

View file

@ -2065,6 +2065,34 @@
*/
#define MBEDTLS_AESNI_C
/**
* \def MBEDTLS_AESCE_C
*
* Enable AES crypto extension support on Arm64.
*
* Module: library/aesce.c
* Caller: library/aes.c
*
* Requires: MBEDTLS_HAVE_ASM, MBEDTLS_AES_C
*
* \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum
* of \c -march=armv8-a+crypto .
*
* \warning If the target architecture is set to something that includes the
* SHA3 feature (e.g. `-march=armv8.2-a+sha3`), for example because
* `MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT` is desired, compilers
* generate code for `MBEDTLS_AESCE_C` that includes instructions
* only present with the (optional) SHA3 feature. This will lead to an
* undefined instruction exception if the code is run on a CPU without
* that feature.
*
* \warning Runtime detection only works on linux. For non-linux operation
* system, crypto extension MUST be supported by CPU.
*
* This module adds support for the AES crypto instructions on Arm64
*/
#define MBEDTLS_AESCE_C
/**
* \def MBEDTLS_AES_C
*
@ -3087,9 +3115,6 @@
* \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building
* for a non-Aarch64 build it will be silently ignored.
*
* \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum
* of \c -march=armv8-a+crypto.
*
* \warning MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the
* same time as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY.
*
@ -3112,9 +3137,6 @@
* \note This allows builds with a smaller code size than with
* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
*
* \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum
* of \c -march=armv8-a+crypto.
*
* \warning MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY cannot be defined at the same
* time as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT.
*
@ -3180,9 +3202,7 @@
* for a non-Aarch64 build it will be silently ignored.
*
* \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or
* Clang >= 7, and \c CFLAGS must be set to a minimum of
* \c -march=armv8.2-a+sha3. An optimisation level of \c -O3 generates the
* fastest code.
* Clang >= 7.
*
* \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the
* same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY.
@ -3207,9 +3227,7 @@
* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
*
* \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or
* Clang >= 7, and \c CFLAGS must be set to a minimum of
* \c -march=armv8.2-a+sha3. An optimisation level of \c -O3 generates the
* fastest code.
* Clang >= 7.
*
* \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same
* time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT.
@ -3548,6 +3566,53 @@
*/
//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null"
/**
* \def MBEDTLS_PSA_CRYPTO_PLATFORM_FILE
*
* If defined, this is a header which will be included instead of
* `"psa/crypto_platform.h"`. This file should declare the same identifiers
* as the one in Mbed TLS, but with definitions adapted to the platform on
* which the library code will run.
*
* \note The required content of this header can vary from one version of
* Mbed TLS to the next. Integrators who provide an alternative file
* should review the changes in the original file whenever they
* upgrade Mbed TLS.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_PSA_CRYPTO_PLATFORM_FILE "psa/crypto_platform_alt.h"
/**
* \def MBEDTLS_PSA_CRYPTO_STRUCT_FILE
*
* If defined, this is a header which will be included instead of
* `"psa/crypto_struct.h"`. This file should declare the same identifiers
* as the one in Mbed TLS, but with definitions adapted to the environment
* in which the library code will run. The typical use for this feature
* is to provide alternative type definitions on the client side in
* client-server integrations of PSA crypto, where operation structures
* contain handles instead of cryptographic data.
*
* \note The required content of this header can vary from one version of
* Mbed TLS to the next. Integrators who provide an alternative file
* should review the changes in the original file whenever they
* upgrade Mbed TLS.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_PSA_CRYPTO_STRUCT_FILE "psa/crypto_struct_alt.h"
/** \} name SECTION: General configuration options */
/**
@ -3570,7 +3635,7 @@
* comment in the specific module. */
/* MPI / BIGNUM options */
//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */
//#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */
//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
/* CTR_DRBG options */

View file

@ -98,8 +98,24 @@ typedef enum {
* See \c mbedtls_rsa_rsassa_pss_verify_ext()
*/
typedef struct mbedtls_pk_rsassa_pss_options {
mbedtls_md_type_t MBEDTLS_PRIVATE(mgf1_hash_id);
int MBEDTLS_PRIVATE(expected_salt_len);
/** The digest to use for MGF1 in PSS.
*
* \note When #MBEDTLS_USE_PSA_CRYPTO is enabled and #MBEDTLS_RSA_C is
* disabled, this must be equal to the \c md_alg argument passed
* to mbedtls_pk_verify_ext(). In a future version of the library,
* this constraint may apply whenever #MBEDTLS_USE_PSA_CRYPTO is
* enabled regardless of the status of #MBEDTLS_RSA_C.
*/
mbedtls_md_type_t mgf1_hash_id;
/** The expected length of the salt, in bytes. This may be
* #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
*
* \note When #MBEDTLS_USE_PSA_CRYPTO is enabled, only
* #MBEDTLS_RSA_SALT_LEN_ANY is valid. Any other value may be
* ignored (allowing any salt length).
*/
int expected_salt_len;
} mbedtls_pk_rsassa_pss_options;
@ -155,6 +171,32 @@ typedef struct mbedtls_pk_rsassa_pss_options {
#endif
#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */
/**
* \brief The following defines are meant to list ECDSA capabilities of the
* PK module in a general way (without any reference to how this
* is achieved, which can be either through PSA driver or
* MBEDTLS_ECDSA_C)
*/
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(PSA_WANT_ALG_ECDSA)
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#endif
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif
#endif /* PSA_WANT_ALG_ECDSA */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) || defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#define MBEDTLS_PK_CAN_ECDSA_SOME
#endif
/**
* \brief Types for interfacing with the debug module
*/
@ -804,6 +846,9 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *ctx,
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
* specific key type, check the result with mbedtls_pk_can_do().
*
* \note For compressed points, see #MBEDTLS_ECP_PF_COMPRESSED for
* limitations.
*
* \note The key is also checked for correctness.
*
* \return 0 if successful, or a specific PK or PEM error code

View file

@ -46,6 +46,8 @@
* - The RFC allows for SignerInfo structure to optionally contain
* unauthenticatedAttributes and authenticatedAttributes. In Mbed TLS it is
* assumed these fields are empty.
* - The RFC allows for the signed Data type to contain contentInfo. This
* implementation assumes the type is DATA and the content is empty.
*/
#ifndef MBEDTLS_PKCS7_H
@ -66,7 +68,7 @@
#define MBEDTLS_ERR_PKCS7_INVALID_FORMAT -0x5300 /**< The format is invalid, e.g. different type expected. */
#define MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE -0x5380 /**< Unavailable feature, e.g. anything other than signed data. */
#define MBEDTLS_ERR_PKCS7_INVALID_VERSION -0x5400 /**< The PKCS7 version element is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO -0x5480 /**< The PKCS7 content info invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO -0x5480 /**< The PKCS7 content info is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_ALG -0x5500 /**< The algorithm tag or value is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CERT -0x5580 /**< The certificate tag or value is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE -0x5600 /**< Error parsing the signature */
@ -133,22 +135,12 @@ typedef struct mbedtls_pkcs7_signer_info {
}
mbedtls_pkcs7_signer_info;
/**
* Structure holding attached data as part of PKCS7 signed data format
*/
typedef struct mbedtls_pkcs7_data {
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(oid);
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(data);
}
mbedtls_pkcs7_data;
/**
* Structure holding the signed data section
*/
typedef struct mbedtls_pkcs7_signed_data {
int MBEDTLS_PRIVATE(version);
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(digest_alg_identifiers);
struct mbedtls_pkcs7_data MBEDTLS_PRIVATE(content);
int MBEDTLS_PRIVATE(no_of_certs);
mbedtls_x509_crt MBEDTLS_PRIVATE(certs);
int MBEDTLS_PRIVATE(no_of_crls);
@ -163,7 +155,6 @@ mbedtls_pkcs7_signed_data;
*/
typedef struct mbedtls_pkcs7 {
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(raw);
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(content_type_oid);
mbedtls_pkcs7_signed_data MBEDTLS_PRIVATE(signed_data);
}
mbedtls_pkcs7;
@ -176,15 +167,17 @@ mbedtls_pkcs7;
void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7);
/**
* \brief Parse a single DER formatted pkcs7 content.
* \brief Parse a single DER formatted pkcs7 detached signature.
*
* \param pkcs7 The pkcs7 structure to be filled by parser for the output.
* \param buf The buffer holding the DER encoded pkcs7.
* \param buflen The size in bytes of \p buf.
* \param buf The buffer holding only the DER encoded pkcs7.
* \param buflen The size in bytes of \p buf. The size must be exactly the
* length of the DER encoded pkcs7.
*
* \note This function makes an internal copy of the PKCS7 buffer
* \p buf. In particular, \p buf may be destroyed or reused
* after this call returns.
* \note Signatures with internal data are not supported.
*
* \return The \c mbedtls_pkcs7_type of \p buf, if successful.
* \return A negative error code on failure.
@ -204,7 +197,8 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
* matches.
*
* This function does not use the certificates held within the
* PKCS7 structure itself.
* PKCS7 structure itself, and does not check that the
* certificate is signed by a trusted certification authority.
*
* \param pkcs7 PKCS7 structure containing signature.
* \param cert Certificate containing key to verify signature.
@ -225,15 +219,15 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
* \brief Verification of PKCS7 signature against a caller-supplied
* certificate.
*
* For each signer in the PKCS structure, this function computes
* a signature over the supplied hash, using the supplied
* certificate and the same digest algorithm as specified by the
* signer. It then compares this signature against the
* signer's signature; verification succeeds if any comparison
* matches.
* For each signer in the PKCS structure, this function
* validates a signature over the supplied hash, using the
* supplied certificate and the same digest algorithm as
* specified by the signer. Verification succeeds if any
* signature is good.
*
* This function does not use the certificates held within the
* PKCS7 structure itself.
* PKCS7 structure itself, and does not check that the
* certificate is signed by a trusted certification authority.
*
* \param pkcs7 PKCS7 structure containing signature.
* \param cert Certificate containing key to verify signature.
@ -241,7 +235,7 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
* \param hashlen Length of the hash.
*
* \note This function is different from mbedtls_pkcs7_signed_data_verify()
* in a way that it directly receives the hash of the data.
* in that it is directly passed the hash of the data.
*
* \return 0 if the signature verifies, or a negative error code on failure.
*/

View file

@ -257,6 +257,9 @@ static inline int mbedtls_psa_get_ecc_oid_from_id(
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH \
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
#define MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH \
PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
/* Expose whatever RNG the PSA subsystem uses to applications using the
* mbedtls_xxx API. The declarations and definitions here need to be
* consistent with the implementation in library/psa_crypto_random_impl.h.

View file

@ -533,7 +533,8 @@
#define MBEDTLS_SSL_HS_SERVER_HELLO 2
#define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3
#define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4
#define MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS 8 // NEW IN TLS 1.3
#define MBEDTLS_SSL_HS_END_OF_EARLY_DATA 5
#define MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS 8
#define MBEDTLS_SSL_HS_CERTIFICATE 11
#define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12
#define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST 13
@ -671,10 +672,12 @@ typedef enum {
MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT,
MBEDTLS_SSL_HELLO_RETRY_REQUEST,
MBEDTLS_SSL_ENCRYPTED_EXTENSIONS,
MBEDTLS_SSL_END_OF_EARLY_DATA,
MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY,
MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED,
MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO,
MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO,
MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO,
MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST,
MBEDTLS_SSL_HANDSHAKE_OVER,
MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET,
@ -4542,7 +4545,7 @@ int mbedtls_ssl_get_max_out_record_payload(const mbedtls_ssl_context *ssl);
/**
* \brief Return the current maximum incoming record payload in bytes.
*
* \note The logic to determine the maximum outgoing record payload is
* \note The logic to determine the maximum incoming record payload is
* version-specific. It takes into account various factors, such as
* the mbedtls_config.h setting \c MBEDTLS_SSL_IN_CONTENT_LEN, extensions
* such as the max fragment length extension or record size limit
@ -4554,7 +4557,7 @@ int mbedtls_ssl_get_max_out_record_payload(const mbedtls_ssl_context *ssl);
*
* \param ssl SSL context
*
* \return Current maximum payload for an outgoing record,
* \return Current maximum payload for an incoming record,
* or a negative error code.
*/
int mbedtls_ssl_get_max_in_record_payload(const mbedtls_ssl_context *ssl);

View file

@ -294,7 +294,7 @@ typedef struct mbedtls_x509_subject_alternative_name {
int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
union {
mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
mbedtls_x509_buf unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
mbedtls_x509_buf unstructured_name; /**< The buffer for the unconstructed types. Only rfc822Name, dnsName and uniformResourceIdentifier are currently supported */
}
san; /**< A union of the supported SAN types */
}
@ -385,8 +385,9 @@ int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
* \param san The target structure to populate with the parsed presentation
* of the subject alternative name encoded in \p san_raw.
*
* \note Only "dnsName" and "otherName" of type hardware_module_name
* as defined in RFC 4180 is supported.
* \note Supported GeneralName types, as defined in RFC 5280:
* "rfc822Name", "dnsName", "uniformResourceIdentifier" and "hardware_module_name"
* of type "otherName", as defined in RFC 4108.
*
* \note This function should be called on a single raw data of
* subject alternative name. For example, after successful

View file

@ -76,7 +76,7 @@ typedef struct mbedtls_x509_crt {
mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */
mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */
mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName, uniformResourceIdentifier and OtherName are listed). */
mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */

File diff suppressed because it is too large Load diff

View file

@ -107,4 +107,78 @@ typedef struct {
#define MBEDTLS_PSA_AEAD_OPERATION_INIT { 0, 0, 0, 0, { 0 } }
#include "mbedtls/ecdsa.h"
/* Context structure for the Mbed TLS interruptible sign hash implementation. */
typedef struct {
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecdsa_context *MBEDTLS_PRIVATE(ctx);
mbedtls_ecdsa_restart_ctx MBEDTLS_PRIVATE(restart_ctx);
uint32_t MBEDTLS_PRIVATE(num_ops);
size_t MBEDTLS_PRIVATE(coordinate_bytes);
psa_algorithm_t MBEDTLS_PRIVATE(alg);
mbedtls_md_type_t MBEDTLS_PRIVATE(md_alg);
uint8_t MBEDTLS_PRIVATE(hash)[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
size_t MBEDTLS_PRIVATE(hash_length);
#else
/* Make the struct non-empty if algs not supported. */
unsigned MBEDTLS_PRIVATE(dummy);
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
} mbedtls_psa_sign_hash_interruptible_operation_t;
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
#define MBEDTLS_PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { { 0 }, { 0 }, 0, 0, 0, 0, 0, 0 }
#else
#define MBEDTLS_PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 }
#endif
/* Context structure for the Mbed TLS interruptible verify hash
* implementation.*/
typedef struct {
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecdsa_context *MBEDTLS_PRIVATE(ctx);
mbedtls_ecdsa_restart_ctx MBEDTLS_PRIVATE(restart_ctx);
uint32_t MBEDTLS_PRIVATE(num_ops);
uint8_t MBEDTLS_PRIVATE(hash)[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
size_t MBEDTLS_PRIVATE(hash_length);
mbedtls_mpi MBEDTLS_PRIVATE(r);
mbedtls_mpi MBEDTLS_PRIVATE(s);
#else
/* Make the struct non-empty if algs not supported. */
unsigned MBEDTLS_PRIVATE(dummy);
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
} mbedtls_psa_verify_hash_interruptible_operation_t;
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
#define MBEDTLS_VERIFY_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { { 0 }, { 0 }, 0, 0, 0, 0, { 0 }, \
{ 0 } }
#else
#define MBEDTLS_VERIFY_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 }
#endif
#endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */

View file

@ -105,11 +105,11 @@ static inline int psa_key_handle_is_null(psa_key_handle_t handle)
* permission to access it. Note that this specification does not
* define any way to create such a key, but it may be possible
* through implementation-specific means.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@ -149,8 +149,8 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key,
* \p handle was a valid handle or \c 0. It is now closed.
* \retval #PSA_ERROR_INVALID_HANDLE
* \p handle is not a valid handle nor \c 0.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize

View file

@ -114,5 +114,15 @@ typedef union {
#endif
} psa_driver_aead_context_t;
typedef union {
unsigned dummy; /* Make sure this union is always non-empty */
mbedtls_psa_sign_hash_interruptible_operation_t mbedtls_ctx;
} psa_driver_sign_hash_interruptible_context_t;
typedef union {
unsigned dummy; /* Make sure this union is always non-empty */
mbedtls_psa_verify_hash_interruptible_operation_t mbedtls_ctx;
} psa_driver_verify_hash_interruptible_context_t;
#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */
/* End of automatically generated file. */

View file

@ -189,12 +189,12 @@ static inline void psa_clear_key_slot_number(
* or the specified slot number is not valid.
* \retval #PSA_ERROR_NOT_PERMITTED
* The caller is not authorized to register the specified key slot.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@ -491,10 +491,10 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
* according to \p type as described above.
* \param data_length Size of the \p data buffer in bytes.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
psa_key_type_t type,
@ -521,8 +521,8 @@ psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
* \param[out] data_length On success, the number of bytes
* that make up the key domain parameters data.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription
*/
psa_status_t psa_get_key_domain_parameters(
const psa_key_attributes_t *attributes,
@ -1352,8 +1352,8 @@ static psa_pake_operation_t psa_pake_operation_init(void);
* compatible with the PAKE algorithm, or the hash algorithm in
* \p cipher_suite is not supported or not compatible with the PAKE
* algorithm and primitive.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid, or
* the library has not been previously initialized by psa_crypto_init().
@ -1397,11 +1397,11 @@ psa_status_t psa_pake_setup(psa_pake_operation_t *operation,
* \retval #PSA_ERROR_NOT_SUPPORTED
* The key type or key size of \p password is not supported with the
* \p operation's cipher suite.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must have been set up.), or
* the library has not been previously initialized by psa_crypto_init().
@ -1439,9 +1439,9 @@ psa_status_t psa_pake_set_password_key(psa_pake_operation_t *operation,
* suite.
* \retval #PSA_ERROR_NOT_SUPPORTED
* The value of \p user_id is not supported by the implementation.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid, or
* the library has not been previously initialized by psa_crypto_init().
@ -1480,9 +1480,9 @@ psa_status_t psa_pake_set_user(psa_pake_operation_t *operation,
* suite.
* \retval #PSA_ERROR_NOT_SUPPORTED
* The algorithm doesn't associate a second identity with the session.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* Calling psa_pake_set_peer() is invalid with the \p operation's
* algorithm, the operation state is not valid, or the library has not
@ -1524,8 +1524,8 @@ psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation,
* The \p role is not a valid PAKE role in the \p operations algorithm.
* \retval #PSA_ERROR_NOT_SUPPORTED
* The \p role for this algorithm is not supported or is not valid.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid, or
* the library has not been previously initialized by psa_crypto_init().
@ -1575,13 +1575,13 @@ psa_status_t psa_pake_set_role(psa_pake_operation_t *operation,
* \p step is not compatible with the operation's algorithm.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p step is not supported with the operation's algorithm.
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be active, and fully set
* up, and this call must conform to the algorithm's requirements
@ -1631,12 +1631,12 @@ psa_status_t psa_pake_output(psa_pake_operation_t *operation,
* \p step p is not supported with the \p operation's algorithm, or the
* \p input is not supported for the \p operation's algorithm, cipher
* suite or \p step.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be active, and fully set
* up, and this call must conform to the algorithm's requirements
@ -1691,12 +1691,12 @@ psa_status_t psa_pake_input(psa_pake_operation_t *operation,
* \retval #PSA_ERROR_NOT_SUPPORTED
* Input from a PAKE is not supported by the algorithm in the \p output
* key derivation operation.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The PAKE operation state is not valid (it must be active, but beyond
* that validity is specific to the algorithm), or
@ -1728,8 +1728,8 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
*
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize

View file

@ -385,8 +385,8 @@ typedef struct {
* \param[in] direction Indicates whether the operation is an encrypt
* or decrypt
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
*/
typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_context,
void *op_context,
@ -407,7 +407,7 @@ typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_cont
* \param[in] p_iv A buffer containing the initialization vector
* \param[in] iv_length The size (in bytes) of the `p_iv` buffer
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context,
const uint8_t *p_iv,
@ -429,7 +429,7 @@ typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context,
* \param[out] p_output_length After completion, will contain the number
* of bytes placed in the `p_output` buffer
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context,
const uint8_t *p_input,
@ -450,7 +450,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context,
* \param[out] p_output_length After completion, will contain the number of
* bytes placed in the `p_output` buffer
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *op_context,
uint8_t *p_output,
@ -485,8 +485,8 @@ typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *op_context);
* \param[in] output_size The allocated size in bytes of the `p_output`
* buffer
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
*/
typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
@ -554,7 +554,7 @@ typedef struct {
* \param[out] p_signature_length On success, the number of bytes
* that make up the returned signature value
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
@ -618,7 +618,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv
* \param[out] p_output_length On success, the number of bytes that make up
* the returned output
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
@ -658,7 +658,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *dr
* \param[out] p_output_length On success, the number of bytes
* that make up the returned output
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
@ -904,8 +904,8 @@ typedef enum {
* Success.
* The core will record \c *key_slot as the key slot where the key
* is stored and will update the persistent data in storage.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
*/
typedef psa_status_t (*psa_drv_se_allocate_key_t)(
psa_drv_se_context_t *drv_context,
@ -1043,13 +1043,13 @@ typedef psa_status_t (*psa_drv_se_destroy_key_t)(
* \param[out] p_data_length On success, the number of bytes
* that make up the key data.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key,
@ -1196,7 +1196,7 @@ typedef struct {
* \param[in] source_key The key to be used as the source material for
* the key derivation
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *drv_context,
void *op_context,
@ -1216,7 +1216,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *
* \param[in] p_collateral A buffer containing the collateral data
* \param[in] collateral_size The size in bytes of the collateral
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context,
uint32_t collateral_id,
@ -1231,7 +1231,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context,
* \param[in] dest_key The slot where the generated key material
* should be placed
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context,
psa_key_slot_number_t dest_key);
@ -1245,7 +1245,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context,
* \param[out] p_output_length Upon success, contains the number of bytes of
* key material placed in `p_output`
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *op_context,
uint8_t *p_output,

View file

@ -491,6 +491,66 @@ static inline size_t psa_get_key_bits(
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits);
}
/**
* \brief The context for PSA interruptible hash signing.
*/
struct psa_sign_hash_interruptible_operation_s {
/** Unique ID indicating which driver got assigned to do the
* operation. Since driver contexts are driver-specific, swapping
* drivers halfway through the operation is not supported.
* ID values are auto-generated in psa_crypto_driver_wrappers.h
* ID value zero means the context is not valid or not assigned to
* any driver (i.e. none of the driver contexts are active). */
unsigned int MBEDTLS_PRIVATE(id);
psa_driver_sign_hash_interruptible_context_t MBEDTLS_PRIVATE(ctx);
unsigned int MBEDTLS_PRIVATE(error_occurred) : 1;
uint32_t MBEDTLS_PRIVATE(num_ops);
};
#define PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0, 0 }
static inline struct psa_sign_hash_interruptible_operation_s
psa_sign_hash_interruptible_operation_init(void)
{
const struct psa_sign_hash_interruptible_operation_s v =
PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT;
return v;
}
/**
* \brief The context for PSA interruptible hash verification.
*/
struct psa_verify_hash_interruptible_operation_s {
/** Unique ID indicating which driver got assigned to do the
* operation. Since driver contexts are driver-specific, swapping
* drivers halfway through the operation is not supported.
* ID values are auto-generated in psa_crypto_driver_wrappers.h
* ID value zero means the context is not valid or not assigned to
* any driver (i.e. none of the driver contexts are active). */
unsigned int MBEDTLS_PRIVATE(id);
psa_driver_verify_hash_interruptible_context_t MBEDTLS_PRIVATE(ctx);
unsigned int MBEDTLS_PRIVATE(error_occurred) : 1;
uint32_t MBEDTLS_PRIVATE(num_ops);
};
#define PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0, 0 }
static inline struct psa_verify_hash_interruptible_operation_s
psa_verify_hash_interruptible_operation_init(void)
{
const struct psa_verify_hash_interruptible_operation_s v =
PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT;
return v;
}
#ifdef __cplusplus
}
#endif

View file

@ -32,16 +32,17 @@
#ifndef PSA_CRYPTO_TYPES_H
#define PSA_CRYPTO_TYPES_H
/* Make sure the Mbed TLS configuration is visible. */
#include "mbedtls/build_info.h"
/* Define the MBEDTLS_PRIVATE macro. */
#include "mbedtls/private_access.h"
#if defined(MBEDTLS_PSA_CRYPTO_PLATFORM_FILE)
#include MBEDTLS_PSA_CRYPTO_PLATFORM_FILE
#else
#include "crypto_platform.h"
/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
* is defined as well to include all PSA code.
*/
#if defined(MBEDTLS_PSA_CRYPTO_C)
#define MBEDTLS_PSA_CRYPTO_CLIENT
#endif /* MBEDTLS_PSA_CRYPTO_C */
#endif
#include <stdint.h>

View file

@ -335,6 +335,13 @@
*/
#define PSA_ERROR_DATA_INVALID ((psa_status_t)-153)
/** The function that returns this status is defined as interruptible and
* still has work to do, thus the user should call the function again with the
* same operation context until it either returns #PSA_SUCCESS or any other
* error. This is not an error per se, more a notification of status.
*/
#define PSA_OPERATION_INCOMPLETE ((psa_status_t)-248)
/* *INDENT-ON* */
/**@}*/
@ -2739,4 +2746,18 @@ static inline int mbedtls_svc_key_id_is_null(mbedtls_svc_key_id_t key)
/**@}*/
/**@}*/
/** \defgroup interruptible Interruptible operations
* @{
*/
/** Maximum value for use with \c psa_interruptible_set_max_ops() to determine
* the maximum number of ops allowed to be executed by an interruptible
* function in a single call.
*/
#define PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED UINT32_MAX
/**@}*/
#endif /* PSA_CRYPTO_VALUES_H */

View file

@ -13,6 +13,7 @@ endif()
set(src_crypto
aes.c
aesni.c
aesce.c
aria.c
asn1parse.c
asn1write.c

View file

@ -78,6 +78,7 @@ endif
OBJS_CRYPTO= \
aes.o \
aesni.o \
aesce.o \
aria.o \
asn1parse.o \
asn1write.o \

View file

@ -39,6 +39,9 @@
#if defined(MBEDTLS_AESNI_C)
#include "aesni.h"
#endif
#if defined(MBEDTLS_AESCE_C)
#include "aesce.h"
#endif
#include "mbedtls/platform.h"
@ -544,6 +547,12 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
}
#endif
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
if (mbedtls_aesce_has_support()) {
return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
}
#endif
for (i = 0; i < (keybits >> 5); i++) {
RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
}
@ -652,6 +661,16 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
}
#endif
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
if (mbedtls_aesce_has_support()) {
mbedtls_aesce_inverse_key(
(unsigned char *) RK,
(const unsigned char *) (cty.buf + cty.rk_offset),
ctx->nr);
goto exit;
}
#endif
SK = cty.buf + cty.rk_offset + cty.nr * 4;
*RK++ = *SK++;
@ -944,6 +963,12 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
}
#endif
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
if (mbedtls_aesce_has_support()) {
return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
}
#endif
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
if (aes_padlock_ace > 0) {
if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {

257
library/aesce.c Normal file
View file

@ -0,0 +1,257 @@
/*
* Arm64 crypto extension support functions
*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "common.h"
#if defined(MBEDTLS_AESCE_C)
#include "aesce.h"
#if defined(MBEDTLS_HAVE_ARM64)
#if defined(__clang__)
# if __clang_major__ < 4
# error "A more recent Clang is required for MBEDTLS_AESCE_C"
# endif
#elif defined(__GNUC__)
# if __GNUC__ < 6
# error "A more recent GCC is required for MBEDTLS_AESCE_C"
# endif
#else
# error "Only GCC and Clang supported for MBEDTLS_AESCE_C"
#endif
#if !defined(__ARM_FEATURE_CRYPTO)
# error "`crypto` feature moddifier MUST be enabled for MBEDTLS_AESCE_C."
# error "Typical option for GCC and Clang is `-march=armv8-a+crypto`."
#endif /* !__ARM_FEATURE_CRYPTO */
#include <arm_neon.h>
#if defined(__linux__)
#include <asm/hwcap.h>
#include <sys/auxv.h>
#endif
/*
* AES instruction support detection routine
*/
int mbedtls_aesce_has_support(void)
{
#if defined(__linux__)
unsigned long auxval = getauxval(AT_HWCAP);
return (auxval & (HWCAP_ASIMD | HWCAP_AES)) ==
(HWCAP_ASIMD | HWCAP_AES);
#else
/* Assume AES instructions are supported. */
return 1;
#endif
}
static uint8x16_t aesce_encrypt_block(uint8x16_t block,
unsigned char *keys,
int rounds)
{
for (int i = 0; i < rounds - 1; i++) {
/* AES AddRoundKey, SubBytes, ShiftRows (in this order).
* AddRoundKey adds the round key for the previous round. */
block = vaeseq_u8(block, vld1q_u8(keys + i * 16));
/* AES mix columns */
block = vaesmcq_u8(block);
}
/* AES AddRoundKey for the previous round.
* SubBytes, ShiftRows for the final round. */
block = vaeseq_u8(block, vld1q_u8(keys + (rounds -1) * 16));
/* Final round: no MixColumns */
/* Final AddRoundKey */
block = veorq_u8(block, vld1q_u8(keys + rounds * 16));
return block;
}
static uint8x16_t aesce_decrypt_block(uint8x16_t block,
unsigned char *keys,
int rounds)
{
for (int i = 0; i < rounds - 1; i++) {
/* AES AddRoundKey, SubBytes, ShiftRows */
block = vaesdq_u8(block, vld1q_u8(keys + i * 16));
/* AES inverse MixColumns for the next round.
*
* This means that we switch the order of the inverse AddRoundKey and
* inverse MixColumns operations. We have to do this as AddRoundKey is
* done in an atomic instruction together with the inverses of SubBytes
* and ShiftRows.
*
* It works because MixColumns is a linear operation over GF(2^8) and
* AddRoundKey is an exclusive or, which is equivalent to addition over
* GF(2^8). (The inverse of MixColumns needs to be applied to the
* affected round keys separately which has been done when the
* decryption round keys were calculated.) */
block = vaesimcq_u8(block);
}
/* The inverses of AES AddRoundKey, SubBytes, ShiftRows finishing up the
* last full round. */
block = vaesdq_u8(block, vld1q_u8(keys + (rounds - 1) * 16));
/* Inverse AddRoundKey for inverting the initial round key addition. */
block = veorq_u8(block, vld1q_u8(keys + rounds * 16));
return block;
}
/*
* AES-ECB block en(de)cryption
*/
int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16])
{
uint8x16_t block = vld1q_u8(&input[0]);
unsigned char *keys = (unsigned char *) (ctx->buf + ctx->rk_offset);
if (mode == MBEDTLS_AES_ENCRYPT) {
block = aesce_encrypt_block(block, keys, ctx->nr);
} else {
block = aesce_decrypt_block(block, keys, ctx->nr);
}
vst1q_u8(&output[0], block);
return 0;
}
/*
* Compute decryption round keys from encryption round keys
*/
void mbedtls_aesce_inverse_key(unsigned char *invkey,
const unsigned char *fwdkey,
int nr)
{
int i, j;
j = nr;
vst1q_u8(invkey, vld1q_u8(fwdkey + j * 16));
for (i = 1, j--; j > 0; i++, j--) {
vst1q_u8(invkey + i * 16,
vaesimcq_u8(vld1q_u8(fwdkey + j * 16)));
}
vst1q_u8(invkey + i * 16, vld1q_u8(fwdkey + j * 16));
}
static inline uint32_t aes_rot_word(uint32_t word)
{
return (word << (32 - 8)) | (word >> 8);
}
static inline uint32_t aes_sub_word(uint32_t in)
{
uint8x16_t v = vreinterpretq_u8_u32(vdupq_n_u32(in));
uint8x16_t zero = vdupq_n_u8(0);
/* vaeseq_u8 does both SubBytes and ShiftRows. Taking the first row yields
* the correct result as ShiftRows doesn't change the first row. */
v = vaeseq_u8(zero, v);
return vgetq_lane_u32(vreinterpretq_u32_u8(v), 0);
}
/*
* Key expansion function
*/
static void aesce_setkey_enc(unsigned char *rk,
const unsigned char *key,
const size_t key_bit_length)
{
static uint8_t const rcon[] = { 0x01, 0x02, 0x04, 0x08, 0x10,
0x20, 0x40, 0x80, 0x1b, 0x36 };
/* See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf
* - Section 5, Nr = Nk + 6
* - Section 5.2, the key expansion size is Nb*(Nr+1)
*/
const uint32_t key_len_in_words = key_bit_length / 32; /* Nk */
const size_t round_key_len_in_words = 4; /* Nb */
const size_t round_keys_needed = key_len_in_words + 6; /* Nr */
const size_t key_expansion_size_in_words =
round_key_len_in_words * (round_keys_needed + 1); /* Nb*(Nr+1) */
const uint32_t *rko_end = (uint32_t *) rk + key_expansion_size_in_words;
memcpy(rk, key, key_len_in_words * 4);
for (uint32_t *rki = (uint32_t *) rk;
rki + key_len_in_words < rko_end;
rki += key_len_in_words) {
size_t iteration = (rki - (uint32_t *) rk) / key_len_in_words;
uint32_t *rko;
rko = rki + key_len_in_words;
rko[0] = aes_rot_word(aes_sub_word(rki[key_len_in_words - 1]));
rko[0] ^= rcon[iteration] ^ rki[0];
rko[1] = rko[0] ^ rki[1];
rko[2] = rko[1] ^ rki[2];
rko[3] = rko[2] ^ rki[3];
if (rko + key_len_in_words > rko_end) {
/* Do not write overflow words.*/
continue;
}
switch (key_bit_length) {
case 128:
break;
case 192:
rko[4] = rko[3] ^ rki[4];
rko[5] = rko[4] ^ rki[5];
break;
case 256:
rko[4] = aes_sub_word(rko[3]) ^ rki[4];
rko[5] = rko[4] ^ rki[5];
rko[6] = rko[5] ^ rki[6];
rko[7] = rko[6] ^ rki[7];
break;
}
}
}
/*
* Key expansion, wrapper
*/
int mbedtls_aesce_setkey_enc(unsigned char *rk,
const unsigned char *key,
size_t bits)
{
switch (bits) {
case 128:
case 192:
case 256:
aesce_setkey_enc(rk, key, bits);
break;
default:
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}
return 0;
}
#endif /* MBEDTLS_HAVE_ARM64 */
#endif /* MBEDTLS_AESCE_C */

98
library/aesce.h Normal file
View file

@ -0,0 +1,98 @@
/**
* \file aesce.h
*
* \brief AES-CE for hardware AES acceleration on ARMv8 processors with crypto
* extension.
*
* \warning These functions are only for internal use by other library
* functions; you must not call them directly.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBEDTLS_AESCE_H
#define MBEDTLS_AESCE_H
#include "mbedtls/build_info.h"
#include "mbedtls/aes.h"
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
defined(__aarch64__) && !defined(MBEDTLS_HAVE_ARM64)
#define MBEDTLS_HAVE_ARM64
#endif
#if defined(MBEDTLS_HAVE_ARM64)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Internal function to detect the crypto extension in CPUs.
*
* \return 1 if CPU has support for the feature, 0 otherwise
*/
int mbedtls_aesce_has_support(void);
/**
* \brief Internal AES-ECB block encryption and decryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 on success (cannot fail)
*/
int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16]);
/**
* \brief Internal round key inversion. This function computes
* decryption round keys from the encryption round keys.
*
* \param invkey Round keys for the equivalent inverse cipher
* \param fwdkey Original round keys (for encryption)
* \param nr Number of rounds (that is, number of round keys minus one)
*/
void mbedtls_aesce_inverse_key(unsigned char *invkey,
const unsigned char *fwdkey,
int nr);
/**
* \brief Internal key expansion for encryption
*
* \param rk Destination buffer where the round keys are written
* \param key Encryption key
* \param bits Key size in bits (must be 128, 192 or 256)
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aesce_setkey_enc(unsigned char *rk,
const unsigned char *key,
size_t bits);
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_HAVE_ARM64 */
#endif /* MBEDTLS_AESCE_H */

View file

@ -130,7 +130,7 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
* byte from x, where byte 0 is the least significant byte.
*/
#define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff))
#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff))
#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff))
#define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff))
#define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff))
#define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff))
@ -155,13 +155,13 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
* Detect Clang built-in byteswap routines
*/
#if defined(__clang__) && defined(__has_builtin)
#if __has_builtin(__builtin_bswap16)
#if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16)
#define MBEDTLS_BSWAP16 __builtin_bswap16
#endif /* __has_builtin(__builtin_bswap16) */
#if __has_builtin(__builtin_bswap32)
#if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32)
#define MBEDTLS_BSWAP32 __builtin_bswap32
#endif /* __has_builtin(__builtin_bswap32) */
#if __has_builtin(__builtin_bswap64)
#if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64)
#define MBEDTLS_BSWAP64 __builtin_bswap64
#endif /* __has_builtin(__builtin_bswap64) */
#endif /* defined(__clang__) && defined(__has_builtin) */
@ -170,13 +170,19 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
* Detect MSVC built-in byteswap routines
*/
#if defined(_MSC_VER)
#if !defined(MBEDTLS_BSWAP16)
#define MBEDTLS_BSWAP16 _byteswap_ushort
#endif
#if !defined(MBEDTLS_BSWAP32)
#define MBEDTLS_BSWAP32 _byteswap_ulong
#endif
#if !defined(MBEDTLS_BSWAP64)
#define MBEDTLS_BSWAP64 _byteswap_uint64
#endif
#endif /* defined(_MSC_VER) */
/* Detect armcc built-in byteswap routine */
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000)
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32)
#define MBEDTLS_BSWAP32 __rev
#endif
@ -239,8 +245,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the four bytes to build the 32 bits unsigned
* integer from.
*/
#define MBEDTLS_GET_UINT32_BE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
#define MBEDTLS_GET_UINT32_BE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
? mbedtls_get_unaligned_uint32((data) + (offset)) \
: MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
)
@ -254,11 +260,11 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* \param offset Offset from \p data where to put the most significant
* byte of the 32 bits unsigned integer \p n.
*/
#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \
#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \
{ \
if (MBEDTLS_IS_BIG_ENDIAN) \
if (MBEDTLS_IS_BIG_ENDIAN) \
{ \
mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \
mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \
} \
else \
{ \
@ -275,8 +281,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the four bytes to build the 32 bits unsigned
* integer from.
*/
#define MBEDTLS_GET_UINT32_LE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
#define MBEDTLS_GET_UINT32_LE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
: mbedtls_get_unaligned_uint32((data) + (offset)) \
)
@ -291,15 +297,15 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* \param offset Offset from \p data where to put the least significant
* byte of the 32 bits unsigned integer \p n.
*/
#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \
#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \
{ \
if (MBEDTLS_IS_BIG_ENDIAN) \
if (MBEDTLS_IS_BIG_ENDIAN) \
{ \
mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
} \
else \
{ \
mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \
mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \
} \
}
@ -312,8 +318,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the two bytes to build the 16 bits unsigned
* integer from.
*/
#define MBEDTLS_GET_UINT16_LE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
#define MBEDTLS_GET_UINT16_LE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
: mbedtls_get_unaligned_uint16((data) + (offset)) \
)
@ -327,15 +333,15 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* \param offset Offset from \p data where to put the least significant
* byte of the 16 bits unsigned integer \p n.
*/
#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \
#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \
{ \
if (MBEDTLS_IS_BIG_ENDIAN) \
if (MBEDTLS_IS_BIG_ENDIAN) \
{ \
mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
} \
else \
{ \
mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
} \
}
@ -348,8 +354,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the two bytes to build the 16 bits unsigned
* integer from.
*/
#define MBEDTLS_GET_UINT16_BE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
#define MBEDTLS_GET_UINT16_BE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
? mbedtls_get_unaligned_uint16((data) + (offset)) \
: MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
)
@ -363,11 +369,11 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* \param offset Offset from \p data where to put the most significant
* byte of the 16 bits unsigned integer \p n.
*/
#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \
#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \
{ \
if (MBEDTLS_IS_BIG_ENDIAN) \
if (MBEDTLS_IS_BIG_ENDIAN) \
{ \
mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
} \
else \
{ \
@ -384,11 +390,11 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the three bytes to build the 24 bits unsigned
* integer from.
*/
#define MBEDTLS_GET_UINT24_BE(data, offset) \
( \
((uint32_t) (data)[(offset)] << 16) \
| ((uint32_t) (data)[(offset) + 1] << 8) \
| ((uint32_t) (data)[(offset) + 2]) \
#define MBEDTLS_GET_UINT24_BE(data, offset) \
( \
((uint32_t) (data)[(offset)] << 16) \
| ((uint32_t) (data)[(offset) + 1] << 8) \
| ((uint32_t) (data)[(offset) + 2]) \
)
/**
@ -401,8 +407,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the 24 bits unsigned integer \p n.
*/
#define MBEDTLS_PUT_UINT24_BE(n, data, offset) \
{ \
(data)[(offset)] = MBEDTLS_BYTE_2(n); \
{ \
(data)[(offset)] = MBEDTLS_BYTE_2(n); \
(data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
(data)[(offset) + 2] = MBEDTLS_BYTE_0(n); \
}
@ -416,9 +422,9 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the three bytes to build the 24 bits unsigned
* integer from.
*/
#define MBEDTLS_GET_UINT24_LE(data, offset) \
( \
((uint32_t) (data)[(offset)]) \
#define MBEDTLS_GET_UINT24_LE(data, offset) \
( \
((uint32_t) (data)[(offset)]) \
| ((uint32_t) (data)[(offset) + 1] << 8) \
| ((uint32_t) (data)[(offset) + 2] << 16) \
)
@ -433,8 +439,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the 24 bits unsigned integer \p n.
*/
#define MBEDTLS_PUT_UINT24_LE(n, data, offset) \
{ \
(data)[(offset)] = MBEDTLS_BYTE_0(n); \
{ \
(data)[(offset)] = MBEDTLS_BYTE_0(n); \
(data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
(data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \
}
@ -448,8 +454,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the eight bytes to build the 64 bits unsigned
* integer from.
*/
#define MBEDTLS_GET_UINT64_BE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
#define MBEDTLS_GET_UINT64_BE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
? mbedtls_get_unaligned_uint64((data) + (offset)) \
: MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
)
@ -463,11 +469,11 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* \param offset Offset from \p data where to put the most significant
* byte of the 64 bits unsigned integer \p n.
*/
#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \
#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \
{ \
if (MBEDTLS_IS_BIG_ENDIAN) \
if (MBEDTLS_IS_BIG_ENDIAN) \
{ \
mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
} \
else \
{ \
@ -484,8 +490,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* byte of the eight bytes to build the 64 bits unsigned
* integer from.
*/
#define MBEDTLS_GET_UINT64_LE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
#define MBEDTLS_GET_UINT64_LE(data, offset) \
((MBEDTLS_IS_BIG_ENDIAN) \
? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
: mbedtls_get_unaligned_uint64((data) + (offset)) \
)
@ -499,15 +505,15 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 };
* \param offset Offset from \p data where to put the least significant
* byte of the 64 bits unsigned integer \p n.
*/
#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \
#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \
{ \
if (MBEDTLS_IS_BIG_ENDIAN) \
if (MBEDTLS_IS_BIG_ENDIAN) \
{ \
mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
} \
else \
{ \
mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
} \
}

View file

@ -1656,6 +1656,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
size_t window_bitsize;
size_t i, j, nblimbs;
size_t bufsize, nbits;
size_t exponent_bits_in_window = 0;
mbedtls_mpi_uint ei, mm, state;
mbedtls_mpi RR, T, W[(size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE], WW, Apos;
int neg;
@ -1829,7 +1830,6 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
nblimbs = E->n;
bufsize = 0;
nbits = 0;
size_t exponent_bits_in_window = 0;
state = 0;
while (1) {

View file

@ -98,14 +98,13 @@ int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx,
if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
}
#if SIZE_MAX > INT_MAX
/* This shouldn't be an issue because
* MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
* configuration, but make sure anyway. */
if (len > INT_MAX) {
return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
}
#endif
/* For backward compatibility with Mbed TLS <= 2.19, store the
* entropy nonce length in a field that already exists, but isn't

View file

@ -239,13 +239,13 @@ cleanup:
* Compute ECDSA signature of a hashed message (SEC1 4.1.3)
* Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
*/
static int ecdsa_sign_restartable(mbedtls_ecp_group *grp,
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
int (*f_rng_blind)(void *, unsigned char *, size_t),
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx)
int mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp,
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
int (*f_rng_blind)(void *, unsigned char *, size_t),
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx)
{
int ret, key_tries, sign_tries;
int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
@ -394,8 +394,8 @@ int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
/* Use the same RNG for both blinding and ephemeral key generation */
return ecdsa_sign_restartable(grp, r, s, d, buf, blen,
f_rng, p_rng, f_rng, p_rng, NULL);
return mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen,
f_rng, p_rng, f_rng, p_rng, NULL);
}
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
@ -406,13 +406,13 @@ int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
* note: The f_rng_blind parameter must not be NULL.
*
*/
static int ecdsa_sign_det_restartable(mbedtls_ecp_group *grp,
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
int (*f_rng_blind)(void *, unsigned char *, size_t),
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx)
int mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp,
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
int (*f_rng_blind)(void *, unsigned char *, size_t),
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_hmac_drbg_context rng_ctx;
@ -462,9 +462,9 @@ sign:
ret = mbedtls_ecdsa_sign(grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, p_rng);
#else
ret = ecdsa_sign_restartable(grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, p_rng,
f_rng_blind, p_rng_blind, rs_ctx);
ret = mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, p_rng,
f_rng_blind, p_rng_blind, rs_ctx);
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
cleanup:
@ -487,8 +487,8 @@ int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r,
size_t),
void *p_rng_blind)
{
return ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg,
f_rng_blind, p_rng_blind, NULL);
return mbedtls_ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg,
f_rng_blind, p_rng_blind, NULL);
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@ -497,11 +497,12 @@ int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r,
* Verify ECDSA signature of hashed message (SEC1 4.1.4)
* Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
*/
static int ecdsa_verify_restartable(mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *r, const mbedtls_mpi *s,
mbedtls_ecdsa_restart_ctx *rs_ctx)
int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *r,
const mbedtls_mpi *s,
mbedtls_ecdsa_restart_ctx *rs_ctx)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi e, s_inv, u1, u2;
@ -610,7 +611,7 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
const mbedtls_mpi *r,
const mbedtls_mpi *s)
{
return ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL);
return mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL);
}
#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
@ -665,9 +666,9 @@ int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
mbedtls_mpi_init(&s);
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
MBEDTLS_MPI_CHK(ecdsa_sign_det_restartable(&ctx->grp, &r, &s, &ctx->d,
hash, hlen, md_alg, f_rng,
p_rng, rs_ctx));
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_restartable(&ctx->grp, &r, &s, &ctx->d,
hash, hlen, md_alg, f_rng,
p_rng, rs_ctx));
#else
(void) md_alg;
@ -678,9 +679,9 @@ int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
hash, hlen, f_rng, p_rng));
#else
/* Use the same RNG for both blinding and ephemeral key generation */
MBEDTLS_MPI_CHK(ecdsa_sign_restartable(&ctx->grp, &r, &s, &ctx->d,
hash, hlen, f_rng, p_rng, f_rng,
p_rng, rs_ctx));
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_restartable(&ctx->grp, &r, &s, &ctx->d,
hash, hlen, f_rng, p_rng, f_rng,
p_rng, rs_ctx));
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@ -760,8 +761,8 @@ int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx,
goto cleanup;
}
#else
if ((ret = ecdsa_verify_restartable(&ctx->grp, hash, hlen,
&ctx->Q, &r, &s, rs_ctx)) != 0) {
if ((ret = mbedtls_ecdsa_verify_restartable(&ctx->grp, hash, hlen,
&ctx->Q, &r, &s, rs_ctx)) != 0) {
goto cleanup;
}
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */

View file

@ -4570,6 +4570,8 @@ static int ecp_group_load(mbedtls_ecp_group *grp,
/* Forward declarations */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
static int ecp_mod_p192(mbedtls_mpi *);
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn);
#endif
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
static int ecp_mod_p224(mbedtls_mpi *);
@ -4582,6 +4584,8 @@ static int ecp_mod_p384(mbedtls_mpi *);
#endif
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
static int ecp_mod_p521(mbedtls_mpi *);
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n);
#endif
#define NIST_MODP(P) grp->modp = ecp_mod_ ## P;
@ -4884,10 +4888,12 @@ static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry)
}
#define WIDTH 8 / sizeof(mbedtls_mpi_uint)
#define A(i) N->p + (i) * WIDTH
#define ADD(i) add64(p, A(i), &c)
#define A(i) Np + (i) * WIDTH
#define ADD(i) add64(p, A(i), &c)
#define NEXT p += WIDTH; carry64(p, &c)
#define LAST p += WIDTH; *p = c; while (++p < end) *p = 0
#define RESET last_carry[0] = c; c = 0; p = Np
#define ADD_LAST add64(p, last_carry, &c)
/*
* Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
@ -4895,28 +4901,51 @@ 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;
mbedtls_mpi_uint c = 0;
mbedtls_mpi_uint *p, *end;
/* Make sure we have enough blocks so that A(5) is legal */
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, 6 * WIDTH));
p = N->p;
end = p + N->n;
ADD(3); ADD(5); NEXT; // A0 += A3 + A5
ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5
ADD(4); ADD(5); LAST; // A2 += A4 + A5
size_t expected_width = 2 * ((192 + biL - 1) / biL);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
ret = mbedtls_ecp_mod_p192_raw(N->p, expected_width);
cleanup:
return ret;
}
MBEDTLS_STATIC_TESTABLE
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)) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
p = Np;
end = p + Nn;
ADD(3); ADD(5); NEXT; // A0 += A3 + A5
ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5
ADD(4); ADD(5); // A2 += A4 + A5
RESET;
/* Use the reduction for the carry as well:
* 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192
*/
ADD_LAST; NEXT; // A0 += last_carry
ADD_LAST; NEXT; // A1 += last_carry
LAST; // A2 += carry
return 0;
}
#undef WIDTH
#undef A
#undef ADD
#undef NEXT
#undef LAST
#undef RESET
#undef ADD_LAST
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
@ -5162,11 +5191,6 @@ cleanup:
MBEDTLS_ECP_DP_SECP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
/*
* Here we have an actual Mersenne prime, so things are more straightforward.
* However, chunks are aligned on a 'weird' boundary (521 bits).
*/
/* Size of p521 in terms of mbedtls_mpi_uint */
#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1)
@ -5174,48 +5198,81 @@ cleanup:
#define P521_MASK 0x01FF
/*
* Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
* Write N as A1 + 2^521 A0, return A0 + A1
* Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5)
*/
static int ecp_mod_p521(mbedtls_mpi *N)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M;
mbedtls_mpi_uint Mp[P521_WIDTH + 1];
/* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
* we need to hold bits 513 to 1056, which is 34 limbs, that is
* P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
if (N->n < P521_WIDTH) {
return 0;
}
/* M = A1 */
M.s = 1;
M.n = N->n - (P521_WIDTH - 1);
if (M.n > P521_WIDTH + 1) {
M.n = P521_WIDTH + 1;
}
M.p = Mp;
memcpy(Mp, N->p + P521_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 521 % (8 * sizeof(mbedtls_mpi_uint))));
/* N = A0 */
N->p[P521_WIDTH - 1] &= P521_MASK;
for (i = P521_WIDTH; i < N->n; i++) {
N->p[i] = 0;
}
/* N = A0 + A1 */
MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
size_t expected_width = 2 * P521_WIDTH;
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
ret = mbedtls_ecp_mod_p521_raw(N->p, expected_width);
cleanup:
return ret;
}
MBEDTLS_STATIC_TESTABLE
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) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
/* Step 1: Reduction to P521_WIDTH limbs */
/* Helper references for bottom part of X */
mbedtls_mpi_uint *X0 = X;
size_t X0_limbs = P521_WIDTH;
/* Helper references for top part of X */
mbedtls_mpi_uint *X1 = X + X0_limbs;
size_t X1_limbs = X_limbs - X0_limbs;
/* Split X as X0 + 2^P521_WIDTH X1 and compute X0 + 2^(biL - 9) X1.
* (We are using that 2^P521_WIDTH = 2^(512 + biL) and that
* 2^(512 + biL) X1 = 2^(biL - 9) X1 mod P521.)
* The high order limb of the result will be held in carry and the rest
* in X0 (that is the result will be represented as
* 2^P521_WIDTH carry + X0).
*
* Also, note that the resulting carry is either 0 or 1:
* X0 < 2^P521_WIDTH = 2^(512 + biL) and X1 < 2^(P521_WIDTH-biL) = 2^512
* therefore
* X0 + 2^(biL - 9) X1 < 2^(512 + biL) + 2^(512 + biL - 9)
* which in turn is less than 2 * 2^(512 + biL).
*/
mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9);
carry = mbedtls_mpi_core_mla(X0, X0_limbs, X1, X1_limbs, shift);
/* Set X to X0 (by clearing the top part). */
memset(X1, 0, X1_limbs * sizeof(mbedtls_mpi_uint));
/* Step 2: Reduction modulo P521
*
* At this point X is reduced to P521_WIDTH limbs. What remains is to add
* the carry (that is 2^P521_WIDTH carry) and to reduce mod P521. */
/* 2^P521_WIDTH carry = 2^(512 + biL) carry = 2^(biL - 9) carry mod P521.
* Also, recall that carry is either 0 or 1. */
mbedtls_mpi_uint addend = carry << (biL - 9);
/* Keep the top 9 bits and reduce the rest, using 2^521 = 1 mod P521. */
addend += (X[P521_WIDTH - 1] >> 9);
X[P521_WIDTH - 1] &= P521_MASK;
/* Resuse the top part of X (already zeroed) as a helper array for
* carrying out the addition. */
mbedtls_mpi_uint *addend_arr = X + P521_WIDTH;
addend_arr[0] = addend;
(void) mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH);
/* Both addends were less than P521 therefore X < 2 * P521. (This also means
* that the result fit in P521_WIDTH limbs and there won't be any carry.) */
/* Clear the reused part of X. */
addend_arr[0] = 0;
return 0;
}
#undef P521_WIDTH
#undef P521_MASK
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
#endif /* MBEDTLS_ECP_NIST_OPTIM */
@ -5477,6 +5534,188 @@ static int ecp_mod_p256k1(mbedtls_mpi *N)
}
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
#endif /* !MBEDTLS_ECP_ALT */
#if defined(MBEDTLS_TEST_HOOKS)
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N,
const mbedtls_ecp_group_id id,
const mbedtls_ecp_curve_type ctype)
{
mbedtls_mpi_uint *p = NULL;
size_t p_limbs;
if (!(ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE || \
ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_SCALAR)) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
switch (id) {
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
case MBEDTLS_ECP_DP_SECP192R1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) secp192r1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(secp192r1_p));
} else {
p = (mbedtls_mpi_uint *) secp192r1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(secp192r1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
case MBEDTLS_ECP_DP_SECP224R1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) secp224r1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(secp224r1_p));
} else {
p = (mbedtls_mpi_uint *) secp224r1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(secp224r1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
case MBEDTLS_ECP_DP_SECP256R1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) secp256r1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(secp256r1_p));
} else {
p = (mbedtls_mpi_uint *) secp256r1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(secp256r1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
case MBEDTLS_ECP_DP_SECP384R1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) secp384r1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(secp384r1_p));
} else {
p = (mbedtls_mpi_uint *) secp384r1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(secp384r1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
case MBEDTLS_ECP_DP_SECP521R1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) secp521r1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(secp521r1_p));
} else {
p = (mbedtls_mpi_uint *) secp521r1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(secp521r1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
case MBEDTLS_ECP_DP_BP256R1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) brainpoolP256r1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP256r1_p));
} else {
p = (mbedtls_mpi_uint *) brainpoolP256r1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP256r1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
case MBEDTLS_ECP_DP_BP384R1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) brainpoolP384r1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP384r1_p));
} else {
p = (mbedtls_mpi_uint *) brainpoolP384r1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP384r1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
case MBEDTLS_ECP_DP_BP512R1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) brainpoolP512r1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP512r1_p));
} else {
p = (mbedtls_mpi_uint *) brainpoolP512r1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP512r1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
case MBEDTLS_ECP_DP_CURVE25519:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) curve25519_p;
p_limbs = CHARS_TO_LIMBS(sizeof(curve25519_p));
} else {
p = (mbedtls_mpi_uint *) curve25519_n;
p_limbs = CHARS_TO_LIMBS(sizeof(curve25519_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
case MBEDTLS_ECP_DP_SECP192K1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) secp192k1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_p));
} else {
p = (mbedtls_mpi_uint *) secp192k1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
case MBEDTLS_ECP_DP_SECP224K1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) secp224k1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_p));
} else {
p = (mbedtls_mpi_uint *) secp224k1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
case MBEDTLS_ECP_DP_SECP256K1:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) secp256k1_p;
p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_p));
} else {
p = (mbedtls_mpi_uint *) secp256k1_n;
p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_n));
}
break;
#endif
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
case MBEDTLS_ECP_DP_CURVE448:
if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) {
p = (mbedtls_mpi_uint *) curve448_p;
p_limbs = CHARS_TO_LIMBS(sizeof(curve448_p));
} else {
p = (mbedtls_mpi_uint *) curve448_n;
p_limbs = CHARS_TO_LIMBS(sizeof(curve448_n));
}
break;
#endif
default:
case MBEDTLS_ECP_DP_NONE:
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
if (mbedtls_mpi_mod_modulus_setup(N, p, p_limbs,
MBEDTLS_MPI_MOD_REP_MONTGOMERY)) {
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
return 0;
}
#endif /* MBEDTLS_TEST_HOOKS */
#endif /* !MBEDTLS_ECP_ALT */
#endif /* MBEDTLS_ECP_C */

View file

@ -28,6 +28,7 @@
#include "common.h"
#include "mbedtls/bignum.h"
#include "bignum_mod.h"
#include "mbedtls/ecp.h"
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_C)
@ -76,6 +77,69 @@ int mbedtls_ecp_gen_privkey_mx(size_t n_bits,
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
/** Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
*
* This operation expects a 384 bit MPI and the result of the reduction
* is a 192 bit MPI.
*
* \param[in,out] Np The address of the MPI to be converted.
* Must have twice as many limbs as the modulus.
* Upon return this holds the reduced value. The bitlength
* of the reduced value is the same as that of the modulus
* (192 bits).
* \param[in] Nn The length of \p Np in limbs.
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn);
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
/** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5)
*
* \param[in,out] X The address of the MPI to be converted.
* Must have twice as many limbs as the modulus
* (the modulus is 521 bits long). Upon return this
* holds the reduced value. The reduced value is
* in range `0 <= X < 2 * N` (where N is the modulus).
* and its the bitlength is one plus the bitlength
* of the modulus.
* \param[in] X_limbs The length of \p X in limbs.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs does not have
* twice as many limbs as the modulus.
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
/** Initialise a modulus with hard-coded const curve data.
*
* \note The caller is responsible for the \p N modulus' memory.
* mbedtls_mpi_mod_modulus_free(&N) should be invoked at the
* end of its lifecycle.
*
* \param[in,out] N The address of the modulus structure to populate.
* Must be initialized.
* \param[in] id The mbedtls_ecp_group_id for which to initialise the modulus.
* \param[in] ctype The mbedtls_ecp_curve_type identifier for a coordinate modulus (P)
* or a scalar modulus (N).
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the given MPIs do not
* have the correct number of limbs.
*
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N,
const mbedtls_ecp_group_id id,
const mbedtls_ecp_curve_type ctype);
#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */
#endif /* MBEDTLS_ECP_INVASIVE_H */

View file

@ -26,6 +26,7 @@
#include "mbedtls/oid.h"
#include "mbedtls/rsa.h"
#include "mbedtls/error.h"
#include "mbedtls/pk.h"
#include "mbedtls/legacy_or_psa.h"
@ -427,7 +428,7 @@ static const oid_sig_alg_t oid_sig_alg[] =
},
#endif /* MBEDTLS_HAS_ALG_SHA_1_VIA_LOWLEVEL_OR_PSA */
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECDSA_C)
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
#if defined(MBEDTLS_HAS_ALG_SHA_1_VIA_LOWLEVEL_OR_PSA)
{
OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA1, "ecdsa-with-SHA1", "ECDSA with SHA1"),
@ -458,7 +459,7 @@ static const oid_sig_alg_t oid_sig_alg[] =
MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA,
},
#endif /* MBEDTLS_HAS_ALG_SHA_512_VIA_LOWLEVEL_OR_PSA */
#endif /* MBEDTLS_ECDSA_C */
#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
#if defined(MBEDTLS_RSA_C)
{
OID_DESCRIPTOR(MBEDTLS_OID_RSASSA_PSS, "RSASSA-PSS", "RSASSA-PSS"),
@ -833,21 +834,55 @@ int mbedtls_oid_get_numeric_string(char *buf, size_t size,
p = buf;
n = size;
/* First byte contains first two dots */
if (oid->len > 0) {
ret = mbedtls_snprintf(p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40);
OID_SAFE_SNPRINTF;
/* First subidentifier contains first two OID components */
i = 0;
value = 0;
if ((oid->p[0]) == 0x80) {
/* Overlong encoding is not allowed */
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
value = 0;
for (i = 1; i < oid->len; i++) {
while (i < oid->len && ((oid->p[i] & 0x80) != 0)) {
/* Prevent overflow in value. */
if (((value << 7) >> 7) != value) {
return MBEDTLS_ERR_OID_BUF_TOO_SMALL;
if (value > (UINT_MAX >> 7)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
value |= oid->p[i] & 0x7F;
value <<= 7;
i++;
}
if (i >= oid->len) {
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
}
/* Last byte of first subidentifier */
value |= oid->p[i] & 0x7F;
i++;
unsigned int component1 = value / 40;
if (component1 > 2) {
/* The first component can only be 0, 1 or 2.
* If oid->p[0] / 40 is greater than 2, the leftover belongs to
* the second component. */
component1 = 2;
}
unsigned int component2 = value - (40 * component1);
ret = mbedtls_snprintf(p, n, "%u.%u", component1, component2);
OID_SAFE_SNPRINTF;
value = 0;
for (; i < oid->len; i++) {
/* Prevent overflow in value. */
if (value > (UINT_MAX >> 7)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
if ((value == 0) && ((oid->p[i]) == 0x80)) {
/* Overlong encoding is not allowed */
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
value <<= 7;
value += oid->p[i] & 0x7F;
value |= oid->p[i] & 0x7F;
if (!(oid->p[i] & 0x80)) {
/* Last byte */

View file

@ -114,7 +114,7 @@ const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
case MBEDTLS_PK_ECKEY_DH:
return &mbedtls_eckeydh_info;
#endif
#if defined(MBEDTLS_ECDSA_C)
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
case MBEDTLS_PK_ECDSA:
return &mbedtls_ecdsa_info;
#endif
@ -501,11 +501,9 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_pk_rsassa_pss_options *pss_opts;
#if SIZE_MAX > UINT_MAX
if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
#endif /* SIZE_MAX > UINT_MAX */
if (options == NULL) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;

File diff suppressed because it is too large Load diff

View file

@ -125,7 +125,7 @@ extern const mbedtls_pk_info_t mbedtls_eckey_info;
extern const mbedtls_pk_info_t mbedtls_eckeydh_info;
#endif
#if defined(MBEDTLS_ECDSA_C)
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
extern const mbedtls_pk_info_t mbedtls_ecdsa_info;
#endif

View file

@ -26,9 +26,6 @@
#include "mbedtls/oid.h"
#include "mbedtls/error.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if defined(MBEDTLS_FS_IO)
#include <sys/types.h>
#include <sys/stat.h>
@ -60,7 +57,10 @@ static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end,
ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_CONTEXT_SPECIFIC);
if (ret != 0) {
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
} else if ((size_t) (end - *p) != *len) {
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
return ret;
@ -94,6 +94,7 @@ static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver)
* [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
**/
static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
unsigned char **seq_end,
mbedtls_pkcs7_buf *pkcs7)
{
size_t len = 0;
@ -106,8 +107,8 @@ static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
*p = start;
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
}
ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OID);
*seq_end = *p + len;
ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID);
if (ret != 0) {
*p = start;
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
@ -186,13 +187,13 @@ static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
size_t len2 = 0;
unsigned char *end_set, *end_cert, *start;
if ((ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_CONTEXT_SPECIFIC)) != 0) {
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
return 0;
} else {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
}
ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_CONTEXT_SPECIFIC);
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
return 0;
}
if (ret != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
}
start = *p;
end_set = *p + len1;
@ -215,12 +216,11 @@ static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
}
*p = start;
if ((ret = mbedtls_x509_crt_parse_der(certs, *p, len1)) < 0) {
if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) {
return MBEDTLS_ERR_PKCS7_INVALID_CERT;
}
*p = *p + len1;
*p = end_cert;
/*
* Since in this version we strictly support single certificate, and reaching
@ -287,9 +287,10 @@ static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
* and unauthenticatedAttributes.
**/
static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
mbedtls_pkcs7_signer_info *signer)
mbedtls_pkcs7_signer_info *signer,
mbedtls_x509_buf *alg)
{
unsigned char *end_signer;
unsigned char *end_signer, *end_issuer_and_sn;
int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
@ -312,10 +313,11 @@ static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
goto out;
}
end_issuer_and_sn = *p + len;
/* Parsing IssuerAndSerialNumber */
signer->issuer_raw.p = *p;
asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len,
asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
if (asn1_ret != 0) {
goto out;
@ -328,18 +330,31 @@ static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
signer->issuer_raw.len = *p - signer->issuer_raw.p;
ret = mbedtls_x509_get_serial(p, end_signer, &signer->serial);
ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
if (ret != 0) {
goto out;
}
/* ensure no extra or missing bytes */
if (*p != end_issuer_and_sn) {
ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
goto out;
}
ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier);
if (ret != 0) {
goto out;
}
/* Assume authenticatedAttributes is nonexistent */
/* Check that the digest algorithm used matches the one provided earlier */
if (signer->alg_identifier.tag != alg->tag ||
signer->alg_identifier.len != alg->len ||
memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) {
ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
goto out;
}
/* Asssume authenticatedAttributes is nonexistent */
ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
if (ret != 0) {
goto out;
@ -372,7 +387,8 @@ out:
* Return negative error code for failure.
**/
static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
mbedtls_pkcs7_signer_info *signers_set)
mbedtls_pkcs7_signer_info *signers_set,
mbedtls_x509_buf *digest_alg)
{
unsigned char *end_set;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -392,7 +408,7 @@ static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
end_set = *p + len;
ret = pkcs7_get_signer_info(p, end_set, signers_set);
ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg);
if (ret != 0) {
return ret;
}
@ -407,7 +423,7 @@ static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
goto cleanup;
}
ret = pkcs7_get_signer_info(p, end_set, signer);
ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg);
if (ret != 0) {
mbedtls_free(signer);
goto cleanup;
@ -449,7 +465,7 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
{
unsigned char *p = buf;
unsigned char *end = buf + buflen;
unsigned char *end_set;
unsigned char *end_content_info = NULL;
size_t len = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_alg;
@ -460,16 +476,19 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
}
end_set = p + len;
if (p + len != end) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
/* Get version of signed data */
ret = pkcs7_get_version(&p, end_set, &signed_data->version);
ret = pkcs7_get_version(&p, end, &signed_data->version);
if (ret != 0) {
return ret;
}
/* Get digest algorithm */
ret = pkcs7_get_digest_algorithm_set(&p, end_set,
ret = pkcs7_get_digest_algorithm_set(&p, end,
&signed_data->digest_alg_identifiers);
if (ret != 0) {
return ret;
@ -480,19 +499,36 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
return MBEDTLS_ERR_PKCS7_INVALID_ALG;
}
/* Do not expect any content */
ret = pkcs7_get_content_info_type(&p, end_set, &signed_data->content.oid);
mbedtls_pkcs7_buf content_type;
memset(&content_type, 0, sizeof(content_type));
ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type);
if (ret != 0) {
return ret;
}
if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &signed_data->content.oid)) {
if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) {
return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
}
if (p != end_content_info) {
/* Determine if valid content is present */
ret = mbedtls_asn1_get_tag(&p,
end_content_info,
&len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
if (ret != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
}
p += len;
if (p != end_content_info) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
}
/* Valid content is present - this is not supported */
return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
}
/* Look for certificates, there may or may not be any */
mbedtls_x509_crt_init(&signed_data->certs);
ret = pkcs7_get_certificates(&p, end_set, &signed_data->certs);
ret = pkcs7_get_certificates(&p, end, &signed_data->certs);
if (ret < 0) {
return ret;
}
@ -508,7 +544,10 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
signed_data->no_of_crls = 0;
/* Get signers info */
ret = pkcs7_get_signers_info_set(&p, end_set, &signed_data->signers);
ret = pkcs7_get_signers_info_set(&p,
end,
&signed_data->signers,
&signed_data->digest_alg_identifiers);
if (ret < 0) {
return ret;
}
@ -530,7 +569,6 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
unsigned char *end;
size_t len = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int isoidset = 0;
if (pkcs7 == NULL) {
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
@ -546,46 +584,63 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
pkcs7->raw.len = buflen;
end = p + buflen;
ret = pkcs7_get_content_info_type(&p, end, &pkcs7->content_type_oid);
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE);
if (ret != 0) {
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
goto out;
}
if ((size_t) (end - p) != len) {
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
goto out;
}
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
goto out;
}
p = pkcs7->raw.p;
len = buflen;
goto try_data;
}
if (!MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &pkcs7->content_type_oid)
|| !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid)
|| !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, &pkcs7->content_type_oid)
|| !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, &pkcs7->content_type_oid)
|| !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DIGESTED_DATA, &pkcs7->content_type_oid)
|| !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid)) {
ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) {
/* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported feature */
if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len)
|| !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len)
|| !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len)
|| !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len)
|| !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) {
/* OID is valid according to the spec, but unsupported */
ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
} else {
/* OID is invalid according to the spec */
ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
}
goto out;
}
if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_SIGNED_DATA, &pkcs7->content_type_oid)) {
ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
goto out;
}
isoidset = 1;
p += len;
ret = pkcs7_get_next_content_len(&p, end, &len);
if (ret != 0) {
goto out;
}
/* ensure no extra/missing data */
if (p + len != end) {
ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
goto out;
}
try_data:
ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data);
if (ret != 0) {
goto out;
}
if (!isoidset) {
pkcs7->content_type_oid.tag = MBEDTLS_ASN1_OID;
pkcs7->content_type_oid.len = MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS7_SIGNED_DATA);
pkcs7->content_type_oid.p = (unsigned char *) MBEDTLS_OID_PKCS7_SIGNED_DATA;
}
ret = MBEDTLS_PKCS7_SIGNED_DATA;
out:
@ -618,6 +673,39 @@ static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
}
ret = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg);
if (ret != 0) {
return ret;
}
md_info = mbedtls_md_info_from_type(md_alg);
if (md_info == NULL) {
return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
}
hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
if (hash == NULL) {
return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
}
/* BEGIN must free hash before jumping out */
if (is_data_hash) {
if (datalen != mbedtls_md_get_size(md_info)) {
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
} else {
memcpy(hash, data, datalen);
}
} else {
ret = mbedtls_md(md_info, data, datalen, hash);
}
if (ret != 0) {
mbedtls_free(hash);
return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
}
/* assume failure */
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
/*
* Potential TODOs
* Currently we iterate over all signers and return success if any of them
@ -627,61 +715,30 @@ static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
* identification and SignerIdentifier fields first. That would also allow
* us to distinguish between 'no signature for key' and 'signature for key
* failed to validate'.
*
* We could also cache hashes by md, so if there are several sigs all using
* the same algo we don't recalculate the hash each time.
*/
for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
ret = mbedtls_oid_get_md_alg(&signer->alg_identifier, &md_alg);
if (ret != 0) {
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
continue;
}
md_info = mbedtls_md_info_from_type(md_alg);
if (md_info == NULL) {
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
continue;
}
hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
if (hash == NULL) {
return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
}
/* BEGIN must free hash before jumping out */
if (is_data_hash) {
if (datalen != mbedtls_md_get_size(md_info)) {
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
} else {
memcpy(hash, data, datalen);
}
} else {
ret = mbedtls_md(md_info, data, datalen, hash);
}
if (ret != 0) {
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
mbedtls_free(hash);
continue;
}
ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash,
mbedtls_md_get_size(md_info),
signer->sig.p, signer->sig.len);
mbedtls_free(hash);
/* END must free hash before jumping out */
if (ret == 0) {
break;
}
}
mbedtls_free(hash);
/* END must free hash before jumping out */
return ret;
}
int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
const mbedtls_x509_crt *cert,
const unsigned char *data,
size_t datalen)
{
if (data == NULL) {
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
}
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
}
@ -690,6 +747,9 @@ int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
const unsigned char *hash,
size_t hashlen)
{
if (hash == NULL) {
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
}
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
}

View file

@ -81,6 +81,7 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "hash_info.h"
#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array)))
@ -310,6 +311,9 @@ psa_status_t mbedtls_to_psa_error(int ret)
case MBEDTLS_ERR_ECP_RANDOM_FAILED:
return PSA_ERROR_INSUFFICIENT_ENTROPY;
case MBEDTLS_ERR_ECP_IN_PROGRESS:
return PSA_OPERATION_INCOMPLETE;
case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
return PSA_ERROR_CORRUPTION_DETECTED;
@ -318,6 +322,44 @@ psa_status_t mbedtls_to_psa_error(int ret)
}
}
/**
* \brief For output buffers which contain "tags"
* (outputs that may be checked for validity like
* hashes, MACs and signatures), fill the unused
* part of the output buffer (the whole buffer on
* error, the trailing part on success) with
* something that isn't a valid tag (barring an
* attack on the tag and deliberately-crafted
* input), in case the caller doesn't check the
* return status properly.
*
* \param output_buffer Pointer to buffer to wipe. May not be NULL
* unless \p output_buffer_size is zero.
* \param status Status of function called to generate
* output_buffer originally
* \param output_buffer_size Size of output buffer. If zero, \p output_buffer
* could be NULL.
* \param output_buffer_length Length of data written to output_buffer, must be
* less than \p output_buffer_size
*/
static void psa_wipe_tag_output_buffer(uint8_t *output_buffer, psa_status_t status,
size_t output_buffer_size, size_t output_buffer_length)
{
size_t offset = 0;
if (output_buffer_size == 0) {
/* If output_buffer_size is 0 then we have nothing to do. We must not
call memset because output_buffer may be NULL in this case */
return;
}
if (status == PSA_SUCCESS) {
offset = output_buffer_length;
}
memset(output_buffer + offset, '!', output_buffer_size - offset);
}
@ -1673,12 +1715,12 @@ static psa_status_t psa_start_key_creation(
*
* \retval #PSA_SUCCESS
* The key was successfully created.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_ALREADY_EXISTS
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
*
* \return If this function fails, the key slot is an invalid state.
* You must call psa_fail_key_creation() to wipe and free the slot.
@ -2500,10 +2542,7 @@ exit:
operation->mac_size = 0;
}
if (mac_size > operation->mac_size) {
memset(&mac[operation->mac_size], '!',
mac_size - operation->mac_size);
}
psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length);
abort_status = psa_mac_abort(operation);
@ -2597,9 +2636,8 @@ exit:
*mac_length = mac_size;
operation_mac_size = 0;
}
if (mac_size > operation_mac_size) {
memset(&mac[operation_mac_size], '!', mac_size - operation_mac_size);
}
psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length);
unlock_status = psa_unlock_key_slot(slot);
@ -2741,18 +2779,8 @@ static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key,
exit:
/* Fill the unused part of the output buffer (the whole buffer on error,
* the trailing part on success) with something that isn't a valid signature
* (barring an attack on the signature and deliberately-crafted input),
* in case the caller doesn't check the return status properly. */
if (status == PSA_SUCCESS) {
memset(signature + *signature_length, '!',
signature_size - *signature_length);
} else {
memset(signature, '!', signature_size);
}
/* If signature_size is 0 then we have nothing to do. We must not call
* memset because signature may be NULL in this case. */
psa_wipe_tag_output_buffer(signature, status, signature_size,
*signature_length);
unlock_status = psa_unlock_key_slot(slot);
@ -3124,7 +3152,756 @@ exit:
return (status == PSA_SUCCESS) ? unlock_status : status;
}
/****************************************************************/
/* Asymmetric interruptible cryptography */
/****************************************************************/
static uint32_t psa_interruptible_max_ops = PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED;
void psa_interruptible_set_max_ops(uint32_t max_ops)
{
psa_interruptible_max_ops = max_ops;
}
uint32_t psa_interruptible_get_max_ops(void)
{
return psa_interruptible_max_ops;
}
uint32_t psa_sign_hash_get_num_ops(
const psa_sign_hash_interruptible_operation_t *operation)
{
return operation->num_ops;
}
uint32_t psa_verify_hash_get_num_ops(
const psa_verify_hash_interruptible_operation_t *operation)
{
return operation->num_ops;
}
static psa_status_t psa_sign_hash_abort_internal(
psa_sign_hash_interruptible_operation_t *operation)
{
if (operation->id == 0) {
/* The object has (apparently) been initialized but it is not (yet)
* in use. It's ok to call abort on such an object, and there's
* nothing to do. */
return PSA_SUCCESS;
}
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_driver_wrapper_sign_hash_abort(operation);
operation->id = 0;
/* Do not clear either the error_occurred or num_ops elements here as they
* only want to be cleared by the application calling abort, not by abort
* being called at completion of an operation. */
return status;
}
psa_status_t psa_sign_hash_start(
psa_sign_hash_interruptible_operation_t *operation,
mbedtls_svc_key_id_t key, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
/* Check that start has not been previously called, or operation has not
* previously errored. */
if (operation->id != 0 || operation->error_occurred) {
return PSA_ERROR_BAD_STATE;
}
status = psa_sign_verify_check_alg(0, alg);
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
return status;
}
status = psa_get_and_lock_key_slot_with_policy(key, &slot,
PSA_KEY_USAGE_SIGN_HASH,
alg);
if (status != PSA_SUCCESS) {
goto exit;
}
if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) {
status = PSA_ERROR_INVALID_ARGUMENT;
goto exit;
}
psa_key_attributes_t attributes = {
.core = slot->attr
};
/* Ensure ops count gets reset, in case of operation re-use. */
operation->num_ops = 0;
status = psa_driver_wrapper_sign_hash_start(operation, &attributes,
slot->key.data,
slot->key.bytes, alg,
hash, hash_length);
exit:
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
psa_sign_hash_abort_internal(operation);
}
unlock_status = psa_unlock_key_slot(slot);
if (unlock_status != PSA_SUCCESS) {
operation->error_occurred = 1;
}
return (status == PSA_SUCCESS) ? unlock_status : status;
}
psa_status_t psa_sign_hash_complete(
psa_sign_hash_interruptible_operation_t *operation,
uint8_t *signature, size_t signature_size,
size_t *signature_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
*signature_length = 0;
/* Check that start has been called first, and that operation has not
* previously errored. */
if (operation->id == 0 || operation->error_occurred) {
status = PSA_ERROR_BAD_STATE;
goto exit;
}
/* Immediately reject a zero-length signature buffer. This guarantees that
* signature must be a valid pointer. */
if (signature_size == 0) {
status = PSA_ERROR_BUFFER_TOO_SMALL;
goto exit;
}
status = psa_driver_wrapper_sign_hash_complete(operation, signature,
signature_size,
signature_length);
/* Update ops count with work done. */
operation->num_ops = psa_driver_wrapper_sign_hash_get_num_ops(operation);
exit:
psa_wipe_tag_output_buffer(signature, status, signature_size,
*signature_length);
if (status != PSA_OPERATION_INCOMPLETE) {
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
}
psa_sign_hash_abort_internal(operation);
}
return status;
}
psa_status_t psa_sign_hash_abort(
psa_sign_hash_interruptible_operation_t *operation)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_sign_hash_abort_internal(operation);
/* We clear the number of ops done here, so that it is not cleared when
* the operation fails or succeeds, only on manual abort. */
operation->num_ops = 0;
/* Likewise, failure state. */
operation->error_occurred = 0;
return status;
}
static psa_status_t psa_verify_hash_abort_internal(
psa_verify_hash_interruptible_operation_t *operation)
{
if (operation->id == 0) {
/* The object has (apparently) been initialized but it is not (yet)
* in use. It's ok to call abort on such an object, and there's
* nothing to do. */
return PSA_SUCCESS;
}
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_driver_wrapper_verify_hash_abort(operation);
operation->id = 0;
/* Do not clear either the error_occurred or num_ops elements here as they
* only want to be cleared by the application calling abort, not by abort
* being called at completion of an operation. */
return status;
}
psa_status_t psa_verify_hash_start(
psa_verify_hash_interruptible_operation_t *operation,
mbedtls_svc_key_id_t key, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
/* Check that start has not been previously called, or operation has not
* previously errored. */
if (operation->id != 0 || operation->error_occurred) {
return PSA_ERROR_BAD_STATE;
}
status = psa_sign_verify_check_alg(0, alg);
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
return status;
}
status = psa_get_and_lock_key_slot_with_policy(key, &slot,
PSA_KEY_USAGE_VERIFY_HASH,
alg);
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
return status;
}
psa_key_attributes_t attributes = {
.core = slot->attr
};
/* Ensure ops count gets reset, in case of operation re-use. */
operation->num_ops = 0;
status = psa_driver_wrapper_verify_hash_start(operation, &attributes,
slot->key.data,
slot->key.bytes,
alg, hash, hash_length,
signature, signature_length);
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
psa_verify_hash_abort_internal(operation);
}
unlock_status = psa_unlock_key_slot(slot);
if (unlock_status != PSA_SUCCESS) {
operation->error_occurred = 1;
}
return (status == PSA_SUCCESS) ? unlock_status : status;
}
psa_status_t psa_verify_hash_complete(
psa_verify_hash_interruptible_operation_t *operation)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
/* Check that start has been called first, and that operation has not
* previously errored. */
if (operation->id == 0 || operation->error_occurred) {
status = PSA_ERROR_BAD_STATE;
goto exit;
}
status = psa_driver_wrapper_verify_hash_complete(operation);
/* Update ops count with work done. */
operation->num_ops = psa_driver_wrapper_verify_hash_get_num_ops(
operation);
exit:
if (status != PSA_OPERATION_INCOMPLETE) {
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
}
psa_verify_hash_abort_internal(operation);
}
return status;
}
psa_status_t psa_verify_hash_abort(
psa_verify_hash_interruptible_operation_t *operation)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_verify_hash_abort_internal(operation);
/* We clear the number of ops done here, so that it is not cleared when
* the operation fails or succeeds, only on manual abort. */
operation->num_ops = 0;
/* Likewise, failure state. */
operation->error_occurred = 0;
return status;
}
/****************************************************************/
/* Asymmetric interruptible cryptography internal */
/* implementations */
/****************************************************************/
void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops)
{
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
/* Internal implementation uses zero to indicate infinite number max ops,
* therefore avoid this value, and set to minimum possible. */
if (max_ops == 0) {
max_ops = 1;
}
mbedtls_ecp_set_max_ops(max_ops);
#else
(void) max_ops;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
uint32_t mbedtls_psa_sign_hash_get_num_ops(
const mbedtls_psa_sign_hash_interruptible_operation_t *operation)
{
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
return operation->num_ops;
#else
(void) operation;
return 0;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
uint32_t mbedtls_psa_verify_hash_get_num_ops(
const mbedtls_psa_verify_hash_interruptible_operation_t *operation)
{
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
return operation->num_ops;
#else
(void) operation;
return 0;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
psa_status_t mbedtls_psa_sign_hash_start(
mbedtls_psa_sign_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
size_t key_buffer_size, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t required_hash_length;
if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (!PSA_ALG_IS_ECDSA(alg)) {
return PSA_ERROR_NOT_SUPPORTED;
}
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecdsa_restart_init(&operation->restart_ctx);
/* Ensure num_ops is zero'ed in case of context re-use. */
operation->num_ops = 0;
status = mbedtls_psa_ecp_load_representation(attributes->core.type,
attributes->core.bits,
key_buffer,
key_buffer_size,
&operation->ctx);
if (status != PSA_SUCCESS) {
return status;
}
operation->coordinate_bytes = PSA_BITS_TO_BYTES(
operation->ctx->grp.nbits);
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
operation->md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
operation->alg = alg;
/* We only need to store the same length of hash as the private key size
* here, it would be truncated by the internal implementation anyway. */
required_hash_length = (hash_length < operation->coordinate_bytes ?
hash_length : operation->coordinate_bytes);
if (required_hash_length > sizeof(operation->hash)) {
/* Shouldn't happen, but better safe than sorry. */
return PSA_ERROR_CORRUPTION_DETECTED;
}
memcpy(operation->hash, hash, required_hash_length);
operation->hash_length = required_hash_length;
return PSA_SUCCESS;
#else
(void) operation;
(void) key_buffer;
(void) key_buffer_size;
(void) alg;
(void) hash;
(void) hash_length;
(void) status;
(void) required_hash_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
psa_status_t mbedtls_psa_sign_hash_complete(
mbedtls_psa_sign_hash_interruptible_operation_t *operation,
uint8_t *signature, size_t signature_size,
size_t *signature_length)
{
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi r;
mbedtls_mpi s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
/* Ensure max_ops is set to the current value (or default). */
mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops());
if (signature_size < 2 * operation->coordinate_bytes) {
status = PSA_ERROR_BUFFER_TOO_SMALL;
goto exit;
}
if (PSA_ALG_ECDSA_IS_DETERMINISTIC(operation->alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
status = mbedtls_to_psa_error(
mbedtls_ecdsa_sign_det_restartable(&operation->ctx->grp,
&r,
&s,
&operation->ctx->d,
operation->hash,
operation->hash_length,
operation->md_alg,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE,
&operation->restart_ctx));
#else /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
} else {
status = mbedtls_to_psa_error(
mbedtls_ecdsa_sign_restartable(&operation->ctx->grp,
&r,
&s,
&operation->ctx->d,
operation->hash,
operation->hash_length,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE,
&operation->restart_ctx));
}
/* Hide the fact that the restart context only holds a delta of number of
* ops done during the last operation, not an absolute value. */
operation->num_ops += operation->restart_ctx.ecp.ops_done;
if (status == PSA_SUCCESS) {
status = mbedtls_to_psa_error(
mbedtls_mpi_write_binary(&r,
signature,
operation->coordinate_bytes)
);
if (status != PSA_SUCCESS) {
goto exit;
}
status = mbedtls_to_psa_error(
mbedtls_mpi_write_binary(&s,
signature +
operation->coordinate_bytes,
operation->coordinate_bytes)
);
if (status != PSA_SUCCESS) {
goto exit;
}
*signature_length = operation->coordinate_bytes * 2;
status = PSA_SUCCESS;
}
exit:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
return status;
#else
(void) operation;
(void) signature;
(void) signature_size;
(void) signature_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
psa_status_t mbedtls_psa_sign_hash_abort(
mbedtls_psa_sign_hash_interruptible_operation_t *operation)
{
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
if (operation->ctx) {
mbedtls_ecdsa_free(operation->ctx);
mbedtls_free(operation->ctx);
operation->ctx = NULL;
}
mbedtls_ecdsa_restart_free(&operation->restart_ctx);
operation->num_ops = 0;
return PSA_SUCCESS;
#else
(void) operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
psa_status_t mbedtls_psa_verify_hash_start(
mbedtls_psa_verify_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t coordinate_bytes = 0;
size_t required_hash_length = 0;
if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (!PSA_ALG_IS_ECDSA(alg)) {
return PSA_ERROR_NOT_SUPPORTED;
}
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecdsa_restart_init(&operation->restart_ctx);
mbedtls_mpi_init(&operation->r);
mbedtls_mpi_init(&operation->s);
/* Ensure num_ops is zero'ed in case of context re-use. */
operation->num_ops = 0;
status = mbedtls_psa_ecp_load_representation(attributes->core.type,
attributes->core.bits,
key_buffer,
key_buffer_size,
&operation->ctx);
if (status != PSA_SUCCESS) {
return status;
}
coordinate_bytes = PSA_BITS_TO_BYTES(operation->ctx->grp.nbits);
if (signature_length != 2 * coordinate_bytes) {
return PSA_ERROR_INVALID_SIGNATURE;
}
status = mbedtls_to_psa_error(
mbedtls_mpi_read_binary(&operation->r,
signature,
coordinate_bytes));
if (status != PSA_SUCCESS) {
return status;
}
status = mbedtls_to_psa_error(
mbedtls_mpi_read_binary(&operation->s,
signature +
coordinate_bytes,
coordinate_bytes));
if (status != PSA_SUCCESS) {
return status;
}
status = mbedtls_psa_ecp_load_public_part(operation->ctx);
if (status != PSA_SUCCESS) {
return status;
}
/* We only need to store the same length of hash as the private key size
* here, it would be truncated by the internal implementation anyway. */
required_hash_length = (hash_length < coordinate_bytes ? hash_length :
coordinate_bytes);
if (required_hash_length > sizeof(operation->hash)) {
/* Shouldn't happen, but better safe than sorry. */
return PSA_ERROR_CORRUPTION_DETECTED;
}
memcpy(operation->hash, hash, required_hash_length);
operation->hash_length = required_hash_length;
return PSA_SUCCESS;
#else
(void) operation;
(void) key_buffer;
(void) key_buffer_size;
(void) alg;
(void) hash;
(void) hash_length;
(void) signature;
(void) signature_length;
(void) status;
(void) coordinate_bytes;
(void) required_hash_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
psa_status_t mbedtls_psa_verify_hash_complete(
mbedtls_psa_verify_hash_interruptible_operation_t *operation)
{
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
/* Ensure max_ops is set to the current value (or default). */
mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops());
status = mbedtls_to_psa_error(
mbedtls_ecdsa_verify_restartable(&operation->ctx->grp,
operation->hash,
operation->hash_length,
&operation->ctx->Q,
&operation->r,
&operation->s,
&operation->restart_ctx));
/* Hide the fact that the restart context only holds a delta of number of
* ops done during the last operation, not an absolute value. */
operation->num_ops += operation->restart_ctx.ecp.ops_done;
return status;
#else
(void) operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
psa_status_t mbedtls_psa_verify_hash_abort(
mbedtls_psa_verify_hash_interruptible_operation_t *operation)
{
#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_ECP_RESTARTABLE)
if (operation->ctx) {
mbedtls_ecdsa_free(operation->ctx);
mbedtls_free(operation->ctx);
operation->ctx = NULL;
}
mbedtls_ecdsa_restart_free(&operation->restart_ctx);
operation->num_ops = 0;
mbedtls_mpi_free(&operation->r);
mbedtls_mpi_free(&operation->s);
return PSA_SUCCESS;
#else
(void) operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) &&
* defined( MBEDTLS_ECP_RESTARTABLE ) */
}
/****************************************************************/
/* Symmetric cryptography */
@ -4126,18 +4903,14 @@ psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
tag, tag_size, tag_length);
exit:
/* In case the operation fails and the user fails to check for failure or
* the zero tag size, make sure the tag is set to something implausible.
* Even if the operation succeeds, make sure we clear the rest of the
* buffer to prevent potential leakage of anything previously placed in
* the same buffer.*/
if (tag != NULL) {
if (status != PSA_SUCCESS) {
memset(tag, '!', tag_size);
} else if (*tag_length < tag_size) {
memset(tag + *tag_length, '!', (tag_size - *tag_length));
}
}
psa_wipe_tag_output_buffer(tag, status, tag_size, *tag_length);
psa_aead_abort(operation);

View file

@ -71,10 +71,10 @@
* \retval #PSA_SUCCESS Success.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* ciphertext_size is too small.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_aead_encrypt(
const psa_key_attributes_t *attributes,
@ -134,10 +134,10 @@ psa_status_t mbedtls_psa_aead_encrypt(
* The cipher is not authentic.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* plaintext_size is too small.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_aead_decrypt(
const psa_key_attributes_t *attributes,

View file

@ -59,10 +59,10 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_CIPHER(\p alg) is true).
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_cipher_encrypt_setup(
mbedtls_psa_cipher_operation_t *operation,
@ -89,10 +89,10 @@ psa_status_t mbedtls_psa_cipher_encrypt_setup(
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_CIPHER(\p alg) is true).
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_cipher_decrypt_setup(
mbedtls_psa_cipher_operation_t *operation,
@ -116,11 +116,11 @@ psa_status_t mbedtls_psa_cipher_decrypt_setup(
* the core to be less or equal to
* PSA_CIPHER_IV_MAX_SIZE.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The size of \p iv is not acceptable for the chosen algorithm,
* or the chosen algorithm does not use an IV.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_cipher_set_iv(
mbedtls_psa_cipher_operation_t *operation,
@ -142,10 +142,10 @@ psa_status_t mbedtls_psa_cipher_set_iv(
* \param[out] output_length On success, the number of bytes
* that make up the returned output.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p output buffer is too small.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_cipher_update(
mbedtls_psa_cipher_operation_t *operation,
@ -165,7 +165,7 @@ psa_status_t mbedtls_psa_cipher_update(
* \param[out] output_length On success, the number of bytes
* that make up the returned output.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The total input size passed to this operation is not valid for
* this particular algorithm. For example, the algorithm is a based
@ -176,7 +176,7 @@ psa_status_t mbedtls_psa_cipher_update(
* padding, and the ciphertext does not contain valid padding.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p output buffer is too small.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_cipher_finish(
mbedtls_psa_cipher_operation_t *operation,
@ -195,7 +195,7 @@ psa_status_t mbedtls_psa_cipher_finish(
*
* \param[in,out] operation Initialized cipher operation.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
*/
psa_status_t mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t *operation);
@ -224,10 +224,10 @@ psa_status_t mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t *operation)
* the returned output. Initialized to zero
* by the core.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p output buffer is too small.
* \retval #PSA_ERROR_INVALID_ARGUMENT
@ -275,10 +275,10 @@ psa_status_t mbedtls_psa_cipher_encrypt(const psa_key_attributes_t *attributes,
* the returned output. Initialized to zero
* by the core.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p output buffer is too small.
* \retval #PSA_ERROR_INVALID_ARGUMENT

View file

@ -209,7 +209,7 @@ psa_status_t psa_get_and_lock_key_slot_with_policy(mbedtls_svc_key_id_t key,
* \retval #PSA_SUCCESS
* Success. This includes the case of a key slot that was
* already fully wiped.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot);
@ -285,9 +285,9 @@ psa_status_t mbedtls_to_psa_error(int ret);
* \retval #PSA_SUCCESS The key was imported successfully.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The key data is not correctly formatted.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t psa_import_key_into_slot(
const psa_key_attributes_t *attributes,
@ -310,12 +310,12 @@ psa_status_t psa_import_key_into_slot(
* \p data
*
* \retval #PSA_SUCCESS The key was exported successfully.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t psa_export_key_internal(
const psa_key_attributes_t *attributes,
@ -338,12 +338,12 @@ psa_status_t psa_export_key_internal(
* \p data
*
* \retval #PSA_SUCCESS The public key was exported successfully.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t psa_export_public_key_internal(
const psa_key_attributes_t *attributes,
@ -364,7 +364,7 @@ psa_status_t psa_export_public_key_internal(
*
* \retval #PSA_SUCCESS
* The key was generated successfully.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED
* Key size in bits or type not supported.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
@ -399,18 +399,18 @@ psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes,
* \param[out] signature_length On success, the number of bytes
* that make up the returned signature value.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
* where \c key_type and \c key_bits are the type and bit-size
* respectively of the key.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
*/
psa_status_t psa_sign_message_builtin(
const psa_key_attributes_t *attributes,
@ -445,9 +445,9 @@ psa_status_t psa_sign_message_builtin(
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was performed successfully, but the passed
* signature is not a valid signature.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t psa_verify_message_builtin(
const psa_key_attributes_t *attributes,
@ -475,18 +475,18 @@ psa_status_t psa_verify_message_builtin(
* \param[out] signature_length On success, the number of bytes
* that make up the returned signature value.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
* where \c key_type and \c key_bits are the type and bit-size
* respectively of the key.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
*/
psa_status_t psa_sign_hash_builtin(
const psa_key_attributes_t *attributes,
@ -519,9 +519,9 @@ psa_status_t psa_sign_hash_builtin(
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was performed successfully, but the passed
* signature is not a valid signature.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t psa_verify_hash_builtin(
const psa_key_attributes_t *attributes,
@ -577,8 +577,8 @@ psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type,
* up the returned shared secret.
* \retval #PSA_SUCCESS
* Success. Shared secret successfully calculated.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p alg is not a key agreement algorithm, or
* \p private_key is not compatible with \p alg,
@ -588,12 +588,12 @@ psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type,
* \p shared_secret_size is too small
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not a supported key agreement algorithm.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_BAD_STATE \emptydescription
*/
psa_status_t psa_key_agreement_raw_builtin(
const psa_key_attributes_t *attributes,
@ -606,4 +606,272 @@ psa_status_t psa_key_agreement_raw_builtin(
size_t shared_secret_size,
size_t *shared_secret_length);
/**
* \brief Set the maximum number of ops allowed to be executed by an
* interruptible function in a single call.
*
* \note The signature of this function is that of a PSA driver
* interruptible_set_max_ops entry point. This function behaves as an
* interruptible_set_max_ops entry point as defined in the PSA driver
* interface specification for transparent drivers.
*
* \param[in] max_ops The maximum number of ops to be executed in a
* single call, this can be a number from 0 to
* #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0
* is obviously the least amount of work done per
* call.
*/
void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops);
/**
* \brief Get the maximum number of ops allowed to be executed by an
* interruptible function in a single call.
*
* \note The signature of this function is that of a PSA driver
* interruptible_get_max_ops entry point. This function behaves as an
* interruptible_get_max_ops entry point as defined in the PSA driver
* interface specification for transparent drivers.
*
* \return Maximum number of ops allowed to be executed
* by an interruptible function in a single call.
*/
uint32_t mbedtls_psa_interruptible_get_max_ops(void);
/**
* \brief Get the number of ops that a hash signing operation has taken for the
* previous call. If no call or work has taken place, this will return
* zero.
*
* \note The signature of this function is that of a PSA driver
* sign_hash_get_num_ops entry point. This function behaves as an
* sign_hash_get_num_ops entry point as defined in the PSA driver
* interface specification for transparent drivers.
*
* \param operation The \c
* mbedtls_psa_sign_hash_interruptible_operation_t
* to use. This must be initialized first.
*
* \return Number of ops that were completed
* in the last call to \c
* mbedtls_psa_sign_hash_complete().
*/
uint32_t mbedtls_psa_sign_hash_get_num_ops(
const mbedtls_psa_sign_hash_interruptible_operation_t *operation);
/**
* \brief Get the number of ops that a hash verification operation has taken for
* the previous call. If no call or work has taken place, this will
* return zero.
*
* \note The signature of this function is that of a PSA driver
* verify_hash_get_num_ops entry point. This function behaves as an
* verify_hash_get_num_ops entry point as defined in the PSA driver
* interface specification for transparent drivers.
*
* \param operation The \c
* mbedtls_psa_verify_hash_interruptible_operation_t
* to use. This must be initialized first.
*
* \return Number of ops that were completed
* in the last call to \c
* mbedtls_psa_verify_hash_complete().
*/
uint32_t mbedtls_psa_verify_hash_get_num_ops(
const mbedtls_psa_verify_hash_interruptible_operation_t *operation);
/**
* \brief Start signing a hash or short message with a private key, in an
* interruptible manner.
*
* \note The signature of this function is that of a PSA driver
* sign_hash_start entry point. This function behaves as a
* sign_hash_start entry point as defined in the PSA driver interface
* specification for transparent drivers.
*
* \param[in] operation The \c
* mbedtls_psa_sign_hash_interruptible_operation_t
* to use. This must be initialized first.
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[in] key_buffer The buffer containing the key context.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
* \param[in] alg A signature algorithm that is compatible with
* the type of the key.
* \param[in] hash The hash or message to sign.
* \param hash_length Size of the \p hash buffer in bytes.
*
* \retval #PSA_SUCCESS
* The operation started successfully - call \c psa_sign_hash_complete()
* with the same context to complete the operation
* \retval #PSA_ERROR_INVALID_ARGUMENT
* An unsupported, incorrectly formatted or incorrect type of key was
* used.
* \retval #PSA_ERROR_NOT_SUPPORTED Either no internal interruptible operations
* are currently supported, or the key type is currently unsupported.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* There was insufficient memory to load the key representation.
*/
psa_status_t mbedtls_psa_sign_hash_start(
mbedtls_psa_sign_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
size_t key_buffer_size, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length);
/**
* \brief Continue and eventually complete the action of signing a hash or
* short message with a private key, in an interruptible manner.
*
* \note The signature of this function is that of a PSA driver
* sign_hash_complete entry point. This function behaves as a
* sign_hash_complete entry point as defined in the PSA driver interface
* specification for transparent drivers.
*
* \param[in] operation The \c
* mbedtls_psa_sign_hash_interruptible_operation_t
* to use. This must be initialized first.
*
* \param[out] signature Buffer where the signature is to be written.
* \param signature_size Size of the \p signature buffer in bytes. This
* must be appropriate for the selected
* algorithm and key.
* \param[out] signature_length On success, the number of bytes that make up
* the returned signature value.
*
* \retval #PSA_SUCCESS
* Operation completed successfully
*
* \retval #PSA_OPERATION_INCOMPLETE
* Operation was interrupted due to the setting of \c
* psa_interruptible_set_max_ops(), there is still work to be done,
* please call this function again with the same operation object.
*
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
* where \c key_type and \c key_bits are the type and bit-size
* respectively of \p key.
*
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
*/
psa_status_t mbedtls_psa_sign_hash_complete(
mbedtls_psa_sign_hash_interruptible_operation_t *operation,
uint8_t *signature, size_t signature_size,
size_t *signature_length);
/**
* \brief Abort a sign hash operation.
*
* \note The signature of this function is that of a PSA driver sign_hash_abort
* entry point. This function behaves as a sign_hash_abort entry point as
* defined in the PSA driver interface specification for transparent
* drivers.
*
* \param[in] operation The \c
* mbedtls_psa_sign_hash_interruptible_operation_t
* to abort.
*
* \retval #PSA_SUCCESS
* The operation was aborted successfully.
*/
psa_status_t mbedtls_psa_sign_hash_abort(
mbedtls_psa_sign_hash_interruptible_operation_t *operation);
/**
* \brief Start reading and verifying a hash or short message, in an
* interruptible manner.
*
* \note The signature of this function is that of a PSA driver
* verify_hash_start entry point. This function behaves as a
* verify_hash_start entry point as defined in the PSA driver interface
* specification for transparent drivers.
*
* \param[in] operation The \c
* mbedtls_psa_verify_hash_interruptible_operation_t
* to use. This must be initialized first.
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[in] key_buffer The buffer containing the key context.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
* \param[in] alg A signature algorithm that is compatible with
* the type of the key.
* \param[in] hash The hash whose signature is to be verified.
* \param hash_length Size of the \p hash buffer in bytes.
* \param[in] signature Buffer containing the signature to verify.
* \param signature_length Size of the \p signature buffer in bytes.
*
* \retval #PSA_SUCCESS
* The operation started successfully - call \c psa_sign_hash_complete()
* with the same context to complete the operation
* \retval #PSA_ERROR_INVALID_ARGUMENT
* An unsupported or incorrect type of key was used.
* \retval #PSA_ERROR_NOT_SUPPORTED
* Either no internal interruptible operations are currently supported,
* or the key type is currently unsupported.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* There was insufficient memory either to load the key representation,
* or to prepare the operation.
*/
psa_status_t mbedtls_psa_verify_hash_start(
mbedtls_psa_verify_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length);
/**
* \brief Continue and eventually complete the action of signing a hash or
* short message with a private key, in an interruptible manner.
*
* \note The signature of this function is that of a PSA driver
* sign_hash_complete entry point. This function behaves as a
* sign_hash_complete entry point as defined in the PSA driver interface
* specification for transparent drivers.
*
* \param[in] operation The \c
* mbedtls_psa_sign_hash_interruptible_operation_t
* to use. This must be initialized first.
*
* \retval #PSA_SUCCESS
* Operation completed successfully, and the passed signature is valid.
*
* \retval #PSA_OPERATION_INCOMPLETE
* Operation was interrupted due to the setting of \c
* psa_interruptible_set_max_ops(), there is still work to be done,
* please call this function again with the same operation object.
*
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was performed successfully, but the passed
* signature is not a valid signature.
*
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_verify_hash_complete(
mbedtls_psa_verify_hash_interruptible_operation_t *operation);
/**
* \brief Abort a verify signed hash operation.
*
* \note The signature of this function is that of a PSA driver
* verify_hash_abort entry point. This function behaves as a
* verify_hash_abort entry point as defined in the PSA driver interface
* specification for transparent drivers.
*
* \param[in] operation The \c
* mbedtls_psa_verify_hash_interruptible_operation_t
* to abort.
*
* \retval #PSA_SUCCESS
* The operation was aborted successfully.
*/
psa_status_t mbedtls_psa_verify_hash_abort(
mbedtls_psa_verify_hash_interruptible_operation_t *operation);
#endif /* PSA_CRYPTO_CORE_H */

View file

@ -66,6 +66,43 @@ psa_status_t psa_driver_wrapper_verify_hash(
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length);
/*
* Interruptible Signature functions
*/
uint32_t psa_driver_wrapper_sign_hash_get_num_ops(
psa_sign_hash_interruptible_operation_t *operation);
uint32_t psa_driver_wrapper_verify_hash_get_num_ops(
psa_verify_hash_interruptible_operation_t *operation);
psa_status_t psa_driver_wrapper_sign_hash_start(
psa_sign_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
size_t key_buffer_size, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length);
psa_status_t psa_driver_wrapper_sign_hash_complete(
psa_sign_hash_interruptible_operation_t *operation,
uint8_t *signature, size_t signature_size,
size_t *signature_length);
psa_status_t psa_driver_wrapper_sign_hash_abort(
psa_sign_hash_interruptible_operation_t *operation);
psa_status_t psa_driver_wrapper_verify_hash_start(
psa_verify_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
size_t key_buffer_size, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length);
psa_status_t psa_driver_wrapper_verify_hash_complete(
psa_verify_hash_interruptible_operation_t *operation);
psa_status_t psa_driver_wrapper_verify_hash_abort(
psa_verify_hash_interruptible_operation_t *operation);
/*
* Key handling functions
*/

View file

@ -404,6 +404,21 @@ cleanup:
return mbedtls_to_psa_error(ret);
}
psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp)
{
int ret = 0;
/* Check whether the public part is loaded. If not, load it. */
if (mbedtls_ecp_is_zero(&ecp->Q)) {
ret = mbedtls_ecp_mul(&ecp->grp, &ecp->Q,
&ecp->d, &ecp->grp.G,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE);
}
return mbedtls_to_psa_error(ret);
}
psa_status_t mbedtls_psa_ecdsa_verify_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer, size_t key_buffer_size,
@ -412,7 +427,6 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash(
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_keypair *ecp = NULL;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t curve_bytes;
mbedtls_mpi r, s;
@ -432,34 +446,39 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash(
mbedtls_mpi_init(&s);
if (signature_length != 2 * curve_bytes) {
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
status = PSA_ERROR_INVALID_SIGNATURE;
goto cleanup;
}
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&r,
signature,
curve_bytes));
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&s,
signature + curve_bytes,
curve_bytes));
/* Check whether the public part is loaded. If not, load it. */
if (mbedtls_ecp_is_zero(&ecp->Q)) {
MBEDTLS_MPI_CHK(
mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE));
status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&r,
signature,
curve_bytes));
if (status != PSA_SUCCESS) {
goto cleanup;
}
ret = mbedtls_ecdsa_verify(&ecp->grp, hash, hash_length,
&ecp->Q, &r, &s);
status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&s,
signature + curve_bytes,
curve_bytes));
if (status != PSA_SUCCESS) {
goto cleanup;
}
status = mbedtls_psa_ecp_load_public_part(ecp);
if (status != PSA_SUCCESS) {
goto cleanup;
}
status = mbedtls_to_psa_error(mbedtls_ecdsa_verify(&ecp->grp, hash,
hash_length, &ecp->Q,
&r, &s));
cleanup:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
mbedtls_ecp_keypair_free(ecp);
mbedtls_free(ecp);
return mbedtls_to_psa_error(ret);
return status;
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \

View file

@ -48,6 +48,15 @@ psa_status_t mbedtls_psa_ecp_load_representation(psa_key_type_t type,
size_t data_length,
mbedtls_ecp_keypair **p_ecp);
/** Load the public part of an internal ECP, if required.
*
* \param ecp The ECP context to load the public part for.
*
* \return PSA_SUCCESS on success, otherwise an MPI error.
*/
psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp);
/** Import an ECP key in binary format.
*
* \note The signature of this function is that of a PSA driver
@ -70,9 +79,9 @@ psa_status_t mbedtls_psa_ecp_load_representation(psa_key_type_t type,
* \retval #PSA_SUCCESS The ECP key was imported successfully.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The key data is not correctly formatted.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_ecp_import_key(
const psa_key_attributes_t *attributes,
@ -111,12 +120,12 @@ psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type,
* \p data
*
* \retval #PSA_SUCCESS The ECP public key was exported successfully.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_ecp_export_public_key(
const psa_key_attributes_t *attributes,
@ -166,17 +175,17 @@ psa_status_t mbedtls_psa_ecp_generate_key(
* \param[out] signature_length On success, the number of bytes
* that make up the returned signature value.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_SIGN_OUTPUT_SIZE(\c PSA_KEY_TYPE_ECC_KEY_PAIR, \c key_bits,
* \p alg) where \c key_bits is the bit-size of the ECC key.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
*/
psa_status_t mbedtls_psa_ecdsa_sign_hash(
const psa_key_attributes_t *attributes,
@ -209,9 +218,9 @@ psa_status_t mbedtls_psa_ecdsa_sign_hash(
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was performed successfully, but the passed
* signature is not a valid signature.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_ecdsa_verify_hash(
const psa_key_attributes_t *attributes,
@ -247,8 +256,8 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash(
* up the returned shared secret.
* \retval #PSA_SUCCESS
* Success. Shared secret successfully calculated.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_NOT_PERMITTED
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p alg is not a key agreement algorithm, or
* \p private_key is not compatible with \p alg,
@ -258,8 +267,8 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash(
* \p shared_secret_size is too small
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not a supported key agreement algorithm.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_key_agreement_ecdh(
const psa_key_attributes_t *attributes,

View file

@ -48,8 +48,8 @@
* \p alg is not supported
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p hash_size is too small
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_hash_compute(
psa_algorithm_t alg,
@ -88,8 +88,8 @@ psa_status_t mbedtls_psa_hash_compute(
* \p alg is not supported
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be inactive).
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_hash_setup(
mbedtls_psa_hash_operation_t *operation,
@ -115,13 +115,13 @@ psa_status_t mbedtls_psa_hash_setup(
* \param[in,out] target_operation The operation object to set up.
* It must be initialized but not active.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The \p source_operation state is not valid (it must be active).
* \retval #PSA_ERROR_BAD_STATE
* The \p target_operation state is not valid (it must be inactive).
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_hash_clone(
const mbedtls_psa_hash_operation_t *source_operation,
@ -147,8 +147,8 @@ psa_status_t mbedtls_psa_hash_clone(
* Success.
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be active).
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_hash_update(
mbedtls_psa_hash_operation_t *operation,
@ -186,8 +186,8 @@ psa_status_t mbedtls_psa_hash_update(
* The size of the \p hash buffer is too small. You can determine a
* sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg)
* where \c alg is the hash algorithm that is calculated.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_hash_finish(
mbedtls_psa_hash_operation_t *operation,
@ -216,8 +216,8 @@ psa_status_t mbedtls_psa_hash_finish(
*
* \param[in,out] operation Initialized hash operation.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_hash_abort(
mbedtls_psa_hash_operation_t *operation);

View file

@ -52,8 +52,8 @@
* \p alg is not supported.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p mac_size is too small
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_mac_compute(
const psa_key_attributes_t *attributes,
@ -89,8 +89,8 @@ psa_status_t mbedtls_psa_mac_compute(
* Success.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be inactive).
*/
@ -124,8 +124,8 @@ psa_status_t mbedtls_psa_mac_sign_setup(
* Success.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \p alg is not supported.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be inactive).
*/
@ -158,8 +158,8 @@ psa_status_t mbedtls_psa_mac_verify_setup(
* Success.
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be active).
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_mac_update(
mbedtls_psa_mac_operation_t *operation,
@ -200,8 +200,8 @@ psa_status_t mbedtls_psa_mac_update(
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p mac buffer is too small. A sufficient buffer size
* can be determined by calling PSA_MAC_LENGTH().
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_mac_sign_finish(
mbedtls_psa_mac_operation_t *operation,
@ -241,8 +241,8 @@ psa_status_t mbedtls_psa_mac_sign_finish(
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be an active mac verify
* operation).
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_mac_verify_finish(
mbedtls_psa_mac_operation_t *operation,
@ -267,8 +267,8 @@ psa_status_t mbedtls_psa_mac_verify_finish(
*
* \param[in,out] operation Initialized MAC operation.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_mac_abort(
mbedtls_psa_mac_operation_t *operation);

View file

@ -332,11 +332,9 @@ static psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg,
/* The Mbed TLS RSA module uses an unsigned int for hash length
* parameters. Validate that it fits so that we don't risk an
* overflow later. */
#if SIZE_MAX > UINT_MAX
if (hash_length > UINT_MAX) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#endif
/* For signatures using a hash, the hash length must be correct. */
if (alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {

View file

@ -61,9 +61,9 @@ psa_status_t mbedtls_psa_rsa_load_representation(psa_key_type_t type,
* \retval #PSA_SUCCESS The RSA key was imported successfully.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The key data is not correctly formatted.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
*/
psa_status_t mbedtls_psa_rsa_import_key(
const psa_key_attributes_t *attributes,
@ -102,12 +102,12 @@ psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type,
* \p data.
*
* \retval #PSA_SUCCESS The RSA public key was exported successfully.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_rsa_export_public_key(
const psa_key_attributes_t *attributes,
@ -158,17 +158,17 @@ psa_status_t mbedtls_psa_rsa_generate_key(
* \param[out] signature_length On success, the number of bytes
* that make up the returned signature value.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_SIGN_OUTPUT_SIZE(\c PSA_KEY_TYPE_RSA_KEY_PAIR, \c key_bits,
* \p alg) where \c key_bits is the bit-size of the RSA key.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
*/
psa_status_t mbedtls_psa_rsa_sign_hash(
const psa_key_attributes_t *attributes,
@ -202,9 +202,9 @@ psa_status_t mbedtls_psa_rsa_sign_hash(
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was performed successfully, but the passed
* signature is not a valid signature.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
psa_status_t mbedtls_psa_rsa_verify_hash(
const psa_key_attributes_t *attributes,
@ -237,20 +237,20 @@ psa_status_t mbedtls_psa_rsa_verify_hash(
* \param[out] output_length On success, the number of bytes
* that make up the returned output.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p output buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
* where \c key_type and \c key_bits are the type and bit-size
* respectively of \p key.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@ -294,21 +294,21 @@ psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attribut
* \param[out] output_length On success, the number of bytes
* that make up the returned output.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p output buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
* where \c key_type and \c key_bits are the type and bit-size
* respectively of \p key.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_INVALID_PADDING
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
* \retval #PSA_ERROR_INVALID_PADDING \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize

View file

@ -125,12 +125,10 @@ static psa_status_t psa_get_se_driver_its_file_uid(
return PSA_ERROR_NOT_SUPPORTED;
}
#if SIZE_MAX > UINT32_MAX
/* ITS file sizes are limited to 32 bits. */
if (driver->u.internal.persistent_data_size > UINT32_MAX) {
return PSA_ERROR_NOT_SUPPORTED;
}
#endif
/* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
*uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location;

View file

@ -88,9 +88,9 @@ static inline int psa_key_id_is_volatile(psa_key_id_t key_id)
* due to a lack of empty key slot, or available memory.
* \retval #PSA_ERROR_DOES_NOT_EXIST
* There is no key with key identifier \p key.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
*/
psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
psa_key_slot_t **p_slot);
@ -118,9 +118,9 @@ void psa_wipe_all_key_slots(void);
* associated to the returned slot.
* \param[out] p_slot On success, a pointer to the slot.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_BAD_STATE
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_BAD_STATE \emptydescription
*/
psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot);
@ -195,8 +195,8 @@ static inline int psa_key_lifetime_is_external(psa_key_lifetime_t lifetime)
* storage, returns a pointer to the driver table
* associated with the key's storage location.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
*/
psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime,
psa_se_drv_table_entry_t **p_drv);
@ -205,7 +205,7 @@ psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime,
*
* \param[in] lifetime The key lifetime attribute.
*
* \retval #PSA_SUCCESS
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED The key is persistent but persistent keys
* are not supported.
*/

View file

@ -79,11 +79,11 @@ static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key)
* \param[out] data Buffer where the data is to be written.
* \param data_size Size of the \c data buffer in bytes.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
*/
static psa_status_t psa_crypto_storage_load(
const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size)
@ -131,11 +131,11 @@ int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key)
* \param data_length The number of bytes
* that make up the data.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_ALREADY_EXISTS
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
*/
static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key,
const uint8_t *data,
@ -205,10 +205,10 @@ psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key)
* is to be obtained.
* \param[out] data_length The number of bytes that make up the data.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
*/
static psa_status_t psa_crypto_storage_get_data_length(
const mbedtls_svc_key_id_t key,

View file

@ -96,14 +96,14 @@ int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key);
* \param[in] data Buffer containing the key data.
* \param data_length The number of bytes that make up the key data.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_ALREADY_EXISTS
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
*/
psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
const uint8_t *data,
@ -129,11 +129,11 @@ psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
* \param[out] data Pointer to an allocated key data buffer on return.
* \param[out] data_length The number of bytes that make up the key data.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_DOES_NOT_EXIST
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
*/
psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
uint8_t **data,
@ -148,7 +148,7 @@ psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
* \retval #PSA_SUCCESS
* The key was successfully removed,
* or the key did not exist.
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
*/
psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key);
@ -190,9 +190,9 @@ void psa_format_key_data_for_storage(const uint8_t *data,
* \param[out] attr On success, the attribute structure is filled
* with the loaded key metadata.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
*/
psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
size_t storage_data_length,
@ -322,10 +322,10 @@ static inline void psa_crypto_prepare_transaction(
* You may call this function multiple times during a transaction to
* atomically update the transaction state.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
*/
psa_status_t psa_crypto_save_transaction(void);
@ -339,9 +339,9 @@ psa_status_t psa_crypto_save_transaction(void);
* #psa_crypto_transaction.
* \retval #PSA_ERROR_DOES_NOT_EXIST
* There is no ongoing transaction.
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
*/
psa_status_t psa_crypto_load_transaction(void);
@ -380,8 +380,8 @@ psa_status_t psa_crypto_stop_transaction(void);
*
* \retval #PSA_SUCCESS
* Success
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_NOT_PERMITTED
* The entropy seed file already exists.
*/

View file

@ -22,6 +22,23 @@
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
defined(__clang__) && __clang_major__ < 18 && __clang_major__ > 3
/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
*
* The intrinsic declaration are guarded by predefined ACLE macros in clang:
* these are normally only enabled by the -march option on the command line.
* By defining the macros ourselves we gain access to those declarations without
* requiring -march on the command line.
*
* `arm_neon.h` could be included by any header file, so we put these defines
* at the top of this file, before any includes.
*/
#define __ARM_FEATURE_CRYPTO 1
#define NEED_TARGET_OPTIONS
#endif /* __aarch64__ && __clang__ &&
!__ARM_FEATURE_CRYPTO && __clang_major__ < 18 && __clang_major__ > 3 */
#include "common.h"
#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C)
@ -37,6 +54,30 @@
#if defined(__aarch64__)
# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
/* *INDENT-OFF* */
# if !defined(__ARM_FEATURE_CRYPTO) || defined(NEED_TARGET_OPTIONS)
# if defined(__clang__)
# if __clang_major__ < 4
# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
# endif
# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
# define MBEDTLS_POP_TARGET_PRAGMA
# elif defined(__GNUC__)
/* FIXME: GCC-5 annouce crypto extension, but some intrinsic are missed.
* Known miss intrinsic can be workaround.
*/
# if __GNUC__ < 6
# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
# else
# pragma GCC push_options
# pragma GCC target ("arch=armv8-a+crypto")
# define MBEDTLS_POP_TARGET_PRAGMA
# endif
# else
# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*"
# endif
# endif
/* *INDENT-ON* */
# include <arm_neon.h>
# endif
# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
@ -353,8 +394,16 @@ int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
SHA256_BLOCK_SIZE) ? 0 : -1;
}
#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
#if defined(MBEDTLS_POP_TARGET_PRAGMA)
#if defined(__clang__)
#pragma clang attribute pop
#elif defined(__GNUC__)
#pragma GCC pop_options
#endif
#undef MBEDTLS_POP_TARGET_PRAGMA
#endif
#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many

View file

@ -22,6 +22,26 @@
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \
defined(__clang__) && __clang_major__ < 18 && \
__clang_major__ >= 13 && __clang_minor__ > 0 && __clang_patchlevel__ > 0
/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
*
* The intrinsic declaration are guarded by predefined ACLE macros in clang:
* these are normally only enabled by the -march option on the command line.
* By defining the macros ourselves we gain access to those declarations without
* requiring -march on the command line.
*
* `arm_neon.h` could be included by any header file, so we put these defines
* at the top of this file, before any includes.
*/
#define __ARM_FEATURE_SHA512 1
#define NEED_TARGET_OPTIONS
#endif /* __aarch64__ && __clang__ &&
!__ARM_FEATURE_SHA512 && __clang_major__ < 18 &&
__clang_major__ >= 13 && __clang_minor__ > 0 &&
__clang_patchlevel__ > 0 */
#include "common.h"
#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C)
@ -43,6 +63,47 @@
#if defined(__aarch64__)
# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY)
/* *INDENT-OFF* */
/*
* Best performance comes from most recent compilers, with intrinsics and -O3.
* Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and
* can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12).
*
* GCC < 8 won't work at all (lacks the sha512 instructions)
* GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512
*
* Clang < 7 won't work at all (lacks the sha512 instructions)
* Clang 7-12 don't have intrinsics (but we work around that with inline
* assembler) or __ARM_FEATURE_SHA512
* Clang == 13.0.0 same as clang 12 (only seen on macOS)
* Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics
*/
# if !defined(__ARM_FEATURE_SHA512) || defined(NEED_TARGET_OPTIONS)
/* Test Clang first, as it defines __GNUC__ */
# if defined(__clang__)
# if __clang_major__ < 7
# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
# elif __clang_major__ < 13 || \
(__clang_major__ == 13 && __clang_minor__ == 0 && \
__clang_patchlevel__ == 0)
/* We implement the intrinsics with inline assembler, so don't error */
# else
# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function)
# define MBEDTLS_POP_TARGET_PRAGMA
# endif
# elif defined(__GNUC__)
# if __GNUC__ < 8
# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
# else
# pragma GCC push_options
# pragma GCC target ("arch=armv8.2-a+sha3")
# define MBEDTLS_POP_TARGET_PRAGMA
# endif
# else
# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*"
# endif
# endif
/* *INDENT-ON* */
# include <arm_neon.h>
# endif
# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
@ -516,6 +577,15 @@ int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
SHA512_BLOCK_SIZE) ? 0 : -1;
}
#if defined(MBEDTLS_POP_TARGET_PRAGMA)
#if defined(__clang__)
#pragma clang attribute pop
#elif defined(__GNUC__)
#pragma GCC pop_options
#endif
#undef MBEDTLS_POP_TARGET_PRAGMA
#endif
#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */

View file

@ -945,25 +945,49 @@ int mbedtls_ssl_write_client_hello(mbedtls_ssl_context *ssl)
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_DTLS */
{
mbedtls_ssl_add_hs_hdr_to_checksum(ssl, MBEDTLS_SSL_HS_CLIENT_HELLO,
msg_len);
ssl->handshake->update_checksum(ssl, buf, msg_len - binders_len);
ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl,
MBEDTLS_SSL_HS_CLIENT_HELLO,
msg_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_add_hs_hdr_to_checksum", ret);
return ret;
}
ret = ssl->handshake->update_checksum(ssl, buf, msg_len - binders_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
return ret;
}
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
if (binders_len > 0) {
MBEDTLS_SSL_PROC_CHK(
mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
ssl, buf + msg_len - binders_len, buf + msg_len));
ssl->handshake->update_checksum(ssl, buf + msg_len - binders_len,
binders_len);
ret = ssl->handshake->update_checksum(ssl, buf + msg_len - binders_len,
binders_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
return ret;
}
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl,
buf_len,
msg_len));
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
}
/*
* Set next state. Note that if TLS 1.3 is proposed, this may be
* overwritten by mbedtls_ssl_tls13_finalize_client_hello().
*/
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (ssl->handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_3 &&
MBEDTLS_SSL_VERSION_TLS1_3 <= ssl->tls_version) {
ret = mbedtls_ssl_tls13_finalize_client_hello(ssl);
}
#endif
}
cleanup:

View file

@ -705,9 +705,12 @@ struct mbedtls_ssl_handshake_params {
mbedtls_ssl_ciphersuite_t const *ciphersuite_info;
void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *);
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
MBEDTLS_CHECK_RETURN_CRITICAL
int (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
MBEDTLS_CHECK_RETURN_CRITICAL
int (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *);
MBEDTLS_CHECK_RETURN_CRITICAL
int (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
mbedtls_ssl_tls_prf_cb *tls_prf;
/*
@ -986,7 +989,6 @@ struct mbedtls_ssl_handshake_params {
mbedtls_ssl_tls13_handshake_secrets tls13_hs_secrets;
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_tls13_early_secrets tls13_early_secrets;
/** TLS 1.3 transform for early data and handshake messages. */
mbedtls_ssl_transform *transform_earlydata;
#endif
@ -1318,7 +1320,8 @@ static inline void mbedtls_ssl_handshake_set_state(mbedtls_ssl_context *ssl,
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl);
void mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl);
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
MBEDTLS_CHECK_RETURN_CRITICAL
@ -1329,7 +1332,8 @@ MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl);
void mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl);
/**
* \brief Update record layer
@ -1462,14 +1466,16 @@ void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl,
/*
* Update checksum of handshake messages.
*/
void mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl,
unsigned hs_type,
unsigned char const *msg,
size_t msg_len);
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl,
unsigned hs_type,
unsigned char const *msg,
size_t msg_len);
void mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl,
unsigned hs_type,
size_t total_hs_len);
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl,
unsigned hs_type,
size_t total_hs_len);
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
@ -2740,4 +2746,8 @@ static inline void mbedtls_ssl_session_clear_ticket_flags(
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl);
#endif
#endif /* ssl_misc.h */

View file

@ -2090,7 +2090,7 @@ int mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want)
return ret;
}
if ((size_t) ret > len || (INT_MAX > SIZE_MAX && ret > (int) SIZE_MAX)) {
if ((size_t) ret > len) {
MBEDTLS_SSL_DEBUG_MSG(1,
("f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
" were requested",
@ -2142,7 +2142,7 @@ int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl)
return ret;
}
if ((size_t) ret > ssl->out_left || (INT_MAX > SIZE_MAX && ret > (int) SIZE_MAX)) {
if ((size_t) ret > ssl->out_left) {
MBEDTLS_SSL_DEBUG_MSG(1,
("f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
" bytes were sent",
@ -2639,7 +2639,12 @@ int mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl,
/* Update running hashes of handshake messages seen */
if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0) {
ssl->handshake->update_checksum(ssl, ssl->out_msg, ssl->out_msglen);
ret = ssl->handshake->update_checksum(ssl, ssl->out_msg,
ssl->out_msglen);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
return ret;
}
}
}
@ -3067,12 +3072,17 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
return 0;
}
void mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl)
int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_handshake_params * const hs = ssl->handshake;
if (mbedtls_ssl_is_handshake_over(ssl) == 0 && hs != NULL) {
ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen);
ret = ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
return ret;
}
}
/* Handshake message is complete, increment counter */
@ -3103,6 +3113,7 @@ void mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl)
memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
}
#endif
return 0;
}
/*
@ -3928,7 +3939,11 @@ int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl,
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
update_hs_digest == 1) {
mbedtls_ssl_update_handshake_status(ssl);
ret = mbedtls_ssl_update_handshake_status(ssl);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
return ret;
}
}
} else {
MBEDTLS_SSL_DEBUG_MSG(2, ("reuse previously read message"));

View file

@ -418,8 +418,8 @@ static int tls_prf_sha256(const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen);
static void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *);
static void ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);
static int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *);
static int ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
@ -430,8 +430,8 @@ static int tls_prf_sha384(const unsigned char *secret, size_t slen,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen);
static void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *);
static void ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
static int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *);
static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session,
@ -444,14 +444,14 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session,
size_t len);
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
static void ssl_update_checksum_start(mbedtls_ssl_context *, const unsigned char *, size_t);
static int ssl_update_checksum_start(mbedtls_ssl_context *, const unsigned char *, size_t);
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
static void ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t);
static int ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t);
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
static void ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t);
static int ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t);
#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf,
@ -788,9 +788,9 @@ void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl,
}
}
void mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl,
unsigned hs_type,
size_t total_hs_len)
int mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl,
unsigned hs_type,
size_t total_hs_len)
{
unsigned char hs_hdr[4];
@ -800,84 +800,137 @@ void mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl,
hs_hdr[2] = MBEDTLS_BYTE_1(total_hs_len);
hs_hdr[3] = MBEDTLS_BYTE_0(total_hs_len);
ssl->handshake->update_checksum(ssl, hs_hdr, sizeof(hs_hdr));
return ssl->handshake->update_checksum(ssl, hs_hdr, sizeof(hs_hdr));
}
void mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl,
unsigned hs_type,
unsigned char const *msg,
size_t msg_len)
int mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl,
unsigned hs_type,
unsigned char const *msg,
size_t msg_len)
{
mbedtls_ssl_add_hs_hdr_to_checksum(ssl, hs_type, msg_len);
ssl->handshake->update_checksum(ssl, msg, msg_len);
int ret;
ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl, hs_type, msg_len);
if (ret != 0) {
return ret;
}
return ssl->handshake->update_checksum(ssl, msg, msg_len);
}
void mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl)
int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl)
{
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) || \
defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_status_t status;
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#endif
#else /* SHA-256 or SHA-384 */
((void) ssl);
#endif /* SHA-256 or SHA-384 */
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&ssl->handshake->fin_sha256_psa);
psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256);
status = psa_hash_abort(&ssl->handshake->fin_sha256_psa);
if (status != PSA_SUCCESS) {
return mbedtls_md_error_from_psa(status);
}
status = psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
return mbedtls_md_error_from_psa(status);
}
#else
mbedtls_sha256_starts(&ssl->handshake->fin_sha256, 0);
ret = mbedtls_sha256_starts(&ssl->handshake->fin_sha256, 0);
if (ret != 0) {
return ret;
}
#endif
#endif
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&ssl->handshake->fin_sha384_psa);
psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384);
status = psa_hash_abort(&ssl->handshake->fin_sha384_psa);
if (status != PSA_SUCCESS) {
return mbedtls_md_error_from_psa(status);
}
status = psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384);
if (status != PSA_SUCCESS) {
return mbedtls_md_error_from_psa(status);
}
#else
mbedtls_sha512_starts(&ssl->handshake->fin_sha384, 1);
ret = mbedtls_sha512_starts(&ssl->handshake->fin_sha384, 1);
if (ret != 0) {
return ret;
}
#endif
#endif
return 0;
}
static void ssl_update_checksum_start(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
static int ssl_update_checksum_start(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
{
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) || \
defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
psa_status_t status;
#else
mbedtls_sha256_update(&ssl->handshake->fin_sha256, buf, len);
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#endif
#endif
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
#else
mbedtls_sha512_update(&ssl->handshake->fin_sha384, buf, len);
#endif
#endif
#if !defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
!defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
(void) ssl;
#else /* SHA-256 or SHA-384 */
((void) ssl);
(void) buf;
(void) len;
#endif /* SHA-256 or SHA-384 */
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
if (status != PSA_SUCCESS) {
return mbedtls_md_error_from_psa(status);
}
#else
ret = mbedtls_sha256_update(&ssl->handshake->fin_sha256, buf, len);
if (ret != 0) {
return ret;
}
#endif
#endif
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
if (status != PSA_SUCCESS) {
return mbedtls_md_error_from_psa(status);
}
#else
ret = mbedtls_sha512_update(&ssl->handshake->fin_sha384, buf, len);
if (ret != 0) {
return ret;
}
#endif
#endif
return 0;
}
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
static void ssl_update_checksum_sha256(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
static int ssl_update_checksum_sha256(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
return mbedtls_md_error_from_psa(psa_hash_update(
&ssl->handshake->fin_sha256_psa, buf, len));
#else
mbedtls_sha256_update(&ssl->handshake->fin_sha256, buf, len);
return mbedtls_sha256_update(&ssl->handshake->fin_sha256, buf, len);
#endif
}
#endif
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
static void ssl_update_checksum_sha384(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
static int ssl_update_checksum_sha384(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
return mbedtls_md_error_from_psa(psa_hash_update(
&ssl->handshake->fin_sha384_psa, buf, len));
#else
mbedtls_sha512_update(&ssl->handshake->fin_sha384, buf, len);
return mbedtls_sha512_update(&ssl->handshake->fin_sha384, buf, len);
#endif
}
#endif
@ -889,19 +942,15 @@ static void ssl_handshake_params_init(mbedtls_ssl_handshake_params *handshake)
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
handshake->fin_sha256_psa = psa_hash_operation_init();
psa_hash_setup(&handshake->fin_sha256_psa, PSA_ALG_SHA_256);
#else
mbedtls_sha256_init(&handshake->fin_sha256);
mbedtls_sha256_starts(&handshake->fin_sha256, 0);
#endif
#endif
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
handshake->fin_sha384_psa = psa_hash_operation_init();
psa_hash_setup(&handshake->fin_sha384_psa, PSA_ALG_SHA_384);
#else
mbedtls_sha512_init(&handshake->fin_sha384);
mbedtls_sha512_starts(&handshake->fin_sha384, 1);
#endif
#endif
@ -971,6 +1020,8 @@ void mbedtls_ssl_session_init(mbedtls_ssl_session *session)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_handshake_init(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Clear old handshake information if present */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if (ssl->transform_negotiate) {
@ -1038,6 +1089,13 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
mbedtls_ssl_transform_init(ssl->transform_negotiate);
#endif
/* Setup handshake checksums */
ret = mbedtls_ssl_reset_checksum(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_reset_checksum", ret);
return ret;
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
defined(MBEDTLS_SSL_SRV_C) && \
defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -6285,7 +6343,10 @@ static int ssl_compute_master(mbedtls_ssl_handshake_params *handshake,
if (handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) {
lbl = "extended master secret";
seed = session_hash;
handshake->calc_verify(ssl, session_hash, &seed_len);
ret = handshake->calc_verify(ssl, session_hash, &seed_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "calc_verify", ret);
}
MBEDTLS_SSL_DEBUG_BUF(3, "session hash for extended master secret",
session_hash, seed_len);
@ -6513,9 +6574,9 @@ int mbedtls_ssl_set_calc_verify_md(mbedtls_ssl_context *ssl, int md)
}
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl,
unsigned char *hash,
size_t *hlen)
int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl,
unsigned char *hash,
size_t *hlen)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
size_t hash_size;
@ -6525,20 +6586,23 @@ void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify sha256"));
status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
return;
goto exit;
}
status = psa_hash_finish(&sha256_psa, hash, 32, &hash_size);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
return;
goto exit;
}
*hlen = 32;
MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify"));
exit:
psa_hash_abort(&sha256_psa);
return mbedtls_md_error_from_psa(status);
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha256_context sha256;
mbedtls_sha256_init(&sha256);
@ -6546,23 +6610,28 @@ void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify sha256"));
mbedtls_sha256_clone(&sha256, &ssl->handshake->fin_sha256);
mbedtls_sha256_finish(&sha256, hash);
ret = mbedtls_sha256_finish(&sha256, hash);
if (ret != 0) {
goto exit;
}
*hlen = 32;
MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
exit:
mbedtls_sha256_free(&sha256);
return ret;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return;
}
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl,
unsigned char *hash,
size_t *hlen)
int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl,
unsigned char *hash,
size_t *hlen)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
size_t hash_size;
@ -6572,20 +6641,23 @@ void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify sha384"));
status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
return;
goto exit;
}
status = psa_hash_finish(&sha384_psa, hash, 48, &hash_size);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
return;
goto exit;
}
*hlen = 48;
MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify"));
exit:
psa_hash_abort(&sha384_psa);
return mbedtls_md_error_from_psa(status);
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha512_context sha512;
mbedtls_sha512_init(&sha512);
@ -6593,16 +6665,21 @@ void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify sha384"));
mbedtls_sha512_clone(&sha512, &ssl->handshake->fin_sha384);
mbedtls_sha512_finish(&sha512, hash);
ret = mbedtls_sha512_finish(&sha512, hash);
if (ret != 0) {
goto exit;
}
*hlen = 48;
MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify"));
exit:
mbedtls_sha512_free(&sha512);
return ret;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return;
}
#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
@ -7545,7 +7622,7 @@ exit:
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
static void ssl_calc_finished_tls_sha256(
static int ssl_calc_finished_tls_sha256(
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
{
int len = 12;
@ -7556,6 +7633,7 @@ static void ssl_calc_finished_tls_sha256(
psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT;
psa_status_t status;
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha256_context sha256;
#endif
@ -7575,14 +7653,12 @@ static void ssl_calc_finished_tls_sha256(
status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
return;
goto exit;
}
status = psa_hash_finish(&sha256_psa, padbuf, sizeof(padbuf), &hash_size);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
return;
goto exit;
}
MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 32);
#else
@ -7604,8 +7680,10 @@ static void ssl_calc_finished_tls_sha256(
sha256.state, sizeof(sha256.state));
#endif
mbedtls_sha256_finish(&sha256, padbuf);
mbedtls_sha256_free(&sha256);
ret = mbedtls_sha256_finish(&sha256, padbuf);
if (ret != 0) {
goto exit;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
ssl->handshake->tls_prf(session->master, 48, sender,
@ -7616,12 +7694,21 @@ static void ssl_calc_finished_tls_sha256(
mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&sha256_psa);
return mbedtls_md_error_from_psa(status);
#else
mbedtls_sha256_free(&sha256);
return ret;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
static void ssl_calc_finished_tls_sha384(
static int ssl_calc_finished_tls_sha384(
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
{
int len = 12;
@ -7632,6 +7719,7 @@ static void ssl_calc_finished_tls_sha384(
psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT;
psa_status_t status;
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha512_context sha512;
#endif
@ -7651,14 +7739,12 @@ static void ssl_calc_finished_tls_sha384(
status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
return;
goto exit;
}
status = psa_hash_finish(&sha384_psa, padbuf, sizeof(padbuf), &hash_size);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
return;
goto exit;
}
MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 48);
#else
@ -7678,9 +7764,10 @@ static void ssl_calc_finished_tls_sha384(
MBEDTLS_SSL_DEBUG_BUF(4, "finished sha512 state", (unsigned char *)
sha512.state, sizeof(sha512.state));
#endif
mbedtls_sha512_finish(&sha512, padbuf);
mbedtls_sha512_free(&sha512);
ret = mbedtls_sha512_finish(&sha512, padbuf);
if (ret != 0) {
goto exit;
}
#endif
ssl->handshake->tls_prf(session->master, 48, sender,
@ -7691,6 +7778,15 @@ static void ssl_calc_finished_tls_sha384(
mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&sha384_psa);
return mbedtls_md_error_from_psa(status);
#else
mbedtls_sha512_free(&sha512);
return ret;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
@ -7787,7 +7883,10 @@ int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
mbedtls_ssl_update_out_pointers(ssl, ssl->transform_negotiate);
ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint);
ret = ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
}
/*
* RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
@ -7897,7 +7996,10 @@ int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse finished"));
ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
ret = ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
}
if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);

View file

@ -1090,6 +1090,7 @@ static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl,
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
uint16_t dtls_legacy_version;
@ -1160,7 +1161,11 @@ static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl)
/* Start over at ClientHello */
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
mbedtls_ssl_reset_checksum(ssl);
ret = mbedtls_ssl_reset_checksum(ssl);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret);
return ret;
}
mbedtls_ssl_recv_flight_completed(ssl);
@ -3283,7 +3288,11 @@ static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
sign:
#endif
ssl->handshake->calc_verify(ssl, hash, &hashlen);
ret = ssl->handshake->calc_verify(ssl, hash, &hashlen);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret);
return ret;
}
/*
* digitally-signed struct {

View file

@ -1020,7 +1020,11 @@ read_record_header:
MBEDTLS_SSL_DEBUG_BUF(4, "record contents", buf, msg_len);
ssl->handshake->update_checksum(ssl, buf, msg_len);
ret = ssl->handshake->update_checksum(ssl, buf, msg_len);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
return ret;
}
/*
* Handshake layer:
@ -4129,7 +4133,11 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
/* Calculate hash and verify signature */
{
size_t dummy_hlen;
ssl->handshake->calc_verify(ssl, hash, &dummy_hlen);
ret = ssl->handshake->calc_verify(ssl, hash, &dummy_hlen);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret);
return ret;
}
}
if ((ret = mbedtls_pk_verify(peer_pk,
@ -4139,7 +4147,11 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
return ret;
}
mbedtls_ssl_update_handshake_status(ssl);
ret = mbedtls_ssl_update_handshake_status(ssl);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
return ret;
}
MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify"));

View file

@ -893,7 +893,7 @@ int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int configured_psk_count = 0;
unsigned char *p = buf;
psa_algorithm_t hash_alg;
psa_algorithm_t hash_alg = PSA_ALG_NONE;
const unsigned char *identity;
size_t identity_len;
size_t l_binders_len = 0;
@ -1092,6 +1092,7 @@ static int ssl_tls13_parse_server_pre_shared_key_ext(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 2);
selected_identity = MBEDTLS_GET_UINT16_BE(buf, 0);
ssl->handshake->selected_identity = (uint16_t) selected_identity;
MBEDTLS_SSL_DEBUG_MSG(3, ("selected_identity = %d", selected_identity));
@ -1118,6 +1119,16 @@ static int ssl_tls13_parse_server_pre_shared_key_ext(mbedtls_ssl_context *ssl,
return ret;
}
if (mbedtls_psa_translate_md(ssl->handshake->ciphersuite_info->mac)
!= hash_alg) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("Invalid ciphersuite for external psk."));
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
ret = mbedtls_ssl_set_hs_psk(ssl, psk, psk_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
@ -1211,6 +1222,80 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
return 0;
}
int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
{
((void) ssl);
#if defined(MBEDTLS_SSL_EARLY_DATA)
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_algorithm_t hash_alg = PSA_ALG_NONE;
const unsigned char *psk;
size_t psk_len;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO);
#endif
MBEDTLS_SSL_DEBUG_MSG(
1, ("Set hs psk for early data when writing the first psk"));
ret = ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
1, "ssl_tls13_ticket_get_psk", ret);
return ret;
}
ret = mbedtls_ssl_set_hs_psk(ssl, psk, psk_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
return ret;
}
/*
* Early data are going to be encrypted using the ciphersuite
* associated with the pre-shared key used for the handshake.
* Note that if the server rejects early data, the handshake
* based on the pre-shared key may complete successfully
* with a selected ciphersuite different from the ciphersuite
* associated with the pre-shared key. Only the hashes of the
* two ciphersuites have to be the same. In that case, the
* encrypted handshake data and application data are
* encrypted using a different ciphersuite than the one used for
* the rejected early data.
*/
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
ssl->session_negotiate->ciphersuite);
ssl->handshake->ciphersuite_info = ciphersuite_info;
/* Enable psk and psk_ephermal to make stage early happy */
ssl->handshake->key_exchange_mode =
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
/* Start the TLS 1.3 key schedule:
* Set the PSK and derive early secret.
*/
ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret);
return ret;
}
/* Derive early data key material */
ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
1, "mbedtls_ssl_tls13_compute_early_transform", ret);
return ret;
}
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
return 0;
}
/*
* Functions for parsing and processing Server Hello
*/
@ -1404,8 +1489,9 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
ssl->keep_current_message = 1;
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_SERVER_HELLO,
buf, (size_t) (end - buf));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_SERVER_HELLO,
buf, (size_t) (end - buf)));
if (mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
ret = ssl_tls13_reset_key_share(ssl);
@ -1627,8 +1713,6 @@ static int ssl_tls13_parse_server_hello(mbedtls_ssl_context *ssl,
mbedtls_ssl_optimize_checksum(ssl, ciphersuite_info);
handshake->ciphersuite_info = ciphersuite_info;
ssl->session_negotiate->ciphersuite = cipher_suite;
MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: ( %04x ) - %s",
cipher_suite, ciphersuite_info->name));
@ -1824,8 +1908,39 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
goto cleanup;
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(EARLY_DATA) &&
(handshake->selected_identity != 0 ||
handshake->ciphersuite_info->id !=
ssl->session_negotiate->ciphersuite)) {
/* RFC8446 4.2.11
* If the server supplies an "early_data" extension, the
* client MUST verify that the server's selected_identity
* is 0. If any other value is returned, the client MUST
* abort the handshake with an "illegal_parameter" alert.
*
* RFC 8446 4.2.10
* In order to accept early data, the server MUST have accepted a PSK
* cipher suite and selected the first key offered in the client's
* "pre_shared_key" extension. In addition, it MUST verify that the
* following values are the same as those associated with the
* selected PSK:
* - The TLS version number
* - The selected cipher suite
* - The selected ALPN [RFC7301] protocol, if any
*
* We check here that when early data is involved the server
* selected the cipher suite associated to the pre-shared key
* as it must have.
*/
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
#endif
if (!mbedtls_ssl_conf_tls13_check_kex_modes(ssl, handshake->key_exchange_mode)) {
if (!mbedtls_ssl_conf_tls13_check_kex_modes(
ssl, handshake->key_exchange_mode)) {
ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
MBEDTLS_SSL_DEBUG_MSG(2,
("Key exchange mode(%s) is not supported.",
@ -1837,16 +1952,27 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
("Selected key exchange mode: %s",
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
/* Start the TLS 1.3 key schedule: Set the PSK and derive early secret.
/* Start the TLS 1.3 key scheduling if not already done.
*
* TODO: We don't have to do this in case we offered 0-RTT and the
* server accepted it. In this case, we could skip generating
* the early secret. */
ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_key_schedule_stage_early",
ret);
goto cleanup;
* If we proposed early data then we have already derived an
* early secret using the selected PSK and its associated hash.
* It means that if the negotiated key exchange mode is psk or
* psk_ephemeral, we have already correctly computed the
* early secret and thus we do not do it again. In all other
* cases we compute it here.
*/
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT ||
handshake->key_exchange_mode ==
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL)
#endif
{
ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret);
goto cleanup;
}
}
ret = mbedtls_ssl_tls13_compute_handshake_transform(ssl);
@ -1859,6 +1985,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
mbedtls_ssl_set_inbound_transform(ssl, handshake->transform_handshake);
MBEDTLS_SSL_DEBUG_MSG(1, ("Switch to handshake keys for inbound traffic"));
ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id;
ssl->session_in = ssl->session_negotiate;
cleanup:
@ -1889,6 +2016,7 @@ static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl)
return ret;
}
ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id;
return 0;
}
@ -1929,8 +2057,9 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_reset_transcript_for_hrr(ssl));
}
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_SERVER_HELLO,
buf, buf_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_SERVER_HELLO, buf,
buf_len));
if (is_hrr) {
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_hrr(ssl));
@ -2087,8 +2216,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
}
#endif
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
buf, buf_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
buf, buf_len));
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
@ -2108,6 +2238,44 @@ cleanup:
}
/*
* Handler for MBEDTLS_SSL_END_OF_EARLY_DATA
*
* RFC 8446 section 4.5
*
* struct {} EndOfEarlyData;
*
* If the server sent an "early_data" extension in EncryptedExtensions, the
* client MUST send an EndOfEarlyData message after receiving the server
* Finished. Otherwise, the client MUST NOT send an EndOfEarlyData message.
*/
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_write_end_of_early_data(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *buf = NULL;
size_t buf_len;
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write EndOfEarlyData"));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA,
&buf, &buf_len));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_hdr_to_checksum(
ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, 0));
MBEDTLS_SSL_PROC_CHK(
mbedtls_ssl_finish_handshake_msg(ssl, buf_len, 0));
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
cleanup:
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write EndOfEarlyData"));
return ret;
}
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
/*
* STATE HANDLING: CertificateRequest
@ -2293,8 +2461,9 @@ static int ssl_tls13_process_certificate_request(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request(ssl,
buf, buf + buf_len));
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
buf, buf_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
buf, buf_len));
} else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) {
ret = 0;
} else {
@ -2367,13 +2536,21 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
return ret;
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
} else if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
} else
#endif /* MBEDTLS_SSL_EARLY_DATA */
{
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
mbedtls_ssl_handshake_set_state(
ssl,
MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED);
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED);
#else
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
}
return 0;
}
@ -2789,6 +2966,10 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
ret = ssl_tls13_process_server_finished(ssl);
break;
case MBEDTLS_SSL_END_OF_EARLY_DATA:
ret = ssl_tls13_write_end_of_early_data(ssl);
break;
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
ret = ssl_tls13_write_client_certificate(ssl);
break;
@ -2828,6 +3009,20 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
}
break;
case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO:
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret == 0) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
#if defined(MBEDTLS_SSL_EARLY_DATA)
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
#endif
}
break;
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)

View file

@ -322,8 +322,9 @@ int mbedtls_ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl)
buf + buf_len, verify_buffer,
verify_buffer_len));
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY,
buf, buf_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_CERTIFICATE_VERIFY,
buf, buf_len));
cleanup:
@ -752,8 +753,9 @@ int mbedtls_ssl_tls13_process_certificate(mbedtls_ssl_context *ssl)
/* Validate the certificate chain and set the verification results. */
MBEDTLS_SSL_PROC_CHK(ssl_tls13_validate_certificate(ssl));
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE,
buf, buf_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_CERTIFICATE, buf,
buf_len));
cleanup:
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
@ -868,8 +870,9 @@ int mbedtls_ssl_tls13_write_certificate(mbedtls_ssl_context *ssl)
buf + buf_len,
&msg_len));
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE,
buf, msg_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_CERTIFICATE, buf,
msg_len));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
ssl, buf_len, msg_len));
@ -1070,8 +1073,9 @@ int mbedtls_ssl_tls13_write_certificate_verify(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_verify_body(
ssl, buf, buf + buf_len, &msg_len));
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY,
buf, msg_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, buf,
msg_len));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
ssl, buf_len, msg_len));
@ -1171,8 +1175,8 @@ int mbedtls_ssl_tls13_process_finished_message(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_finished_message(ssl, buf, buf + buf_len));
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_FINISHED,
buf, buf_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_FINISHED, buf, buf_len));
cleanup:
@ -1248,8 +1252,8 @@ int mbedtls_ssl_tls13_write_finished_message(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_finished_message_body(
ssl, buf, buf + buf_len, &msg_len));
mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_FINISHED,
buf, msg_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
MBEDTLS_SSL_HS_FINISHED, buf, msg_len));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
ssl, buf_len, msg_len));
@ -1378,9 +1382,8 @@ int mbedtls_ssl_reset_transcript_for_hrr(mbedtls_ssl_context *ssl)
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char hash_transcript[PSA_HASH_MAX_SIZE + 4];
size_t hash_len;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
uint16_t cipher_suite = ssl->session_negotiate->ciphersuite;
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(cipher_suite);
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG(3, ("Reset SSL session for HRR"));
@ -1389,7 +1392,7 @@ int mbedtls_ssl_reset_transcript_for_hrr(mbedtls_ssl_context *ssl)
PSA_HASH_MAX_SIZE,
&hash_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(4, "mbedtls_ssl_get_handshake_transcript", ret);
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_handshake_transcript", ret);
return ret;
}
@ -1400,37 +1403,20 @@ int mbedtls_ssl_reset_transcript_for_hrr(mbedtls_ssl_context *ssl)
hash_len += 4;
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
if (ciphersuite_info->mac == MBEDTLS_MD_SHA256) {
MBEDTLS_SSL_DEBUG_BUF(4, "Truncated SHA-256 handshake transcript",
hash_transcript, hash_len);
MBEDTLS_SSL_DEBUG_BUF(4, "Truncated handshake transcript",
hash_transcript, hash_len);
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&ssl->handshake->fin_sha256_psa);
psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256);
#else
mbedtls_sha256_starts(&ssl->handshake->fin_sha256, 0);
#endif
/* Reset running hash and replace it with a hash of the transcript */
ret = mbedtls_ssl_reset_checksum(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_reset_checksum", ret);
return ret;
}
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
if (ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
MBEDTLS_SSL_DEBUG_BUF(4, "Truncated SHA-384 handshake transcript",
hash_transcript, hash_len);
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&ssl->handshake->fin_sha384_psa);
psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384);
#else
mbedtls_sha512_starts(&ssl->handshake->fin_sha384, 1);
#endif
ret = ssl->handshake->update_checksum(ssl, hash_transcript, hash_len);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
return ret;
}
#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) || \
defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
ssl->handshake->update_checksum(ssl, hash_transcript, hash_len);
#endif \
/* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA || MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
return ret;
}

View file

@ -1127,10 +1127,10 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
size_t transcript_len;
size_t key_len;
size_t iv_len;
mbedtls_ssl_tls13_early_secrets tls13_early_secrets;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = handshake->ciphersuite_info;
mbedtls_ssl_tls13_early_secrets *tls13_early_secrets = &handshake->tls13_early_secrets;
MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_early_key"));
@ -1158,7 +1158,7 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
ret = mbedtls_ssl_tls13_derive_early_secrets(
hash_alg, handshake->tls13_master_secrets.early,
transcript, transcript_len, tls13_early_secrets);
transcript, transcript_len, &tls13_early_secrets);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
1, "mbedtls_ssl_tls13_derive_early_secrets", ret);
@ -1167,7 +1167,7 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF(
4, "Client early traffic secret",
tls13_early_secrets->client_early_traffic_secret, hash_len);
tls13_early_secrets.client_early_traffic_secret, hash_len);
/*
* Export client handshake traffic secret
@ -1176,7 +1176,7 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
ssl->f_export_keys(
ssl->p_export_keys,
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET,
tls13_early_secrets->client_early_traffic_secret,
tls13_early_secrets.client_early_traffic_secret,
hash_len,
handshake->randbytes,
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
@ -1185,7 +1185,7 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
ret = ssl_tls13_make_traffic_key(
hash_alg,
tls13_early_secrets->client_early_traffic_secret,
tls13_early_secrets.client_early_traffic_secret,
hash_len, traffic_keys->client_write_key, key_len,
traffic_keys->client_write_iv, iv_len);
if (ret != 0) {
@ -1206,9 +1206,9 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_early_key"));
cleanup:
/* Erase secret and transcript */
/* Erase early secrets and transcript */
mbedtls_platform_zeroize(
tls13_early_secrets, sizeof(mbedtls_ssl_tls13_early_secrets));
&tls13_early_secrets, sizeof(mbedtls_ssl_tls13_early_secrets));
mbedtls_platform_zeroize(transcript, sizeof(transcript));
return ret;
}
@ -1238,7 +1238,7 @@ int mbedtls_ssl_tls13_compute_early_transform(mbedtls_ssl_context *ssl)
ret = mbedtls_ssl_tls13_populate_transform(
transform_earlydata,
ssl->conf->endpoint,
ssl->session_negotiate->ciphersuite,
handshake->ciphersuite_info->id,
&traffic_keys,
ssl);
if (ret != 0) {
@ -1699,7 +1699,7 @@ int mbedtls_ssl_tls13_compute_handshake_transform(mbedtls_ssl_context *ssl)
ret = mbedtls_ssl_tls13_populate_transform(
transform_handshake,
ssl->conf->endpoint,
ssl->session_negotiate->ciphersuite,
handshake->ciphersuite_info->id,
&traffic_keys,
ssl);
if (ret != 0) {
@ -1789,7 +1789,7 @@ int mbedtls_ssl_tls13_compute_application_transform(mbedtls_ssl_context *ssl)
ret = mbedtls_ssl_tls13_populate_transform(
transform_application,
ssl->conf->endpoint,
ssl->session_negotiate->ciphersuite,
ssl->handshake->ciphersuite_info->id,
&traffic_keys,
ssl);
if (ret != 0) {

View file

@ -486,6 +486,7 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl,
const unsigned char *ciphersuites,
const unsigned char *ciphersuites_end)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *identities = pre_shared_key_ext;
const unsigned char *p_identity_len;
size_t identities_len;
@ -521,8 +522,12 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_READ_PTR(p_binder_len, pre_shared_key_ext_end, binders_len);
binders_end = p_binder_len + binders_len;
ssl->handshake->update_checksum(ssl, pre_shared_key_ext,
identities_end - pre_shared_key_ext);
ret = ssl->handshake->update_checksum(ssl, pre_shared_key_ext,
identities_end - pre_shared_key_ext);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
return ret;
}
while (p_identity_len < identities_end && p_binder_len < binders_end) {
const unsigned char *identity;
@ -530,7 +535,6 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl,
uint32_t obfuscated_ticket_age;
const unsigned char *binder;
size_t binder_len;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int psk_type;
uint16_t cipher_suite;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
@ -642,9 +646,13 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl,
}
/* Update the handshake transcript with the binder list. */
ssl->handshake->update_checksum(ssl,
identities_end,
(size_t) (binders_end - identities_end));
ret = ssl->handshake->update_checksum(ssl,
identities_end,
(size_t) (binders_end - identities_end));
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
return ret;
}
if (matched_identity == -1) {
MBEDTLS_SSL_DEBUG_MSG(3, ("No matched PSK or ticket."));
return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
@ -1590,9 +1598,13 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_CLIENT_HELLO,
handshake->received_extensions);
mbedtls_ssl_add_hs_hdr_to_checksum(ssl,
MBEDTLS_SSL_HS_CLIENT_HELLO,
p - buf);
ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl,
MBEDTLS_SSL_HS_CLIENT_HELLO,
p - buf);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_add_hs_hdr_to_checksum"), ret);
return ret;
}
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/* Update checksum with either
@ -1603,8 +1615,12 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
if (mbedtls_ssl_tls13_some_psk_enabled(ssl) &&
mbedtls_ssl_conf_tls13_some_psk_enabled(ssl) &&
(handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY))) {
handshake->update_checksum(ssl, buf,
pre_shared_key_ext - buf);
ret = handshake->update_checksum(ssl, buf,
pre_shared_key_ext - buf);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
return ret;
}
ret = ssl_tls13_parse_pre_shared_key_ext(ssl,
pre_shared_key_ext,
pre_shared_key_ext_end,
@ -1620,7 +1636,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
} else
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
{
handshake->update_checksum(ssl, buf, p - buf);
ret = handshake->update_checksum(ssl, buf, p - buf);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
return ret;
}
}
ret = ssl_tls13_determine_key_exchange_mode(ssl);
@ -2100,7 +2120,7 @@ static int ssl_tls13_write_server_hello_body(mbedtls_ssl_context *ssl,
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_finalize_write_server_hello(mbedtls_ssl_context *ssl)
static int ssl_tls13_finalize_server_hello(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_ssl_tls13_compute_handshake_transform(ssl);
@ -2134,13 +2154,13 @@ static int ssl_tls13_write_server_hello(mbedtls_ssl_context *ssl)
&msg_len,
0));
mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
ssl, buf_len, msg_len));
MBEDTLS_SSL_PROC_CHK(ssl_tls13_finalize_write_server_hello(ssl));
MBEDTLS_SSL_PROC_CHK(ssl_tls13_finalize_server_hello(ssl));
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
/* The server sends a dummy change_cipher_spec record immediately
@ -2207,8 +2227,8 @@ static int ssl_tls13_write_hello_retry_request(mbedtls_ssl_context *ssl)
buf + buf_len,
&msg_len,
1));
mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl, buf_len,
@ -2306,8 +2326,8 @@ static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_encrypted_extensions_body(
ssl, buf, buf + buf_len, &msg_len));
mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, msg_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, msg_len));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
ssl, buf_len, msg_len));
@ -2439,8 +2459,8 @@ static int ssl_tls13_write_certificate_request(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_request_body(
ssl, buf, buf + buf_len, &msg_len));
mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, buf, msg_len);
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, buf, msg_len));
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
ssl, buf_len, msg_len));

View file

@ -1156,11 +1156,6 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
}
if (p + len >= end) {
mbedtls_platform_zeroize(other_name, sizeof(*other_name));
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
p += len;
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
@ -1168,11 +1163,21 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
}
if (end != p + len) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
}
if (end != p + len) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
}
@ -1181,11 +1186,6 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
other_name->value.hardware_module_name.oid.p = p;
other_name->value.hardware_module_name.oid.len = len;
if (p + len >= end) {
mbedtls_platform_zeroize(other_name, sizeof(*other_name));
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
p += len;
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_OCTET_STRING)) != 0) {
@ -1197,8 +1197,6 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
other_name->value.hardware_module_name.val.len = len;
p += len;
if (p != end) {
mbedtls_platform_zeroize(other_name,
sizeof(*other_name));
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
@ -1229,8 +1227,9 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
* nameAssigner [0] DirectoryString OPTIONAL,
* partyName [1] DirectoryString }
*
* NOTE: we list all types, but only use dNSName and otherName
* of type HwModuleName, as defined in RFC 4108, at this point.
* We list all types, but use the following GeneralName types from RFC 5280:
* "dnsName", "uniformResourceIdentifier" and "hardware_module_name"
* of type "otherName", as defined in RFC 4108.
*/
int mbedtls_x509_get_subject_alt_name(unsigned char **p,
const unsigned char *end,
@ -1238,8 +1237,6 @@ int mbedtls_x509_get_subject_alt_name(unsigned char **p,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len, tag_len;
mbedtls_asn1_buf *buf;
unsigned char tag;
mbedtls_asn1_sequence *cur = subject_alt_name;
/* Get main sequence tag */
@ -1255,15 +1252,20 @@ int mbedtls_x509_get_subject_alt_name(unsigned char **p,
while (*p < end) {
mbedtls_x509_subject_alternative_name dummy_san_buf;
mbedtls_x509_buf tmp_san_buf;
memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
tag = **p;
tmp_san_buf.tag = **p;
(*p)++;
if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
}
if ((tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
tmp_san_buf.p = *p;
tmp_san_buf.len = tag_len;
if ((tmp_san_buf.tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
@ -1272,7 +1274,7 @@ int mbedtls_x509_get_subject_alt_name(unsigned char **p,
/*
* Check that the SAN is structured correctly.
*/
ret = mbedtls_x509_parse_subject_alt_name(&(cur->buf), &dummy_san_buf);
ret = mbedtls_x509_parse_subject_alt_name(&tmp_san_buf, &dummy_san_buf);
/*
* In case the extension is malformed, return an error,
* and clear the allocated sequences.
@ -1299,11 +1301,8 @@ int mbedtls_x509_get_subject_alt_name(unsigned char **p,
cur = cur->next;
}
buf = &(cur->buf);
buf->tag = tag;
buf->p = *p;
buf->len = tag_len;
*p += buf->len;
cur->buf = tmp_san_buf;
*p += tmp_san_buf.len;
}
/* Set final sequence entry's next pointer to NULL */
@ -1399,7 +1398,19 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
}
break;
/*
* uniformResourceIdentifier
*/
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER):
{
memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
san->type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
memcpy(&san->san.unstructured_name,
san_buf, sizeof(*san_buf));
}
break;
/*
* dNSName
*/
@ -1410,7 +1421,17 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
memcpy(&san->san.unstructured_name,
san_buf, sizeof(*san_buf));
}
break;
/*
* RFC822 Name
*/
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_RFC822_NAME):
{
memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
san->type = MBEDTLS_X509_SAN_RFC822_NAME;
memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf));
}
break;
@ -1490,13 +1511,38 @@ int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
}/* MBEDTLS_OID_ON_HW_MODULE_NAME */
}
break;
/*
* uniformResourceIdentifier
*/
case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
{
ret = mbedtls_snprintf(p, n, "\n%s uniformResourceIdentifier : ", prefix);
MBEDTLS_X509_SAFE_SNPRINTF;
if (san.san.unstructured_name.len >= n) {
*p = '\0';
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
p += san.san.unstructured_name.len;
n -= san.san.unstructured_name.len;
}
break;
/*
* dNSName
* RFC822 Name
*/
case MBEDTLS_X509_SAN_DNS_NAME:
case MBEDTLS_X509_SAN_RFC822_NAME:
{
ret = mbedtls_snprintf(p, n, "\n%s dNSName : ", prefix);
const char *dns_name = "dNSName";
const char *rfc822_name = "rfc822Name";
ret = mbedtls_snprintf(p, n,
"\n%s %s : ",
prefix,
san.type ==
MBEDTLS_X509_SAN_DNS_NAME ? dns_name : rfc822_name);
MBEDTLS_X509_SAFE_SNPRINTF;
if (san.san.unstructured_name.len >= n) {
*p = '\0';

View file

@ -1449,8 +1449,8 @@ int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path)
}
w_ret = WideCharToMultiByte(CP_ACP, 0, file_data.cFileName,
lstrlenW(file_data.cFileName),
p, (int) len - 1,
-1,
p, (int) len,
NULL, NULL);
if (w_ret == 0) {
ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;

1
programs/.gitignore vendored
View file

@ -64,6 +64,7 @@ test/cpp_dummy_build.cpp
test/dlopen
test/ecp-bench
test/query_compile_time_config
test/query_included_headers
test/selftest
test/ssl_cert_test
test/udp_proxy

View file

@ -123,6 +123,7 @@ APPS = \
ssl/ssl_server2 \
test/benchmark \
test/query_compile_time_config \
test/query_included_headers \
test/selftest \
test/udp_proxy \
test/zeroize \
@ -403,6 +404,10 @@ test/query_config.o: test/query_config.c test/query_config.h $(DEP)
echo " CC test/query_config.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c test/query_config.c -o $@
test/query_included_headers$(EXEXT): test/query_included_headers.c $(DEP)
echo " CC test/query_included_headers.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/query_included_headers.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
test/selftest$(EXEXT): test/selftest.c $(DEP)
echo " CC test/selftest.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/selftest.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@

View file

@ -3,6 +3,7 @@ set(libs
)
set(executables_libs
query_included_headers
selftest
udp_proxy
)

View file

@ -0,0 +1,41 @@
/* Ad hoc report on included headers. */
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <psa/crypto.h>
#include <mbedtls/platform.h>
int main(void)
{
/* Which PSA platform header? */
#if defined(PSA_CRYPTO_PLATFORM_H)
mbedtls_printf("PSA_CRYPTO_PLATFORM_H\n");
#endif
#if defined(PSA_CRYPTO_PLATFORM_ALT_H)
mbedtls_printf("PSA_CRYPTO_PLATFORM_ALT_H\n");
#endif
/* Which PSA struct header? */
#if defined(PSA_CRYPTO_STRUCT_H)
mbedtls_printf("PSA_CRYPTO_STRUCT_H\n");
#endif
#if defined(PSA_CRYPTO_STRUCT_ALT_H)
mbedtls_printf("PSA_CRYPTO_STRUCT_ALT_H\n");
#endif
}

View file

@ -340,6 +340,32 @@ int main(int argc, char *argv[])
#endif
void *pointer;
/*
* Check some basic platform requirements as specified in README.md
*/
if (SIZE_MAX < INT_MAX || SIZE_MAX < UINT_MAX) {
mbedtls_printf("SIZE_MAX must be at least as big as INT_MAX and UINT_MAX\n");
mbedtls_exit(MBEDTLS_EXIT_FAILURE);
}
if (sizeof(int) < 4) {
mbedtls_printf("int must be at least 32 bits\n");
mbedtls_exit(MBEDTLS_EXIT_FAILURE);
}
if (sizeof(size_t) < 4) {
mbedtls_printf("size_t must be at least 32 bits\n");
mbedtls_exit(MBEDTLS_EXIT_FAILURE);
}
uint32_t endian_test = 0x12345678;
char *p = (char *) &endian_test;
if (!(p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78) &&
!(p[3] == 0x12 && p[2] == 0x34 && p[1] == 0x56 && p[0] == 0x78)) {
mbedtls_printf("Mixed-endian platforms are not supported\n");
mbedtls_exit(MBEDTLS_EXIT_FAILURE);
}
/*
* The C standard doesn't guarantee that all-bits-0 is the representation
* of a NULL pointer. We do however use that in our code for initializing

View file

@ -33,6 +33,14 @@ CHECK_GENERATED_FILES = "tests/scripts/check-generated-files.sh"
def print_err(*args):
print("Error: ", *args, file=sys.stderr)
# Print the file names that will be skipped and the help message
def print_skip(files_to_skip):
print()
print(*files_to_skip, sep=", SKIP\n", end=", SKIP\n")
print("Warning: The listed files will be skipped because\n"
"they are not known to git.")
print()
# Match FILENAME(s) in "check SCRIPT (FILENAME...)"
CHECK_CALL_RE = re.compile(r"\n\s*check\s+[^\s#$&*?;|]+([^\n#$&*?;|]+)",
re.ASCII)
@ -174,22 +182,27 @@ 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)'))
# --files is almost useless: it only matters if there are no files
# --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 --files' does nothing). In particular,
# 'code_style.py --fix --files ...' is intended as a stable ("porcelain")
# 'code_style.py --subset' does nothing). In particular,
# 'code_style.py --fix --subset ...' is intended as a stable ("porcelain")
# way to restyle a possibly empty set of files.
parser.add_argument('--files', action='store_true',
parser.add_argument('--subset', action='store_true',
help='only check the specified files (default with non-option arguments)')
parser.add_argument('operands', nargs='*', metavar='FILE',
help='files to check (if none: check files that are known to git)')
help='files to check (files MUST be known to git, if none: check all)')
args = parser.parse_args()
if args.files or args.operands:
src_files = args.operands
covered = frozenset(get_src_files())
# 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]
skip_src_files = [f for f in args.operands if f not in covered]
if skip_src_files:
print_skip(skip_src_files)
else:
src_files = get_src_files()
src_files = list(covered)
if args.fix:
# Fix mode

View file

@ -433,6 +433,251 @@ psa_status_t psa_driver_wrapper_verify_hash(
}
}
uint32_t psa_driver_wrapper_sign_hash_get_num_ops(
psa_sign_hash_interruptible_operation_t *operation )
{
switch( operation->id )
{
/* If uninitialised, return 0, as no work can have been done. */
case 0:
return 0;
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
return(mbedtls_psa_sign_hash_get_num_ops(&operation->ctx.mbedtls_ctx));
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
/* Add test driver tests here */
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
}
return( PSA_ERROR_INVALID_ARGUMENT );
}
uint32_t psa_driver_wrapper_verify_hash_get_num_ops(
psa_verify_hash_interruptible_operation_t *operation )
{
switch( operation->id )
{
/* If uninitialised, return 0, as no work can have been done. */
case 0:
return 0;
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
return (mbedtls_psa_verify_hash_get_num_ops(&operation->ctx.mbedtls_ctx));
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
/* Add test driver tests here */
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
}
return( PSA_ERROR_INVALID_ARGUMENT );
}
psa_status_t psa_driver_wrapper_sign_hash_start(
psa_sign_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
size_t key_buffer_size, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length )
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
PSA_KEY_LIFETIME_GET_LOCATION(
attributes->core.lifetime );
switch( location )
{
case PSA_KEY_LOCATION_LOCAL_STORAGE:
/* Key is stored in the slot in export representation, so
* cycle through all known transparent accelerators */
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
/* Add test driver tests here */
/* Declared with fallback == true */
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
/* Fell through, meaning no accelerator supports this operation */
operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
return( mbedtls_psa_sign_hash_start( &operation->ctx.mbedtls_ctx,
attributes,
key_buffer, key_buffer_size,
alg, hash, hash_length ) );
break;
/* Add cases for opaque driver here */
default:
/* Key is declared with a lifetime not known to us */
( void ) status;
return( PSA_ERROR_INVALID_ARGUMENT );
}
( void ) operation;
( void ) key_buffer;
( void ) key_buffer_size;
( void ) alg;
( void ) hash;
( void ) hash_length;
return( status );
}
psa_status_t psa_driver_wrapper_sign_hash_complete(
psa_sign_hash_interruptible_operation_t *operation,
uint8_t *signature, size_t signature_size,
size_t *signature_length )
{
switch( operation->id )
{
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
return( mbedtls_psa_sign_hash_complete( &operation->ctx.mbedtls_ctx,
signature, signature_size,
signature_length ) );
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
/* Add test driver tests here */
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
}
( void ) signature;
( void ) signature_size;
( void ) signature_length;
return( PSA_ERROR_INVALID_ARGUMENT );
}
psa_status_t psa_driver_wrapper_sign_hash_abort(
psa_sign_hash_interruptible_operation_t *operation )
{
switch( operation->id )
{
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
return( mbedtls_psa_sign_hash_abort( &operation->ctx.mbedtls_ctx ) );
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
/* Add test driver tests here */
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
}
return( PSA_ERROR_INVALID_ARGUMENT );
}
psa_status_t psa_driver_wrapper_verify_hash_start(
psa_verify_hash_interruptible_operation_t *operation,
const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
size_t key_buffer_size, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length )
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
attributes->core.lifetime );
switch( location )
{
case PSA_KEY_LOCATION_LOCAL_STORAGE:
/* Key is stored in the slot in export representation, so
* cycle through all known transparent accelerators */
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
/* Add test driver tests here */
/* Declared with fallback == true */
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
/* Fell through, meaning no accelerator supports this operation */
operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
return( mbedtls_psa_verify_hash_start( &operation->ctx.mbedtls_ctx,
attributes,
key_buffer, key_buffer_size,
alg, hash, hash_length,
signature, signature_length
) );
break;
/* Add cases for opaque driver here */
default:
/* Key is declared with a lifetime not known to us */
( void ) status;
return( PSA_ERROR_INVALID_ARGUMENT );
}
( void ) operation;
( void ) key_buffer;
( void ) key_buffer_size;
( void ) alg;
( void ) hash;
( void ) hash_length;
( void ) signature;
( void ) signature_length;
return( status );
}
psa_status_t psa_driver_wrapper_verify_hash_complete(
psa_verify_hash_interruptible_operation_t *operation )
{
switch( operation->id )
{
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
return( mbedtls_psa_verify_hash_complete(
&operation->ctx.mbedtls_ctx
) );
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
/* Add test driver tests here */
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
}
return( PSA_ERROR_INVALID_ARGUMENT );
}
psa_status_t psa_driver_wrapper_verify_hash_abort(
psa_verify_hash_interruptible_operation_t *operation )
{
switch( operation->id )
{
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
return( mbedtls_psa_verify_hash_abort( &operation->ctx.mbedtls_ctx
) );
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
#if defined(PSA_CRYPTO_DRIVER_TEST)
/* Add test driver tests here */
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
}
return( PSA_ERROR_INVALID_ARGUMENT );
}
/** Calculate the key buffer size required to store the key material of a key
* associated with an opaque driver from input key data.
*
@ -441,9 +686,9 @@ psa_status_t psa_driver_wrapper_verify_hash(
* \param[in] data_length The input data length.
* \param[out] key_buffer_size Minimum buffer size to contain the key material.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
*/
psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data(
const psa_key_attributes_t *attributes,
@ -1182,8 +1427,9 @@ psa_status_t psa_driver_wrapper_cipher_decrypt_setup(
operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
return( status );
#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
#else /* MBEDTLS_PSA_BUILTIN_CIPHER */
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
/* Add cases for opaque driver here */
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)

View file

@ -11,4 +11,5 @@ python scripts\generate_ssl_debug_helpers.py || exit /b 1
perl scripts\generate_visualc_files.pl || exit /b 1
python scripts\generate_psa_constants.py || exit /b 1
python tests\scripts\generate_bignum_tests.py || exit /b 1
python tests\scripts\generate_ecp_tests.py || exit /b 1
python tests\scripts\generate_psa_tests.py || exit /b 1

168
scripts/mbedtls_dev/ecp.py Normal file
View file

@ -0,0 +1,168 @@
"""Framework classes for generation of ecp test cases."""
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List
from . import test_data_generation
from . import bignum_common
class EcpTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
"""Target for ecp test case generation."""
target_basename = 'test_suite_ecp.generated'
class EcpP192R1Raw(bignum_common.ModOperationCommon,
EcpTarget):
"""Test cases for ecp quasi_reduction()."""
symbol = "-"
test_function = "ecp_mod_p192_raw"
test_name = "ecp_mod_p192_raw"
input_style = "fixed"
arity = 1
moduli = ["fffffffffffffffffffffffffffffffeffffffffffffffff"] # type: List[str]
input_values = [
"0", "1",
# Modulus - 1
"fffffffffffffffffffffffffffffffefffffffffffffffe",
# First 8 number generated by random.getrandbits(384) - seed(2,2)
("cf1822ffbc6887782b491044d5e341245c6e433715ba2bdd"
"177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
("ffed9235288bc781ae66267594c9c9500925e4749b575bd1"
"3653f8dd9b1f282e4067c3584ee207f8da94e3e8ab73738f"),
("ef8acd128b4f2fc15f3f57ebf30b94fa82523e86feac7eb7"
"dc38f519b91751dacdbd47d364be8049a372db8f6e405d93"),
("e8624fab5186ee32ee8d7ee9770348a05d300cb90706a045"
"defc044a09325626e6b58de744ab6cce80877b6f71e1f6d2"),
("2d3d854e061b90303b08c6e33c7295782d6c797f8f7d9b78"
"2a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"),
("fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f1"
"5c14bc4a829e07b0829a48d422fe99a22c70501e533c9135"),
("97eeab64ca2ce6bc5d3fd983c34c769fe89204e2e8168561"
"867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2"),
("bd143fa9b714210c665d7435c1066932f4767f26294365b2"
"721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b"),
# Next 2 number generated by random.getrandbits(192)
"47733e847d718d733ff98ff387c56473a7a83ee0761ebfd2",
"cbd4d3e2d4dec9ef83f0be4e80371eb97f81375eecc1cb63"
]
@property
def arg_a(self) -> str:
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
def result(self) -> List[str]:
result = self.int_a % self.int_n
return [self.format_result(result)]
@property
def is_valid(self) -> bool:
return True
class EcpP521R1Raw(bignum_common.ModOperationCommon,
EcpTarget):
"""Test cases for ecp quasi_reduction()."""
test_function = "ecp_mod_p521_raw"
test_name = "ecp_mod_p521_raw"
input_style = "arch_split"
arity = 1
moduli = [("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
] # type: List[str]
input_values = [
"0", "1",
# Corner case: maximum canonical P521 multiplication result
("0003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"fffff800"
"0000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000004"),
# Test case for overflow during addition
("0001efffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"000001ef"
"0000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000f000000"),
# First 8 number generated by random.getrandbits(1042) - seed(2,2)
("0003cc2e82523e86feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f"
"6e405d93ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd"
"9b1f282e"
"4067c3584ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124"
"5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
("00017052829e07b0829a48d422fe99a22c70501e533c91352d3d854e061b9030"
"3b08c6e33c7295782d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c5055"
"6c71c4a6"
"6148a86fe8624fab5186ee32ee8d7ee9770348a05d300cb90706a045defc044a"
"09325626e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57eb"),
("00021f15a7a83ee0761ebfd2bd143fa9b714210c665d7435c1066932f4767f26"
"294365b2721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b97eeab64"
"ca2ce6bc"
"5d3fd983c34c769fe89204e2e8168561867e5e15bc01bfce6a27e0dfcbf87544"
"72154e76e4c11ab2fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f1"),
("000381bc2a838af8d5c44a4eb3172062d08f1bb2531d6460f0caeef038c89b38"
"a8acb5137c9260dc74e088a9b9492f258ebdbfe3eb9ac688b9d39cca91551e82"
"59cc60b1"
"7604e4b4e73695c3e652c71a74667bffe202849da9643a295a9ac6decbd4d3e2"
"d4dec9ef83f0be4e80371eb97f81375eecc1cb6347733e847d718d733ff98ff3"),
("00034816c8c69069134bccd3e1cf4f589f8e4ce0af29d115ef24bd625dd961e6"
"830b54fa7d28f93435339774bb1e386c4fd5079e681b8f5896838b769da59b74"
"a6c3181c"
"81e220df848b1df78feb994a81167346d4c0dca8b4c9e755cc9c3adcf515a823"
"4da4daeb4f3f87777ad1f45ae9500ec9c5e2486c44a4a8f69dc8db48e86ec9c6"),
("000397846c4454b90f756132e16dce72f18e859835e1f291d322a7353ead4efe"
"440e2b4fda9c025a22f1a83185b98f5fc11e60de1b343f52ea748db9e020307a"
"aeb6db2c"
"3a038a709779ac1f45e9dd320c855fdfa7251af0930cdbd30f0ad2a81b2d19a2"
"beaa14a7ff3fe32a30ffc4eed0a7bd04e85bfcdd0227eeb7b9d7d01f5769da05"),
("00002c3296e6bc4d62b47204007ee4fab105d83e85e951862f0981aebc1b00d9"
"2838e766ef9b6bf2d037fe2e20b6a8464174e75a5f834da70569c018eb2b5693"
"babb7fbb"
"0a76c196067cfdcb11457d9cf45e2fa01d7f4275153924800600571fac3a5b26"
"3fdf57cd2c0064975c3747465cc36c270e8a35b10828d569c268a20eb78ac332"),
("00009d23b4917fc09f20dbb0dcc93f0e66dfe717c17313394391b6e2e6eacb0f"
"0bb7be72bd6d25009aeb7fa0c4169b148d2f527e72daf0a54ef25c0707e33868"
"7d1f7157"
"5653a45c49390aa51cf5192bbf67da14be11d56ba0b4a2969d8055a9f03f2d71"
"581d8e830112ff0f0948eccaf8877acf26c377c13f719726fd70bddacb4deeec"),
# Next 2 number generated by random.getrandbits(521)
("12b84ae65e920a63ac1f2b64df6dff07870c9d531ae72a47403063238da1a1fe"
"3f9d6a179fa50f96cd4aff9261aa92c0e6f17ec940639bc2ccdf572df00790813e3"),
("166049dd332a73fa0b26b75196cf87eb8a09b27ec714307c68c425424a1574f1"
"eedf5b0f16cdfdb839424d201e653f53d6883ca1c107ca6e706649889c0c7f38608")
]
@property
def arg_a(self) -> str:
# Number of limbs: 2 * N
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
def result(self) -> List[str]:
result = self.int_a % self.int_n
return [self.format_result(result)]
@property
def is_valid(self) -> bool:
return True

2
tests/.gitignore vendored
View file

@ -13,6 +13,8 @@ data_files/hmac_drbg_seed
data_files/ctr_drbg_seed
data_files/entropy_seed
include/alt-extra/psa/crypto_platform_alt.h
include/alt-extra/psa/crypto_struct_alt.h
include/test/instrument_record_status.h
src/*.o

View file

@ -29,6 +29,18 @@ execute_process(
string(REGEX REPLACE "[^;]*/" ""
base_bignum_generated_data_files "${base_bignum_generated_data_files}")
execute_process(
COMMAND
${MBEDTLS_PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_ecp_tests.py
--list-for-cmake
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}/..
OUTPUT_VARIABLE
base_ecp_generated_data_files)
string(REGEX REPLACE "[^;]*/" ""
base_ecp_generated_data_files "${base_ecp_generated_data_files}")
execute_process(
COMMAND
${MBEDTLS_PYTHON_EXECUTABLE}
@ -44,14 +56,18 @@ string(REGEX REPLACE "[^;]*/" ""
# Derive generated file paths in the build directory. The generated data
# files go into the suites/ subdirectory.
set(base_generated_data_files
${base_bignum_generated_data_files} ${base_psa_generated_data_files})
${base_bignum_generated_data_files} ${base_ecp_generated_data_files} ${base_psa_generated_data_files})
string(REGEX REPLACE "([^;]+)" "suites/\\1"
all_generated_data_files "${base_generated_data_files}")
set(bignum_generated_data_files "")
set(ecp_generated_data_files "")
set(psa_generated_data_files "")
foreach(file ${base_bignum_generated_data_files})
list(APPEND bignum_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
endforeach()
foreach(file ${base_ecp_generated_data_files})
list(APPEND ecp_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
endforeach()
foreach(file ${base_psa_generated_data_files})
list(APPEND psa_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
endforeach()
@ -75,6 +91,22 @@ if(GEN_FILES)
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_case.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_data_generation.py
)
add_custom_command(
OUTPUT
${ecp_generated_data_files}
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}/..
COMMAND
${MBEDTLS_PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_ecp_tests.py
--directory ${CMAKE_CURRENT_BINARY_DIR}/suites
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_ecp_tests.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_common.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/ecp.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_case.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_data_generation.py
)
add_custom_command(
OUTPUT
${psa_generated_data_files}
@ -107,6 +139,7 @@ endif()
# With this line, only 4 sub-makefiles include the above command, that reduces
# the risk of a race.
add_custom_target(test_suite_bignum_generated_data DEPENDS ${bignum_generated_data_files})
add_custom_target(test_suite_ecp_generated_data DEPENDS ${ecp_generated_data_files})
add_custom_target(test_suite_psa_generated_data DEPENDS ${psa_generated_data_files})
# If SKIP_TEST_SUITES is not defined with -D, get it from the environment.
if((NOT DEFINED SKIP_TEST_SUITES) AND (DEFINED ENV{SKIP_TEST_SUITES}))
@ -129,6 +162,7 @@ function(add_test_suite suite_name)
# Get the test names of the tests with generated .data files
# from the generated_data_files list in parent scope.
set(bignum_generated_data_names "")
set(ecp_generated_data_names "")
set(psa_generated_data_names "")
foreach(generated_data_file ${bignum_generated_data_files})
# Get the plain filename
@ -139,6 +173,15 @@ function(add_test_suite suite_name)
string(SUBSTRING ${generated_data_name} 11 -1 generated_data_name)
list(APPEND bignum_generated_data_names ${generated_data_name})
endforeach()
foreach(generated_data_file ${ecp_generated_data_files})
# Get the plain filename
get_filename_component(generated_data_name ${generated_data_file} NAME)
# Remove the ".data" extension
get_name_without_last_ext(generated_data_name ${generated_data_name})
# Remove leading "test_suite_"
string(SUBSTRING ${generated_data_name} 11 -1 generated_data_name)
list(APPEND ecp_generated_data_names ${generated_data_name})
endforeach()
foreach(generated_data_file ${psa_generated_data_files})
# Get the plain filename
get_filename_component(generated_data_name ${generated_data_file} NAME)
@ -153,6 +196,10 @@ function(add_test_suite suite_name)
set(data_file
${CMAKE_CURRENT_BINARY_DIR}/suites/test_suite_${data_name}.data)
set(dependency test_suite_bignum_generated_data)
elseif(";${ecp_generated_data_names};" MATCHES ";${data_name};")
set(data_file
${CMAKE_CURRENT_BINARY_DIR}/suites/test_suite_${data_name}.data)
set(dependency test_suite_ecp_generated_data)
elseif(";${psa_generated_data_names};" MATCHES ";${data_name};")
set(data_file
${CMAKE_CURRENT_BINARY_DIR}/suites/test_suite_${data_name}.data)
@ -160,7 +207,7 @@ function(add_test_suite suite_name)
else()
set(data_file
${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${data_name}.data)
set(dependency test_suite_bignum_generated_data test_suite_psa_generated_data)
set(dependency test_suite_bignum_generated_data test_suite_ecp_generated_data test_suite_psa_generated_data)
endif()
add_custom_command(

View file

@ -73,6 +73,13 @@ GENERATED_BIGNUM_DATA_FILES := $(patsubst tests/%,%,$(shell \
ifeq ($(GENERATED_BIGNUM_DATA_FILES),FAILED)
$(error "$(PYTHON) scripts/generate_bignum_tests.py --list" failed)
endif
GENERATED_ECP_DATA_FILES := $(patsubst tests/%,%,$(shell \
$(PYTHON) scripts/generate_ecp_tests.py --list || \
echo FAILED \
))
ifeq ($(GENERATED_ECP_DATA_FILES),FAILED)
$(error "$(PYTHON) scripts/generate_ecp_tests.py --list" failed)
endif
GENERATED_PSA_DATA_FILES := $(patsubst tests/%,%,$(shell \
$(PYTHON) scripts/generate_psa_tests.py --list || \
echo FAILED \
@ -80,7 +87,7 @@ GENERATED_PSA_DATA_FILES := $(patsubst tests/%,%,$(shell \
ifeq ($(GENERATED_PSA_DATA_FILES),FAILED)
$(error "$(PYTHON) scripts/generate_psa_tests.py --list" failed)
endif
GENERATED_FILES := $(GENERATED_PSA_DATA_FILES) $(GENERATED_BIGNUM_DATA_FILES)
GENERATED_FILES := $(GENERATED_PSA_DATA_FILES) $(GENERATED_ECP_DATA_FILES) $(GENERATED_BIGNUM_DATA_FILES)
generated_files: $(GENERATED_FILES)
# generate_bignum_tests.py and generate_psa_tests.py spend more time analyzing
@ -89,7 +96,7 @@ generated_files: $(GENERATED_FILES)
# It's rare not to want all the outputs. So always generate all of its outputs.
# Use an intermediate phony dependency so that parallel builds don't run
# a separate instance of the recipe for each output file.
.SECONDARY: generated_bignum_test_data generated_psa_test_data
.SECONDARY: generated_bignum_test_data generated_ecp_test_data generated_psa_test_data
$(GENERATED_BIGNUM_DATA_FILES): generated_bignum_test_data
generated_bignum_test_data: scripts/generate_bignum_tests.py
generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_common.py
@ -102,6 +109,16 @@ generated_bignum_test_data:
echo " Gen $(GENERATED_BIGNUM_DATA_FILES)"
$(PYTHON) scripts/generate_bignum_tests.py
$(GENERATED_ECP_DATA_FILES): generated_ecp_test_data
generated_ecp_test_data: scripts/generate_ecp_tests.py
generated_ecp_test_data: ../scripts/mbedtls_dev/bignum_common.py
generated_ecp_test_data: ../scripts/mbedtls_dev/ecp.py
generated_ecp_test_data: ../scripts/mbedtls_dev/test_case.py
generated_ecp_test_data: ../scripts/mbedtls_dev/test_data_generation.py
generated_ecp_test_data:
echo " Gen $(GENERATED_ECP_DATA_FILES)"
$(PYTHON) scripts/generate_ecp_tests.py
$(GENERATED_PSA_DATA_FILES): generated_psa_test_data
generated_psa_test_data: scripts/generate_psa_tests.py
generated_psa_test_data: ../scripts/mbedtls_dev/crypto_knowledge.py
@ -202,6 +219,7 @@ ifndef WINDOWS
rm -rf $(BINARIES) *.c *.datax
rm -f src/*.o src/drivers/*.o src/libmbed*
rm -f include/test/instrument_record_status.h
rm -f include/alt-extra/*/*_alt.h
rm -rf libtestdriver1
rm -f ../library/libtestdriver1.a
else
@ -227,6 +245,10 @@ check: $(BINARIES)
test: check
# Generate variants of some headers for testing
include/alt-extra/%_alt.h: ../include/%.h
perl -p -e 's/^(# *(define|ifndef) +\w+_)H\b/$${1}ALT_H/' $< >$@
# Generate test library
# Perl code that is executed to transform each original line from a library

View file

@ -200,17 +200,6 @@ filter()
echo "$NEW_LIST" | sed -e 's/[[:space:]][[:space:]]*/ /g' -e 's/^ //' -e 's/ $//'
}
# OpenSSL 1.0.1h with -Verify wants a ClientCertificate message even for
# PSK ciphersuites with DTLS, which is incorrect, so disable them for now
check_openssl_server_bug()
{
if test "X$VERIFY" = "XYES" && is_dtls "$MODE" && \
test "$TYPE" = "PSK";
then
SKIP_NEXT="YES"
fi
}
filter_ciphersuites()
{
if [ "X" != "X$FILTER" -o "X" != "X$EXCLUDE" ];
@ -227,7 +216,7 @@ filter_ciphersuites()
# For GnuTLS client -> mbed TLS server,
# we need to force IPv4 by connecting to 127.0.0.1 but then auth fails
if [ "X$VERIFY" = "XYES" ] && is_dtls "$MODE"; then
if is_dtls "$MODE" && [ "X$VERIFY" = "XYES" ]; then
G_CIPHERS=""
fi
}
@ -545,6 +534,16 @@ add_mbedtls_ciphersuites()
esac
}
# o_check_ciphersuite STANDARD_CIPHER_SUITE
o_check_ciphersuite()
{
if [ "${O_SUPPORT_ECDH}" = "NO" ]; then
case "$1" in
*ECDH_*) SKIP_NEXT="YES"
esac
fi
}
setup_arguments()
{
O_MODE=""
@ -599,7 +598,6 @@ setup_arguments()
M_CLIENT_ARGS="server_port=$PORT server_addr=127.0.0.1 force_version=$MODE"
O_CLIENT_ARGS="-connect localhost:$PORT -$O_MODE"
G_CLIENT_ARGS="-p $PORT --debug 3 $G_MODE"
G_CLIENT_PRIO="NONE:$G_PRIO_MODE:+COMP-NULL:+CURVE-ALL:+SIGN-ALL"
# Newer versions of OpenSSL have a syntax to enable all "ciphers", even
# low-security ones. This covers not just cipher suites but also protocol
@ -615,6 +613,11 @@ setup_arguments()
;;
esac
case $($OPENSSL ciphers ALL) in
*ECDH-ECDSA*|*ECDH-RSA*) O_SUPPORT_ECDH="YES";;
*) O_SUPPORT_ECDH="NO";;
esac
if [ "X$VERIFY" = "XYES" ];
then
M_SERVER_ARGS="$M_SERVER_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required"
@ -831,7 +834,7 @@ run_client() {
if [ $EXIT -eq 0 ]; then
RESULT=0
else
# If the cipher isn't supported...
# If it is NULL cipher ...
if grep 'Cipher is (NONE)' $CLI_OUT >/dev/null; then
RESULT=1
else
@ -1001,10 +1004,20 @@ SKIP_NEXT="NO"
trap cleanup INT TERM HUP
for VERIFY in $VERIFIES; do
VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
for MODE in $MODES; do
for TYPE in $TYPES; do
for MODE in $MODES; do
for TYPE in $TYPES; do
# PSK cipher suites do not allow client certificate verification.
# This means PSK test cases with VERIFY=YES should be replaced by
# VERIFY=NO or be ignored. SUB_VERIFIES variable is used to constrain
# verification option for PSK test cases.
SUB_VERIFIES=$VERIFIES
if [ "$TYPE" = "PSK" ]; then
SUB_VERIFIES="NO"
fi
for VERIFY in $SUB_VERIFIES; do
VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
for PEER in $PEERS; do
setup_arguments
@ -1035,7 +1048,7 @@ for VERIFY in $VERIFIES; do
start_server "OpenSSL"
translate_ciphers m $M_CIPHERS
for i in $ciphers; do
check_openssl_server_bug
o_check_ciphersuite "${i%%=*}"
run_client mbedTLS ${i%%=*} ${i#*=}
done
stop_server
@ -1045,6 +1058,7 @@ for VERIFY in $VERIFIES; do
start_server "mbedTLS"
translate_ciphers o $O_CIPHERS
for i in $ciphers; do
o_check_ciphersuite "${i%%=*}"
run_client OpenSSL ${i%%=*} ${i#*=}
done
stop_server

View file

@ -29,10 +29,12 @@
/* Disable TLS 1.2 and 1.2-specific features */
#undef MBEDTLS_SSL_ENCRYPT_THEN_MAC
#undef MBEDTLS_SSL_EXTENDED_MASTER_SECRET
#undef MBEDTLS_SSL_RENEGOTIATION
#undef MBEDTLS_SSL_PROTO_TLS1_2
#undef MBEDTLS_SSL_PROTO_DTLS
#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY
#undef MBEDTLS_SSL_DTLS_SRTP
#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT

View file

@ -140,6 +140,9 @@ test_csr_v3_all_malformed_attributes_extension_request_sequence_len1.csr.der: te
test_csr_v3_all_malformed_attributes_extension_request_sequence_len2.csr.der: test_csr_v3_all.csr.der
(hexdump -ve '1/1 "%.2X"' $< | sed "s/3051300B0603551D0F04/3050300B0603551D0F04/" | xxd -r -p ) > $@
test_cert_rfc822name.crt.der: cert_example_multi.csr
$(OPENSSL) x509 -req -CA $(test_ca_crt) -CAkey $(test_ca_key_file_rsa) -extfile $(test_ca_config_file) -outform DER -extensions rfc822name_names -passin "pass:$(test_ca_pwd_rsa)" -set_serial 17 -days 3653 -sha256 -in $< > $@
$(test_ca_key_file_rsa_alt):test-ca.opensslconf
$(OPENSSL) genrsa -out $@ 2048
test-ca-alt.csr: $(test_ca_key_file_rsa_alt) $(test_ca_config_file)
@ -336,6 +339,12 @@ server5-tricky-ip-san.crt: 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 -out $@
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"
rsa_multiple_san_uri.crt.der: rsa_multiple_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, URI:urn:example.com:5ff40f78-9210-494f-8206-abcde1234567" -extensions 'v3_req' -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS URI SAN"
server10-badsign.crt: server10.crt
{ head -n-2 $<; tail -n-2 $< | sed -e '1s/0\(=*\)$$/_\1/' -e '1s/[^_=]\(=*\)$$/0\1/' -e '1s/_/1/'; } > $@
all_final += server10-badsign.crt
@ -911,6 +920,70 @@ ec_prv.pk8param.pem: ec_prv.pk8param.der
$(OPENSSL) pkey -in $< -inform DER -out $@
all_final += ec_prv.pk8param.pem
ec_prv.sec1.comp.pem: ec_prv.sec1.pem
$(OPENSSL) ec -in $< -out $@ -conv_form compressed
all_final += ec_prv.sec1.comp.pem
ec_224_prv.comp.pem: ec_224_prv.pem
$(OPENSSL) ec -in $< -out $@ -conv_form compressed
all_final += ec_224_prv.comp.pem
ec_256_prv.comp.pem: ec_256_prv.pem
$(OPENSSL) ec -in $< -out $@ -conv_form compressed
all_final += ec_256_prv.comp.pem
ec_384_prv.comp.pem: ec_384_prv.pem
$(OPENSSL) ec -in $< -out $@ -conv_form compressed
all_final += ec_384_prv.comp.pem
ec_521_prv.comp.pem: ec_521_prv.pem
$(OPENSSL) ec -in $< -out $@ -conv_form compressed
all_final += ec_521_prv.comp.pem
ec_bp256_prv.comp.pem: ec_bp256_prv.pem
$(OPENSSL) ec -in $< -out $@ -conv_form compressed
all_final += ec_bp256_prv.comp.pem
ec_bp384_prv.comp.pem: ec_bp384_prv.pem
$(OPENSSL) ec -in $< -out $@ -conv_form compressed
all_final += ec_bp384_prv.comp.pem
ec_bp512_prv.comp.pem: ec_bp512_prv.pem
$(OPENSSL) ec -in $< -out $@ -conv_form compressed
all_final += ec_bp512_prv.comp.pem
ec_pub.comp.pem: ec_pub.pem
$(OPENSSL) ec -pubin -in $< -out $@ -conv_form compressed
all_final += ec_pub.comp.pem
ec_224_pub.comp.pem: ec_224_pub.pem
$(OPENSSL) ec -pubin -in $< -out $@ -conv_form compressed
all_final += ec_224_pub.comp.pem
ec_256_pub.comp.pem: ec_256_pub.pem
$(OPENSSL) ec -pubin -in $< -out $@ -conv_form compressed
all_final += ec_256_pub.comp.pem
ec_384_pub.comp.pem: ec_384_pub.pem
$(OPENSSL) ec -pubin -in $< -out $@ -conv_form compressed
all_final += ec_384_pub.comp.pem
ec_521_pub.comp.pem: ec_521_pub.pem
$(OPENSSL) ec -pubin -in $< -out $@ -conv_form compressed
all_final += ec_521_pub.comp.pem
ec_bp256_pub.comp.pem: ec_bp256_pub.pem
$(OPENSSL) ec -pubin -in $< -out $@ -conv_form compressed
all_final += ec_bp256_pub.comp.pem
ec_bp384_pub.comp.pem: ec_bp384_pub.pem
$(OPENSSL) ec -pubin -in $< -out $@ -conv_form compressed
all_final += ec_bp384_pub.comp.pem
ec_bp512_pub.comp.pem: ec_bp512_pub.pem
$(OPENSSL) ec -pubin -in $< -out $@ -conv_form compressed
all_final += ec_bp512_pub.comp.pem
################################################################
### Generate CSRs for X.509 write test suite
################################################################
@ -1198,14 +1271,19 @@ tls13_certs: ecdsa_secp521r1.crt ecdsa_secp521r1.key
# PKCS7 test data
pkcs7_test_cert_1 = pkcs7-rsa-sha256-1.crt
pkcs7_test_cert_2 = pkcs7-rsa-sha256-2.crt
pkcs7_test_cert_3 = pkcs7-rsa-sha256-3.crt
pkcs7_test_file = pkcs7_data.bin
$(pkcs7_test_file):
echo -e "Hello\xd" > $@
printf "Hello\15\n" > $@
all_final += $(pkcs7_test_file)
pkcs7_zerolendata.bin:
printf '' > $@
all_final += pkcs7_zerolendata.bin
pkcs7_data_1.bin:
echo -e "2\xd" > $@
printf "2\15\n" > $@
all_final += pkcs7_data_1.bin
# Generate signing cert
@ -1219,6 +1297,15 @@ pkcs7-rsa-sha256-2.crt:
cat pkcs7-rsa-sha256-2.crt pkcs7-rsa-sha256-2.key > pkcs7-rsa-sha256-2.pem
all_final += pkcs7-rsa-sha256-2.crt
pkcs7-rsa-sha256-3.crt:
$(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert 3" -sha256 -nodes -days 365 -newkey rsa:2048 -keyout pkcs7-rsa-sha256-3.key -out pkcs7-rsa-sha256-3.crt
cat pkcs7-rsa-sha256-3.crt pkcs7-rsa-sha256-3.key > pkcs7-rsa-sha256-3.pem
all_final += pkcs7-rsa-sha256-3.crt
pkcs7-rsa-expired.crt:
$(FAKETIME) -f -3650d $(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert Expired" -sha256 -nodes -days 365 -newkey rsa:2048 -keyout pkcs7-rsa-expired.key -out pkcs7-rsa-expired.crt
all_final += pkcs7-rsa-expired.crt
# Convert signing certs to DER for testing PEM-free builds
pkcs7-rsa-sha256-1.der: $(pkcs7_test_cert_1)
$(OPENSSL) x509 -in pkcs7-rsa-sha256-1.crt -out $@ -outform DER
@ -1228,6 +1315,11 @@ pkcs7-rsa-sha256-2.der: $(pkcs7_test_cert_2)
$(OPENSSL) x509 -in pkcs7-rsa-sha256-2.crt -out $@ -outform DER
all_final += pkcs7-rsa-sha256-2.der
# pkcs7 signature file over zero-len data
pkcs7_zerolendata_detached.der: pkcs7_zerolendata.bin pkcs7-rsa-sha256-1.key pkcs7-rsa-sha256-1.crt
$(OPENSSL) smime -sign -md sha256 -nocerts -noattr -in pkcs7_zerolendata.bin -inkey pkcs7-rsa-sha256-1.key -outform DER -binary -signer pkcs7-rsa-sha256-1.crt -out pkcs7_zerolendata_detached.der
all_final += pkcs7_zerolendata_detached.der
# pkcs7 signature file with CERT
pkcs7_data_cert_signed_sha256.der: $(pkcs7_test_file) $(pkcs7_test_cert_1)
$(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -signer pkcs7-rsa-sha256-1.pem -noattr -outform DER -out $@
@ -1248,11 +1340,21 @@ pkcs7_data_without_cert_signed.der: $(pkcs7_test_file) $(pkcs7_test_cert_1)
$(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -signer pkcs7-rsa-sha256-1.pem -nocerts -noattr -outform DER -out $@
all_final += pkcs7_data_without_cert_signed.der
# pkcs7 signature file with multiple signers
# pkcs7 signature file with signature
pkcs7_data_with_signature.der: $(pkcs7_test_file) $(pkcs7_test_cert_1)
$(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -signer pkcs7-rsa-sha256-1.pem -nocerts -noattr -nodetach -outform DER -out $@
all_final += pkcs7_data_with_signature.der
# pkcs7 signature file with two signers
pkcs7_data_multiple_signed.der: $(pkcs7_test_file) $(pkcs7_test_cert_1) $(pkcs7_test_cert_2)
$(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -signer pkcs7-rsa-sha256-1.pem -signer pkcs7-rsa-sha256-2.pem -nocerts -noattr -outform DER -out $@
all_final += pkcs7_data_multiple_signed.der
# pkcs7 signature file with three signers
pkcs7_data_3_signed.der: $(pkcs7_test_file) $(pkcs7_test_cert_1) $(pkcs7_test_cert_2) $(pkcs7_test_cert_3)
$(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -signer pkcs7-rsa-sha256-1.pem -signer pkcs7-rsa-sha256-2.pem -signer pkcs7-rsa-sha256-3.pem -nocerts -noattr -outform DER -out $@
all_final += pkcs7_data_3_signed.der
# pkcs7 signature file with multiple certificates
pkcs7_data_multiple_certs_signed.der: $(pkcs7_test_file) $(pkcs7_test_cert_1) $(pkcs7_test_cert_2)
$(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -signer pkcs7-rsa-sha256-1.pem -signer pkcs7-rsa-sha256-2.pem -noattr -outform DER -out $@
@ -1261,19 +1363,31 @@ all_final += pkcs7_data_multiple_certs_signed.der
# pkcs7 signature file with corrupted CERT
pkcs7_data_signed_badcert.der: pkcs7_data_cert_signed_sha256.der
cp pkcs7_data_cert_signed_sha256.der $@
echo -en '\xa1' | dd of=$@ bs=1 seek=547 conv=notrunc
echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=547 conv=notrunc
all_final += pkcs7_data_signed_badcert.der
# pkcs7 signature file with corrupted signer info
pkcs7_data_signed_badsigner.der: pkcs7_data_cert_signed_sha256.der
cp pkcs7_data_cert_signed_sha256.der $@
echo -en '\xa1' | dd of=$@ bs=1 seek=918 conv=notrunc
echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=918 conv=notrunc
all_final += pkcs7_data_signed_badsigner.der
# pkcs7 signature file with invalid tag in signerInfo[1].serial after long issuer name
pkcs7_signerInfo_1_serial_invalid_tag_after_long_name.der: pkcs7_data_multiple_signed.der
cp $< $@
echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=498 conv=notrunc
all_final += pkcs7_signerInfo_1_serial_invalid_tag_after_long_name.der
# pkcs7 signature file with invalid tag in signerInfo[2]
pkcs7_signerInfo_2_invalid_tag.der: pkcs7_data_3_signed.der
cp $< $@
echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=810 conv=notrunc
all_final += pkcs7_signerInfo_2_invalid_tag.der
# pkcs7 file with version 2
pkcs7_data_cert_signed_v2.der: pkcs7_data_cert_signed_sha256.der
cp pkcs7_data_cert_signed_sha256.der $@
echo -en '\x02' | dd of=$@ bs=1 seek=25 conv=notrunc
echo '02' | xxd -r -p | dd of=$@ bs=1 seek=25 conv=notrunc
all_final += pkcs7_data_cert_signed_v2.der
pkcs7_data_cert_encrypted.der: $(pkcs7_test_file) $(pkcs7_test_cert_1)
@ -1284,12 +1398,12 @@ all_final += pkcs7_data_cert_encrypted.der
# For some interesting sizes, what happens if we make them off-by-one?
pkcs7_signerInfo_issuer_invalid_size.der: pkcs7_data_cert_signed_sha256.der
cp $< $@
echo -en '\x35' | dd of=$@ seek=919 bs=1 conv=notrunc
echo '35' | xxd -r -p | dd of=$@ seek=919 bs=1 conv=notrunc
all_final += pkcs7_signerInfo_issuer_invalid_size.der
pkcs7_signerInfo_serial_invalid_size.der: pkcs7_data_cert_signed_sha256.der
cp $< $@
echo -en '\x15' | dd of=$@ seek=973 bs=1 conv=notrunc
echo '15' | xxd -r -p | dd of=$@ seek=973 bs=1 conv=notrunc
all_final += pkcs7_signerInfo_serial_invalid_size.der
# pkcs7 signature file just with signed data

View file

@ -0,0 +1,4 @@
-----BEGIN EC PRIVATE KEY-----
MEwCAQEEHGhJ+X0QZvaZd1ljfH44mUZM7j7HrJcGU6C+B0KgBwYFK4EEACGhIAMe
AAMWk6KQ9/C1cf4rQdXYSwEydjH0qGD5lfozLAl/
-----END EC PRIVATE KEY-----

View file

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MDIwEAYHKoZIzj0CAQYFK4EEACEDHgADFpOikPfwtXH+K0HV2EsBMnYx9Khg+ZX6
MywJfw==
-----END PUBLIC KEY-----

Some files were not shown because too many files have changed in this diff Show more