Merge branch 'development' into buffer-sharing-merge

This commit is contained in:
David Horstmann 2024-03-12 15:02:28 +00:00
commit 93fa4e1b87
265 changed files with 14538 additions and 6022 deletions

View File

@ -18,3 +18,10 @@ Please tick as appropriate and edit the reasons (e.g.: "backport: not needed bec
Please refer to the [contributing guidelines](https://github.com/Mbed-TLS/mbedtls/blob/development/CONTRIBUTING.md), especially the
checklist for PR contributors.
Help make review efficient:
* Multiple simple commits
- please structure your PR into a series of small commits, each of which does one thing
* Avoid force-push
- please do not force-push to update your PR - just add new commit(s)
* See our [Guidelines for Contributors](https://mbed-tls.readthedocs.io/en/latest/reviews/review-for-contributors/) for more details about the review process.

View File

@ -1,6 +1,6 @@
THIRDPARTY_INCLUDES+=-I../3rdparty/everest/include -I../3rdparty/everest/include/everest -I../3rdparty/everest/include/everest/kremlib
THIRDPARTY_INCLUDES+=-I$(THIRDPARTY_DIR)/everest/include -I$(THIRDPARTY_DIR)/everest/include/everest -I$(THIRDPARTY_DIR)/everest/include/everest/kremlib
THIRDPARTY_CRYPTO_OBJECTS+= \
../3rdparty/everest/library/everest.o \
../3rdparty/everest/library/x25519.o \
../3rdparty/everest/library/Hacl_Curve25519_joined.o
$(THIRDPARTY_DIR)/everest/library/everest.o \
$(THIRDPARTY_DIR)/everest/library/x25519.o \
$(THIRDPARTY_DIR)/everest/library/Hacl_Curve25519_joined.o

View File

@ -1,5 +1,5 @@
THIRDPARTY_INCLUDES+=-I../3rdparty/p256-m/p256-m/include -I../3rdparty/p256-m/p256-m/include/p256-m -I../3rdparty/p256-m/p256-m_driver_interface
THIRDPARTY_INCLUDES+=-I$(THIRDPARTY_DIR)/p256-m/p256-m/include -I$(THIRDPARTY_DIR)/p256-m/p256-m/include/p256-m -I$(THIRDPARTY_DIR)/p256-m/p256-m_driver_interface
THIRDPARTY_CRYPTO_OBJECTS+= \
../3rdparty/p256-m//p256-m_driver_entrypoints.o \
../3rdparty/p256-m//p256-m/p256-m.o
$(THIRDPARTY_DIR)/p256-m//p256-m_driver_entrypoints.o \
$(THIRDPARTY_DIR)/p256-m//p256-m/p256-m.o

View File

@ -34,9 +34,15 @@ cmake_policy(SET CMP0011 NEW)
cmake_policy(SET CMP0012 NEW)
if(TEST_CPP)
project("Mbed TLS" LANGUAGES C CXX)
project("Mbed TLS"
LANGUAGES C CXX
VERSION 3.5.2
)
else()
project("Mbed TLS" LANGUAGES C)
project("Mbed TLS"
LANGUAGES C
VERSION 3.5.2
)
endif()
include(GNUInstallDirs)
@ -114,6 +120,11 @@ if(MBEDTLS_PYTHON_EXECUTABLE)
endif()
# We now potentially need to link all executables against PThreads, if available
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads)
# If this is the root project add longer list of available CMAKE_BUILD_TYPE values
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
@ -278,6 +289,8 @@ add_subdirectory(3rdparty)
add_subdirectory(library)
add_subdirectory(pkgconfig)
#
# The C files in tests/src directory contain test code shared among test suites
# and programs. This shared test code is compiled and linked to test suites and

3
ChangeLog.d/7765.txt Normal file
View File

@ -0,0 +1,3 @@
Features
* Add functions mbedtls_ecdsa_raw_to_der() and mbedtls_ecdsa_der_to_raw() to
convert ECDSA signatures between raw and DER (ASN.1) formats.

7
ChangeLog.d/8030.txt Normal file
View File

@ -0,0 +1,7 @@
Changes
* Extended PSA Crypto configurations options for FFDH by making it possible
to select only some of the parameters / groups, with the macros
PSA_WANT_DH_RFC7919_XXXX. You now need to defined the corresponding macro
for each size you want to support. Also, if you have an FFDH accelerator,
you'll need to define the appropriate MBEDTLS_PSA_ACCEL macros to signal
support for these domain parameters.

10
ChangeLog.d/8647.txt Normal file
View File

@ -0,0 +1,10 @@
Default behavior changes
* psa_import_key() now only accepts RSA keys in the PSA standard formats.
The undocumented ability to import other formats (PKCS#8, SubjectPublicKey,
PEM) accepted by the pkparse module has been removed. Applications that
need these formats can call mbedtls_pk_parse_{public,}key() followed by
mbedtls_pk_import_into_psa().
Changes
* RSA support in PSA no longer auto-enables the pkparse and pkwrite modules,
saving code size when those are not otherwise enabled.

3
ChangeLog.d/8799.txt Normal file
View File

@ -0,0 +1,3 @@
Bugfix
* mbedtls_pem_read_buffer() now performs a check on the padding data of
decrypted keys and it rejects invalid ones.

8
ChangeLog.d/8824.txt Normal file
View File

@ -0,0 +1,8 @@
Bugfix
* Fix mbedtls_pk_sign(), mbedtls_pk_verify(), mbedtls_pk_decrypt() and
mbedtls_pk_encrypt() on non-opaque RSA keys to honor the padding mode in
the RSA context. Before, if MBEDTLS_USE_PSA_CRYPTO was enabled and the
RSA context was configured for PKCS#1 v2.1 (PSS/OAEP), the sign/verify
functions performed a PKCS#1 v1.5 signature instead and the
encrypt/decrypt functions returned an error. Fixes #8824.

6
ChangeLog.d/8825.txt Normal file
View File

@ -0,0 +1,6 @@
Features
* mbedtls_psa_get_random() is always available as soon as
MBEDTLS_PSA_CRYPTO_CLIENT is enabled at build time and psa_crypto_init() is
called at runtime. This together with MBEDTLS_PSA_RANDOM_STATE can be
used as random number generator function (f_rng) and context (p_rng) in
legacy functions.

6
ChangeLog.d/8848.txt Normal file
View File

@ -0,0 +1,6 @@
Removals
* Temporary function mbedtls_pk_wrap_as_opaque() is removed. To mimic the
same behavior mbedtls_pk_get_psa_attributes() and
mbedtls_pk_import_into_psa() can be used to import a PK key into PSA,
while mbedtls_pk_setup_opaque() can be used to wrap a PSA key into a opaque
PK context.

View File

@ -0,0 +1,3 @@
Features
* Add support for using AES-CBC 128, 192, and 256 bit schemes
with PKCS#5 PBES2. Keys encrypted this way can now be parsed by PK parse.

View File

@ -0,0 +1,3 @@
Features
* Add new accessor to expose the private group id member of
`mbedtls_ecdh_context` structure.

View File

@ -0,0 +1,3 @@
Features
* The benchmark program now reports times for both ephemeral and static
ECDH in all ECDH configurations.

View File

@ -0,0 +1,9 @@
New deprecations
* In the PSA API, domain parameters are no longer used for anything.
They are deprecated and will be removed in a future version of the
library.
Removals
* In the PSA API, the experimental way to encode the public exponent of
an RSA key as a domain parameter is no longer supported. Use
psa_generate_key_ext() instead.

View File

@ -0,0 +1,8 @@
Features
* The new function mbedtls_ecp_write_key_ext() is similar to
mbedtls_ecp_write_key(), but can be used without separately calculating
the output length.
New deprecations
* mbedtls_ecp_write_key() is deprecated in favor of
mbedtls_ecp_write_key_ext().

View File

@ -0,0 +1,4 @@
Bugfix
* Fix missing bitflags in SSL session serialization headers. Their absence
allowed SSL sessions saved in one configuration to be loaded in a
different, incompatible configuration.

View File

@ -0,0 +1,3 @@
Bugfix
* Correct initial capacities for key derivation algorithms:TLS12_PRF,
TLS12_PSK_TO_MS, PBKDF2-HMAC, PBKDF2-CMAC

View File

@ -0,0 +1,4 @@
Features
* Add support for 8-bit GCM tables for Shoup's algorithm to speedup GCM
operations when hardware accelerated AES is not present. Improves
performance by around 30% on 64-bit Intel; 125% on Armv7-M.

View File

@ -0,0 +1,3 @@
Bugfix
* Avoid segmentation fault caused by releasing not initialized
entropy resource in gen_key example. Fixes #8809.

View File

@ -0,0 +1,3 @@
Features
* Add getter (mbedtls_ssl_session_get_ticket_creation_time()) to access
`mbedtls_ssl_session.ticket_creation_time`.

View File

@ -0,0 +1,4 @@
Bugfix
* On Linux on ARMv8, fix a build error with SHA-256 and SHA-512
acceleration detection when the libc headers do not define the
corresponding constant. Reported by valord577.

View File

@ -0,0 +1,4 @@
Features
* The new functions mbedtls_pk_get_psa_attributes() and
mbedtls_pk_import_into_psa() provide a uniform way to create a PSA
key from a PK key.

View File

@ -0,0 +1,4 @@
Features
* Add pc files for pkg-config, e.g.:
pkg-config --cflags --libs (mbedtls|mbedcrypto|mbedx509)

View File

@ -0,0 +1,3 @@
Features
* The new function psa_generate_key_ext() allows generating an RSA
key pair with a custom public exponent.

View File

@ -0,0 +1,7 @@
Bugfix
* Fix mbedtls_pk_get_bitlen() for RSA keys whose size is not a
multiple of 8. Fixes #868.
Features
* The new function mbedtls_rsa_get_bitlen() returns the length of the modulus
in bits, i.e. the key size for an RSA key.

View File

@ -0,0 +1,6 @@
Changes
* mbedtls_mpi_exp_mod and code that uses it, notably RSA and DHM operations,
have changed their speed/memory compromise as part of a proactive security
improvement. The new default value of MBEDTLS_MPI_WINDOW_SIZE roughly
preserves the current speed, at the expense of increasing memory
consumption.

View File

@ -0,0 +1,5 @@
Features
* Add new accessor to expose the `MBEDTLS_PRIVATE(ca_istrue)` member of
`mbedtls_x509_crt` structure. This requires setting
the MBEDTLS_X509_EXT_BASIC_CONSTRAINTS bit in the certificate's
ext_types field.

View File

@ -0,0 +1,344 @@
Bridges between legacy and PSA crypto APIs
==========================================
## Introduction
### Goal of this document
This document explores the needs of applications that use both Mbed TLS legacy crypto interfaces and PSA crypto interfaces. Based on [requirements](#requirements), we [analyze gaps](#gap-analysis) and [API design](#api-design).
This is a design document. The target audience is library maintainers. See the companion document [“Transitioning to the PSA API”](../../psa-transition.md) for a user focus on the same topic.
### Keywords
* [TODO] A part of the analysis that isn't finished.
* [OPEN] Open question: a specific aspect of the design where there are several plausible decisions.
* [ACTION] A finalized part of the design that will need to be carried out.
### Context
Mbed TLS 3.x supports two cryptographic APIs:
* The legacy API `mbedtls_xxx` is inherited from PolarSSL.
* The PSA API `psa_xxx` was introduced in Mbed TLS 2.17.
Mbed TLS is gradually shifting from the legacy API to the PSA API. Mbed TLS 4.0 will be the first version where the PSA API is considered the main API, and large parts of the legacy API will be removed.
In Mbed TLS 4.0, the cryptography will be provided by a separate project [TF-PSA-Crypto](https://github.com/Mbed-TLS/TF-PSA-Crypto). For simplicity, in this document, we just refer to the whole as “Mbed TLS”.
### Document history
This document was originally written when preparing Mbed TLS 3.6. Mbed TLS 3.6 includes both PSA and legacy APIs covering largely overlapping ground. Many legacy APIs will be removed in Mbed TLS 4.0.
## Requirements
### Why mix APIs?
There is functionality that is tied to one API and is not directly available in the other API:
* Only PSA fully supports PSA accelerators and secure element integration.
* Only PSA supports isolating cryptographic material in a secure service.
* The legacy API has features that are not present (yet) in PSA, notably parsing and formatting asymmetric keys.
The legacy API can partially leverage PSA features via `MBEDTLS_USE_PSA_CRYPTO`, but this has limited scope.
In addition, many applications cannot be migrated in a single go. For large projects, it is impractical to rewrite a significant part of the code all at once. (For example, Mbed TLS itself will have taken more than 6 years to transition.) Projects that use one or more library in addition to Mbed TLS must follow the evolution of these libraries, each of which might have its own pace.
### Where mixing happens
Mbed TLS can be, and normally is, built with support for both APIs. Therefore no special effort is necessary to allow an application to use both APIs.
Special effort is necessary to use both APIs as part of the implementation of the same feature. From an informal analysis of typical application requirements, we identify four parts of the use of cryptography which can be provided by different APIs:
* Metadata manipulation: parsing and producing encrypted or signed files, finding mutually supported algorithms in a network protocol negotiation, etc.
* Key management: parsing, generating, deriving and formatting cryptographic keys.
* Data manipulation other than keys. In practice, most data formats within the scope of the legacy crypto APIs are trivial (ciphertexts, hashes, MACs, shared secrets). The one exception is ECDSA signatures.
* Cryptographic operations: hash, sign, encrypt, etc.
From this, we deduce the following requirements:
* Convert between PSA and legacy metadata.
* Creating a key with the legacy API and consuming it in the PSA API.
* Creating a key with the PSA API and consuming it in the legacy API.
* Manipulating data formats, other than keys, where the PSA API is lacking.
### Scope limitations
The goal of this document is to bridge the legacy API and the PSA API. The goal is not to provide a PSA way to do everything that is currently possible with the legacy API. The PSA API is less flexible in some regards, and extending it is out of scope in the present study.
With respect to the legacy API, we do not consider functionality of low-level modules for individual algorithms. Our focus is on applications that use high-level legacy crypto modules (md, cipher, pk) and need to combine that with uses of the PSA APIs.
## Gap analysis
The document [“Transitioning to the PSA API”](../../psa-transition.md) enumerates the public header files in Mbed TLS 3.4 and the API elements (especially enums and functions) that they provide, listing PSA equivalents where they exist. There are gaps in two cases:
* Where the PSA equivalents do not provide the same functionality. A typical example is parsing and formatting asymmetric keys.
* To convert between data representations used by legacy APIs and data representations used by PSA APIs.
Based on “[Where mixing happens](#where-mixing-happens)”, we focus the gap analysis on two topics: metadata and keys. This chapter explores the gaps in each family of cryptographic mechanisms.
### Generic metadata gaps
#### Need for error code conversion
Do we need public functions to convert between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` error codes? We have such functions for internal use.
Mbed TLS needs these conversions because it has many functions that expose one API (legacy/API) but are implemented on top of the other API. Most applications would convert legacy and PSA error code to their own error codes, and converting between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` is not particularly helpful for that. Application code might need such conversion functions when implementing an X.509 or TLS callback (returning `MBEDTLS_ERR_xxx`) on top of PSA functions, but this is a very limited use case.
Conclusion: no need for public error code conversion functions.
### Hash gap analysis
Hashes do not involve keys, and involves no nontrivial data format. Therefore the only gap is with metadata, namely specifying a hash algorithm.
Hashes are often used as building blocks for other mechanisms (HMAC, signatures, key derivation, etc.). Therefore metadata about hashes is relevant not only when calculating hashes, but also when performing many other cryptographic operations.
Gap: functions to convert between `psa_algorithm_t` hash algorithms and `mbedtls_md_type_t`. Such functions exist in Mbed TLS 3.5 (`mbedtls_md_psa_alg_from_type`, `mbedtls_md_type_from_psa_alg`) but they are declared only in private headers.
### MAC gap analysis
[TODO]
### Cipher and AEAD gap analysis
[TODO]
### Key derivation gap analysis
[TODO]
### Random generation gap analysis
[TODO]
### Asymmetric cryptography gap analysis
#### Asymmetric cryptography metadata
The legacy API only has generic support for two key types: RSA and ECC, via the pk module. ECC keys can also be further classified according to their curve. The legacy API also supports DHM (Diffie-Hellman-Merkle = FFDH: finite-field Diffie-Hellman) keys, but those are not integrated in the pk module.
An RSA or ECC key can potentially be used for different algorithms in the scope of the pk module:
* RSA: PKCS#1v1.5 signature, PSS signature, PKCS#1v1.5 encryption, OAEP encryption.
* ECC: ECDSA signature (randomized or deterministic), ECDH key agreement (via `mbedtls_pk_ec`).
ECC keys are also involved in EC-JPAKE, but this happens internally: the EC-JPAKE interface only needs one piece of metadata, namely, to identify a curve.
Since there is no algorithm that can be used with multiple types, and PSA keys have a policy that (for the most part) limits them to one algorithm, there does not seem to be a need to convert between legacy and PSA asymmetric key types on their own. The useful metadata conversions are:
* Selecting an **elliptic curve**.
This means converting between an `mbedtls_ecp_group_id` and a pair of `{psa_ecc_family_t; size_t}`.
This is fulfilled by `mbedtls_ecc_group_to_psa` and `mbedtls_ecc_group_from_psa`, which were introduced into the public API between Mbed TLS 3.5 and 3.6 ([#8664](https://github.com/Mbed-TLS/mbedtls/pull/8664)).
* Selecting A **DHM group**.
PSA only supports predefined groups, whereas legacy only supports ad hoc groups. An existing application referring to `MBEDTLS_DHM_RFC7919_FFDHExxx` values would need to refer to `PSA_DH_FAMILY_RFC7919`; an existing application using arbitrary groups cannot migrate to PSA.
* Simultaneously supporting **a key type and an algorithm**.
On the legacy side, this is an `mbedtls_pk_type_t` value and more. For ECDSA, the choice between randomized and deterministic is made at compile time. For RSA, the choice of encryption or signature algorithm is made either by configuring the underlying `mbedtls_rsa_context` or when calling the operation function.
On the PSA side, this is a `psa_key_type_t` value and an algorithm which is normally encoded as policy information in a `psa_key_attributes_t`. The algorithm is also needed in its own right when calling operation functions.
#### Using a legacy key pair or public key with PSA
There are several scenarios where an application has a legacy key pair or public key (`mbedtls_pk_context`) and needs to create a PSA key object (`psa_key_id_t`).
Reasons for first creating a legacy key object, where it's impossible or impractical to directly create a PSA key:
* A very common case where the input is a legacy key object is parsing. PSA does not (yet) have an equivalent of the `mbedtls_pk_parse_xxx` functions.
* The PSA key creation interface is less flexible in some cases. In particular, PSA RSA key generation does not (yet) allow choosing the public exponent.
* The pk object may be created by a part of the application (or a third-party library) that hasn't been migrated to the PSA API yet.
Reasons for needing a PSA key object:
* Using the key with third-party interface that takes a PSA key identifier as input. (Mbed TLS itself has a few TLS functions that take PSA key identifiers, but as of Mbed TLS 3.5, it is always possible to use a legacy key instead.)
* Benefiting from a PSA accelerator, or from PSA's world separation, even without `MBEDTLS_USE_PSA_CRYPTO`. (Not a priority scenario: we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA.)
Gap: a way to create a PSA key object from an `mbedtls_pk_context`. This partially exists in the form of `mbedtls_pk_wrap_as_opaque`, but it is not fully satisfactory, for reasons that are detailed in “[API to create a PSA key from a PK context](#api-to-create-a-psa-key-from-a-pk-context)” below.
#### Using a PSA key as a PK context
There are several scenarios where an application has a PSA key and needs to use it through an interface that wants an `mbedtls_pk_context` object. Typically, there is an existing key in the PSA key store (possibly in a secure element and non-exportable), and the key needs to be used in an interface that requires a `mbedtls_pk_context *` input, such as Mbed TLS's X.509 and TLS APIs or a similar third-party interface, or the `mbedtls_pk_write_xxx` interfaces which do not (yet) have PSA equivalents.
There is a function `mbedtls_pk_setup_opaque` that mostly does this. However, it has several limitations:
* It creates a PK key of type `MBEDTLS_PK_OPAQUE` that wraps the PSA key. This is good enough in some scenarios, but not others. For example, it's ok for pkwrite, because we've upgraded the pkwrite code to handle `MBEDTLS_PK_OPAQUE`. That doesn't help users of third-party libraries that haven't yet been upgraded.
* It ties the lifetime of the PK object to the PSA key, which is error-prone: if the PSA key is destroyed but the PK object isn't, there is no way to reliably detect any subsequent misuse of the PK object.
* It is only available under `MBEDTLS_USE_PSA_CRYPTO`. This is not a priority concern, since we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA. However, this function is useful to use specific PSA keys in X.509/TLS regardless of whether X.509/TLS use the PSA API for all cryptographic operations, so this is a wart in the current API.
It therefore appears that we need two ways to “convert” a PSA key to PK:
* Wrapping, which is what `mbedtls_pk_setup_opaque` does. This works for any PSA key but is limited by the key's lifetime and creates a PK object with limited functionality.
* Copying, which requires a new function. This requires an exportable key but creates a fully independent, fully functional PK object.
Gap: a way to copy a PSA key into a PK context. This can only be expected to work if the PSA key is exportable.
After some discussion, have not identified anything we want to change in the behavior of `mbedtls_pk_setup_opaque`. We only want to generalize it to non-`MBEDTLS_USE_PSA_CRYPTO` and to document it better.
#### Signature formats
The pk module uses signature formats intended for X.509. The PSA module uses the simplest sensible signature format.
* For RSA, the formats are the same.
* For ECDSA, PSA uses a fixed-size concatenation of (r,s), whereas X.509 and pk use an ASN.1 DER encoding of the sequence (r,s).
Gap: We need APIs to convert between these two formats. The conversion code already exists under the hood, but it's in pieces that can't be called directly.
There is a design choice here: do we provide conversions functions for ECDSA specifically, or do we provide conversion functions that take an algorithm as argument and just happen to be a no-op with RSA? One factor is plausible extensions. These conversions functions will remain useful in Mbed TLS 4.x and perhaps beyond. We will at least add EdDSA support, and its signature encoding is the fixed-size concatenation (r,s) even in X.509. We may well also add support for some post-quantum signatures, and their concrete format is still uncertain.
Given the uncertainty, it would be nice to provide a sufficiently generic interface to convert between the PSA and the pk signature format, parametrized by the algorithm. However, it is difficult to predict exactly what parameters are needed. For example, converting from an ASN.1 ECDSA signature to (r,s) requires the knowledge of the curve, or at least the curve's size. Therefore we are not going to add a generic function at this stage.
For ECDSA, there are two plausible APIs: follow the ASN.1/X.509 write/parse APIs, or present an ordinary input/output API. The ASN.1 APIs are the way they are to accommodate nested TLV structures. But ECDSA signatures do not appear nested in TLV structures in either TLS (there's just a signature field) or X.509 (the signature is inside a BITSTRING, not directly in a SEQUENCE). So there does not seem to be a need for an ASN.1-like API for the ASN.1 format, just the format conversion itself in a buffer that just contains the signature.
#### Asymmetric cryptography TODO
[TODO] Other gaps?
## New APIs
This section presents new APIs to implement based on the [gap analysis](#gap-analysis).
### General notes
Each action to implement a function entails:
* Implement the library function.
* Document it precisely, including error conditions.
* Unit-test it.
* Mention it where relevant in the PSA transition guide.
### Hash APIs
Based on the [gap analysis](#hash-gap-analysis):
[ACTION] [#8340](https://github.com/Mbed-TLS/mbedtls/issues/8340) Move `mbedtls_md_psa_alg_from_type` and `mbedtls_md_type_from_psa_alg` from `library/md_psa.h` to `include/mbedtls/md.h`.
### MAC APIs
[TODO]
### Cipher and AEAD APIs
[TODO]
### Key derivation APIs
[TODO]
### Random generation APIs
[TODO]
### Asymmetric cryptography APIs
#### Asymmetric cryptography metadata APIs
Based on the [gap analysis](#asymmetric-cryptography-metadata):
* No further work is needed about RSA specifically. The amount of metadata other than hashes is sufficiently small to be handled in ad hoc ways in applications, and hashes have [their own conversions](#hash-apis).
* No further work is needed about ECC specifically. We have just added adequate functions.
* No further work is needed about DHM specifically. There is no good way to translate the relevant information.
* [OPEN] Is there a decent way to convert between `mbedtls_pk_type_t` plus extra information, and `psa_key_type_t` plus policy information? The two APIs are different in crucial ways, with different splits between key type, policy information and operation algorithm.
Thinking so far: there isn't really a nice way to present this conversion. For a specific key, `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_copy_from_psa` do the job.
#### API to create a PSA key from a PK context
Based on the [gap analysis](#using-a-legacy-key-pair-or-public-key-with-psa):
Given an `mbedtls_pk_context`, we want a function that creates a PSA key with the same key material and algorithm. “Same key material” is straightforward, but “same algorithm” is not, because a PK context has incomplete algorithm information. For example, there is no way to distinguish between an RSA key that is intended for signature or for encryption. Between algorithms of the same nature, there is no way to distinguish a key intended for PKCS#1v1.5 and one intended for PKCS#1v2.1 (OAEP/PSS): this is indicated in the underlying RSA context, but the indication there is only a default that can be overridden by calling `mbedtls_pk_{sign,verify}_ext`. Also there is no way to distinguish between `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)` and `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`: in the legacy interface, this is only determined when actually doing a signature/verification operation. Therefore the function that creates the PSA key needs extra information to indicate which algorithm to put in the key's policy.
When creating a PSA key, apart from the key material, the key is determined by attributes, which fall under three categories:
* Type and size. These are directly related to the key material and can be deduced from it if the key material is in a structured format, which is the case with an `mbedtls_pk_context` input.
* Policy. This includes the chosen algorithm, which as discussed above cannot be fully deduced from the `mbedtls_pk_context` object. Just choosing one algorithm is problematic because it doesn't allow implementation-specific extensions, such as Mbed TLS's enrollment algorithm. The intended usage flags cannot be deduced from the PK context either, but the conversion function could sensibly just enable all the relevant usage flags. Users who want a more restrictive usage can call `psa_copy_key` and `psa_destroy_key` to obtain a PSA key object with a more restrictive usage.
* Persistence and location. This is completely orthogonal to the information from the `mbedtls_pk_context` object. It is convenient, but not necessary, for the conversion function to allow customizing these aspects. If it doesn't, users can call the conversion function and then call `psa_copy_key` and `psa_destroy_key` to move the key to its desired location.
To allow the full flexibility around policies, and make the creation of a persistent key more convenient, the conversion function shall take a `const psa_key_attributes_t *` input, like all other functions that create a PSA key. In addition, there shall be a helper function to populate a `psa_key_attributes_t` with a sensible default. This lets the caller choose a more flexible, or just different usage policy, unlike the default-then-copy approach which only allows restricting the policy.
This is close to the existing function `mbedtls_pk_wrap_as_opaque`, but does not bake in the implementation-specific consideration that a PSA key has exactly two algorithms, and also allows the caller to benefit from default for the policy in more cases.
[ACTION] [#8708](https://github.com/Mbed-TLS/mbedtls/issues/8708) Implement `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_import_into_psa` as described below. These functions are available whenever `MBEDTLS_PK_C` and `MBEDTLS_PSA_CRYPTO_CLIENT` are both defined. Deprecate `mbedtls_pk_wrap_as_opaque`.
```
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
psa_key_usage_flags_t usage,
psa_key_attributes_t *attributes);
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key_id);
```
* `mbedtls_pk_get_psa_attributes` does not change the id/lifetime fields of the attributes (which indicate a volatile key by default).
* [OPEN] Or should it reset them to 0? Resetting is more convenient for the case where the pk key is a `MBEDTLS_PK_OPAQUE`. But that's an uncommon use case. It's probably less surprising if this function leaves the lifetime-related alone, since its job is to set the type-related and policy-related attributes.
* `mbedtls_pk_get_psa_attributes` sets the type and size based on what's in the pk context.
* The key type is a key pair if the context contains a private key and the indicated usage is a private-key usage. The key type is a public key if the context only contains a public key, in which case a private-key usage is an error.
* `mbedtls_pk_get_psa_attributes` sets the usage flags based on the `usage` parameter. It extends the usage to other usage that is possible:
* `EXPORT` and `COPY` are always set.
* If `SIGN_{HASH,MESSAGE}` is set then so is `VERIFY_{HASH,MESSAGE}`.
* If `DECRYPT` is set then so is `ENCRYPT`.
* It is an error if `usage` has more than one flag set, or has a usage that is incompatible with the key type.
* `mbedtls_pk_get_psa_attributes` sets the algorithm usage policy based on information in the key object and on `usage`.
* For an RSA key with the `MBEDTLS_RSA_PKCS_V15` padding mode, the algorithm policy is `PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_PKCS1V15_CRYPT` for an encrypt/decrypt usage.
* For an RSA key with the `MBEDTLS_RSA_PKCS_V21` padding mode, the algorithm policy is `PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_OAEP(hash)` for an encrypt/decrypt usage where `hash` is from the RSA key's parameters. (Note that `PSA_ALG_ANY_HASH` is only allowed in signature algorithms.)
* For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDSA` with a sign/verify usage, the algorithm policy is `PSA_ALG_DETERMINISTIC_ECDSA` if `MBEDTLS_ECDSA_DETERMINISTIC` is enabled and `PSA_ALG_ECDSA` otherwise. In either case, the hash policy is `PSA_ALG_ANY_HASH`.
* For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDKEY_DH` with the usage `PSA_KEY_USAGE_DERIVE`, the algorithm is `PSA_ALG_ECDH`.
* For a `MBEDTLS_PK_OPAQUE`, this function reads the attributes of the existing PK key and copies them (without overriding the lifetime and key identifier in `attributes`), then applies a public-key restriction if needed.
* Public-key restriction: if `usage` is a public-key usage, change the type to the corresponding public-key type, and remove private-key usage flags from the usage flags read from the existing key.
* `mbedtls_pk_import_into_psa` checks that the type field in the attributes is consistent with the content of the `mbedtls_pk_context` object (RSA/ECC, and availability of the private key).
* The key type can be a public key even if the private key is available.
* `mbedtls_pk_import_into_psa` does not need to check the bit-size in the attributes: `psa_import_key` will do enough checks.
* `mbedtls_pk_import_into_psa` does not check that the policy in the attributes is sensible. That's on the user.
#### API to copy a PSA key to a PK context
Based on the [gap analysis](#using-a-psa-key-as-a-pk-context):
[ACTION] [#8709](https://github.com/Mbed-TLS/mbedtls/issues/8709) Implement `mbedtls_pk_copy_from_psa` as described below.
```
int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id,
mbedtls_pk_context *pk);
```
* `pk` must be initialized, but not set up.
* It is an error if the key is neither a key pair nor a public key.
* It is an error if the key is not exportable.
* The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. That's `MBEDTLS_PK_RSA` for RSA keys (since pk objects don't use `MBEDTLS_PK_RSASSA_PSS` as a type), and `MBEDTLS_PK_ECKEY` for ECC keys (following the example of pkparse).
* Once this function returns, the pk object is completely independent of the PSA key.
* Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`) if that is a matching operation type (sign/verify, encrypt/decrypt), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`).
* For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today.
* For an RSA key, the output key will allow both encrypt/decrypt and sign/verify regardless of the original key's policy. The original key's policy determines the output key's padding mode.
* The primary intent of this requirement is to allow an application to switch to PSA for creating the key material (for example to benefit from a PSA accelerator driver, or to start using a secure element), without modifying the code that consumes the key. For RSA keys, the PSA primary algorithm policy is how one conveys the same information as RSA key padding information in the legacy API. Convey this in the documentation.
#### API to create a PK object that wraps a PSA key
Based on the [gap analysis](#using-a-psa-key-as-a-pk-context):
[ACTION] [#8712](https://github.com/Mbed-TLS/mbedtls/issues/8712) Clarify the documentation of `mbedtls_pk_setup_opaque` regarding which algorithms the resulting key will perform with `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt`.
[ACTION] [#8710](https://github.com/Mbed-TLS/mbedtls/issues/8710) Provide `mbedtls_pk_setup_opaque` whenever `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, not just when `MBEDTLS_USE_PSA_CRYPTO` is enabled. This is nice-to-have, not critical. Update `use-psa-crypto.md` accordingly.
[OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`?
#### API to convert between signature formats
Based on the [gap analysis](#signature-formats):
[ACTION] [#7765](https://github.com/Mbed-TLS/mbedtls/issues/7765) Implement `mbedtls_ecdsa_raw_to_der` and `mbedtls_ecdsa_der_to_raw` as described below.
```
int mbedtls_ecdsa_raw_to_der(size_t bits,
const unsigned char *raw, size_t raw_len,
unsigned char *der, size_t der_size, size_t *der_len);
int mbedtls_ecdsa_der_to_raw(size_t bits,
const unsigned char *der, size_t der_len,
unsigned char *raw, size_t raw_size, size_t *raw_len);
```
* These functions convert between the signature format used by `mbedtls_pk_{sign,verify}{,_ext}` and the signature format used by `psa_{sign,verify}_{hash,message}`.
* The input and output buffers can overlap.
* The `bits` parameter is necessary in the DER-to-raw direction because the DER format lacks leading zeros, so something else needs to convey the size of (r,s). The `bits` parameter is redundant in the raw-to-DER direction, but we have it anyway because [it helps catch errors](https://github.com/Mbed-TLS/mbedtls/pull/8681#discussion_r1445980971), and it isn't a burden on the caller because the information is readily available in practice.
* Should these functions rely on the ASN.1 module? We experimented [calling ASN.1 functions](https://github.com/Mbed-TLS/mbedtls/pull/8681), [reimplementing simpler ASN.1 functions](https://github.com/Mbed-TLS/mbedtls/pull/8696), and [providing the functions from the ASN.1 module](https://github.com/Mbed-TLS/mbedtls/pull/8703). Providing the functions from the ASN.1 module [won on a compromise of code size and simplicity](https://github.com/Mbed-TLS/mbedtls/issues/7765#issuecomment-1893670015).

View File

@ -105,7 +105,28 @@ provided by a driver or built-in, you should use the following macros:
- for code that uses only the PSA Crypto API: `PSA_WANT_ALG_xxx` from
`psa/crypto.h`;
- for code that uses non-PSA crypto APIs: `MBEDTLS_MD_CAN_xxx` from
`mbedtls/md.h`.
`mbedtls/config_adjust_legacy_crypto.h`.
### HMAC
In addition to accelerated hash operations, it is also possible to accelerate
HMAC by enabling and accelerating:
- HMAC algorithm and key type, i.e. `[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_HMAC` and
`[PSA_WANT|MBEDTLS_PSA_ACCEL]KEY_TYPE_HMAC`.
- Required hash algorithm(s) as explained in [Hashes](#hashes) section.
In such a build it is possible to disable legacy HMAC support by disabling
`MBEDTLS_MD_C` and still getting crypto operations, X.509 and TLS to work as
usual. Exceptions are:
- As mentioned in [Hashes](#hashes) direct calls to legacy lo-level hash APIs
(`mbedtls_sha256()` etc.) will not be possible for the legacy modules that
are disabled.
- Legacy HMAC support (`mbedtls_md_hmac_xxx()`) won't be possible.
- `MBEDTLS_PKCS[5|7]_C`, `MBEDTLS_HMAC_DRBG_C` and `MBEDTLS_HKDF_C` since they
depend on the legacy implementation of HMAC.
- disabling HMAC_DRBG_C cause deterministic ECDSA (i.e.
`MBEDTLS_DETERMINISTIC_ECDSA` on the legacy side and
`PSA_WANT_ALG_DETERMINISTIC_ECDSA` on the PSA one) to be not available.
Elliptic-curve cryptography (ECC)
---------------------------------

View File

@ -157,11 +157,11 @@ The driver wrapper functions in `psa_crypto_driver_wrappers.h.jinja` for all fou
```
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
attributes->core.bits == 256 )
PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_sign_hash( attributes,
key_buffer,

View File

@ -845,7 +845,6 @@ For an ECC private key (a future version of Mbed TLS [will provide a more direct
```
unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk));
mbedtls_ecp_keypair *ec = mbedtls_pk_ec(&pk);
psa_ecc_curve_t curve;
{
@ -862,7 +861,8 @@ psa_ecc_curve_t curve;
mbedtls_ecp_point_free(&Q);
mbedtls_mpi_free(&d);
}
mbedtls_ecp_write_key(ec, buf, length);
size_t length;
mbedtls_ecp_write_key_ext(ec, &length, buf, sizeof(buf));
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
@ -900,8 +900,8 @@ mbedtls_ecp_keypair_init(&ec);
// Omitted: fill ec with key material
// (the public key will not be used and does not need to be set)
unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk));
mbedtls_ecp_write_key(&ec, buf, length);
size_t length;
mbedtls_ecp_write_key_ext(&ec, &length, buf, sizeof(buf));
psa_ecc_curve_t curve = ...; // need to determine the curve family manually
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
@ -1300,7 +1300,7 @@ There is no PSA equivalent to the types `mbedtls_ecdsa_context` and `mbedtls_ecd
The PSA API is a cryptography API, not an arithmetic API. As a consequence, there is no PSA equivalent for the ECC arithmetic functionality exposed by `ecp.h`:
* Manipulation of point objects and input-output: the type `mbedtls_ecp_point` and functions operating on it (`mbedtls_ecp_point_xxx`, `mbedtls_ecp_copy`, `mbedtls_ecp_{set,is}_zero`, `mbedtls_ecp_tls_{read,write}_point`). Note that the PSA export format for public keys corresponds to the uncompressed point format (`MBEDTLS_ECP_PF_UNCOMPRESSED`), so [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) are equivalent to `mbedtls_ecp_point_read_binary` and `mbedtls_ecp_point_write_binary` for uncompressed points. The PSA API does not currently support compressed points, but it is likely that such support will be added in the future.
* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key`.
* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key_ext`.
* Elliptic curve arithmetic (`mbedtls_ecp_mul`, `mbedtls_ecp_muladd` and their restartable variants).
### Additional information about RSA

View File

@ -6,7 +6,7 @@ EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
CASE_SENSE_NAMES = NO
INPUT = ../include input
INPUT = ../include input ../tests/include/alt-dummy
FILE_PATTERNS = *.h
RECURSIVE = YES
EXCLUDE_SYMLINKS = YES

View File

@ -197,7 +197,8 @@ typedef struct mbedtls_asn1_named_data {
}
mbedtls_asn1_named_data;
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/**
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
@ -244,7 +245,7 @@ int mbedtls_asn1_get_len(unsigned char **p,
int mbedtls_asn1_get_tag(unsigned char **p,
const unsigned char *end,
size_t *len, int tag);
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_PARSE_C)
/**

View File

@ -36,7 +36,8 @@
extern "C" {
#endif
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C)
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/**
* \brief Write a length field in ASN.1 format.
*
@ -65,7 +66,7 @@ int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start,
*/
int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start,
unsigned char tag);
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA*/
#if defined(MBEDTLS_ASN1_WRITE_C)
/**

View File

@ -51,15 +51,15 @@
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
/*
* Maximum window size used for modular exponentiation. Default: 2
* Maximum window size used for modular exponentiation. Default: 3
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
* for the sliding window calculation. (So 8 by default)
*
* Reduction in size, reduces speed.
*/
#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */
#define MBEDTLS_MPI_WINDOW_SIZE 3 /**< Maximum window size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)

View File

@ -158,7 +158,8 @@
* (e.g. MBEDTLS_MD_LIGHT)
*/
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \
defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */
defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */ || \
defined(MBEDTLS_PSA_CRYPTO_CLIENT) /* The same as the previous, but with separation only */
#include "mbedtls/config_psa.h"
#endif

View File

@ -27,18 +27,8 @@
#if !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_C is required on Windows"
#endif
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in mbedtls_config.h as
* it would confuse config.py. */
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
#endif
/* See auto-enabling SNPRINTF_ALT and VSNPRINTF_ALT
* in * config_adjust_legacy_crypto.h */
#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */
#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C)
@ -54,65 +44,6 @@
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
#endif
/* Check that each MBEDTLS_ECP_DP_xxx symbol has its PSA_WANT_ECC_xxx counterpart
* when PSA crypto is enabled. */
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) || defined(MBEDTLS_PSA_CRYPTO_C)
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
#error "MBEDTLS_ECP_DP_BP256R1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
#error "MBEDTLS_ECP_DP_BP384R1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
#error "MBEDTLS_ECP_DP_BP512R1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && !defined(PSA_WANT_ECC_MONTGOMERY_255)
#error "MBEDTLS_ECP_DP_CURVE25519_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) && !defined(PSA_WANT_ECC_MONTGOMERY_448)
#error "MBEDTLS_ECP_DP_CURVE448_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_192)
#error "MBEDTLS_ECP_DP_SECP192R1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_224)
#error "MBEDTLS_ECP_DP_SECP224R1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_256)
#error "MBEDTLS_ECP_DP_SECP256R1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_384)
#error "MBEDTLS_ECP_DP_SECP384R1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_521)
#error "MBEDTLS_ECP_DP_SECP521R1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && !defined(PSA_WANT_ECC_SECP_K1_192)
#error "MBEDTLS_ECP_DP_SECP192K1_ENABLED defined, but not its PSA counterpart"
#endif
/* SECP224K1 is buggy in PSA API so we skip this check */
#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && !defined(PSA_WANT_ECC_SECP_K1_224)
#error "MBEDTLS_ECP_DP_SECP224K1_ENABLED defined, but not its PSA counterpart"
#endif
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && !defined(PSA_WANT_ECC_SECP_K1_256)
#error "MBEDTLS_ECP_DP_SECP256K1_ENABLED defined, but not its PSA counterpart"
#endif
#endif /* MBEDTLS_PSA_CRYPTO_CONFIG || MBEDTLS_PSA_CRYPTO_C */
/* Limitations on ECC key types acceleration: if we have any of `PUBLIC_KEY`,
* `KEY_PAIR_BASIC`, `KEY_PAIR_IMPORT`, `KEY_PAIR_EXPORT` then we must have
* all 4 of them.
@ -154,7 +85,7 @@
#endif /* some curve accelerated */
#if defined(MBEDTLS_CTR_DRBG_C) && !(defined(MBEDTLS_AES_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_KEY_TYPE_AES) && \
(defined(MBEDTLS_PSA_CRYPTO_CLIENT) && defined(PSA_WANT_KEY_TYPE_AES) && \
defined(PSA_WANT_ALG_ECB_NO_PADDING)))
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
@ -234,9 +165,8 @@
#endif
#endif /* MBEDTLS_PK_C && MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECJPAKE_C) && \
( !defined(MBEDTLS_ECP_C) || \
!( defined(MBEDTLS_MD_C) || defined(MBEDTLS_PSA_CRYPTO_C) ) )
#if defined(MBEDTLS_ECJPAKE_C) && \
!defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
@ -277,27 +207,8 @@
#error "MBEDTLS_ECP_C defined (or a subset enabled), but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
#endif
/* Helpers for hash dependencies, will be undefined at the end of the file */
/* Do SHA-256, 384, 512 to cover Entropy and TLS. */
#if defined(MBEDTLS_SHA256_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256))
#define MBEDTLS_MD_HAVE_SHA256
#endif
#if defined(MBEDTLS_SHA384_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_384))
#define MBEDTLS_MD_HAVE_SHA384
#endif
#if defined(MBEDTLS_SHA512_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_512))
#define MBEDTLS_MD_HAVE_SHA512
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
!(defined(MBEDTLS_MD_HAVE_SHA512) || defined(MBEDTLS_MD_HAVE_SHA256))
!(defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA256))
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
@ -305,24 +216,24 @@
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
(defined(MBEDTLS_ENTROPY_FORCE_SHA256) || !defined(MBEDTLS_MD_HAVE_SHA512)) \
(defined(MBEDTLS_ENTROPY_FORCE_SHA256) || !defined(MBEDTLS_MD_CAN_SHA512)) \
&& defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_MD_HAVE_SHA256)
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_MD_CAN_SHA256)
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define MBEDTLS_HAS_MEMSAN
#define MBEDTLS_HAS_MEMSAN // #undef at the end of this paragraph
#endif
#endif
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN)
#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer"
#endif
#undef MBEDTLS_HAS_MEMSAN
#undef MBEDTLS_HAS_MEMSAN // temporary macro defined above
#if defined(MBEDTLS_CCM_C) && \
!(defined(MBEDTLS_CCM_GCM_CAN_AES) || defined(MBEDTLS_CCM_GCM_CAN_ARIA) || \
@ -388,28 +299,6 @@
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
/* Helper for JPAKE dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#define MBEDTLS_PK_HAVE_JPAKE
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECJPAKE_C)
#define MBEDTLS_PK_HAVE_JPAKE
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Helper for curve SECP256R1 */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ECC_SECP_R1_256)
#define MBEDTLS_PK_HAVE_CURVE_SECP256R1
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
#define MBEDTLS_PK_HAVE_CURVE_SECP256R1
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_CAN_ECDH) || \
!defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \
@ -463,47 +352,52 @@
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_PK_HAVE_JPAKE) || \
!defined(MBEDTLS_PK_HAVE_CURVE_SECP256R1) )
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(PSA_WANT_ALG_JPAKE) || \
!defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
!defined(PSA_WANT_ECC_SECP_R1_256) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Use of EC J-PAKE in TLS requires SHA-256. */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
!defined(MBEDTLS_MD_HAVE_SHA256)
!defined(MBEDTLS_MD_CAN_SHA256)
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
( !defined(MBEDTLS_SHA256_C) && \
!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA1_C) )
#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires MBEDTLS_SHA512_C, MBEDTLS_SHA256_C or MBEDTLS_SHA1_C"
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
!defined(MBEDTLS_MD_CAN_SHA256) && \
!defined(MBEDTLS_MD_CAN_SHA512) && \
!defined(MBEDTLS_MD_CAN_SHA1)
#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires SHA-512, SHA-256 or SHA-1".
#endif
#if defined(MBEDTLS_MD_C) && !( \
defined(MBEDTLS_MD5_C) || \
defined(MBEDTLS_RIPEMD160_C) || \
defined(MBEDTLS_SHA1_C) || \
defined(MBEDTLS_SHA224_C) || \
defined(MBEDTLS_SHA256_C) || \
defined(MBEDTLS_SHA384_C) || \
defined(MBEDTLS_SHA512_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && \
(defined(PSA_WANT_ALG_MD5) || \
defined(PSA_WANT_ALG_RIPEMD160) || \
defined(PSA_WANT_ALG_SHA_1) || \
defined(PSA_WANT_ALG_SHA_224) || \
defined(PSA_WANT_ALG_SHA_256) || \
defined(PSA_WANT_ALG_SHA_384) || \
defined(PSA_WANT_ALG_SHA_512))))
#error "MBEDTLS_MD_C defined, but not all prerequisites"
#if defined(MBEDTLS_MD_C) && \
!defined(MBEDTLS_MD_CAN_MD5) && \
!defined(MBEDTLS_MD_CAN_RIPEMD160) && \
!defined(MBEDTLS_MD_CAN_SHA1) && \
!defined(MBEDTLS_MD_CAN_SHA224) && \
!defined(MBEDTLS_MD_CAN_SHA256) && \
!defined(MBEDTLS_MD_CAN_SHA384) && \
!defined(MBEDTLS_MD_CAN_SHA512) && \
!defined(MBEDTLS_MD_CAN_SHA3_224) && \
!defined(MBEDTLS_MD_CAN_SHA3_256) && \
!defined(MBEDTLS_MD_CAN_SHA3_384) && \
!defined(MBEDTLS_MD_CAN_SHA3_512)
#error "MBEDTLS_MD_C defined, but no hash algorithm"
#endif
#if defined(MBEDTLS_LMS_C) && \
! ( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256) )
! ( defined(MBEDTLS_PSA_CRYPTO_CLIENT) && defined(PSA_WANT_ALG_SHA_256) )
#error "MBEDTLS_LMS_C requires MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256"
#endif
@ -538,11 +432,17 @@
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
#if defined(MBEDTLS_PK_PARSE_C) && \
(!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_OID_C) || \
!defined(MBEDTLS_PK_C))
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
#if defined(MBEDTLS_PK_WRITE_C) && \
(!defined(MBEDTLS_ASN1_WRITE_C) || \
!defined(MBEDTLS_OID_C) || \
!defined(MBEDTLS_PK_C))
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
#endif
@ -891,7 +791,7 @@
* Note: for dependencies common with TLS 1.2 (running handshake hash),
* see MBEDTLS_SSL_TLS_C. */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
!(defined(MBEDTLS_PSA_CRYPTO_C) && \
!(defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
defined(PSA_WANT_ALG_HKDF_EXTRACT) && \
defined(PSA_WANT_ALG_HKDF_EXPAND) && \
(defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384)))
@ -975,7 +875,7 @@
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if !defined(MBEDTLS_MD_C) || \
!(defined(MBEDTLS_MD_HAVE_SHA256) || defined(MBEDTLS_MD_HAVE_SHA384))
!(defined(MBEDTLS_MD_CAN_SHA256) || defined(MBEDTLS_MD_CAN_SHA384))
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
@ -1074,22 +974,20 @@
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#define MBEDTLS_THREADING_IMPL // undef at the end of this paragraph
#endif
#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#define MBEDTLS_THREADING_IMPL // undef at the end of this paragraph
#endif
#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
#endif
#undef MBEDTLS_THREADING_IMPL
#undef MBEDTLS_THREADING_IMPL // temporary macro defined above
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C)
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites"
#endif
@ -1218,13 +1116,6 @@
#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
#endif
/* Undefine helper symbols */
#undef MBEDTLS_PK_HAVE_JPAKE
#undef MBEDTLS_MD_HAVE_SHA256
#undef MBEDTLS_MD_HAVE_SHA384
#undef MBEDTLS_MD_HAVE_SHA512
#undef MBEDTLS_PK_HAVE_CURVE_SECP256R1
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the

View File

@ -678,7 +678,6 @@ int MBEDTLS_DEPRECATED mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,
static inline unsigned int mbedtls_cipher_get_block_size(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return 0;
}
@ -698,7 +697,6 @@ static inline unsigned int mbedtls_cipher_get_block_size(
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, MBEDTLS_MODE_NONE);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return MBEDTLS_MODE_NONE;
}
@ -719,7 +717,6 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
static inline int mbedtls_cipher_get_iv_size(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return 0;
}
@ -743,8 +740,6 @@ static inline int mbedtls_cipher_get_iv_size(
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_CIPHER_NONE);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return MBEDTLS_CIPHER_NONE;
}
@ -764,7 +759,6 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
static inline const char *mbedtls_cipher_get_name(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return 0;
}
@ -784,8 +778,6 @@ static inline const char *mbedtls_cipher_get_name(
static inline int mbedtls_cipher_get_key_bitlen(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_KEY_LENGTH_NONE);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return MBEDTLS_KEY_LENGTH_NONE;
}
@ -805,8 +797,6 @@ static inline int mbedtls_cipher_get_key_bitlen(
static inline mbedtls_operation_t mbedtls_cipher_get_operation(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_OPERATION_NONE);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return MBEDTLS_OPERATION_NONE;
}

View File

@ -22,6 +22,22 @@
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
#define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
/* Ideally, we'd set those as defaults in mbedtls_config.h, but
* putting an #ifdef _WIN32 in mbedtls_config.h would confuse config.py.
*
* So, adjust it here.
* Not related to crypto, but this is the bottom of the stack. */
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
#endif
#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */
/* Auto-enable CIPHER_C when any of the unauthenticated ciphers is builtin
* in PSA. */
#if defined(MBEDTLS_PSA_CRYPTO_C) && \
@ -324,15 +340,6 @@
#define MBEDTLS_PSA_CRYPTO_CLIENT
#endif /* MBEDTLS_PSA_CRYPTO_C */
/* The PK wrappers need pk_write/pk_parse functions to format RSA key objects
* when they are dispatching to the PSA API. This happens under MBEDTLS_USE_PSA_CRYPTO,
* and even under just MBEDTLS_PSA_CRYPTO_C in psa_crypto_rsa.c. */
#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
/* Helpers to state that each key is supported either on the builtin or PSA side. */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521)
#define MBEDTLS_ECP_HAVE_SECP521R1
@ -400,6 +407,13 @@
#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
#endif
/* psa_util file features some ECDSA conversion functions, to convert between
* legacy's ASN.1 DER format and PSA's raw one. */
#if defined(MBEDTLS_ECDSA_C) || (defined(MBEDTLS_PSA_CRYPTO_C) && \
(defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)))
#define MBEDTLS_PSA_UTIL_HAVE_ECDSA
#endif
/* Some internal helpers to determine which keys are availble. */
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES))

View File

@ -47,139 +47,65 @@
*/
/* ECC: curves: is acceleration complete? */
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256)
#if (defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256)) || \
(defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384)) || \
(defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512)) || \
(defined(PSA_WANT_ECC_SECP_R1_192) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192)) || \
(defined(PSA_WANT_ECC_SECP_R1_224) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224)) || \
(defined(PSA_WANT_ECC_SECP_R1_256) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256)) || \
(defined(PSA_WANT_ECC_SECP_R1_384) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384)) || \
(defined(PSA_WANT_ECC_SECP_R1_521) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)) || \
(defined(PSA_WANT_ECC_SECP_K1_192) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192)) || \
(defined(PSA_WANT_ECC_SECP_K1_224) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224)) || \
(defined(PSA_WANT_ECC_SECP_K1_256) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384)
#if (defined(PSA_WANT_ECC_MONTGOMERY_255) && !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255)) || \
(defined(PSA_WANT_ECC_MONTGOMERY_448) && !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_MONTGOMERY_255) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#endif
#if defined(PSA_WANT_ECC_MONTGOMERY_448) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#endif
#if defined(PSA_WANT_ECC_SECP_R1_192) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_SECP_R1_224) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_SECP_R1_256) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_SECP_R1_384) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_SECP_R1_521) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_SECP_K1_192) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_SECP_K1_224) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if defined(PSA_WANT_ECC_SECP_K1_256) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
/* ECC: algs: is acceleration complete? */
#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS
#endif
#if defined(PSA_WANT_ALG_ECDH) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_ECDH)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS
#endif
#if defined(PSA_WANT_ALG_ECDSA) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS
#endif
#if defined(PSA_WANT_ALG_JPAKE) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE)
#if (defined(PSA_WANT_ALG_ECDH) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH)) || \
(defined(PSA_WANT_ALG_ECDSA) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)) || \
(defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)) || \
(defined(PSA_WANT_ALG_JPAKE) && !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS
#endif
/* ECC: key types: is acceleration complete? */
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES
#if (defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC
#endif
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC
#endif
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES
#endif
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES
#endif
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES
#endif
/* Special case: we don't support cooked key derivation in drivers yet */
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
#undef MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE
#endif
/* Note: the condition is always true as DERIVE can't be accelerated yet */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
/* Note: the condition about key derivation is always true as DERIVE can't be
* accelerated yet */
#if (defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES
#endif
@ -386,8 +312,6 @@
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
#define MBEDTLS_ECP_LIGHT
#define MBEDTLS_BIGNUM_C
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
@ -396,8 +320,6 @@
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
#define MBEDTLS_ECP_LIGHT
#define MBEDTLS_BIGNUM_C
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */
@ -405,8 +327,6 @@
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
#define MBEDTLS_ECP_LIGHT
#define MBEDTLS_BIGNUM_C
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT */
@ -414,8 +334,6 @@
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT */
@ -423,8 +341,6 @@
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
@ -433,20 +349,149 @@
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
#define MBEDTLS_ECP_LIGHT
#define MBEDTLS_BIGNUM_C
#endif /* missing accel */
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
#define MBEDTLS_ECP_LIGHT
#define MBEDTLS_BIGNUM_C
#endif
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#endif
/* End of ECC section */
/*
* DH key types follow the same pattern used above for EC keys. They are defined
* by a triplet (group, key_type, alg). A triplet is accelerated if all its
* component are accelerated, otherwise each component needs to be builtin.
*/
/* DH: groups: is acceleration complete? */
#if (defined(PSA_WANT_DH_RFC7919_2048) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_2048)) || \
(defined(PSA_WANT_DH_RFC7919_3072) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_3072)) || \
(defined(PSA_WANT_DH_RFC7919_4096) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_4096)) || \
(defined(PSA_WANT_DH_RFC7919_6144) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_6144)) || \
(defined(PSA_WANT_DH_RFC7919_8192) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_8192))
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS
#endif
/* DH: algs: is acceleration complete? */
#if defined(PSA_WANT_ALG_FFDH) && !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH)
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS
#endif
/* DH: key types: is acceleration complete? */
#if (defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY)) || \
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC)) || \
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT)) || \
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT)) || \
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE))
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES
#endif
#if defined(PSA_WANT_DH_RFC7919_2048)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_2048) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
#endif /* PSA_WANT_DH_RFC7919_2048 */
#if defined(PSA_WANT_DH_RFC7919_3072)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_3072) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
#endif /* PSA_WANT_DH_RFC7919_3072 */
#if defined(PSA_WANT_DH_RFC7919_4096)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_4096) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
#endif /* PSA_WANT_DH_RFC7919_4096 */
#if defined(PSA_WANT_DH_RFC7919_6144)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_6144) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
#endif /* PSA_WANT_DH_RFC7919_6144 */
#if defined(PSA_WANT_DH_RFC7919_8192)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_8192) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
#endif /* PSA_WANT_DH_RFC7919_8192 */
#if defined(PSA_WANT_ALG_FFDH)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1
#define MBEDTLS_BIGNUM_C
#endif /* !MBEDTLS_PSA_ACCEL_ALG_FFDH */
#endif /* PSA_WANT_ALG_FFDH */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC */
#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1
#define MBEDTLS_BIGNUM_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY */
#endif /* PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY */
/* End of DH section */
#if defined(PSA_WANT_ALG_HKDF)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF)
/*
@ -634,46 +679,12 @@
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC */
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC */
#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1
#define MBEDTLS_BIGNUM_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY */
#endif /* PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY */
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_PK_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */

View File

@ -81,13 +81,22 @@
#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE 1
#define PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY 1
#define PSA_WANT_ALG_FFDH 1
#define PSA_WANT_DH_FAMILY_RFC7919 1
#define PSA_WANT_DH_RFC7919_2048 1
#define PSA_WANT_DH_RFC7919_3072 1
#define PSA_WANT_DH_RFC7919_4096 1
#define PSA_WANT_DH_RFC7919_6144 1
#define PSA_WANT_DH_RFC7919_8192 1
#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 1
#endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_GCM_C)

View File

@ -34,6 +34,10 @@
#undef MBEDTLS_SSL_PROTO_DTLS
#endif
#if !(defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SESSION_TICKETS))
#undef MBEDTLS_SSL_TICKET_C
#endif
#if !defined(MBEDTLS_SSL_PROTO_DTLS)
#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID

View File

@ -149,165 +149,8 @@ extern "C" {
*/
void mbedtls_debug_set_threshold(int threshold);
/**
* \brief Print a message to the debug output. This function is always used
* through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
* context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the message has occurred in
* \param line line number the message has occurred at
* \param format format specifier, in printf format
* \param ... variables used by the format specifier
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6);
/**
* \brief Print the return value of a function to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text the name of the function that returned the error
* \param ret the return code value
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret);
/**
* \brief Output a buffer of size len bytes to the debug output. This function
* is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the buffer being dumped. Normally the
* variable or buffer name
* \param buf the buffer to be outputted
* \param len length of the buffer
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text,
const unsigned char *buf, size_t len);
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Print a MPI variable to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the MPI being output. Normally the
* variable name
* \param X the MPI variable
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X);
#endif
#if defined(MBEDTLS_ECP_LIGHT)
/**
* \brief Print an ECP point to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the ECP point being output. Normally the
* variable name
* \param X the ECP point
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_ecp_point *X);
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
/**
* \brief Print a X.509 certificate structure to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the certificate being output
* \param crt X.509 certificate structure
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_x509_crt *crt);
#endif
/* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function
only works for the built-in implementation. */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \
defined(MBEDTLS_ECDH_C)
typedef enum {
MBEDTLS_DEBUG_ECDH_Q,
MBEDTLS_DEBUG_ECDH_QP,
MBEDTLS_DEBUG_ECDH_Z,
} mbedtls_debug_ecdh_attr;
/**
* \brief Print a field of the ECDH structure in the SSL context to the debug
* output. This function is always used through the
* MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
* and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param ecdh the ECDH context
* \param attr the identifier of the attribute being output
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const mbedtls_ecdh_context *ecdh,
mbedtls_debug_ecdh_attr attr);
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
MBEDTLS_ECDH_C */
#ifdef __cplusplus
}
#endif
#endif /* debug.h */
#endif /* MBEDTLS_DEBUG_H */

View File

@ -141,6 +141,19 @@ typedef struct mbedtls_ecdh_context {
}
mbedtls_ecdh_context;
/**
* \brief Return the ECP group for provided context.
*
* \note To access group specific fields, users should use
* `mbedtls_ecp_curve_info_from_grp_id` or
* `mbedtls_ecp_group_load` on the extracted `group_id`.
*
* \param ctx The ECDH context to parse. This must not be \c NULL.
*
* \return The \c mbedtls_ecp_group_id of the context.
*/
mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx);
/**
* \brief Check whether a given group can be used for ECDH.
*

View File

@ -24,6 +24,7 @@
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/bignum.h"
@ -1327,28 +1328,84 @@ int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,
int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
const unsigned char *buf, size_t buflen);
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/**
* \brief This function exports an elliptic curve private key.
*
* \deprecated Note that although this function accepts an output
* buffer that is smaller or larger than the key, most key
* import interfaces require the output to have exactly
* key's nominal length. It is generally simplest to
* pass the key's nominal length as \c buflen, after
* checking that the output buffer is large enough.
* See the description of the \p buflen parameter for
* how to calculate the nominal length.
* To avoid this difficulty, use mbedtls_ecp_write_key_ext()
* instead.
* mbedtls_ecp_write_key() is deprecated and will be
* removed in a future version of the library.
*
* \note If the private key was not set in \p key,
* the output is unspecified. Future versions
* may return an error in that case.
*
* \param key The private key.
* \param buf The output buffer for containing the binary representation
* of the key.
* For Weierstrass curves, this is the big-endian
* representation, padded with null bytes at the beginning
* to reach \p buflen bytes.
* For Montgomery curves, this is the standard byte string
* representation (which is little-endian), padded with
* null bytes at the end to reach \p buflen bytes.
* \param buflen The total length of the buffer in bytes.
* The length of the output is
* (`grp->nbits` + 7) / 8 bytes
* where `grp->nbits` is the private key size in bits.
* For Weierstrass keys, if the output buffer is smaller,
* leading zeros are trimmed to fit if possible. For
* Montgomery keys, the output buffer must always be large
* enough for the nominal length.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL or
* #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the \p key
* representation is larger than the available space in \p buf.
* \return Another negative error code on different kinds of failure.
*/
int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen);
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief This function exports an elliptic curve private key.
*
* \param key The private key.
* \param olen On success, the length of the private key.
* This is always (`grp->nbits` + 7) / 8 bytes
* where `grp->nbits` is the private key size in bits.
* \param buf The output buffer for containing the binary representation
* of the key. (Big endian integer for Weierstrass curves, byte
* string for Montgomery curves.)
* of the key.
* \param buflen The total length of the buffer in bytes.
* #MBEDTLS_ECP_MAX_BYTES is always sufficient.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key
representation is larger than the available space in \p buf.
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
* the group is not implemented.
* representation is larger than the available space in \p buf.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if no private key is
* set in \p key.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen);
int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
size_t *olen, unsigned char *buf, size_t buflen);
/**
* \brief This function exports an elliptic curve public key.
*
* \note If the public key was not set in \p key,
* the output is unspecified. Future versions
* may return an error in that case.
*
* \param key The public key.
* \param format The point format. This must be either
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
@ -1431,6 +1488,10 @@ mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id(
* Each of the output parameters can be a null pointer
* if you do not need that parameter.
*
* \note If the private key or the public key was not set in \p key,
* the corresponding output is unspecified. Future versions
* may return an error in that case.
*
* \param key The key pair to export from.
* \param grp Slot for exported ECP group.
* It must either be null or point to an initialized ECP group.

View File

@ -46,6 +46,12 @@ extern "C" {
#if !defined(MBEDTLS_GCM_ALT)
#if defined(MBEDTLS_GCM_LARGE_TABLE)
#define MBEDTLS_GCM_HTABLE_SIZE 256
#else
#define MBEDTLS_GCM_HTABLE_SIZE 16
#endif
/**
* \brief The GCM context structure.
*/
@ -53,18 +59,18 @@ typedef struct mbedtls_gcm_context {
#if defined(MBEDTLS_BLOCK_CIPHER_C)
mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */
#else
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
#endif
uint64_t MBEDTLS_PRIVATE(HL)[16]; /*!< Precalculated HTable low. */
uint64_t MBEDTLS_PRIVATE(HH)[16]; /*!< Precalculated HTable high. */
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */
uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */
unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */
unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */
int MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
#MBEDTLS_GCM_ENCRYPT or
#MBEDTLS_GCM_DECRYPT. */
uint64_t MBEDTLS_PRIVATE(H)[MBEDTLS_GCM_HTABLE_SIZE][2]; /*!< Precalculated HTable. */
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */
uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */
unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */
unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */
unsigned char MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
#MBEDTLS_GCM_ENCRYPT or
#MBEDTLS_GCM_DECRYPT. */
unsigned char MBEDTLS_PRIVATE(acceleration); /*!< The acceleration to use. */
}
mbedtls_gcm_context;

View File

@ -2816,6 +2816,22 @@
*/
#define MBEDTLS_GCM_C
/**
* \def MBEDTLS_GCM_LARGE_TABLE
*
* Enable large pre-computed tables for Galois/Counter Mode (GCM).
* Can significantly increase throughput on systems without GCM hardware
* acceleration (e.g., AESNI, AESCE).
*
* The mbedtls_gcm_context size will increase by 3840 bytes.
* The code size will increase by roughly 344 bytes.
*
* Module: library/gcm.c
*
* Requires: MBEDTLS_GCM_C
*/
//#define MBEDTLS_GCM_LARGE_TABLE
/**
* \def MBEDTLS_HKDF_C
*
@ -3075,7 +3091,7 @@
* Caller: library/x509_crt.c
* library/x509_csr.c
*
* Requires: MBEDTLS_PK_C
* Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_C
*
* Uncomment to enable generic public key parse functions.
*/
@ -3089,7 +3105,7 @@
* Module: library/pkwrite.c
* Caller: library/x509write.c
*
* Requires: MBEDTLS_PK_C
* Requires: MBEDTLS_ASN1_WRITE_C, MBEDTLS_OID_C, MBEDTLS_PK_C
*
* Uncomment to enable generic public key write functions.
*/

View File

@ -288,12 +288,17 @@
#define MBEDTLS_OID_HMAC_RIPEMD160 MBEDTLS_OID_INTERNET "\x05\x05\x08\x01\x04" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= {iso(1) iso-identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1) hmacRIPEMD160(4)} */
/*
* Encryption algorithms
* Encryption algorithms,
* the following standardized object identifiers are specified at
* https://datatracker.ietf.org/doc/html/rfc8018#appendix-C.
*/
#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG \
MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
#define MBEDTLS_OID_AES_128_CBC MBEDTLS_OID_AES "\x02" /** aes128-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes128-CBC-PAD(2) } */
#define MBEDTLS_OID_AES_192_CBC MBEDTLS_OID_AES "\x16" /** aes192-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes192-CBC-PAD(22) } */
#define MBEDTLS_OID_AES_256_CBC MBEDTLS_OID_AES "\x2a" /** aes256-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes256-CBC-PAD(42) } */
/*
* Key Wrapping algorithms

View File

@ -73,11 +73,11 @@ void mbedtls_pem_init(mbedtls_pem_context *ctx);
* \param data source data to look in (must be nul-terminated)
* \param pwd password for decryption (can be NULL)
* \param pwdlen length of password
* \param use_len destination for total length used (set after header is
* correctly read, so unless you get
* \param use_len destination for total length used from data buffer. It is
* set after header is correctly read, so unless you get
* MBEDTLS_ERR_PEM_BAD_INPUT_DATA or
* MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
* the length to skip)
* the length to skip.
*
* \note Attempts to check password correctness by verifying if
* the decrypted text starts with an ASN.1 sequence of

View File

@ -28,7 +28,7 @@
#include "mbedtls/ecdsa.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include "psa/crypto.h"
#endif
@ -181,13 +181,6 @@ typedef struct mbedtls_pk_rsassa_pss_options {
#define MBEDTLS_PK_USE_PSA_EC_DATA
#endif
/* Helper symbol to state that the PK module has support for EC keys. This
* can either be provided through the legacy ECP solution or through the
* PSA friendly MBEDTLS_PK_USE_PSA_EC_DATA. */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_ECP_C)
#define MBEDTLS_PK_HAVE_ECC_KEYS
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_ECP_C */
/**
* \brief Types for interfacing with the debug module
*/
@ -253,6 +246,8 @@ typedef struct mbedtls_pk_context {
* inside the ecp_keypair structure
* - the following fields are used for all public key operations: signature
* verify, key pair check and key write.
* - For a key pair, priv_id contains the private key. For a public key,
* priv_id is null.
* Of course, when MBEDTLS_PK_USE_PSA_EC_DATA is not enabled, the legacy
* ecp_keypair structure is used for storing the public key and performing
* all the operations.
@ -484,6 +479,168 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
psa_key_usage_t usage);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PSA_CRYPTO_C)
/**
* \brief Determine valid PSA attributes that can be used to
* import a key into PSA.
*
* The attributes determined by this function are suitable
* for calling mbedtls_pk_import_into_psa() to create
* a PSA key with the same key material.
*
* The typical flow of operations involving this function is
* ```
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* int ret = mbedtls_pk_get_psa_attributes(pk, &attributes);
* if (ret != 0) ...; // error handling omitted
* // Tweak attributes if desired
* psa_key_id_t key_id = 0;
* ret = mbedtls_pk_import_into_psa(pk, &attributes, &key_id);
* if (ret != 0) ...; // error handling omitted
* ```
*
* \note This function does not support RSA-alt contexts
* (set up with mbedtls_pk_setup_rsa_alt()).
*
* \param[in] pk The PK context to use. It must have been set up.
* It can either contain a key pair or just a public key.
* \param usage A single `PSA_KEY_USAGE_xxx` flag among the following:
* - #PSA_KEY_USAGE_DECRYPT: \p pk must contain a
* key pair. The output \p attributes will contain a
* key pair type, and the usage policy will allow
* #PSA_KEY_USAGE_ENCRYPT as well as
* #PSA_KEY_USAGE_DECRYPT.
* - #PSA_KEY_USAGE_DERIVE: \p pk must contain a
* key pair. The output \p attributes will contain a
* key pair type.
* - #PSA_KEY_USAGE_ENCRYPT: The output
* \p attributes will contain a public key type.
* - #PSA_KEY_USAGE_SIGN_HASH: \p pk must contain a
* key pair. The output \p attributes will contain a
* key pair type, and the usage policy will allow
* #PSA_KEY_USAGE_VERIFY_HASH as well as
* #PSA_KEY_USAGE_SIGN_HASH.
* - #PSA_KEY_USAGE_SIGN_MESSAGE: \p pk must contain a
* key pair. The output \p attributes will contain a
* key pair type, and the usage policy will allow
* #PSA_KEY_USAGE_VERIFY_MESSAGE as well as
* #PSA_KEY_USAGE_SIGN_MESSAGE.
* - #PSA_KEY_USAGE_VERIFY_HASH: The output
* \p attributes will contain a public key type.
* - #PSA_KEY_USAGE_VERIFY_MESSAGE: The output
* \p attributes will contain a public key type.
* \param[out] attributes
* On success, valid attributes to import the key into PSA.
* - The lifetime and key identifier are unchanged. If the
* attribute structure was initialized or reset before
* calling this function, this will result in a volatile
* key. Call psa_set_key_identifier() before or after this
* function if you wish to create a persistent key. Call
* psa_set_key_lifetime() before or after this function if
* you wish to import the key in a secure element.
* - The key type and bit-size are determined by the contents
* of the PK context. If the PK context contains a key
* pair, the key type can be either a key pair type or
* the corresponding public key type, depending on
* \p usage. If the PK context contains a public key,
* the key type is a public key type.
* - The key's policy is determined by the key type and
* the \p usage parameter. The usage always allows
* \p usage, exporting and copying the key, and
* possibly other permissions as documented for the
* \p usage parameter.
* The permitted algorithm policy is determined as follows
* based on the #mbedtls_pk_type_t type of \p pk,
* the chosen \p usage and other factors:
* - #MBEDTLS_PK_RSA whose underlying
* #mbedtls_rsa_context has the padding mode
* #MBEDTLS_RSA_PKCS_V15:
* #PSA_ALG_RSA_PKCS1V15_SIGN(#PSA_ALG_ANY_HASH)
* if \p usage is SIGN/VERIFY, and
* #PSA_ALG_RSA_PKCS1V15_CRYPT
* if \p usage is ENCRYPT/DECRYPT.
* - #MBEDTLS_PK_RSA whose underlying
* #mbedtls_rsa_context has the padding mode
* #MBEDTLS_RSA_PKCS_V21 and the digest type
* corresponding to the PSA algorithm \c hash:
* #PSA_ALG_RSA_PSS_ANY_SALT(#PSA_ALG_ANY_HASH)
* if \p usage is SIGN/VERIFY, and
* #PSA_ALG_RSA_OAEP(\c hash)
* if \p usage is ENCRYPT/DECRYPT.
* - #MBEDTLS_PK_RSA_ALT: not supported.
* - #MBEDTLS_PK_ECDSA or #MBEDTLS_PK_ECKEY
* if \p usage is SIGN/VERIFY:
* #PSA_ALG_DETERMINISTIC_ECDSA(#PSA_ALG_ANY_HASH)
* if #MBEDTLS_ECDSA_DETERMINISTIC is enabled,
* otherwise #PSA_ALG_ECDSA(#PSA_ALG_ANY_HASH).
* - #MBEDTLS_PK_ECKEY_DH or #MBEDTLS_PK_ECKEY
* if \p usage is DERIVE:
* #PSA_ALG_ECDH.
* - #MBEDTLS_PK_OPAQUE: same as the primary algorithm
* set for the underlying PSA key, except that
* sign/decrypt flags are removed if the type is
* set to a public key type.
* The underlying key must allow \p usage.
* Note that the enrollment algorithm set with
* psa_set_key_enrollment_algorithm() is not copied.
*
* \return 0 on success.
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if \p pk does not contain
* a key of the type identified in \p attributes.
* Another error code on other failures.
*/
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
psa_key_usage_t usage,
psa_key_attributes_t *attributes);
/**
* \brief Import a key into the PSA key store.
*
* This function is equivalent to calling psa_import_key()
* with the key material from \p pk.
*
* The typical way to use this function is:
* -# Call mbedtls_pk_get_psa_attributes() to obtain
* attributes for the given key.
* -# If desired, modify the attributes, for example:
* - To create a persistent key, call
* psa_set_key_identifier() and optionally
* psa_set_key_lifetime().
* - To import only the public part of a key pair:
*
* psa_set_key_type(&attributes,
* PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
* psa_get_key_type(&attributes)));
* - Restrict the key usage if desired.
* -# Call mbedtls_pk_import_into_psa().
*
* \note This function does not support RSA-alt contexts
* (set up with mbedtls_pk_setup_rsa_alt()).
*
* \param[in] pk The PK context to use. It must have been set up.
* It can either contain a key pair or just a public key.
* \param[in] attributes
* The attributes to use for the new key. They must be
* compatible with \p pk. In particular, the key type
* must match the content of \p pk.
* If \p pk contains a key pair, the key type in
* attributes can be either the key pair type or the
* corresponding public key type (to import only the
* public part).
* \param[out] key_id
* On success, the identifier of the newly created key.
* On error, this is #MBEDTLS_SVC_KEY_ID_INIT.
*
* \return 0 on success.
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if \p pk does not contain
* a key of the type identified in \p attributes.
* Another error code on other failures.
*/
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key_id);
#endif /* MBEDTLS_PSA_CRYPTO_C */
/**
* \brief Verify signature (including padding if relevant).
*
@ -502,14 +659,17 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
* \param sig Signature to verify
* \param sig_len Signature length
*
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
* either PKCS#1 v1.5 or PSS (accepting any salt length),
* depending on the padding mode in the underlying RSA context.
* For a pk object constructed by parsing, this is PKCS#1 v1.5
* by default. Use mbedtls_pk_verify_ext() to explicitly select
* a different algorithm.
*
* \return 0 on success (signature is valid),
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* signature in \p sig but its length is less than \p sig_len,
* or a specific error code.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... )
* to verify RSASSA_PSS signatures.
*/
int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
@ -596,11 +756,15 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
* \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
* \return 0 on success, or a specific error code.
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
* either PKCS#1 v1.5 or PSS (using the largest possible salt
* length up to the hash length), depending on the padding mode
* in the underlying RSA context. For a pk object constructed
* by parsing, this is PKCS#1 v1.5 by default. Use
* mbedtls_pk_verify_ext() to explicitly select a different
* algorithm.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* There is no interface in the PK module to make RSASSA-PSS
* signatures yet.
* \return 0 on success, or a specific error code.
*
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
@ -696,7 +860,10 @@ int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
* \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
* either PKCS#1 v1.5 or OAEP, depending on the padding mode in
* the underlying RSA context. For a pk object constructed by
* parsing, this is PKCS#1 v1.5 by default.
*
* \return 0 on success, or a specific error code.
*/
@ -717,9 +884,12 @@ int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
* \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
* \note \p f_rng is used for padding generation.
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
* either PKCS#1 v1.5 or OAEP, depending on the padding mode in
* the underlying RSA context. For a pk object constructed by
* parsing, this is PKCS#1 v1.5 by default.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* \note \p f_rng is used for padding generation.
*
* \return 0 on success, or a specific error code.
*/
@ -1042,41 +1212,6 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *key);
#endif /* MBEDTLS_PK_WRITE_C */
/*
* Internal module functions. You probably do not want to use these unless you
* know you do.
*/
#if defined(MBEDTLS_FS_IO)
int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n);
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Turn an EC or RSA key into an opaque one.
*
* \warning This is a temporary utility function for tests. It might
* change or be removed at any time without notice.
*
* \param pk Input: the EC or RSA key to import to a PSA key.
* Output: a PK context wrapping that PSA key.
* \param key Output: a PSA key identifier.
* It's the caller's responsibility to call
* psa_destroy_key() on that key identifier after calling
* mbedtls_pk_free() on the PK context.
* \param alg The algorithm to allow for use with that key.
* \param usage The usage to allow for use with that key.
* \param alg2 The secondary algorithm to allow for use with that key.
*
* \return \c 0 if successful.
* \return An Mbed TLS error code otherwise.
*/
int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
mbedtls_svc_key_id_t *key,
psa_algorithm_t alg,
psa_key_usage_t usage,
psa_algorithm_t alg2);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#ifdef __cplusplus
}
#endif

View File

@ -41,7 +41,6 @@
#include "mbedtls/build_info.h"
#include "mbedtls/asn1.h"
#include "mbedtls/x509.h"
#include "mbedtls/x509_crt.h"
/**

View File

@ -23,10 +23,6 @@
extern "C" {
#endif
/* Internal macros meant to be called only from within the library. */
#define MBEDTLS_INTERNAL_VALIDATE_RET(cond, ret) do { } while (0)
#define MBEDTLS_INTERNAL_VALIDATE(cond) do { } while (0)
/* Internal helper macros for deprecating API constants. */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)

View File

@ -16,44 +16,29 @@
#include "psa/crypto.h"
#if defined(MBEDTLS_PSA_CRYPTO_C)
/* ASN1 defines used in the ECDSA conversion functions.
* Note: intentionally not adding MBEDTLS_ASN1_[PARSE|WRITE]_C guards here
* otherwise error codes would be unknown in test_suite_psa_crypto_util.data.*/
#include <mbedtls/asn1write.h>
/* 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.
* See that file for implementation documentation. */
/* The type of a `f_rng` random generator function that many library functions
* take.
*
* This type name is not part of the Mbed TLS stable API. It may be renamed
* or moved without warning.
*/
typedef int mbedtls_f_rng_t(void *p_rng, unsigned char *output, size_t output_size);
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
/** The random generator function for the PSA subsystem.
*
* This function is suitable as the `f_rng` random generator function
* parameter of many `mbedtls_xxx` functions. Use #MBEDTLS_PSA_RANDOM_STATE
* to obtain the \p p_rng parameter.
* parameter of many `mbedtls_xxx` functions.
*
* The implementation of this function depends on the configuration of the
* library.
*
* \note Depending on the configuration, this may be a function or
* a pointer to a function.
*
* \note This function may only be used if the PSA crypto subsystem is active.
* This means that you must call psa_crypto_init() before any call to
* this function, and you must not call this function after calling
* mbedtls_psa_crypto_free().
*
* \param p_rng The random generator context. This must be
* #MBEDTLS_PSA_RANDOM_STATE. No other state is
* supported.
* \param p_rng This parameter is only kept for backward compatibility
* reasons with legacy `f_rng` functions and it's ignored.
* Set to #MBEDTLS_PSA_RANDOM_STATE or NULL.
* \param output The buffer to fill. It must have room for
* \c output_size bytes.
* \param output_size The number of bytes to write to \p output.
@ -75,32 +60,11 @@ int mbedtls_psa_get_random(void *p_rng,
/** The random generator state for the PSA subsystem.
*
* This macro expands to an expression which is suitable as the `p_rng`
* random generator state parameter of many `mbedtls_xxx` functions.
* It must be used in combination with the random generator function
* mbedtls_psa_get_random().
*
* The implementation of this macro depends on the configuration of the
* library. Do not make any assumption on its nature.
* This macro always expands to NULL because the `p_rng` parameter is unused
* in mbedtls_psa_get_random(), but it's kept for interface's backward
* compatibility.
*/
#define MBEDTLS_PSA_RANDOM_STATE NULL
#else /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
#if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_ctr_drbg_random;
#elif defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_hmac_drbg_random;
#endif
extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
#define MBEDTLS_PSA_RANDOM_STATE NULL
/** \defgroup psa_tls_helpers TLS helper functions
* @{
@ -175,8 +139,50 @@ static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa
{
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
}
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/** Convert an ECDSA signature from raw format to DER ASN.1 format.
*
* \param bits Size of each coordinate in bits.
* \param raw Buffer that contains the signature in raw format.
* \param raw_len Length of \p raw in bytes. This must be
* PSA_BITS_TO_BYTES(bits) bytes.
* \param[out] der Buffer that will be filled with the converted DER
* output. It can overlap with raw buffer.
* \param der_size Size of \p der in bytes. It is enough if \p der_size
* is at least the size of the actual output. (The size
* of the output can vary depending on the presence of
* leading zeros in the data.) You can use
* #MBEDTLS_ECDSA_MAX_SIG_LEN(\p bits) to determine a
* size that is large enough for all signatures for a
* given value of \p bits.
* \param[out] der_len On success it contains the amount of valid data
* (in bytes) written to \p der. It's undefined
* in case of failure.
*/
int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
unsigned char *der, size_t der_size, size_t *der_len);
/** Convert an ECDSA signature from DER ASN.1 format to raw format.
*
* \param bits Size of each coordinate in bits.
* \param der Buffer that contains the signature in DER format.
* \param der_len Size of \p der in bytes.
* \param[out] raw Buffer that will be filled with the converted raw
* signature. It can overlap with der buffer.
* \param raw_size Size of \p raw in bytes. Must be at least
* 2 * PSA_BITS_TO_BYTES(bits) bytes.
* \param[out] raw_len On success it is updated with the amount of valid
* data (in bytes) written to \p raw. It's undefined
* in case of failure.
*/
int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
unsigned char *raw, size_t raw_size, size_t *raw_len);
#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
/**@}*/
#endif /* MBEDTLS_PSA_CRYPTO_C */
#endif /* MBEDTLS_PSA_UTIL_H */

View File

@ -426,6 +426,16 @@ int mbedtls_rsa_export_raw(const mbedtls_rsa_context *ctx,
int mbedtls_rsa_export_crt(const mbedtls_rsa_context *ctx,
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP);
/**
* \brief This function retrieves the length of the RSA modulus in bits.
*
* \param ctx The initialized RSA context.
*
* \return The length of the RSA modulus in bits.
*
*/
size_t mbedtls_rsa_get_bitlen(const mbedtls_rsa_context *ctx);
/**
* \brief This function retrieves the length of RSA modulus in Bytes.
*

View File

@ -90,8 +90,18 @@
#define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00
/** Not possible to read early data */
#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80
/**
* Early data has been received as part of an on-going handshake.
* This error code can be returned only on server side if and only if early
* data has been enabled by means of the mbedtls_ssl_conf_early_data() API.
* This error code can then be returned by mbedtls_ssl_handshake(),
* mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write() if
* early data has been received as part of the handshake sequence they
* triggered. To read the early data, call mbedtls_ssl_read_early_data().
*/
#define MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA -0x7C00
/** Not possible to write early data */
#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C00
#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C80
/* Error space gap */
/* Error space gap */
/* Error space gap */
@ -343,6 +353,26 @@
#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN 1000
#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX 60000
/*
* Whether early data record should be discarded or not and how.
*
* The client has indicated early data and the server has rejected them.
* The server has then to skip past early data by either:
* - attempting to deprotect received records using the handshake traffic
* key, discarding records which fail deprotection (up to the configured
* max_early_data_size). Once a record is deprotected successfully,
* it is treated as the start of the client's second flight and the
* server proceeds as with an ordinary 1-RTT handshake.
* - skipping all records with an external content type of
* "application_data" (indicating that they are encrypted), up to the
* configured max_early_data_size. This is the expected behavior if the
* server has sent an HelloRetryRequest message. The server ignores
* application data message before 2nd ClientHello.
*/
#define MBEDTLS_SSL_EARLY_DATA_NO_DISCARD 0
#define MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD 1
#define MBEDTLS_SSL_EARLY_DATA_DISCARD 2
/**
* \name SECTION: Module settings
*
@ -704,6 +734,51 @@ typedef enum {
}
mbedtls_ssl_states;
/*
* Early data status, client side only.
*/
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
typedef enum {
/*
* The client has not sent the first ClientHello yet, it is unknown if the
* client will send an early data indication extension or not.
*/
MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN,
/*
* See documentation of mbedtls_ssl_get_early_data_status().
*/
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT,
MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED,
/*
* The client has sent an early data indication extension in its first
* ClientHello, it has not received the response (ServerHello or
* HelloRetryRequest) from the server yet. The transform to protect early data
* is not set and early data cannot be sent yet.
*/
MBEDTLS_SSL_EARLY_DATA_STATUS_SENT,
/*
* The client has sent an early data indication extension in its first
* ClientHello, it has not received the response (ServerHello or
* HelloRetryRequest) from the server yet. The transform to protect early data
* has been set and early data can be written now.
*/
MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE,
/*
* The client has sent an early data indication extension in its first
* ClientHello, the server has accepted them and the client has received the
* server Finished message. It cannot send early data to the server anymore.
*/
MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED,
} mbedtls_ssl_early_data_status;
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
/**
* \brief Callback type: send data on the network.
*
@ -1194,6 +1269,7 @@ struct mbedtls_ssl_session {
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
unsigned char MBEDTLS_PRIVATE(exported);
uint8_t MBEDTLS_PRIVATE(endpoint); /*!< 0: client, 1: server */
/** TLS version negotiated in the session. Used if and when renegotiating
* or resuming a session instead of the configured minor TLS version.
@ -1227,26 +1303,41 @@ struct mbedtls_ssl_session {
uint32_t MBEDTLS_PRIVATE(ticket_lifetime); /*!< ticket lifetime hint */
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) && \
defined(MBEDTLS_HAVE_TIME)
/*! When a ticket is created by a TLS server as part of an established TLS
* session, the ticket creation time may need to be saved for the ticket
* module to be able to check the ticket age when the ticket is used.
* That's the purpose of this field.
* Before creating a new ticket, an Mbed TLS server set this field with
* its current time in milliseconds. This time may then be saved in the
* session ticket data by the session ticket writing function and
* recovered by the ticket parsing function later when the ticket is used.
* The ticket module may then use this time to compute the ticket age and
* determine if it has expired or not.
* The Mbed TLS implementations of the session ticket writing and parsing
* functions save and retrieve the ticket creation time as part of the
* session ticket data. The session ticket parsing function relies on
* the mbedtls_ssl_session_get_ticket_creation_time() API to get the
* ticket creation time from the session ticket data.
*/
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time);
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
uint8_t MBEDTLS_PRIVATE(endpoint); /*!< 0: client, 1: server */
uint8_t MBEDTLS_PRIVATE(ticket_flags); /*!< Ticket flags */
uint32_t MBEDTLS_PRIVATE(ticket_age_add); /*!< Randomly generated value used to obscure the age of the ticket */
uint8_t MBEDTLS_PRIVATE(resumption_key_len); /*!< resumption_key length */
uint32_t MBEDTLS_PRIVATE(ticket_age_add); /*!< Randomly generated value used to obscure the age of the ticket */
uint8_t MBEDTLS_PRIVATE(ticket_flags); /*!< Ticket flags */
uint8_t MBEDTLS_PRIVATE(resumption_key_len); /*!< resumption_key length */
unsigned char MBEDTLS_PRIVATE(resumption_key)[MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN];
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && defined(MBEDTLS_SSL_CLI_C)
char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_HAVE_TIME)
#if defined(MBEDTLS_SSL_CLI_C)
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time); /*!< time when ticket was received. */
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C)
/*! Time in milliseconds when the last ticket was received. */
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time);
#endif
#if defined(MBEDTLS_SSL_SRV_C)
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time); /*!< time when ticket was created. */
#endif
#endif /* MBEDTLS_HAVE_TIME */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_EARLY_DATA)
@ -1627,23 +1718,31 @@ struct mbedtls_ssl_context {
#endif /* MBEDTLS_SSL_RENEGOTIATION */
/**
* Maximum TLS version to be negotiated, then negotiated TLS version.
* Maximum TLS version to be negotiated, then negotiated TLS version.
*
* It is initialized as the configured maximum TLS version to be
* negotiated by mbedtls_ssl_setup().
* It is initialized as the configured maximum TLS version to be
* negotiated by mbedtls_ssl_setup().
*
* When renegotiating or resuming a session, it is overwritten in the
* ClientHello writing preparation stage with the previously negotiated
* TLS version.
* When renegotiating or resuming a session, it is overwritten in the
* ClientHello writing preparation stage with the previously negotiated
* TLS version.
*
* On client side, it is updated to the TLS version selected by the server
* for the handshake when the ServerHello is received.
* On client side, it is updated to the TLS version selected by the server
* for the handshake when the ServerHello is received.
*
* On server side, it is updated to the TLS version the server selects for
* the handshake when the ClientHello is received.
* On server side, it is updated to the TLS version the server selects for
* the handshake when the ClientHello is received.
*/
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
/**
* Status of the negotiation of the use of early data. Reset to
* MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN when the context is reset.
*/
mbedtls_ssl_early_data_status MBEDTLS_PRIVATE(early_data_status);
#endif
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@ -1760,6 +1859,19 @@ struct mbedtls_ssl_context {
* within a single datagram. */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_EARLY_DATA)
#if defined(MBEDTLS_SSL_SRV_C)
/*
* One of:
* MBEDTLS_SSL_EARLY_DATA_NO_DISCARD
* MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD
* MBEDTLS_SSL_EARLY_DATA_DISCARD
*/
uint8_t MBEDTLS_PRIVATE(discard_early_data_record);
#endif
uint32_t MBEDTLS_PRIVATE(total_early_data_size); /*!< Number of received/written early data bytes */
#endif /* MBEDTLS_SSL_EARLY_DATA */
/*
* Record layer (outgoing data)
*/
@ -1841,10 +1953,6 @@ struct mbedtls_ssl_context {
* and #MBEDTLS_SSL_CID_DISABLED. */
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_EARLY_DATA)
int MBEDTLS_PRIVATE(early_data_status);
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
/** Callback to export key block and master secret */
mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys);
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */
@ -1993,7 +2101,7 @@ void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport);
*/
void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode);
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_EARLY_DATA)
#if defined(MBEDTLS_SSL_EARLY_DATA)
/**
* \brief Set the early data mode
* Default: disabled on server and client
@ -2001,14 +2109,24 @@ void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode);
* \param conf The SSL configuration to use.
* \param early_data_enabled can be:
*
* MBEDTLS_SSL_EARLY_DATA_DISABLED: early data functionality is disabled
* This is the default on client and server.
* MBEDTLS_SSL_EARLY_DATA_DISABLED:
* Early data functionality is disabled. This is the default on client and
* server.
*
* MBEDTLS_SSL_EARLY_DATA_ENABLED: early data functionality is enabled and
* may be negotiated in the handshake. Application using
* early data functionality needs to be aware of the
* lack of replay protection of the early data application
* payloads.
* MBEDTLS_SSL_EARLY_DATA_ENABLED:
* Early data functionality is enabled and may be negotiated in the handshake.
* Application using early data functionality needs to be aware that the
* security properties for early data (also refered to as 0-RTT data) are
* weaker than those for other kinds of TLS data. See the documentation of
* mbedtls_ssl_write_early_data() and mbedtls_ssl_read_early_data() for more
* information.
* When early data functionality is enabled on server and only in that case,
* the call to one of the APIs that trigger or resume an handshake sequence,
* namely mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
* mbedtls_ssl_read() or mbedtls_ssl_write() may return with the error code
* MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have
* been received. To read the early data, call mbedtls_ssl_read_early_data()
* before calling the original function again.
*
* \warning This interface is experimental and may change without notice.
*
@ -2048,7 +2166,7 @@ void mbedtls_ssl_conf_max_early_data_size(
mbedtls_ssl_config *conf, uint32_t max_early_data_size);
#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
@ -2572,6 +2690,34 @@ void mbedtls_ssl_conf_session_tickets_cb(mbedtls_ssl_config *conf,
mbedtls_ssl_ticket_write_t *f_ticket_write,
mbedtls_ssl_ticket_parse_t *f_ticket_parse,
void *p_ticket);
#if defined(MBEDTLS_HAVE_TIME)
/**
* \brief Get the creation time of a session ticket.
*
* \note See the documentation of \c ticket_creation_time for information about
* the intended usage of this function.
*
* \param session SSL session
* \param ticket_creation_time On exit, holds the ticket creation time in
* milliseconds.
*
* \return 0 on success,
* MBEDTLS_ERR_SSL_BAD_INPUT_DATA if an input is not valid.
*/
static inline int mbedtls_ssl_session_get_ticket_creation_time(
mbedtls_ssl_session *session, mbedtls_ms_time_t *ticket_creation_time)
{
if (session == NULL || ticket_creation_time == NULL ||
session->MBEDTLS_PRIVATE(endpoint) != MBEDTLS_SSL_IS_SERVER) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
*ticket_creation_time = session->MBEDTLS_PRIVATE(ticket_creation_time);
return 0;
}
#endif /* MBEDTLS_HAVE_TIME */
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
/**
@ -4679,7 +4825,7 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert(const mbedtls_ssl_context *ssl
* \param ssl The SSL context representing the connection for which to
* to export a session structure for later resumption.
* \param session The target structure in which to store the exported session.
* This must have been initialized with mbedtls_ssl_init_session()
* This must have been initialized with mbedtls_ssl_session_init()
* but otherwise be unused.
*
* \note This function can handle a variety of mechanisms for session
@ -4733,6 +4879,13 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
* and the client did not demonstrate reachability yet - in
* this case you must stop using the context (see below).
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
@ -4741,7 +4894,8 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
@ -4810,8 +4964,9 @@ static inline int mbedtls_ssl_is_handshake_over(mbedtls_ssl_context *ssl)
*
* \warning If this function returns something other than \c 0,
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, you must stop using
* the SSL context for reading or writing, and either free it
* or call \c mbedtls_ssl_session_reset() on it before
* re-using it for a new connection; the current connection
@ -4879,6 +5034,13 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
* \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
* side of a DTLS connection and the client is initiating a
* new connection using the same source port. See below.
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
@ -4887,8 +5049,9 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
@ -4953,6 +5116,13 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
* operation is in progress (see mbedtls_ecp_set_max_ops()) -
* in this case you must call this function again to complete
* the handshake when you're done attending other tasks.
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
* defined in RFC 8446 (TLS 1.3 specification), has been
* received as part of the handshake. This is server specific
* and may occur only if the early data feature has been
* enabled on server (see mbedtls_ssl_conf_early_data()
* documentation). You must call mbedtls_ssl_read_early_data()
* to read the early data before resuming the handshake.
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
@ -4960,8 +5130,9 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
* a non-negative value,
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
@ -5023,54 +5194,48 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
#if defined(MBEDTLS_SSL_EARLY_DATA)
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 0
#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 1
#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 2
#if defined(MBEDTLS_SSL_SRV_C)
/**
* \brief Read at most 'len' application data bytes while performing
* the handshake (early data).
* \brief Read at most 'len' bytes of early data
*
* \note This function behaves mainly as mbedtls_ssl_read(). The
* specification of mbedtls_ssl_read() relevant to TLS 1.3
* (thus not the parts specific to (D)TLS 1.2) applies to this
* function and the present documentation is restricted to the
* differences with mbedtls_ssl_read().
* \note This API is server specific.
*
* \param ssl SSL context
* \warning Early data is defined in the TLS 1.3 specification, RFC 8446.
* IMPORTANT NOTE from section 2.3 of the specification:
*
* The security properties for 0-RTT data are weaker than
* those for other kinds of TLS data. Specifically:
* - This data is not forward secret, as it is encrypted
* solely under keys derived using the offered PSK.
* - There are no guarantees of non-replay between connections.
* Protection against replay for ordinary TLS 1.3 1-RTT data
* is provided via the server's Random value, but 0-RTT data
* does not depend on the ServerHello and therefore has
* weaker guarantees. This is especially relevant if the
* data is authenticated either with TLS client
* authentication or inside the application protocol. The
* same warnings apply to any use of the
* early_exporter_master_secret.
*
* \note This function is used in conjunction with
* mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(),
* mbedtls_ssl_read() and mbedtls_ssl_write() to read early
* data when these functions return
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA.
*
* \param ssl SSL context, it must have been initialized and set up.
* \param buf buffer that will hold the data
* \param len maximum number of bytes to read
*
* \return One additional specific return value:
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA.
*
* #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA is returned when it
* is not possible to read early data for the SSL context
* \p ssl.
*
* It may have been possible and it is not possible
* anymore because the server received the End of Early Data
* message or the maximum number of allowed early data for the
* PSK in use has been reached.
*
* It may never have been possible and will never be possible
* for the SSL context \p ssl because the use of early data
* is disabled for that context or more generally the context
* is not suitably configured to enable early data or the
* client does not use early data or the first call to the
* function was done while the handshake was already too
* advanced to gather and accept early data.
*
* It is not possible to read early data for the SSL context
* \p ssl but this does not preclude for using it with
* mbedtls_ssl_write(), mbedtls_ssl_read() or
* mbedtls_ssl_handshake().
*
* \note When a server wants to retrieve early data, it is expected
* that this function starts the handshake for the SSL context
* \p ssl. But this is not mandatory.
*
* \return The (positive) number of bytes read if successful.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
* \return #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA if it is not
* possible to read early data for the SSL context \p ssl. Note
* that this function is intended to be called for an SSL
* context \p ssl only after a call to mbedtls_ssl_handshake(),
* mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or
* mbedtls_ssl_write() for \p ssl that has returned
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA.
*/
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len);
@ -5081,17 +5246,43 @@ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
* \brief Try to write exactly 'len' application data bytes while
* performing the handshake (early data).
*
* \warning Early data is defined in the TLS 1.3 specification, RFC 8446.
* IMPORTANT NOTE from section 2.3 of the specification:
*
* The security properties for 0-RTT data are weaker than
* those for other kinds of TLS data. Specifically:
* - This data is not forward secret, as it is encrypted
* solely under keys derived using the offered PSK.
* - There are no guarantees of non-replay between connections.
* Protection against replay for ordinary TLS 1.3 1-RTT data
* is provided via the server's Random value, but 0-RTT data
* does not depend on the ServerHello and therefore has
* weaker guarantees. This is especially relevant if the
* data is authenticated either with TLS client
* authentication or inside the application protocol. The
* same warnings apply to any use of the
* early_exporter_master_secret.
*
* \note This function behaves mainly as mbedtls_ssl_write(). The
* specification of mbedtls_ssl_write() relevant to TLS 1.3
* (thus not the parts specific to (D)TLS1.2) applies to this
* function and the present documentation is restricted to the
* differences with mbedtls_ssl_write().
* function and the present documentation is mainly restricted
* to the differences with mbedtls_ssl_write(). One noticeable
* difference though is that mbedtls_ssl_write() aims to
* complete the handshake before to write application data
* while mbedtls_ssl_write_early() aims to drive the handshake
* just past the point where it is not possible to send early
* data anymore.
*
* \param ssl SSL context
* \param buf buffer holding the data
* \param len how many bytes must be written
*
* \return One additional specific return value:
* \return The (non-negative) number of bytes actually written if
* successful (may be less than \p len).
*
* \return One additional specific error code compared to
* mbedtls_ssl_write():
* #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA.
*
* #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA is returned when it
@ -5112,9 +5303,11 @@ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
* already completed.
*
* It is not possible to write early data for the SSL context
* \p ssl but this does not preclude for using it with
* \p ssl and any subsequent call to this API will return this
* error code. But this does not preclude for using it with
* mbedtls_ssl_write(), mbedtls_ssl_read() or
* mbedtls_ssl_handshake().
* mbedtls_ssl_handshake() and the handshake can be
* completed by calling one of these APIs.
*
* \note This function may write early data only if the SSL context
* has been configured for the handshake with a PSK for which

View File

@ -463,18 +463,6 @@ const int *mbedtls_ssl_list_ciphersuites(void);
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string(const char *ciphersuite_name);
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id(int ciphersuite_id);
#if defined(MBEDTLS_PK_C)
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info);
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info);
psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info);
#endif
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info);
#endif
int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info);
int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info);
static inline const char *mbedtls_ssl_ciphersuite_get_name(const mbedtls_ssl_ciphersuite_t *info)
{
return info->MBEDTLS_PRIVATE(name);
@ -482,133 +470,6 @@ static inline const char *mbedtls_ssl_ciphersuite_get_name(const mbedtls_ssl_cip
size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersuite_t *info);
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
static inline int mbedtls_ssl_ciphersuite_has_pfs(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
static inline int mbedtls_ssl_ciphersuite_no_pfs(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_PSK:
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_ecdh(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
static inline int mbedtls_ssl_ciphersuite_cert_req_allowed(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return 1;
default:
return 0;
}
}
static inline int mbedtls_ssl_ciphersuite_uses_srv_cert(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return 1;
default:
return 0;
}
}
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_dhe(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_ecdhe(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_server_signature(
const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
#ifdef __cplusplus
}
#endif

View File

@ -50,6 +50,10 @@ typedef struct mbedtls_ssl_ticket_key {
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t MBEDTLS_PRIVATE(generation_time); /*!< key generation timestamp (seconds) */
#endif
/*! Lifetime of the key in seconds. This is also the lifetime of the
* tickets created under that key.
*/
uint32_t MBEDTLS_PRIVATE(lifetime);
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_cipher_context_t MBEDTLS_PRIVATE(ctx); /*!< context for auth enc/decryption */
#else

View File

@ -307,6 +307,7 @@ typedef struct mbedtls_x509_san_list {
mbedtls_x509_san_list;
/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
/** \} addtogroup x509_module */
/**
* \brief Store the certificate DN in printable form into buf;
@ -321,6 +322,23 @@ mbedtls_x509_san_list;
*/
int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn);
/**
* \brief Convert the certificate DN string \p name into
* a linked list of mbedtls_x509_name (equivalent to
* mbedtls_asn1_named_data).
*
* \note This function allocates a linked list, and places the head
* pointer in \p head. This list must later be freed by a
* call to mbedtls_asn1_free_named_data_list().
*
* \param[out] head Address in which to store the pointer to the head of the
* allocated list of mbedtls_x509_name
* \param[in] name The string representation of a DN to convert
*
* \return 0 on success, or a negative error code.
*/
int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name);
/**
* \brief Return the next relative DN in an X509 name.
*
@ -448,75 +466,6 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
*/
void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san);
/** \} addtogroup x509_module */
/*
* Internal module functions. You probably do not want to use these unless you
* know you do.
*/
int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
mbedtls_x509_name *cur);
int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *alg);
int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *alg, mbedtls_x509_buf *params);
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params,
mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
int *salt_len);
#endif
int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig);
int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
void **sig_opts);
int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end,
mbedtls_x509_time *t);
int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *serial);
int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *ext, int tag);
#if !defined(MBEDTLS_X509_REMOVE_INFO)
int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
const void *sig_opts);
#endif
int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name);
int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name);
int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
int critical, const unsigned char *val,
size_t val_len);
int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *first);
int mbedtls_x509_write_names(unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *first);
int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
unsigned char *sig, size_t size,
mbedtls_pk_type_t pk_alg);
int mbedtls_x509_get_ns_cert_type(unsigned char **p,
const unsigned char *end,
unsigned char *ns_cert_type);
int mbedtls_x509_get_key_usage(unsigned char **p,
const unsigned char *end,
unsigned int *key_usage);
int mbedtls_x509_get_subject_alt_name(unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *subject_alt_name);
int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *subject_alt_name);
int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
const mbedtls_x509_sequence
*subject_alt_name,
const char *prefix);
int mbedtls_x509_info_cert_type(char **buf, size_t *size,
unsigned char ns_cert_type);
int mbedtls_x509_info_key_usage(char **buf, size_t *size,
unsigned int key_usage);
int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions,
const mbedtls_x509_san_list *san_list);
/**
* \brief This function parses a CN string as an IP address.
*
@ -547,4 +496,4 @@ size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst);
}
#endif
#endif /* x509.h */
#endif /* MBEDTLS_X509_H */

View File

@ -916,6 +916,18 @@ static inline int mbedtls_x509_crt_has_ext_type(const mbedtls_x509_crt *ctx,
return ctx->MBEDTLS_PRIVATE(ext_types) & ext_type;
}
/**
* \brief Access the ca_istrue field
*
* \param[in] crt Certificate to be queried, must not be \c NULL
*
* \return \c 1 if this a CA certificate \c 0 otherwise.
* \return MBEDTLS_ERR_X509_INVALID_EXTENSIONS if the certificate does not contain
* the Optional Basic Constraint extension.
*
*/
int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt);
/** \} name Structures and functions for parsing and writing X.509 certificates */
#if defined(MBEDTLS_X509_CRT_WRITE_C)

View File

@ -119,8 +119,9 @@ static psa_key_attributes_t psa_key_attributes_init(void);
* value in the structure.
* The persistent key will be written to storage when the attribute
* structure is passed to a key creation function such as
* psa_import_key(), psa_generate_key(),
* psa_key_derivation_output_key() or psa_copy_key().
* psa_import_key(), psa_generate_key(), psa_generate_key_ext(),
* psa_key_derivation_output_key(), psa_key_derivation_output_key_ext()
* or psa_copy_key().
*
* This function may be declared as `static` (i.e. without external
* linkage). This function may be provided as a function-like macro,
@ -163,8 +164,9 @@ static void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes,
* value in the structure.
* The persistent key will be written to storage when the attribute
* structure is passed to a key creation function such as
* psa_import_key(), psa_generate_key(),
* psa_key_derivation_output_key() or psa_copy_key().
* psa_import_key(), psa_generate_key(), psa_generate_key_ext(),
* psa_key_derivation_output_key(), psa_key_derivation_output_key_ext()
* or psa_copy_key().
*
* This function may be declared as `static` (i.e. without external
* linkage). This function may be provided as a function-like macro,
@ -3226,7 +3228,8 @@ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void);
* psa_key_derivation_set_capacity(). You may do this before, in the middle
* of or after providing inputs. For some algorithms, this step is mandatory
* because the output depends on the maximum capacity.
* -# To derive a key, call psa_key_derivation_output_key().
* -# To derive a key, call psa_key_derivation_output_key() or
* psa_key_derivation_output_key_ext().
* To derive a byte string for a different purpose, call
* psa_key_derivation_output_bytes().
* Successive calls to these functions use successive output bytes
@ -3449,7 +3452,8 @@ psa_status_t psa_key_derivation_input_integer(
* \note Once all inputs steps are completed, the operations will allow:
* - psa_key_derivation_output_bytes() if each input was either a direct input
* or a key with #PSA_KEY_USAGE_DERIVE set;
* - psa_key_derivation_output_key() if the input for step
* - psa_key_derivation_output_key() or psa_key_derivation_output_key_ext()
* if the input for step
* #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD
* was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was
* either a direct input or a key with #PSA_KEY_USAGE_DERIVE set;
@ -3697,6 +3701,11 @@ psa_status_t psa_key_derivation_output_bytes(
* Future versions of this specification may include additional restrictions
* on the derived key based on the attributes and strength of the secret key.
*
* \note This function is equivalent to calling
* psa_key_derivation_output_key_ext()
* with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
* and `params_data_length == 0` (i.e. `params->data` is empty).
*
* \param[in] attributes The attributes for the new key.
* If the key type to be created is
* #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
@ -3750,6 +3759,83 @@ psa_status_t psa_key_derivation_output_key(
psa_key_derivation_operation_t *operation,
mbedtls_svc_key_id_t *key);
/** Derive a key from an ongoing key derivation operation with custom
* production parameters.
*
* See the description of psa_key_derivation_out_key() for the operation of
* this function with the default production parameters.
* Mbed TLS currently does not currently support any non-default production
* parameters.
*
* \note This function is experimental and may change in future minor
* versions of Mbed TLS.
*
* \param[in] attributes The attributes for the new key.
* If the key type to be created is
* #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
* the policy must be the same as in the current
* operation.
* \param[in,out] operation The key derivation operation object to read from.
* \param[in] params Customization parameters for the key derivation.
* When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
* with \p params_data_length = 0,
* this function is equivalent to
* psa_key_derivation_output_key().
* Mbed TLS currently only supports the default
* production parameters, i.e.
* #PSA_KEY_PRODUCTION_PARAMETERS_INIT,
* for all key types.
* \param params_data_length
* Length of `params->data` in bytes.
* \param[out] key On success, an identifier for the newly created
* key. For persistent keys, this is the key
* identifier defined in \p attributes.
* \c 0 on failure.
*
* \retval #PSA_SUCCESS
* Success.
* If the key is persistent, the key material and the key's metadata
* have been saved to persistent storage.
* \retval #PSA_ERROR_ALREADY_EXISTS
* This is an attempt to create a persistent key, and there is
* already a persistent key with the given identifier.
* \retval #PSA_ERROR_INSUFFICIENT_DATA
* There was not enough data to create the desired key.
* Note that in this case, no output is written to the output buffer.
* The operation's capacity is set to 0, thus subsequent calls to
* this function will not succeed, even with a smaller output buffer.
* \retval #PSA_ERROR_NOT_SUPPORTED
* The key type or key size is not supported, either by the
* implementation in general or in this particular location.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The provided key attributes are not valid for the operation.
* \retval #PSA_ERROR_NOT_PERMITTED
* The #PSA_KEY_DERIVATION_INPUT_SECRET or
* #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a
* key; or one of the inputs was a key whose policy didn't allow
* #PSA_KEY_USAGE_DERIVE.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (it must be active and completed
* all required input steps), or the library has not been previously
* initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
* results in this error code.
*/
psa_status_t psa_key_derivation_output_key_ext(
const psa_key_attributes_t *attributes,
psa_key_derivation_operation_t *operation,
const psa_key_production_parameters_t *params,
size_t params_data_length,
mbedtls_svc_key_id_t *key);
/** Compare output data from a key derivation operation to an expected value.
*
* This function calculates output bytes from a key derivation algorithm and
@ -3835,7 +3921,8 @@ psa_status_t psa_key_derivation_verify_bytes(
* and the permitted algorithm must match the
* operation. The value of this key was likely
* computed by a previous call to
* psa_key_derivation_output_key().
* psa_key_derivation_output_key() or
* psa_key_derivation_output_key_ext().
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_SIGNATURE
@ -4003,6 +4090,10 @@ psa_status_t psa_generate_random(uint8_t *output,
* between 2^{n-1} and 2^n where n is the bit size specified in the
* attributes.
*
* \note This function is equivalent to calling psa_generate_key_ext()
* with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
* and `params_data_length == 0` (i.e. `params->data` is empty).
*
* \param[in] attributes The attributes for the new key.
* \param[out] key On success, an identifier for the newly created
* key. For persistent keys, this is the key
@ -4035,6 +4126,60 @@ psa_status_t psa_generate_random(uint8_t *output,
psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key);
/**
* \brief Generate a key or key pair using custom production parameters.
*
* See the description of psa_generate_key() for the operation of this
* function with the default production parameters. In addition, this function
* supports the following production customizations, described in more detail
* in the documentation of ::psa_key_production_parameters_t:
*
* - RSA keys: generation with a custom public exponent.
*
* \note This function is experimental and may change in future minor
* versions of Mbed TLS.
*
* \param[in] attributes The attributes for the new key.
* \param[in] params Customization parameters for the key generation.
* When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
* with \p params_data_length = 0,
* this function is equivalent to
* psa_generate_key().
* \param params_data_length
* Length of `params->data` in bytes.
* \param[out] key On success, an identifier for the newly created
* key. For persistent keys, this is the key
* identifier defined in \p attributes.
* \c 0 on failure.
*
* \retval #PSA_SUCCESS
* Success.
* If the key is persistent, the key material and the key's metadata
* have been saved to persistent storage.
* \retval #PSA_ERROR_ALREADY_EXISTS
* This is an attempt to create a persistent key, and there is
* already a persistent key with the given identifier.
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \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
* results in this error code.
*/
psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
const psa_key_production_parameters_t *params,
size_t params_data_length,
mbedtls_svc_key_id_t *key);
/**@}*/
/** \defgroup interruptible_hash Interruptible sign/verify hash

View File

@ -146,6 +146,83 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key,
*/
psa_status_t psa_close_key(psa_key_handle_t handle);
/** \addtogroup attributes
* @{
*/
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/** Custom Diffie-Hellman group.
*
* Mbed TLS does not support custom DH groups.
*
* \deprecated This value is not useful, so this macro will be removed in
* a future version of the library.
*/
#define PSA_DH_FAMILY_CUSTOM \
((psa_dh_family_t) MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(0x7e))
/**
* \brief Set domain parameters for a key.
*
* \deprecated Mbed TLS no longer supports any domain parameters.
* This function only does the equivalent of
* psa_set_key_type() and will be removed in a future version
* of the library.
*
* \param[in,out] attributes Attribute structure where \p type will be set.
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
* \param[in] data Ignored.
* \param data_length Must be 0.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
*/
static inline psa_status_t MBEDTLS_DEPRECATED psa_set_key_domain_parameters(
psa_key_attributes_t *attributes,
psa_key_type_t type, const uint8_t *data, size_t data_length)
{
(void) data;
if (data_length != 0) {
return PSA_ERROR_NOT_SUPPORTED;
}
psa_set_key_type(attributes, type);
return PSA_SUCCESS;
}
/**
* \brief Get domain parameters for a key.
*
* \deprecated Mbed TLS no longer supports any domain parameters.
* This function alwaya has an empty output and will be
* removed in a future version of the library.
* \param[in] attributes Ignored.
* \param[out] data Ignored.
* \param data_size Ignored.
* \param[out] data_length Set to 0.
*
* \retval #PSA_SUCCESS \emptydescription
*/
static inline psa_status_t MBEDTLS_DEPRECATED psa_get_key_domain_parameters(
const psa_key_attributes_t *attributes,
uint8_t *data, size_t data_size, size_t *data_length)
{
(void) attributes;
(void) data;
(void) data_size;
*data_length = 0;
return PSA_SUCCESS;
}
/** Safe output buffer size for psa_get_key_domain_parameters().
*
*/
#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \
MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(1u)
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**@}*/
#ifdef __cplusplus
}
#endif

View File

@ -109,6 +109,12 @@
#define PSA_WANT_ECC_SECP_R1_384 1
#define PSA_WANT_ECC_SECP_R1_521 1
#define PSA_WANT_DH_RFC7919_2048 1
#define PSA_WANT_DH_RFC7919_3072 1
#define PSA_WANT_DH_RFC7919_4096 1
#define PSA_WANT_DH_RFC7919_6144 1
#define PSA_WANT_DH_RFC7919_8192 1
#define PSA_WANT_KEY_TYPE_DERIVE 1
#define PSA_WANT_KEY_TYPE_PASSWORD 1
#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1

View File

@ -59,7 +59,7 @@ static inline void psa_set_key_enrollment_algorithm(
psa_key_attributes_t *attributes,
psa_algorithm_t alg2)
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2;
attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2;
}
/** Retrieve the enrollment algorithm policy from key attributes.
@ -71,7 +71,7 @@ static inline void psa_set_key_enrollment_algorithm(
static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
const psa_key_attributes_t *attributes)
{
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2);
return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2);
}
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@ -129,7 +129,7 @@ static inline void psa_set_key_slot_number(
psa_key_attributes_t *attributes,
psa_key_slot_number_t slot_number)
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
attributes->MBEDTLS_PRIVATE(has_slot_number) = 1;
attributes->MBEDTLS_PRIVATE(slot_number) = slot_number;
}
@ -142,8 +142,7 @@ static inline void psa_set_key_slot_number(
static inline void psa_clear_key_slot_number(
psa_key_attributes_t *attributes)
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) &=
~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
attributes->MBEDTLS_PRIVATE(has_slot_number) = 0;
}
/** Register a key that is already present in a secure element.
@ -198,6 +197,8 @@ psa_status_t mbedtls_psa_register_se_key(
*
* This function clears all data associated with the PSA layer,
* including the whole key store.
* This function is not thread safe, it wipes every key slot regardless of
* state and reader count. It should only be called when no slot is in use.
*
* This is an Mbed TLS extension.
*/
@ -407,140 +408,11 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
* @{
*/
/** Custom Diffie-Hellman group.
*
* For keys of type #PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_FAMILY_CUSTOM) or
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_FAMILY_CUSTOM), the group data comes
* from domain parameters set by psa_set_key_domain_parameters().
*/
#define PSA_DH_FAMILY_CUSTOM ((psa_dh_family_t) 0x7e)
/** PAKE operation stages. */
#define PSA_PAKE_OPERATION_STAGE_SETUP 0
#define PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS 1
#define PSA_PAKE_OPERATION_STAGE_COMPUTATION 2
/**
* \brief Set domain parameters for a key.
*
* Some key types require additional domain parameters in addition to
* the key type identifier and the key size. Use this function instead
* of psa_set_key_type() when you need to specify domain parameters.
*
* The format for the required domain parameters varies based on the key type.
* Mbed TLS supports the following key type with domain parameters:
*
* - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEY_PAIR),
* the domain parameter data consists of the public exponent,
* represented as a big-endian integer with no leading zeros.
* This information is used when generating an RSA key pair.
* When importing a key, the public exponent is read from the imported
* key data and the exponent recorded in the attribute structure is ignored.
* As an exception, the public exponent 65537 is represented by an empty
* byte string.
*
* \note This function may allocate memory or other resources.
* Once you have called this function on an attribute structure,
* you must call psa_reset_key_attributes() to free these resources.
*
* \note This is an experimental extension to the interface. It may change
* in future versions of the library.
*
* \note Due to an implementation limitation, domain parameters are ignored
* for keys that are managed by a driver.
*
* \param[in,out] attributes Attribute structure where the specified domain
* parameters will be stored.
* If this function fails, the content of
* \p attributes is not modified.
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
* \param[in] data Buffer containing the key domain parameters.
* The content of this buffer is interpreted
* according to \p type as described above.
* \param data_length Size of the \p data buffer in bytes.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
*/
#if !defined(PSA_SET_KEY_DOMAIN_PARAMETERS)
#define PSA_SET_KEY_DOMAIN_PARAMETERS
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
psa_key_type_t type,
const uint8_t *data,
size_t data_length);
#endif /* PSA_SET_KEY_DOMAIN_PARAMETERS */
/**
* \brief Get domain parameters for a key.
*
* Get the domain parameters for a key with this function, if any. The format
* of the domain parameters written to \p data is specified in the
* documentation for psa_set_key_domain_parameters().
*
* \note This is an experimental extension to the interface. It may change
* in future versions of the library.
*
* \note Due to an implementation limitation, domain parameters are not
* supported with keys that are managed by a driver.
*
* \param[in] attributes The key attribute structure to query.
* \param[out] data On success, the key domain parameters.
* \param data_size Size of the \p data buffer in bytes.
* The buffer is guaranteed to be large
* enough if its size in bytes is at least
* the value given by
* PSA_KEY_DOMAIN_PARAMETERS_SIZE().
* \param[out] data_length On success, the number of bytes
* that make up the key domain parameters data.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription
* \retval #PSA_ERROR_NOT_SUPPORTED
* The key is managed by a driver.
*/
psa_status_t psa_get_key_domain_parameters(
const psa_key_attributes_t *attributes,
uint8_t *data,
size_t data_size,
size_t *data_length);
/** Safe output buffer size for psa_get_key_domain_parameters().
*
* This macro returns a compile-time constant if its arguments are
* compile-time constants.
*
* \warning This function may call its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
* \note This is an experimental extension to the interface. It may change
* in future versions of the library.
*
* \param key_type A supported key type.
* \param key_bits The size of the key in bits.
*
* \return If the parameters are valid and supported, return
* a buffer size in bytes that guarantees that
* psa_get_key_domain_parameters() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \
(PSA_KEY_TYPE_IS_RSA(key_type) ? sizeof(int) : \
PSA_KEY_TYPE_IS_DH(key_type) ? PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
PSA_KEY_TYPE_IS_DSA(key_type) ? PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
0)
#define PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 3 /*without optional parts*/)
#define PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 2 /*p, g*/ + 34 /*q*/)
/**@}*/
@ -1828,8 +1700,12 @@ psa_status_t psa_pake_abort(psa_pake_operation_t *operation);
/** Returns a suitable initializer for a PAKE operation object of type
* psa_pake_operation_t.
*/
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_PAKE_OPERATION_INIT { 0 }
#else
#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, 0, PSA_PAKE_OPERATION_STAGE_SETUP, \
{ 0 }, { { 0 } } }
#endif
struct psa_pake_cipher_suite_s {
psa_algorithm_t algorithm;
@ -1957,6 +1833,9 @@ struct psa_jpake_computation_stage_s {
((round) == PSA_JPAKE_FIRST ? 2 : 1))
struct psa_pake_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** 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.
@ -1982,6 +1861,7 @@ struct psa_pake_operation_s {
psa_driver_pake_context_t MBEDTLS_PRIVATE(ctx);
psa_crypto_driver_pake_inputs_t MBEDTLS_PRIVATE(inputs);
} MBEDTLS_PRIVATE(data);
#endif
};
static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init(void)

View File

@ -89,4 +89,14 @@ typedef struct {
} mbedtls_psa_external_random_context_t;
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
/** The type of the client handle used in context structures
*
* When a client view of the multipart context structures is required,
* this handle is used to keep a mapping with the service side of the
* context which contains the actual data.
*/
typedef uint32_t mbedtls_psa_client_handle_t;
#endif
#endif /* PSA_CRYPTO_PLATFORM_H */

View File

@ -224,10 +224,20 @@
#endif
/* The maximum size of an DH key on this implementation, in bits.
*
* Note that an implementation may set different size limits for different
* operations, and does not need to accept all key sizes up to the limit. */
* This is a vendor-specific macro.*/
#if defined(PSA_WANT_DH_RFC7919_8192)
#define PSA_VENDOR_FFDH_MAX_KEY_BITS 8192u
#elif defined(PSA_WANT_DH_RFC7919_6144)
#define PSA_VENDOR_FFDH_MAX_KEY_BITS 6144u
#elif defined(PSA_WANT_DH_RFC7919_4096)
#define PSA_VENDOR_FFDH_MAX_KEY_BITS 4096u
#elif defined(PSA_WANT_DH_RFC7919_3072)
#define PSA_VENDOR_FFDH_MAX_KEY_BITS 3072u
#elif defined(PSA_WANT_DH_RFC7919_2048)
#define PSA_VENDOR_FFDH_MAX_KEY_BITS 2048u
#else
#define PSA_VENDOR_FFDH_MAX_KEY_BITS 0u
#endif
/* The maximum size of an ECC key on this implementation, in bits.
* This is a vendor-specific macro. */

View File

@ -68,6 +68,9 @@ extern "C" {
#include "psa/crypto_driver_contexts_primitives.h"
struct psa_hash_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** 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.
@ -76,9 +79,13 @@ struct psa_hash_operation_s {
* any driver (i.e. the driver context is not active, in use). */
unsigned int MBEDTLS_PRIVATE(id);
psa_driver_hash_context_t MBEDTLS_PRIVATE(ctx);
#endif
};
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_HASH_OPERATION_INIT { 0 }
#else
#define PSA_HASH_OPERATION_INIT { 0, { 0 } }
#endif
static inline struct psa_hash_operation_s psa_hash_operation_init(void)
{
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
@ -86,6 +93,9 @@ static inline struct psa_hash_operation_s psa_hash_operation_init(void)
}
struct psa_cipher_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** 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.
@ -100,9 +110,14 @@ struct psa_cipher_operation_s {
uint8_t MBEDTLS_PRIVATE(default_iv_length);
psa_driver_cipher_context_t MBEDTLS_PRIVATE(ctx);
#endif
};
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_CIPHER_OPERATION_INIT { 0 }
#else
#define PSA_CIPHER_OPERATION_INIT { 0, 0, 0, 0, { 0 } }
#endif
static inline struct psa_cipher_operation_s psa_cipher_operation_init(void)
{
const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
@ -114,6 +129,9 @@ static inline struct psa_cipher_operation_s psa_cipher_operation_init(void)
#include "psa/crypto_driver_contexts_composites.h"
struct psa_mac_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** 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.
@ -124,9 +142,14 @@ struct psa_mac_operation_s {
uint8_t MBEDTLS_PRIVATE(mac_size);
unsigned int MBEDTLS_PRIVATE(is_sign) : 1;
psa_driver_mac_context_t MBEDTLS_PRIVATE(ctx);
#endif
};
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_MAC_OPERATION_INIT { 0 }
#else
#define PSA_MAC_OPERATION_INIT { 0, 0, 0, { 0 } }
#endif
static inline struct psa_mac_operation_s psa_mac_operation_init(void)
{
const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT;
@ -134,7 +157,9 @@ static inline struct psa_mac_operation_s psa_mac_operation_init(void)
}
struct psa_aead_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** 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.
@ -156,9 +181,14 @@ struct psa_aead_operation_s {
unsigned int MBEDTLS_PRIVATE(is_encrypt) : 1;
psa_driver_aead_context_t MBEDTLS_PRIVATE(ctx);
#endif
};
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_AEAD_OPERATION_INIT { 0 }
#else
#define PSA_AEAD_OPERATION_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }
#endif
static inline struct psa_aead_operation_s psa_aead_operation_init(void)
{
const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
@ -170,14 +200,22 @@ static inline struct psa_aead_operation_s psa_aead_operation_init(void)
#include "psa/crypto_driver_contexts_key_derivation.h"
struct psa_key_derivation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
psa_algorithm_t MBEDTLS_PRIVATE(alg);
unsigned int MBEDTLS_PRIVATE(can_output_key) : 1;
size_t MBEDTLS_PRIVATE(capacity);
psa_driver_key_derivation_context_t MBEDTLS_PRIVATE(ctx);
#endif
};
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_KEY_DERIVATION_OPERATION_INIT { 0 }
#else
/* This only zeroes out the first byte in the union, the rest is unspecified. */
#define PSA_KEY_DERIVATION_OPERATION_INIT { 0, 0, 0, { 0 } }
#endif
static inline struct psa_key_derivation_s psa_key_derivation_operation_init(
void)
{
@ -185,6 +223,22 @@ static inline struct psa_key_derivation_s psa_key_derivation_operation_init(
return v;
}
struct psa_key_production_parameters_s {
/* Future versions may add other fields in this structure. */
uint32_t flags;
uint8_t data[];
};
/** The default production parameters for key generation or key derivation.
*
* Calling psa_generate_key_ext() or psa_key_derivation_output_key_ext()
* with `params=PSA_KEY_PRODUCTION_PARAMETERS_INIT` and
* `params_data_length == 0` is equivalent to
* calling psa_generate_key() or psa_key_derivation_output_key()
* respectively.
*/
#define PSA_KEY_PRODUCTION_PARAMETERS_INIT { 0 }
struct psa_key_policy_s {
psa_key_usage_t MBEDTLS_PRIVATE(usage);
psa_algorithm_t MBEDTLS_PRIVATE(alg);
@ -212,69 +266,39 @@ typedef uint16_t psa_key_bits_t;
* conditionals. */
#define PSA_MAX_KEY_BITS 0xfff8
/** A mask of flags that can be stored in key attributes.
*
* This type is also used internally to store flags in slots. Internal
* flags are defined in library/psa_crypto_core.h. Internal flags may have
* the same value as external flags if they are properly handled during
* key creation and in psa_get_key_attributes.
*/
typedef uint16_t psa_key_attributes_flag_t;
#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \
((psa_key_attributes_flag_t) 0x0001)
/* A mask of key attribute flags used externally only.
* Only meant for internal checks inside the library. */
#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \
MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \
0)
/* A mask of key attribute flags used both internally and externally.
* Currently there aren't any. */
#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \
0)
typedef struct {
struct psa_key_attributes_s {
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
int MBEDTLS_PRIVATE(has_slot_number);
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
psa_key_type_t MBEDTLS_PRIVATE(type);
psa_key_bits_t MBEDTLS_PRIVATE(bits);
psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime);
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id);
psa_key_policy_t MBEDTLS_PRIVATE(policy);
psa_key_attributes_flag_t MBEDTLS_PRIVATE(flags);
} psa_core_key_attributes_t;
#define PSA_CORE_KEY_ATTRIBUTES_INIT { PSA_KEY_TYPE_NONE, 0, \
PSA_KEY_LIFETIME_VOLATILE, \
MBEDTLS_SVC_KEY_ID_INIT, \
PSA_KEY_POLICY_INIT, 0 }
struct psa_key_attributes_s {
psa_core_key_attributes_t MBEDTLS_PRIVATE(core);
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
/* Unlike normal buffers, there are three cases for domain_parameters
* and domain_parameters_size:
* - domain_parameters_size == SIZE_MAX && domain_parameters == NULL:
* Access to domain parameters is not supported for this key.
* This is a hack which should not exist, intended for keys managed
* by a driver, because drivers don't support domain parameters.
* - domain_parameters_size == 0 && domain_parameters == NULL:
* The domain parameters are empty.
* - domain_parameters_size > 0 &&
* domain_parameters == valid pointer to domain_parameters_size bytes:
* The domain parameters are non-empty.
/* This type has a different layout in the client view wrt the
* service view of the key id, i.e. in service view usually is
* expected to have MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined
* thus adding an owner field to the standard psa_key_id_t. For
* implementations with client/service separation, this means the
* object will be marshalled through a transport channel and
* interpreted differently at each side of the transport. Placing
* it at the end of structures allows to interpret the structure
* at the client without reorganizing the memory layout of the
* struct
*/
void *MBEDTLS_PRIVATE(domain_parameters);
size_t MBEDTLS_PRIVATE(domain_parameters_size);
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id);
};
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#define PSA_KEY_ATTRIBUTES_INIT { PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0 }
#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, 0,
#else
#define PSA_KEY_ATTRIBUTES_INIT { PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0 }
#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER
#endif
#define PSA_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \
PSA_KEY_TYPE_NONE, 0, \
PSA_KEY_LIFETIME_VOLATILE, \
PSA_KEY_POLICY_INIT, \
MBEDTLS_SVC_KEY_ID_INIT }
static inline struct psa_key_attributes_s psa_key_attributes_init(void)
{
@ -285,12 +309,12 @@ static inline struct psa_key_attributes_s psa_key_attributes_init(void)
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t key)
{
psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(lifetime);
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = key;
attributes->MBEDTLS_PRIVATE(id) = key;
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) =
attributes->MBEDTLS_PRIVATE(lifetime) =
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
PSA_KEY_LIFETIME_PERSISTENT,
PSA_KEY_LIFETIME_GET_LOCATION(lifetime));
@ -300,26 +324,26 @@ static inline void psa_set_key_id(psa_key_attributes_t *attributes,
static inline mbedtls_svc_key_id_t psa_get_key_id(
const psa_key_attributes_t *attributes)
{
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id);
return attributes->MBEDTLS_PRIVATE(id);
}
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
static inline void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes,
mbedtls_key_owner_id_t owner)
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner;
attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner;
}
#endif
static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
psa_key_lifetime_t lifetime)
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) = lifetime;
attributes->MBEDTLS_PRIVATE(lifetime) = lifetime;
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0;
attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0;
#else
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = 0;
attributes->MBEDTLS_PRIVATE(id) = 0;
#endif
}
}
@ -327,7 +351,7 @@ static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
static inline psa_key_lifetime_t psa_get_key_lifetime(
const psa_key_attributes_t *attributes)
{
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
return attributes->MBEDTLS_PRIVATE(lifetime);
}
static inline void psa_extend_key_usage_flags(psa_key_usage_t *usage_flags)
@ -345,78 +369,62 @@ static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
psa_key_usage_t usage_flags)
{
psa_extend_key_usage_flags(&usage_flags);
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
}
static inline psa_key_usage_t psa_get_key_usage_flags(
const psa_key_attributes_t *attributes)
{
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
}
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
psa_algorithm_t alg)
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
}
static inline psa_algorithm_t psa_get_key_algorithm(
const psa_key_attributes_t *attributes)
{
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
}
/* This function is declared in crypto_extra.h, which comes after this
* header file, but we need the function here, so repeat the declaration. */
#if !defined(PSA_SET_KEY_DOMAIN_PARAMETERS)
#define PSA_SET_KEY_DOMAIN_PARAMETERS
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
psa_key_type_t type,
const uint8_t *data,
size_t data_length);
#endif /* PSA_SET_KEY_DOMAIN_PARAMETERS */
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
psa_key_type_t type)
{
if (attributes->MBEDTLS_PRIVATE(domain_parameters) == NULL) {
/* Common case: quick path */
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type) = type;
} else {
/* Call the bigger function to free the old domain parameters.
* Ignore any errors which may arise due to type requiring
* non-default domain parameters, since this function can't
* report errors. */
(void) psa_set_key_domain_parameters(attributes, type, NULL, 0);
}
attributes->MBEDTLS_PRIVATE(type) = type;
}
static inline psa_key_type_t psa_get_key_type(
const psa_key_attributes_t *attributes)
{
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type);
return attributes->MBEDTLS_PRIVATE(type);
}
static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
size_t bits)
{
if (bits > PSA_MAX_KEY_BITS) {
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
attributes->MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
} else {
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits;
attributes->MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits;
}
}
static inline size_t psa_get_key_bits(
const psa_key_attributes_t *attributes)
{
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits);
return attributes->MBEDTLS_PRIVATE(bits);
}
/**
* \brief The context for PSA interruptible hash signing.
*/
struct psa_sign_hash_interruptible_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** 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.
@ -430,9 +438,14 @@ struct psa_sign_hash_interruptible_operation_s {
unsigned int MBEDTLS_PRIVATE(error_occurred) : 1;
uint32_t MBEDTLS_PRIVATE(num_ops);
#endif
};
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 }
#else
#define PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0, 0 }
#endif
static inline struct psa_sign_hash_interruptible_operation_s
psa_sign_hash_interruptible_operation_init(void)
@ -447,6 +460,9 @@ psa_sign_hash_interruptible_operation_init(void)
* \brief The context for PSA interruptible hash verification.
*/
struct psa_verify_hash_interruptible_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** 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.
@ -460,9 +476,14 @@ struct psa_verify_hash_interruptible_operation_s {
unsigned int MBEDTLS_PRIVATE(error_occurred) : 1;
uint32_t MBEDTLS_PRIVATE(num_ops);
#endif
};
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 }
#else
#define PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0, 0 }
#endif
static inline struct psa_verify_hash_interruptible_operation_s
psa_verify_hash_interruptible_operation_init(void)

View File

@ -455,6 +455,30 @@ typedef uint64_t psa_key_slot_number_t;
*/
typedef uint16_t psa_key_derivation_step_t;
/** \brief Custom parameters for key generation or key derivation.
*
* This is a structure type with at least the following fields:
*
* - \c flags: an unsigned integer type. 0 for the default production parameters.
* - \c data: a flexible array of bytes.
*
* The interpretation of this structure depend on the type of the
* created key.
*
* - #PSA_KEY_TYPE_RSA_KEY_PAIR:
* - \c flags: must be 0.
* - \c data: the public exponent, in little-endian order.
* This must be an odd integer and must not be 1.
* Implementations must support 65535, should support 3 and may
* support other values.
* When not using a driver, Mbed TLS supports values up to \c INT_MAX.
* If this is empty or if the custom production parameters are omitted
* altogether, the default value 65537 is used.
* - Other key types: reserved for future use. \c flags must be 0.
*
*/
typedef struct psa_key_production_parameters_s psa_key_production_parameters_t;
/**@}*/
#endif /* PSA_CRYPTO_TYPES_H */

View File

@ -413,7 +413,7 @@
((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
/** The public key type corresponding to a key pair type.
*
* You may also pass a key pair type as \p type, it will be left unchanged.
* You may also pass a public key type as \p type, it will be left unchanged.
*
* \param type A public key type or key pair type.
*

View File

@ -231,7 +231,7 @@ if(HAIKU)
endif(HAIKU)
if(LINK_WITH_PTHREAD)
set(libs ${libs} pthread)
set(libs ${libs} ${CMAKE_THREAD_LIBS_INIT})
endif()
if(LINK_WITH_TRUSTED_STORAGE)

View File

@ -334,7 +334,7 @@ static void aesce_setkey_enc(unsigned char *rk,
* - Section 5, Nr = Nk + 6
* - Section 5.2, the length of round keys is Nb*(Nr+1)
*/
const uint32_t key_len_in_words = key_bit_length / 32; /* Nk */
const size_t key_len_in_words = key_bit_length / 32; /* Nk */
const size_t round_key_len_in_words = 4; /* Nb */
const size_t rounds_needed = key_len_in_words + 6; /* Nr */
const size_t round_keys_len_in_words =

View File

@ -53,28 +53,45 @@ typedef uint16_t __packed mbedtls_uint16_unaligned_t;
typedef uint32_t __packed mbedtls_uint32_unaligned_t;
typedef uint64_t __packed mbedtls_uint64_unaligned_t;
#elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \
((MBEDTLS_GCC_VERSION < 90300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)))
((MBEDTLS_GCC_VERSION < 60300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)))
/*
* Old versions of gcc, depending on how the target is specified, may generate a branch to memcpy
* for calls like `memcpy(dest, src, 4)` rather than generating some LDR or LDRB instructions
* (similar for stores).
* Recent versions where unaligned access is not enabled also do this.
* gcc may generate a branch to memcpy for calls like `memcpy(dest, src, 4)` rather than
* generating some LDR or LDRB instructions (similar for stores).
*
* This is architecture dependent: x86-64 seems fine even with old gcc; 32-bit Arm
* is affected. To keep it simple, we enable for all architectures.
*
* For versions of gcc < 5.4.0 this issue always happens.
* For gcc < 6.3.0, this issue happens at -O0
* For all versions, this issue happens iff unaligned access is not supported.
*
* For gcc 4.x, this implementation will generate byte-by-byte loads even if unaligned access is
* supported, which is correct but not optimal.
*
* For performance (and code size, in some cases), we want to avoid the branch and just generate
* some inline load/store instructions since the access is small and constant-size.
*
* The manual states:
* "The aligned attribute specifies a minimum alignment for the variable or structure field,
* measured in bytes."
* https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
* "The packed attribute specifies that a variable or structure field should have the smallest
* possible alignmentone byte for a variable"
* https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Variable-Attributes.html
*
* Tested with several versions of GCC from 4.5.0 up to 9.3.0
* Previous implementations used __attribute__((__aligned__(1)), but had issues with a gcc bug:
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94662
*
* Tested with several versions of GCC from 4.5.0 up to 13.2.0
* We don't enable for older than 4.5.0 as this has not been tested.
*/
#define UINT_UNALIGNED
typedef uint16_t __attribute__((__aligned__(1))) mbedtls_uint16_unaligned_t;
typedef uint32_t __attribute__((__aligned__(1))) mbedtls_uint32_unaligned_t;
typedef uint64_t __attribute__((__aligned__(1))) mbedtls_uint64_unaligned_t;
#define UINT_UNALIGNED_STRUCT
typedef struct {
uint16_t x;
} __attribute__((packed)) mbedtls_uint16_unaligned_t;
typedef struct {
uint32_t x;
} __attribute__((packed)) mbedtls_uint32_unaligned_t;
typedef struct {
uint64_t x;
} __attribute__((packed)) mbedtls_uint64_unaligned_t;
#endif
/*
@ -101,6 +118,9 @@ static inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
#if defined(UINT_UNALIGNED)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
r = *p16;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
r = p16->x;
#else
memcpy(&r, p, sizeof(r));
#endif
@ -124,6 +144,9 @@ static inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
#if defined(UINT_UNALIGNED)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
*p16 = x;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
p16->x = x;
#else
memcpy(p, &x, sizeof(x));
#endif
@ -147,6 +170,9 @@ static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = *p32;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = p32->x;
#else
memcpy(&r, p, sizeof(r));
#endif
@ -170,6 +196,9 @@ static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
*p32 = x;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
p32->x = x;
#else
memcpy(p, &x, sizeof(x));
#endif
@ -193,6 +222,9 @@ static inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
#if defined(UINT_UNALIGNED)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
r = *p64;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
r = p64->x;
#else
memcpy(&r, p, sizeof(r));
#endif
@ -216,6 +248,9 @@ static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
#if defined(UINT_UNALIGNED)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
*p64 = x;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
p64->x = x;
#else
memcpy(p, &x, sizeof(x));
#endif

View File

@ -25,12 +25,6 @@
#include "mbedtls/platform_util.h"
/* Parameter validation macros */
#define ARIA_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA)
#define ARIA_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
/*
* modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
*
@ -363,8 +357,6 @@ int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
int i;
uint32_t w[4][4], *w2;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(key != NULL);
if (keybits != 128 && keybits != 192 && keybits != 256) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
@ -418,8 +410,6 @@ int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
const unsigned char *key, unsigned int keybits)
{
int i, j, k, ret;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(key != NULL);
ret = mbedtls_aria_setkey_enc(ctx, key, keybits);
if (ret != 0) {
@ -455,9 +445,6 @@ int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
int i;
uint32_t a, b, c, d;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(input != NULL);
ARIA_VALIDATE_RET(output != NULL);
a = MBEDTLS_GET_UINT32_LE(input, 0);
b = MBEDTLS_GET_UINT32_LE(input, 4);
@ -505,7 +492,6 @@ int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
/* Initialize context */
void mbedtls_aria_init(mbedtls_aria_context *ctx)
{
ARIA_VALIDATE(ctx != NULL);
memset(ctx, 0, sizeof(mbedtls_aria_context));
}
@ -532,12 +518,9 @@ int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx,
{
unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(mode == MBEDTLS_ARIA_ENCRYPT ||
mode == MBEDTLS_ARIA_DECRYPT);
ARIA_VALIDATE_RET(length == 0 || input != NULL);
ARIA_VALIDATE_RET(length == 0 || output != NULL);
ARIA_VALIDATE_RET(iv != NULL);
if ((mode != MBEDTLS_ARIA_ENCRYPT) && (mode != MBEDTLS_ARIA_DECRYPT)) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
}
if (length % MBEDTLS_ARIA_BLOCKSIZE) {
return MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH;
@ -588,19 +571,14 @@ int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
unsigned char c;
size_t n;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(mode == MBEDTLS_ARIA_ENCRYPT ||
mode == MBEDTLS_ARIA_DECRYPT);
ARIA_VALIDATE_RET(length == 0 || input != NULL);
ARIA_VALIDATE_RET(length == 0 || output != NULL);
ARIA_VALIDATE_RET(iv != NULL);
ARIA_VALIDATE_RET(iv_off != NULL);
if ((mode != MBEDTLS_ARIA_ENCRYPT) && (mode != MBEDTLS_ARIA_DECRYPT)) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
}
n = *iv_off;
/* An overly large value of n can lead to an unlimited
* buffer overflow. Therefore, guard against this
* outside of parameter validation. */
* buffer overflow. */
if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
}
@ -650,17 +628,9 @@ int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx,
int c, i;
size_t n;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(length == 0 || input != NULL);
ARIA_VALIDATE_RET(length == 0 || output != NULL);
ARIA_VALIDATE_RET(nonce_counter != NULL);
ARIA_VALIDATE_RET(stream_block != NULL);
ARIA_VALIDATE_RET(nc_off != NULL);
n = *nc_off;
/* An overly large value of n can lead to an unlimited
* buffer overflow. Therefore, guard against this
* outside of parameter validation. */
* buffer overflow. */
if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
}

View File

@ -7,7 +7,8 @@
#include "common.h"
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
#include "mbedtls/asn1.h"
#include "mbedtls/platform_util.h"
@ -73,7 +74,7 @@ int mbedtls_asn1_get_tag(unsigned char **p,
return mbedtls_asn1_get_len(p, end, len);
}
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_PARSE_C)
int mbedtls_asn1_get_bool(unsigned char **p,

View File

@ -7,7 +7,8 @@
#include "common.h"
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C)
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
@ -62,7 +63,7 @@ int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, unsign
return 1;
}
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_WRITE_C)
static int mbedtls_asn1_write_len_and_tag(unsigned char **p,

View File

@ -37,10 +37,18 @@
#include "mbedtls/platform.h"
#define MPI_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA)
#define MPI_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
/*
* Conditionally select an MPI sign in constant time.
* (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid
* values.)
*/
static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,
signed short sign1, signed short sign2)
{
return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1;
}
/*
* Compare signed values in constant time
@ -51,10 +59,6 @@ int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
{
mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
MPI_VALIDATE_RET(ret != NULL);
if (X->n != Y->n) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
@ -115,15 +119,13 @@ int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
unsigned char assign)
{
int ret = 0;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
{
mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);
X->s = (int) mbedtls_ct_uint_if(do_assign, Y->s, X->s);
X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s);
mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);
@ -149,8 +151,6 @@ int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
{
int ret = 0;
int s;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
if (X == Y) {
return 0;
@ -162,8 +162,8 @@ int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
s = X->s;
X->s = (int) mbedtls_ct_uint_if(do_swap, Y->s, X->s);
Y->s = (int) mbedtls_ct_uint_if(do_swap, s, Y->s);
X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s);
Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s);
mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);
@ -179,8 +179,6 @@ cleanup:
*/
void mbedtls_mpi_init(mbedtls_mpi *X)
{
MPI_VALIDATE(X != NULL);
X->s = 1;
X->n = 0;
X->p = NULL;
@ -210,7 +208,6 @@ void mbedtls_mpi_free(mbedtls_mpi *X)
int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
{
mbedtls_mpi_uint *p;
MPI_VALIDATE_RET(X != NULL);
if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
@ -243,7 +240,6 @@ int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs)
{
mbedtls_mpi_uint *p;
size_t i;
MPI_VALIDATE_RET(X != NULL);
if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
@ -305,15 +301,12 @@ static int mbedtls_mpi_resize_clear(mbedtls_mpi *X, size_t limbs)
* This function is not constant-time. Leading zeros in Y may be removed.
*
* Ensure that X does not shrink. This is not guaranteed by the public API,
* but some code in the bignum module relies on this property, for example
* in mbedtls_mpi_exp_mod().
* but some code in the bignum module might still rely on this property.
*/
int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
{
int ret = 0;
size_t i;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
if (X == Y) {
return 0;
@ -355,8 +348,6 @@ cleanup:
void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y)
{
mbedtls_mpi T;
MPI_VALIDATE(X != NULL);
MPI_VALIDATE(Y != NULL);
memcpy(&T, X, sizeof(mbedtls_mpi));
memcpy(X, Y, sizeof(mbedtls_mpi));
@ -385,7 +376,6 @@ static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z)
int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MPI_VALIDATE_RET(X != NULL);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1));
memset(X->p, 0, X->n * ciL);
@ -403,8 +393,6 @@ cleanup:
*/
int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos)
{
MPI_VALIDATE_RET(X != NULL);
if (X->n * biL <= pos) {
return 0;
}
@ -420,7 +408,6 @@ int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val)
int ret = 0;
size_t off = pos / biL;
size_t idx = pos % biL;
MPI_VALIDATE_RET(X != NULL);
if (val != 0 && val != 1) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -448,7 +435,6 @@ cleanup:
size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
{
size_t i;
MBEDTLS_INTERNAL_VALIDATE_RET(X != NULL, 0);
#if defined(__has_builtin)
#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)
@ -530,8 +516,6 @@ int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s)
int sign = 1;
mbedtls_mpi_uint d;
mbedtls_mpi T;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(s != NULL);
if (radix < 2 || radix > 16) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -634,9 +618,6 @@ int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,
size_t n;
char *p;
mbedtls_mpi T;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(olen != NULL);
MPI_VALIDATE_RET(buflen == 0 || buf != NULL);
if (radix < 2 || radix > 16) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -726,9 +707,6 @@ int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin)
*/
char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(fin != NULL);
if (radix < 2 || radix > 16) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
@ -772,7 +750,6 @@ int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE
* newline characters and '\0'
*/
char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
MPI_VALIDATE_RET(X != NULL);
if (radix < 2 || radix > 16) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -844,9 +821,6 @@ int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buf
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const size_t limbs = CHARS_TO_LIMBS(buflen);
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(buflen == 0 || buf != NULL);
/* Ensure that target MPI has exactly the necessary number of limbs */
MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
@ -887,7 +861,6 @@ int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
MPI_VALIDATE_RET(X != NULL);
i = mbedtls_mpi_bitlen(X) + count;
@ -908,7 +881,6 @@ cleanup:
*/
int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)
{
MPI_VALIDATE_RET(X != NULL);
if (X->n != 0) {
mbedtls_mpi_core_shift_r(X->p, X->n, count);
}
@ -921,8 +893,6 @@ int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)
int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)
{
size_t i, j;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
for (i = X->n; i > 0; i--) {
if (X->p[i - 1] != 0) {
@ -964,8 +934,6 @@ int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)
int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y)
{
size_t i, j;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
for (i = X->n; i > 0; i--) {
if (X->p[i - 1] != 0) {
@ -1016,7 +984,6 @@ int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)
{
mbedtls_mpi Y;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET(X != NULL);
*p = mpi_sint_abs(z);
Y.s = TO_SIGN(z);
@ -1035,9 +1002,6 @@ int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
size_t j;
mbedtls_mpi_uint *p;
mbedtls_mpi_uint c;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
if (X == B) {
const mbedtls_mpi *T = A; A = X; B = T;
@ -1098,9 +1062,6 @@ int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
mbedtls_mpi_uint carry;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
for (n = B->n; n > 0; n--) {
if (B->p[n - 1] != 0) {
@ -1152,9 +1113,6 @@ static int add_sub_mpi(mbedtls_mpi *X,
int flip_B)
{
int ret, s;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
s = A->s;
if (A->s * B->s * flip_B < 0) {
@ -1203,8 +1161,6 @@ int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b
{
mbedtls_mpi B;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = TO_SIGN(b);
@ -1221,8 +1177,6 @@ int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b
{
mbedtls_mpi B;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = TO_SIGN(b);
@ -1241,9 +1195,6 @@ int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
size_t i, j;
mbedtls_mpi TA, TB;
int result_is_zero = 0;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
mbedtls_mpi_init(&TA);
mbedtls_mpi_init(&TB);
@ -1300,9 +1251,6 @@ cleanup:
*/
int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b)
{
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
size_t n = A->n;
while (n > 0 && A->p[n - 1] == 0) {
--n;
@ -1448,8 +1396,6 @@ int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
size_t i, n, t, k;
mbedtls_mpi X, Y, Z, T1, T2;
mbedtls_mpi_uint TP2[3];
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
if (mbedtls_mpi_cmp_int(B, 0) == 0) {
return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
@ -1572,7 +1518,6 @@ int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
{
mbedtls_mpi B;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = TO_SIGN(b);
@ -1588,9 +1533,6 @@ int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MPI_VALIDATE_RET(R != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
if (mbedtls_mpi_cmp_int(B, 0) < 0) {
return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
@ -1618,8 +1560,6 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s
{
size_t i;
mbedtls_mpi_uint x, y, z;
MPI_VALIDATE_RET(r != NULL);
MPI_VALIDATE_RET(A != NULL);
if (b == 0) {
return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
@ -1670,103 +1610,11 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s
return 0;
}
static void mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N)
{
*mm = mbedtls_mpi_core_montmul_init(N->p);
}
/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
*
* \param[in,out] A One of the numbers to multiply.
* It must have at least as many limbs as N
* (A->n >= N->n), and any limbs beyond n are ignored.
* On successful completion, A contains the result of
* the multiplication A * B * R^-1 mod N where
* R = (2^ciL)^n.
* \param[in] B One of the numbers to multiply.
* It must be nonzero and must not have more limbs than N
* (B->n <= N->n).
* \param[in] N The modulus. \p N must be odd.
* \param mm The value calculated by `mpi_montg_init(&mm, N)`.
* This is -N^-1 mod 2^ciL.
* \param[in,out] T A bignum for temporary storage.
* It must be at least twice the limb size of N plus 1
* (T->n >= 2 * N->n + 1).
* Its initial content is unused and
* its final content is indeterminate.
* It does not get reallocated.
*/
static void mpi_montmul(mbedtls_mpi *A, const mbedtls_mpi *B,
const mbedtls_mpi *N, mbedtls_mpi_uint mm,
mbedtls_mpi *T)
{
mbedtls_mpi_core_montmul(A->p, A->p, B->p, B->n, N->p, N->n, mm, T->p);
}
/*
* Montgomery reduction: A = A * R^-1 mod N
*
* See mpi_montmul() regarding constraints and guarantees on the parameters.
*/
static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N,
mbedtls_mpi_uint mm, mbedtls_mpi *T)
{
mbedtls_mpi_uint z = 1;
mbedtls_mpi U;
U.n = 1;
U.s = 1;
U.p = &z;
mpi_montmul(A, &U, N, mm, T);
}
/**
* Select an MPI from a table without leaking the index.
*
* This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
* reads the entire table in order to avoid leaking the value of idx to an
* attacker able to observe memory access patterns.
*
* \param[out] R Where to write the selected MPI.
* \param[in] T The table to read from.
* \param[in] T_size The number of elements in the table.
* \param[in] idx The index of the element to select;
* this must satisfy 0 <= idx < T_size.
*
* \return \c 0 on success, or a negative error code.
*/
static int mpi_select(mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
for (size_t i = 0; i < T_size; i++) {
MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(R, &T[i],
(unsigned char) mbedtls_ct_uint_eq(i, idx)));
}
cleanup:
return ret;
}
/*
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
*/
int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
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;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(E != NULL);
MPI_VALIDATE_RET(N != NULL);
if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -1782,261 +1630,88 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
}
/*
* Init temps and window size
* Ensure that the exponent that we are passing to the core is not NULL.
*/
mpi_montg_init(&mm, N);
mbedtls_mpi_init(&RR); mbedtls_mpi_init(&T);
mbedtls_mpi_init(&Apos);
mbedtls_mpi_init(&WW);
memset(W, 0, sizeof(W));
i = mbedtls_mpi_bitlen(E);
window_bitsize = (i > 671) ? 6 : (i > 239) ? 5 :
(i > 79) ? 4 : (i > 23) ? 3 : 1;
#if (MBEDTLS_MPI_WINDOW_SIZE < 6)
if (window_bitsize > MBEDTLS_MPI_WINDOW_SIZE) {
window_bitsize = MBEDTLS_MPI_WINDOW_SIZE;
if (E->n == 0) {
ret = mbedtls_mpi_lset(X, 1);
return ret;
}
#endif
const size_t w_table_used_size = (size_t) 1 << window_bitsize;
/*
* This function is not constant-trace: its memory accesses depend on the
* exponent value. To defend against timing attacks, callers (such as RSA
* and DHM) should use exponent blinding. However this is not enough if the
* adversary can find the exponent in a single trace, so this function
* takes extra precautions against adversaries who can observe memory
* access patterns.
*
* This function performs a series of multiplications by table elements and
* squarings, and we want the prevent the adversary from finding out which
* table element was used, and from distinguishing between multiplications
* and squarings. Firstly, when multiplying by an element of the window
* W[i], we do a constant-trace table lookup to obfuscate i. This leaves
* squarings as having a different memory access patterns from other
* multiplications. So secondly, we put the accumulator in the table as
* well, and also do a constant-trace table lookup to multiply by the
* accumulator which is W[x_index].
*
* This way, all multiplications take the form of a lookup-and-multiply.
* The number of lookup-and-multiply operations inside each iteration of
* the main loop still depends on the bits of the exponent, but since the
* other operations in the loop don't have an easily recognizable memory
* trace, an adversary is unlikely to be able to observe the exact
* patterns.
*
* An adversary may still be able to recover the exponent if they can
* observe both memory accesses and branches. However, branch prediction
* exploitation typically requires many traces of execution over the same
* data, which is defeated by randomized blinding.
* Allocate working memory for mbedtls_mpi_core_exp_mod()
*/
const size_t x_index = 0;
mbedtls_mpi_init(&W[x_index]);
j = N->n + 1;
/* All W[i] including the accumulator must have at least N->n limbs for
* the mpi_montmul() and mpi_montred() calls later. Here we ensure that
* W[1] and the accumulator W[x_index] are large enough. later we'll grow
* other W[i] to the same length. They must not be shrunk midway through
* this function!
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], j));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T, j * 2));
/*
* Compensate for negative A (and correct at the end)
*/
neg = (A->s == -1);
if (neg) {
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Apos, A));
Apos.s = 1;
A = &Apos;
size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);
mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));
if (T == NULL) {
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
}
mbedtls_mpi RR;
mbedtls_mpi_init(&RR);
/*
* If 1st call, pre-compute R^2 mod N
*/
if (prec_RR == NULL || prec_RR->p == NULL) {
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&RR, 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&RR, N->n * 2 * biL));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&RR, &RR, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
if (prec_RR != NULL) {
memcpy(prec_RR, &RR, sizeof(mbedtls_mpi));
*prec_RR = RR;
}
} else {
memcpy(&RR, prec_RR, sizeof(mbedtls_mpi));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));
RR = *prec_RR;
}
/*
* W[1] = A * R^2 * R^-1 mod N = A * R mod N
* To preserve constness we need to make a copy of A. Using X for this to
* save memory.
*/
if (mbedtls_mpi_cmp_mpi(A, N) >= 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&W[1], A, N));
/* This should be a no-op because W[1] is already that large before
* mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
* in mpi_montmul() below, so let's make sure. */
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], N->n + 1));
} else {
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[1], A));
}
/* Note that this is safe because W[1] always has at least N->n limbs
* (it grew above and was preserved by mbedtls_mpi_copy()). */
mpi_montmul(&W[1], &RR, N, mm, &T);
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
/*
* W[x_index] = R^2 * R^-1 mod N = R mod N
* Compensate for negative A (and correct at the end).
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[x_index], &RR));
mpi_montred(&W[x_index], N, mm, &T);
X->s = 1;
if (window_bitsize > 1) {
/*
* W[i] = W[1] ^ i
*
* The first bit of the sliding window is always 1 and therefore we
* only need to store the second half of the table.
*
* (There are two special elements in the table: W[0] for the
* accumulator/result and W[1] for A in Montgomery form. Both of these
* are already set at this point.)
*/
j = w_table_used_size / 2;
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[j], N->n + 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[j], &W[1]));
for (i = 0; i < window_bitsize - 1; i++) {
mpi_montmul(&W[j], &W[j], N, mm, &T);
}
/*
* W[i] = W[i - 1] * W[1]
*/
for (i = j + 1; i < w_table_used_size; i++) {
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[i], N->n + 1));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[i], &W[i - 1]));
mpi_montmul(&W[i], &W[1], N, mm, &T);
}
/*
* Make sure that X is in a form that is safe for consumption by
* the core functions.
*
* - The core functions will not touch the limbs of X above N->n. The
* result will be correct if those limbs are 0, which the mod call
* ensures.
* - Also, X must have at least as many limbs as N for the calls to the
* core functions.
*/
if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
}
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));
nblimbs = E->n;
bufsize = 0;
nbits = 0;
state = 0;
while (1) {
if (bufsize == 0) {
if (nblimbs == 0) {
break;
}
nblimbs--;
bufsize = sizeof(mbedtls_mpi_uint) << 3;
}
bufsize--;
ei = (E->p[nblimbs] >> bufsize) & 1;
/*
* skip leading 0s
*/
if (ei == 0 && state == 0) {
continue;
}
if (ei == 0 && state == 1) {
/*
* out of window, square W[x_index]
*/
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
mpi_montmul(&W[x_index], &WW, N, mm, &T);
continue;
}
/*
* add ei to current window
*/
state = 2;
nbits++;
exponent_bits_in_window |= (ei << (window_bitsize - nbits));
if (nbits == window_bitsize) {
/*
* W[x_index] = W[x_index]^window_bitsize R^-1 mod N
*/
for (i = 0; i < window_bitsize; i++) {
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
x_index));
mpi_montmul(&W[x_index], &WW, N, mm, &T);
}
/*
* W[x_index] = W[x_index] * W[exponent_bits_in_window] R^-1 mod N
*/
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
exponent_bits_in_window));
mpi_montmul(&W[x_index], &WW, N, mm, &T);
state--;
nbits = 0;
exponent_bits_in_window = 0;
}
/*
* Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().
*/
{
mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
}
/*
* process the remaining bits
* Correct for negative A.
*/
for (i = 0; i < nbits; i++) {
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
mpi_montmul(&W[x_index], &WW, N, mm, &T);
if (A->s == -1 && (E->p[0] & 1) != 0) {
mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);
X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);
exponent_bits_in_window <<= 1;
if ((exponent_bits_in_window & ((size_t) 1 << window_bitsize)) != 0) {
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, 1));
mpi_montmul(&W[x_index], &WW, N, mm, &T);
}
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
}
/*
* W[x_index] = A^E * R * R^-1 mod N = A^E mod N
*/
mpi_montred(&W[x_index], N, mm, &T);
if (neg && E->n != 0 && (E->p[0] & 1) != 0) {
W[x_index].s = -1;
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&W[x_index], N, &W[x_index]));
}
/*
* Load the result in the output variable.
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &W[x_index]));
cleanup:
/* The first bit of the sliding window is always 1 and therefore the first
* half of the table was unused. */
for (i = w_table_used_size/2; i < w_table_used_size; i++) {
mbedtls_mpi_free(&W[i]);
}
mbedtls_mpi_free(&W[x_index]);
mbedtls_mpi_free(&W[1]);
mbedtls_mpi_free(&T);
mbedtls_mpi_free(&Apos);
mbedtls_mpi_free(&WW);
mbedtls_mpi_zeroize_and_free(T, T_limbs);
if (prec_RR == NULL || prec_RR->p == NULL) {
mbedtls_mpi_free(&RR);
@ -2054,10 +1729,6 @@ int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
size_t lz, lzt;
mbedtls_mpi TA, TB;
MPI_VALIDATE_RET(G != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));
@ -2168,9 +1839,6 @@ int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const size_t limbs = CHARS_TO_LIMBS(size);
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(f_rng != NULL);
/* Ensure that target MPI has exactly the necessary number of limbs */
MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
if (size == 0) {
@ -2214,9 +1882,6 @@ int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(N != NULL);
if (mbedtls_mpi_cmp_int(N, 1) <= 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -2372,9 +2037,6 @@ static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds,
size_t i, j, k, s;
mbedtls_mpi W, R, T, A, RR;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(f_rng != NULL);
mbedtls_mpi_init(&W); mbedtls_mpi_init(&R);
mbedtls_mpi_init(&T); mbedtls_mpi_init(&A);
mbedtls_mpi_init(&RR);
@ -2462,8 +2124,6 @@ int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi XX;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(f_rng != NULL);
XX.s = 1;
XX.n = X->n;
@ -2513,9 +2173,6 @@ int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
mbedtls_mpi_uint r;
mbedtls_mpi Y;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(f_rng != NULL);
if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}

View File

@ -856,16 +856,17 @@ mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
return c;
}
mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
size_t limbs)
mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
size_t limbs)
{
volatile const mbedtls_mpi_uint *force_read_A = A;
mbedtls_mpi_uint bits = 0;
for (size_t i = 0; i < limbs; i++) {
bits |= A[i];
bits |= force_read_A[i];
}
return bits;
return mbedtls_ct_bool(bits);
}
void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X,

View File

@ -662,11 +662,11 @@ mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
* \param[in] A The MPI to test.
* \param limbs Number of limbs in \p A.
*
* \return 0 if `A == 0`
* non-0 (may be any value) if `A != 0`.
* \return MBEDTLS_CT_FALSE if `A == 0`
* MBEDTLS_CT_TRUE if `A != 0`.
*/
mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
size_t limbs);
mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
size_t limbs);
/**
* \brief Returns the number of limbs of working memory required for

View File

@ -11,7 +11,7 @@
#include "mbedtls/platform.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include <stdarg.h>

172
library/debug_internal.h Normal file
View File

@ -0,0 +1,172 @@
/**
* \file debug_internal.h
*
* \brief Internal part of the public "debug.h".
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_DEBUG_INTERNAL_H
#define MBEDTLS_DEBUG_INTERNAL_H
#include "mbedtls/debug.h"
/**
* \brief Print a message to the debug output. This function is always used
* through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
* context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the message has occurred in
* \param line line number the message has occurred at
* \param format format specifier, in printf format
* \param ... variables used by the format specifier
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6);
/**
* \brief Print the return value of a function to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text the name of the function that returned the error
* \param ret the return code value
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret);
/**
* \brief Output a buffer of size len bytes to the debug output. This function
* is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the buffer being dumped. Normally the
* variable or buffer name
* \param buf the buffer to be outputted
* \param len length of the buffer
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text,
const unsigned char *buf, size_t len);
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Print a MPI variable to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the MPI being output. Normally the
* variable name
* \param X the MPI variable
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X);
#endif
#if defined(MBEDTLS_ECP_LIGHT)
/**
* \brief Print an ECP point to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the ECP point being output. Normally the
* variable name
* \param X the ECP point
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_ecp_point *X);
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
/**
* \brief Print a X.509 certificate structure to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the certificate being output
* \param crt X.509 certificate structure
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_x509_crt *crt);
#endif
/* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function
only works for the built-in implementation. */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \
defined(MBEDTLS_ECDH_C)
typedef enum {
MBEDTLS_DEBUG_ECDH_Q,
MBEDTLS_DEBUG_ECDH_QP,
MBEDTLS_DEBUG_ECDH_Z,
} mbedtls_debug_ecdh_attr;
/**
* \brief Print a field of the ECDH structure in the SSL context to the debug
* output. This function is always used through the
* MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
* and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param ecdh the ECDH context
* \param attr the identifier of the attribute being output
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const mbedtls_ecdh_context *ecdh,
mbedtls_debug_ecdh_attr attr);
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
MBEDTLS_ECDH_C */
#endif /* MBEDTLS_DEBUG_INTERNAL_H */

View File

@ -144,6 +144,15 @@ static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx)
#endif
}
mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx)
{
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
return ctx->MBEDTLS_PRIVATE(grp).id;
#else
return ctx->MBEDTLS_PRIVATE(grp_id);
#endif
}
/*
* Initialize context
*/

View File

@ -3302,10 +3302,11 @@ cleanup:
/*
* Write a private key.
*/
#if !defined MBEDTLS_DEPRECATED_REMOVED
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen)
{
int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
@ -3332,6 +3333,39 @@ cleanup:
return ret;
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */
int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
size_t *olen, unsigned char *buf, size_t buflen)
{
size_t len = (key->grp.nbits + 7) / 8;
if (len > buflen) {
/* For robustness, ensure *olen <= buflen even on error. */
*olen = 0;
return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
}
*olen = len;
/* Private key not set */
if (key->d.n == 0) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
return mbedtls_mpi_write_binary_le(&key->d, buf, len);
}
#endif
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
return mbedtls_mpi_write_binary(&key->d, buf, len);
}
#endif
/* Private key set but no recognized curve type? This shouldn't happen. */
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
/*
* Write a public key.

View File

@ -23,12 +23,6 @@
#if !defined(MBEDTLS_ECP_ALT)
/* Parameter validation macros based on platform_util.h */
#define ECP_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA)
#define ECP_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) }
#define ECP_MPI_INIT_ARRAY(x) \
@ -52,7 +46,7 @@
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
/* For these curves, we build the group parameters dynamically. */
#define ECP_LOAD_GROUP
static mbedtls_mpi_uint mpi_one[] = { 1 };
static const mbedtls_mpi_uint mpi_one[] = { 1 };
#endif
/*
@ -4511,7 +4505,7 @@ static inline void ecp_mpi_set1(mbedtls_mpi *X)
{
X->s = 1;
X->n = 1;
X->p = mpi_one;
X->p = (mbedtls_mpi_uint *) mpi_one; /* X->p will not be modified so the cast is safe */
}
/*
@ -4722,7 +4716,6 @@ cleanup:
*/
int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
{
ECP_VALIDATE_RET(grp != NULL);
mbedtls_ecp_group_free(grp);
mbedtls_ecp_group_init(grp);
@ -5318,7 +5311,7 @@ cleanup:
*/
#define P_KOBLITZ_MAX (256 / 8 / sizeof(mbedtls_mpi_uint)) // Max limbs in P
#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R
static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
static inline int ecp_mod_koblitz(mbedtls_mpi *N, const mbedtls_mpi_uint *Rp, size_t p_limbs,
size_t adjust, size_t shift, mbedtls_mpi_uint mask)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -5332,7 +5325,7 @@ static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p
/* Init R */
R.s = 1;
R.p = Rp;
R.p = (mbedtls_mpi_uint *) Rp; /* R.p will not be modified so the cast is safe */
R.n = P_KOBLITZ_R;
/* Common setup for M */
@ -5403,7 +5396,7 @@ cleanup:
*/
static int ecp_mod_p192k1(mbedtls_mpi *N)
{
static mbedtls_mpi_uint Rp[] = {
static const mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
};
@ -5420,7 +5413,7 @@ static int ecp_mod_p192k1(mbedtls_mpi *N)
*/
static int ecp_mod_p224k1(mbedtls_mpi *N)
{
static mbedtls_mpi_uint Rp[] = {
static const mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
};
@ -5442,7 +5435,7 @@ static int ecp_mod_p224k1(mbedtls_mpi *N)
*/
static int ecp_mod_p256k1(mbedtls_mpi *N)
{
static mbedtls_mpi_uint Rp[] = {
static const mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
};

View File

@ -28,12 +28,6 @@
#if !defined(MBEDTLS_ECP_ALT)
/* Parameter validation macros based on platform_util.h */
#define ECP_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA)
#define ECP_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) }
#define ECP_MPI_INIT_ARRAY(x) \
@ -4764,7 +4758,6 @@ cleanup:
*/
int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
{
ECP_VALIDATE_RET(grp != NULL);
mbedtls_ecp_group_free(grp);
mbedtls_ecp_group_init(grp);

View File

@ -5,7 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#if defined(__linux__) && !defined(_GNU_SOURCE)
#if defined(__linux__) || defined(__midipix__) && !defined(_GNU_SOURCE)
/* Ensure that syscall() is available even when compiling with -std=c99 */
#define _GNU_SOURCE
#endif

View File

@ -41,6 +41,12 @@
#if !defined(MBEDTLS_GCM_ALT)
/* Used to select the acceleration mechanism */
#define MBEDTLS_GCM_ACC_SMALLTABLE 0
#define MBEDTLS_GCM_ACC_LARGETABLE 1
#define MBEDTLS_GCM_ACC_AESNI 2
#define MBEDTLS_GCM_ACC_AESCE 3
/*
* Initialize a context
*/
@ -49,6 +55,39 @@ void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
memset(ctx, 0, sizeof(mbedtls_gcm_context));
}
static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx)
{
#if defined(MBEDTLS_GCM_LARGE_TABLE)
ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE;
#else
ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE;
#endif
#if defined(MBEDTLS_AESNI_HAVE_CODE)
/* With CLMUL support, we need only h, not the rest of the table */
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
ctx->acceleration = MBEDTLS_GCM_ACC_AESNI;
}
#endif
#if defined(MBEDTLS_AESCE_HAVE_CODE)
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
ctx->acceleration = MBEDTLS_GCM_ACC_AESCE;
}
#endif
}
static inline void gcm_gen_table_rightshift(uint64_t dst[2], const uint64_t src[2])
{
uint8_t *u8Dst = (uint8_t *) dst;
uint8_t *u8Src = (uint8_t *) src;
MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[1], 0) >> 1, &dst[1], 0);
u8Dst[8] |= (u8Src[7] & 0x01) << 7;
MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[0], 0) >> 1, &dst[0], 0);
u8Dst[0] ^= (u8Src[15] & 0x01) ? 0xE1 : 0;
}
/*
* Precompute small multiples of H, that is set
* HH[i] || HL[i] = H times i,
@ -60,11 +99,8 @@ void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
static int gcm_gen_table(mbedtls_gcm_context *ctx)
{
int ret, i, j;
uint64_t hi, lo;
uint64_t vl, vh;
unsigned char h[16];
memset(h, 0, 16);
uint64_t u64h[2] = { 0 };
uint8_t *h = (uint8_t *) u64h;
#if defined(MBEDTLS_BLOCK_CIPHER_C)
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
@ -76,53 +112,48 @@ static int gcm_gen_table(mbedtls_gcm_context *ctx)
return ret;
}
/* pack h as two 64-bits ints, big-endian */
hi = MBEDTLS_GET_UINT32_BE(h, 0);
lo = MBEDTLS_GET_UINT32_BE(h, 4);
vh = (uint64_t) hi << 32 | lo;
gcm_set_acceleration(ctx);
hi = MBEDTLS_GET_UINT32_BE(h, 8);
lo = MBEDTLS_GET_UINT32_BE(h, 12);
vl = (uint64_t) hi << 32 | lo;
/* 8 = 1000 corresponds to 1 in GF(2^128) */
ctx->HL[8] = vl;
ctx->HH[8] = vh;
/* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */
ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0];
ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1];
switch (ctx->acceleration) {
#if defined(MBEDTLS_AESNI_HAVE_CODE)
/* With CLMUL support, we need only h, not the rest of the table */
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
return 0;
}
case MBEDTLS_GCM_ACC_AESNI:
return 0;
#endif
#if defined(MBEDTLS_AESCE_HAVE_CODE)
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
return 0;
}
case MBEDTLS_GCM_ACC_AESCE:
return 0;
#endif
/* 0 corresponds to 0 in GF(2^128) */
ctx->HH[0] = 0;
ctx->HL[0] = 0;
default:
/* 0 corresponds to 0 in GF(2^128) */
ctx->H[0][0] = 0;
ctx->H[0][1] = 0;
for (i = 4; i > 0; i >>= 1) {
uint32_t T = (vl & 1) * 0xe1000000U;
vl = (vh << 63) | (vl >> 1);
vh = (vh >> 1) ^ ((uint64_t) T << 32);
for (i = MBEDTLS_GCM_HTABLE_SIZE/4; i > 0; i >>= 1) {
gcm_gen_table_rightshift(ctx->H[i], ctx->H[i*2]);
}
ctx->HL[i] = vl;
ctx->HH[i] = vh;
}
#if !defined(MBEDTLS_GCM_LARGE_TABLE)
/* pack elements of H as 64-bits ints, big-endian */
for (i = MBEDTLS_GCM_HTABLE_SIZE/2; i > 0; i >>= 1) {
MBEDTLS_PUT_UINT64_BE(ctx->H[i][0], &ctx->H[i][0], 0);
MBEDTLS_PUT_UINT64_BE(ctx->H[i][1], &ctx->H[i][1], 0);
}
#endif
for (i = 2; i <= 8; i *= 2) {
uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
vh = *HiH;
vl = *HiL;
for (j = 1; j < i; j++) {
HiH[j] = vh ^ ctx->HH[j];
HiL[j] = vl ^ ctx->HL[j];
}
for (i = 2; i < MBEDTLS_GCM_HTABLE_SIZE; i <<= 1) {
for (j = 1; j < i; j++) {
mbedtls_xor_no_simd((unsigned char *) ctx->H[i+j],
(unsigned char *) ctx->H[i],
(unsigned char *) ctx->H[j],
16);
}
}
}
return 0;
@ -181,6 +212,80 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
return 0;
}
#if defined(MBEDTLS_GCM_LARGE_TABLE)
static const uint16_t last8[256] = {
0x0000, 0xc201, 0x8403, 0x4602, 0x0807, 0xca06, 0x8c04, 0x4e05,
0x100e, 0xd20f, 0x940d, 0x560c, 0x1809, 0xda08, 0x9c0a, 0x5e0b,
0x201c, 0xe21d, 0xa41f, 0x661e, 0x281b, 0xea1a, 0xac18, 0x6e19,
0x3012, 0xf213, 0xb411, 0x7610, 0x3815, 0xfa14, 0xbc16, 0x7e17,
0x4038, 0x8239, 0xc43b, 0x063a, 0x483f, 0x8a3e, 0xcc3c, 0x0e3d,
0x5036, 0x9237, 0xd435, 0x1634, 0x5831, 0x9a30, 0xdc32, 0x1e33,
0x6024, 0xa225, 0xe427, 0x2626, 0x6823, 0xaa22, 0xec20, 0x2e21,
0x702a, 0xb22b, 0xf429, 0x3628, 0x782d, 0xba2c, 0xfc2e, 0x3e2f,
0x8070, 0x4271, 0x0473, 0xc672, 0x8877, 0x4a76, 0x0c74, 0xce75,
0x907e, 0x527f, 0x147d, 0xd67c, 0x9879, 0x5a78, 0x1c7a, 0xde7b,
0xa06c, 0x626d, 0x246f, 0xe66e, 0xa86b, 0x6a6a, 0x2c68, 0xee69,
0xb062, 0x7263, 0x3461, 0xf660, 0xb865, 0x7a64, 0x3c66, 0xfe67,
0xc048, 0x0249, 0x444b, 0x864a, 0xc84f, 0x0a4e, 0x4c4c, 0x8e4d,
0xd046, 0x1247, 0x5445, 0x9644, 0xd841, 0x1a40, 0x5c42, 0x9e43,
0xe054, 0x2255, 0x6457, 0xa656, 0xe853, 0x2a52, 0x6c50, 0xae51,
0xf05a, 0x325b, 0x7459, 0xb658, 0xf85d, 0x3a5c, 0x7c5e, 0xbe5f,
0x00e1, 0xc2e0, 0x84e2, 0x46e3, 0x08e6, 0xcae7, 0x8ce5, 0x4ee4,
0x10ef, 0xd2ee, 0x94ec, 0x56ed, 0x18e8, 0xdae9, 0x9ceb, 0x5eea,
0x20fd, 0xe2fc, 0xa4fe, 0x66ff, 0x28fa, 0xeafb, 0xacf9, 0x6ef8,
0x30f3, 0xf2f2, 0xb4f0, 0x76f1, 0x38f4, 0xfaf5, 0xbcf7, 0x7ef6,
0x40d9, 0x82d8, 0xc4da, 0x06db, 0x48de, 0x8adf, 0xccdd, 0x0edc,
0x50d7, 0x92d6, 0xd4d4, 0x16d5, 0x58d0, 0x9ad1, 0xdcd3, 0x1ed2,
0x60c5, 0xa2c4, 0xe4c6, 0x26c7, 0x68c2, 0xaac3, 0xecc1, 0x2ec0,
0x70cb, 0xb2ca, 0xf4c8, 0x36c9, 0x78cc, 0xbacd, 0xfccf, 0x3ece,
0x8091, 0x4290, 0x0492, 0xc693, 0x8896, 0x4a97, 0x0c95, 0xce94,
0x909f, 0x529e, 0x149c, 0xd69d, 0x9898, 0x5a99, 0x1c9b, 0xde9a,
0xa08d, 0x628c, 0x248e, 0xe68f, 0xa88a, 0x6a8b, 0x2c89, 0xee88,
0xb083, 0x7282, 0x3480, 0xf681, 0xb884, 0x7a85, 0x3c87, 0xfe86,
0xc0a9, 0x02a8, 0x44aa, 0x86ab, 0xc8ae, 0x0aaf, 0x4cad, 0x8eac,
0xd0a7, 0x12a6, 0x54a4, 0x96a5, 0xd8a0, 0x1aa1, 0x5ca3, 0x9ea2,
0xe0b5, 0x22b4, 0x64b6, 0xa6b7, 0xe8b2, 0x2ab3, 0x6cb1, 0xaeb0,
0xf0bb, 0x32ba, 0x74b8, 0xb6b9, 0xf8bc, 0x3abd, 0x7cbf, 0xbebe
};
static void gcm_mult_largetable(uint8_t *output, const uint8_t *x, uint64_t H[256][2])
{
int i;
uint64_t u64z[2];
uint16_t *u16z = (uint16_t *) u64z;
uint8_t *u8z = (uint8_t *) u64z;
uint8_t rem;
u64z[0] = 0;
u64z[1] = 0;
if (MBEDTLS_IS_BIG_ENDIAN) {
for (i = 15; i > 0; i--) {
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
rem = u8z[15];
u64z[1] >>= 8;
u8z[8] = u8z[7];
u64z[0] >>= 8;
u16z[0] ^= MBEDTLS_GET_UINT16_LE(&last8[rem], 0);
}
} else {
for (i = 15; i > 0; i--) {
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
rem = u8z[15];
u64z[1] <<= 8;
u8z[8] = u8z[7];
u64z[0] <<= 8;
u16z[0] ^= last8[rem];
}
}
mbedtls_xor_no_simd(output, u8z, (uint8_t *) H[x[0]], 16);
}
#else
/*
* Shoup's method for multiplication use this table with
* last4[x] = x times P^128
@ -194,6 +299,47 @@ static const uint16_t last4[16] =
0x9180, 0x8da0, 0xa9c0, 0xb5e0
};
static void gcm_mult_smalltable(uint8_t *output, const uint8_t *x, uint64_t H[16][2])
{
int i = 0;
unsigned char lo, hi, rem;
uint64_t u64z[2];
const uint64_t *pu64z = NULL;
uint8_t *u8z = (uint8_t *) u64z;
lo = x[15] & 0xf;
hi = (x[15] >> 4) & 0xf;
pu64z = H[lo];
rem = (unsigned char) pu64z[1] & 0xf;
u64z[1] = (pu64z[0] << 60) | (pu64z[1] >> 4);
u64z[0] = (pu64z[0] >> 4);
u64z[0] ^= (uint64_t) last4[rem] << 48;
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
for (i = 14; i >= 0; i--) {
lo = x[i] & 0xf;
hi = (x[i] >> 4) & 0xf;
rem = (unsigned char) u64z[1] & 0xf;
u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
u64z[0] = (u64z[0] >> 4);
u64z[0] ^= (uint64_t) last4[rem] << 48;
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[lo], 16);
rem = (unsigned char) u64z[1] & 0xf;
u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
u64z[0] = (u64z[0] >> 4);
u64z[0] ^= (uint64_t) last4[rem] << 48;
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
}
MBEDTLS_PUT_UINT64_BE(u64z[0], output, 0);
MBEDTLS_PUT_UINT64_BE(u64z[1], output, 8);
}
#endif
/*
* Sets output to x times H using the precomputed tables.
* x and output are seen as elements of GF(2^128) as in [MGV].
@ -201,71 +347,31 @@ static const uint16_t last4[16] =
static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
unsigned char output[16])
{
int i = 0;
unsigned char lo, hi, rem;
uint64_t zh, zl;
switch (ctx->acceleration) {
#if defined(MBEDTLS_AESNI_HAVE_CODE)
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
unsigned char h[16];
/* mbedtls_aesni_gcm_mult needs big-endian input */
MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
mbedtls_aesni_gcm_mult(output, x, h);
return;
}
#endif /* MBEDTLS_AESNI_HAVE_CODE */
#if defined(MBEDTLS_AESCE_HAVE_CODE)
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
unsigned char h[16];
/* mbedtls_aesce_gcm_mult needs big-endian input */
MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
mbedtls_aesce_gcm_mult(output, x, h);
return;
}
case MBEDTLS_GCM_ACC_AESNI:
mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
break;
#endif
lo = x[15] & 0xf;
#if defined(MBEDTLS_AESCE_HAVE_CODE)
case MBEDTLS_GCM_ACC_AESCE:
mbedtls_aesce_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
break;
#endif
zh = ctx->HH[lo];
zl = ctx->HL[lo];
for (i = 15; i >= 0; i--) {
lo = x[i] & 0xf;
hi = (x[i] >> 4) & 0xf;
if (i != 15) {
rem = (unsigned char) zl & 0xf;
zl = (zh << 60) | (zl >> 4);
zh = (zh >> 4);
zh ^= (uint64_t) last4[rem] << 48;
zh ^= ctx->HH[lo];
zl ^= ctx->HL[lo];
}
rem = (unsigned char) zl & 0xf;
zl = (zh << 60) | (zl >> 4);
zh = (zh >> 4);
zh ^= (uint64_t) last4[rem] << 48;
zh ^= ctx->HH[hi];
zl ^= ctx->HL[hi];
#if defined(MBEDTLS_GCM_LARGE_TABLE)
case MBEDTLS_GCM_ACC_LARGETABLE:
gcm_mult_largetable(output, x, ctx->H);
break;
#else
case MBEDTLS_GCM_ACC_SMALLTABLE:
gcm_mult_smalltable(output, x, ctx->H);
break;
#endif
}
MBEDTLS_PUT_UINT32_BE(zh >> 32, output, 0);
MBEDTLS_PUT_UINT32_BE(zh, output, 4);
MBEDTLS_PUT_UINT32_BE(zl >> 32, output, 8);
MBEDTLS_PUT_UINT32_BE(zl, output, 12);
return;
}
int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
@ -354,9 +460,17 @@ int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
{
const unsigned char *p;
size_t use_len, offset;
uint64_t new_add_len;
/* IV is limited to 2^64 bits, so 2^61 bytes */
if ((uint64_t) add_len >> 61 != 0) {
/* AD is limited to 2^64 bits, ie 2^61 bytes
* Also check for possible overflow */
#if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL
if (add_len > 0xFFFFFFFFFFFFFFFFULL) {
return MBEDTLS_ERR_GCM_BAD_INPUT;
}
#endif
new_add_len = ctx->add_len + (uint64_t) add_len;
if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
return MBEDTLS_ERR_GCM_BAD_INPUT;
}
@ -539,6 +653,9 @@ int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
(void) output_size;
*output_length = 0;
/* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
* and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of
* the two multiplications would overflow. */
orig_len = ctx->len * 8;
orig_add_len = ctx->add_len * 8;

View File

@ -65,7 +65,8 @@ static int local_err_translation(psa_status_t status)
#define H_TREE_HEIGHT_MAX 10
#define MERKLE_TREE_NODE_AM(type) ((size_t) 1 << (MBEDTLS_LMS_H_TREE_HEIGHT(type) + 1u))
#define MERKLE_TREE_LEAF_NODE_AM(type) ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type))
#define MERKLE_TREE_INTERNAL_NODE_AM(type) ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type))
#define MERKLE_TREE_INTERNAL_NODE_AM(type) ((unsigned int) \
(1u << MBEDTLS_LMS_H_TREE_HEIGHT(type)))
#define D_CONST_LEN (2)
static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = { 0x82, 0x82 };

View File

@ -683,6 +683,18 @@ static const oid_cipher_alg_t oid_cipher_alg[] =
OID_DESCRIPTOR(MBEDTLS_OID_DES_EDE3_CBC, "des-ede3-cbc", "DES-EDE3-CBC"),
MBEDTLS_CIPHER_DES_EDE3_CBC,
},
{
OID_DESCRIPTOR(MBEDTLS_OID_AES_128_CBC, "aes128-cbc", "AES128-CBC"),
MBEDTLS_CIPHER_AES_128_CBC,
},
{
OID_DESCRIPTOR(MBEDTLS_OID_AES_192_CBC, "aes192-cbc", "AES192-CBC"),
MBEDTLS_CIPHER_AES_192_CBC,
},
{
OID_DESCRIPTOR(MBEDTLS_OID_AES_256_CBC, "aes256-cbc", "AES256-CBC"),
MBEDTLS_CIPHER_AES_256_CBC,
},
{
NULL_OID_DESCRIPTOR,
MBEDTLS_CIPHER_NONE,

View File

@ -240,6 +240,29 @@ exit:
}
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
{
/* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */
size_t pad_len = input[input_len - 1];
size_t i;
if (pad_len > input_len) {
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
}
*data_len = input_len - pad_len;
for (i = *data_len; i < input_len; i++) {
if (input[i] != pad_len) {
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
}
}
return 0;
}
#endif /* MBEDTLS_DES_C || MBEDTLS_AES_C */
#endif /* PEM_RFC1421 */
int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer,
@ -389,6 +412,10 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret);
}
if (len == 0) {
return MBEDTLS_ERR_PEM_BAD_INPUT_DATA;
}
if ((buf = mbedtls_calloc(1, len)) == NULL) {
return MBEDTLS_ERR_PEM_ALLOC_FAILED;
}
@ -426,20 +453,20 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
#endif /* MBEDTLS_AES_C */
if (ret != 0) {
mbedtls_free(buf);
mbedtls_zeroize_and_free(buf, len);
return ret;
}
/*
* The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
* length bytes (allow 4 to be sure) in all known use cases.
*
* Use that as a heuristic to try to detect password mismatches.
*/
if (len <= 2 || buf[0] != 0x30 || buf[1] > 0x83) {
/* Check PKCS padding and update data length based on padding info.
* This can be used to detect invalid padding data and password
* mismatches. */
size_t unpadded_len;
ret = pem_check_pkcs_padding(buf, len, &unpadded_len);
if (ret != 0) {
mbedtls_zeroize_and_free(buf, len);
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
return ret;
}
len = unpadded_len;
#else
mbedtls_zeroize_and_free(buf, len);
return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE;

View File

@ -18,10 +18,8 @@
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#if defined(MBEDTLS_PKCS1_V21) && !defined(MBEDTLS_USE_PSA_CRYPTO)
#include "rsa_internal.h"
#endif
#endif
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#include "mbedtls/ecp.h"
#endif
@ -29,7 +27,7 @@
#include "mbedtls/ecdsa.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include "psa_util_internal.h"
#include "mbedtls/psa_util.h"
#endif
@ -378,6 +376,482 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PSA_CRYPTO_C)
#if defined(MBEDTLS_RSA_C)
static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa,
int want_crypt)
{
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
if (want_crypt) {
mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa);
return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type));
} else {
return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH);
}
} else {
if (want_crypt) {
return PSA_ALG_RSA_PKCS1V15_CRYPT;
} else {
return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH);
}
}
}
#endif /* MBEDTLS_RSA_C */
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
psa_key_usage_t usage,
psa_key_attributes_t *attributes)
{
mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
psa_key_usage_t more_usage = usage;
if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) {
more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
} else if (usage == PSA_KEY_USAGE_SIGN_HASH) {
more_usage |= PSA_KEY_USAGE_VERIFY_HASH;
} else if (usage == PSA_KEY_USAGE_DECRYPT) {
more_usage |= PSA_KEY_USAGE_ENCRYPT;
}
more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE ||
usage == PSA_KEY_USAGE_VERIFY_HASH ||
usage == PSA_KEY_USAGE_ENCRYPT);
switch (pk_type) {
#if defined(MBEDTLS_RSA_C)
case MBEDTLS_PK_RSA:
{
int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
/* Nothing to do. */
break;
case PSA_KEY_USAGE_DECRYPT:
case PSA_KEY_USAGE_ENCRYPT:
want_crypt = 1;
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
/* Detect the presence of a private key in a way that works both
* in CRT and non-CRT configurations. */
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
int has_private = (mbedtls_rsa_check_privkey(rsa) == 0);
if (want_private && !has_private) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, (want_private ?
PSA_KEY_TYPE_RSA_KEY_PAIR :
PSA_KEY_TYPE_RSA_PUBLIC_KEY));
psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk));
psa_set_key_algorithm(attributes,
psa_algorithm_for_rsa(rsa, want_crypt));
break;
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
{
int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH);
int derive_ok = (pk_type != MBEDTLS_PK_ECDSA);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_ecc_family_t family = pk->ec_family;
size_t bits = pk->ec_bits;
int has_private = 0;
if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) {
has_private = 1;
}
#else
const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
int has_private = (ec->d.n != 0);
size_t bits = 0;
psa_ecc_family_t family =
mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
#endif
psa_algorithm_t alg = 0;
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
if (!sign_ok) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH);
#else
alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH);
#endif
break;
case PSA_KEY_USAGE_DERIVE:
alg = PSA_ALG_ECDH;
if (!derive_ok) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
if (want_private && !has_private) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, (want_private ?
PSA_KEY_TYPE_ECC_KEY_PAIR(family) :
PSA_KEY_TYPE_ECC_PUBLIC_KEY(family)));
psa_set_key_bits(attributes, bits);
psa_set_key_algorithm(attributes, alg);
break;
}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
case MBEDTLS_PK_RSA_ALT:
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
case MBEDTLS_PK_OPAQUE:
{
psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_get_key_attributes(pk->priv_id, &old_attributes);
if (status != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_key_type_t old_type = psa_get_key_type(&old_attributes);
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) ||
old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
case PSA_KEY_USAGE_DECRYPT:
case PSA_KEY_USAGE_ENCRYPT:
if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
case PSA_KEY_USAGE_DERIVE:
if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_key_type_t new_type = old_type;
/* Opaque keys are always key pairs, so we don't need a check
* on the input if the required usage is private. We just need
* to adjust the type correctly if the required usage is public. */
if (!want_private) {
new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type);
}
more_usage = psa_get_key_usage_flags(&old_attributes);
if ((usage & more_usage) == 0) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, new_type);
psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes));
psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes));
break;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
default:
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_set_key_usage_flags(attributes, more_usage);
psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE);
return 0;
}
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO)
static psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *new_key_id)
{
unsigned char key_buffer[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
size_t key_length = 0;
psa_status_t status = psa_export_key(old_key_id,
key_buffer, sizeof(key_buffer),
&key_length);
if (status != PSA_SUCCESS) {
return status;
}
status = psa_import_key(attributes, key_buffer, key_length, new_key_id);
mbedtls_platform_zeroize(key_buffer, key_length);
return status;
}
static int copy_into_psa(mbedtls_svc_key_id_t old_key_id,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *new_key_id)
{
/* Normally, we prefer copying: it's more efficient and works even
* for non-exportable keys. */
psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id);
if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ ||
status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) {
/* There are edge cases where copying won't work, but export+import
* might:
* - If the old key does not allow PSA_KEY_USAGE_COPY.
* - If the old key's usage does not allow what attributes wants.
* Because the key was intended for use in the pk module, and may
* have had a policy chosen solely for what pk needs rather than
* based on a detailed understanding of PSA policies, we are a bit
* more liberal than psa_copy_key() here.
*/
/* Here we need to check that the types match, otherwise we risk
* importing nonsensical data. */
psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
status = psa_get_key_attributes(old_key_id, &old_attributes);
if (status != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_key_type_t old_type = psa_get_key_type(&old_attributes);
psa_reset_key_attributes(&old_attributes);
if (old_type != psa_get_key_type(attributes)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
status = export_import_into_psa(old_key_id, attributes, new_key_id);
}
return PSA_PK_TO_MBEDTLS_ERR(status);
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */
static int import_pair_into_psa(const mbedtls_pk_context *pk,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key_id)
{
switch (mbedtls_pk_get_type(pk)) {
#if defined(MBEDTLS_RSA_C)
case MBEDTLS_PK_RSA:
{
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
unsigned char key_buffer[
PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)];
unsigned char *const key_end = key_buffer + sizeof(key_buffer);
unsigned char *key_data = key_end;
int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk),
key_buffer, &key_data);
if (ret < 0) {
return ret;
}
size_t key_length = key_end - key_data;
ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
key_data, key_length,
key_id));
mbedtls_platform_zeroize(key_data, key_length);
return ret;
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
{
/* We need to check the curve family, otherwise the import could
* succeed with nonsensical data.
* We don't check the bit-size: it's optional in attributes,
* and if it's specified, psa_import_key() will know from the key
* data length and will check that the bit-size matches. */
psa_key_type_t to_type = psa_get_key_type(attributes);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_ecc_family_t from_family = pk->ec_family;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
size_t from_bits = 0;
psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
&from_bits);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if (mbedtls_svc_key_id_is_null(pk->priv_id)) {
/* We have a public key and want a key pair. */
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
return copy_into_psa(pk->priv_id, attributes, key_id);
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
if (ec->d.n == 0) {
/* Private key not set. Assume the input is a public key only.
* (The other possibility is that it's an incomplete object
* where the group is set but neither the public key nor
* the private key. This is not possible through ecp.h
* functions, so we don't bother reporting a more suitable
* error in that case.) */
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
size_t key_length = 0;
int ret = mbedtls_ecp_write_key_ext(ec, &key_length,
key_buffer, sizeof(key_buffer));
if (ret < 0) {
return ret;
}
ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
key_buffer, key_length,
key_id));
mbedtls_platform_zeroize(key_buffer, key_length);
return ret;
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
case MBEDTLS_PK_OPAQUE:
return copy_into_psa(pk->priv_id, attributes, key_id);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
default:
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
}
static int import_public_into_psa(const mbedtls_pk_context *pk,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key_id)
{
psa_key_type_t psa_type = psa_get_key_type(attributes);
#if defined(MBEDTLS_RSA_C) || \
(defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \
defined(MBEDTLS_USE_PSA_CRYPTO)
unsigned char key_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
#endif
unsigned char *key_data = NULL;
size_t key_length = 0;
switch (mbedtls_pk_get_type(pk)) {
#if defined(MBEDTLS_RSA_C)
case MBEDTLS_PK_RSA:
{
if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
unsigned char *const key_end = key_buffer + sizeof(key_buffer);
key_data = key_end;
int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk),
key_buffer, &key_data);
if (ret < 0) {
return ret;
}
key_length = (size_t) ret;
break;
}
#endif /*MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
{
/* We need to check the curve family, otherwise the import could
* succeed with nonsensical data.
* We don't check the bit-size: it's optional in attributes,
* and if it's specified, psa_import_key() will know from the key
* data length and will check that the bit-size matches. */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
key_data = (unsigned char *) pk->pub_raw;
key_length = pk->pub_raw_len;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
size_t from_bits = 0;
psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
&from_bits);
if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
int ret = mbedtls_ecp_write_public_key(
ec, MBEDTLS_ECP_PF_UNCOMPRESSED,
&key_length, key_buffer, sizeof(key_buffer));
if (ret < 0) {
return ret;
}
key_data = key_buffer;
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
break;
}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
case MBEDTLS_PK_OPAQUE:
{
psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status =
psa_get_key_attributes(pk->priv_id, &old_attributes);
if (status != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_key_type_t old_type = psa_get_key_type(&old_attributes);
psa_reset_key_attributes(&old_attributes);
if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
status = psa_export_public_key(pk->priv_id,
key_buffer, sizeof(key_buffer),
&key_length);
if (status != PSA_SUCCESS) {
return PSA_PK_TO_MBEDTLS_ERR(status);
}
key_data = key_buffer;
break;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
default:
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
key_data, key_length,
key_id));
}
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key_id)
{
/* Set the output immediately so that it won't contain garbage even
* if we error out before calling psa_import_key(). */
*key_id = MBEDTLS_SVC_KEY_ID_INIT;
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) {
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
}
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes));
if (want_public) {
return import_public_into_psa(pk, attributes, key_id);
} else {
return import_pair_into_psa(pk, attributes, key_id);
}
}
#endif /* MBEDTLS_PSA_CRYPTO_C */
/*
* Helper for mbedtls_pk_sign and mbedtls_pk_verify
*/
@ -708,9 +1182,32 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
}
if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t psa_alg, psa_enrollment_alg, sign_alg;
psa_status_t status;
status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
status = psa_get_key_attributes(ctx->priv_id, &key_attr);
if (status != PSA_SUCCESS) {
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
}
psa_alg = psa_get_key_algorithm(&key_attr);
psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr);
psa_reset_key_attributes(&key_attr);
/* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between
* alg and enrollment alg should be of type RSA_PSS. */
if (PSA_ALG_IS_RSA_PSS(psa_alg)) {
sign_alg = psa_alg;
} else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) {
sign_alg = psa_enrollment_alg;
} else {
/* The opaque key has no RSA PSS algorithm associated. */
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* Adjust the hashing algorithm. */
sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg);
status = psa_sign_hash(ctx->priv_id, sign_alg,
hash, hash_len,
sig, sig_size, sig_len);
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
@ -877,124 +1374,4 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
return ctx->pk_info->type;
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* Load the key to a PSA key slot,
* then turn the PK context into a wrapper for that key slot.
*
* Currently only works for EC & RSA private keys.
*/
int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
mbedtls_svc_key_id_t *key,
psa_algorithm_t alg,
psa_key_usage_t usage,
psa_algorithm_t alg2)
{
#if !defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_RSA_C)
((void) pk);
((void) key);
((void) alg);
((void) usage);
((void) alg2);
#else /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
size_t d_len;
psa_ecc_family_t curve_id;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t key_type;
size_t bits;
psa_status_t status;
/* export the private key material in the format PSA wants */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
unsigned char d[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
status = psa_export_key(pk->priv_id, d, sizeof(d), &d_len);
if (status != PSA_SUCCESS) {
return psa_pk_status_to_mbedtls(status);
}
curve_id = pk->ec_family;
bits = pk->ec_bits;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
d_len = PSA_BITS_TO_BYTES(ec->grp.nbits);
if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) {
return ret;
}
curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
/* prepare the key attributes */
psa_set_key_type(&attributes, key_type);
psa_set_key_bits(&attributes, bits);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, alg);
if (alg2 != PSA_ALG_NONE) {
psa_set_key_enrollment_algorithm(&attributes, alg2);
}
/* import private key into PSA */
status = psa_import_key(&attributes, d, d_len, key);
mbedtls_platform_zeroize(d, sizeof(d));
if (status != PSA_SUCCESS) {
return PSA_PK_TO_MBEDTLS_ERR(status);
}
/* make PK context wrap the key slot */
mbedtls_pk_free(pk);
mbedtls_pk_init(pk);
return mbedtls_pk_setup_opaque(pk, *key);
} else
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_RSA_C)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) {
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
int key_len;
psa_status_t status;
/* export the private key material in the format PSA wants */
key_len = mbedtls_pk_write_key_der(pk, buf, sizeof(buf));
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* prepare the key attributes */
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
psa_set_key_bits(&attributes, mbedtls_pk_get_bitlen(pk));
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, alg);
if (alg2 != PSA_ALG_NONE) {
psa_set_key_enrollment_algorithm(&attributes, alg2);
}
/* import private key into PSA */
status = psa_import_key(&attributes,
buf + sizeof(buf) - key_len,
key_len, key);
mbedtls_platform_zeroize(buf, sizeof(buf));
if (status != PSA_SUCCESS) {
return PSA_PK_TO_MBEDTLS_ERR(status);
}
/* make PK context wrap the key slot */
mbedtls_pk_free(pk);
mbedtls_pk_init(pk);
return mbedtls_pk_setup_opaque(pk, *key);
} else
#endif /* MBEDTLS_RSA_C */
#endif /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_PK_C */

View File

@ -17,7 +17,7 @@
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include "psa/crypto.h"
#include "psa_util_internal.h"
@ -28,7 +28,7 @@
#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_pk_ecdsa_errors, \
psa_pk_status_to_mbedtls)
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
/* Headers/footers for PEM files */
#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----"
@ -144,4 +144,8 @@ MBEDTLS_STATIC_TESTABLE int mbedtls_pk_parse_key_pkcs8_encrypted_der(
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
#endif
#if defined(MBEDTLS_FS_IO)
int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n);
#endif
#endif /* MBEDTLS_PK_INTERNAL_H */

View File

@ -29,9 +29,11 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa_util_internal.h"
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_RSA_C)
#include "pkwrite.h"
#include "rsa_internal.h"
#endif
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
@ -56,7 +58,7 @@ static int rsa_can_do(mbedtls_pk_type_t type)
static size_t rsa_get_bitlen(mbedtls_pk_context *pk)
{
const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) pk->pk_ctx;
return 8 * mbedtls_rsa_get_len(rsa);
return mbedtls_rsa_get_bitlen(rsa);
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -69,11 +71,10 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_status_t status;
mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
psa_algorithm_t psa_alg_md =
PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
unsigned char *p = buf + sizeof(buf);
psa_algorithm_t psa_alg_md;
size_t rsa_len = mbedtls_rsa_get_len(rsa);
#if SIZE_MAX > UINT_MAX
@ -82,15 +83,17 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
}
#endif
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
psa_alg_md = PSA_ALG_RSA_PSS(mbedtls_md_psa_alg_from_type(md_alg));
} else {
psa_alg_md = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
}
if (sig_len < rsa_len) {
return MBEDTLS_ERR_RSA_VERIFY_FAILED;
}
/* mbedtls_pk_write_pubkey_der() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &mbedtls_rsa_info;
key.pk_ctx = rsa;
key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@ -172,14 +175,15 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_status_t status;
mbedtls_pk_context key;
int key_len;
unsigned char *buf = NULL;
unsigned char *p;
buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
if (buf == NULL) {
return MBEDTLS_ERR_PK_ALLOC_FAILED;
}
mbedtls_pk_info_t pk_info = mbedtls_rsa_info;
p = buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES;
*sig_len = mbedtls_rsa_get_len(rsa_ctx);
if (sig_size < *sig_len) {
@ -187,11 +191,7 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
}
/* mbedtls_pk_write_key_der() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &pk_info;
key.pk_ctx = rsa_ctx;
key_len = mbedtls_pk_write_key_der(&key, buf, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
key_len = mbedtls_rsa_write_key(rsa_ctx, buf, &p);
if (key_len <= 0) {
mbedtls_free(buf);
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@ -240,10 +240,14 @@ static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
if (psa_md_alg == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_algorithm_t psa_alg;
if (mbedtls_rsa_get_padding_mode(mbedtls_pk_rsa(*pk)) == MBEDTLS_RSA_PKCS_V21) {
psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
} else {
psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg);
}
return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PKCS1V15_SIGN(
psa_md_alg),
pk->pk_ctx, hash, hash_len,
return mbedtls_pk_psa_rsa_sign_ext(psa_alg, pk->pk_ctx, hash, hash_len,
sig, sig_size, sig_len);
}
#else /* MBEDTLS_USE_PSA_CRYPTO */
@ -281,36 +285,33 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_algorithm_t psa_md_alg, decrypt_alg;
psa_status_t status;
mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
unsigned char *p = buf + sizeof(buf);
((void) f_rng);
((void) p_rng);
#if !defined(MBEDTLS_RSA_ALT)
if (rsa->padding != MBEDTLS_RSA_PKCS_V15) {
return MBEDTLS_ERR_RSA_INVALID_PADDING;
}
#endif /* !MBEDTLS_RSA_ALT */
if (ilen != mbedtls_rsa_get_len(rsa)) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
/* mbedtls_pk_write_key_der() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &mbedtls_rsa_info;
key.pk_ctx = rsa;
key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf));
key_len = mbedtls_rsa_write_key(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
decrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
} else {
decrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
}
psa_set_key_algorithm(&attributes, decrypt_alg);
status = psa_import_key(&attributes,
buf + sizeof(buf) - key_len, key_len,
@ -320,7 +321,7 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
goto cleanup;
}
status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
status = psa_asymmetric_decrypt(key_id, decrypt_alg,
input, ilen,
NULL, 0,
output, osize, olen);
@ -367,35 +368,31 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_algorithm_t psa_md_alg;
psa_status_t status;
mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
unsigned char *p = buf + sizeof(buf);
((void) f_rng);
((void) p_rng);
#if !defined(MBEDTLS_RSA_ALT)
if (rsa->padding != MBEDTLS_RSA_PKCS_V15) {
return MBEDTLS_ERR_RSA_INVALID_PADDING;
}
#endif
if (mbedtls_rsa_get_len(rsa) > osize) {
return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
}
/* mbedtls_pk_write_pubkey_der() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &mbedtls_rsa_info;
key.pk_ctx = rsa;
key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_OAEP(psa_md_alg));
} else {
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
}
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
status = psa_import_key(&attributes,
@ -536,66 +533,6 @@ static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
* those integers and convert it to the fixed-length encoding expected by PSA.
*/
static int extract_ecdsa_sig_int(unsigned char **from, const unsigned char *end,
unsigned char *to, size_t to_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t unpadded_len, padding_len;
if ((ret = mbedtls_asn1_get_tag(from, end, &unpadded_len,
MBEDTLS_ASN1_INTEGER)) != 0) {
return ret;
}
while (unpadded_len > 0 && **from == 0x00) {
(*from)++;
unpadded_len--;
}
if (unpadded_len > to_len || unpadded_len == 0) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
padding_len = to_len - unpadded_len;
memset(to, 0x00, padding_len);
memcpy(to + padding_len, *from, unpadded_len);
(*from) += unpadded_len;
return 0;
}
/*
* Convert a signature from an ASN.1 sequence of two integers
* to a raw {r,s} buffer. Note: the provided sig buffer must be at least
* twice as big as int_size.
*/
static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end,
unsigned char *sig, size_t int_size)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t tmp_size;
if ((ret = mbedtls_asn1_get_tag(p, end, &tmp_size,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return ret;
}
/* Extract r */
if ((ret = extract_ecdsa_sig_int(p, end, sig, int_size)) != 0) {
return ret;
}
/* Extract s */
if ((ret = extract_ecdsa_sig_int(p, end, sig + int_size, int_size)) != 0) {
return ret;
}
return 0;
}
/* Common helper for ECDSA verify using PSA functions. */
static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
psa_ecc_family_t curve, size_t curve_bits,
@ -607,6 +544,7 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
size_t converted_sig_len;
unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
unsigned char *p;
psa_status_t status;
@ -631,11 +569,14 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
}
p = (unsigned char *) sig;
/* extract_ecdsa_sig's last parameter is the size
* of each integer to be parsed, so it's actually half
* the size of the signature. */
if ((ret = extract_ecdsa_sig(&p, sig + sig_len, extracted_sig,
signature_len/2)) != 0) {
ret = mbedtls_ecdsa_der_to_raw(curve_bits, p, sig_len, extracted_sig,
sizeof(extracted_sig), &converted_sig_len);
if (ret != 0) {
goto cleanup;
}
if (converted_sig_len != signature_len) {
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
goto cleanup;
}
@ -646,10 +587,6 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
goto cleanup;
}
if (p != sig + sig_len) {
ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
goto cleanup;
}
ret = 0;
cleanup:
@ -751,90 +688,6 @@ static int ecdsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* Simultaneously convert and move raw MPI from the beginning of a buffer
* to an ASN.1 MPI at the end of the buffer.
* See also mbedtls_asn1_write_mpi().
*
* p: pointer to the end of the output buffer
* start: start of the output buffer, and also of the mpi to write at the end
* n_len: length of the mpi to read from start
*/
static int asn1_write_mpibuf(unsigned char **p, unsigned char *start,
size_t n_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if ((size_t) (*p - start) < n_len) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
len = n_len;
*p -= len;
memmove(*p, start, len);
/* ASN.1 DER encoding requires minimal length, so skip leading 0s.
* Neither r nor s should be 0, but as a failsafe measure, still detect
* that rather than overflowing the buffer in case of a PSA error. */
while (len > 0 && **p == 0x00) {
++(*p);
--len;
}
/* this is only reached if the signature was invalid */
if (len == 0) {
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
}
/* if the msb is 1, ASN.1 requires that we prepend a 0.
* Neither r nor s can be 0, so we can assume len > 0 at all times. */
if (**p & 0x80) {
if (*p - start < 1) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
*--(*p) = 0x00;
len += 1;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
MBEDTLS_ASN1_INTEGER));
return (int) len;
}
/* Transcode signature from PSA format to ASN.1 sequence.
* See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
* MPIs, and in-place.
*
* [in/out] sig: the signature pre- and post-transcoding
* [in/out] sig_len: signature length pre- and post-transcoding
* [int] buf_len: the available size the in/out buffer
*/
static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len,
size_t buf_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
const size_t rs_len = *sig_len / 2;
unsigned char *p = sig + buf_len;
MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig + rs_len, rs_len));
MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig, rs_len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, sig, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, sig,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
memmove(sig, p, len);
*sig_len = len;
return 0;
}
/* Common helper for ECDSA sign using PSA functions.
* Instead of extracting key's properties in order to check which kind of ECDSA
* signature it supports, we try both deterministic and non-deterministic.
@ -845,6 +698,15 @@ static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
size_t key_bits = 0;
status = psa_get_key_attributes(key_id, &key_attr);
if (status != PSA_SUCCESS) {
return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
}
key_bits = psa_get_key_bits(&key_attr);
psa_reset_key_attributes(&key_attr);
status = psa_sign_hash(key_id,
PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
@ -863,7 +725,7 @@ static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
}
done:
ret = pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size);
ret = mbedtls_ecdsa_raw_to_der(key_bits, sig, *sig_len, sig, sig_size, sig_len);
return ret;
}

View File

@ -7,7 +7,7 @@
#include "mbedtls/build_info.h"
#if defined(MBEDTLS_PKCS7_C)
#include "mbedtls/pkcs7.h"
#include "mbedtls/x509.h"
#include "x509_internal.h"
#include "mbedtls/asn1.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/x509_crl.h"

View File

@ -28,6 +28,7 @@
/* Key types */
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#include "rsa_internal.h"
#endif
/* Extended formats */
@ -757,68 +758,6 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
static int pk_get_rsapubkey(unsigned char **p,
const unsigned char *end,
mbedtls_rsa_context *rsa)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
}
if (*p + len != end) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
/* Import N */
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
}
if ((ret = mbedtls_rsa_import_raw(rsa, *p, len, NULL, 0, NULL, 0,
NULL, 0, NULL, 0)) != 0) {
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
}
*p += len;
/* Import E */
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
}
if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, *p, len)) != 0) {
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
}
*p += len;
if (mbedtls_rsa_complete(rsa) != 0 ||
mbedtls_rsa_check_pubkey(rsa) != 0) {
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
}
if (*p != end) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
return 0;
}
#endif /* MBEDTLS_RSA_C */
/* Get a PK algorithm identifier
*
* AlgorithmIdentifier ::= SEQUENCE {
@ -911,7 +850,17 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
#if defined(MBEDTLS_RSA_C)
if (pk_alg == MBEDTLS_PK_RSA) {
ret = pk_get_rsapubkey(p, end, mbedtls_pk_rsa(*pk));
ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), *p, (size_t) (end - *p));
if (ret == 0) {
/* On success all the input has been consumed by the parsing function. */
*p += end - *p;
} else if ((ret <= MBEDTLS_ERR_ASN1_OUT_OF_DATA) &&
(ret >= MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)) {
/* In case of ASN1 error codes add MBEDTLS_ERR_PK_INVALID_PUBKEY. */
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
} else {
ret = MBEDTLS_ERR_PK_INVALID_PUBKEY;
}
} else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
@ -944,195 +893,6 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
return ret;
}
#if defined(MBEDTLS_RSA_C)
/*
* Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
*
* The value zero is:
* - never a valid value for an RSA parameter
* - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
*
* Since values can't be omitted in PKCS#1, passing a zero value to
* rsa_complete() would be incorrect, so reject zero values early.
*/
static int asn1_get_nonzero_mpi(unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X)
{
int ret;
ret = mbedtls_asn1_get_mpi(p, end, X);
if (ret != 0) {
return ret;
}
if (mbedtls_mpi_cmp_int(X, 0) == 0) {
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
return 0;
}
/*
* Parse a PKCS#1 encoded private RSA key
*/
static int pk_parse_key_pkcs1_der(mbedtls_rsa_context *rsa,
const unsigned char *key,
size_t keylen)
{
int ret, version;
size_t len;
unsigned char *p, *end;
mbedtls_mpi T;
mbedtls_mpi_init(&T);
p = (unsigned char *) key;
end = p + keylen;
/*
* This function parses the RSAPrivateKey (PKCS#1)
*
* RSAPrivateKey ::= SEQUENCE {
* version Version,
* modulus INTEGER, -- n
* publicExponent INTEGER, -- e
* privateExponent INTEGER, -- d
* prime1 INTEGER, -- p
* prime2 INTEGER, -- q
* exponent1 INTEGER, -- d mod (p-1)
* exponent2 INTEGER, -- d mod (q-1)
* coefficient INTEGER, -- (inverse of q) mod p
* otherPrimeInfos OtherPrimeInfos OPTIONAL
* }
*/
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
end = p + len;
if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
if (version != 0) {
return MBEDTLS_ERR_PK_KEY_INVALID_VERSION;
}
/* Import N */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, &T, NULL, NULL,
NULL, NULL)) != 0) {
goto cleanup;
}
/* Import E */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
NULL, &T)) != 0) {
goto cleanup;
}
/* Import D */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
&T, NULL)) != 0) {
goto cleanup;
}
/* Import P */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, &T, NULL,
NULL, NULL)) != 0) {
goto cleanup;
}
/* Import Q */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, &T,
NULL, NULL)) != 0) {
goto cleanup;
}
#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
/*
* The RSA CRT parameters DP, DQ and QP are nominally redundant, in
* that they can be easily recomputed from D, P and Q. However by
* parsing them from the PKCS1 structure it is possible to avoid
* recalculating them which both reduces the overhead of loading
* RSA private keys into memory and also avoids side channels which
* can arise when computing those values, since all of D, P, and Q
* are secret. See https://eprint.iacr.org/2020/055 for a
* description of one such attack.
*/
/* Import DP */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) {
goto cleanup;
}
/* Import DQ */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) {
goto cleanup;
}
/* Import QP */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) {
goto cleanup;
}
#else
/* Verify existence of the CRT params */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) {
goto cleanup;
}
#endif
/* rsa_complete() doesn't complete anything with the default
* implementation but is still called:
* - for the benefit of alternative implementation that may want to
* pre-compute stuff beyond what's provided (eg Montgomery factors)
* - as is also sanity-checks the key
*
* Furthermore, we also check the public part for consistency with
* mbedtls_pk_parse_pubkey(), as it includes size minima for example.
*/
if ((ret = mbedtls_rsa_complete(rsa)) != 0 ||
(ret = mbedtls_rsa_check_pubkey(rsa)) != 0) {
goto cleanup;
}
if (p != end) {
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
cleanup:
mbedtls_mpi_free(&T);
if (ret != 0) {
/* Wrap error code if it's coming from a lower level */
if ((ret & 0xff80) == 0) {
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
} else {
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
mbedtls_rsa_free(rsa);
}
return ret;
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
/*
* Parse a SEC1 encoded private EC key
@ -1348,7 +1108,7 @@ static int pk_parse_key_pkcs8_unencrypted_der(
#if defined(MBEDTLS_RSA_C)
if (pk_alg == MBEDTLS_PK_RSA) {
if ((ret = pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), p, len)) != 0) {
if ((ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), p, len)) != 0) {
mbedtls_pk_free(pk);
return ret;
}
@ -1538,8 +1298,8 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
if (ret == 0) {
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 ||
(ret = pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk),
pem.buf, pem.buflen)) != 0) {
(ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk),
pem.buf, pem.buflen)) != 0) {
mbedtls_pk_free(pk);
}
@ -1679,7 +1439,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
if (mbedtls_pk_setup(pk, pk_info) == 0 &&
pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), key, keylen) == 0) {
mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), key, keylen) == 0) {
return 0;
}
@ -1754,7 +1514,7 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
return ret;
}
if ((ret = pk_get_rsapubkey(&p, p + pem.buflen, mbedtls_pk_rsa(*ctx))) != 0) {
if ((ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, pem.buflen)) != 0) {
mbedtls_pk_free(ctx);
}
@ -1801,13 +1561,12 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
}
p = (unsigned char *) key;
ret = pk_get_rsapubkey(&p, p + keylen, mbedtls_pk_rsa(*ctx));
ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, keylen);
if (ret == 0) {
return ret;
}
mbedtls_pk_free(ctx);
if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG))) {
if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
return ret;
}
#endif /* MBEDTLS_RSA_C */

View File

@ -32,6 +32,9 @@
#if defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
#endif
#if defined(MBEDTLS_RSA_C)
#include "rsa_internal.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
@ -56,60 +59,13 @@
* Internal functions for RSA keys.
******************************************************************************/
#if defined(MBEDTLS_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
static int pk_write_rsa_pubkey(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_mpi T;
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
mbedtls_mpi_init(&T);
/* Export E */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export N */
if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
end_of_export:
mbedtls_mpi_free(&T);
if (ret < 0) {
return ret;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
return (int) len;
}
static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
const mbedtls_pk_context *pk)
{
size_t len = 0;
int ret;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
size_t tmp_len = 0;
size_t len = 0, tmp_len = 0;
if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@ -118,94 +74,11 @@ static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
memcpy(*p, tmp, tmp_len);
len += tmp_len;
mbedtls_platform_zeroize(tmp, sizeof(tmp));
} else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
mbedtls_mpi T; /* Temporary holding the exported parameters */
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
/*
* Export the parameters one after another to avoid simultaneous copies.
*/
mbedtls_mpi_init(&T);
/* Export QP */
if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export DQ */
if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export DP */
if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export Q */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
&T, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export P */
if ((ret = mbedtls_rsa_export(rsa, NULL, &T,
NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export D */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
NULL, &T, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export E */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export N */
if ((ret = mbedtls_rsa_export(rsa, &T, NULL,
NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
end_of_export:
mbedtls_mpi_free(&T);
if (ret < 0) {
return ret;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p,
buf, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
return (int) len;
}
return (int) len;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), buf, p);
}
#endif /* MBEDTLS_RSA_C */
@ -329,7 +202,7 @@ static int pk_write_ec_private(unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
byte_length = (ec->grp.pbits + 7) / 8;
ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
ret = mbedtls_ecp_write_key_ext(ec, &byte_length, tmp, sizeof(tmp));
if (ret != 0) {
goto exit;
}
@ -543,7 +416,7 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
#if defined(MBEDTLS_RSA_C)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, key));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*key), start, p));
} else
#endif
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)

View File

@ -93,8 +93,6 @@ static void *(*const volatile memset_func)(void *, int, size_t) = memset;
void mbedtls_platform_zeroize(void *buf, size_t len)
{
MBEDTLS_INTERNAL_VALIDATE(len == 0 || buf != NULL);
if (len > 0) {
#if defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO)
explicit_bzero(buf, len);
@ -151,10 +149,10 @@ void mbedtls_zeroize_and_free(void *buf, size_t len)
#include <time.h>
#if !defined(_WIN32) && (defined(unix) || \
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
defined(__MACH__)))
defined(__MACH__)) || defined__midipix__)
#include <unistd.h>
#endif /* !_WIN32 && (unix || __unix || __unix__ ||
* (__APPLE__ && __MACH__)) */
* (__APPLE__ && __MACH__) || __midipix__) */
#if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \
(defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
@ -222,9 +220,10 @@ void (*mbedtls_test_hook_test_fail)(const char *, int, const char *);
#include <time.h>
#if !defined(_WIN32) && \
(defined(unix) || defined(__unix) || defined(__unix__) || \
(defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__))
(defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) || defined(__midipix__))
#include <unistd.h>
#endif /* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__) */
#endif \
/* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__ || __midipix__) */
#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 199309L) || defined(__HAIKU__)
mbedtls_ms_time_t mbedtls_ms_time(void)
{
@ -232,7 +231,7 @@ mbedtls_ms_time_t mbedtls_ms_time(void)
struct timespec tv;
mbedtls_ms_time_t current_ms;
#if defined(__linux__) && defined(CLOCK_BOOTTIME)
#if defined(__linux__) && defined(CLOCK_BOOTTIME) || defined(__midipix__)
ret = clock_gettime(CLOCK_BOOTTIME, &tv);
#else
ret = clock_gettime(CLOCK_MONOTONIC, &tv);

File diff suppressed because it is too large Load Diff

View File

@ -33,10 +33,10 @@ static psa_status_t psa_aead_setup(
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_cipher_id_t cipher_id;
mbedtls_cipher_mode_t mode;
size_t key_bits = attributes->core.bits;
size_t key_bits = attributes->bits;
(void) key_buffer_size;
status = mbedtls_cipher_values_from_psa(alg, attributes->core.type,
status = mbedtls_cipher_values_from_psa(alg, attributes->type,
&key_bits, &mode, &cipher_id);
if (status != PSA_SUCCESS) {
return status;
@ -49,7 +49,7 @@ static psa_status_t psa_aead_setup(
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
* The call to mbedtls_ccm_encrypt_and_tag or
* mbedtls_ccm_auth_decrypt will validate the tag length. */
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
@ -69,7 +69,7 @@ static psa_status_t psa_aead_setup(
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
* The call to mbedtls_gcm_crypt_and_tag or
* mbedtls_gcm_auth_decrypt will validate the tag length. */
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}

View File

@ -289,14 +289,14 @@ static psa_status_t psa_cipher_setup(
int ret = 0;
size_t key_bits;
const mbedtls_cipher_info_t *cipher_info = NULL;
psa_key_type_t key_type = attributes->core.type;
psa_key_type_t key_type = attributes->type;
(void) key_buffer_size;
mbedtls_cipher_init(&operation->ctx.cipher);
operation->alg = alg;
key_bits = attributes->core.bits;
key_bits = attributes->bits;
cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
key_bits, NULL);
if (cipher_info == NULL) {

View File

@ -16,57 +16,7 @@
void psa_reset_key_attributes(psa_key_attributes_t *attributes)
{
mbedtls_free(attributes->domain_parameters);
memset(attributes, 0, sizeof(*attributes));
}
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
psa_key_type_t type,
const uint8_t *data,
size_t data_length)
{
uint8_t *copy = NULL;
if (data_length != 0) {
copy = mbedtls_calloc(1, data_length);
if (copy == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
memcpy(copy, data, data_length);
}
/* After this point, this function is guaranteed to succeed, so it
* can start modifying `*attributes`. */
if (attributes->domain_parameters != NULL) {
mbedtls_free(attributes->domain_parameters);
attributes->domain_parameters = NULL;
attributes->domain_parameters_size = 0;
}
attributes->domain_parameters = copy;
attributes->domain_parameters_size = data_length;
attributes->core.type = type;
return PSA_SUCCESS;
}
psa_status_t psa_get_key_domain_parameters(
const psa_key_attributes_t *attributes,
uint8_t *data, size_t data_size, size_t *data_length)
{
if (attributes->domain_parameters == NULL &&
attributes->domain_parameters_size == SIZE_MAX) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (attributes->domain_parameters_size > data_size) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
*data_length = attributes->domain_parameters_size;
if (attributes->domain_parameters_size != 0) {
memcpy(data, attributes->domain_parameters,
attributes->domain_parameters_size);
}
return PSA_SUCCESS;
}
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */

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