Merge remote-tracking branch 'development' into pk_import_into_psa-use_usage

This commit is contained in:
Gilles Peskine 2024-02-06 10:14:17 +01:00
commit 8a85673a39
121 changed files with 3893 additions and 1305 deletions

View file

@ -106,6 +106,6 @@ The following branches are currently maintained:
- [`development`](https://github.com/Mbed-TLS/mbedtls/)
- [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28)
maintained until at least the end of 2024, see
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.6>.
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.7>.
Users are urged to always use the latest version of a maintained branch.

View file

@ -381,7 +381,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
write_basic_package_version_file(
"cmake/MbedTLSConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
VERSION 3.5.1)
VERSION 3.5.2)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"

View file

@ -1,5 +1,20 @@
Mbed TLS ChangeLog (Sorted per branch, date)
= Mbed TLS 3.5.2 branch released 2024-01-26
Security
* Fix a timing side channel in private key RSA operations. This side channel
could be sufficient for an attacker to recover the plaintext. A local
attacker or a remote attacker who is close to the victim on the network
might have precise enough timing measurements to exploit this. It requires
the attacker to send a large number of messages for decryption. For
details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. Reported
by Hubert Kario, Red Hat.
* Fix a failure to validate input when writing x509 extensions lengths which
could result in an integer overflow, causing a zero-length buffer to be
allocated to hold the extension. The extension would then be copied into
the buffer, causing a heap buffer overflow.
= Mbed TLS 3.5.1 branch released 2023-11-06
Changes

3
ChangeLog.d/7764.txt Normal file
View file

@ -0,0 +1,3 @@
Features
* Add functions mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa()
to convert between Mbed TLS and PSA curve identifiers.

4
ChangeLog.d/8340.txt Normal file
View file

@ -0,0 +1,4 @@
Features
* Add functions mbedtls_md_psa_alg_from_type() and
mbedtls_md_type_from_psa_alg() to convert between mbedtls_md_type_t and
psa_algorithm_t.

4
ChangeLog.d/8461.txt Normal file
View file

@ -0,0 +1,4 @@
Bugfix
* Fix unsupported PSA asymmetric encryption and decryption
(psa_asymmetric_[en|de]crypt) with opaque keys.
Resolves #8461.

2
ChangeLog.d/8726.txt Normal file
View file

@ -0,0 +1,2 @@
Features
* Add partial platform support for z/OS.

3
ChangeLog.d/ctr-perf.txt Normal file
View file

@ -0,0 +1,3 @@
Features
* Improve performance of AES-GCM, AES-CTR and CTR-DRBG when
hardware accelerated AES is not present (around 13-23% on 64-bit Arm).

View file

@ -0,0 +1,5 @@
Features
* Add utility functions to manipulate mbedtls_ecp_keypair objects, filling
gaps made by making its fields private: mbedtls_ecp_set_public_key(),
mbedtls_ecp_write_public_key(), mbedtls_ecp_keypair_calc_public(),
mbedtls_ecp_keypair_get_group_id(). Fixes #5017, #5441, #8367, #8652.

View file

@ -0,0 +1,2 @@
Features
* Improve performance for gcc (versions older than 9.3.0) and IAR.

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,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(const unsigned char *raw, size_t raw_len,
unsigned char *der, size_t der_size, size_t *der_len,
size_t bits);
int mbedtls_ecdsa_der_to_raw(const unsigned char *der, size_t der_len,
unsigned char *raw, size_t raw_size, size_t *raw_len,
size_t bits);
```
* 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 not needed in the raw-to-DER direction, but [it can help catch errors](https://github.com/Mbed-TLS/mbedtls/pull/8681#discussion_r1445980971) and 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

@ -443,6 +443,10 @@ The equivalent to `mbedtls_md_type_t` and `MBEDTLS_MD_XXX` constants is the type
| `MBEDTLS_MD_SHA3_384` | `PSA_ALG_SHA3_384` |
| `MBEDTLS_MD_SHA3_512` | `PSA_ALG_SHA3_512` |
The following helper functions can be used to convert between the 2 types:
- `mbedtls_md_psa_alg_from_type()` converts from legacy `mbedtls_md_type_t` to PSA's `psa_algorithm_t`.
- `mbedtls_md_type_from_psa_alg()` converts from PSA's `psa_algorithm_t` to legacy `mbedtls_md_type_t`.
### MAC mechanism selection
PSA Crypto has a generic API with the same functions for all MAC mechanisms. The mechanism is determined by a combination of an algorithm value of type [`psa_algorithm_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2e4d47f1300d73c2f829a6d99252d69) and a key type value of type [`psa_key_type_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga63fce6880ca5933b5d6baa257febf1f6).
@ -725,7 +729,11 @@ An ECC public key has the type [`PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)`](https://mb
An ECC key pair has the type [`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0b6f5d4d5037c54ffa850d8059c32df0) where `curve` is a curve family identifier. A key with this type can be used both for private-key and public-key operations (there is no separate key type for a private key without the corresponding public key).
You can always use a private key for operations on the corresponding public key (as long as the policy permits it).
A curve is fully determined by a curve family identifier and the private key size in bits. The following table gives the correspondence between legacy and PSA elliptic curve designations.
A curve is fully determined by a curve family identifier and the private key size in bits. You can use the following functions to convert between the PSA and legacy elliptic curve designations:
- [`mbedtls_ecc_group_to_psa()`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__psa__tls__helpers/#group__psa__tls__helpers_1ga9c83c095adfec7da99401cf81e164f99) converts from the legacy curve type identifier to PSA curve family and bit-size.
- [`mbedtls_ecc_group_from_psa()`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__psa__tls__helpers/#group__psa__tls__helpers_1ga6243eb619d5b2f5fe4667811adeb8a12) converts from PSA curve family and bit-size to the legacy identifier.
The following table gives the correspondence between legacy and PSA elliptic curve designations.
| Mbed TLS legacy curve identifier | PSA curve family | Curve bit-size |
| -------------------------------- | ---------------- | -------------- |

View file

@ -7,5 +7,5 @@
# expose it.
- type: exact
from_url: /projects/api/en/latest/$rest
to_url: /projects/api/en/development/
from_url: /projects/api/en/latest/*
to_url: /projects/api/en/development/:splat

View file

@ -10,7 +10,7 @@
*/
/**
* @mainpage Mbed TLS v3.5.1 API Documentation
* @mainpage Mbed TLS v3.5.2 API Documentation
*
* This documentation describes the internal structure of Mbed TLS. It was
* automatically generated from specially formatted comment blocks in

View file

@ -1,4 +1,4 @@
PROJECT_NAME = "Mbed TLS v3.5.1"
PROJECT_NAME = "Mbed TLS v3.5.2"
OUTPUT_DIRECTORY = ../apidoc/
FULL_PATH_NAMES = NO
OPTIMIZE_OUTPUT_FOR_C = YES

View file

@ -26,16 +26,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 3
#define MBEDTLS_VERSION_MINOR 5
#define MBEDTLS_VERSION_PATCH 1
#define MBEDTLS_VERSION_PATCH 2
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define MBEDTLS_VERSION_NUMBER 0x03050100
#define MBEDTLS_VERSION_STRING "3.5.1"
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.5.1"
#define MBEDTLS_VERSION_NUMBER 0x03050200
#define MBEDTLS_VERSION_STRING "3.5.2"
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.5.2"
/* Macros for build-time platform detection */
@ -83,6 +83,14 @@
#endif
#endif
#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \
&& !defined(__llvm__) && !defined(__INTEL_COMPILER)
/* Defined if the compiler really is gcc and not clang, etc */
#define MBEDTLS_COMPILER_IS_GCC
#define MBEDTLS_GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1
#endif

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

@ -1259,9 +1259,56 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng);
/** \brief Set the public key in a key pair object.
*
* \note This function does not check that the point actually
* belongs to the given group. Call mbedtls_ecp_check_pubkey()
* on \p Q before calling this function to check that.
*
* \note This function does not check that the public key matches
* the private key that is already in \p key, if any.
* To check the consistency of the resulting key pair object,
* call mbedtls_ecp_check_pub_priv() after setting both
* the public key and the private key.
*
* \param grp_id The ECP group identifier.
* \param key The key pair object. It must be initialized.
* If its group has already been set, it must match \p grp_id.
* If its group has not been set, it will be set to \p grp_id.
* If the public key has already been set, it is overwritten.
* \param Q The public key to copy. This must be a point on the
* curve indicated by \p grp_id.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p key does not
* match \p grp_id.
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
* the group is not implemented.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,
mbedtls_ecp_keypair *key,
const mbedtls_ecp_point *Q);
/**
* \brief This function reads an elliptic curve private key.
*
* \note This function does not set the public key in the
* key pair object. Without a public key, the key pair object
* cannot be used with operations that require the public key.
* Call mbedtls_ecp_keypair_calc_public() to set the public
* key from the private key. Alternatively, you can call
* mbedtls_ecp_set_public_key() to set the public key part,
* and then optionally mbedtls_ecp_check_pub_priv() to check
* that the private and public parts are consistent.
*
* \note If a public key has already been set in the key pair
* object, this function does not check that it is consistent
* with the private key. Call mbedtls_ecp_check_pub_priv()
* after setting both the public key and the private key
* to make that check.
*
* \param grp_id The ECP group identifier.
* \param key The destination key.
* \param buf The buffer containing the binary representation of the
@ -1299,6 +1346,32 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen);
/**
* \brief This function exports an elliptic curve public key.
*
* \param key The public key.
* \param format The point format. This must be either
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
* (For groups without these formats, this parameter is
* ignored. But it still has to be either of the above
* values.)
* \param olen The address at which to store the length of
* the output in Bytes. This must not be \c NULL.
* \param buf The output buffer. This must be a writable buffer
* of length \p buflen Bytes.
* \param buflen The length of the output buffer \p buf in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
* is too small to hold the point.
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
* or the export for the given group is not implemented.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key,
int format, size_t *olen,
unsigned char *buf, size_t buflen);
/**
* \brief This function checks that the keypair objects
* \p pub and \p prv have the same group and the
@ -1323,16 +1396,48 @@ int mbedtls_ecp_check_pub_priv(
const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
/** \brief Calculate the public key from a private key in a key pair.
*
* \param key A keypair structure. It must have a private key set.
* If the public key is set, it will be overwritten.
* \param f_rng The RNG function. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c
* NULL if \p f_rng doesn't need a context.
*
* \return \c 0 on success. The key pair object can be used for
* operations that require the public key.
* \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX
* error code on calculation failure.
*/
int mbedtls_ecp_keypair_calc_public(
mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
/** \brief Query the group that a key pair belongs to.
*
* \param key The key pair to query.
*
* \return The group ID for the group registered in the key pair
* object.
* This is \c MBEDTLS_ECP_DP_NONE if no group has been set
* in the key pair object.
*/
mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id(
const mbedtls_ecp_keypair *key);
/**
* \brief This function exports generic key-pair parameters.
*
* Each of the output parameters can be a null pointer
* if you do not need that parameter.
*
* \param key The key pair to export from.
* \param grp Slot for exported ECP group.
* It must point to an initialized ECP group.
* It must either be null or point to an initialized ECP group.
* \param d Slot for the exported secret value.
* It must point to an initialized mpi.
* It must either be null or point to an initialized mpi.
* \param Q Slot for the exported public value.
* It must point to an initialized ECP point.
* It must either be null or point to an initialized ECP point.
*
* \return \c 0 on success,
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.

View file

@ -1159,14 +1159,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.

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

@ -109,45 +109,73 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
#include <mbedtls/ecp.h>
/** Convert an ECC curve identifier from the Mbed TLS encoding to PSA.
*
* \note This function is provided solely for the convenience of
* Mbed TLS and may be removed at any time without notice.
*
* \param grpid An Mbed TLS elliptic curve identifier
* (`MBEDTLS_ECP_DP_xxx`).
* \param[out] bits On success, the bit size of the curve.
* \param[out] bits On success the bit size of the curve; 0 on failure.
*
* \return The corresponding PSA elliptic curve identifier
* (`PSA_ECC_FAMILY_xxx`).
* \return \c 0 on failure (\p grpid is not recognized).
* \return If the curve is supported in the PSA API, this function
* returns the proper PSA curve identifier
* (`PSA_ECC_FAMILY_xxx`). This holds even if the curve is
* not supported by the ECP module.
* \return \c 0 if the curve is not supported in the PSA API.
*/
psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
size_t *bits);
/** Convert an ECC curve identifier from the PSA encoding to Mbed TLS.
*
* \note This function is provided solely for the convenience of
* Mbed TLS and may be removed at any time without notice.
*
* \param curve A PSA elliptic curve identifier
* \param family A PSA elliptic curve family identifier
* (`PSA_ECC_FAMILY_xxx`).
* \param bits The bit-length of a private key on \p curve.
* \param bits_is_sloppy If true, \p bits may be the bit-length rounded up
* to the nearest multiple of 8. This allows the caller
* to infer the exact curve from the length of a key
* which is supplied as a byte string.
*
* \return The corresponding Mbed TLS elliptic curve identifier
* (`MBEDTLS_ECP_DP_xxx`).
* \return #MBEDTLS_ECP_DP_NONE if \c curve is not recognized.
* \return #MBEDTLS_ECP_DP_NONE if \p bits is not
* correct for \p curve.
* \return If the curve is supported in the PSA API, this function
* returns the corresponding Mbed TLS elliptic curve
* identifier (`MBEDTLS_ECP_DP_xxx`).
* \return #MBEDTLS_ECP_DP_NONE if the combination of \c curve
* and \p bits is not supported.
*/
mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
size_t bits,
int bits_is_sloppy);
mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
size_t bits);
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
/**
* \brief This function returns the PSA algorithm identifier
* associated with the given digest type.
*
* \param md_type The type of digest to search for. Must not be NONE.
*
* \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will
* not return \c PSA_ALG_NONE, but an invalid algorithm.
*
* \warning This function does not check if the algorithm is
* supported, it always returns the corresponding identifier.
*
* \return The PSA algorithm identifier associated with \p md_type,
* regardless of whether it is supported or not.
*/
static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type)
{
return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type;
}
/**
* \brief This function returns the given digest type
* associated with the PSA algorithm identifier.
*
* \param psa_alg The PSA algorithm identifier to search for.
*
* \warning This function does not check if the algorithm is
* supported, it always returns the corresponding identifier.
*
* \return The MD type associated with \p psa_alg,
* regardless of whether it is supported or not.
*/
static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg)
{
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
}
/**@}*/
#endif /* MBEDTLS_PSA_CRYPTO_C */

View file

@ -684,6 +684,10 @@ int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
* It is the generic wrapper for performing a PKCS#1 decryption
* operation.
*
* \warning When \p ctx->padding is set to #MBEDTLS_RSA_PKCS_V15,
* mbedtls_rsa_rsaes_pkcs1_v15_decrypt() is called, which is an
* inherently dangerous function (CWE-242).
*
* \note The output buffer length \c output_max_len should be
* as large as the size \p ctx->len of \p ctx->N (for example,
* 128 Bytes if RSA-1024 is used) to be able to hold an
@ -720,6 +724,11 @@ int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx,
* \brief This function performs a PKCS#1 v1.5 decryption
* operation (RSAES-PKCS1-v1_5-DECRYPT).
*
* \warning This is an inherently dangerous function (CWE-242). Unless
* it is used in a side channel free and safe way (eg.
* implementing the TLS protocol as per 7.4.7.1 of RFC 5246),
* the calling code is vulnerable.
*
* \note The output buffer length \c output_max_len should be
* as large as the size \p ctx->len of \p ctx->N, for example,
* 128 Bytes if RSA-1024 is used, to be able to hold an

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 */
@ -1644,6 +1654,18 @@ struct mbedtls_ssl_context {
*/
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.
* See the documentation of mbedtls_ssl_get_early_data_status() for more
* information.
*
* Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT when the context is
* reset.
*/
int MBEDTLS_PRIVATE(early_data_status);
#endif
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@ -1841,10 +1863,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 +2011,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 +2019,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 +2076,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)
/**
@ -4733,6 +4761,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 +4776,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 +4846,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 +4916,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 +4931,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 +4998,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 +5012,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
@ -5029,48 +5082,46 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
#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);

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

@ -100,6 +100,20 @@ extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
#if defined(MBEDTLS_PSA_CRYPTO_C)
/*
* A mutex used to make the PSA subsystem thread safe.
*
* key_slot_mutex protects the registered_readers and
* state variable for all key slots in &global_data.key_slots.
*
* This mutex must be held when any read from or write to a state or
* registered_readers field is performed, i.e. when calling functions:
* psa_key_slot_state_transition(), psa_register_read(), psa_unregister_read(),
* psa_key_slot_has_readers() and psa_wipe_key_slot(). */
extern mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex;
#endif
#endif /* MBEDTLS_THREADING_C */
#ifdef __cplusplus

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,201 +322,7 @@ mbedtls_x509_san_list;
*/
int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn);
/**
* \brief Return the next relative DN in an X509 name.
*
* \note Intended use is to compare function result to dn->next
* in order to detect boundaries of multi-valued RDNs.
*
* \param dn Current node in the X509 name
*
* \return Pointer to the first attribute-value pair of the
* next RDN in sequence, or NULL if end is reached.
*/
static inline mbedtls_x509_name *mbedtls_x509_dn_get_next(
mbedtls_x509_name *dn)
{
while (dn->MBEDTLS_PRIVATE(next_merged) && dn->next != NULL) {
dn = dn->next;
}
return dn->next;
}
/**
* \brief Store the certificate serial in printable form into buf;
* no more than size characters will be written.
*
* \param buf Buffer to write to
* \param size Maximum size of buffer
* \param serial The X509 serial to represent
*
* \return The length of the string written (not including the
* terminated nul byte), or a negative error code.
*/
int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial);
/**
* \brief Compare pair of mbedtls_x509_time.
*
* \param t1 mbedtls_x509_time to compare
* \param t2 mbedtls_x509_time to compare
*
* \return < 0 if t1 is before t2
* 0 if t1 equals t2
* > 0 if t1 is after t2
*/
int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1, const mbedtls_x509_time *t2);
#if defined(MBEDTLS_HAVE_TIME_DATE)
/**
* \brief Fill mbedtls_x509_time with provided mbedtls_time_t.
*
* \param tt mbedtls_time_t to convert
* \param now mbedtls_x509_time to fill with converted mbedtls_time_t
*
* \return \c 0 on success
* \return A non-zero return value on failure.
*/
int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now);
#endif /* MBEDTLS_HAVE_TIME_DATE */
/**
* \brief Check a given mbedtls_x509_time against the system time
* and tell if it's in the past.
*
* \note Intended usage is "if( is_past( valid_to ) ) ERROR".
* Hence the return value of 1 if on internal errors.
*
* \param to mbedtls_x509_time to check
*
* \return 1 if the given time is in the past or an error occurred,
* 0 otherwise.
*/
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to);
/**
* \brief Check a given mbedtls_x509_time against the system time
* and tell if it's in the future.
*
* \note Intended usage is "if( is_future( valid_from ) ) ERROR".
* Hence the return value of 1 if on internal errors.
*
* \param from mbedtls_x509_time to check
*
* \return 1 if the given time is in the future or an error occurred,
* 0 otherwise.
*/
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
/**
* \brief This function parses an item in the SubjectAlternativeNames
* extension. Please note that this function might allocate
* additional memory for a subject alternative name, thus
* mbedtls_x509_free_subject_alt_name has to be called
* to dispose of this additional memory afterwards.
*
* \param san_buf The buffer holding the raw data item of the subject
* alternative name.
* \param san The target structure to populate with the parsed presentation
* of the subject alternative name encoded in \p san_buf.
*
* \note Supported GeneralName types, as defined in RFC 5280:
* "rfc822Name", "dnsName", "directoryName",
* "uniformResourceIdentifier" and "hardware_module_name"
* of type "otherName", as defined in RFC 4108.
*
* \note This function should be called on a single raw data of
* subject alternative name. For example, after successful
* certificate parsing, one must iterate on every item in the
* \c crt->subject_alt_names sequence, and pass it to
* this function.
*
* \warning The target structure contains pointers to the raw data of the
* parsed certificate, and its lifetime is restricted by the
* lifetime of the certificate.
*
* \return \c 0 on success
* \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
* SAN type.
* \return Another negative value for any other failure.
*/
int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
mbedtls_x509_subject_alternative_name *san);
/**
* \brief Unallocate all data related to subject alternative name
*
* \param san SAN structure - extra memory owned by this structure will be freed
*/
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 +354,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

@ -279,6 +279,11 @@
* to read from a resource. */
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
/** This can be returned if a function can no longer operate correctly.
* For example, if an essential initialization operation failed or
* a mutex operation failed. */
#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144)
/** The key identifier is not valid. See also :ref:\`key-handles\`.
*/
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
@ -1751,6 +1756,13 @@
0)
/** RSA PKCS#1 v1.5 encryption.
*
* \warning Calling psa_asymmetric_decrypt() with this algorithm as a
* parameter is considered an inherently dangerous function
* (CWE-242). Unless it is used in a side channel free and safe
* way (eg. implementing the TLS protocol as per 7.4.7.1 of
* RFC 5246), the calling code is vulnerable.
*
*/
#define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t) 0x07000200)

View file

@ -297,7 +297,7 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
add_library(${mbedcrypto_target} SHARED ${src_crypto})
set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.5.1 SOVERSION 15)
set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.5.2 SOVERSION 15)
target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
if(TARGET ${everest_target})
@ -309,11 +309,11 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
endif()
add_library(${mbedx509_target} SHARED ${src_x509})
set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.5.1 SOVERSION 6)
set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.5.2 SOVERSION 6)
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
add_library(${mbedtls_target} SHARED ${src_tls})
set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.5.1 SOVERSION 20)
set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.5.2 SOVERSION 20)
target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
endif(USE_SHARED_MBEDTLS_LIBRARY)

View file

@ -53,6 +53,7 @@
#endif
#include "mbedtls/platform.h"
#include "ctr.h"
/*
* This is a convenience shorthand macro to check if we need reverse S-box and
@ -1441,36 +1442,38 @@ int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
const unsigned char *input,
unsigned char *output)
{
int c, i;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
n = *nc_off;
size_t offset = *nc_off;
if (n > 0x0F) {
if (offset > 0x0F) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
while (length--) {
if (n == 0) {
for (size_t i = 0; i < length;) {
size_t n = 16;
if (offset == 0) {
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
if (ret != 0) {
goto exit;
}
for (i = 16; i > 0; i--) {
if (++nonce_counter[i - 1] != 0) {
break;
}
}
mbedtls_ctr_increment_counter(nonce_counter);
} else {
n -= offset;
}
c = *input++;
*output++ = (unsigned char) (c ^ stream_block[n]);
n = (n + 1) & 0x0F;
if (n > (length - i)) {
n = (length - i);
}
mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
// offset might be non-zero for the last block, but in that case, we don't use it again
offset = 0;
i += n;
}
*nc_off = n;
// capture offset for future resumption
*nc_off = (*nc_off + length) % 16;
ret = 0;
exit:

View file

@ -37,6 +37,52 @@
#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
#endif
#if defined(__IAR_SYSTEMS_ICC__) && \
(defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \
|| defined(__ICCRX__) || defined(__ICCRL78__) || defined(__ICCRISCV__))
#pragma language=save
#pragma language=extended
#define MBEDTLS_POP_IAR_LANGUAGE_PRAGMA
/* IAR recommend this technique for accessing unaligned data in
* https://www.iar.com/knowledge/support/technical-notes/compiler/accessing-unaligned-data
* This results in a single load / store instruction (if unaligned access is supported).
* According to that document, this is only supported on certain architectures.
*/
#define UINT_UNALIGNED
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)))
/*
* 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.
*
* 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
*
* Tested with several versions of GCC from 4.5.0 up to 9.3.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;
#endif
/*
* We try to force mbedtls_(get|put)_unaligned_uintXX to be always inline, because this results
* in code that is both smaller and faster. IAR and gcc both benefit from this when optimising
* for size.
*/
/**
* Read the unsigned 16 bits integer from the given address, which need not
* be aligned.
@ -44,10 +90,20 @@
* \param p pointer to 2 bytes of data
* \return Data at the given address
*/
inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
#if defined(__IAR_SYSTEMS_ICC__)
#pragma inline = forced
#elif defined(__GNUC__)
__attribute__((always_inline))
#endif
static inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
{
uint16_t r;
#if defined(UINT_UNALIGNED)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
r = *p16;
#else
memcpy(&r, p, sizeof(r));
#endif
return r;
}
@ -58,9 +114,19 @@ inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
* \param p pointer to 2 bytes of data
* \param x data to write
*/
inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
#if defined(__IAR_SYSTEMS_ICC__)
#pragma inline = forced
#elif defined(__GNUC__)
__attribute__((always_inline))
#endif
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;
#else
memcpy(p, &x, sizeof(x));
#endif
}
/**
@ -70,10 +136,20 @@ inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
* \param p pointer to 4 bytes of data
* \return Data at the given address
*/
inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
#if defined(__IAR_SYSTEMS_ICC__)
#pragma inline = forced
#elif defined(__GNUC__)
__attribute__((always_inline))
#endif
static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
{
uint32_t r;
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = *p32;
#else
memcpy(&r, p, sizeof(r));
#endif
return r;
}
@ -84,9 +160,19 @@ inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
* \param p pointer to 4 bytes of data
* \param x data to write
*/
inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
#if defined(__IAR_SYSTEMS_ICC__)
#pragma inline = forced
#elif defined(__GNUC__)
__attribute__((always_inline))
#endif
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;
#else
memcpy(p, &x, sizeof(x));
#endif
}
/**
@ -96,10 +182,20 @@ inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
* \param p pointer to 8 bytes of data
* \return Data at the given address
*/
inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
#if defined(__IAR_SYSTEMS_ICC__)
#pragma inline = forced
#elif defined(__GNUC__)
__attribute__((always_inline))
#endif
static inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
{
uint64_t r;
#if defined(UINT_UNALIGNED)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
r = *p64;
#else
memcpy(&r, p, sizeof(r));
#endif
return r;
}
@ -110,11 +206,25 @@ inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
* \param p pointer to 8 bytes of data
* \param x data to write
*/
inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
#if defined(__IAR_SYSTEMS_ICC__)
#pragma inline = forced
#elif defined(__GNUC__)
__attribute__((always_inline))
#endif
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;
#else
memcpy(p, &x, sizeof(x));
#endif
}
#if defined(MBEDTLS_POP_IAR_LANGUAGE_PRAGMA)
#pragma language=restore
#endif
/** Byte Reading Macros
*
* Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th

View file

@ -27,15 +27,6 @@
#define MBEDTLS_HAVE_NEON_INTRINSICS
#endif
#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \
&& !defined(__llvm__) && !defined(__INTEL_COMPILER)
/* Defined if the compiler really is gcc and not clang, etc */
#define MBEDTLS_COMPILER_IS_GCC
#define MBEDTLS_GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
/** Helper to define a function as static except when building invasive tests.
*
* If a function is only used inside its own source file and should be
@ -167,6 +158,12 @@ static inline const unsigned char *mbedtls_buffer_offset_const(
return p == NULL ? NULL : p + n;
}
/* Always inline mbedtls_xor() for similar reasons as mbedtls_xor_no_simd(). */
#if defined(__IAR_SYSTEMS_ICC__)
#pragma inline = forced
#elif defined(__GNUC__)
__attribute__((always_inline))
#endif
/**
* Perform a fast block XOR operation, such that
* r[i] = a[i] ^ b[i] where 0 <= i < n
@ -177,8 +174,19 @@ static inline const unsigned char *mbedtls_buffer_offset_const(
* \param a Pointer to input (buffer of at least \p n bytes)
* \param b Pointer to input (buffer of at least \p n bytes)
* \param n Number of bytes to process.
*
* \note Depending on the situation, it may be faster to use either mbedtls_xor() or
* mbedtls_xor_no_simd() (these are functionally equivalent).
* If the result is used immediately after the xor operation in non-SIMD code (e.g, in
* AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
* registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
* the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
* For targets without SIMD support, they will behave the same.
*/
inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n)
static inline void mbedtls_xor(unsigned char *r,
const unsigned char *a,
const unsigned char *b,
size_t n)
{
size_t i = 0;
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
@ -191,17 +199,36 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
uint8x16_t x = veorq_u8(v1, v2);
vst1q_u8(r + i, x);
}
#if defined(__IAR_SYSTEMS_ICC__)
/* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
* where n is a constant multiple of 16.
* For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
* constant, and is a very small perf regression if n is not a compile-time constant. */
if (n % 16 == 0) {
return;
}
#endif
#elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
/* This codepath probably only makes sense on architectures with 64-bit registers */
for (; (i + 8) <= n; i += 8) {
uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
mbedtls_put_unaligned_uint64(r + i, x);
}
#if defined(__IAR_SYSTEMS_ICC__)
if (n % 8 == 0) {
return;
}
#endif
#else
for (; (i + 4) <= n; i += 4) {
uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
mbedtls_put_unaligned_uint32(r + i, x);
}
#if defined(__IAR_SYSTEMS_ICC__)
if (n % 4 == 0) {
return;
}
#endif
#endif
#endif
for (; i < n; i++) {
@ -209,11 +236,18 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
}
}
/* Always inline mbedtls_xor_no_simd() as we see significant perf regressions when it does not get
* inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */
#if defined(__IAR_SYSTEMS_ICC__)
#pragma inline = forced
#elif defined(__GNUC__)
__attribute__((always_inline))
#endif
/**
* Perform a fast block XOR operation, such that
* r[i] = a[i] ^ b[i] where 0 <= i < n
*
* In some situations, this can perform better than mbedtls_xor (e.g., it's about 5%
* In some situations, this can perform better than mbedtls_xor() (e.g., it's about 5%
* better in AES-CBC).
*
* \param r Pointer to result (buffer of at least \p n bytes). \p r
@ -222,6 +256,14 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
* \param a Pointer to input (buffer of at least \p n bytes)
* \param b Pointer to input (buffer of at least \p n bytes)
* \param n Number of bytes to process.
*
* \note Depending on the situation, it may be faster to use either mbedtls_xor() or
* mbedtls_xor_no_simd() (these are functionally equivalent).
* If the result is used immediately after the xor operation in non-SIMD code (e.g, in
* AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
* registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
* the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
* For targets without SIMD support, they will behave the same.
*/
static inline void mbedtls_xor_no_simd(unsigned char *r,
const unsigned char *a,
@ -236,11 +278,25 @@ static inline void mbedtls_xor_no_simd(unsigned char *r,
uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
mbedtls_put_unaligned_uint64(r + i, x);
}
#if defined(__IAR_SYSTEMS_ICC__)
/* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
* where n is a constant multiple of 8.
* For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
* constant, and is a very small perf regression if n is not a compile-time constant. */
if (n % 8 == 0) {
return;
}
#endif
#else
for (; (i + 4) <= n; i += 4) {
uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
mbedtls_put_unaligned_uint32(r + i, x);
}
#if defined(__IAR_SYSTEMS_ICC__)
if (n % 4 == 0) {
return;
}
#endif
#endif
#endif
for (; i < n; i++) {

35
library/ctr.h Normal file
View file

@ -0,0 +1,35 @@
/**
* \file ctr.h
*
* \brief This file contains common functionality for counter algorithms.
*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CTR_H
#define MBEDTLS_CTR_H
#include "common.h"
/**
* \brief Increment a big-endian 16-byte value.
* This is quite performance-sensitive for AES-CTR and CTR-DRBG.
*
* \param n A 16-byte value to be incremented.
*/
static inline void mbedtls_ctr_increment_counter(uint8_t n[16])
{
// The 32-bit version seems to perform about the same as a 64-bit version
// on 64-bit architectures, so no need to define a 64-bit version.
for (int i = 3;; i--) {
uint32_t x = MBEDTLS_GET_UINT32_BE(n, i << 2);
x += 1;
MBEDTLS_PUT_UINT32_BE(x, n, i << 2);
if (x != 0 || i == 0) {
break;
}
}
}
#endif /* MBEDTLS_CTR_H */

View file

@ -14,6 +14,7 @@
#if defined(MBEDTLS_CTR_DRBG_C)
#include "ctr.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@ -333,7 +334,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
{
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = tmp;
int i, j;
int j;
int ret = 0;
#if !defined(MBEDTLS_AES_C)
psa_status_t status;
@ -346,11 +347,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
/*
* Increase counter
*/
for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
if (++ctx->counter[i - 1] != 0) {
break;
}
}
mbedtls_ctr_increment_counter(ctx->counter);
/*
* Crypt counter block
@ -372,9 +369,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
}
for (i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++) {
tmp[i] ^= data[i];
}
mbedtls_xor(tmp, tmp, data, MBEDTLS_CTR_DRBG_SEEDLEN);
/*
* Update key and counter
@ -617,10 +612,11 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
{
int ret = 0;
mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = output;
unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
int i;
struct {
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
} locals;
size_t use_len;
if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) {
@ -631,7 +627,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
}
memset(add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
memset(locals.add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
if (ctx->reseed_counter > ctx->reseed_interval ||
ctx->prediction_resistance) {
@ -642,30 +638,26 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
}
if (add_len > 0) {
if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
if ((ret = block_cipher_df(locals.add_input, additional, add_len)) != 0) {
goto exit;
}
if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
goto exit;
}
}
while (output_len > 0) {
/*
* Increase counter
* Increase counter (treat it as a 128-bit big-endian integer).
*/
for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
if (++ctx->counter[i - 1] != 0) {
break;
}
}
mbedtls_ctr_increment_counter(ctx->counter);
/*
* Crypt counter block
*/
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
ctx->counter, tmp)) != 0) {
ctx->counter, locals.tmp)) != 0) {
goto exit;
}
#else
@ -673,7 +665,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
size_t tmp_len;
status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
locals.tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
@ -685,20 +677,19 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
/*
* Copy random block to destination
*/
memcpy(p, tmp, use_len);
memcpy(p, locals.tmp, use_len);
p += use_len;
output_len -= use_len;
}
if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
goto exit;
}
ctx->reseed_counter++;
exit:
mbedtls_platform_zeroize(add_input, sizeof(add_input));
mbedtls_platform_zeroize(tmp, sizeof(tmp));
mbedtls_platform_zeroize(&locals, sizeof(locals));
return ret;
}

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

@ -3198,6 +3198,25 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
}
#endif /* MBEDTLS_ECP_C */
int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,
mbedtls_ecp_keypair *key,
const mbedtls_ecp_point *Q)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if (key->grp.id == MBEDTLS_ECP_DP_NONE) {
/* Group not set yet */
if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) {
return ret;
}
} else if (key->grp.id != grp_id) {
/* Group mismatch */
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
return mbedtls_ecp_copy(&key->Q, Q);
}
#define ECP_CURVE25519_KEY_SIZE 32
#define ECP_CURVE448_KEY_SIZE 56
/*
@ -3314,6 +3333,18 @@ cleanup:
return ret;
}
/*
* Write a public key.
*/
int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key,
int format, size_t *olen,
unsigned char *buf, size_t buflen)
{
return mbedtls_ecp_point_write_binary(&key->grp, &key->Q,
format, olen, buf, buflen);
}
#if defined(MBEDTLS_ECP_C)
/*
* Check a public-private key pair
@ -3355,8 +3386,22 @@ cleanup:
return ret;
}
int mbedtls_ecp_keypair_calc_public(mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
return mbedtls_ecp_mul(&key->grp, &key->Q, &key->d, &key->grp.G,
f_rng, p_rng);
}
#endif /* MBEDTLS_ECP_C */
mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id(
const mbedtls_ecp_keypair *key)
{
return key->grp.id;
}
/*
* Export generic key-pair parameters.
*/
@ -3365,15 +3410,15 @@ int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ((ret = mbedtls_ecp_group_copy(grp, &key->grp)) != 0) {
if (grp != NULL && (ret = mbedtls_ecp_group_copy(grp, &key->grp)) != 0) {
return ret;
}
if ((ret = mbedtls_mpi_copy(d, &key->d)) != 0) {
if (d != NULL && (ret = mbedtls_mpi_copy(d, &key->d)) != 0) {
return ret;
}
if ((ret = mbedtls_ecp_copy(Q, &key->Q)) != 0) {
if (Q != NULL && (ret = mbedtls_ecp_copy(Q, &key->Q)) != 0) {
return ret;
}

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
@ -29,7 +29,7 @@
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
!defined(__HAIKU__) && !defined(__midipix__)
!defined(__HAIKU__) && !defined(__midipix__) && !defined(__MVS__)
#error \
"Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in mbedtls_config.h"
#endif

View file

@ -354,9 +354,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;
}
@ -401,12 +409,9 @@ int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
/* Increment the counter. */
static void gcm_incr(unsigned char y[16])
{
size_t i;
for (i = 16; i > 12; i--) {
if (++y[i - 1] != 0) {
break;
}
}
uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
x++;
MBEDTLS_PUT_UINT32_BE(x, y, 12);
}
/* Calculate and apply the encryption mask. Process use_len bytes of data,
@ -542,6 +547,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

@ -15,43 +15,6 @@
#include "mbedtls/md.h"
#include "psa/crypto.h"
/**
* \brief This function returns the PSA algorithm identifier
* associated with the given digest type.
*
* \param md_type The type of digest to search for. Must not be NONE.
*
* \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will
* not return \c PSA_ALG_NONE, but an invalid algorithm.
*
* \warning This function does not check if the algorithm is
* supported, it always returns the corresponding identifier.
*
* \return The PSA algorithm identifier associated with \p md_type,
* regardless of whether it is supported or not.
*/
static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type)
{
return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type;
}
/**
* \brief This function returns the given digest type
* associated with the PSA algorithm identifier.
*
* \param psa_alg The PSA algorithm identifier to search for.
*
* \warning This function does not check if the algorithm is
* supported, it always returns the corresponding identifier.
*
* \return The MD type associated with \p psa_alg,
* regardless of whether it is supported or not.
*/
static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg)
{
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
}
/** Convert PSA status to MD error code.
*
* \param status PSA status.

View file

@ -31,7 +31,7 @@
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include "psa_util_internal.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#endif
#include <limits.h>

View file

@ -98,13 +98,13 @@ static inline mbedtls_ecp_group_id mbedtls_pk_get_ec_group_id(const mbedtls_pk_c
}
opaque_key_type = psa_get_key_type(&opaque_attrs);
curve = PSA_KEY_TYPE_ECC_GET_FAMILY(opaque_key_type);
id = mbedtls_ecc_group_of_psa(curve, psa_get_key_bits(&opaque_attrs), 0);
id = mbedtls_ecc_group_from_psa(curve, psa_get_key_bits(&opaque_attrs));
psa_reset_key_attributes(&opaque_attrs);
} else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0);
id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits);
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
id = mbedtls_pk_ec_ro(*pk)->grp.id;
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
@ -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

@ -13,7 +13,7 @@
#include "pk_wrap.h"
#include "pk_internal.h"
#include "mbedtls/error.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
/* Even if RSA not activated, for the sake of RSA-alt */
#include "mbedtls/rsa.h"

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

@ -250,7 +250,7 @@ static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk,
mbedtls_ecp_group_id ecp_group_id;
int ret;
ecp_group_id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0);
ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits);
mbedtls_ecp_keypair_init(&ecp_key);
ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);

View file

@ -151,10 +151,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) && \
@ -217,35 +217,15 @@ struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt,
void (*mbedtls_test_hook_test_fail)(const char *, int, const char *);
#endif /* MBEDTLS_TEST_HOOKS */
/*
* Provide external definitions of some inline functions so that the compiler
* has the option to not inline them
*/
extern inline void mbedtls_xor(unsigned char *r,
const unsigned char *a,
const unsigned char *b,
size_t n);
extern inline uint16_t mbedtls_get_unaligned_uint16(const void *p);
extern inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x);
extern inline uint32_t mbedtls_get_unaligned_uint32(const void *p);
extern inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x);
extern inline uint64_t mbedtls_get_unaligned_uint64(const void *p);
extern inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x);
#if defined(MBEDTLS_HAVE_TIME) && !defined(MBEDTLS_PLATFORM_MS_TIME_ALT)
#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)
{
@ -253,7 +233,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);

View file

@ -70,7 +70,7 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \
@ -890,8 +890,9 @@ static psa_status_t psa_restrict_key_policy(
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
* On success, the returned key slot is locked. It is the responsibility of
* the caller to unlock the key slot when it does not access it anymore.
* On success, the returned key slot has been registered for reading.
* It is the responsibility of the caller to call psa_unregister_read(slot)
* when they have finished reading the contents of the slot.
*/
static psa_status_t psa_get_and_lock_key_slot_with_policy(
mbedtls_svc_key_id_t key,
@ -935,7 +936,7 @@ static psa_status_t psa_get_and_lock_key_slot_with_policy(
error:
*p_slot = NULL;
psa_unlock_key_slot(slot);
psa_unregister_read(slot);
return status;
}
@ -950,8 +951,9 @@ error:
* psa_get_and_lock_key_slot_with_policy() when there is no opaque key support
* for a cryptographic operation.
*
* On success, the returned key slot is locked. It is the responsibility of the
* caller to unlock the key slot when it does not access it anymore.
* On success, the returned key slot has been registered for reading.
* It is the responsibility of the caller to call psa_unregister_read(slot)
* when they have finished reading the contents of the slot.
*/
static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
mbedtls_svc_key_id_t key,
@ -966,7 +968,7 @@ static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
}
if (psa_key_lifetime_is_external((*p_slot)->attr.lifetime)) {
psa_unlock_key_slot(*p_slot);
psa_unregister_read(*p_slot);
*p_slot = NULL;
return PSA_ERROR_NOT_SUPPORTED;
}
@ -994,15 +996,41 @@ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot)
/*
* As the return error code may not be handled in case of multiple errors,
* do our best to report an unexpected lock counter. Assert with
* MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is equal to one:
* do our best to report an unexpected amount of registered readers or
* an unexpected state.
* Assert with MBEDTLS_TEST_HOOK_TEST_ASSERT that the slot is valid for
* wiping.
* if the MBEDTLS_TEST_HOOKS configuration option is enabled and the
* function is called as part of the execution of a test suite, the
* execution of the test suite is stopped in error if the assertion fails.
*/
if (slot->lock_count != 1) {
MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->lock_count == 1);
status = PSA_ERROR_CORRUPTION_DETECTED;
switch (slot->state) {
case PSA_SLOT_FULL:
/* In this state psa_wipe_key_slot() must only be called if the
* caller is the last reader. */
case PSA_SLOT_PENDING_DELETION:
/* In this state psa_wipe_key_slot() must only be called if the
* caller is the last reader. */
if (slot->registered_readers != 1) {
MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 1);
status = PSA_ERROR_CORRUPTION_DETECTED;
}
break;
case PSA_SLOT_FILLING:
/* In this state registered_readers must be 0. */
if (slot->registered_readers != 0) {
MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 0);
status = PSA_ERROR_CORRUPTION_DETECTED;
}
break;
case PSA_SLOT_EMPTY:
/* The slot is already empty, it cannot be wiped. */
MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->state != PSA_SLOT_EMPTY);
status = PSA_ERROR_CORRUPTION_DETECTED;
break;
default:
/* The slot's state is invalid. */
status = PSA_ERROR_CORRUPTION_DETECTED;
}
/* Multipart operations may still be using the key. This is safe
@ -1012,7 +1040,8 @@ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot)
* key material can linger until all operations are completed. */
/* At this point, key material and other type-specific content has
* been wiped. Clear remaining metadata. We can call memset and not
* zeroize because the metadata is not particularly sensitive. */
* zeroize because the metadata is not particularly sensitive.
* This memset also sets the slot's state to PSA_SLOT_EMPTY. */
memset(slot, 0, sizeof(*slot));
return status;
}
@ -1031,28 +1060,26 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
}
/*
* Get the description of the key in a key slot. In case of a persistent
* key, this will load the key description from persistent memory if not
* done yet. We cannot avoid this loading as without it we don't know if
* Get the description of the key in a key slot, and register to read it.
* In the case of a persistent key, this will load the key description
* from persistent memory if not done yet.
* We cannot avoid this loading as without it we don't know if
* the key is operated by an SE or not and this information is needed by
* the current implementation.
*/
* the current implementation. */
status = psa_get_and_lock_key_slot(key, &slot);
if (status != PSA_SUCCESS) {
return status;
}
/*
* If the key slot containing the key description is under access by the
* library (apart from the present access), the key cannot be destroyed
* yet. For the time being, just return in error. Eventually (to be
* implemented), the key should be destroyed when all accesses have
* stopped.
*/
if (slot->lock_count > 1) {
psa_unlock_key_slot(slot);
return PSA_ERROR_GENERIC_ERROR;
}
/* Set the key slot containing the key description's state to
* PENDING_DELETION. This stops new operations from registering
* to read the slot. Current readers can safely continue to access
* the key within the slot; the last registered reader will
* automatically wipe the slot when they call psa_unregister_read().
* If the key is persistent, we can now delete the copy of the key
* from memory. If the key is opaque, we require the driver to
* deal with the deletion. */
slot->state = PSA_SLOT_PENDING_DELETION;
if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
/* Refuse the destruction of a read-only key (which may or may not work
@ -1100,6 +1127,9 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
/* Destroy the copy of the persistent key from storage.
* The slot will still hold a copy of the key until the last reader
* unregisters. */
status = psa_destroy_persistent_key(slot->attr.id);
if (overall_status == PSA_SUCCESS) {
overall_status = status;
@ -1126,8 +1156,11 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
exit:
status = psa_wipe_key_slot(slot);
/* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
/* Unregister from reading the slot. If we are the last active reader
* then this will wipe the slot. */
status = psa_unregister_read(slot);
/* Prioritize CORRUPTION_DETECTED from unregistering over
* a storage error. */
if (status != PSA_SUCCESS) {
overall_status = status;
}
@ -1252,7 +1285,7 @@ psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key,
psa_reset_key_attributes(attributes);
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -1348,7 +1381,7 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key,
slot->key.data, slot->key.bytes,
data, data_size, data_length);
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -1462,7 +1495,7 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key,
data, data_size, data_length);
exit:
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -1579,8 +1612,9 @@ static psa_status_t psa_validate_key_attributes(
* In case of failure at any step, stop the sequence and call
* psa_fail_key_creation().
*
* On success, the key slot is locked. It is the responsibility of the caller
* to unlock the key slot when it does not access it anymore.
* On success, the key slot's state is PSA_SLOT_FILLING.
* It is the responsibility of the caller to change the slot's state to
* PSA_SLOT_EMPTY/FULL once key creation has finished.
*
* \param method An identification of the calling function.
* \param[in] attributes Key attributes for the new key.
@ -1611,7 +1645,7 @@ static psa_status_t psa_start_key_creation(
return status;
}
status = psa_get_empty_key_slot(&volatile_key_id, p_slot);
status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
if (status != PSA_SUCCESS) {
return status;
}
@ -1637,7 +1671,7 @@ static psa_status_t psa_start_key_creation(
/* Erase external-only flags from the internal copy. To access
* external-only flags, query `attributes`. Thanks to the check
* in psa_validate_key_attributes(), this leaves the dual-use
* flags and any internal flag that psa_get_empty_key_slot()
* flags and any internal flag that psa_reserve_free_key_slot()
* may have set. */
slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
@ -1689,8 +1723,6 @@ static psa_status_t psa_start_key_creation(
}
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
slot->status = PSA_SLOT_OCCUPIED;
return PSA_SUCCESS;
}
@ -1702,9 +1734,9 @@ static psa_status_t psa_start_key_creation(
* See the documentation of psa_start_key_creation() for the intended use
* of this function.
*
* If the finalization succeeds, the function unlocks the key slot (it was
* locked by psa_start_key_creation()) and the key slot cannot be accessed
* anymore as part of the key creation process.
* If the finalization succeeds, the function sets the key slot's state to
* PSA_SLOT_FULL, and the key slot can no longer be accessed as part of the
* key creation process.
*
* \param[in,out] slot Pointer to the slot with key material.
* \param[in] driver The secure element driver for the key,
@ -1780,7 +1812,8 @@ static psa_status_t psa_finish_key_creation(
if (status == PSA_SUCCESS) {
*key = slot->attr.id;
status = psa_unlock_key_slot(slot);
status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
PSA_SLOT_FULL);
if (status != PSA_SUCCESS) {
*key = MBEDTLS_SVC_KEY_ID_INIT;
}
@ -1795,7 +1828,7 @@ static psa_status_t psa_finish_key_creation(
* or after psa_finish_key_creation() fails. In other circumstances, this
* function may not clean up persistent storage.
* See the documentation of psa_start_key_creation() for the intended use
* of this function.
* of this function. Sets the slot's state to PSA_SLOT_EMPTY.
*
* \param[in,out] slot Pointer to the slot with key material.
* \param[in] driver The secure element driver for the key,
@ -2134,7 +2167,7 @@ exit:
psa_fail_key_creation(target_slot, driver);
}
unlock_status = psa_unlock_key_slot(source_slot);
unlock_status = psa_unregister_read(source_slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -2455,7 +2488,7 @@ exit:
psa_mac_abort(operation);
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -2641,7 +2674,7 @@ exit:
psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length);
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -2785,7 +2818,7 @@ exit:
psa_wipe_tag_output_buffer(signature, status, signature_size,
*signature_length);
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -2833,7 +2866,7 @@ static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key,
signature, signature_length);
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
@ -3080,7 +3113,7 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key,
return PSA_ERROR_INVALID_ARGUMENT;
}
status = psa_get_and_lock_transparent_key_slot_with_policy(
status = psa_get_and_lock_key_slot_with_policy(
key, &slot, PSA_KEY_USAGE_ENCRYPT, alg);
if (status != PSA_SUCCESS) {
return status;
@ -3100,7 +3133,7 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
exit:
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -3132,7 +3165,7 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key,
return PSA_ERROR_INVALID_ARGUMENT;
}
status = psa_get_and_lock_transparent_key_slot_with_policy(
status = psa_get_and_lock_key_slot_with_policy(
key, &slot, PSA_KEY_USAGE_DECRYPT, alg);
if (status != PSA_SUCCESS) {
return status;
@ -3152,7 +3185,7 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key,
output, output_size, output_length);
exit:
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -3261,7 +3294,7 @@ exit:
psa_sign_hash_abort_internal(operation);
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
if (unlock_status != PSA_SUCCESS) {
operation->error_occurred = 1;
@ -3406,7 +3439,7 @@ psa_status_t psa_verify_hash_start(
psa_verify_hash_abort_internal(operation);
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
if (unlock_status != PSA_SUCCESS) {
operation->error_occurred = 1;
@ -3978,7 +4011,7 @@ exit:
psa_cipher_abort(operation);
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -4223,7 +4256,7 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key,
output_size - default_iv_length, output_length);
exit:
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
if (status == PSA_SUCCESS) {
status = unlock_status;
}
@ -4284,7 +4317,7 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key,
output, output_size, output_length);
exit:
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
if (status == PSA_SUCCESS) {
status = unlock_status;
}
@ -4410,7 +4443,7 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key,
}
exit:
psa_unlock_key_slot(slot);
psa_unregister_read(slot);
return status;
}
@ -4465,7 +4498,7 @@ psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key,
}
exit:
psa_unlock_key_slot(slot);
psa_unregister_read(slot);
return status;
}
@ -4577,7 +4610,7 @@ static psa_status_t psa_aead_setup(psa_aead_operation_t *operation,
operation->key_type = psa_get_key_type(&attributes);
exit:
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
if (status == PSA_SUCCESS) {
status = unlock_status;
@ -5708,7 +5741,7 @@ static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper(
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
slot->attr.type);
mbedtls_ecp_group_id grp_id =
mbedtls_ecc_group_of_psa(curve, bits, 0);
mbedtls_ecc_group_from_psa(curve, bits);
if (grp_id == MBEDTLS_ECP_DP_NONE) {
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
@ -6900,7 +6933,7 @@ psa_status_t psa_key_derivation_input_key(
slot->key.data,
slot->key.bytes);
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -7057,7 +7090,7 @@ psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *op
}
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -7118,7 +7151,7 @@ exit:
*output_length = output_size;
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}
@ -7792,7 +7825,7 @@ exit:
if (status != PSA_SUCCESS) {
psa_pake_abort(operation);
}
unlock_status = psa_unlock_key_slot(slot);
unlock_status = psa_unregister_read(slot);
return (status == PSA_SUCCESS) ? unlock_status : status;
}

View file

@ -20,6 +20,9 @@
#include "psa/crypto.h"
#include "psa/crypto_se_driver.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
/**
* Tell if PSA is ready for this hash.
@ -47,8 +50,10 @@ int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg);
typedef enum {
PSA_SLOT_EMPTY = 0,
PSA_SLOT_OCCUPIED,
} psa_key_slot_status_t;
PSA_SLOT_FILLING,
PSA_SLOT_FULL,
PSA_SLOT_PENDING_DELETION,
} psa_key_slot_state_t;
/** The data structure representing a key slot, containing key material
* and metadata for one key.
@ -56,18 +61,37 @@ typedef enum {
typedef struct {
psa_core_key_attributes_t attr;
psa_key_slot_status_t status;
/*
* The current state of the key slot, as described in
* docs/architecture/psa-thread-safety/psa-thread-safety.md.
*
* Library functions can modify the state of a key slot by calling
* psa_key_slot_state_transition.
*
* The state variable is used to help determine whether library functions
* which operate on the slot succeed. For example, psa_finish_key_creation,
* which transfers the state of a slot from PSA_SLOT_FILLING to
* PSA_SLOT_FULL, must fail with error code PSA_ERROR_CORRUPTION_DETECTED
* if the state of the slot is not PSA_SLOT_FILLING.
*
* Library functions which traverse the array of key slots only consider
* slots that are in a suitable state for the function.
* For example, psa_get_and_lock_key_slot_in_memory, which finds a slot
* containing a given key ID, will only check slots whose state variable is
* PSA_SLOT_FULL. */
psa_key_slot_state_t state;
/*
* Number of locks on the key slot held by the library.
* Number of functions registered as reading the material in the key slot.
*
* This counter is incremented by one each time a library function
* retrieves through one of the dedicated internal API a pointer to the
* key slot.
* Library functions must not write directly to registered_readers
*
* This counter is decremented by one each time a library function stops
* accessing the key slot and states it by calling the
* psa_unlock_key_slot() API.
* A function must call psa_register_read(slot) before reading the current
* contents of the slot for an operation.
* They then must call psa_unregister_read(slot) once they have finished
* reading the current contents of the slot.
* A function must call psa_key_slot_has_readers(slot) to check if
* the slot is in use for reading.
*
* This counter is used to prevent resetting the key slot while the library
* may access it. For example, such control is needed in the following
@ -78,10 +102,9 @@ typedef struct {
* the library cannot be reclaimed to free a key slot to load the
* persistent key.
* . In case of a multi-threaded application where one thread asks to close
* or purge or destroy a key while it is in used by the library through
* another thread.
*/
size_t lock_count;
* or purge or destroy a key while it is in use by the library through
* another thread. */
size_t registered_readers;
/* Dynamically allocated key data buffer.
* Format as specified in psa_export_key(). */
@ -91,36 +114,65 @@ typedef struct {
} key;
} psa_key_slot_t;
#if defined(MBEDTLS_THREADING_C)
/** Perform a mutex operation and return immediately upon failure.
*
* Returns PSA_ERROR_SERVICE_FAILURE if the operation fails
* and status was PSA_SUCCESS.
*
* Assumptions:
* psa_status_t status exists.
* f is a mutex operation which returns 0 upon success.
*/
#define PSA_THREADING_CHK_RET(f) \
do \
{ \
if ((f) != 0) { \
if (status == PSA_SUCCESS) { \
return PSA_ERROR_SERVICE_FAILURE; \
} \
return status; \
} \
} while (0);
/** Perform a mutex operation and goto exit on failure.
*
* Sets status to PSA_ERROR_SERVICE_FAILURE if status was PSA_SUCCESS.
*
* Assumptions:
* psa_status_t status exists.
* Label exit: exists.
* f is a mutex operation which returns 0 upon success.
*/
#define PSA_THREADING_CHK_GOTO_EXIT(f) \
do \
{ \
if ((f) != 0) { \
if (status == PSA_SUCCESS) { \
status = PSA_ERROR_SERVICE_FAILURE; \
} \
goto exit; \
} \
} while (0);
#endif
/* A mask of key attribute flags used only internally.
* Currently there aren't any. */
#define PSA_KA_MASK_INTERNAL_ONLY ( \
0)
/** Test whether a key slot is occupied.
*
* A key slot is occupied iff the key type is nonzero. This works because
* no valid key can have 0 as its key type.
/** Test whether a key slot has any registered readers.
* If multi-threading is enabled, the caller must hold the
* global key slot mutex.
*
* \param[in] slot The key slot to test.
*
* \return 1 if the slot is occupied, 0 otherwise.
* \return 1 if the slot has any registered readers, 0 otherwise.
*/
static inline int psa_is_key_slot_occupied(const psa_key_slot_t *slot)
static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot)
{
return slot->status == PSA_SLOT_OCCUPIED;
}
/** Test whether a key slot is locked.
*
* A key slot is locked iff its lock counter is strictly greater than 0.
*
* \param[in] slot The key slot to test.
*
* \return 1 if the slot is locked, 0 otherwise.
*/
static inline int psa_is_key_slot_locked(const psa_key_slot_t *slot)
{
return slot->lock_count > 0;
return slot->registered_readers > 0;
}
/** Retrieve flags from psa_key_slot_t::attr::core::flags.
@ -190,13 +242,20 @@ static inline psa_key_slot_number_t psa_key_slot_get_slot_number(
/** Completely wipe a slot in memory, including its policy.
*
* Persistent storage is not affected.
* Sets the slot's state to PSA_SLOT_EMPTY.
* If multi-threading is enabled, the caller must hold the
* global key slot mutex.
*
* \param[in,out] slot The key slot to wipe.
*
* \retval #PSA_SUCCESS
* Success. This includes the case of a key slot that was
* already fully wiped.
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* The slot has been successfully wiped.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* The slot's state was PSA_SLOT_FULL or PSA_SLOT_PENDING_DELETION, and
* the amount of registered readers was not equal to 1. Or,
* the slot's state was PSA_SLOT_EMPTY. Or,
* the slot's state was PSA_SLOT_FILLING, and the amount
* of registered readers was not equal to 0.
*/
psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot);

View file

@ -14,7 +14,7 @@
#include "psa_crypto_core.h"
#include "psa_crypto_ecp.h"
#include "psa_crypto_random_impl.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#include <stdlib.h>
#include <string.h>
@ -32,6 +32,61 @@
defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
/* Helper function to verify if the provided EC's family and key bit size are valid.
*
* Note: "bits" parameter is used both as input and output and it might be updated
* in case provided input value is not multiple of 8 ("sloppy" bits).
*/
static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits)
{
switch (family) {
case PSA_ECC_FAMILY_SECP_R1:
switch (*bits) {
case 192:
case 224:
case 256:
case 384:
case 521:
return PSA_SUCCESS;
case 528:
*bits = 521;
return PSA_SUCCESS;
}
break;
case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
switch (*bits) {
case 256:
case 384:
case 512:
return PSA_SUCCESS;
}
break;
case PSA_ECC_FAMILY_MONTGOMERY:
switch (*bits) {
case 448:
case 255:
return PSA_SUCCESS;
case 256:
*bits = 255;
return PSA_SUCCESS;
}
break;
case PSA_ECC_FAMILY_SECP_K1:
switch (*bits) {
case 192:
/* secp224k1 is not and will not be supported in PSA (#3541). */
case 256:
return PSA_SUCCESS;
}
break;
}
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_status_t mbedtls_psa_ecp_load_representation(
psa_key_type_t type, size_t curve_bits,
const uint8_t *data, size_t data_length,
@ -82,16 +137,15 @@ psa_status_t mbedtls_psa_ecp_load_representation(
}
mbedtls_ecp_keypair_init(ecp);
status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), &curve_bits);
if (status != PSA_SUCCESS) {
goto exit;
}
/* Load the group. */
grp_id = mbedtls_ecc_group_of_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type),
curve_bits, !explicit_bits);
grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type),
curve_bits);
if (grp_id == MBEDTLS_ECP_DP_NONE) {
/* We can't distinguish between a nonsensical family/size combination
* (which would warrant PSA_ERROR_INVALID_ARGUMENT) and a
* well-regarded curve that Mbed TLS just doesn't know about (which
* would warrant PSA_ERROR_NOT_SUPPORTED). For uniformity with how
* curves that Mbed TLS knows about but for which support is disabled
* at build time, return NOT_SUPPORTED. */
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
@ -285,7 +339,7 @@ psa_status_t mbedtls_psa_ecp_generate_key(
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
attributes->core.type);
mbedtls_ecp_group_id grp_id =
mbedtls_ecc_group_of_psa(curve, attributes->core.bits, 0);
mbedtls_ecc_group_from_psa(curve, attributes->core.bits);
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id(grp_id);

View file

@ -16,7 +16,7 @@
#include "psa_crypto_random_impl.h"
#include "psa_crypto_rsa.h"
#include "psa_crypto_hash.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#include <stdlib.h>
#include <string.h>

View file

@ -23,6 +23,9 @@
#include <stdlib.h>
#include <string.h>
#include "mbedtls/platform.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
typedef struct {
psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
@ -108,7 +111,9 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory(
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
slot = &global_data.key_slots[slot_idx];
if (mbedtls_svc_key_id_equal(key, slot->attr.id)) {
/* Only consider slots which are in a full state. */
if ((slot->state == PSA_SLOT_FULL) &&
(mbedtls_svc_key_id_equal(key, slot->attr.id))) {
break;
}
}
@ -117,7 +122,7 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory(
}
if (status == PSA_SUCCESS) {
status = psa_lock_key_slot(slot);
status = psa_register_read(slot);
if (status == PSA_SUCCESS) {
*p_slot = slot;
}
@ -141,36 +146,38 @@ void psa_wipe_all_key_slots(void)
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
slot->lock_count = 1;
slot->registered_readers = 1;
slot->state = PSA_SLOT_PENDING_DELETION;
(void) psa_wipe_key_slot(slot);
}
global_data.key_slots_initialized = 0;
}
psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot)
psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t slot_idx;
psa_key_slot_t *selected_slot, *unlocked_persistent_key_slot;
psa_key_slot_t *selected_slot, *unused_persistent_key_slot;
if (!global_data.key_slots_initialized) {
status = PSA_ERROR_BAD_STATE;
goto error;
}
selected_slot = unlocked_persistent_key_slot = NULL;
selected_slot = unused_persistent_key_slot = NULL;
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
if (!psa_is_key_slot_occupied(slot)) {
if (slot->state == PSA_SLOT_EMPTY) {
selected_slot = slot;
break;
}
if ((unlocked_persistent_key_slot == NULL) &&
(!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
(!psa_is_key_slot_locked(slot))) {
unlocked_persistent_key_slot = slot;
if ((unused_persistent_key_slot == NULL) &&
(slot->state == PSA_SLOT_FULL) &&
(!psa_key_slot_has_readers(slot)) &&
(!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime))) {
unused_persistent_key_slot = slot;
}
}
@ -182,14 +189,18 @@ psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
* storage.
*/
if ((selected_slot == NULL) &&
(unlocked_persistent_key_slot != NULL)) {
selected_slot = unlocked_persistent_key_slot;
selected_slot->lock_count = 1;
psa_wipe_key_slot(selected_slot);
(unused_persistent_key_slot != NULL)) {
selected_slot = unused_persistent_key_slot;
psa_register_read(selected_slot);
status = psa_wipe_key_slot(selected_slot);
if (status != PSA_SUCCESS) {
goto error;
}
}
if (selected_slot != NULL) {
status = psa_lock_key_slot(selected_slot);
status = psa_key_slot_state_transition(selected_slot, PSA_SLOT_EMPTY,
PSA_SLOT_FILLING);
if (status != PSA_SUCCESS) {
goto error;
}
@ -239,7 +250,8 @@ static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot)
slot, data->slot_number, sizeof(data->slot_number));
if (status == PSA_SUCCESS) {
slot->status = PSA_SLOT_OCCUPIED;
status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
PSA_SLOT_FULL);
}
goto exit;
}
@ -250,7 +262,8 @@ static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot)
goto exit;
}
slot->status = PSA_SLOT_OCCUPIED;
status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
PSA_SLOT_FULL);
exit:
psa_free_persistent_key_data(key_data, key_data_length);
@ -324,8 +337,9 @@ static psa_status_t psa_load_builtin_key_into_slot(psa_key_slot_t *slot)
/* Copy actual key length and core attributes into the slot on success */
slot->key.bytes = key_buffer_length;
slot->attr = attributes.core;
slot->status = PSA_SLOT_OCCUPIED;
status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
PSA_SLOT_FULL);
exit:
if (status != PSA_SUCCESS) {
psa_remove_key_data_from_memory(slot);
@ -358,7 +372,7 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
psa_key_id_t volatile_key_id;
status = psa_get_empty_key_slot(&volatile_key_id, p_slot);
status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
if (status != PSA_SUCCESS) {
return status;
}
@ -380,12 +394,17 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
if (status != PSA_SUCCESS) {
psa_wipe_key_slot(*p_slot);
if (status == PSA_ERROR_DOES_NOT_EXIST) {
status = PSA_ERROR_INVALID_HANDLE;
}
} else {
/* Add implicit usage flags. */
psa_extend_key_usage_flags(&(*p_slot)->attr.policy.usage);
psa_key_slot_state_transition((*p_slot), PSA_SLOT_FILLING,
PSA_SLOT_FULL);
status = psa_register_read(*p_slot);
}
return status;
@ -394,26 +413,37 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
}
psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot)
psa_status_t psa_unregister_read(psa_key_slot_t *slot)
{
if (slot == NULL) {
return PSA_SUCCESS;
}
if ((slot->state != PSA_SLOT_FULL) &&
(slot->state != PSA_SLOT_PENDING_DELETION)) {
return PSA_ERROR_CORRUPTION_DETECTED;
}
if (slot->lock_count > 0) {
slot->lock_count--;
/* If we are the last reader and the slot is marked for deletion,
* we must wipe the slot here. */
if ((slot->state == PSA_SLOT_PENDING_DELETION) &&
(slot->registered_readers == 1)) {
return psa_wipe_key_slot(slot);
}
if (psa_key_slot_has_readers(slot)) {
slot->registered_readers--;
return PSA_SUCCESS;
}
/*
* As the return error code may not be handled in case of multiple errors,
* do our best to report if the lock counter is equal to zero. Assert with
* MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is strictly greater
* than zero: if the MBEDTLS_TEST_HOOKS configuration option is enabled and
* do our best to report if there are no registered readers. Assert with
* MBEDTLS_TEST_HOOK_TEST_ASSERT that there are registered readers:
* if the MBEDTLS_TEST_HOOKS configuration option is enabled and
* the function is called as part of the execution of a test suite, the
* execution of the test suite is stopped in error if the assertion fails.
*/
MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->lock_count > 0);
MBEDTLS_TEST_HOOK_TEST_ASSERT(psa_key_slot_has_readers(slot));
return PSA_ERROR_CORRUPTION_DETECTED;
}
@ -480,7 +510,7 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key, psa_key_handle_t *handle)
*handle = key;
return psa_unlock_key_slot(slot);
return psa_unregister_read(slot);
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
(void) key;
@ -506,10 +536,10 @@ psa_status_t psa_close_key(psa_key_handle_t handle)
return status;
}
if (slot->lock_count <= 1) {
if (slot->registered_readers == 1) {
return psa_wipe_key_slot(slot);
} else {
return psa_unlock_key_slot(slot);
return psa_unregister_read(slot);
}
}
@ -524,10 +554,10 @@ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key)
}
if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
(slot->lock_count <= 1)) {
(slot->registered_readers == 1)) {
return psa_wipe_key_slot(slot);
} else {
return psa_unlock_key_slot(slot);
return psa_unregister_read(slot);
}
}
@ -539,10 +569,10 @@ void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats)
for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
const psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
if (psa_is_key_slot_locked(slot)) {
if (psa_key_slot_has_readers(slot)) {
++stats->locked_slots;
}
if (!psa_is_key_slot_occupied(slot)) {
if (slot->state == PSA_SLOT_EMPTY) {
++stats->empty_slots;
continue;
}

View file

@ -54,8 +54,9 @@ static inline int psa_key_id_is_volatile(psa_key_id_t key_id)
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
* On success, the returned key slot is locked. It is the responsibility of
* the caller to unlock the key slot when it does not access it anymore.
* On success, the returned key slot has been registered for reading.
* It is the responsibility of the caller to call psa_unregister_read(slot)
* when they have finished reading the contents of the slot.
*
* \param key Key identifier to query.
* \param[out] p_slot On success, `*p_slot` contains a pointer to the
@ -95,50 +96,92 @@ psa_status_t psa_initialize_key_slots(void);
* This does not affect persistent storage. */
void psa_wipe_all_key_slots(void);
/** Find a free key slot.
/** Find a free key slot and reserve it to be filled with a key.
*
* This function returns a key slot that is available for use and is in its
* ground state (all-bits-zero). On success, the key slot is locked. It is
* the responsibility of the caller to unlock the key slot when it does not
* access it anymore.
* This function finds a key slot that is free,
* sets its state to PSA_SLOT_FILLING and then returns the slot.
*
* On success, the key slot's state is PSA_SLOT_FILLING.
* It is the responsibility of the caller to change the slot's state to
* PSA_SLOT_EMPTY/FULL once key creation has finished.
*
* \param[out] volatile_key_id On success, volatile key identifier
* associated to the returned slot.
* \param[out] p_slot On success, a pointer to the slot.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* There were no free key slots.
* \retval #PSA_ERROR_BAD_STATE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* This function attempted to operate on a key slot which was in an
* unexpected state.
*/
psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot);
psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot);
/** Lock a key slot.
/** Change the state of a key slot.
*
* This function increments the key slot lock counter by one.
* This function changes the state of the key slot from expected_state to
* new state. If the state of the slot was not expected_state, the state is
* unchanged.
*
* If multi-threading is enabled, the caller must hold the
* global key slot mutex.
*
* \param[in] slot The key slot.
* \param[in] expected_state The current state of the slot.
* \param[in] new_state The new state of the slot.
*
* \retval #PSA_SUCCESS
The key slot's state variable is new_state.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* The slot's state was not expected_state.
*/
static inline psa_status_t psa_key_slot_state_transition(
psa_key_slot_t *slot, psa_key_slot_state_t expected_state,
psa_key_slot_state_t new_state)
{
if (slot->state != expected_state) {
return PSA_ERROR_CORRUPTION_DETECTED;
}
slot->state = new_state;
return PSA_SUCCESS;
}
/** Register as a reader of a key slot.
*
* This function increments the key slot registered reader counter by one.
* If multi-threading is enabled, the caller must hold the
* global key slot mutex.
*
* \param[in] slot The key slot.
*
* \retval #PSA_SUCCESS
The key slot lock counter was incremented.
The key slot registered reader counter was incremented.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* The lock counter already reached its maximum value and was not
* increased.
* The reader counter already reached its maximum value and was not
* increased, or the slot's state was not PSA_SLOT_FULL.
*/
static inline psa_status_t psa_lock_key_slot(psa_key_slot_t *slot)
static inline psa_status_t psa_register_read(psa_key_slot_t *slot)
{
if (slot->lock_count >= SIZE_MAX) {
if ((slot->state != PSA_SLOT_FULL) ||
(slot->registered_readers >= SIZE_MAX)) {
return PSA_ERROR_CORRUPTION_DETECTED;
}
slot->lock_count++;
slot->registered_readers++;
return PSA_SUCCESS;
}
/** Unlock a key slot.
/** Unregister from reading a key slot.
*
* This function decrements the key slot lock counter by one.
* This function decrements the key slot registered reader counter by one.
* If the state of the slot is PSA_SLOT_PENDING_DELETION,
* and there is only one registered reader (the caller),
* this function will call psa_wipe_key_slot().
* If multi-threading is enabled, the caller must hold the
* global key slot mutex.
*
* \note To ease the handling of errors in retrieving a key slot
* a NULL input pointer is valid, and the function returns
@ -146,13 +189,16 @@ static inline psa_status_t psa_lock_key_slot(psa_key_slot_t *slot)
*
* \param[in] slot The key slot.
* \retval #PSA_SUCCESS
* \p slot is NULL or the key slot lock counter has been
* decremented successfully.
* \p slot is NULL or the key slot reader counter has been
* decremented (and potentially wiped) successfully.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* The lock counter was equal to 0.
*
* The slot's state was neither PSA_SLOT_FULL nor
* PSA_SLOT_PENDING_DELETION.
* Or a wipe was attempted and the slot's state was not
* PSA_SLOT_PENDING_DELETION.
* Or registered_readers was equal to 0.
*/
psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot);
psa_status_t psa_unregister_read(psa_key_slot_t *slot);
/** Test whether a lifetime designates a key in an external cryptoprocessor.
*

View file

@ -232,9 +232,7 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
return PSA_ECC_FAMILY_SECP_K1;
#endif
#if defined(MBEDTLS_ECP_HAVE_SECP224K1)
case MBEDTLS_ECP_DP_SECP224K1:
*bits = 224;
return PSA_ECC_FAMILY_SECP_K1;
/* secp224k1 is not and will not be supported in PSA (#3541). */
#endif
#if defined(MBEDTLS_ECP_HAVE_SECP256K1)
case MBEDTLS_ECP_DP_SECP256K1:
@ -252,11 +250,10 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
}
}
mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
size_t bits,
int bits_is_sloppy)
mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
size_t bits)
{
switch (curve) {
switch (family) {
case PSA_ECC_FAMILY_SECP_R1:
switch (bits) {
#if defined(PSA_WANT_ECC_SECP_R1_192)
@ -278,11 +275,6 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
#if defined(PSA_WANT_ECC_SECP_R1_521)
case 521:
return MBEDTLS_ECP_DP_SECP521R1;
case 528:
if (bits_is_sloppy) {
return MBEDTLS_ECP_DP_SECP521R1;
}
break;
#endif
}
break;
@ -309,11 +301,6 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
#if defined(PSA_WANT_ECC_MONTGOMERY_255)
case 255:
return MBEDTLS_ECP_DP_CURVE25519;
case 256:
if (bits_is_sloppy) {
return MBEDTLS_ECP_DP_CURVE25519;
}
break;
#endif
#if defined(PSA_WANT_ECC_MONTGOMERY_448)
case 448:
@ -329,8 +316,7 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
return MBEDTLS_ECP_DP_SECP192K1;
#endif
#if defined(PSA_WANT_ECC_SECP_K1_224)
case 224:
return MBEDTLS_ECP_DP_SECP224K1;
/* secp224k1 is not and will not be supported in PSA (#3541). */
#endif
#if defined(PSA_WANT_ECC_SECP_K1_256)
case 256:
@ -340,7 +326,6 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
break;
}
(void) bits_is_sloppy;
return MBEDTLS_ECP_DP_NONE;
}
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */

View file

@ -28,6 +28,7 @@
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#include "bignum_core.h"
#include "rsa_alt_helpers.h"
#include "rsa_internal.h"
#include "mbedtls/oid.h"
@ -970,6 +971,45 @@ cleanup:
return ret;
}
/*
* Unblind
* T = T * Vf mod N
*/
static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, const mbedtls_mpi *N)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
const size_t nlimbs = N->n;
const size_t tlimbs = mbedtls_mpi_core_montmul_working_limbs(nlimbs);
mbedtls_mpi RR, M_T;
mbedtls_mpi_init(&RR);
mbedtls_mpi_init(&M_T);
MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&M_T, tlimbs));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(T, nlimbs));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Vf, nlimbs));
/* T = T * Vf mod N
* Reminder: montmul(A, B, N) = A * B * R^-1 mod N
* Usually both operands are multiplied by R mod N beforehand (by calling
* `to_mont_rep()` on them), yielding a result that's also * R mod N (aka
* "in the Montgomery domain"). Here we only multiply one operand by R mod
* N, so the result is directly what we want - no need to call
* `from_mont_rep()` on it. */
mbedtls_mpi_core_to_mont_rep(T->p, T->p, N->p, nlimbs, mm, RR.p, M_T.p);
mbedtls_mpi_core_montmul(T->p, T->p, Vf->p, nlimbs, N->p, nlimbs, mm, M_T.p);
cleanup:
mbedtls_mpi_free(&RR);
mbedtls_mpi_free(&M_T);
return ret;
}
/*
* Exponent blinding supposed to prevent side-channel attacks using multiple
* traces of measurements to recover the RSA key. The more collisions are there,
@ -1017,23 +1057,14 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
/* Temporaries holding the blinded exponents for
* the mod p resp. mod q computation (if used). */
mbedtls_mpi DP_blind, DQ_blind;
/* Pointers to actual exponents to be used - either the unblinded
* or the blinded ones, depending on the presence of a PRNG. */
mbedtls_mpi *DP = &ctx->DP;
mbedtls_mpi *DQ = &ctx->DQ;
#else
/* Temporary holding the blinded exponent (if used). */
mbedtls_mpi D_blind;
/* Pointer to actual exponent to be used - either the unblinded
* or the blinded one, depending on the presence of a PRNG. */
mbedtls_mpi *D = &ctx->D;
#endif /* MBEDTLS_RSA_NO_CRT */
/* Temporaries holding the initial input and the double
* checked result; should be the same in the end. */
mbedtls_mpi I, C;
mbedtls_mpi input_blinded, check_result_blinded;
if (f_rng == NULL) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
@ -1068,8 +1099,8 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
mbedtls_mpi_init(&TP); mbedtls_mpi_init(&TQ);
#endif
mbedtls_mpi_init(&I);
mbedtls_mpi_init(&C);
mbedtls_mpi_init(&input_blinded);
mbedtls_mpi_init(&check_result_blinded);
/* End of MPI initialization */
@ -1079,8 +1110,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
goto cleanup;
}
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&I, &T));
/*
* Blinding
* T = T * Vi mod N
@ -1089,6 +1118,8 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vi));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N));
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&input_blinded, &T));
/*
* Exponent blinding
*/
@ -1104,8 +1135,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &P1, &Q1));
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &D_blind, &R));
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&D_blind, &D_blind, &ctx->D));
D = &D_blind;
#else
/*
* DP_blind = ( P - 1 ) * R + DP
@ -1116,8 +1145,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DP_blind, &DP_blind,
&ctx->DP));
DP = &DP_blind;
/*
* DQ_blind = ( Q - 1 ) * R + DQ
*/
@ -1126,12 +1153,10 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DQ_blind, &Q1, &R));
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DQ_blind, &DQ_blind,
&ctx->DQ));
DQ = &DQ_blind;
#endif /* MBEDTLS_RSA_NO_CRT */
#if defined(MBEDTLS_RSA_NO_CRT)
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, D, &ctx->N, &ctx->RN));
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &D_blind, &ctx->N, &ctx->RN));
#else
/*
* Faster decryption using the CRT
@ -1140,8 +1165,8 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
* TQ = input ^ dQ mod Q
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, DP, &ctx->P, &ctx->RP));
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, DQ, &ctx->Q, &ctx->RQ));
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, &DP_blind, &ctx->P, &ctx->RP));
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, &DQ_blind, &ctx->Q, &ctx->RQ));
/*
* T = (TP - TQ) * (Q^-1 mod P) mod P
@ -1157,20 +1182,19 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&T, &TQ, &TP));
#endif /* MBEDTLS_RSA_NO_CRT */
/* Verify the result to prevent glitching attacks. */
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&check_result_blinded, &T, &ctx->E,
&ctx->N, &ctx->RN));
if (mbedtls_mpi_cmp_mpi(&check_result_blinded, &input_blinded) != 0) {
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
goto cleanup;
}
/*
* Unblind
* T = T * Vf mod N
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vf));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N));
/* Verify the result to prevent glitching attacks. */
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&C, &T, &ctx->E,
&ctx->N, &ctx->RN));
if (mbedtls_mpi_cmp_mpi(&C, &I) != 0) {
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
goto cleanup;
}
MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N));
olen = ctx->len;
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
@ -1199,8 +1223,8 @@ cleanup:
mbedtls_mpi_free(&TP); mbedtls_mpi_free(&TQ);
#endif
mbedtls_mpi_free(&C);
mbedtls_mpi_free(&I);
mbedtls_mpi_free(&check_result_blinded);
mbedtls_mpi_free(&input_blinded);
if (ret != 0 && ret >= -0x007f) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret);

View file

@ -102,6 +102,14 @@
# if defined(__linux__)
/* Our preferred method of detection is getauxval() */
# include <sys/auxv.h>
# if !defined(HWCAP_SHA512)
/* The same header that declares getauxval() should provide the HWCAP_xxx
* constants to analyze its return value. However, the libc may be too
* old to have the constant that we need. So if it's missing, assume that
* the value is the same one used by the Linux kernel ABI.
*/
# define HWCAP_SHA512 (1 << 21)
# endif
# endif
/* Use SIGILL on Unix, and fall back to it on Linux */
# include <signal.h>

View file

@ -17,7 +17,7 @@
#include "mbedtls/ssl.h"
#include "ssl_misc.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#endif
#include <string.h>

View file

@ -0,0 +1,154 @@
/**
* \file ssl_ciphersuites_internal.h
*
* \brief Internal part of the public "ssl_ciphersuites.h".
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H
#define MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H
#include "mbedtls/pk.h"
#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_USE_PSA_CRYPTO */
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info);
#endif /* MBEDTLS_PK_C */
int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info);
int mbedtls_ssl_ciphersuite_uses_psk(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 */
#endif /* MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H */

View file

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

View file

@ -24,7 +24,7 @@
#include <string.h>
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "md_psa.h"
#include "mbedtls/psa_util.h"
/* Define a local translating function to save code size by not using too many
* arguments in each translating place. */
static int local_err_translation(psa_status_t status)

View file

@ -44,6 +44,8 @@
#endif
#include "mbedtls/pk.h"
#include "ssl_ciphersuites_internal.h"
#include "x509_internal.h"
#include "pk_internal.h"
#include "common.h"
@ -650,6 +652,10 @@ struct mbedtls_ssl_handshake_params {
/* Flag indicating if a CertificateRequest message has been sent
* to the client or not. */
uint8_t certificate_request_sent;
#if defined(MBEDTLS_SSL_EARLY_DATA)
/* Flag indicating if the server has accepted early data or not. */
uint8_t early_data_accepted;
#endif
#endif /* MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -2130,12 +2136,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len);
#if defined(MBEDTLS_SSL_SRV_C)
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED \
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT
#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

View file

@ -18,7 +18,7 @@
#include "mbedtls/ssl.h"
#include "ssl_misc.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/version.h"
@ -5647,13 +5647,54 @@ static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
/*
* brief Read at most 'len' application data bytes from the input
* buffer.
*
* param ssl SSL context:
* - First byte of application data not read yet in the input
* buffer located at address `in_offt`.
* - The number of bytes of data not read yet is `in_msglen`.
* param buf buffer that will hold the data
* param len maximum number of bytes to read
*
* note The function updates the fields `in_offt` and `in_msglen`
* according to the number of bytes read.
*
* return The number of bytes read.
*/
static int ssl_read_application_data(
mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen;
if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}
return (int) n;
}
/*
* Receive application data decrypted from the SSL layer
*/
int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
if (ssl == NULL || ssl->conf == NULL) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
@ -5817,32 +5858,34 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
#endif /* MBEDTLS_SSL_PROTO_DTLS */
}
n = (len < ssl->in_msglen)
? len : ssl->in_msglen;
if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}
ret = ssl_read_application_data(ssl, buf, len);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
return (int) n;
return ret;
}
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len)
{
if (ssl == NULL || (ssl->conf == NULL)) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
/*
* The server may receive early data only while waiting for the End of
* Early Data handshake message.
*/
if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) ||
(ssl->in_offt == NULL)) {
return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
}
return ssl_read_application_data(ssl, buf, len);
}
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */
/*
* Send application data to be encrypted by the SSL layer, taking care of max
* fragment length and buffer size.

View file

@ -20,7 +20,7 @@
#include "ssl_debug_helpers.h"
#include "ssl_misc.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/version.h"
@ -29,6 +29,7 @@
#include <string.h>
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "mbedtls/psa_util.h"
#include "md_psa.h"
#include "psa_util_internal.h"
#include "psa/crypto.h"
@ -1097,6 +1098,10 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
#endif
/* Initialize structures */
mbedtls_ssl_session_init(ssl->session_negotiate);
ssl_handshake_params_init(ssl->handshake);

View file

@ -14,7 +14,7 @@
#include "mbedtls/ssl.h"
#include "ssl_client.h"
#include "ssl_misc.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/constant_time.h"

View file

@ -13,7 +13,7 @@
#include "mbedtls/ssl.h"
#include "ssl_misc.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include "constant_time_internal.h"

View file

@ -11,7 +11,7 @@
#include <string.h>
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
@ -19,7 +19,7 @@
#include "ssl_client.h"
#include "ssl_tls13_keys.h"
#include "ssl_debug_helpers.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
/* Define a local translating function to save code size by not using too many
@ -1236,10 +1236,6 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO);
#endif
MBEDTLS_SSL_DEBUG_MSG(
1, ("Set hs psk for early data when writing the first psk"));
@ -1294,6 +1290,15 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
return ret;
}
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO);
#else
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
#endif
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
return 0;
@ -3067,19 +3072,19 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
}
break;
#if defined(MBEDTLS_SSL_EARLY_DATA)
case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO:
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret == 0) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
#if defined(MBEDTLS_SSL_EARLY_DATA)
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
#endif
}
break;
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)

View file

@ -12,12 +12,12 @@
#include <string.h>
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
#include "psa/crypto.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#include "ssl_misc.h"
#include "ssl_tls13_invasive.h"

View file

@ -13,7 +13,7 @@
#include <string.h>
#include "mbedtls/hkdf.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
@ -22,7 +22,7 @@
#include "ssl_tls13_invasive.h"
#include "psa/crypto.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
/* Define a local translating function to save code size by not using too many
* arguments in each translating place. */

View file

@ -9,12 +9,12 @@
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
#include "mbedtls/oid.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
@ -1780,7 +1780,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
static int ssl_tls13_is_early_data_accepted(mbedtls_ssl_context *ssl,
int hrr_required)
{
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@ -1788,17 +1789,19 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: no early data extension received."));
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED;
return;
return 0;
}
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
MBEDTLS_SSL_DEBUG_MSG(
1,
("EarlyData: rejected, feature disabled in server configuration."));
return;
return 0;
}
if (hrr_required) {
MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, HRR required."));
return 0;
}
if (!handshake->resume) {
@ -1807,7 +1810,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
resumption. */
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, not a session resumption."));
return;
return 0;
}
/* RFC 8446 4.2.10
@ -1830,7 +1833,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected key in "
"`pre_shared_key` is not the first one."));
return;
return 0;
}
if (handshake->ciphersuite_info->id !=
@ -1838,7 +1841,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected ciphersuite is not the one "
"of the selected pre-shared key."));
return;
return 0;
}
@ -1847,18 +1850,18 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
1,
("EarlyData: rejected, early_data not allowed in ticket "
"permission bits."));
return;
return 0;
}
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
return 1;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Update the handshake state machine */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl,
int hrr_required)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -1882,10 +1885,10 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
/* There is enough information, update early data state. */
ssl_tls13_update_early_data_status(ssl);
ssl->handshake->early_data_accepted =
ssl_tls13_is_early_data_accepted(ssl, hrr_required);
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->handshake->early_data_accepted) {
ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
@ -1893,6 +1896,8 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
return ret;
}
}
#else
((void) hrr_required);
#endif /* MBEDTLS_SSL_EARLY_DATA */
return 0;
@ -1947,7 +1952,9 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
return 0;
}
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_client_hello(ssl));
MBEDTLS_SSL_PROC_CHK(
ssl_tls13_postprocess_client_hello(ssl, parse_client_hello_ret ==
SSL_CLIENT_HELLO_HRR_REQUIRED));
if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
@ -2530,7 +2537,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->handshake->early_data_accepted) {
ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &output_len);
if (ret != 0) {
@ -2857,7 +2864,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->handshake->early_data_accepted) {
/* See RFC 8446 section A.2 for more information */
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early keys for inbound traffic. "
@ -2911,6 +2918,17 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl)
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
/* RFC 8446 section 4.6.1
*
* A server receiving more than max_early_data_size bytes of 0-RTT data
* SHOULD terminate the connection with an "unexpected_message" alert.
*
* TODO: Add received data size check here.
*/
if (ssl->in_offt == NULL) {
/* Set the reading pointer */
ssl->in_offt = ssl->in_msg;
}
return SSL_GOT_EARLY_DATA;
}
@ -2936,37 +2954,6 @@ static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl,
return 0;
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_early_application_data(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
return ret;
}
/*
* Output early data
*
* For the time being, we print received data via debug message.
*
* TODO: Remove it when `mbedtls_ssl_read_early_data` is ready.
*/
ssl->in_msg[ssl->in_msglen] = 0;
MBEDTLS_SSL_DEBUG_MSG(3, ("\n%s", ssl->in_msg));
/* RFC 8446 section 4.6.1
*
* A server receiving more than max_early_data_size bytes of 0-RTT data
* SHOULD terminate the connection with an "unexpected_message" alert.
*
* TODO: Add received data size check here.
*/
return 0;
}
/*
* RFC 8446 section A.2
*
@ -3037,7 +3024,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
ssl_tls13_prepare_for_handshake_second_flight(ssl);
} else if (ret == SSL_GOT_EARLY_DATA) {
MBEDTLS_SSL_PROC_CHK(ssl_tls13_process_early_application_data(ssl));
ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA;
goto cleanup;
} else {
MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;

View file

@ -148,6 +148,9 @@ void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *),
#if defined(THREADING_USE_GMTIME)
mbedtls_mutex_init(&mbedtls_threading_gmtime_mutex);
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_mutex_init(&mbedtls_threading_key_slot_mutex);
#endif
}
/*
@ -161,6 +164,9 @@ void mbedtls_threading_free_alt(void)
#if defined(THREADING_USE_GMTIME)
mbedtls_mutex_free(&mbedtls_threading_gmtime_mutex);
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_mutex_free(&mbedtls_threading_key_slot_mutex);
#endif
}
#endif /* MBEDTLS_THREADING_ALT */
@ -176,5 +182,8 @@ mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT;
#if defined(THREADING_USE_GMTIME)
mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT;
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex MUTEX_INIT;
#endif
#endif /* MBEDTLS_THREADING_C */

View file

@ -19,7 +19,7 @@
#if defined(MBEDTLS_X509_USE_C)
#include "mbedtls/x509.h"
#include "x509_internal.h"
#include "mbedtls/asn1.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"

View file

@ -9,7 +9,7 @@
#if defined(MBEDTLS_X509_CREATE_C)
#include "mbedtls/x509.h"
#include "x509_internal.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"

View file

@ -20,6 +20,7 @@
#if defined(MBEDTLS_X509_CRL_PARSE_C)
#include "mbedtls/x509_crl.h"
#include "x509_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"

View file

@ -22,6 +22,7 @@
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/x509_crt.h"
#include "x509_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
@ -35,7 +36,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "psa_util_internal.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#include "pk_internal.h"

View file

@ -20,6 +20,7 @@
#if defined(MBEDTLS_X509_CSR_PARSE_C)
#include "mbedtls/x509_csr.h"
#include "x509_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"

213
library/x509_internal.h Normal file
View file

@ -0,0 +1,213 @@
/**
* \file x509.h
*
* \brief Internal part of the public "x509.h".
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_X509_INTERNAL_H
#define MBEDTLS_X509_INTERNAL_H
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
#include "mbedtls/x509.h"
#include "mbedtls/asn1.h"
#include "pk_internal.h"
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#endif
/**
* \brief Return the next relative DN in an X509 name.
*
* \note Intended use is to compare function result to dn->next
* in order to detect boundaries of multi-valued RDNs.
*
* \param dn Current node in the X509 name
*
* \return Pointer to the first attribute-value pair of the
* next RDN in sequence, or NULL if end is reached.
*/
static inline mbedtls_x509_name *mbedtls_x509_dn_get_next(
mbedtls_x509_name *dn)
{
while (dn->MBEDTLS_PRIVATE(next_merged) && dn->next != NULL) {
dn = dn->next;
}
return dn->next;
}
/**
* \brief Store the certificate serial in printable form into buf;
* no more than size characters will be written.
*
* \param buf Buffer to write to
* \param size Maximum size of buffer
* \param serial The X509 serial to represent
*
* \return The length of the string written (not including the
* terminated nul byte), or a negative error code.
*/
int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial);
/**
* \brief Compare pair of mbedtls_x509_time.
*
* \param t1 mbedtls_x509_time to compare
* \param t2 mbedtls_x509_time to compare
*
* \return < 0 if t1 is before t2
* 0 if t1 equals t2
* > 0 if t1 is after t2
*/
int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1, const mbedtls_x509_time *t2);
#if defined(MBEDTLS_HAVE_TIME_DATE)
/**
* \brief Fill mbedtls_x509_time with provided mbedtls_time_t.
*
* \param tt mbedtls_time_t to convert
* \param now mbedtls_x509_time to fill with converted mbedtls_time_t
*
* \return \c 0 on success
* \return A non-zero return value on failure.
*/
int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now);
#endif /* MBEDTLS_HAVE_TIME_DATE */
/**
* \brief Check a given mbedtls_x509_time against the system time
* and tell if it's in the past.
*
* \note Intended usage is "if( is_past( valid_to ) ) ERROR".
* Hence the return value of 1 if on internal errors.
*
* \param to mbedtls_x509_time to check
*
* \return 1 if the given time is in the past or an error occurred,
* 0 otherwise.
*/
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to);
/**
* \brief Check a given mbedtls_x509_time against the system time
* and tell if it's in the future.
*
* \note Intended usage is "if( is_future( valid_from ) ) ERROR".
* Hence the return value of 1 if on internal errors.
*
* \param from mbedtls_x509_time to check
*
* \return 1 if the given time is in the future or an error occurred,
* 0 otherwise.
*/
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
/**
* \brief This function parses an item in the SubjectAlternativeNames
* extension. Please note that this function might allocate
* additional memory for a subject alternative name, thus
* mbedtls_x509_free_subject_alt_name has to be called
* to dispose of this additional memory afterwards.
*
* \param san_buf The buffer holding the raw data item of the subject
* alternative name.
* \param san The target structure to populate with the parsed presentation
* of the subject alternative name encoded in \p san_buf.
*
* \note Supported GeneralName types, as defined in RFC 5280:
* "rfc822Name", "dnsName", "directoryName",
* "uniformResourceIdentifier" and "hardware_module_name"
* of type "otherName", as defined in RFC 4108.
*
* \note This function should be called on a single raw data of
* subject alternative name. For example, after successful
* certificate parsing, one must iterate on every item in the
* \c crt->subject_alt_names sequence, and pass it to
* this function.
*
* \warning The target structure contains pointers to the raw data of the
* parsed certificate, and its lifetime is restricted by the
* lifetime of the certificate.
*
* \return \c 0 on success
* \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
* SAN type.
* \return Another negative value for any other failure.
*/
int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
mbedtls_x509_subject_alternative_name *san);
/**
* \brief Unallocate all data related to subject alternative name
*
* \param san SAN structure - extra memory owned by this structure will be freed
*/
void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san);
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_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);
#endif /* MBEDTLS_X509_INTERNAL_H */

View file

@ -8,6 +8,7 @@
#if defined(MBEDTLS_X509_CSR_WRITE_C) || defined(MBEDTLS_X509_CRT_WRITE_C)
#include "mbedtls/x509_crt.h"
#include "x509_internal.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"

View file

@ -16,6 +16,7 @@
#if defined(MBEDTLS_X509_CRT_WRITE_C)
#include "mbedtls/x509_crt.h"
#include "x509_internal.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"
@ -33,7 +34,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "psa_util_internal.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx)

View file

@ -14,7 +14,7 @@
#if defined(MBEDTLS_X509_CSR_WRITE_C)
#include "mbedtls/x509.h"
#include "x509_internal.h"
#include "mbedtls/x509_csr.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
@ -24,7 +24,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "psa_util_internal.h"
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#include <string.h>

View file

@ -13,14 +13,13 @@
#if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \
defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \
defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) && \
defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) && \
defined(MBEDTLS_MD_CAN_SHA1)
defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) && \
defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/net_sockets.h"
#include "mbedtls/aes.h"
#include "mbedtls/dhm.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
@ -33,9 +32,8 @@
#if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \
!defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \
!defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) || \
!defined(MBEDTLS_SHA1_C)
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_SHA256_C) || \
!defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C)
int main(void)
{
mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C "
@ -60,12 +58,14 @@ int main(void)
int ret = 1;
int exit_code = MBEDTLS_EXIT_FAILURE;
unsigned int mdlen;
size_t n, buflen;
mbedtls_net_context server_fd;
unsigned char *p, *end;
unsigned char buf[2048];
unsigned char hash[32];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
mbedtls_mpi N, E;
const char *pers = "dh_client";
mbedtls_entropy_context entropy;
@ -78,6 +78,8 @@ int main(void)
mbedtls_dhm_init(&dhm);
mbedtls_aes_init(&aes);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_mpi_init(&N);
mbedtls_mpi_init(&E);
/*
* 1. Setup the RNG
@ -106,16 +108,13 @@ int main(void)
}
mbedtls_rsa_init(&rsa);
if ((ret = mbedtls_mpi_read_file(&rsa.MBEDTLS_PRIVATE(N), 16, f)) != 0 ||
(ret = mbedtls_mpi_read_file(&rsa.MBEDTLS_PRIVATE(E), 16, f)) != 0) {
if ((ret = mbedtls_mpi_read_file(&N, 16, f)) != 0 ||
(ret = mbedtls_mpi_read_file(&E, 16, f)) != 0 ||
(ret = mbedtls_rsa_import(&rsa, &N, NULL, NULL, NULL, &E) != 0)) {
mbedtls_printf(" failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret);
fclose(f);
goto exit;
}
rsa.MBEDTLS_PRIVATE(len) = (mbedtls_mpi_bitlen(&rsa.MBEDTLS_PRIVATE(N)) + 7) >> 3;
fclose(f);
/*
@ -182,18 +181,24 @@ int main(void)
p += 2;
if ((n = (size_t) (end - p)) != rsa.MBEDTLS_PRIVATE(len)) {
if ((n = (size_t) (end - p)) != mbedtls_rsa_get_len(&rsa)) {
mbedtls_printf(" failed\n ! Invalid RSA signature size\n\n");
goto exit;
}
if ((ret = mbedtls_sha1(buf, (int) (p - 2 - buf), hash)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret);
mdlen = (unsigned int) mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256));
if (mdlen == 0) {
mbedtls_printf(" failed\n ! Invalid digest type\n\n");
goto exit;
}
if ((ret = mbedtls_sha256(buf, (int) (p - 2 - buf), hash, 0)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_sha256 returned %d\n\n", ret);
goto exit;
}
if ((ret = mbedtls_rsa_pkcs1_verify(&rsa, MBEDTLS_MD_SHA256,
32, hash, p)) != 0) {
mdlen, hash, p)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_rsa_pkcs1_verify returned %d\n\n", ret);
goto exit;
}
@ -273,6 +278,8 @@ exit:
mbedtls_dhm_free(&dhm);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
mbedtls_mpi_free(&N);
mbedtls_mpi_free(&E);
mbedtls_exit(exit_code);
}

View file

@ -13,14 +13,13 @@
#if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \
defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \
defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) && \
defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) && \
defined(MBEDTLS_MD_CAN_SHA1)
defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) && \
defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/net_sockets.h"
#include "mbedtls/aes.h"
#include "mbedtls/dhm.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
@ -33,9 +32,8 @@
#if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \
!defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \
!defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) || \
!defined(MBEDTLS_SHA1_C)
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_SHA256_C) || \
!defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C)
int main(void)
{
mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C "
@ -53,11 +51,12 @@ int main(void)
int ret = 1;
int exit_code = MBEDTLS_EXIT_FAILURE;
unsigned int mdlen;
size_t n, buflen;
mbedtls_net_context listen_fd, client_fd;
unsigned char buf[2048];
unsigned char hash[32];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
unsigned char buf2[2];
const char *pers = "dh_server";
@ -186,21 +185,30 @@ int main(void)
/*
* 5. Sign the parameters and send them
*/
if ((ret = mbedtls_sha1(buf, n, hash)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret);
mdlen = (unsigned int) mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256));
if (mdlen == 0) {
mbedtls_printf(" failed\n ! Invalid digest type\n\n");
goto exit;
}
buf[n] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len) >> 8);
buf[n + 1] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len));
if ((ret = mbedtls_sha256(buf, n, hash, 0)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_sha256 returned %d\n\n", ret);
goto exit;
}
if ((ret = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_MD_SHA256,
32, hash, buf + n + 2)) != 0) {
const size_t rsa_key_len = mbedtls_rsa_get_len(&rsa);
buf[n] = (unsigned char) (rsa_key_len >> 8);
buf[n + 1] = (unsigned char) (rsa_key_len);
if ((ret = mbedtls_rsa_pkcs1_sign(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg,
MBEDTLS_MD_SHA256, mdlen,
hash, buf + n + 2)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_rsa_pkcs1_sign returned %d\n\n", ret);
goto exit;
}
buflen = n + 2 + rsa.MBEDTLS_PRIVATE(len);
buflen = n + 2 + rsa_key_len;
buf2[0] = (unsigned char) (buflen >> 8);
buf2[1] = (unsigned char) (buflen);

View file

@ -60,8 +60,8 @@ static void dump_pubkey(const char *title, mbedtls_ecdsa_context *key)
unsigned char buf[300];
size_t len;
if (mbedtls_ecp_point_write_binary(&key->MBEDTLS_PRIVATE(grp), &key->MBEDTLS_PRIVATE(Q),
MBEDTLS_ECP_PF_UNCOMPRESSED, &len, buf, sizeof(buf)) != 0) {
if (mbedtls_ecp_write_public_key(key, MBEDTLS_ECP_PF_UNCOMPRESSED,
&len, buf, sizeof(buf)) != 0) {
mbedtls_printf("internal error\n");
return;
}
@ -79,6 +79,8 @@ int main(int argc, char *argv[])
int ret = 1;
int exit_code = MBEDTLS_EXIT_FAILURE;
mbedtls_ecdsa_context ctx_sign, ctx_verify;
mbedtls_ecp_point Q;
mbedtls_ecp_point_init(&Q);
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
unsigned char message[100];
@ -128,7 +130,10 @@ int main(int argc, char *argv[])
goto exit;
}
mbedtls_printf(" ok (key size: %d bits)\n", (int) ctx_sign.MBEDTLS_PRIVATE(grp).pbits);
mbedtls_ecp_group_id grp_id = mbedtls_ecp_keypair_get_group_id(&ctx_sign);
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id(grp_id);
mbedtls_printf(" ok (key size: %d bits)\n", (int) curve_info->bit_size);
dump_pubkey(" + Public key: ", &ctx_sign);
@ -174,16 +179,13 @@ int main(int argc, char *argv[])
mbedtls_printf(" . Preparing verification context...");
fflush(stdout);
if ((ret =
mbedtls_ecp_group_copy(&ctx_verify.MBEDTLS_PRIVATE(grp),
&ctx_sign.MBEDTLS_PRIVATE(grp))) != 0) {
mbedtls_printf(" failed\n ! mbedtls_ecp_group_copy returned %d\n", ret);
if ((ret = mbedtls_ecp_export(&ctx_sign, NULL, NULL, &Q)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_ecp_export returned %d\n", ret);
goto exit;
}
if ((ret =
mbedtls_ecp_copy(&ctx_verify.MBEDTLS_PRIVATE(Q), &ctx_sign.MBEDTLS_PRIVATE(Q))) != 0) {
mbedtls_printf(" failed\n ! mbedtls_ecp_copy returned %d\n", ret);
if ((ret = mbedtls_ecp_set_public_key(grp_id, &ctx_verify, &Q)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_ecp_set_public_key returned %d\n", ret);
goto exit;
}
@ -208,6 +210,7 @@ exit:
mbedtls_ecdsa_free(&ctx_verify);
mbedtls_ecdsa_free(&ctx_sign);
mbedtls_ecp_point_free(&Q);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);

View file

@ -9,8 +9,19 @@
#include "mbedtls/platform.h"
#if defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_FS_IO) && \
defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_CTR_DRBG_C)
#if !defined(MBEDTLS_PK_WRITE_C) || !defined(MBEDTLS_PEM_WRITE_C) || \
!defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_ENTROPY_C) || \
!defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_BIGNUM_C)
int main(void)
{
mbedtls_printf("MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO and/or "
"MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
"MBEDTLS_PEM_WRITE_C and/or MBEDTLS_BIGNUM_C "
"not defined.\n");
mbedtls_exit(0);
}
#else
#include "mbedtls/error.h"
#include "mbedtls/pk.h"
#include "mbedtls/ecdsa.h"
@ -61,7 +72,6 @@ int dev_random_entropy_poll(void *data, unsigned char *output,
return 0;
}
#endif /* !_WIN32 */
#endif
#if defined(MBEDTLS_ECP_C)
#define DFL_EC_CURVE mbedtls_ecp_curve_list()->grp_id
@ -96,19 +106,6 @@ int dev_random_entropy_poll(void *data, unsigned char *output,
USAGE_DEV_RANDOM \
"\n"
#if !defined(MBEDTLS_PK_WRITE_C) || !defined(MBEDTLS_PEM_WRITE_C) || \
!defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_ENTROPY_C) || \
!defined(MBEDTLS_CTR_DRBG_C)
int main(void)
{
mbedtls_printf("MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO and/or "
"MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
"MBEDTLS_PEM_WRITE_C"
"not defined.\n");
mbedtls_exit(0);
}
#else
/*
* global options
@ -160,6 +157,71 @@ static int write_private_key(mbedtls_pk_context *key, const char *output_file)
return 0;
}
#if defined(MBEDTLS_ECP_C)
static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private)
{
int ret = 0;
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id(
mbedtls_ecp_keypair_get_group_id(ecp));
mbedtls_printf("curve: %s\n", curve_info->name);
mbedtls_ecp_group grp;
mbedtls_ecp_group_init(&grp);
mbedtls_mpi D;
mbedtls_mpi_init(&D);
mbedtls_ecp_point pt;
mbedtls_ecp_point_init(&pt);
mbedtls_mpi X, Y;
mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp,
(has_private ? &D : NULL),
&pt));
unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN];
size_t len = 0;
MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary(
&grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED,
&len, point_bin, sizeof(point_bin)));
switch (mbedtls_ecp_get_type(&grp)) {
case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS:
if ((len & 1) == 0 || point_bin[0] != 0x04) {
/* Point in an unxepected format. This shouldn't happen. */
ret = -1;
goto cleanup;
}
MBEDTLS_MPI_CHK(
mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2));
MBEDTLS_MPI_CHK(
mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2));
mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL);
mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL);
break;
case MBEDTLS_ECP_TYPE_MONTGOMERY:
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len));
mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL);
break;
default:
mbedtls_printf(
"This program does not yet support listing coordinates for this curve type.\n");
break;
}
if (has_private) {
mbedtls_mpi_write_file("D: ", &D, 16, NULL);
}
cleanup:
mbedtls_ecp_group_free(&grp);
mbedtls_mpi_free(&D);
mbedtls_ecp_point_free(&pt);
mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
return ret;
}
#endif
int main(int argc, char *argv[])
{
int ret = 1;
@ -365,12 +427,10 @@ usage:
#endif
#if defined(MBEDTLS_ECP_C)
if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) {
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key);
mbedtls_printf("curve: %s\n",
mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name);
mbedtls_mpi_write_file("X_Q: ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL);
mbedtls_mpi_write_file("Y_Q: ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL);
mbedtls_mpi_write_file("D: ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL);
if (show_ecp_key(mbedtls_pk_ec(key), 1) != 0) {
mbedtls_printf(" failed\n ! could not export ECC parameters\n\n");
goto exit;
}
} else
#endif
mbedtls_printf(" ! key type not supported\n");
@ -415,5 +475,4 @@ exit:
mbedtls_exit(exit_code);
}
#endif /* MBEDTLS_PK_WRITE_C && MBEDTLS_PEM_WRITE_C && MBEDTLS_FS_IO &&
* MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
#endif /* program viability conditions */

View file

@ -53,6 +53,71 @@ int main(void)
#else
#if defined(MBEDTLS_ECP_C)
static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private)
{
int ret = 0;
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id(
mbedtls_ecp_keypair_get_group_id(ecp));
mbedtls_printf("curve: %s\n", curve_info->name);
mbedtls_ecp_group grp;
mbedtls_ecp_group_init(&grp);
mbedtls_mpi D;
mbedtls_mpi_init(&D);
mbedtls_ecp_point pt;
mbedtls_ecp_point_init(&pt);
mbedtls_mpi X, Y;
mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp,
(has_private ? &D : NULL),
&pt));
unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN];
size_t len = 0;
MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary(
&grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED,
&len, point_bin, sizeof(point_bin)));
switch (mbedtls_ecp_get_type(&grp)) {
case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS:
if ((len & 1) == 0 || point_bin[0] != 0x04) {
/* Point in an unxepected format. This shouldn't happen. */
ret = -1;
goto cleanup;
}
MBEDTLS_MPI_CHK(
mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2));
MBEDTLS_MPI_CHK(
mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2));
mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL);
mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL);
break;
case MBEDTLS_ECP_TYPE_MONTGOMERY:
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len));
mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL);
break;
default:
mbedtls_printf(
"This program does not yet support listing coordinates for this curve type.\n");
break;
}
if (has_private) {
mbedtls_mpi_write_file("D: ", &D, 16, NULL);
}
cleanup:
mbedtls_ecp_group_free(&grp);
mbedtls_mpi_free(&D);
mbedtls_ecp_point_free(&pt);
mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
return ret;
}
#endif
/*
* global options
*/
@ -219,17 +284,10 @@ usage:
#endif
#if defined(MBEDTLS_ECP_C)
if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY) {
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(pk);
MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(X): ",
&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16,
NULL));
MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Y): ",
&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16,
NULL));
MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Z): ",
&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16,
NULL));
MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("D : ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL));
if (show_ecp_key(mbedtls_pk_ec(pk), 1) != 0) {
mbedtls_printf(" failed\n ! could not export ECC parameters\n\n");
goto cleanup;
}
} else
#endif
{
@ -269,16 +327,10 @@ usage:
#endif
#if defined(MBEDTLS_ECP_C)
if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY) {
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(pk);
MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(X): ",
&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16,
NULL));
MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Y): ",
&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16,
NULL));
MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Z): ",
&ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16,
NULL));
if (show_ecp_key(mbedtls_pk_ec(pk), 0) != 0) {
mbedtls_printf(" failed\n ! could not export ECC parameters\n\n");
goto cleanup;
}
} else
#endif
{

View file

@ -9,9 +9,21 @@
#include "mbedtls/platform.h"
#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PK_WRITE_C) && \
defined(MBEDTLS_FS_IO) && \
defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_CTR_DRBG_C)
#if !defined(MBEDTLS_PK_PARSE_C) || \
!defined(MBEDTLS_PK_WRITE_C) || \
!defined(MBEDTLS_FS_IO) || \
!defined(MBEDTLS_ENTROPY_C) || \
!defined(MBEDTLS_CTR_DRBG_C) || \
!defined(MBEDTLS_BIGNUM_C)
int main(void)
{
mbedtls_printf("MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or "
"MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
"MBEDTLS_FS_IO and/or MBEDTLS_BIGNUM_C not defined.\n");
mbedtls_exit(0);
}
#else
#include "mbedtls/error.h"
#include "mbedtls/pk.h"
#include "mbedtls/error.h"
@ -21,7 +33,6 @@
#include <stdio.h>
#include <string.h>
#endif
#if defined(MBEDTLS_PEM_WRITE_C)
#define USAGE_OUT \
@ -66,20 +77,6 @@
USAGE_OUT \
"\n"
#if !defined(MBEDTLS_PK_PARSE_C) || \
!defined(MBEDTLS_PK_WRITE_C) || \
!defined(MBEDTLS_FS_IO) || \
!defined(MBEDTLS_ENTROPY_C) || \
!defined(MBEDTLS_CTR_DRBG_C)
int main(void)
{
mbedtls_printf("MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or "
"MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
"MBEDTLS_FS_IO not defined.\n");
mbedtls_exit(0);
}
#else
/*
* global options
@ -176,6 +173,71 @@ static int write_private_key(mbedtls_pk_context *key, const char *output_file)
return 0;
}
#if defined(MBEDTLS_ECP_C)
static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private)
{
int ret = 0;
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id(
mbedtls_ecp_keypair_get_group_id(ecp));
mbedtls_printf("curve: %s\n", curve_info->name);
mbedtls_ecp_group grp;
mbedtls_ecp_group_init(&grp);
mbedtls_mpi D;
mbedtls_mpi_init(&D);
mbedtls_ecp_point pt;
mbedtls_ecp_point_init(&pt);
mbedtls_mpi X, Y;
mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp,
(has_private ? &D : NULL),
&pt));
unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN];
size_t len = 0;
MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary(
&grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED,
&len, point_bin, sizeof(point_bin)));
switch (mbedtls_ecp_get_type(&grp)) {
case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS:
if ((len & 1) == 0 || point_bin[0] != 0x04) {
/* Point in an unxepected format. This shouldn't happen. */
ret = -1;
goto cleanup;
}
MBEDTLS_MPI_CHK(
mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2));
MBEDTLS_MPI_CHK(
mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2));
mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL);
mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL);
break;
case MBEDTLS_ECP_TYPE_MONTGOMERY:
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len));
mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL);
break;
default:
mbedtls_printf(
"This program does not yet support listing coordinates for this curve type.\n");
break;
}
if (has_private) {
mbedtls_mpi_write_file("D: ", &D, 16, NULL);
}
cleanup:
mbedtls_ecp_group_free(&grp);
mbedtls_mpi_free(&D);
mbedtls_ecp_point_free(&pt);
mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
return ret;
}
#endif
int main(int argc, char *argv[])
{
int ret = 1;
@ -338,11 +400,10 @@ usage:
#endif
#if defined(MBEDTLS_ECP_C)
if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) {
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key);
mbedtls_mpi_write_file("Q(X): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL);
mbedtls_mpi_write_file("Q(Y): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL);
mbedtls_mpi_write_file("Q(Z): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, NULL);
mbedtls_mpi_write_file("D : ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL);
if (show_ecp_key(mbedtls_pk_ec(key), 1) != 0) {
mbedtls_printf(" failed\n ! could not export ECC parameters\n\n");
goto exit;
}
} else
#endif
mbedtls_printf("key type not supported yet\n");
@ -384,10 +445,10 @@ usage:
#endif
#if defined(MBEDTLS_ECP_C)
if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) {
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key);
mbedtls_mpi_write_file("Q(X): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL);
mbedtls_mpi_write_file("Q(Y): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL);
mbedtls_mpi_write_file("Q(Z): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, NULL);
if (show_ecp_key(mbedtls_pk_ec(key), 0) != 0) {
mbedtls_printf(" failed\n ! could not export ECC parameters\n\n");
goto exit;
}
} else
#endif
mbedtls_printf("key type not supported yet\n");
@ -431,5 +492,4 @@ exit:
mbedtls_exit(exit_code);
}
#endif /* MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO &&
MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
#endif /* program viability conditions */

View file

@ -133,7 +133,7 @@ int main(int argc, char *argv[])
fclose(f);
if (i != rsa.MBEDTLS_PRIVATE(len)) {
if (i != mbedtls_rsa_get_len(&rsa)) {
mbedtls_printf("\n ! Invalid RSA signature format\n\n");
goto exit;
}

View file

@ -126,7 +126,7 @@ int main(int argc, char *argv[])
goto exit;
}
for (i = 0; i < rsa.MBEDTLS_PRIVATE(len); i++) {
for (i = 0; i < mbedtls_rsa_get_len(&rsa); i++) {
mbedtls_fprintf(f, "%02X%s", buf[i],
(i + 1) % 16 == 0 ? "\r\n" : " ");
}

View file

@ -131,7 +131,7 @@ int main(int argc, char *argv[])
goto exit;
}
for (i = 0; i < rsa.MBEDTLS_PRIVATE(len); i++) {
for (i = 0; i < mbedtls_rsa_get_len(&rsa); i++) {
mbedtls_fprintf(f, "%02X%s", buf[i],
(i + 1) % 16 == 0 ? "\r\n" : " ");
}

View file

@ -37,11 +37,14 @@ int main(int argc, char *argv[])
int exit_code = MBEDTLS_EXIT_FAILURE;
size_t i;
mbedtls_rsa_context rsa;
mbedtls_mpi N, E;
unsigned char hash[32];
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
char filename[512];
mbedtls_rsa_init(&rsa);
mbedtls_mpi_init(&N);
mbedtls_mpi_init(&E);
if (argc != 2) {
mbedtls_printf("usage: rsa_verify <filename>\n");
@ -62,15 +65,13 @@ int main(int argc, char *argv[])
goto exit;
}
if ((ret = mbedtls_mpi_read_file(&rsa.MBEDTLS_PRIVATE(N), 16, f)) != 0 ||
(ret = mbedtls_mpi_read_file(&rsa.MBEDTLS_PRIVATE(E), 16, f)) != 0) {
if ((ret = mbedtls_mpi_read_file(&N, 16, f)) != 0 ||
(ret = mbedtls_mpi_read_file(&E, 16, f)) != 0 ||
(ret = mbedtls_rsa_import(&rsa, &N, NULL, NULL, NULL, &E) != 0)) {
mbedtls_printf(" failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret);
fclose(f);
goto exit;
}
rsa.MBEDTLS_PRIVATE(len) = (mbedtls_mpi_bitlen(&rsa.MBEDTLS_PRIVATE(N)) + 7) >> 3;
fclose(f);
/*
@ -91,7 +92,7 @@ int main(int argc, char *argv[])
fclose(f);
if (i != rsa.MBEDTLS_PRIVATE(len)) {
if (i != mbedtls_rsa_get_len(&rsa)) {
mbedtls_printf("\n ! Invalid RSA signature format\n\n");
goto exit;
}
@ -124,6 +125,8 @@ int main(int argc, char *argv[])
exit:
mbedtls_rsa_free(&rsa);
mbedtls_mpi_free(&N);
mbedtls_mpi_free(&E);
mbedtls_exit(exit_code);
}

View file

@ -1612,6 +1612,7 @@ int main(int argc, char *argv[])
#if defined(MBEDTLS_SSL_EARLY_DATA)
int tls13_early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED;
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf));
#if defined(MBEDTLS_MEMORY_DEBUG)
@ -3450,6 +3451,19 @@ handshake:
fflush(stdout);
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) {
memset(buf, 0, opt.buffer_size);
ret = mbedtls_ssl_read_early_data(&ssl, buf, opt.buffer_size);
if (ret > 0) {
buf[ret] = '\0';
mbedtls_printf(" %d early data bytes read\n\n%s\n",
ret, (char *) buf);
}
continue;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS &&
ssl_async_keys.inject_error == SSL_ASYNC_INJECT_ERROR_CANCEL) {

View file

@ -507,7 +507,7 @@ typedef struct {
char md5, ripemd160, sha1, sha256, sha512,
sha3_224, sha3_256, sha3_384, sha3_512,
des3, des,
aes_cbc, aes_cfb128, aes_cfb8, aes_gcm, aes_ccm, aes_xts, chachapoly,
aes_cbc, aes_cfb128, aes_cfb8, aes_ctr, aes_gcm, aes_ccm, aes_xts, chachapoly,
aes_cmac, des3_cmac,
aria, camellia, chacha20,
poly1305,
@ -571,6 +571,8 @@ int main(int argc, char *argv[])
todo.aes_cfb128 = 1;
} else if (strcmp(argv[i], "aes_cfb8") == 0) {
todo.aes_cfb8 = 1;
} else if (strcmp(argv[i], "aes_ctr") == 0) {
todo.aes_ctr = 1;
} else if (strcmp(argv[i], "aes_xts") == 0) {
todo.aes_xts = 1;
} else if (strcmp(argv[i], "aes_gcm") == 0) {
@ -774,6 +776,31 @@ int main(int argc, char *argv[])
mbedtls_aes_free(&aes);
}
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
if (todo.aes_ctr) {
int keysize;
mbedtls_aes_context aes;
uint8_t stream_block[16];
size_t nc_off;
mbedtls_aes_init(&aes);
for (keysize = 128; keysize <= 256; keysize += 64) {
mbedtls_snprintf(title, sizeof(title), "AES-CTR-%d", keysize);
memset(buf, 0, sizeof(buf));
memset(tmp, 0, sizeof(tmp));
memset(stream_block, 0, sizeof(stream_block));
nc_off = 0;
CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize));
TIME_AND_TSC(title, mbedtls_aes_crypt_ctr(&aes, BUFSIZE, &nc_off, tmp, stream_block,
buf, buf));
}
mbedtls_aes_free(&aes);
}
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
if (todo.aes_xts) {
int keysize;

View file

@ -1,3 +1,4 @@
EarlyData context: line 0 lf
EarlyData context: line 1 lf
EarlyData context: line 2 lf
EarlyData context: If it appears, that means early_data received.

View file

@ -67,6 +67,10 @@ void mbedtls_test_transparent_free(void);
psa_status_t mbedtls_test_opaque_init(void);
void mbedtls_test_opaque_free(void);
psa_status_t mbedtls_test_opaque_unwrap_key(
const uint8_t *wrapped_key, size_t wrapped_key_length, uint8_t *key_buffer,
size_t key_buffer_size, size_t *key_buffer_length);
psa_status_t mbedtls_test_transparent_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key, size_t key_size, size_t *key_length);

View file

@ -125,8 +125,8 @@
do { \
TEST_ASSERT((pointer) == NULL); \
if ((item_count) != 0) { \
(pointer) = mbedtls_calloc(sizeof(*(pointer)), \
(item_count)); \
(pointer) = mbedtls_calloc((item_count), \
sizeof(*(pointer))); \
TEST_ASSERT((pointer) != NULL); \
} \
} while (0)
@ -155,8 +155,8 @@
#define TEST_CALLOC_NONNULL(pointer, item_count) \
do { \
TEST_ASSERT((pointer) == NULL); \
(pointer) = mbedtls_calloc(sizeof(*(pointer)), \
(item_count)); \
(pointer) = mbedtls_calloc((item_count), \
sizeof(*(pointer))); \
if (((pointer) == NULL) && ((item_count) == 0)) { \
(pointer) = mbedtls_calloc(1, 1); \
} \
@ -175,8 +175,8 @@
do { \
TEST_ASSERT((pointer) == NULL); \
if ((item_count) != 0) { \
(pointer) = mbedtls_calloc(sizeof(*(pointer)), \
(item_count)); \
(pointer) = mbedtls_calloc((item_count), \
sizeof(*(pointer))); \
TEST_ASSUME((pointer) != NULL); \
} \
} while (0)

View file

@ -589,6 +589,16 @@ int mbedtls_test_tweak_tls13_certificate_msg_vector_len(
int *expected_result, mbedtls_ssl_chk_buf_ptr_args *args);
#endif /* MBEDTLS_TEST_HOOKS */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
int mbedtls_test_ticket_write(
void *p_ticket, const mbedtls_ssl_session *session,
unsigned char *start, const unsigned char *end,
size_t *tlen, uint32_t *ticket_lifetime);
int mbedtls_test_ticket_parse(void *p_ticket, mbedtls_ssl_session *session,
unsigned char *buf, size_t len);
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#define ECJPAKE_TEST_PWD "bla"
#if defined(MBEDTLS_USE_PSA_CRYPTO)

View file

@ -506,4 +506,7 @@ run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \
-s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \
-s "ClientHello: early_data(42) extension exists." \
-s "EncryptedExtensions: early_data(42) extension exists." \
-s "$( tail -1 $EARLY_DATA_INPUT )"
-s "$( head -1 $EARLY_DATA_INPUT )" \
-s "$( tail -1 $EARLY_DATA_INPUT )" \
-s "200 early data bytes read" \
-s "106 early data bytes read"

View file

@ -821,6 +821,14 @@ pre_generate_files() {
fi
}
clang_version() {
if command -v clang > /dev/null ; then
clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#'
else
echo 0 # report version 0 for "no clang"
fi
}
################################################################
#### Helpers for components using libtestdriver1
################################################################
@ -4694,14 +4702,8 @@ component_test_aesni_m32 () { # ~ 60s
}
support_test_aesni_m32_clang() {
support_test_aesni_m32 && if command -v clang > /dev/null ; then
# clang >= 4 is required to build with target attributes
clang_ver="$(clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#')"
[[ "${clang_ver}" -ge 4 ]]
else
# clang not available
false
fi
# clang >= 4 is required to build with target attributes
support_test_aesni_m32 && [[ $(clang_version) -ge 4 ]]
}
component_test_aesni_m32_clang() {
@ -4752,9 +4754,8 @@ component_build_aes_aesce_armcc () {
}
support_build_aes_armce() {
# clang >= 4 is required to build with AES extensions
ver="$(clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#')"
[ "${ver}" -ge 11 ]
# clang >= 11 is required to build with AES extensions
[[ $(clang_version) -ge 11 ]]
}
component_build_aes_armce () {
@ -4809,15 +4810,8 @@ component_build_aes_armce () {
}
support_build_sha_armce() {
if command -v clang > /dev/null ; then
# clang >= 4 is required to build with SHA extensions
clang_ver="$(clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#')"
[[ "${clang_ver}" -ge 4 ]]
else
# clang not available
false
fi
# clang >= 4 is required to build with SHA extensions
[[ $(clang_version) -ge 4 ]]
}
component_build_sha_armce () {

View file

@ -325,6 +325,7 @@ KNOWN_TASKS = {
# is required.
'test_suite_ecp': [
re.compile(r'ECP check public-private .*'),
re.compile(r'ECP calculate public: .*'),
re.compile(r'ECP gen keypair .*'),
re.compile(r'ECP point muladd .*'),
re.compile(r'ECP point multiplication .*'),

View file

@ -13,11 +13,15 @@
#include "psa_crypto_rsa.h"
#include "string.h"
#include "test/drivers/asymmetric_encryption.h"
#include "test/drivers/key_management.h"
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1)
#include "libtestdriver1/library/psa_crypto_rsa.h"
#endif
#define PSA_RSA_KEY_PAIR_MAX_SIZE \
PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)
mbedtls_test_driver_asymmetric_encryption_hooks_t mbedtls_test_driver_asymmetric_encryption_hooks =
MBEDTLS_TEST_DRIVER_ASYMMETRIC_ENCRYPTION_INIT;
@ -104,7 +108,7 @@ psa_status_t mbedtls_test_transparent_asymmetric_decrypt(
}
/*
* opaque versions - TODO
* opaque versions
*/
psa_status_t mbedtls_test_opaque_asymmetric_encrypt(
const psa_key_attributes_t *attributes, const uint8_t *key,
@ -112,17 +116,31 @@ psa_status_t mbedtls_test_opaque_asymmetric_encrypt(
size_t input_length, const uint8_t *salt, size_t salt_length,
uint8_t *output, size_t output_size, size_t *output_length)
{
(void) attributes;
(void) key;
(void) key_length;
(void) alg;
(void) input;
(void) input_length;
(void) salt;
(void) salt_length;
(void) output;
(void) output_size;
(void) output_length;
unsigned char unwrapped_key[PSA_RSA_KEY_PAIR_MAX_SIZE];
size_t unwrapped_key_length;
psa_status_t status;
status = mbedtls_test_opaque_unwrap_key(key, key_length,
unwrapped_key, sizeof(unwrapped_key),
&unwrapped_key_length);
if (status != PSA_SUCCESS) {
return status;
}
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
(defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP) || defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT))
return libtestdriver1_mbedtls_psa_asymmetric_encrypt(
(const libtestdriver1_psa_key_attributes_t *) attributes,
unwrapped_key, unwrapped_key_length,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
#else
return mbedtls_psa_asymmetric_encrypt(
attributes, unwrapped_key, unwrapped_key_length,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
#endif
return PSA_ERROR_NOT_SUPPORTED;
}
@ -132,17 +150,31 @@ psa_status_t mbedtls_test_opaque_asymmetric_decrypt(
size_t input_length, const uint8_t *salt, size_t salt_length,
uint8_t *output, size_t output_size, size_t *output_length)
{
(void) attributes;
(void) key;
(void) key_length;
(void) alg;
(void) input;
(void) input_length;
(void) salt;
(void) salt_length;
(void) output;
(void) output_size;
(void) output_length;
unsigned char unwrapped_key[PSA_RSA_KEY_PAIR_MAX_SIZE];
size_t unwrapped_key_length;
psa_status_t status;
status = mbedtls_test_opaque_unwrap_key(key, key_length,
unwrapped_key, sizeof(unwrapped_key),
&unwrapped_key_length);
if (status != PSA_SUCCESS) {
return status;
}
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
(defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP) || defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT))
return libtestdriver1_mbedtls_psa_asymmetric_decrypt(
(const libtestdriver1_psa_key_attributes_t *) attributes,
unwrapped_key, unwrapped_key_length,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
#else
return mbedtls_psa_asymmetric_decrypt(
attributes, unwrapped_key, unwrapped_key_length,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
#endif
return PSA_ERROR_NOT_SUPPORTED;
}

View file

@ -159,7 +159,7 @@ static psa_status_t mbedtls_test_opaque_wrap_key(
* The argument key_buffer_length is filled with the unwrapped(clear)
* key_size on success.
* */
static psa_status_t mbedtls_test_opaque_unwrap_key(
psa_status_t mbedtls_test_opaque_unwrap_key(
const uint8_t *wrapped_key,
size_t wrapped_key_length,
uint8_t *key_buffer,

View file

@ -9,7 +9,7 @@
*/
#include <test/ssl_helpers.h>
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_SSL_TLS_C)
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
@ -841,6 +841,23 @@ int mbedtls_test_ssl_endpoint_init(
}
#endif
#if defined(MBEDTLS_DEBUG_C)
#if defined(MBEDTLS_SSL_SRV_C)
if (endpoint_type == MBEDTLS_SSL_IS_SERVER &&
options->srv_log_fun != NULL) {
mbedtls_ssl_conf_dbg(&(ep->conf), options->srv_log_fun,
options->srv_log_obj);
}
#endif
#if defined(MBEDTLS_SSL_CLI_C)
if (endpoint_type == MBEDTLS_SSL_IS_CLIENT &&
options->cli_log_fun != NULL) {
mbedtls_ssl_conf_dbg(&(ep->conf), options->cli_log_fun,
options->cli_log_obj);
}
#endif
#endif /* MBEDTLS_DEBUG_C */
ret = mbedtls_test_ssl_endpoint_certificate_init(ep, options->pk_alg,
options->opaque_alg,
options->opaque_alg2,
@ -1977,6 +1994,12 @@ void mbedtls_test_ssl_perform_handshake(
mbedtls_test_message_socket_init(&server_context);
mbedtls_test_message_socket_init(&client_context);
#if defined(MBEDTLS_DEBUG_C)
if (options->cli_log_fun || options->srv_log_fun) {
mbedtls_debug_set_threshold(4);
}
#endif
/* Client side */
if (options->dtls != 0) {
TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&client,
@ -2000,14 +2023,6 @@ void mbedtls_test_ssl_perform_handshake(
set_ciphersuite(&client.conf, options->cipher, forced_ciphersuite);
}
#if defined(MBEDTLS_DEBUG_C)
if (options->cli_log_fun) {
mbedtls_debug_set_threshold(4);
mbedtls_ssl_conf_dbg(&client.conf, options->cli_log_fun,
options->cli_log_obj);
}
#endif
/* Server side */
if (options->dtls != 0) {
TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&server,
@ -2072,14 +2087,6 @@ void mbedtls_test_ssl_perform_handshake(
}
#endif /* MBEDTLS_SSL_RENEGOTIATION */
#if defined(MBEDTLS_DEBUG_C)
if (options->srv_log_fun) {
mbedtls_debug_set_threshold(4);
mbedtls_ssl_conf_dbg(&server.conf, options->srv_log_fun,
options->srv_log_obj);
}
#endif
TEST_ASSERT(mbedtls_test_mock_socket_connect(&(client.socket),
&(server.socket),
BUFFSIZE) == 0);
@ -2419,4 +2426,40 @@ int mbedtls_test_tweak_tls13_certificate_msg_vector_len(
return 0;
}
#endif /* MBEDTLS_TEST_HOOKS */
/*
* Functions for tests based on tickets. Implementations of the
* write/parse ticket interfaces as defined by mbedtls_ssl_ticket_write/parse_t.
* Basically same implementations as in ticket.c without the encryption. That
* way we can tweak easily tickets characteristics to simulate misbehaving
* peers.
*/
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
int mbedtls_test_ticket_write(
void *p_ticket, const mbedtls_ssl_session *session,
unsigned char *start, const unsigned char *end,
size_t *tlen, uint32_t *lifetime)
{
int ret;
((void) p_ticket);
if ((ret = mbedtls_ssl_session_save(session, start, end - start,
tlen)) != 0) {
return ret;
}
/* Maximum ticket lifetime as defined in RFC 8446 */
*lifetime = 7 * 24 * 3600;
return 0;
}
int mbedtls_test_ticket_parse(void *p_ticket, mbedtls_ssl_session *session,
unsigned char *buf, size_t len)
{
((void) p_ticket);
return mbedtls_ssl_session_load(session, buf, len);
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#endif /* MBEDTLS_SSL_TLS_C */

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