Merge branch 'Mbed-TLS:development' into update-pkparse-tests-to-use-AES
This commit is contained in:
commit
4823d5ff0e
204 changed files with 11805 additions and 4116 deletions
5
.github/pull_request_template.md
vendored
5
.github/pull_request_template.md
vendored
|
@ -4,7 +4,9 @@ Please write a few sentences describing the overall goals of the pull request's
|
|||
|
||||
|
||||
|
||||
## Gatekeeper checklist
|
||||
## PR checklist
|
||||
|
||||
Please tick as appropriate and edit the reasons (e.g.: "backport: not needed because this is a new feature")
|
||||
|
||||
- [ ] **changelog** provided, or not required
|
||||
- [ ] **backport** done, or not required
|
||||
|
@ -16,4 +18,3 @@ Please write a few sentences describing the overall goals of the pull request's
|
|||
|
||||
Please refer to the [contributing guidelines](https://github.com/Mbed-TLS/mbedtls/blob/development/CONTRIBUTING.md), especially the
|
||||
checklist for PR contributors.
|
||||
|
||||
|
|
9
3rdparty/CMakeLists.txt
vendored
9
3rdparty/CMakeLists.txt
vendored
|
@ -1,5 +1,10 @@
|
|||
execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls/mbedtls_config.h get MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED RESULT_VARIABLE result)
|
||||
execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls/mbedtls_config.h get MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED RESULT_VARIABLE everest_result)
|
||||
execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls/mbedtls_config.h get MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED RESULT_VARIABLE p256m_result)
|
||||
|
||||
if(${result} EQUAL 0)
|
||||
if(${everest_result} EQUAL 0)
|
||||
add_subdirectory(everest)
|
||||
endif()
|
||||
|
||||
if(${p256m_result} EQUAL 0)
|
||||
add_subdirectory(p256-m)
|
||||
endif()
|
||||
|
|
3
3rdparty/Makefile.inc
vendored
3
3rdparty/Makefile.inc
vendored
|
@ -1,2 +1,3 @@
|
|||
THIRDPARTY_DIR = $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
THIRDPARTY_DIR = $(dir $(word 2, $(MAKEFILE_LIST)))
|
||||
include $(THIRDPARTY_DIR)/everest/Makefile.inc
|
||||
include $(THIRDPARTY_DIR)/p256-m/Makefile.inc
|
||||
|
|
25
3rdparty/p256-m/CMakeLists.txt
vendored
Normal file
25
3rdparty/p256-m/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
add_library(p256m
|
||||
p256-m_driver_entrypoints.c
|
||||
p256-m/p256-m.c)
|
||||
|
||||
target_include_directories(p256m
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/p256-m>
|
||||
$<BUILD_INTERFACE:${MBEDTLS_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
PRIVATE ${MBEDTLS_DIR}/library/)
|
||||
|
||||
if(INSTALL_MBEDTLS_HEADERS)
|
||||
|
||||
install(DIRECTORY :${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DESTINATION include
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
endif(INSTALL_MBEDTLS_HEADERS)
|
||||
|
||||
install(TARGETS p256m
|
||||
EXPORT MbedTLSTargets
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
5
3rdparty/p256-m/Makefile.inc
vendored
Normal file
5
3rdparty/p256-m/Makefile.inc
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
THIRDPARTY_INCLUDES+=-I../3rdparty/p256-m/p256-m/include -I../3rdparty/p256-m/p256-m/include/p256-m -I../3rdparty/p256-m/p256-m_driver_interface
|
||||
|
||||
THIRDPARTY_CRYPTO_OBJECTS+= \
|
||||
../3rdparty/p256-m//p256-m_driver_entrypoints.o \
|
||||
../3rdparty/p256-m//p256-m/p256-m.o
|
4
3rdparty/p256-m/README.md
vendored
Normal file
4
3rdparty/p256-m/README.md
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
The files within the `p256-m/` subdirectory originate from the [p256-m GitHub repository](https://github.com/mpg/p256-m), which is distributed under the Apache 2.0 license. They are authored by Manuel Pégourié-Gonnard. p256-m is a minimalistic implementation of ECDH and ECDSA on NIST P-256, especially suited to constrained 32-bit environments. Mbed TLS documentation for integrating drivers uses p256-m as an example of a software accelerator, and describes how it can be integrated alongside Mbed TLS. It should be noted that p256-m files in the Mbed TLS repo will not be updated regularly, so they may not have fixes and improvements present in the upstream project.
|
||||
|
||||
The files `p256-m.c` and `.h`, along with the license, have been taken from the `p256-m` repository.
|
||||
It should be noted that p256-m deliberately does not supply its own cryptographically secure RNG function. As a result, the PSA RNG is used, with `p256_generate_random()` wrapping `psa_generate_random()`.
|
202
3rdparty/p256-m/p256-m/LICENSE
vendored
Normal file
202
3rdparty/p256-m/p256-m/LICENSE
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
544
3rdparty/p256-m/p256-m/README.md
vendored
Normal file
544
3rdparty/p256-m/p256-m/README.md
vendored
Normal file
|
@ -0,0 +1,544 @@
|
|||
*This is the original README for the p256-m repository. Please note that as
|
||||
only a subset of p256-m's files are present in Mbed TLS, this README may refer
|
||||
to files that are not present/relevant here.*
|
||||
|
||||
p256-m is a minimalistic implementation of ECDH and ECDSA on NIST P-256,
|
||||
especially suited to constrained 32-bit environments. It's written in standard
|
||||
C, with optional bits of assembly for Arm Cortex-M and Cortex-A CPUs.
|
||||
|
||||
Its design is guided by the following goals in this order:
|
||||
|
||||
1. correctness & security;
|
||||
2. low code size & RAM usage;
|
||||
3. runtime performance.
|
||||
|
||||
Most cryptographic implementations care more about speed than footprint, and
|
||||
some might even risk weakening security for more speed. p256-m was written
|
||||
because I wanted to see what happened when reversing the usual emphasis.
|
||||
|
||||
The result is a full implementation of ECDH and ECDSA in **less than 3KiB of
|
||||
code**, using **less than 768 bytes of RAM**, with comparable performance
|
||||
to existing implementations (see below) - in less than 700 LOC.
|
||||
|
||||
_Contents of this Readme:_
|
||||
|
||||
- [Correctness](#correctness)
|
||||
- [Security](#security)
|
||||
- [Code size](#code-size)
|
||||
- [RAM usage](#ram-usage)
|
||||
- [Runtime performance](#runtime-performance)
|
||||
- [Comparison with other implementations](#comparison-with-other-implementations)
|
||||
- [Design overview](#design-overview)
|
||||
- [Notes about other curves](#notes-about-other-curves)
|
||||
- [Notes about other platforms](#notes-about-other-platforms)
|
||||
|
||||
## Correctness
|
||||
|
||||
**API design:**
|
||||
|
||||
- The API is minimal: only 4 public functions.
|
||||
- Each public function fully validates its inputs and returns specific errors.
|
||||
- The API uses arrays of octets for all input and output.
|
||||
|
||||
**Testing:**
|
||||
|
||||
- p256-m is validated against multiple test vectors from various RFCs and
|
||||
NIST.
|
||||
- In addition, crafted inputs are used for negative testing and to reach
|
||||
corner cases.
|
||||
- Two test suites are provided: one for closed-box testing (using only the
|
||||
public API), one for open-box testing (for unit-testing internal functions,
|
||||
and reaching more error cases by exploiting knowledge of how the RNG is used).
|
||||
- The resulting branch coverage is maximal: closed-box testing reaches all
|
||||
branches except four; three of them are reached by open-box testing using a
|
||||
rigged RNG; the last branch could only be reached by computing a discrete log
|
||||
on P-256... See `coverage.sh`.
|
||||
- Testing also uses dynamic analysis: valgrind, ASan, MemSan, UBSan.
|
||||
|
||||
**Code quality:**
|
||||
|
||||
- The code is standard C99; it builds without warnings with `clang
|
||||
-Weverything` and `gcc -Wall -Wextra -pedantic`.
|
||||
- The code is small and well documented, including internal APIs: with the
|
||||
header file, it's less than 700 lines of code, and more lines of comments
|
||||
than of code.
|
||||
- However it _has not been reviewed_ independently so far, as this is a
|
||||
personal project.
|
||||
|
||||
**Short Weierstrass pitfalls:**
|
||||
|
||||
Its has been [pointed out](https://safecurves.cr.yp.to/) that the NIST curves,
|
||||
and indeed all Short Weierstrass curves, have a number of pitfalls including
|
||||
risk for the implementation to:
|
||||
|
||||
- "produce incorrect results for some rare curve points" - this is avoided by
|
||||
carefully checking the validity domain of formulas used throughout the code;
|
||||
- "leak secret data when the input isn't a curve point" - this is avoided by
|
||||
validating that points lie on the curve every time a point is deserialized.
|
||||
|
||||
## Security
|
||||
|
||||
In addition to the above correctness claims, p256-m has the following
|
||||
properties:
|
||||
|
||||
- it has no branch depending (even indirectly) on secret data;
|
||||
- it has no memory access depending (even indirectly) on secret data.
|
||||
|
||||
These properties are checked using valgrind and MemSan with the ideas
|
||||
behind [ctgrind](https://github.com/agl/ctgrind), see `consttime.sh`.
|
||||
|
||||
In addition to avoiding branches and memory accesses depending on secret data,
|
||||
p256-m also avoid instructions (or library functions) whose execution time
|
||||
depends on the value of operands on cores of interest. Namely, it never uses
|
||||
integer division, and for multiplication by default it only uses 16x16->32 bit
|
||||
unsigned multiplication. On cores which have a constant-time 32x32->64 bit
|
||||
unsigned multiplication instruction, the symbol `MUL64_IS_CONSTANT_TIME` can
|
||||
be defined by the user at compile-time to take advantage of it in order to
|
||||
improve performance and code size. (On Cortex-M and Cortex-A cores wtih GCC or
|
||||
Clang this is not necessary, since inline assembly is used instead.)
|
||||
|
||||
As a result, p256-m should be secure against the following classes of attackers:
|
||||
|
||||
1. attackers who can only manipulate the input and observe the output;
|
||||
2. attackers who can also measure the total computation time of the operation;
|
||||
3. attackers who can also observe and manipulate micro-architectural features
|
||||
such as the cache or branch predictor with arbitrary precision.
|
||||
|
||||
However, p256-m makes no attempt to protect against:
|
||||
|
||||
4. passive physical attackers who can record traces of physical emissions
|
||||
(power, EM, sound) of the CPU while it manipulates secrets;
|
||||
5. active physical attackers who can also inject faults in the computation.
|
||||
|
||||
(Note: p256-m should actually be secure against SPA, by virtue of being fully
|
||||
constant-flow, but is not expected to resist any other physical attack.)
|
||||
|
||||
**Warning:** p256-m requires an externally-provided RNG function. If that
|
||||
function is not cryptographically secure, then neither is p256-m's key
|
||||
generation or ECDSA signature generation.
|
||||
|
||||
_Note:_ p256-m also follows best practices such as securely erasing secret
|
||||
data on the stack before returning.
|
||||
|
||||
## Code size
|
||||
|
||||
Compiled with
|
||||
[ARM-GCC 9](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads),
|
||||
with `-mthumb -Os`, here are samples of code sizes reached on selected cores:
|
||||
|
||||
- Cortex-M0: 2988 bytes
|
||||
- Cortex-M4: 2900 bytes
|
||||
- Cortex-A7: 2924 bytes
|
||||
|
||||
Clang was also tried but tends to generate larger code (by about 10%). For
|
||||
details, see `sizes.sh`.
|
||||
|
||||
**What's included:**
|
||||
|
||||
- Full input validation and (de)serialisation of input/outputs to/from bytes.
|
||||
- Cleaning up secret values from the stack before returning from a function.
|
||||
- The code has no dependency on libc functions or the toolchain's runtime
|
||||
library (such as helpers for long multiply); this can be checked for the
|
||||
Arm-GCC toolchain with the `deps.sh` script.
|
||||
|
||||
**What's excluded:**
|
||||
|
||||
- A secure RNG function needs to be provided externally, see
|
||||
`p256_generate_random()` in `p256-m.h`.
|
||||
|
||||
## RAM usage
|
||||
|
||||
p256-m doesn't use any dynamic memory (on the heap), only the stack. Here's
|
||||
how much stack is used by each of its 4 public functions on selected cores:
|
||||
|
||||
| Function | Cortex-M0 | Cortex-M4 | Cortex-A7 |
|
||||
| ------------------------- | --------: | --------: | --------: |
|
||||
| `p256_gen_keypair` | 608 | 564 | 564 |
|
||||
| `p256_ecdh_shared_secret` | 640 | 596 | 596 |
|
||||
| `p256_ecdsa_sign` | 664 | 604 | 604 |
|
||||
| `p256_ecdsa_verify` | 752 | 700 | 700 |
|
||||
|
||||
For details, see `stack.sh`, `wcs.py` and `libc.msu` (the above figures assume
|
||||
that the externally-provided RNG function uses at most 384 bytes of stack).
|
||||
|
||||
## Runtime performance
|
||||
|
||||
Here are the timings of each public function in milliseconds measured on
|
||||
platforms based on a selection of cores:
|
||||
|
||||
- Cortex-M0 at 48 MHz: STM32F091 board running Mbed OS 6
|
||||
- Cortex-M4 at 100 MHz: STM32F411 board running Mbed OS 6
|
||||
- Cortex-A7 at 900 MHz: Raspberry Pi 2B running Raspbian Buster
|
||||
|
||||
| Function | Cortex-M0 | Cortex-M4 | Cortex-A7 |
|
||||
| ------------------------- | --------: | --------: | --------: |
|
||||
| `p256_gen_keypair` | 921 | 145 | 11 |
|
||||
| `p256_ecdh_shared_secret` | 922 | 144 | 11 |
|
||||
| `p256_ecdsa_sign` | 990 | 155 | 12 |
|
||||
| `p256_ecdsa_verify` | 1976 | 309 | 24 |
|
||||
| Sum of the above | 4809 | 753 | 59 |
|
||||
|
||||
The sum of these operations corresponds to a TLS handshake using ECDHE-ECDSA
|
||||
with mutual authentication based on raw public keys or directly-trusted
|
||||
certificates (otherwise, add one 'verify' for each link in the peer's
|
||||
certificate chain).
|
||||
|
||||
_Note_: the above figures where obtained by compiling with GCC, which is able
|
||||
to use inline assembly. Without that inline assembly (22 lines for Cortex-M0,
|
||||
1 line for Cortex-M4), the code would be roughly 2 times slower on those
|
||||
platforms. (The effect is much less important on the Cortex-A7 core.)
|
||||
|
||||
For details, see `bench.sh`, `benchmark.c` and `on-target-benchmark/`.
|
||||
|
||||
## Comparison with other implementations
|
||||
|
||||
The most relevant/convenient implementation for comparisons is
|
||||
[TinyCrypt](https://github.com/intel/tinycrypt), as it's also a standalone
|
||||
implementation of ECDH and ECDSA on P-256 only, that also targets constrained
|
||||
devices. Other implementations tend to implement many curves and build on a
|
||||
shared bignum/MPI module (possibly also supporting RSA), which makes fair
|
||||
comparisons less convenient.
|
||||
|
||||
The scripts used for TinyCrypt measurements are available in [this
|
||||
branch](https://github.com/mpg/tinycrypt/tree/measurements), based on version
|
||||
0.2.8.
|
||||
|
||||
**Code size**
|
||||
|
||||
| Core | p256-m | TinyCrypt |
|
||||
| --------- | -----: | --------: |
|
||||
| Cortex-M0 | 2988 | 6134 |
|
||||
| Cortex-M4 | 2900 | 5934 |
|
||||
| Cortex-A7 | 2924 | 5934 |
|
||||
|
||||
**RAM usage**
|
||||
|
||||
TinyCrypto also uses no heap, only the stack. Here's the RAM used by each
|
||||
operation on a Cortex-M0 core:
|
||||
|
||||
| operation | p256-m | TinyCrypt |
|
||||
| ------------------ | -----: | --------: |
|
||||
| key generation | 608 | 824 |
|
||||
| ECDH shared secret | 640 | 728 |
|
||||
| ECDSA sign | 664 | 880 |
|
||||
| ECDSA verify | 752 | 824 |
|
||||
|
||||
On a Cortex-M4 or Cortex-A7 core (identical numbers):
|
||||
|
||||
| operation | p256-m | TinyCrypt |
|
||||
| ------------------ | -----: | --------: |
|
||||
| key generation | 564 | 796 |
|
||||
| ECDH shared secret | 596 | 700 |
|
||||
| ECDSA sign | 604 | 844 |
|
||||
| ECDSA verify | 700 | 808 |
|
||||
|
||||
**Runtime performance**
|
||||
|
||||
Here are the timings of each operation in milliseconds measured on
|
||||
platforms based on a selection of cores:
|
||||
|
||||
_Cortex-M0_ at 48 MHz: STM32F091 board running Mbed OS 6
|
||||
|
||||
| Operation | p256-m | TinyCrypt |
|
||||
| ------------------ | -----: | --------: |
|
||||
| Key generation | 921 | 979 |
|
||||
| ECDH shared secret | 922 | 975 |
|
||||
| ECDSA sign | 990 | 1009 |
|
||||
| ECDSA verify | 1976 | 1130 |
|
||||
| Sum of those 4 | 4809 | 4093 |
|
||||
|
||||
_Cortex-M4_ at 100 MHz: STM32F411 board running Mbed OS 6
|
||||
|
||||
| Operation | p256-m | TinyCrypt |
|
||||
| ------------------ | -----: | --------: |
|
||||
| Key generation | 145 | 178 |
|
||||
| ECDH shared secret | 144 | 177 |
|
||||
| ECDSA sign | 155 | 188 |
|
||||
| ECDSA verify | 309 | 210 |
|
||||
| Sum of those 4 | 753 | 753 |
|
||||
|
||||
_Cortex-A7_ at 900 MHz: Raspberry Pi 2B running Raspbian Buster
|
||||
|
||||
| Operation | p256-m | TinyCrypt |
|
||||
| ------------------ | -----: | --------: |
|
||||
| Key generation | 11 | 13 |
|
||||
| ECDH shared secret | 11 | 13 |
|
||||
| ECDSA sign | 12 | 14 |
|
||||
| ECDSA verify | 24 | 15 |
|
||||
| Sum of those 4 | 59 | 55 |
|
||||
|
||||
_64-bit Intel_ (i7-6500U at 2.50GHz) laptop running Ubuntu 20.04
|
||||
|
||||
Note: results in microseconds (previous benchmarks in milliseconds)
|
||||
|
||||
| Operation | p256-m | TinyCrypt |
|
||||
| ------------------ | -----: | --------: |
|
||||
| Key generation | 1060 | 1627 |
|
||||
| ECDH shared secret | 1060 | 1611 |
|
||||
| ECDSA sign | 1136 | 1712 |
|
||||
| ECDSA verify | 2279 | 1888 |
|
||||
| Sum of those 4 | 5535 | 6838 |
|
||||
|
||||
**Other differences**
|
||||
|
||||
- While p256-m fully validates all inputs, Tinycrypt's ECDH shared secret
|
||||
function doesn't include validation of the peer's public key, which should be
|
||||
done separately by the user for static ECDH (there are attacks [when users
|
||||
forget](https://link.springer.com/chapter/10.1007/978-3-319-24174-6_21)).
|
||||
- The two implementations have slightly different security characteristics:
|
||||
p256-m is fully constant-time from the ground up so should be more robust
|
||||
than TinyCrypt against powerful local attackers (such as an untrusted OS
|
||||
attacking a secure enclave); on the other hand TinyCrypt includes coordinate
|
||||
randomisation which protects against some passive physical attacks (such as
|
||||
DPA, see Table 3, column C9 of [this
|
||||
paper](https://www.esat.kuleuven.be/cosic/publications/article-2293.pdf#page=12)),
|
||||
which p256-m completely ignores.
|
||||
- TinyCrypt's code looks like it could easily be expanded to support other
|
||||
curves, while p256-m has much more hard-coded to minimize code size (see
|
||||
"Notes about other curves" below).
|
||||
- TinyCrypt uses a specialised routine for reduction modulo the curve prime,
|
||||
exploiting its structure as a Solinas prime, which should be faster than the
|
||||
generic Montgomery reduction used by p256-m, but other factors appear to
|
||||
compensate for that.
|
||||
- TinyCrypt uses Co-Z Jacobian formulas for point operation, which should be
|
||||
faster (though a bit larger) than the mixed affine-Jacobian formulas
|
||||
used by p256-m, but again other factors appear to compensate for that.
|
||||
- p256-m uses bits of inline assembly for 64-bit multiplication on the
|
||||
platforms used for benchmarking, while TinyCrypt uses only C (and the
|
||||
compiler's runtime library).
|
||||
- TinyCrypt uses a specialised routine based on Shamir's trick for
|
||||
ECDSA verification, which gives much better performance than the generic
|
||||
code that p256-m uses in order to minimize code size.
|
||||
|
||||
## Design overview
|
||||
|
||||
The implementation is contained in a single file to keep most functions static
|
||||
and allow for more optimisations. It is organized in multiple layers:
|
||||
|
||||
- Fixed-width multi-precision arithmetic
|
||||
- Fixed-width modular arithmetic
|
||||
- Operations on curve points
|
||||
- Operations with scalars
|
||||
- The public API
|
||||
|
||||
**Multi-precision arithmetic.**
|
||||
|
||||
Large integers are represented as arrays of `uint32_t` limbs. When carries may
|
||||
occur, casts to `uint64_t` are used to nudge the compiler towards using the
|
||||
CPU's carry flag. When overflow may occur, functions return a carry flag.
|
||||
|
||||
This layer contains optional assembly for Cortex-M and Cortex-A cores, for the
|
||||
internal `u32_muladd64()` function, as well as two pure C versions of this
|
||||
function, depending on whether `MUL64_IS_CONSTANT_TIME`.
|
||||
|
||||
This layer's API consists of:
|
||||
|
||||
- addition, subtraction;
|
||||
- multiply-and-add, shift by one limb (for Montgomery multiplication);
|
||||
- conditional assignment, assignment of a small value;
|
||||
- comparison of two values for equality, comparison to 0 for equality;
|
||||
- (de)serialization as big-endian arrays of bytes.
|
||||
|
||||
**Modular arithmetic.**
|
||||
|
||||
All modular operations are done in the Montgomery domain, that is x is
|
||||
represented by `x * 2^256 mod m`; integers need to be converted to that domain
|
||||
before computations, and back from it afterwards. Montgomery constants
|
||||
associated to the curve's p and n are pre-computed and stored in static
|
||||
structures.
|
||||
|
||||
Modular inversion is computed using Fermat's little theorem to get
|
||||
constant-time behaviour with respect to the value being inverted.
|
||||
|
||||
This layer's API consists of:
|
||||
|
||||
- the curve's constants p and n (and associated Montgomery constants);
|
||||
- modular addition, subtraction, multiplication, and inversion;
|
||||
- assignment of a small value;
|
||||
- conversion to/from Montgomery domain;
|
||||
- (de)serialization to/from bytes with integrated range checking and
|
||||
Montgomery domain conversion.
|
||||
|
||||
**Operations on curve points.**
|
||||
|
||||
Curve points are represented using either affine or Jacobian coordinates;
|
||||
affine coordinates are extended to represent 0 as (0,0). Individual
|
||||
coordinates are always in the Montgomery domain.
|
||||
|
||||
Not all formulas associated with affine or Jacobian coordinates are complete;
|
||||
great care is taken to document and satisfy each function's pre-conditions.
|
||||
|
||||
This layer's API consists of:
|
||||
|
||||
- curve constants: b from the equation, the base point's coordinates;
|
||||
- point validity check (on the curve and not 0);
|
||||
- Jacobian to affine coordinate conversion;
|
||||
- point doubling in Jacobian coordinates (complete formulas);
|
||||
- point addition in mixed affine-Jacobian coordinates (P not in {0, Q, -Q});
|
||||
- point addition-or-doubling in affine coordinates (leaky version, only used
|
||||
for ECDSA verify where all data is public);
|
||||
- (de)serialization to/from bytes with integrated validity checking
|
||||
|
||||
**Scalar operations.**
|
||||
|
||||
The crucial function here is scalar multiplication. It uses a signed binary
|
||||
ladder, which is a variant of the good old double-and-add algorithm where an
|
||||
addition/subtraction is performed at each step. Again, care is taken to make
|
||||
sure the pre-conditions for the addition formulas are always satisfied. The
|
||||
signed binary ladder only works if the scalar is odd; this is ensured by
|
||||
negating both the scalar (mod n) and the input point if necessary.
|
||||
|
||||
This layer's API consists of:
|
||||
|
||||
- scalar multiplication
|
||||
- de-serialization from bytes with integrated range checking
|
||||
- generation of a scalar and its associated public key
|
||||
|
||||
**Public API.**
|
||||
|
||||
This layer builds on the others, but unlike them, all inputs and outputs are
|
||||
byte arrays. Key generation and ECDH shared secret computation are thin
|
||||
wrappers around internal functions, just taking care of format conversions and
|
||||
errors. The ECDSA functions have more non-trivial logic.
|
||||
|
||||
This layer's API consists of:
|
||||
|
||||
- key-pair generation
|
||||
- ECDH shared secret computation
|
||||
- ECDSA signature creation
|
||||
- ECDSA signature verification
|
||||
|
||||
**Testing.**
|
||||
|
||||
A self-contained, straightforward, pure-Python implementation was first
|
||||
produced as a warm-up and to help check intermediate values. Test vectors from
|
||||
various sources are embedded and used to validate the implementation.
|
||||
|
||||
This implementation, `p256.py`, is used by a second Python script,
|
||||
`gen-test-data.py`, to generate additional data for both positive and negative
|
||||
testing, available from a C header file, that is then used by the closed-box
|
||||
and open-box test programs.
|
||||
|
||||
p256-m can be compiled with extra instrumentation to mark secret data and
|
||||
allow either valgrind or MemSan to check that no branch or memory access
|
||||
depends on it (even indirectly). Macros are defined for this purpose near the
|
||||
top of the file.
|
||||
|
||||
**Tested platforms.**
|
||||
|
||||
There are 4 versions of the internal function `u32_muladd64`: two assembly
|
||||
versions, for Cortex-M/A cores with or without the DSP extension, and two
|
||||
pure-C versions, depending on whether `MUL64_IS_CONSTANT_TIME`.
|
||||
|
||||
Tests are run on the following platforms:
|
||||
|
||||
- `make` on x64 tests the pure-C version without `MUL64_IS_CONSTANT_TIME`
|
||||
(with Clang).
|
||||
- `./consttime.sh` on x64 tests both pure-C versions (with Clang).
|
||||
- `make` on Arm v7-A (Raspberry Pi 2) tests the Arm-DSP assembly version (with
|
||||
Clang).
|
||||
- `on-target-*box` on boards based on Cortex-M0 and M4 cores test both
|
||||
assembly versions (with GCC).
|
||||
|
||||
In addition:
|
||||
|
||||
- `sizes.sh` builds the code for three Arm cores with GCC and Clang.
|
||||
- `deps.sh` checks for external dependencies with GCC.
|
||||
|
||||
## Notes about other curves
|
||||
|
||||
It should be clear that minimal code size can only be reached by specializing
|
||||
the implementation to the curve at hand. Here's a list of things in the
|
||||
implementation that are specific to the NIST P-256 curve, and how the
|
||||
implementation could be changed to expand to other curves, layer by layer (see
|
||||
"Design Overview" above).
|
||||
|
||||
**Fixed-width multi-precision arithmetic:**
|
||||
|
||||
- The number of limbs is hard-coded to 8. For other 256-bit curves, nothing to
|
||||
change. For a curve of another size, hard-code to another value. For multiple
|
||||
curves of various sizes, add a parameter to each function specifying the
|
||||
number of limbs; when declaring arrays, always use the maximum number of
|
||||
limbs.
|
||||
|
||||
**Fixed-width modular arithmetic:**
|
||||
|
||||
- The values of the curve's constant p and n, and their associated Montgomery
|
||||
constants, are hard-coded. For another curve, just hard-code the new constants.
|
||||
For multiple other curves, define all the constants, and from this layer's API
|
||||
only keep the functions that already accept a `mod` parameter (that is, remove
|
||||
convenience functions `m256_xxx_p()`).
|
||||
- The number of limbs is again hard-coded to 8. See above, but it order to
|
||||
support multiple sizes there is no need to add a new parameter to functions
|
||||
in this layer: the existing `mod` parameter can include the number of limbs as
|
||||
well.
|
||||
|
||||
**Operations on curve points:**
|
||||
|
||||
- The values of the curve's constants b (constant term from the equation) and
|
||||
gx, gy (coordinates of the base point) are hard-coded. For another curve,
|
||||
hard-code the other values. For multiple curves, define each curve's value and
|
||||
add a "curve id" parameter to all functions in this layer.
|
||||
- The value of the curve's constant a is implicitly hard-coded to `-3` by using
|
||||
a standard optimisation to save one multiplication in the first step of
|
||||
`point_double()`. For curves that don't have a == -3, replace that with the
|
||||
normal computation.
|
||||
- The fact that b != 0 in the curve equation is used indirectly, to ensure
|
||||
that (0, 0) is not a point on the curve and re-use that value to represent
|
||||
the point 0. As far as I know, all Short Weierstrass curves standardized so
|
||||
far have b != 0.
|
||||
- The shape of the curve is assumed to be Short Weierstrass. For other curve
|
||||
shapes (Montgomery, (twisted) Edwards), this layer would probably look very
|
||||
different (both implementation and API).
|
||||
|
||||
**Scalar operations:**
|
||||
|
||||
- If multiple curves are to be supported, all function in this layer need to
|
||||
gain a new "curve id" parameter.
|
||||
- This layer assumes that the bit size of the curve's order n is the same as
|
||||
that of the modulus p. This is true of most curves standardized so far, the
|
||||
only exception being secp224k1. If that curve were to be supported, the
|
||||
representation of `n` and scalars would need adapting to allow for an extra
|
||||
limb.
|
||||
- The bit size of the curve's order is hard-coded in `scalar_mult()`. For
|
||||
multiple curves, this should be deduced from the "curve id" parameter.
|
||||
- The `scalar_mult()` function exploits the fact that the second least
|
||||
significant bit of the curve's order n is set in order to avoid a special
|
||||
case. For curve orders that don't meet this criterion, we can just handle that
|
||||
special case (multiplication by +-2) separately (always compute that and
|
||||
conditionally assign it to the result).
|
||||
- The shape of the curve is again assumed to be Short Weierstrass. For other curve
|
||||
shapes (Montgomery, (twisted) Edwards), this layer would probably have a
|
||||
very different implementation.
|
||||
|
||||
**Public API:**
|
||||
|
||||
- For multiple curves, all functions in this layer would need to gain a "curve
|
||||
id" parameter and handle variable-sized input/output.
|
||||
- The shape of the curve is again assumed to be Short Weierstrass. For other curve
|
||||
shapes (Montgomery, (twisted) Edwards), the ECDH API would probably look
|
||||
quite similar (with differences in the size of public keys), but the ECDSA API
|
||||
wouldn't apply and an EdDSA API would look pretty different.
|
||||
|
||||
## Notes about other platforms
|
||||
|
||||
While p256-m is standard C99, it is written with constrained 32-bit platforms
|
||||
in mind and makes a few assumptions about the platform:
|
||||
|
||||
- The types `uint8_t`, `uint16_t`, `uint32_t` and `uint64_t` exist.
|
||||
- 32-bit unsigned addition and subtraction with carry are constant time.
|
||||
- 16x16->32-bit unsigned multiplication is available and constant time.
|
||||
|
||||
Also, on platforms on which 64-bit addition and subtraction with carry, or
|
||||
even 64x64->128-bit multiplication, are available, p256-m makes no use of
|
||||
them, though they could significantly improve performance.
|
||||
|
||||
This could be improved by replacing uses of arrays of `uint32_t` with a
|
||||
defined type throughout the internal APIs, and then on 64-bit platforms define
|
||||
that type to be an array of `uint64_t` instead, and making the obvious
|
||||
adaptations in the multi-precision arithmetic layer.
|
||||
|
||||
Finally, the optional assembly code (which boosts performance by a factor 2 on
|
||||
tested Cortex-M CPUs, while slightly reducing code size and stack usage) is
|
||||
currently only available with compilers that support GCC's extended asm
|
||||
syntax (which includes GCC and Clang).
|
1470
3rdparty/p256-m/p256-m/p256-m.c
vendored
Normal file
1470
3rdparty/p256-m/p256-m/p256-m.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
95
3rdparty/p256-m/p256-m/p256-m.h
vendored
Normal file
95
3rdparty/p256-m/p256-m/p256-m.h
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Interface of curve P-256 (ECDH and ECDSA)
|
||||
*
|
||||
* Author: Manuel Pégourié-Gonnard.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef P256_M_H
|
||||
#define P256_M_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Status codes */
|
||||
#define P256_SUCCESS 0
|
||||
#define P256_RANDOM_FAILED -1
|
||||
#define P256_INVALID_PUBKEY -2
|
||||
#define P256_INVALID_PRIVKEY -3
|
||||
#define P256_INVALID_SIGNATURE -4
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RNG function - must be provided externally and be cryptographically secure.
|
||||
*
|
||||
* in: output - must point to a writable buffer of at least output_size bytes.
|
||||
* output_size - the number of random bytes to write to output.
|
||||
* out: output is filled with output_size random bytes.
|
||||
* return 0 on success, non-zero on errors.
|
||||
*/
|
||||
extern int p256_generate_random(uint8_t * output, unsigned output_size);
|
||||
|
||||
/*
|
||||
* ECDH/ECDSA generate key pair
|
||||
*
|
||||
* [in] draws from p256_generate_random()
|
||||
* [out] priv: on success, holds the private key, as a big-endian integer
|
||||
* [out] pub: on success, holds the public key, as two big-endian integers
|
||||
*
|
||||
* return: P256_SUCCESS on success
|
||||
* P256_RANDOM_FAILED on failure
|
||||
*/
|
||||
int p256_gen_keypair(uint8_t priv[32], uint8_t pub[64]);
|
||||
|
||||
/*
|
||||
* ECDH compute shared secret
|
||||
*
|
||||
* [out] secret: on success, holds the shared secret, as a big-endian integer
|
||||
* [in] priv: our private key as a big-endian integer
|
||||
* [in] pub: the peer's public key, as two big-endian integers
|
||||
*
|
||||
* return: P256_SUCCESS on success
|
||||
* P256_INVALID_PRIVKEY if priv is invalid
|
||||
* P256_INVALID_PUBKEY if pub is invalid
|
||||
*/
|
||||
int p256_ecdh_shared_secret(uint8_t secret[32],
|
||||
const uint8_t priv[32], const uint8_t pub[64]);
|
||||
|
||||
/*
|
||||
* ECDSA sign
|
||||
*
|
||||
* [in] draws from p256_generate_random()
|
||||
* [out] sig: on success, holds the signature, as two big-endian integers
|
||||
* [in] priv: our private key as a big-endian integer
|
||||
* [in] hash: the hash of the message to be signed
|
||||
* [in] hlen: the size of hash in bytes
|
||||
*
|
||||
* return: P256_SUCCESS on success
|
||||
* P256_RANDOM_FAILED on failure
|
||||
* P256_INVALID_PRIVKEY if priv is invalid
|
||||
*/
|
||||
int p256_ecdsa_sign(uint8_t sig[64], const uint8_t priv[32],
|
||||
const uint8_t *hash, size_t hlen);
|
||||
|
||||
/*
|
||||
* ECDSA verify
|
||||
*
|
||||
* [in] sig: the signature to be verified, as two big-endian integers
|
||||
* [in] pub: the associated public key, as two big-endian integers
|
||||
* [in] hash: the hash of the message that was signed
|
||||
* [in] hlen: the size of hash in bytes
|
||||
*
|
||||
* return: P256_SUCCESS on success - the signature was verified as valid
|
||||
* P256_INVALID_PUBKEY if pub is invalid
|
||||
* P256_INVALID_SIGNATURE if the signature was found to be invalid
|
||||
*/
|
||||
int p256_ecdsa_verify(const uint8_t sig[64], const uint8_t pub[64],
|
||||
const uint8_t *hash, size_t hlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* P256_M_H */
|
242
3rdparty/p256-m/p256-m_driver_entrypoints.c
vendored
Normal file
242
3rdparty/p256-m/p256-m_driver_entrypoints.c
vendored
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Driver entry points for p256-m
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "p256-m_driver_entrypoints.h"
|
||||
#include "p256-m/p256-m.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_driver_wrappers.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)
|
||||
|
||||
/* INFORMATION ON PSA KEY EXPORT FORMATS:
|
||||
*
|
||||
* PSA exports SECP256R1 keys in two formats:
|
||||
* 1. Keypair format: 32 byte string which is just the private key (public key
|
||||
* can be calculated from the private key)
|
||||
* 2. Public Key format: A leading byte 0x04 (indicating uncompressed format),
|
||||
* followed by the 64 byte public key. This results in a
|
||||
* total of 65 bytes.
|
||||
*
|
||||
* p256-m's internal format for private keys matches PSA. Its format for public
|
||||
* keys is only 64 bytes; the same as PSA but without the leading byte (0x04).
|
||||
* Hence, when passing public keys from PSA to p256-m, the leading byte is
|
||||
* removed.
|
||||
*/
|
||||
|
||||
/* Convert between p256-m and PSA error codes */
|
||||
static psa_status_t p256_to_psa_error(int ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case P256_SUCCESS:
|
||||
return PSA_SUCCESS;
|
||||
case P256_INVALID_PUBKEY:
|
||||
case P256_INVALID_PRIVKEY:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
case P256_INVALID_SIGNATURE:
|
||||
return PSA_ERROR_INVALID_SIGNATURE;
|
||||
case P256_RANDOM_FAILED:
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length)
|
||||
{
|
||||
/* We don't use this argument, but the specification mandates the signature
|
||||
* of driver entry-points. (void) used to avoid compiler warning. */
|
||||
(void) attributes;
|
||||
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
/*
|
||||
* p256-m generates a 32 byte private key, and expects to write to a buffer
|
||||
* that is of that size. */
|
||||
if (key_buffer_size != 32) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* p256-m's keypair generation function outputs both public and private
|
||||
* keys. Allocate a buffer to which the public key will be written. The
|
||||
* private key will be written to key_buffer, which is passed to this
|
||||
* function as an argument. */
|
||||
uint8_t public_key_buffer[64];
|
||||
|
||||
status = p256_to_psa_error(
|
||||
p256_gen_keypair(key_buffer, public_key_buffer));
|
||||
if (status == PSA_SUCCESS) {
|
||||
*key_buffer_length = 32;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_key_agreement(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length)
|
||||
{
|
||||
/* We don't use these arguments, but the specification mandates the
|
||||
* sginature of driver entry-points. (void) used to avoid compiler
|
||||
* warning. */
|
||||
(void) attributes;
|
||||
(void) alg;
|
||||
|
||||
/*
|
||||
* Check that private key = 32 bytes, peer public key = 65 bytes,
|
||||
* and that the shared secret buffer is big enough. */
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
if (key_buffer_size != 32 || shared_secret_size < 32 ||
|
||||
peer_key_length != 65) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* We add 1 to peer_key pointer to omit the leading byte of the public key
|
||||
* representation (0x04). See information about PSA key formats at the top
|
||||
* of the file. */
|
||||
status = p256_to_psa_error(
|
||||
p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key+1));
|
||||
if (status == PSA_SUCCESS) {
|
||||
*shared_secret_length = 32;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length)
|
||||
{
|
||||
/* We don't use these arguments, but the specification mandates the
|
||||
* sginature of driver entry-points. (void) used to avoid compiler
|
||||
* warning. */
|
||||
(void) attributes;
|
||||
(void) alg;
|
||||
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
if (key_buffer_size != 32 || signature_size != 64) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = p256_to_psa_error(
|
||||
p256_ecdsa_sign(signature, key_buffer, hash, hash_length));
|
||||
if (status == PSA_SUCCESS) {
|
||||
*signature_length = 64;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* This function expects the key buffer to contain a 65 byte public key,
|
||||
* as exported by psa_export_public_key() */
|
||||
static psa_status_t p256_verify_hash_with_public_key(
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
if (key_buffer_size != 65 || signature_length != 64 || *key_buffer != 0x04) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* We add 1 to public_key_buffer pointer to omit the leading byte of the
|
||||
* public key representation (0x04). See information about PSA key formats
|
||||
* at the top of the file. */
|
||||
const uint8_t *public_key_buffer = key_buffer + 1;
|
||||
status = p256_to_psa_error(
|
||||
p256_ecdsa_verify(signature, public_key_buffer, hash, hash_length));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
/* We don't use this argument, but the specification mandates the signature
|
||||
* of driver entry-points. (void) used to avoid compiler warning. */
|
||||
(void) alg;
|
||||
|
||||
psa_status_t status;
|
||||
uint8_t public_key_buffer[65];
|
||||
size_t public_key_buffer_size = 65;
|
||||
|
||||
size_t public_key_length = 65;
|
||||
/* As p256-m doesn't require dynamic allocation, we want to avoid it in
|
||||
* the entrypoint functions as well. psa_driver_wrapper_export_public_key()
|
||||
* requires size_t*, so we use a pointer to a stack variable. */
|
||||
size_t *public_key_length_ptr = &public_key_length;
|
||||
|
||||
/* The contents of key_buffer may either be the 32 byte private key
|
||||
* (keypair format), or 0x04 followed by the 64 byte public key (public
|
||||
* key format). To ensure the key is in the latter format, the public key
|
||||
* is exported. */
|
||||
status = psa_driver_wrapper_export_public_key(
|
||||
attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
public_key_buffer,
|
||||
public_key_buffer_size,
|
||||
public_key_length_ptr);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = p256_verify_hash_with_public_key(
|
||||
public_key_buffer,
|
||||
public_key_buffer_size,
|
||||
hash,
|
||||
hash_length,
|
||||
signature,
|
||||
signature_length);
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED */
|
162
3rdparty/p256-m/p256-m_driver_entrypoints.h
vendored
Normal file
162
3rdparty/p256-m/p256-m_driver_entrypoints.h
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Driver entry points for p256-m
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef P256M_DRIVER_ENTRYPOINTS_H
|
||||
#define P256M_DRIVER_ENTRYPOINTS_H
|
||||
|
||||
#if defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
#endif /* MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED */
|
||||
|
||||
#include "psa/crypto_types.h"
|
||||
|
||||
/** Generate SECP256R1 ECC Key Pair.
|
||||
* Interface function which calls the p256-m key generation function and
|
||||
* places it in the key buffer provided by the caller (mbed TLS) in the
|
||||
* correct format. For a SECP256R1 curve this is the 32 bit private key.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[out] key_buffer The buffer to contain the key data in
|
||||
* output format upon successful return.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[out] key_buffer_length The length of the data written in \p
|
||||
* key_buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Keypair generated and stored in buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_GENERIC_ERROR
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
*/
|
||||
psa_status_t p256_transparent_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length);
|
||||
|
||||
/** Perform raw key agreement using p256-m's ECDH implementation
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the private key
|
||||
* in the format specified by PSA.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg A key agreement algorithm that is
|
||||
* compatible with the type of the key.
|
||||
* \param[in] peer_key The buffer containing the peer's public
|
||||
* key in format specified by PSA.
|
||||
* \param[in] peer_key_length Size of the \p peer_key buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret The buffer to which the shared secret
|
||||
* is to be written.
|
||||
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret_length On success, the number of bytes that
|
||||
* make up the returned shared secret.
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Shared secret successfully calculated.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t p256_transparent_key_agreement(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length);
|
||||
|
||||
/** Sign an already-calculated hash with a private key using p256-m's ECDSA
|
||||
* implementation
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the private key
|
||||
* in the format specified by PSA.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg A signature algorithm that is compatible
|
||||
* with the type of the key.
|
||||
* \param[in] hash The hash to sign.
|
||||
* \param[in] hash_length Size of the \p hash buffer in bytes.
|
||||
* \param[out] signature Buffer where signature is to be written.
|
||||
* \param[in] signature_size Size of the \p signature buffer in bytes.
|
||||
* \param[out] signature_length On success, the number of bytes
|
||||
* that make up the returned signature value.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Hash was signed successfully.
|
||||
* respectively of the key.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t p256_transparent_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length);
|
||||
|
||||
/** Verify the signature of a hash using a SECP256R1 public key using p256-m's
|
||||
* ECDSA implementation.
|
||||
*
|
||||
* \note p256-m expects a 64 byte public key, but the contents of the key
|
||||
buffer may be the 32 byte keypair representation or the 65 byte
|
||||
public key representation. As a result, this function calls
|
||||
psa_driver_wrapper_export_public_key() to ensure the public key
|
||||
can be passed to p256-m.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
*
|
||||
* \param[in] key_buffer The buffer containing the key
|
||||
* in the format specified by PSA.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg A signature algorithm that is compatible with
|
||||
* the type of the key.
|
||||
* \param[in] hash The hash whose signature is to be
|
||||
* verified.
|
||||
* \param[in] hash_length Size of the \p hash buffer in bytes.
|
||||
* \param[in] signature Buffer containing the signature to verify.
|
||||
* \param[in] signature_length Size of the \p signature buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The signature is valid.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The calculation was performed successfully, but the passed
|
||||
* signature is not a valid signature.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t p256_transparent_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length);
|
||||
|
||||
#endif /* P256M_DRIVER_ENTRYPOINTS_H */
|
|
@ -23,6 +23,11 @@ the API of 3.(x+1) is backward compatible with 3.x). We only break API
|
|||
compatibility on major version changes (e.g. from 3.x to 4.0). We also maintain
|
||||
ABI compatibility within LTS branches; see the next section for details.
|
||||
|
||||
Every major version will become an LTS branch when the next major version is
|
||||
released. We may occasionally create LTS branches from other releases at our
|
||||
discretion.
|
||||
When a new LTS branch is created, it usually remains supported for three years.
|
||||
|
||||
## Backwards Compatibility for application code
|
||||
|
||||
We maintain API compatibility in released versions of Mbed TLS. If you have
|
||||
|
|
|
@ -24,7 +24,7 @@ Making a Contribution
|
|||
1. [Check for open issues](https://github.com/Mbed-TLS/mbedtls/issues) or [start a discussion](https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org) around a feature idea or a bug.
|
||||
1. Fork the [Mbed TLS repository on GitHub](https://github.com/Mbed-TLS/mbedtls) to start making your changes. As a general rule, you should use the ["development" branch](https://github.com/Mbed-TLS/mbedtls/tree/development) as a basis.
|
||||
1. Write a test which shows that the bug was fixed or that the feature works as expected.
|
||||
1. Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary. We will include your name in the ChangeLog :)
|
||||
1. Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary. See our [review process guidelines](https://mbed-tls.readthedocs.io/en/latest/reviews/review-for-contributors/).
|
||||
1. For quick merging, the contribution should be short, and concentrated on a single feature or topic. The larger the contribution is, the longer it would take to review it and merge it.
|
||||
|
||||
Backwards Compatibility
|
||||
|
|
3
ChangeLog.d/X509Parse_SignatureKeyId_AuthorityKeyId.txt
Normal file
3
ChangeLog.d/X509Parse_SignatureKeyId_AuthorityKeyId.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Features
|
||||
* When parsing X.509 certificates, support the extensions
|
||||
SignatureKeyIdentifier and AuthorityKeyIdentifier.
|
5
ChangeLog.d/add-missing-md-includes.txt
Normal file
5
ChangeLog.d/add-missing-md-includes.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
Bugfix
|
||||
* Add missing md.h includes to some of the external programs from
|
||||
the programs directory. Without this, even though the configuration
|
||||
was sufficient for a particular program to work, it would only print
|
||||
a message that one of the required defines is missing.
|
3
ChangeLog.d/ec_jpake_user_peer_2.txt
Normal file
3
ChangeLog.d/ec_jpake_user_peer_2.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Bugfix
|
||||
* Fix the J-PAKE driver interface for user and peer to accept any values
|
||||
(previously accepted values were limited to "client" or "server").
|
|
@ -0,0 +1,5 @@
|
|||
Bugfix
|
||||
* Fix declaration of mbedtls_ecdsa_sign_det_restartable() function
|
||||
in the ecdsa.h header file. There was a build warning when the
|
||||
configuration macro MBEDTLS_ECDSA_SIGN_ALT was defined.
|
||||
Resolves #7407.
|
|
@ -0,0 +1,3 @@
|
|||
Bugfix
|
||||
* Fix an error when MBEDTLS_ECDSA_SIGN_ALT is defined but not
|
||||
MBEDTLS_ECDSA_VERIFY_ALT, causing ecdsa verify to fail. Fixes #7498.
|
3
ChangeLog.d/programs_psa_fix.txt
Normal file
3
ChangeLog.d/programs_psa_fix.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Bugfix
|
||||
* Fix missing PSA initialization in sample programs when
|
||||
MBEDTLS_USE_PSA_CRYPTO is enabled.
|
3
ChangeLog.d/rfc8410.txt
Normal file
3
ChangeLog.d/rfc8410.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Features
|
||||
* Add support for reading and writing X25519 and X448
|
||||
public and private keys in RFC 8410 format using the existing PK APIs.
|
5
ChangeLog.d/tls13-server-version-negotiation.txt
Normal file
5
ChangeLog.d/tls13-server-version-negotiation.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
Features
|
||||
* Add support for server-side TLS version negotiation. If both TLS 1.2 and
|
||||
TLS 1.3 protocols are enabled, the TLS server now selects TLS 1.2 or
|
||||
TLS 1.3 depending on the capabilities and preferences of TLS clients.
|
||||
Fixes #6867.
|
2
ChangeLog.d/verify-ip-sans-properly.txt
Normal file
2
ChangeLog.d/verify-ip-sans-properly.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Features
|
||||
* X.509 hostname verification now supports IPAddress Subject Alternate Names.
|
|
@ -307,6 +307,12 @@ License
|
|||
|
||||
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license. See the [LICENSE](LICENSE) file for the full text of this license. Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses. This enables LTS (Long Term Support) branches of the software to be provided under either the Apache-2.0 OR GPL-2.0-or-later licenses.
|
||||
|
||||
### Third-party code included in Mbed TLS
|
||||
This project contains code from other projects. This code is located within the `3rdparty/` directory. The original license text is included within project subdirectories, and in source files. The projects are listed below:
|
||||
|
||||
* `3rdparty/everest/`: Files stem from [Project Everest](https://project-everest.github.io/) and are distributed under the Apache 2.0 license.
|
||||
* `3rdparty/p256-m/p256-m/`: Files have been taken from the [p256-m](https://github.com/mpg/p256-m) repository. The code in the original repository is distributed under the Apache 2.0 license. It is also used by the project under the Apache 2.0 license. We do not plan to regularly update these files, so they may not contain fixes and improvements present in the upstream project.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
|
|
|
@ -17,13 +17,20 @@
|
|||
#
|
||||
# Purpose
|
||||
#
|
||||
# Show symbols in the X.509 and TLS libraries that are defined in another
|
||||
# libmbedtlsXXX.a library. This is usually done to list Crypto dependencies.
|
||||
# Show external links in built libraries (X509 or TLS) or modules. This is
|
||||
# usually done to list Crypto dependencies or to check modules'
|
||||
# interdependencies.
|
||||
#
|
||||
# Usage:
|
||||
# - build the library with debug symbols and the config you're interested in
|
||||
# (default, full minus MBEDTLS_USE_PSA_CRYPTO, full, etc.)
|
||||
# - run this script with the name of your config as the only argument
|
||||
# - launch this script with 1 or more arguments depending on the analysis' goal:
|
||||
# - if only 1 argument is used (which is the name of the used config,
|
||||
# ex: full), then the analysis is done on libmbedx509 and libmbedtls
|
||||
# libraries by default
|
||||
# - if multiple arguments are provided, then modules' names (ex: pk,
|
||||
# pkparse, pkwrite, etc) are expected after the 1st one and the analysis
|
||||
# will be done on those modules instead of the libraries.
|
||||
|
||||
set -eu
|
||||
|
||||
|
@ -35,10 +42,21 @@ syms() {
|
|||
nm "$FILE" | sed -n "s/[0-9a-f ]*${TYPE} \(mbedtls_.*\)/\1/p" | sort -u
|
||||
}
|
||||
|
||||
# Check if the provided name refers to a module or library and return the
|
||||
# same path with proper extension
|
||||
get_file_with_extension() {
|
||||
BASE=$1
|
||||
if [ -f $BASE.o ]; then
|
||||
echo $BASE.o
|
||||
elif [ -f $BASE.a ]; then
|
||||
echo $BASE.a
|
||||
fi
|
||||
}
|
||||
|
||||
# create listings for the given library
|
||||
list() {
|
||||
NAME="$1"
|
||||
FILE="library/libmbed${NAME}.a"
|
||||
FILE=$(get_file_with_extension "library/${NAME}")
|
||||
PREF="${CONFIG}-$NAME"
|
||||
|
||||
syms '[TRrD]' $FILE > ${PREF}-defined
|
||||
|
@ -54,5 +72,14 @@ list() {
|
|||
|
||||
CONFIG="${1:-unknown}"
|
||||
|
||||
list x509
|
||||
list tls
|
||||
# List of modules to check is provided as parameters
|
||||
if [ $# -gt 1 ]; then
|
||||
shift 1
|
||||
ITEMS_TO_CHECK="$@"
|
||||
else
|
||||
ITEMS_TO_CHECK="libmbedx509 libmbedtls"
|
||||
fi
|
||||
|
||||
for ITEM in $ITEMS_TO_CHECK; do
|
||||
list $ITEM
|
||||
done
|
||||
|
|
|
@ -86,17 +86,11 @@ Support description
|
|||
|
||||
- Supported versions:
|
||||
|
||||
- TLS 1.2 and TLS 1.3 with version negotiation on the client side, not server
|
||||
side.
|
||||
- TLS 1.2 and TLS 1.3 with version negotiation on client and server side.
|
||||
|
||||
- TLS 1.2 and TLS 1.3 can be enabled in the build independently of each
|
||||
other.
|
||||
|
||||
- If both TLS 1.3 and TLS 1.2 are enabled at build time, only one of them can
|
||||
be configured at runtime via `mbedtls_ssl_conf_{min,max}_tls_version` for a
|
||||
server endpoint. Otherwise, `mbedtls_ssl_setup` will raise
|
||||
`MBEDTLS_ERR_SSL_BAD_CONFIG` error.
|
||||
|
||||
- Compatibility with existing SSL/TLS build options:
|
||||
|
||||
The TLS 1.3 implementation is compatible with nearly all TLS 1.2
|
||||
|
|
|
@ -390,10 +390,6 @@ psa_status_t psa_crypto_driver_pake_get_peer(
|
|||
const psa_crypto_driver_pake_inputs_t *inputs,
|
||||
uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length);
|
||||
|
||||
psa_status_t psa_crypto_driver_pake_get_role(
|
||||
const psa_crypto_driver_pake_inputs_t *inputs,
|
||||
psa_pake_role_t *role);
|
||||
|
||||
psa_status_t psa_crypto_driver_pake_get_cipher_suite(
|
||||
const psa_crypto_driver_pake_inputs_t *inputs,
|
||||
psa_pake_cipher_suite_t *cipher_suite);
|
||||
|
@ -474,7 +470,8 @@ For `PSA_ALG_JPAKE` the following steps are available for input operation:
|
|||
* `PSA_JPAKE_X4S_STEP_ZK_PUBLIC` Round 2: input Schnorr NIZKP public key for the X4S key
|
||||
* `PSA_JPAKE_X4S_STEP_ZK_PROOF` Round 2: input Schnorr NIZKP proof for the X4S key
|
||||
|
||||
The core checks that input_length is smaller than PSA_PAKE_INPUT_MAX_SIZE.
|
||||
The core checks that `input_length` is not greater than `PSA_PAKE_INPUT_SIZE(alg, prim, step)` and
|
||||
the driver can rely on that.
|
||||
|
||||
### PAKE driver get implicit key
|
||||
|
||||
|
|
175
docs/psa-driver-example-and-guide.md
Normal file
175
docs/psa-driver-example-and-guide.md
Normal file
|
@ -0,0 +1,175 @@
|
|||
# PSA Cryptoprocessor driver development examples
|
||||
|
||||
As of Mbed TLS 3.4.0, the PSA Driver Interface has only been partially implemented. As a result, the deliverables for writing a driver and the method for integrating a driver with Mbed TLS will vary depending on the operation being accelerated. This document describes how to write and integrate cryptoprocessor drivers depending on which operation or driver type is being implemented.
|
||||
|
||||
The `docs/proposed/` directory contains three documents which pertain to the proposed, work-in-progress driver system. The [PSA Driver Interface](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-interface.md) describes how drivers will interface with Mbed TLS in the future, as well as driver types, operation types, and entry points. As many key terms and concepts used in the examples in this document are defined in the PSA Driver Interface, it is recommended that developers read it prior to starting work on implementing drivers.
|
||||
The PSA Driver [Developer](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-developer-guide.md) Guide describes the deliverables for writing a driver that can be used with Mbed TLS, and the PSA Driver [Integration](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-integration-guide.md) Guide describes how a driver can be built alongside Mbed TLS.
|
||||
|
||||
## Contents:
|
||||
[Background on how Mbed TLS calls drivers](#background-on-how-mbed-tls-calls-drivers)\
|
||||
[Process for Entry Points where auto-generation is implemented](#process-for-entry-points-where-auto-generation-is-implemented) \
|
||||
[Process for Entry Points where auto-generation is not implemented](#process-for-entry-points-where-auto-generation-is-not-implemented) \
|
||||
[Example: Manually integrating a software accelerator alongside Mbed TLS](#example-manually-integrating-a-software-accelerator-alongside-mbed-tls)
|
||||
|
||||
## Background on how Mbed TLS calls drivers
|
||||
|
||||
The PSA Driver Interface specification specifies which cryptographic operations can be accelerated by third-party drivers. Operations that are completed within one step (one function call), such as verifying a signature, are called *Single-Part Operations*. On the other hand, operations that consist of multiple steps implemented by different functions called sequentially are called *Multi-Part Operations*. Single-part operations implemented by a driver will have one entry point, while multi-part operations will have multiple: one for each step.
|
||||
|
||||
There are two types of drivers: *transparent* or *opaque*. See below an excerpt from the PSA Driver Interface specification defining them:
|
||||
* **Transparent** drivers implement cryptographic operations on keys that are provided in cleartext at the beginning of each operation. They are typically used for hardware **accelerators**. When a transparent driver is available for a particular combination of parameters (cryptographic algorithm, key type and size, etc.), it is used instead of the default software implementation. Transparent drivers can also be pure software implementations that are distributed as plug-ins to a PSA Cryptography implementation (for example, an alternative implementation with different performance characteristics, or a certified implementation).
|
||||
* **Opaque** drivers implement cryptographic operations on keys that can only be used inside a protected environment such as a **secure element**, a hardware security module, a smartcard, a secure enclave, etc. An opaque driver is invoked for the specific [key location](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-interface.md#lifetimes-and-locations) that the driver is registered for: the dispatch is based on the key's lifetime.
|
||||
|
||||
Mbed TLS contains a **driver dispatch layer** (also called a driver wrapper layer). For each cryptographic operation that supports driver acceleration (or sub-part of a multi-part operation), the library calls the corresponding function in the driver wrapper. Using flags set at compile time, the driver wrapper ascertains whether any present drivers support the operation. When no such driver is present, the built-in library implementation is called as a fallback (if allowed). When a compatible driver is present, the driver wrapper calls the driver entry point function provided by the driver author.
|
||||
|
||||
The long-term goal is for the driver dispatch layer to be auto-generated using a JSON driver description file provided by the driver author.
|
||||
For some cryptographic operations, this auto-generation logic has already been implemented. When accelerating these operations, the instructions in the above documents can be followed. For the remaining operations which do not yet support auto-generation of the driver wrapper, developers will have to manually edit the driver dispatch layer and call their driver's entry point functions from there.
|
||||
|
||||
Auto-generation of the driver wrapper is supported for the operation entry points specified in the table below. Certain operations are only permitted for opaque drivers. All other operation entry points do not support auto-generation of the driver wrapper.
|
||||
|
||||
| Transparent Driver | Opaque Driver |
|
||||
|---------------------|---------------------|
|
||||
| `import_key` | `import_key` |
|
||||
| `export_key` | `export_key` |
|
||||
| `export_public_key` | `export_public_key` |
|
||||
| | `copy_key` |
|
||||
| | `get_builtin_key` |
|
||||
|
||||
### Process for Entry Points where auto-generation is implemented
|
||||
|
||||
If the driver is accelerating operations whose entry points are in the above table, the instructions in the driver [developer](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-developer-guide.md) and [integration](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-integration-guide.md) guides should be followed.
|
||||
|
||||
There are three deliverables for creating such a driver. These are:
|
||||
- A driver description file (in JSON format).
|
||||
- C header files defining the types required by the driver description. The names of these header files are declared in the driver description file.
|
||||
- An object file compiled for the target platform defining the functions required by the driver description. Implementations may allow drivers to be provided as source files and compiled with the core instead of being pre-compiled.
|
||||
|
||||
The Mbed TLS driver tests for the aforementioned entry points provide examples of how these deliverables can be implemented. For sample driver description JSON files, see [`mbedtls_test_transparent_driver.json`](https://github.com/Mbed-TLS/mbedtls/blob/development/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json) or [`mbedtls_test_opaque_driver.json`](https://github.com/Mbed-TLS/mbedtls/blob/development/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json). The header file required by the driver description is [`test_driver.h`](https://github.com/Mbed-TLS/mbedtls/blob/development/tests/include/test/drivers/test_driver.h). As Mbed TLS tests are built from source, there is no object file for the test driver. However, the source for the test driver can be found under `tests/src/drivers`.
|
||||
|
||||
### Process for Entry Points where auto-generation is not implemented
|
||||
|
||||
If the driver is accelerating operations whose entry points are not present in the table, a different process is followed where the developer manually edits the driver dispatch layer. The following steps describe this process. Steps 1, 2, 3, and 7 only need to be done once *per driver*. Steps 4, 5, and 6 must be done *for each single-part operation* or *for each sub-part of a multi-part operation* implemented by the driver.
|
||||
|
||||
**1. Choose a driver prefix and a macro name that indicates whether the driver is enabled** \
|
||||
A driver prefix is simply a word (often the name of the driver) that all functions/macros associated with the driver should begin with. This is similar to how most functions/macros in Mbed TLS begin with `PSA_XXX/psa_xxx` or `MBEDTLS_XXX/mbedtls_xxx`. The macro name can follow the form `DRIVER_PREFIX_ENABLED` or something similar; it will be used to indicate the driver is available to be called. When building with the driver present, define this macro at compile time.
|
||||
|
||||
**2. Include the following in one of the driver header files:**
|
||||
```
|
||||
#if defined(DRIVER_PREFIX_ENABLED)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
|
||||
// other definitions here
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
**3. Conditionally include header files required by the driver**
|
||||
Include any header files required by the driver in `psa_crypto_driver_wrappers.h`, placing the `#include` statements within an `#if defined` block which checks if the driver is available:
|
||||
```
|
||||
#if defined(DRIVER_PREFIX_ENABLED)
|
||||
#include ...
|
||||
#endif
|
||||
```
|
||||
|
||||
|
||||
**4. For each operation being accelerated, locate the function in the driver dispatch layer that corresponds to the entry point of that operation.** \
|
||||
The file `psa_crypto_driver_wrappers.c.jinja` contains the driver wrapper functions. For the entry points that have driver wrapper auto-generation implemented, the functions have been replaced with `jinja` templating logic. While the file has a `.jinja` extension, the driver wrapper functions for the remaining entry points are simple C functions. The names of these functions are of the form `psa_driver_wrapper` followed by the entry point name. So, for example, the function `psa_driver_wrapper_sign_hash()` corresponds to the `sign_hash` entry point.
|
||||
|
||||
**5. If a driver entry point function has been provided then ensure it has the same signature as the driver wrapper function.** \
|
||||
If one has not been provided then write one. Its name should begin with the driver prefix, followed by transparent/opaque (depending on driver type), and end with the entry point name. It should have the same signature as the driver wrapper function. The purpose of the entry point function is to take arguments in PSA format for the implemented operation and return outputs/status codes in PSA format. \
|
||||
*Return Codes:*
|
||||
* `PSA_SUCCESS`: Successful Execution
|
||||
* `PSA_ERROR_NOT_SUPPORTED`: Input arguments are correct, but the driver does not support the operation. If a transparent driver returns this then it allows fallback to another driver or software implementation.
|
||||
* `PSA_ERROR_XXX`: Any other PSA error code, see API documentation
|
||||
|
||||
**6. Modify the driver wrapper function** \
|
||||
Each driver wrapper function contains a `switch` statement which checks the location of the key. If the key is stored in local storage, then operations are performed by a transparent driver. If it is stored elsewhere, then operations are performed by an opaque driver.
|
||||
* **Transparent drivers:** Calls to driver entry points go under `case PSA_KEY_LOCATION_LOCAL_STORAGE`.
|
||||
* **Opaque Drivers** Calls to driver entry points go in a separate `case` block corresponding to the key location.
|
||||
|
||||
|
||||
The diagram below shows the layout of a driver wrapper function which can dispatch to two transparent drivers `Foo` and `Bar`, and one opaque driver `Baz`.
|
||||
|
||||
```
|
||||
psa_driver_wrapper_xxx()
|
||||
├── switch(location)
|
||||
| |
|
||||
| ├── case PSA_KEY_LOCATION_LOCAL_STORAGE //transparent driver
|
||||
| | ├── #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
| | | ├── #if defined(FOO_DRIVER_PREFIX_ENABLED)
|
||||
| | | | ├── if(//conditions for foo driver capibilities)
|
||||
| | | | ├── foo_driver_transparent_xxx() //call to driver entry point
|
||||
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
|
||||
| | | ├── #endif
|
||||
| | | ├── #if defined(BAR_DRIVER_PREFIX_ENABLED)
|
||||
| | | | ├── if(//conditions for bar driver capibilities)
|
||||
| | | | ├── bar_driver_transparent_xxx() //call to driver entry point
|
||||
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
|
||||
| | | ├── #endif
|
||||
| | ├── #endif
|
||||
| |
|
||||
| ├── case SECURE_ELEMENT_LOCATION //opaque driver
|
||||
| | ├── #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
| | | ├── #if defined(BAZ_DRIVER_PREFIX_ENABLED)
|
||||
| | | | ├── if(//conditions for baz driver capibilities)
|
||||
| | | | ├── baz_driver_opaque_xxx() //call to driver entry point
|
||||
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
|
||||
| | | ├── #endif
|
||||
| | ├── #endif
|
||||
└── return psa_xxx_builtin() // fall back to built in implementation
|
||||
```
|
||||
|
||||
All code related to driver calls within each `case` must be contained between `#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)` and a corresponding `#endif`. Within this block, each individual driver's compatibility checks and call to the entry point must be contained between `#if defined(DRIVER_PREFIX_ENABLED)` and a corresponding `#endif`. Checks that involve accessing key material using PSA macros, such as determining the key type or number of bits, must be done in the driver wrapper.
|
||||
|
||||
**7. Build Mbed TLS with the driver**
|
||||
This guide assumes you are building Mbed TLS from source alongside your project. If building with a driver present, the chosen driver macro (`DRIVER_PREFIX_ENABLED`) must be defined. This can be done in two ways:
|
||||
* *At compile time via flags.* This is the preferred option when your project uses Mbed TLS mostly out-of-the-box without significantly modifying the configuration. This can be done by passing the option via `CFLAGS`.
|
||||
* **Make**:
|
||||
```
|
||||
make CFLAGS="-DDRIVER_PREFIX_ENABLED"
|
||||
```
|
||||
* **CMake**: CFLAGS must be passed to CMake when it is invoked. Invoke CMake with
|
||||
|
||||
```
|
||||
CFLAGS="-DDRIVER_PREFIX_ENABLED" cmake path/to/source
|
||||
```
|
||||
* *Providing a user config file.* This is the preferred option when your project requires a custom configuration that is significantly different to the default. Define the macro for the driver, along with any other custom configurations in a separate header file, then use `config.py`, to set `MBEDTLS_USER_CONFIG_FILE`, providing the path to the defined header file. This will include your custom config file after the default. If you wish to completely replace the default config file, set `MBEDTLS_CONFIG_FILE` instead.
|
||||
|
||||
### Example: Manually integrating a software accelerator alongside Mbed TLS
|
||||
|
||||
[p256-m](https://github.com/mpg/p256-m) is a minimalistic implementation of ECDH and ECDSA on the NIST P-256 curve, specifically optimized for use in constrained 32-bit environments. As such, it serves as a software accelerator. This section demonstrates the integration of `p256-m` as a transparent driver alongside Mbed TLS, serving as a guide for implementation.
|
||||
The code for p256-m can be found in `3rdparty/p256-m/p256m`. In this demonstration, p256-m is built from source alongside Mbed TLS.
|
||||
|
||||
The driver prefix for p256-m is `P256`/`p256`. The driver macro is `MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED`. To build with and use p256-m, set the macro using `config.py`, then build as usual using make/cmake. From the root of the `mbedtls/` directory, run:
|
||||
|
||||
python3 scripts/config.py set MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED
|
||||
make
|
||||
|
||||
p256-m implements four entry points: `generate_key`, `key_agreement`, `sign_hash`, `verify_hash`. The `sign/verify_hash` entry points are used instead of `sign/verify_message` as messages must be hashed prior to any operation, and p256-m does not implement this. The driver entry point functions can be found in `p256m_driver_entrypoints.[hc]`. These functions act as an interface between Mbed TLS and p256-m; converting between PSA and p256-m argument formats and performing sanity checks. If the driver's status codes differ from PSA's, it is recommended to implement a status code translation function. The function `p256_to_psa_error()` converts error codes returned by p256-m into PSA error codes.
|
||||
|
||||
The driver wrapper functions in `psa_crypto_driver_wrappers.c.jinja` for all four entry points have also been modified. The code block below shows the additions made to `psa_driver_wrapper_sign_hash()`. In adherence to the defined process, all code related to the driver call is placed within a check for `MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED`. p256-m only supports non-deterministic ECDSA using keys based on NIST P256; these constraints are enforced through checks (see the `if` statement). Checks that involve accessing key attributes, (e.g. checking key type or bits) **must** be performed in the driver wrapper. This is because this information is marked private and may not be accessed outside the library. Other checks can be performed here or in the entry point function. The status returned by the driver is propagated up the call hierarchy **unless** the driver does not support the operation (i.e. return `PSA_ERROR_NOT_SUPPORTED`). In that case the next available driver/built-in implementation is called.
|
||||
|
||||
```
|
||||
#if defined (MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)
|
||||
if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
|
||||
PSA_ALG_IS_ECDSA(alg) &&
|
||||
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
|
||||
attributes->core.bits == 256 )
|
||||
{
|
||||
status = p256_transparent_sign_hash( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
alg,
|
||||
hash,
|
||||
hash_length,
|
||||
signature,
|
||||
signature_size,
|
||||
signature_length );
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
}
|
||||
#endif /* MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED */
|
||||
```
|
||||
Following this, p256-m is now ready to use alongside Mbed TLS as a software accelerator. If `MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED` is set in the config, p256-m's implementations of key generation, ECDH, and ECDSA will be used where applicable.
|
|
@ -13,7 +13,8 @@ General considerations
|
|||
|
||||
**Application code:** when this option is enabled, you need to call
|
||||
`psa_crypto_init()` before calling any function from the SSL/TLS, X.509 or PK
|
||||
module.
|
||||
modules, except for the various mbedtls_xxx_init() functions which can be called
|
||||
at any time.
|
||||
|
||||
**Why enable this option:** to fully take advantage of PSA drivers in PK,
|
||||
X.509 and TLS. For example, enabling this option is what allows use of drivers
|
||||
|
|
|
@ -22,73 +22,10 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @mainpage mbed TLS v3.4.0 source code documentation
|
||||
* @mainpage Mbed TLS v3.4.0 API Documentation
|
||||
*
|
||||
* This documentation describes the internal structure of mbed TLS. It was
|
||||
* This documentation describes the internal structure of Mbed TLS. It was
|
||||
* automatically generated from specially formatted comment blocks in
|
||||
* mbed TLS's source code using Doxygen. (See
|
||||
* http://www.stack.nl/~dimitri/doxygen/ for more information on Doxygen)
|
||||
*
|
||||
* mbed TLS has a simple setup: it provides the ingredients for an SSL/TLS
|
||||
* implementation. These ingredients are listed as modules in the
|
||||
* \ref mainpage_modules "Modules section". This "Modules section" introduces
|
||||
* the high-level module concepts used throughout this documentation.\n
|
||||
* Some examples of mbed TLS usage can be found in the \ref mainpage_examples
|
||||
* "Examples section".
|
||||
*
|
||||
* @section mainpage_modules Modules
|
||||
*
|
||||
* mbed TLS supports TLSv1.0 up to TLSv1.2 communication by providing the
|
||||
* following:
|
||||
* - TCP/IP communication functions: listen, connect, accept, read/write.
|
||||
* - SSL/TLS communication functions: init, handshake, read/write.
|
||||
* - X.509 functions: CRT, CRL and key handling
|
||||
* - Random number generation
|
||||
* - Hashing
|
||||
* - Encryption/decryption
|
||||
*
|
||||
* Above functions are split up neatly into logical interfaces. These can be
|
||||
* used separately to provide any of the above functions or to mix-and-match
|
||||
* into an SSL server/client solution that utilises a X.509 PKI. Examples of
|
||||
* such implementations are amply provided with the source code.
|
||||
*
|
||||
* Note that mbed TLS does not provide a control channel or (multiple) session
|
||||
* handling without additional work from the developer.
|
||||
*
|
||||
* @section mainpage_examples Examples
|
||||
*
|
||||
* Example server setup:
|
||||
*
|
||||
* \b Prerequisites:
|
||||
* - X.509 certificate and private key
|
||||
* - session handling functions
|
||||
*
|
||||
* \b Setup:
|
||||
* - Load your certificate and your private RSA key (X.509 interface)
|
||||
* - Setup the listening TCP socket (TCP/IP interface)
|
||||
* - Accept incoming client connection (TCP/IP interface)
|
||||
* - Initialise as an SSL-server (SSL/TLS interface)
|
||||
* - Set parameters, e.g. authentication, ciphers, CA-chain, key exchange
|
||||
* - Set callback functions RNG, IO, session handling
|
||||
* - Perform an SSL-handshake (SSL/TLS interface)
|
||||
* - Read/write data (SSL/TLS interface)
|
||||
* - Close and cleanup (all interfaces)
|
||||
*
|
||||
* Example client setup:
|
||||
*
|
||||
* \b Prerequisites:
|
||||
* - X.509 certificate and private key
|
||||
* - X.509 trusted CA certificates
|
||||
*
|
||||
* \b Setup:
|
||||
* - Load the trusted CA certificates (X.509 interface)
|
||||
* - Load your certificate and your private RSA key (X.509 interface)
|
||||
* - Setup a TCP/IP connection (TCP/IP interface)
|
||||
* - Initialise as an SSL-client (SSL/TLS interface)
|
||||
* - Set parameters, e.g. authentication mode, ciphers, CA-chain, session
|
||||
* - Set callback functions RNG, IO
|
||||
* - Perform an SSL-handshake (SSL/TLS interface)
|
||||
* - Verify the server certificate (SSL/TLS interface)
|
||||
* - Write/read data (SSL/TLS interface)
|
||||
* - Close and cleanup (all interfaces)
|
||||
* Mbed TLS's source code using Doxygen. (See
|
||||
* https://www.doxygen.nl for more information on Doxygen)
|
||||
*/
|
||||
|
|
|
@ -163,6 +163,27 @@ int mbedtls_asn1_write_algorithm_identifier(unsigned char **p,
|
|||
const char *oid, size_t oid_len,
|
||||
size_t par_len);
|
||||
|
||||
/**
|
||||
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param oid The OID of the algorithm to write.
|
||||
* \param oid_len The length of the algorithm's OID.
|
||||
* \param par_len The length of the parameters, which must be already written.
|
||||
* \param has_par If there are any parameters. If 0, par_len must be 0. If 1
|
||||
* and \p par_len is 0, NULL parameters are added.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p,
|
||||
const unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
size_t par_len, int has_par);
|
||||
|
||||
/**
|
||||
* \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
|
||||
* in ASN.1 format.
|
||||
|
|
|
@ -105,6 +105,13 @@
|
|||
#define MBEDTLS_MD_LIGHT
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_ECP_C now consists of MBEDTLS_ECP_LIGHT plus functions for curve
|
||||
* arithmetic. As a consequence if MBEDTLS_ECP_C is required for some reason,
|
||||
* then MBEDTLS_ECP_LIGHT should be enabled as well. */
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#define MBEDTLS_ECP_LIGHT
|
||||
#endif
|
||||
|
||||
/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
|
||||
* is defined as well to include all PSA code.
|
||||
*/
|
||||
|
|
|
@ -66,13 +66,6 @@
|
|||
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) && defined(__GNUC__)
|
||||
/* We don't do anything with MBEDTLS_AESCE_C on systems without ^ these two */
|
||||
#if defined(MBEDTLS_AESCE_C) && !defined(MBEDTLS_HAVE_ASM)
|
||||
#error "MBEDTLS_AESCE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
|
||||
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
@ -284,7 +277,9 @@
|
|||
|
||||
/* Helper for ECDSA dependencies, will be undefined at the end of the file */
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#if defined(PSA_HAVE_FULL_ECDSA)
|
||||
#if (defined(PSA_WANT_ALG_ECDSA) || \
|
||||
defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)) && \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
|
||||
#define MBEDTLS_PK_HAVE_ECDSA
|
||||
#endif
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
@ -295,7 +290,7 @@
|
|||
|
||||
/* Helper for JPAKE dependencies, will be undefined at the end of the file */
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#if defined(PSA_HAVE_FULL_JPAKE)
|
||||
#if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
|
||||
#define MBEDTLS_PK_HAVE_JPAKE
|
||||
#endif
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
@ -306,7 +301,7 @@
|
|||
|
||||
/* Helper for ECDH dependencies, will be undefined at the end of the file */
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#if defined(PSA_HAVE_FULL_ECDH)
|
||||
#if defined(PSA_WANT_ALG_ECDH) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
|
||||
#define MBEDTLS_PK_HAVE_ECDH
|
||||
#endif
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
@ -454,7 +449,7 @@
|
|||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_C) && \
|
||||
!defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C)
|
||||
!defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_LIGHT)
|
||||
#error "MBEDTLS_PK_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -148,6 +148,13 @@ extern "C" {
|
|||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_ECDSA */
|
||||
#endif /* PSA_WANT_ALG_ECDSA */
|
||||
|
||||
#if defined(PSA_WANT_ALG_FFDH)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_FFDH */
|
||||
#endif /* PSA_WANT_ALG_FFDH */
|
||||
|
||||
#if defined(PSA_WANT_ALG_HKDF)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||
|
@ -287,6 +294,13 @@ extern "C" {
|
|||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR 1
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
|
@ -295,6 +309,13 @@ extern "C" {
|
|||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR 1
|
||||
|
@ -651,6 +672,16 @@ extern "C" {
|
|||
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
#if defined(MBEDTLS_DHM_C)
|
||||
#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR 1
|
||||
#define PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY 1
|
||||
#define PSA_WANT_ALG_FFDH 1
|
||||
#define PSA_WANT_DH_FAMILY_RFC7919 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR 1
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1
|
||||
#endif /* MBEDTLS_DHM_C */
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1
|
||||
#define PSA_WANT_ALG_GCM 1
|
||||
|
@ -877,22 +908,6 @@ extern "C" {
|
|||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
|
||||
|
||||
#if defined(PSA_WANT_ALG_ECDSA) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#define PSA_HAVE_FULL_ECDSA 1
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#define PSA_HAVE_FULL_JPAKE 1
|
||||
#endif
|
||||
|
||||
/* Having support for ECDH implicitly includes support for private and
|
||||
* public keys, so we don't specify that requirement here. */
|
||||
#if defined(PSA_WANT_ALG_ECDH)
|
||||
#define PSA_HAVE_FULL_ECDH 1
|
||||
#endif
|
||||
|
||||
/* These features are always enabled. */
|
||||
#define PSA_WANT_KEY_TYPE_DERIVE 1
|
||||
#define PSA_WANT_KEY_TYPE_PASSWORD 1
|
||||
|
|
|
@ -288,6 +288,8 @@ int mbedtls_ecdsa_sign_restartable(
|
|||
void *p_rng_blind,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx);
|
||||
|
||||
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
|
||||
/**
|
||||
|
@ -321,6 +323,7 @@ int mbedtls_ecdsa_sign_restartable(
|
|||
* buffer of length \p blen Bytes. It may be \c NULL if
|
||||
* \p blen is zero.
|
||||
* \param blen The length of \p buf in Bytes.
|
||||
* \param md_alg The hash algorithm used to hash the original data.
|
||||
* \param f_rng_blind The RNG function used for blinding. This must not be
|
||||
* \c NULL.
|
||||
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
|
||||
|
@ -348,8 +351,6 @@ int mbedtls_ecdsa_sign_det_restartable(
|
|||
|
||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||
|
||||
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
|
||||
|
||||
/**
|
||||
* \brief This function verifies the ECDSA signature of a
|
||||
* previously-hashed message.
|
||||
|
|
|
@ -54,6 +54,7 @@ extern "C" {
|
|||
typedef enum {
|
||||
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
|
||||
MBEDTLS_ECJPAKE_SERVER, /**< Server */
|
||||
MBEDTLS_ECJPAKE_NONE, /**< Undefined */
|
||||
} mbedtls_ecjpake_role;
|
||||
|
||||
#if !defined(MBEDTLS_ECJPAKE_ALT)
|
||||
|
|
|
@ -312,7 +312,7 @@ mbedtls_ecp_group;
|
|||
/**
|
||||
* The maximum size of the groups, that is, of \c N and \c P.
|
||||
*/
|
||||
#if !defined(MBEDTLS_ECP_C)
|
||||
#if !defined(MBEDTLS_ECP_LIGHT)
|
||||
/* Dummy definition to help code that has optional ECP support and
|
||||
* defines an MBEDTLS_ECP_MAX_BYTES-sized array unconditionally. */
|
||||
#define MBEDTLS_ECP_MAX_BITS 1
|
||||
|
@ -343,9 +343,9 @@ mbedtls_ecp_group;
|
|||
#define MBEDTLS_ECP_MAX_BITS 192
|
||||
#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
||||
#define MBEDTLS_ECP_MAX_BITS 192
|
||||
#else
|
||||
#else /* !MBEDTLS_ECP_LIGHT */
|
||||
#error "Missing definition of MBEDTLS_ECP_MAX_BITS"
|
||||
#endif
|
||||
#endif /* !MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#define MBEDTLS_ECP_MAX_BYTES ((MBEDTLS_ECP_MAX_BITS + 7) / 8)
|
||||
#define MBEDTLS_ECP_MAX_PT_LEN (2 * MBEDTLS_ECP_MAX_BYTES + 1)
|
||||
|
|
|
@ -1931,7 +1931,8 @@
|
|||
* break backwards compatibility.
|
||||
*
|
||||
* \warning If you enable this option, you need to call `psa_crypto_init()`
|
||||
* before calling any function from the SSL/TLS, X.509 or PK modules.
|
||||
* before calling any function from the SSL/TLS, X.509 or PK modules, except
|
||||
* for the various mbedtls_xxx_init() functions which can be called at any time.
|
||||
*
|
||||
* \note An important and desirable effect of this option is that it allows
|
||||
* PK, X.509 and TLS to take advantage of PSA drivers. For example, enabling
|
||||
|
@ -2076,12 +2077,15 @@
|
|||
* Module: library/aesce.c
|
||||
* Caller: library/aes.c
|
||||
*
|
||||
* Requires: MBEDTLS_HAVE_ASM, MBEDTLS_AES_C
|
||||
* Requires: MBEDTLS_AES_C
|
||||
*
|
||||
* \warning Runtime detection only works on Linux. For non-Linux operating
|
||||
* system, Armv8-A Cryptographic Extensions must be supported by
|
||||
* the CPU when this option is enabled.
|
||||
*
|
||||
* \note Minimum compiler versions for this feature are Clang 4.0,
|
||||
* GCC 6.0 or MSVC 2019 version 16.11.2.
|
||||
*
|
||||
* This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems.
|
||||
*/
|
||||
#define MBEDTLS_AESCE_C
|
||||
|
@ -3916,4 +3920,18 @@
|
|||
*/
|
||||
//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
|
||||
|
||||
/**
|
||||
* Uncomment to enable p256-m, which implements ECC key generation, ECDH,
|
||||
* and ECDSA for SECP256R1 curves. This driver is used as an example to
|
||||
* document how a third-party driver or software accelerator can be integrated
|
||||
* to work alongside Mbed TLS.
|
||||
*
|
||||
* \warning p256-m has only been included to serve as a sample implementation
|
||||
* of how a driver/accelerator can be integrated alongside Mbed TLS. It is not
|
||||
* intended for use in production. p256-m files in Mbed TLS are not updated
|
||||
* regularly, so they may not contain upstream fixes/improvements.
|
||||
* DO NOT ENABLE/USE THIS MACRO IN PRODUCTION BUILDS!
|
||||
*/
|
||||
//#define MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED
|
||||
|
||||
/** \} name SECTION: Module configuration options */
|
||||
|
|
|
@ -90,6 +90,9 @@
|
|||
#define MBEDTLS_OID_OIW_SECSIG MBEDTLS_OID_ORG_OIW "\x03"
|
||||
#define MBEDTLS_OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG "\x02"
|
||||
#define MBEDTLS_OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_ALG "\x1a"
|
||||
#define MBEDTLS_OID_ORG_THAWTE "\x65" /* thawte(101) */
|
||||
#define MBEDTLS_OID_THAWTE MBEDTLS_OID_ISO_IDENTIFIED_ORG \
|
||||
MBEDTLS_OID_ORG_THAWTE
|
||||
#define MBEDTLS_OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */
|
||||
#define MBEDTLS_OID_CERTICOM MBEDTLS_OID_ISO_IDENTIFIED_ORG \
|
||||
MBEDTLS_OID_ORG_CERTICOM
|
||||
|
@ -437,6 +440,15 @@
|
|||
* ecdsa-with-SHA2(3) 4 } */
|
||||
#define MBEDTLS_OID_ECDSA_SHA512 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x04"
|
||||
|
||||
/*
|
||||
* EC key algorithms from RFC 8410
|
||||
*/
|
||||
|
||||
#define MBEDTLS_OID_X25519 MBEDTLS_OID_THAWTE "\x6e" /**< id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 } */
|
||||
#define MBEDTLS_OID_X448 MBEDTLS_OID_THAWTE "\x6f" /**< id-X448 OBJECT IDENTIFIER ::= { 1 3 101 111 } */
|
||||
#define MBEDTLS_OID_ED25519 MBEDTLS_OID_THAWTE "\x70" /**< id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } */
|
||||
#define MBEDTLS_OID_ED448 MBEDTLS_OID_THAWTE "\x71" /**< id-Ed448 OBJECT IDENTIFIER ::= { 1 3 101 113 } */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -509,7 +521,7 @@ int mbedtls_oid_get_pk_alg(const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_al
|
|||
int mbedtls_oid_get_oid_by_pk_alg(mbedtls_pk_type_t pk_alg,
|
||||
const char **oid, size_t *olen);
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/**
|
||||
* \brief Translate NamedCurve OID into an EC group identifier
|
||||
*
|
||||
|
@ -531,7 +543,31 @@ int mbedtls_oid_get_ec_grp(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *gr
|
|||
*/
|
||||
int mbedtls_oid_get_oid_by_ec_grp(mbedtls_ecp_group_id grp_id,
|
||||
const char **oid, size_t *olen);
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
/**
|
||||
* \brief Translate AlgorithmIdentifier OID into an EC group identifier,
|
||||
* for curves that are directly encoded at this level
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param grp_id place to store group id
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_ec_grp_algid(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id);
|
||||
|
||||
/**
|
||||
* \brief Translate EC group identifier into AlgorithmIdentifier OID,
|
||||
* for curves that are directly encoded at this level
|
||||
*
|
||||
* \param grp_id EC group identifier
|
||||
* \param oid place to store ASN.1 OID string pointer
|
||||
* \param olen length of the OID
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_oid_by_ec_grp_algid(mbedtls_ecp_group_id grp_id,
|
||||
const char **oid, size_t *olen);
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/**
|
||||
* \brief Translate SignatureAlgorithm OID into md_type and pk_type
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include "mbedtls/ecdsa.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
|
||||
|
@ -234,10 +234,17 @@ typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
|
|||
|
||||
/**
|
||||
* \brief Public key container
|
||||
*
|
||||
* \note The priv_id is guarded by MBEDTLS_PSA_CRYPTO_C and not
|
||||
* by MBEDTLS_USE_PSA_CRYPTO because it can be used also
|
||||
* in mbedtls_pk_sign_ext for RSA keys.
|
||||
*/
|
||||
typedef struct mbedtls_pk_context {
|
||||
const mbedtls_pk_info_t *MBEDTLS_PRIVATE(pk_info); /**< Public key information */
|
||||
void *MBEDTLS_PRIVATE(pk_ctx); /**< Underlying public key context */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(priv_id); /**< Key ID for opaque keys */
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
} mbedtls_pk_context;
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
|
@ -771,7 +778,7 @@ static inline mbedtls_rsa_context *mbedtls_pk_rsa(const mbedtls_pk_context pk)
|
|||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/**
|
||||
* Quick access to an EC context inside a PK context.
|
||||
*
|
||||
|
@ -794,7 +801,7 @@ static inline mbedtls_ecp_keypair *mbedtls_pk_ec(const mbedtls_pk_context pk)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#if defined(MBEDTLS_PK_PARSE_C)
|
||||
/** \ingroup pk_module */
|
||||
|
|
|
@ -345,7 +345,11 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
|
|||
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
|
||||
|
||||
typedef struct {
|
||||
psa_status_t psa_status;
|
||||
/* Error codes used by PSA crypto are in -255..-128, fitting in 16 bits. */
|
||||
int16_t psa_status;
|
||||
/* Error codes used by Mbed TLS are in one of the ranges
|
||||
* -127..-1 (low-level) or -32767..-4096 (high-level with a low-level
|
||||
* code optionally added), fitting in 16 bits. */
|
||||
int16_t mbedtls_error;
|
||||
} mbedtls_error_pair_t;
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "mbedtls/dhm.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#if defined(MBEDTLS_ECDH_C)
|
||||
#include "mbedtls/ecdh.h"
|
||||
#endif
|
||||
|
@ -106,7 +108,8 @@
|
|||
/* Error space gap */
|
||||
/* Error space gap */
|
||||
/* Error space gap */
|
||||
/* Error space gap */
|
||||
/** Cache entry not found */
|
||||
#define MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND -0x7E80
|
||||
/** Memory allocation failed */
|
||||
#define MBEDTLS_ERR_SSL_ALLOC_FAILED -0x7F00
|
||||
/** Hardware acceleration function returned with error */
|
||||
|
@ -1483,7 +1486,7 @@ struct mbedtls_ssl_config {
|
|||
const uint16_t *MBEDTLS_PRIVATE(sig_algs); /*!< allowed signature algorithms */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#if defined(MBEDTLS_ECP_LIGHT) && !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
const mbedtls_ecp_group_id *MBEDTLS_PRIVATE(curve_list); /*!< allowed curves */
|
||||
#endif
|
||||
|
||||
|
@ -1605,19 +1608,21 @@ struct mbedtls_ssl_context {
|
|||
renego_max_records is < 0 */
|
||||
#endif /* MBEDTLS_SSL_RENEGOTIATION */
|
||||
|
||||
/** Server: Negotiated TLS protocol version.
|
||||
* Client: Maximum TLS version to be negotiated, then negotiated TLS
|
||||
* version.
|
||||
/**
|
||||
* Maximum TLS version to be negotiated, then negotiated TLS version.
|
||||
*
|
||||
* It is initialized as the maximum TLS version to be negotiated in the
|
||||
* ClientHello writing preparation stage and used throughout the
|
||||
* ClientHello writing. For a fresh handshake not linked to any previous
|
||||
* handshake, it is initialized to the configured maximum TLS version
|
||||
* to be negotiated. When renegotiating or resuming a session, it is
|
||||
* initialized to the previously negotiated TLS version.
|
||||
* It is initialized as the configured maximum TLS version to be
|
||||
* negotiated by mbedtls_ssl_setup().
|
||||
*
|
||||
* Updated to the negotiated TLS version as soon as the ServerHello is
|
||||
* received.
|
||||
* When renegotiating or resuming a session, it is overwritten in the
|
||||
* ClientHello writing preparation stage with the previously negotiated
|
||||
* TLS version.
|
||||
*
|
||||
* On client side, it is updated to the TLS version selected by the server
|
||||
* for the handshake when the ServerHello is received.
|
||||
*
|
||||
* On server side, it is updated to the TLS version the server selects for
|
||||
* the handshake when the ClientHello is received.
|
||||
*/
|
||||
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
|
||||
|
||||
|
@ -3616,7 +3621,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
|
|||
unsigned int bitlen);
|
||||
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
* \brief Set the allowed curves in order of preference.
|
||||
|
@ -3662,7 +3667,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
|
|||
void MBEDTLS_DEPRECATED mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
|
||||
const mbedtls_ecp_group_id *curves);
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/**
|
||||
* \brief Set the allowed groups in order of preference.
|
||||
|
|
|
@ -102,6 +102,11 @@ void mbedtls_ssl_cache_init(mbedtls_ssl_cache_context *cache);
|
|||
* \param session_id_len The length of \p session_id in bytes.
|
||||
* \param session The address at which to store the session
|
||||
* associated with \p session_id, if present.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND if there is
|
||||
* no cache entry with specified session ID found, or
|
||||
* any other negative error code for other failures.
|
||||
*/
|
||||
int mbedtls_ssl_cache_get(void *data,
|
||||
unsigned char const *session_id,
|
||||
|
@ -117,6 +122,9 @@ int mbedtls_ssl_cache_get(void *data,
|
|||
* associated to \p session.
|
||||
* \param session_id_len The length of \p session_id in bytes.
|
||||
* \param session The session to store.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ssl_cache_set(void *data,
|
||||
unsigned char const *session_id,
|
||||
|
@ -132,9 +140,10 @@ int mbedtls_ssl_cache_set(void *data,
|
|||
* associated to \p session.
|
||||
* \param session_id_len The length of \p session_id in bytes.
|
||||
*
|
||||
* \return 0: The cache entry for session with provided ID
|
||||
* is removed or does not exist.
|
||||
* Otherwise: fail.
|
||||
* \return \c 0 on success. This indicates the cache entry for
|
||||
* the session with provided ID is removed or does not
|
||||
* exist.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ssl_cache_remove(void *data,
|
||||
unsigned char const *session_id,
|
||||
|
|
|
@ -243,6 +243,17 @@ typedef mbedtls_asn1_named_data mbedtls_x509_name;
|
|||
*/
|
||||
typedef mbedtls_asn1_sequence mbedtls_x509_sequence;
|
||||
|
||||
/*
|
||||
* Container for the fields of the Authority Key Identifier object
|
||||
*/
|
||||
typedef struct mbedtls_x509_authority {
|
||||
mbedtls_x509_buf keyIdentifier;
|
||||
mbedtls_x509_sequence authorityCertIssuer;
|
||||
mbedtls_x509_buf authorityCertSerialNumber;
|
||||
mbedtls_x509_buf raw;
|
||||
}
|
||||
mbedtls_x509_authority;
|
||||
|
||||
/** Container for date and time (precision in seconds). */
|
||||
typedef struct mbedtls_x509_time {
|
||||
int year, mon, day; /**< Date. */
|
||||
|
@ -470,6 +481,9 @@ int mbedtls_x509_get_key_usage(unsigned char **p,
|
|||
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,
|
||||
|
|
|
@ -76,6 +76,8 @@ typedef struct mbedtls_x509_crt {
|
|||
mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
|
||||
mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */
|
||||
mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName, uniformResourceIdentifier, DirectoryName and OtherName are listed). */
|
||||
mbedtls_x509_buf subject_key_id; /**< Optional X.509 v3 extension subject key identifier. */
|
||||
mbedtls_x509_authority authority_key_id; /**< Optional X.509 v3 extension authority key identifier. */
|
||||
|
||||
mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */
|
||||
|
||||
|
@ -559,6 +561,7 @@ int mbedtls_x509_crt_parse_file(mbedtls_x509_crt *chain, const char *path);
|
|||
int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path);
|
||||
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
|
@ -638,7 +641,7 @@ int mbedtls_x509_crt_verify_info(char *buf, size_t size, const char *prefix,
|
|||
* \param cn The expected Common Name. This will be checked to be
|
||||
* present in the certificate's subjectAltNames extension or,
|
||||
* if this extension is absent, as a CN component in its
|
||||
* Subject name. Currently only DNS names are supported. This
|
||||
* Subject name. DNS names and IP addresses are supported. This
|
||||
* may be \c NULL if the CN need not be verified.
|
||||
* \param flags The address at which to store the result of the verification.
|
||||
* If the verification couldn't be completed, the flag value is
|
||||
|
|
|
@ -202,7 +202,7 @@ typedef struct {
|
|||
uint8_t *MBEDTLS_PRIVATE(password);
|
||||
size_t MBEDTLS_PRIVATE(password_len);
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
uint8_t MBEDTLS_PRIVATE(role);
|
||||
mbedtls_ecjpake_role MBEDTLS_PRIVATE(role);
|
||||
uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_JPAKE_BUFFER_SIZE]);
|
||||
size_t MBEDTLS_PRIVATE(buffer_length);
|
||||
size_t MBEDTLS_PRIVATE(buffer_offset);
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
|
||||
#define PSA_WANT_ALG_ECB_NO_PADDING 1
|
||||
#define PSA_WANT_ALG_ECDH 1
|
||||
#define PSA_WANT_ALG_FFDH 1
|
||||
#define PSA_WANT_ALG_ECDSA 1
|
||||
#define PSA_WANT_ALG_JPAKE 1
|
||||
#define PSA_WANT_ALG_GCM 1
|
||||
|
@ -126,6 +127,8 @@
|
|||
#define PSA_WANT_KEY_TYPE_DES 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR 1
|
||||
#define PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY 1
|
||||
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
|
||||
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1
|
||||
#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||
|
|
|
@ -573,7 +573,7 @@ psa_status_t psa_get_key_domain_parameters(
|
|||
* @{
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#include <mbedtls/ecp.h>
|
||||
|
||||
/** Convert an ECC curve identifier from the Mbed TLS encoding to PSA.
|
||||
|
@ -660,7 +660,7 @@ static inline psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grp
|
|||
mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
|
||||
size_t bits,
|
||||
int bits_is_sloppy);
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
@ -1328,20 +1328,6 @@ psa_status_t psa_crypto_driver_pake_get_password(
|
|||
const psa_crypto_driver_pake_inputs_t *inputs,
|
||||
uint8_t *buffer, size_t buffer_size, size_t *buffer_length);
|
||||
|
||||
/** Get the role from given inputs.
|
||||
*
|
||||
* \param[in] inputs Operation inputs.
|
||||
* \param[out] role Return buffer for role.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* Role hasn't been set yet.
|
||||
*/
|
||||
psa_status_t psa_crypto_driver_pake_get_role(
|
||||
const psa_crypto_driver_pake_inputs_t *inputs,
|
||||
psa_pake_role_t *role);
|
||||
|
||||
/** Get the length of the user id in bytes from given inputs.
|
||||
*
|
||||
* \param[in] inputs Operation inputs.
|
||||
|
@ -1560,7 +1546,6 @@ psa_status_t psa_pake_set_password_key(psa_pake_operation_t *operation,
|
|||
* been set (psa_pake_set_user() hasn't been
|
||||
* called yet).
|
||||
* \param[in] user_id The user ID to authenticate with.
|
||||
* (temporary limitation: "client" or "server" only)
|
||||
* \param user_id_len Size of the \p user_id buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
|
@ -1602,7 +1587,6 @@ psa_status_t psa_pake_set_user(psa_pake_operation_t *operation,
|
|||
* been set (psa_pake_set_peer() hasn't been
|
||||
* called yet).
|
||||
* \param[in] peer_id The peer's ID to authenticate.
|
||||
* (temporary limitation: "client" or "server" only)
|
||||
* \param peer_id_len Size of the \p peer_id buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
|
@ -1937,6 +1921,9 @@ psa_status_t psa_pake_abort(psa_pake_operation_t *operation);
|
|||
*
|
||||
* This macro must expand to a compile-time constant integer.
|
||||
*
|
||||
* The value of this macro must be at least as large as the largest value
|
||||
* returned by PSA_PAKE_OUTPUT_SIZE()
|
||||
*
|
||||
* See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p step).
|
||||
*/
|
||||
#define PSA_PAKE_OUTPUT_MAX_SIZE 65
|
||||
|
@ -1946,6 +1933,9 @@ psa_status_t psa_pake_abort(psa_pake_operation_t *operation);
|
|||
*
|
||||
* This macro must expand to a compile-time constant integer.
|
||||
*
|
||||
* The value of this macro must be at least as large as the largest value
|
||||
* returned by PSA_PAKE_INPUT_SIZE()
|
||||
*
|
||||
* See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p step).
|
||||
*/
|
||||
#define PSA_PAKE_INPUT_MAX_SIZE 65
|
||||
|
@ -1958,7 +1948,7 @@ psa_status_t psa_pake_abort(psa_pake_operation_t *operation);
|
|||
/** Returns a suitable initializer for a PAKE operation object of type
|
||||
* psa_pake_operation_t.
|
||||
*/
|
||||
#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, PSA_PAKE_OPERATION_STAGE_SETUP, \
|
||||
#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, 0, PSA_PAKE_OPERATION_STAGE_SETUP, \
|
||||
{ 0 }, { { 0 } } }
|
||||
|
||||
struct psa_pake_cipher_suite_s {
|
||||
|
@ -2033,7 +2023,6 @@ static inline void psa_pake_cs_set_hash(psa_pake_cipher_suite_t *cipher_suite,
|
|||
struct psa_crypto_driver_pake_inputs_s {
|
||||
uint8_t *MBEDTLS_PRIVATE(password);
|
||||
size_t MBEDTLS_PRIVATE(password_len);
|
||||
psa_pake_role_t MBEDTLS_PRIVATE(role);
|
||||
uint8_t *MBEDTLS_PRIVATE(user);
|
||||
size_t MBEDTLS_PRIVATE(user_len);
|
||||
uint8_t *MBEDTLS_PRIVATE(peer);
|
||||
|
@ -2104,6 +2093,8 @@ struct psa_pake_operation_s {
|
|||
unsigned int MBEDTLS_PRIVATE(id);
|
||||
/* Algorithm of the PAKE operation */
|
||||
psa_algorithm_t MBEDTLS_PRIVATE(alg);
|
||||
/* A primitive of type compatible with algorithm */
|
||||
psa_pake_primitive_t MBEDTLS_PRIVATE(primitive);
|
||||
/* Stage of the PAKE operation: waiting for the setup, collecting inputs
|
||||
* or computing. */
|
||||
uint8_t MBEDTLS_PRIVATE(stage);
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
|
||||
#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
|
||||
#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
|
||||
#define PSA_MAX_OF_THREE(a, b, c) ((a) <= (b) ? (b) <= (c) ? \
|
||||
(c) : (b) : (a) <= (c) ? (c) : (a))
|
||||
|
||||
#define PSA_ROUND_UP_TO_MULTIPLE(block_size, length) \
|
||||
(((length) + (block_size) - 1) / (block_size) * (block_size))
|
||||
|
@ -195,6 +197,12 @@
|
|||
* operations, and does not need to accept all key sizes up to the limit. */
|
||||
#define PSA_VENDOR_RSA_MAX_KEY_BITS 4096
|
||||
|
||||
/* The maximum size of an DH key on this implementation, in bits.
|
||||
*
|
||||
* Note that an implementation may set different size limits for different
|
||||
* operations, and does not need to accept all key sizes up to the limit. */
|
||||
#define PSA_VENDOR_FFDH_MAX_KEY_BITS 8192
|
||||
|
||||
/* The maximum size of an ECC key on this implementation, in bits.
|
||||
* This is a vendor-specific macro. */
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_521)
|
||||
|
@ -804,6 +812,18 @@
|
|||
#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \
|
||||
(PSA_BITS_TO_BYTES(key_bits))
|
||||
|
||||
/* Maximum size of the export encoding of an DH key pair.
|
||||
*
|
||||
* An DH key pair is represented by the secret value.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(key_bits) \
|
||||
(PSA_BITS_TO_BYTES(key_bits))
|
||||
|
||||
/* Maximum size of the export encoding of an DH public key.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(key_bits) \
|
||||
(PSA_BITS_TO_BYTES(key_bits))
|
||||
|
||||
/** Sufficient output buffer size for psa_export_key() or
|
||||
* psa_export_public_key().
|
||||
*
|
||||
|
@ -845,6 +865,7 @@
|
|||
*/
|
||||
#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_DH(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
|
||||
|
@ -901,6 +922,7 @@
|
|||
#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_RSA(key_type) ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_DH(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
|
||||
0)
|
||||
|
||||
/** Sufficient buffer size for exporting any asymmetric key pair.
|
||||
|
@ -911,11 +933,10 @@
|
|||
*
|
||||
* See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
|
||||
*/
|
||||
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
|
||||
(PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \
|
||||
PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) ? \
|
||||
PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) : \
|
||||
PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS))
|
||||
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
|
||||
PSA_MAX_OF_THREE(PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS), \
|
||||
PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS), \
|
||||
PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS))
|
||||
|
||||
/** Sufficient buffer size for exporting any asymmetric public key.
|
||||
*
|
||||
|
@ -926,11 +947,11 @@
|
|||
*
|
||||
* See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
|
||||
*/
|
||||
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
|
||||
(PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \
|
||||
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) ? \
|
||||
PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) : \
|
||||
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS))
|
||||
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
|
||||
PSA_MAX_OF_THREE(PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS), \
|
||||
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS), \
|
||||
PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS))
|
||||
|
||||
|
||||
/** Sufficient output buffer size for psa_raw_key_agreement().
|
||||
*
|
||||
|
@ -955,11 +976,9 @@
|
|||
* If the parameters are not valid,
|
||||
* the return value is unspecified.
|
||||
*/
|
||||
/* FFDH is not yet supported in PSA. */
|
||||
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? \
|
||||
PSA_BITS_TO_BYTES(key_bits) : \
|
||||
0)
|
||||
((PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || \
|
||||
PSA_KEY_TYPE_IS_DH_KEY_PAIR(key_type)) ? PSA_BITS_TO_BYTES(key_bits) : 0)
|
||||
|
||||
/** Maximum size of the output from psa_raw_key_agreement().
|
||||
*
|
||||
|
@ -968,8 +987,11 @@
|
|||
*
|
||||
* See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits).
|
||||
*/
|
||||
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \
|
||||
(PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS))
|
||||
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \
|
||||
(PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
|
||||
PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) ? \
|
||||
PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) : \
|
||||
PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS))
|
||||
|
||||
/** The default IV size for a cipher algorithm, in bytes.
|
||||
*
|
||||
|
|
|
@ -69,6 +69,7 @@ set(src_crypto
|
|||
psa_crypto_client.c
|
||||
psa_crypto_driver_wrappers.c
|
||||
psa_crypto_ecp.c
|
||||
psa_crypto_ffdh.c
|
||||
psa_crypto_hash.c
|
||||
psa_crypto_mac.c
|
||||
psa_crypto_pake.c
|
||||
|
@ -272,6 +273,10 @@ if(USE_STATIC_MBEDTLS_LIBRARY)
|
|||
target_link_libraries(${mbedcrypto_static_target} PUBLIC everest)
|
||||
endif()
|
||||
|
||||
if(TARGET p256m)
|
||||
target_link_libraries(${mbedcrypto_static_target} PUBLIC p256m)
|
||||
endif()
|
||||
|
||||
add_library(${mbedx509_static_target} STATIC ${src_x509})
|
||||
set_target_properties(${mbedx509_static_target} PROPERTIES OUTPUT_NAME mbedx509)
|
||||
target_link_libraries(${mbedx509_static_target} PUBLIC ${libs} ${mbedcrypto_static_target})
|
||||
|
@ -291,6 +296,10 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
|
|||
target_link_libraries(${mbedcrypto_target} PUBLIC everest)
|
||||
endif()
|
||||
|
||||
if(TARGET p256m)
|
||||
target_link_libraries(${mbedcrypto_target} PUBLIC p256m)
|
||||
endif()
|
||||
|
||||
add_library(${mbedx509_target} SHARED ${src_x509})
|
||||
set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.4.0 SOVERSION 5)
|
||||
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
|
||||
|
|
|
@ -134,6 +134,7 @@ OBJS_CRYPTO= \
|
|||
psa_crypto_client.o \
|
||||
psa_crypto_driver_wrappers.o \
|
||||
psa_crypto_ecp.o \
|
||||
psa_crypto_ffdh.o \
|
||||
psa_crypto_hash.o \
|
||||
psa_crypto_mac.o \
|
||||
psa_crypto_pake.o \
|
||||
|
|
|
@ -48,22 +48,34 @@
|
|||
|
||||
#if defined(MBEDTLS_HAVE_ARM64)
|
||||
|
||||
/* Compiler version checks. */
|
||||
#if defined(__clang__)
|
||||
# if __clang_major__ < 4
|
||||
# error "Minimum version of Clang for MBEDTLS_AESCE_C is 4.0."
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if __GNUC__ < 6
|
||||
# error "Minimum version of GCC for MBEDTLS_AESCE_C is 6.0."
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
/* TODO: We haven't verified MSVC from 1920 to 1928. If someone verified that,
|
||||
* please update this and document of `MBEDTLS_AESCE_C` in
|
||||
* `mbedtls_config.h`. */
|
||||
# if _MSC_VER < 1929
|
||||
# error "Minimum version of MSVC for MBEDTLS_AESCE_C is 2019 version 16.11.2."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(__ARM_FEATURE_AES) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
|
||||
# if defined(__clang__)
|
||||
# if __clang_major__ < 4
|
||||
# error "A more recent Clang is required for MBEDTLS_AESCE_C"
|
||||
# endif
|
||||
# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function)
|
||||
# define MBEDTLS_POP_TARGET_PRAGMA
|
||||
# elif defined(__GNUC__)
|
||||
# if __GNUC__ < 6
|
||||
# error "A more recent GCC is required for MBEDTLS_AESCE_C"
|
||||
# endif
|
||||
# pragma GCC push_options
|
||||
# pragma GCC target ("arch=armv8-a+crypto")
|
||||
# define MBEDTLS_POP_TARGET_PRAGMA
|
||||
# else
|
||||
# error "Only GCC and Clang supported for MBEDTLS_AESCE_C"
|
||||
# elif defined(_MSC_VER)
|
||||
# error "Required feature(__ARM_FEATURE_AES) is not enabled."
|
||||
# endif
|
||||
#endif /* !__ARM_FEATURE_AES || MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */
|
||||
|
||||
|
@ -295,12 +307,24 @@ static inline poly64_t vget_low_p64(poly64x2_t __a)
|
|||
* Older compilers miss some intrinsic functions for `poly*_t`. We use
|
||||
* uint8x16_t and uint8x16x3_t as input/output parameters.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
/* GCC reports incompatible type error without cast. GCC think poly64_t and
|
||||
* poly64x1_t are different, that is different with MSVC and Clang. */
|
||||
#define MBEDTLS_VMULL_P64(a, b) vmull_p64((poly64_t) a, (poly64_t) b)
|
||||
#else
|
||||
/* MSVC reports `error C2440: 'type cast'` with cast. Clang does not report
|
||||
* error with/without cast. And I think poly64_t and poly64x1_t are same, no
|
||||
* cast for clang also. */
|
||||
#define MBEDTLS_VMULL_P64(a, b) vmull_p64(a, b)
|
||||
#endif
|
||||
static inline uint8x16_t pmull_low(uint8x16_t a, uint8x16_t b)
|
||||
{
|
||||
|
||||
return vreinterpretq_u8_p128(
|
||||
vmull_p64(
|
||||
(poly64_t) vget_low_p64(vreinterpretq_p64_u8(a)),
|
||||
(poly64_t) vget_low_p64(vreinterpretq_p64_u8(b))));
|
||||
MBEDTLS_VMULL_P64(
|
||||
vget_low_p64(vreinterpretq_p64_u8(a)),
|
||||
vget_low_p64(vreinterpretq_p64_u8(b))
|
||||
));
|
||||
}
|
||||
|
||||
static inline uint8x16_t pmull_high(uint8x16_t a, uint8x16_t b)
|
||||
|
@ -362,9 +386,14 @@ static inline uint8x16x3_t poly_mult_128(uint8x16_t a, uint8x16_t b)
|
|||
static inline uint8x16_t poly_mult_reduce(uint8x16x3_t input)
|
||||
{
|
||||
uint8x16_t const ZERO = vdupq_n_u8(0);
|
||||
/* use 'asm' as an optimisation barrier to prevent loading MODULO from memory */
|
||||
|
||||
uint64x2_t r = vreinterpretq_u64_u8(vdupq_n_u8(0x87));
|
||||
#if defined(__GNUC__)
|
||||
/* use 'asm' as an optimisation barrier to prevent loading MODULO from
|
||||
* memory. It is for GNUC compatible compilers.
|
||||
*/
|
||||
asm ("" : "+w" (r));
|
||||
#endif
|
||||
uint8x16_t const MODULO = vreinterpretq_u8_u64(vshrq_n_u64(r, 64 - 8));
|
||||
uint8x16_t h, m, l; /* input high/middle/low 128b */
|
||||
uint8x16_t c, d, e, f, g, n, o;
|
||||
|
|
|
@ -30,11 +30,11 @@
|
|||
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
|
||||
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
|
||||
defined(__aarch64__) && !defined(MBEDTLS_HAVE_ARM64)
|
||||
#if !defined(MBEDTLS_HAVE_ARM64)
|
||||
#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
|
||||
#define MBEDTLS_HAVE_ARM64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVE_ARM64)
|
||||
|
||||
|
|
|
@ -194,14 +194,23 @@ int mbedtls_asn1_write_oid(unsigned char **p, const unsigned char *start,
|
|||
int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, const unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
size_t par_len)
|
||||
{
|
||||
return mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, par_len, 1);
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, const unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
size_t par_len, int has_par)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
if (par_len == 0) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start));
|
||||
} else {
|
||||
len += par_len;
|
||||
if (has_par) {
|
||||
if (par_len == 0) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start));
|
||||
} else {
|
||||
len += par_len;
|
||||
}
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len));
|
||||
|
|
|
@ -35,6 +35,23 @@
|
|||
|
||||
size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a)
|
||||
{
|
||||
#if defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_clz)
|
||||
if (sizeof(mbedtls_mpi_uint) == sizeof(unsigned int)) {
|
||||
return (size_t) __builtin_clz(a);
|
||||
}
|
||||
#endif
|
||||
#if __has_builtin(__builtin_clzl)
|
||||
if (sizeof(mbedtls_mpi_uint) == sizeof(unsigned long)) {
|
||||
return (size_t) __builtin_clzl(a);
|
||||
}
|
||||
#endif
|
||||
#if __has_builtin(__builtin_clzll)
|
||||
if (sizeof(mbedtls_mpi_uint) == sizeof(unsigned long long)) {
|
||||
return (size_t) __builtin_clzll(a);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
size_t j;
|
||||
mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
|
||||
|
||||
|
@ -51,21 +68,17 @@ size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a)
|
|||
|
||||
size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs)
|
||||
{
|
||||
size_t i, j;
|
||||
int i;
|
||||
size_t j;
|
||||
|
||||
if (A_limbs == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = A_limbs - 1; i > 0; i--) {
|
||||
for (i = ((int) A_limbs) - 1; i >= 0; i--) {
|
||||
if (A[i] != 0) {
|
||||
break;
|
||||
j = biL - mbedtls_mpi_core_clz(A[i]);
|
||||
return (i * biL) + j;
|
||||
}
|
||||
}
|
||||
|
||||
j = biL - mbedtls_mpi_core_clz(A[i]);
|
||||
|
||||
return (i * biL) + j;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
|
||||
|
|
|
@ -101,10 +101,13 @@
|
|||
(((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff)
|
||||
|
||||
/** Count leading zero bits in a given integer.
|
||||
*
|
||||
* \warning The result is undefined if \p a == 0
|
||||
*
|
||||
* \param a Integer to count leading zero bits.
|
||||
*
|
||||
* \return The number of leading zero bits in \p a.
|
||||
* \return The number of leading zero bits in \p a, if \p a != 0.
|
||||
* If \p a == 0, the result is undefined.
|
||||
*/
|
||||
size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a);
|
||||
|
||||
|
|
|
@ -362,38 +362,46 @@ int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
|
|||
size_t buflen,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
|
||||
/* Do our best to check if r and m have been set up */
|
||||
if (r->limbs == 0 || N->limbs == 0) {
|
||||
goto cleanup;
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
if (r->limbs != N->limbs) {
|
||||
goto cleanup;
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi_uint *working_memory = r->p;
|
||||
size_t working_memory_len = sizeof(mbedtls_mpi_uint) * r->limbs;
|
||||
|
||||
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
|
||||
ret = mbedtls_mpi_mod_raw_from_mont_rep(r->p, N);
|
||||
|
||||
working_memory = mbedtls_calloc(r->limbs, sizeof(mbedtls_mpi_uint));
|
||||
|
||||
if (working_memory == NULL) {
|
||||
ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(working_memory, r->p, working_memory_len);
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_from_mont_rep(working_memory, N);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_write(r->p, N, buf, buflen, ext_rep);
|
||||
|
||||
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
|
||||
/* If this fails, the value of r is corrupted and we want to return
|
||||
* this error (as opposed to the error code from the write above) to
|
||||
* let the caller know. If it succeeds, we want to return the error
|
||||
* code from write above. */
|
||||
int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep(r->p, N);
|
||||
if (ret == 0) {
|
||||
ret = conv_ret;
|
||||
}
|
||||
}
|
||||
ret = mbedtls_mpi_mod_raw_write(working_memory, N, buf, buflen, ext_rep);
|
||||
|
||||
cleanup:
|
||||
|
||||
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY &&
|
||||
working_memory != NULL) {
|
||||
|
||||
mbedtls_platform_zeroize(working_memory, working_memory_len);
|
||||
mbedtls_free(working_memory);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,40 +316,6 @@ unsigned mbedtls_ct_uint_if(unsigned condition,
|
|||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
|
||||
/** Select between two sign values without branches.
|
||||
*
|
||||
* This is functionally equivalent to `condition ? if1 : if0` but uses only bit
|
||||
* operations in order to avoid branches.
|
||||
*
|
||||
* \note if1 and if0 must be either 1 or -1, otherwise the result
|
||||
* is undefined.
|
||||
*
|
||||
* \param condition Condition to test; must be either 0 or 1.
|
||||
* \param if1 The first sign; must be either +1 or -1.
|
||||
* \param if0 The second sign; must be either +1 or -1.
|
||||
*
|
||||
* \return \c if1 if \p condition is nonzero, otherwise \c if0.
|
||||
* */
|
||||
static int mbedtls_ct_cond_select_sign(unsigned char condition,
|
||||
int if1,
|
||||
int if0)
|
||||
{
|
||||
/* In order to avoid questions about what we can reasonably assume about
|
||||
* the representations of signed integers, move everything to unsigned
|
||||
* by taking advantage of the fact that if1 and if0 are either +1 or -1. */
|
||||
unsigned uif1 = if1 + 1;
|
||||
unsigned uif0 = if0 + 1;
|
||||
|
||||
/* condition was 0 or 1, mask is 0 or 2 as are uif1 and uif0 */
|
||||
const unsigned mask = condition << 1;
|
||||
|
||||
/* select uif1 or uif0 */
|
||||
unsigned ur = (uif0 & ~mask) | (uif1 & mask);
|
||||
|
||||
/* ur is now 0 or 2, convert back to -1 or +1 */
|
||||
return (int) ur - 1;
|
||||
}
|
||||
|
||||
void mbedtls_ct_mpi_uint_cond_assign(size_t n,
|
||||
mbedtls_mpi_uint *dest,
|
||||
const mbedtls_mpi_uint *src,
|
||||
|
@ -754,7 +720,7 @@ int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
|
|||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
|
||||
|
||||
X->s = mbedtls_ct_cond_select_sign(assign, Y->s, X->s);
|
||||
X->s = (int) mbedtls_ct_uint_if(assign, Y->s, X->s);
|
||||
|
||||
mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, assign);
|
||||
|
||||
|
@ -789,8 +755,8 @@ int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
|
|||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
|
||||
|
||||
s = X->s;
|
||||
X->s = mbedtls_ct_cond_select_sign(swap, Y->s, X->s);
|
||||
Y->s = mbedtls_ct_cond_select_sign(swap, s, Y->s);
|
||||
X->s = (int) mbedtls_ct_uint_if(swap, Y->s, X->s);
|
||||
Y->s = (int) mbedtls_ct_uint_if(swap, s, Y->s);
|
||||
|
||||
mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, swap);
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
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)
|
||||
|
@ -192,7 +192,7 @@ void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
|
|||
mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
|
||||
mbedtls_debug_print_mpi(ssl, level, file, line, str, &X->Y);
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
|
||||
|
@ -273,7 +273,7 @@ static void debug_print_pk(const mbedtls_ssl_context *ssl, int level,
|
|||
if (items[i].type == MBEDTLS_PK_DEBUG_MPI) {
|
||||
mbedtls_debug_print_mpi(ssl, level, file, line, name, items[i].value);
|
||||
} else
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (items[i].type == MBEDTLS_PK_DEBUG_ECP) {
|
||||
mbedtls_debug_print_ecp(ssl, level, file, line, name, items[i].value);
|
||||
} else
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
/*
|
||||
* References:
|
||||
*
|
||||
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
|
||||
* SEC1 https://www.secg.org/sec1-v2.pdf
|
||||
* RFC 4492
|
||||
*/
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
/*
|
||||
* References:
|
||||
*
|
||||
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
|
||||
* SEC1 https://www.secg.org/sec1-v2.pdf
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
@ -234,6 +234,19 @@ cleanup:
|
|||
}
|
||||
#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
|
||||
|
||||
int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid)
|
||||
{
|
||||
switch (gid) {
|
||||
#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
case MBEDTLS_ECP_DP_CURVE25519: return 0;
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
case MBEDTLS_ECP_DP_CURVE448: return 0;
|
||||
#endif
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
|
||||
/*
|
||||
* Compute ECDSA signature of a hashed message (SEC1 4.1.3)
|
||||
|
@ -373,19 +386,6 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid)
|
||||
{
|
||||
switch (gid) {
|
||||
#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
case MBEDTLS_ECP_DP_CURVE25519: return 0;
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
case MBEDTLS_ECP_DP_CURVE448: return 0;
|
||||
#endif
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute ECDSA signature of a hashed message
|
||||
*/
|
||||
|
|
|
@ -20,13 +20,15 @@
|
|||
/*
|
||||
* References:
|
||||
*
|
||||
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
|
||||
* SEC1 https://www.secg.org/sec1-v2.pdf
|
||||
* GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
|
||||
* FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
|
||||
* RFC 4492 for the related TLS structures and constants
|
||||
* - https://www.rfc-editor.org/rfc/rfc4492
|
||||
* RFC 7748 for the Curve448 and Curve25519 curve definitions
|
||||
* - https://www.rfc-editor.org/rfc/rfc7748
|
||||
*
|
||||
* [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
|
||||
* [Curve25519] https://cr.yp.to/ecdh/curve25519-20060209.pdf
|
||||
*
|
||||
* [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
|
||||
* for elliptic curve cryptosystems. In : Cryptographic Hardware and
|
||||
|
@ -70,7 +72,7 @@
|
|||
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/threading.h"
|
||||
|
@ -93,7 +95,10 @@
|
|||
* Counts of point addition and doubling, and field multiplications.
|
||||
* Used to test resistance of point multiplication to simple timing attacks.
|
||||
*/
|
||||
static unsigned long add_count, dbl_count, mul_count;
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
static unsigned long add_count, dbl_count;
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
static unsigned long mul_count;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
|
@ -320,6 +325,7 @@ int mbedtls_ecp_check_budget(const mbedtls_ecp_group *grp,
|
|||
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
static void mpi_init_many(mbedtls_mpi *arr, size_t size)
|
||||
{
|
||||
while (size--) {
|
||||
|
@ -333,6 +339,7 @@ static void mpi_free_many(mbedtls_mpi *arr, size_t size)
|
|||
mbedtls_mpi_free(arr++);
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
/*
|
||||
* List of supported curves:
|
||||
|
@ -1306,7 +1313,10 @@ cleanup:
|
|||
mbedtls_mpi_free(&exp);
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
|
||||
/*
|
||||
* For curves in short Weierstrass form, we do all the internal operations in
|
||||
* Jacobian coordinates.
|
||||
|
@ -2723,6 +2733,7 @@ int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||
{
|
||||
return mbedtls_ecp_mul_restartable(grp, R, m, P, f_rng, p_rng, NULL);
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
|
||||
/*
|
||||
|
@ -2763,6 +2774,7 @@ cleanup:
|
|||
}
|
||||
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
|
||||
/*
|
||||
* R = m * P with shortcuts for m == 0, m == 1 and m == -1
|
||||
|
@ -2914,6 +2926,7 @@ int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||
return mbedtls_ecp_muladd_restartable(grp, R, m, P, n, Q, NULL);
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||
|
@ -3159,6 +3172,7 @@ int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp,
|
|||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/*
|
||||
* Generate a keypair with configurable base point
|
||||
*/
|
||||
|
@ -3200,6 +3214,7 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
|
|||
|
||||
return mbedtls_ecp_gen_keypair(&key->grp, &key->d, &key->Q, f_rng, p_rng);
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
#define ECP_CURVE25519_KEY_SIZE 32
|
||||
#define ECP_CURVE448_KEY_SIZE 56
|
||||
|
@ -3316,7 +3331,7 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/*
|
||||
* Check a public-private key pair
|
||||
*/
|
||||
|
@ -3357,6 +3372,7 @@ cleanup:
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
/*
|
||||
* Export generic key-pair parameters.
|
||||
|
@ -3383,6 +3399,7 @@ int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp,
|
|||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/*
|
||||
* PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
|
||||
*
|
||||
|
@ -3490,12 +3507,14 @@ cleanup:
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
int mbedtls_ecp_self_test(int verbose)
|
||||
{
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_group grp;
|
||||
mbedtls_ecp_point R, P;
|
||||
|
@ -3609,10 +3628,14 @@ cleanup:
|
|||
}
|
||||
|
||||
return ret;
|
||||
#else /* MBEDTLS_ECP_C */
|
||||
(void) verbose;
|
||||
return 0;
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#endif /* !MBEDTLS_ECP_ALT */
|
||||
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
@ -4605,15 +4605,23 @@ static int ecp_mod_p255(mbedtls_mpi *);
|
|||
#endif
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
static int ecp_mod_p448(mbedtls_mpi *);
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p448(mbedtls_mpi *);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
||||
static int ecp_mod_p192k1(mbedtls_mpi *);
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p192k1(mbedtls_mpi *);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||
static int ecp_mod_p224k1(mbedtls_mpi *);
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p224k1(mbedtls_mpi *);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
static int ecp_mod_p256k1(mbedtls_mpi *);
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p256k1(mbedtls_mpi *);
|
||||
#endif
|
||||
|
||||
#if defined(ECP_LOAD_GROUP)
|
||||
|
@ -4897,7 +4905,7 @@ static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry)
|
|||
#define A(i) Np + (i) * WIDTH
|
||||
#define ADD(i) add64(p, A(i), &c)
|
||||
#define NEXT p += WIDTH; carry64(p, &c)
|
||||
#define LAST p += WIDTH; *p = c; while (++p < end) *p = 0
|
||||
#define LAST p += WIDTH; do *p = 0; while (++p < end)
|
||||
#define RESET last_carry[0] = c; c = 0; p = Np
|
||||
#define ADD_LAST add64(p, last_carry, &c)
|
||||
|
||||
|
@ -4934,13 +4942,23 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn)
|
|||
|
||||
RESET;
|
||||
|
||||
/* Use the reduction for the carry as well:
|
||||
* 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192
|
||||
* It can generate a carry. */
|
||||
ADD_LAST; NEXT; // A0 += last_carry
|
||||
ADD_LAST; NEXT; // A1 += last_carry
|
||||
// A2 += carry
|
||||
|
||||
RESET;
|
||||
|
||||
/* Use the reduction for the carry as well:
|
||||
* 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192
|
||||
*/
|
||||
ADD_LAST; NEXT; // A0 += last_carry
|
||||
ADD_LAST; NEXT; // A1 += last_carry
|
||||
// A2 += carry
|
||||
|
||||
LAST; // A2 += carry
|
||||
LAST;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -5433,6 +5451,11 @@ static int ecp_mod_p255(mbedtls_mpi *N)
|
|||
#define P224_WIDTH_MAX DIV_ROUND_UP(28, sizeof(mbedtls_mpi_uint))
|
||||
#define P224_UNUSED_BITS ((P224_WIDTH_MAX * sizeof(mbedtls_mpi_uint) * 8) - 224)
|
||||
|
||||
static int ecp_mod_p448(mbedtls_mpi *N)
|
||||
{
|
||||
return mbedtls_ecp_mod_p448(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
|
||||
* Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
|
||||
|
@ -5444,7 +5467,8 @@ static int ecp_mod_p255(mbedtls_mpi *N)
|
|||
* but for 64-bit targets it should use half the number of operations if we do
|
||||
* the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
|
||||
*/
|
||||
static int ecp_mod_p448(mbedtls_mpi *N)
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p448(mbedtls_mpi *N)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t i;
|
||||
|
@ -5514,7 +5538,6 @@ static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p
|
|||
size_t adjust, size_t shift, mbedtls_mpi_uint mask)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t i;
|
||||
mbedtls_mpi M, R;
|
||||
mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
|
||||
|
||||
|
@ -5531,55 +5554,31 @@ static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p
|
|||
M.s = 1;
|
||||
M.p = Mp;
|
||||
|
||||
/* M = A1 */
|
||||
M.n = N->n - (p_limbs - adjust);
|
||||
if (M.n > p_limbs + adjust) {
|
||||
M.n = p_limbs + adjust;
|
||||
}
|
||||
memset(Mp, 0, sizeof(Mp));
|
||||
memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
|
||||
if (shift != 0) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
|
||||
}
|
||||
M.n += R.n; /* Make room for multiplication by R */
|
||||
for (size_t pass = 0; pass < 2; pass++) {
|
||||
/* M = A1 */
|
||||
M.n = N->n - (p_limbs - adjust);
|
||||
if (M.n > p_limbs + adjust) {
|
||||
M.n = p_limbs + adjust;
|
||||
}
|
||||
memset(Mp, 0, sizeof(Mp));
|
||||
memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
|
||||
if (shift != 0) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
|
||||
}
|
||||
M.n += R.n; /* Make room for multiplication by R */
|
||||
|
||||
/* N = A0 */
|
||||
if (mask != 0) {
|
||||
N->p[p_limbs - 1] &= mask;
|
||||
}
|
||||
for (i = p_limbs; i < N->n; i++) {
|
||||
N->p[i] = 0;
|
||||
}
|
||||
/* N = A0 */
|
||||
if (mask != 0) {
|
||||
N->p[p_limbs - 1] &= mask;
|
||||
}
|
||||
for (size_t i = p_limbs; i < N->n; i++) {
|
||||
N->p[i] = 0;
|
||||
}
|
||||
|
||||
/* N = A0 + R * A1 */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
|
||||
|
||||
/* Second pass */
|
||||
|
||||
/* M = A1 */
|
||||
M.n = N->n - (p_limbs - adjust);
|
||||
if (M.n > p_limbs + adjust) {
|
||||
M.n = p_limbs + adjust;
|
||||
/* N = A0 + R * A1 */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
|
||||
}
|
||||
memset(Mp, 0, sizeof(Mp));
|
||||
memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
|
||||
if (shift != 0) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
|
||||
}
|
||||
M.n += R.n; /* Make room for multiplication by R */
|
||||
|
||||
/* N = A0 */
|
||||
if (mask != 0) {
|
||||
N->p[p_limbs - 1] &= mask;
|
||||
}
|
||||
for (i = p_limbs; i < N->n; i++) {
|
||||
N->p[i] = 0;
|
||||
}
|
||||
|
||||
/* N = A0 + R * A1 */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
|
@ -5594,6 +5593,12 @@ cleanup:
|
|||
* with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
|
||||
*/
|
||||
static int ecp_mod_p192k1(mbedtls_mpi *N)
|
||||
{
|
||||
return mbedtls_ecp_mod_p192k1(N);
|
||||
}
|
||||
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p192k1(mbedtls_mpi *N)
|
||||
{
|
||||
static mbedtls_mpi_uint Rp[] = {
|
||||
MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
|
@ -5606,11 +5611,18 @@ static int ecp_mod_p192k1(mbedtls_mpi *N)
|
|||
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||
|
||||
static int ecp_mod_p224k1(mbedtls_mpi *N)
|
||||
{
|
||||
return mbedtls_ecp_mod_p224k1(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p224k1 = 2^224 - R,
|
||||
* with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
|
||||
*/
|
||||
static int ecp_mod_p224k1(mbedtls_mpi *N)
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p224k1(mbedtls_mpi *N)
|
||||
{
|
||||
static mbedtls_mpi_uint Rp[] = {
|
||||
MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
|
@ -5628,11 +5640,18 @@ static int ecp_mod_p224k1(mbedtls_mpi *N)
|
|||
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
|
||||
static int ecp_mod_p256k1(mbedtls_mpi *N)
|
||||
{
|
||||
return mbedtls_ecp_mod_p256k1(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p256k1 = 2^256 - R,
|
||||
* with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
|
||||
*/
|
||||
static int ecp_mod_p256k1(mbedtls_mpi *N)
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p256k1(mbedtls_mpi *N)
|
||||
{
|
||||
static mbedtls_mpi_uint Rp[] = {
|
||||
MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
|
@ -5827,4 +5846,4 @@ int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
|||
}
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
#endif /* !MBEDTLS_ECP_ALT */
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "bignum_mod.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_LIGHT)
|
||||
|
||||
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
|
||||
/** Generate a private key on a Montgomery curve (Curve25519 or Curve448).
|
||||
|
@ -47,7 +47,7 @@
|
|||
* This is the bit-size of the key minus 1:
|
||||
* 254 for Curve25519 or 447 for Curve448.
|
||||
* \param d The randomly generated key. This is a number of size
|
||||
* exactly \p n_bits + 1 bits, with the least significant bits
|
||||
* exactly \p high_bit + 1 bits, with the least significant bits
|
||||
* masked as specified in [Curve25519] and in [RFC7748] §5.
|
||||
* \param f_rng The RNG function.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng.
|
||||
|
@ -55,7 +55,7 @@
|
|||
* \return \c 0 on success.
|
||||
* \return \c MBEDTLS_ERR_ECP_xxx or MBEDTLS_ERR_MPI_xxx on failure.
|
||||
*/
|
||||
int mbedtls_ecp_gen_privkey_mx(size_t n_bits,
|
||||
int mbedtls_ecp_gen_privkey_mx(size_t high_bit,
|
||||
mbedtls_mpi *d,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
@ -169,6 +169,37 @@ int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
|||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p192k1 = 2^192 - R,
|
||||
* with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p192k1(mbedtls_mpi *N);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p224k1(mbedtls_mpi *N);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p256k1(mbedtls_mpi *N);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p448(mbedtls_mpi *N);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
|
||||
|
||||
/** Initialise a modulus with hard-coded const curve data.
|
||||
*
|
||||
* \note The caller is responsible for the \p N modulus' memory.
|
||||
|
|
|
@ -318,6 +318,18 @@ static const oid_x509_ext_t oid_x509_ext[] =
|
|||
"Certificate Policies"),
|
||||
MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
|
||||
"id-ce-subjectKeyIdentifier",
|
||||
"Subject Key Identifier"),
|
||||
MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
|
||||
"id-ce-authorityKeyIdentifier",
|
||||
"Authority Key Identifier"),
|
||||
MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER,
|
||||
},
|
||||
{
|
||||
NULL_OID_DESCRIPTOR,
|
||||
0,
|
||||
|
@ -531,9 +543,9 @@ FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg,
|
|||
mbedtls_pk_type_t,
|
||||
pk_alg)
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/*
|
||||
* For namedCurve (RFC 5480)
|
||||
* For elliptic curves that use namedCurve inside ECParams (RFC 5480)
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_oid_descriptor_t descriptor;
|
||||
|
@ -621,7 +633,48 @@ FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp,
|
|||
oid_ecp_grp,
|
||||
mbedtls_ecp_group_id,
|
||||
grp_id)
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
/*
|
||||
* For Elliptic Curve algorithms that are directly
|
||||
* encoded in the AlgorithmIdentifier (RFC 8410)
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_oid_descriptor_t descriptor;
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
} oid_ecp_grp_algid_t;
|
||||
|
||||
static const oid_ecp_grp_algid_t oid_ecp_grp_algid[] =
|
||||
{
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_X25519, "X25519", "X25519"),
|
||||
MBEDTLS_ECP_DP_CURVE25519,
|
||||
},
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_X448, "X448", "X448"),
|
||||
MBEDTLS_ECP_DP_CURVE448,
|
||||
},
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
|
||||
{
|
||||
NULL_OID_DESCRIPTOR,
|
||||
MBEDTLS_ECP_DP_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_algid_t, grp_id_algid, oid_ecp_grp_algid)
|
||||
FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp_algid,
|
||||
oid_ecp_grp_algid_t,
|
||||
grp_id_algid,
|
||||
mbedtls_ecp_group_id,
|
||||
grp_id)
|
||||
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp_algid,
|
||||
oid_ecp_grp_algid_t,
|
||||
oid_ecp_grp_algid,
|
||||
mbedtls_ecp_group_id,
|
||||
grp_id)
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
/*
|
||||
|
|
|
@ -491,7 +491,7 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer,
|
|||
size_t len = 0, use_len, add_len = 0;
|
||||
|
||||
mbedtls_base64_encode(NULL, 0, &use_len, der_data, der_len);
|
||||
add_len = strlen(header) + strlen(footer) + (use_len / 64) + 1;
|
||||
add_len = strlen(header) + strlen(footer) + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1;
|
||||
|
||||
if (use_len + add_len > buf_len) {
|
||||
*olen = use_len + add_len;
|
||||
|
|
68
library/pk.c
68
library/pk.c
|
@ -32,7 +32,7 @@
|
|||
#if defined(MBEDTLS_RSA_C)
|
||||
#include "mbedtls/rsa.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#include "mbedtls/ecp.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
|
@ -60,6 +60,9 @@ void mbedtls_pk_init(mbedtls_pk_context *ctx)
|
|||
{
|
||||
ctx->pk_info = NULL;
|
||||
ctx->pk_ctx = NULL;
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -71,7 +74,7 @@ void mbedtls_pk_free(mbedtls_pk_context *ctx)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ctx->pk_info != NULL) {
|
||||
if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) {
|
||||
ctx->pk_info->ctx_free_func(ctx->pk_ctx);
|
||||
}
|
||||
|
||||
|
@ -114,17 +117,17 @@ const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
|
|||
#if defined(MBEDTLS_RSA_C)
|
||||
case MBEDTLS_PK_RSA:
|
||||
return &mbedtls_rsa_info;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
case MBEDTLS_PK_ECKEY:
|
||||
return &mbedtls_eckey_info;
|
||||
case MBEDTLS_PK_ECKEY_DH:
|
||||
return &mbedtls_eckeydh_info;
|
||||
#endif
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
|
||||
case MBEDTLS_PK_ECDSA:
|
||||
return &mbedtls_ecdsa_info;
|
||||
#endif
|
||||
#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
|
||||
/* MBEDTLS_PK_RSA_ALT omitted on purpose */
|
||||
default:
|
||||
return NULL;
|
||||
|
@ -140,7 +143,8 @@ int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
|
|||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
|
||||
if ((info->ctx_alloc_func == NULL) ||
|
||||
((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) {
|
||||
return MBEDTLS_ERR_PK_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
|
@ -158,7 +162,6 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
|
|||
{
|
||||
const mbedtls_pk_info_t *info = NULL;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t *pk_ctx;
|
||||
psa_key_type_t type;
|
||||
|
||||
if (ctx == NULL || ctx->pk_info != NULL) {
|
||||
|
@ -179,14 +182,8 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
|
|||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
|
||||
return MBEDTLS_ERR_PK_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
ctx->pk_info = info;
|
||||
|
||||
pk_ctx = (mbedtls_svc_key_id_t *) ctx->pk_ctx;
|
||||
*pk_ctx = key;
|
||||
ctx->priv_id = key;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -315,12 +312,11 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
|
|||
return (key_usage & usage) == usage;
|
||||
}
|
||||
|
||||
const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t key_alg, key_alg2;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_get_key_attributes(*key, &attributes);
|
||||
status = psa_get_key_attributes(ctx->priv_id, &attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -443,7 +439,7 @@ int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = ctx->pk_info->verify_rs_func(ctx->pk_ctx,
|
||||
ret = ctx->pk_info->verify_rs_func(ctx,
|
||||
md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx);
|
||||
|
||||
if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
|
||||
|
@ -460,7 +456,7 @@ int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
|
|||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
return ctx->pk_info->verify_func(ctx->pk_ctx, md_alg, hash, hash_len,
|
||||
return ctx->pk_info->verify_func(ctx, md_alg, hash, hash_len,
|
||||
sig, sig_len);
|
||||
}
|
||||
|
||||
|
@ -626,7 +622,7 @@ int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = ctx->pk_info->sign_rs_func(ctx->pk_ctx, md_alg,
|
||||
ret = ctx->pk_info->sign_rs_func(ctx, md_alg,
|
||||
hash, hash_len,
|
||||
sig, sig_size, sig_len,
|
||||
f_rng, p_rng, rs_ctx->rs_ctx);
|
||||
|
@ -645,7 +641,7 @@ int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
|
|||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
return ctx->pk_info->sign_func(ctx->pk_ctx, md_alg,
|
||||
return ctx->pk_info->sign_func(ctx, md_alg,
|
||||
hash, hash_len,
|
||||
sig, sig_size, sig_len,
|
||||
f_rng, p_rng);
|
||||
|
@ -701,10 +697,9 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
|
|||
}
|
||||
|
||||
if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
|
||||
const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_sign_hash(*key, PSA_ALG_RSA_PSS(psa_md_alg),
|
||||
status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
|
||||
hash, hash_len,
|
||||
sig, sig_size, sig_len);
|
||||
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
|
||||
|
@ -736,7 +731,7 @@ int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
|
|||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
return ctx->pk_info->decrypt_func(ctx->pk_ctx, input, ilen,
|
||||
return ctx->pk_info->decrypt_func(ctx, input, ilen,
|
||||
output, olen, osize, f_rng, p_rng);
|
||||
}
|
||||
|
||||
|
@ -756,7 +751,7 @@ int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
|
|||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
return ctx->pk_info->encrypt_func(ctx->pk_ctx, input, ilen,
|
||||
return ctx->pk_info->encrypt_func(ctx, input, ilen,
|
||||
output, olen, osize, f_rng, p_rng);
|
||||
}
|
||||
|
||||
|
@ -791,7 +786,9 @@ int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
|
|||
}
|
||||
}
|
||||
|
||||
return prv->pk_info->check_pair_func(pub->pk_ctx, prv->pk_ctx, f_rng, p_rng);
|
||||
return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub,
|
||||
(mbedtls_pk_context *) prv,
|
||||
f_rng, p_rng);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -805,7 +802,7 @@ size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return ctx->pk_info->get_bitlen(ctx->pk_ctx);
|
||||
return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -821,7 +818,7 @@ int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items
|
|||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
ctx->pk_info->debug_func(ctx->pk_ctx, items);
|
||||
ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -862,16 +859,16 @@ int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
|
|||
psa_key_usage_t usage,
|
||||
psa_algorithm_t alg2)
|
||||
{
|
||||
#if !defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_RSA_C)
|
||||
#if !defined(MBEDTLS_ECP_LIGHT) && !defined(MBEDTLS_RSA_C)
|
||||
((void) pk);
|
||||
((void) key);
|
||||
((void) alg);
|
||||
((void) usage);
|
||||
((void) alg2);
|
||||
#else
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#else /* !MBEDTLS_ECP_LIGHT && !MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
|
||||
const mbedtls_ecp_keypair *ec;
|
||||
mbedtls_ecp_keypair *ec;
|
||||
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
|
||||
size_t d_len;
|
||||
psa_ecc_family_t curve_id;
|
||||
|
@ -884,7 +881,7 @@ int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
|
|||
/* export the private key material in the format PSA wants */
|
||||
ec = mbedtls_pk_ec(*pk);
|
||||
d_len = PSA_BITS_TO_BYTES(ec->grp.nbits);
|
||||
if ((ret = mbedtls_mpi_write_binary(&ec->d, d, d_len)) != 0) {
|
||||
if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -902,6 +899,7 @@ int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
|
|||
|
||||
/* import private key into PSA */
|
||||
status = psa_import_key(&attributes, d, d_len, key);
|
||||
mbedtls_platform_zeroize(d, sizeof(d));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
@ -912,7 +910,7 @@ int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
|
|||
|
||||
return mbedtls_pk_setup_opaque(pk, *key);
|
||||
} else
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) {
|
||||
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
|
||||
|
@ -953,7 +951,7 @@ int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
|
|||
return mbedtls_pk_setup_opaque(pk, *key);
|
||||
} else
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#endif /* !MBEDTLS_ECP_C && !MBEDTLS_RSA_C */
|
||||
#endif /* !MBEDTLS_ECP_LIGHT && !MBEDTLS_RSA_C */
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
|
|
@ -191,18 +191,18 @@ static int rsa_can_do(mbedtls_pk_type_t type)
|
|||
type == MBEDTLS_PK_RSASSA_PSS;
|
||||
}
|
||||
|
||||
static size_t rsa_get_bitlen(const void *ctx)
|
||||
static size_t rsa_get_bitlen(mbedtls_pk_context *pk)
|
||||
{
|
||||
const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) ctx;
|
||||
const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) pk->pk_ctx;
|
||||
return 8 * mbedtls_rsa_get_len(rsa);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static int rsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len)
|
||||
{
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
|
@ -225,7 +225,7 @@ static int rsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
/* mbedtls_pk_write_pubkey_der() expects a full PK context;
|
||||
* re-construct one to make it happy */
|
||||
key.pk_info = &mbedtls_rsa_info;
|
||||
key.pk_ctx = ctx;
|
||||
key.pk_ctx = rsa;
|
||||
key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
|
||||
if (key_len <= 0) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
@ -260,12 +260,12 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
#else
|
||||
static int rsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
|
||||
size_t rsa_len = mbedtls_rsa_get_len(rsa);
|
||||
|
||||
if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
|
||||
|
@ -354,7 +354,7 @@ cleanup:
|
|||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static int rsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
|
@ -370,16 +370,16 @@ static int rsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
|
||||
return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PKCS1V15_SIGN(
|
||||
psa_md_alg),
|
||||
ctx, hash, hash_len,
|
||||
pk->pk_ctx, hash, hash_len,
|
||||
sig, sig_size, sig_len);
|
||||
}
|
||||
#else
|
||||
static int rsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
|
||||
|
||||
if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
@ -397,12 +397,12 @@ static int rsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static int rsa_decrypt_wrap(void *ctx,
|
||||
static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
|
@ -427,7 +427,7 @@ static int rsa_decrypt_wrap(void *ctx,
|
|||
/* mbedtls_pk_write_key_der() expects a full PK context;
|
||||
* re-construct one to make it happy */
|
||||
key.pk_info = &mbedtls_rsa_info;
|
||||
key.pk_ctx = ctx;
|
||||
key.pk_ctx = rsa;
|
||||
key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf));
|
||||
if (key_len <= 0) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
@ -466,12 +466,12 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
#else
|
||||
static int rsa_decrypt_wrap(void *ctx,
|
||||
static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
|
||||
|
||||
if (ilen != mbedtls_rsa_get_len(rsa)) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
@ -483,12 +483,12 @@ static int rsa_decrypt_wrap(void *ctx,
|
|||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static int rsa_encrypt_wrap(void *ctx,
|
||||
static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
|
@ -513,7 +513,7 @@ static int rsa_encrypt_wrap(void *ctx,
|
|||
/* mbedtls_pk_write_pubkey_der() expects a full PK context;
|
||||
* re-construct one to make it happy */
|
||||
key.pk_info = &mbedtls_rsa_info;
|
||||
key.pk_ctx = ctx;
|
||||
key.pk_ctx = rsa;
|
||||
key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
|
||||
if (key_len <= 0) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
@ -551,12 +551,12 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
#else
|
||||
static int rsa_encrypt_wrap(void *ctx,
|
||||
static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
|
||||
*olen = mbedtls_rsa_get_len(rsa);
|
||||
|
||||
if (*olen > osize) {
|
||||
|
@ -568,14 +568,14 @@ static int rsa_encrypt_wrap(void *ctx,
|
|||
}
|
||||
#endif
|
||||
|
||||
static int rsa_check_pair_wrap(const void *pub, const void *prv,
|
||||
static int rsa_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng)
|
||||
{
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub,
|
||||
(const mbedtls_rsa_context *) prv);
|
||||
return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub->pk_ctx,
|
||||
(const mbedtls_rsa_context *) prv->pk_ctx);
|
||||
}
|
||||
|
||||
static void *rsa_alloc_wrap(void)
|
||||
|
@ -595,22 +595,24 @@ static void rsa_free_wrap(void *ctx)
|
|||
mbedtls_free(ctx);
|
||||
}
|
||||
|
||||
static void rsa_debug(const void *ctx, mbedtls_pk_debug_item *items)
|
||||
static void rsa_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
|
||||
{
|
||||
#if defined(MBEDTLS_RSA_ALT)
|
||||
/* Not supported */
|
||||
(void) ctx;
|
||||
(void) pk;
|
||||
(void) items;
|
||||
#else
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
|
||||
|
||||
items->type = MBEDTLS_PK_DEBUG_MPI;
|
||||
items->name = "rsa.N";
|
||||
items->value = &(((mbedtls_rsa_context *) ctx)->N);
|
||||
items->value = &(rsa->N);
|
||||
|
||||
items++;
|
||||
|
||||
items->type = MBEDTLS_PK_DEBUG_MPI;
|
||||
items->name = "rsa.E";
|
||||
items->value = &(((mbedtls_rsa_context *) ctx)->E);
|
||||
items->value = &(rsa->E);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -638,7 +640,7 @@ const mbedtls_pk_info_t mbedtls_rsa_info = {
|
|||
};
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/*
|
||||
* Generic EC key
|
||||
*/
|
||||
|
@ -649,9 +651,10 @@ static int eckey_can_do(mbedtls_pk_type_t type)
|
|||
type == MBEDTLS_PK_ECDSA;
|
||||
}
|
||||
|
||||
static size_t eckey_get_bitlen(const void *ctx)
|
||||
static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
|
||||
{
|
||||
return ((mbedtls_ecp_keypair *) ctx)->grp.pbits;
|
||||
mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
return ecp->grp.pbits;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
|
||||
|
@ -716,11 +719,12 @@ static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ecdsa_verify_wrap(void *ctx_arg, mbedtls_md_type_t md_alg,
|
||||
static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
|
||||
mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len)
|
||||
{
|
||||
mbedtls_ecp_keypair *ctx = ctx_arg;
|
||||
mbedtls_ecp_keypair *ctx = pk->pk_ctx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
|
@ -799,14 +803,14 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
static int ecdsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int ecdsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
((void) md_alg);
|
||||
|
||||
ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) ctx,
|
||||
ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) pk->pk_ctx,
|
||||
hash, hash_len, sig, sig_len);
|
||||
|
||||
if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
|
||||
|
@ -904,12 +908,12 @@ static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ecdsa_sign_wrap(void *ctx_arg, mbedtls_md_type_t md_alg,
|
||||
static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
mbedtls_ecp_keypair *ctx = ctx_arg;
|
||||
mbedtls_ecp_keypair *ctx = pk->pk_ctx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
|
@ -974,12 +978,12 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) ctx,
|
||||
return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) pk->pk_ctx,
|
||||
md_alg, hash, hash_len,
|
||||
sig, sig_size, sig_len,
|
||||
f_rng, p_rng);
|
||||
|
@ -989,12 +993,12 @@ static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/* Forward declarations */
|
||||
static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int ecdsa_verify_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len,
|
||||
void *rs_ctx);
|
||||
|
||||
static int ecdsa_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int ecdsa_sign_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
|
@ -1041,7 +1045,7 @@ static void eckey_rs_free(void *ctx)
|
|||
mbedtls_free(ctx);
|
||||
}
|
||||
|
||||
static int eckey_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int eckey_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len,
|
||||
void *rs_ctx)
|
||||
|
@ -1056,10 +1060,10 @@ static int eckey_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
|
||||
/* set up our own sub-context if needed (that is, on first run) */
|
||||
if (rs->ecdsa_ctx.grp.pbits == 0) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, ctx));
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx));
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(&rs->ecdsa_ctx,
|
||||
MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(pk,
|
||||
md_alg, hash, hash_len,
|
||||
sig, sig_len, &rs->ecdsa_rs));
|
||||
|
||||
|
@ -1067,7 +1071,7 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int eckey_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int eckey_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
|
@ -1083,10 +1087,10 @@ static int eckey_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
|
||||
/* set up our own sub-context if needed (that is, on first run) */
|
||||
if (rs->ecdsa_ctx.grp.pbits == 0) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, ctx));
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx));
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(&rs->ecdsa_ctx, md_alg,
|
||||
MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(pk, md_alg,
|
||||
hash, hash_len, sig, sig_size, sig_len,
|
||||
f_rng, p_rng, &rs->ecdsa_rs));
|
||||
|
||||
|
@ -1095,13 +1099,92 @@ cleanup:
|
|||
}
|
||||
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
static int eckey_check_pair(const void *pub, const void *prv,
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
/*
|
||||
* Alternative function used to verify that the EC private/public key pair
|
||||
* is valid using PSA functions instead of ECP ones.
|
||||
* The flow is:
|
||||
* - import the private key "prv" to PSA and export its public part
|
||||
* - write the raw content of public key "pub" to a local buffer
|
||||
* - compare the two buffers
|
||||
*/
|
||||
static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
|
||||
{
|
||||
psa_status_t status, destruction_status;
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_ecp_keypair *prv_ctx = prv->pk_ctx;
|
||||
mbedtls_ecp_keypair *pub_ctx = pub->pk_ctx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
/* We are using MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH for the size of this
|
||||
* buffer because it will be used to hold the private key at first and
|
||||
* then its public part (but not at the same time). */
|
||||
uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
|
||||
size_t prv_key_len;
|
||||
uint8_t pub_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
|
||||
size_t pub_key_len;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
size_t curve_bits;
|
||||
const psa_ecc_family_t curve =
|
||||
mbedtls_ecc_group_to_psa(prv_ctx->grp.id, &curve_bits);
|
||||
const size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits);
|
||||
|
||||
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&prv_ctx->d, prv_key_buf, curve_bytes);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
status = psa_import_key(&key_attr, prv_key_buf, curve_bytes, &key_id);
|
||||
ret = PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf));
|
||||
|
||||
status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
|
||||
&prv_key_len);
|
||||
ret = PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
destruction_status = psa_destroy_key(key_id);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
} else if (destruction_status != PSA_SUCCESS) {
|
||||
return PSA_PK_TO_MBEDTLS_ERR(destruction_status);
|
||||
}
|
||||
|
||||
ret = mbedtls_ecp_point_write_binary(&pub_ctx->grp, &pub_ctx->Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
&pub_key_len, pub_key_buf,
|
||||
sizeof(pub_key_buf));
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
static int eckey_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng)
|
||||
{
|
||||
return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub,
|
||||
(const mbedtls_ecp_keypair *) prv,
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
return eckey_check_pair_psa(pub, prv);
|
||||
#elif defined(MBEDTLS_ECP_C)
|
||||
return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub->pk_ctx,
|
||||
(const mbedtls_ecp_keypair *) prv->pk_ctx,
|
||||
f_rng, p_rng);
|
||||
#else
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *eckey_alloc_wrap(void)
|
||||
|
@ -1121,11 +1204,12 @@ static void eckey_free_wrap(void *ctx)
|
|||
mbedtls_free(ctx);
|
||||
}
|
||||
|
||||
static void eckey_debug(const void *ctx, mbedtls_pk_debug_item *items)
|
||||
static void eckey_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
|
||||
{
|
||||
mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
items->type = MBEDTLS_PK_DEBUG_ECP;
|
||||
items->name = "eckey.Q";
|
||||
items->value = &(((mbedtls_ecp_keypair *) ctx)->Q);
|
||||
items->value = &(ecp->Q);
|
||||
}
|
||||
|
||||
const mbedtls_pk_info_t mbedtls_eckey_info = {
|
||||
|
@ -1190,7 +1274,7 @@ const mbedtls_pk_info_t mbedtls_eckeydh_info = {
|
|||
#endif
|
||||
eckey_debug, /* Same underlying key structure */
|
||||
};
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
|
||||
static int ecdsa_can_do(mbedtls_pk_type_t type)
|
||||
|
@ -1199,7 +1283,7 @@ static int ecdsa_can_do(mbedtls_pk_type_t type)
|
|||
}
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int ecdsa_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len,
|
||||
void *rs_ctx)
|
||||
|
@ -1208,7 +1292,7 @@ static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
((void) md_alg);
|
||||
|
||||
ret = mbedtls_ecdsa_read_signature_restartable(
|
||||
(mbedtls_ecdsa_context *) ctx,
|
||||
(mbedtls_ecdsa_context *) pk->pk_ctx,
|
||||
hash, hash_len, sig, sig_len,
|
||||
(mbedtls_ecdsa_restart_ctx *) rs_ctx);
|
||||
|
||||
|
@ -1219,14 +1303,14 @@ static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ecdsa_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int ecdsa_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
void *rs_ctx)
|
||||
{
|
||||
return mbedtls_ecdsa_write_signature_restartable(
|
||||
(mbedtls_ecdsa_context *) ctx,
|
||||
(mbedtls_ecdsa_context *) pk->pk_ctx,
|
||||
md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng,
|
||||
(mbedtls_ecdsa_restart_ctx *) rs_ctx);
|
||||
|
||||
|
@ -1292,19 +1376,19 @@ static int rsa_alt_can_do(mbedtls_pk_type_t type)
|
|||
return type == MBEDTLS_PK_RSA;
|
||||
}
|
||||
|
||||
static size_t rsa_alt_get_bitlen(const void *ctx)
|
||||
static size_t rsa_alt_get_bitlen(mbedtls_pk_context *pk)
|
||||
{
|
||||
const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
|
||||
const mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
|
||||
|
||||
return 8 * rsa_alt->key_len_func(rsa_alt->key);
|
||||
}
|
||||
|
||||
static int rsa_alt_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int rsa_alt_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
|
||||
mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
|
||||
|
||||
if (UINT_MAX < hash_len) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
@ -1322,12 +1406,12 @@ static int rsa_alt_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
md_alg, (unsigned int) hash_len, hash, sig);
|
||||
}
|
||||
|
||||
static int rsa_alt_decrypt_wrap(void *ctx,
|
||||
static int rsa_alt_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
|
||||
mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
|
||||
|
||||
((void) f_rng);
|
||||
((void) p_rng);
|
||||
|
@ -1341,7 +1425,7 @@ static int rsa_alt_decrypt_wrap(void *ctx,
|
|||
}
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
static int rsa_alt_check_pair(const void *pub, const void *prv,
|
||||
static int rsa_alt_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng)
|
||||
{
|
||||
|
@ -1356,14 +1440,14 @@ static int rsa_alt_check_pair(const void *pub, const void *prv,
|
|||
|
||||
memset(hash, 0x2a, sizeof(hash));
|
||||
|
||||
if ((ret = rsa_alt_sign_wrap((void *) prv, MBEDTLS_MD_NONE,
|
||||
if ((ret = rsa_alt_sign_wrap(prv, MBEDTLS_MD_NONE,
|
||||
hash, sizeof(hash),
|
||||
sig, sizeof(sig), &sig_len,
|
||||
f_rng, p_rng)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rsa_verify_wrap((void *) pub, MBEDTLS_MD_NONE,
|
||||
if (rsa_verify_wrap(pub, MBEDTLS_MD_NONE,
|
||||
hash, sizeof(hash), sig, sig_len) != 0) {
|
||||
return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
|
||||
}
|
||||
|
@ -1419,29 +1503,12 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
|
|||
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
||||
static void *pk_opaque_alloc_wrap(void)
|
||||
static size_t pk_opaque_get_bitlen(mbedtls_pk_context *pk)
|
||||
{
|
||||
void *ctx = mbedtls_calloc(1, sizeof(mbedtls_svc_key_id_t));
|
||||
|
||||
/* no _init() function to call, as calloc() already zeroized */
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void pk_opaque_free_wrap(void *ctx)
|
||||
{
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_svc_key_id_t));
|
||||
mbedtls_free(ctx);
|
||||
}
|
||||
|
||||
static size_t pk_opaque_get_bitlen(const void *ctx)
|
||||
{
|
||||
const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx;
|
||||
size_t bits;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
if (PSA_SUCCESS != psa_get_key_attributes(*key, &attributes)) {
|
||||
if (PSA_SUCCESS != psa_get_key_attributes(pk->priv_id, &attributes)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1462,13 +1529,13 @@ static int pk_opaque_rsa_can_do(mbedtls_pk_type_t type)
|
|||
type == MBEDTLS_PK_RSASSA_PSS;
|
||||
}
|
||||
|
||||
static int pk_opaque_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
||||
static int pk_opaque_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
#if !defined(MBEDTLS_PK_CAN_ECDSA_SIGN) && !defined(MBEDTLS_RSA_C)
|
||||
((void) ctx);
|
||||
((void) pk);
|
||||
((void) md_alg);
|
||||
((void) hash);
|
||||
((void) hash_len);
|
||||
|
@ -1479,7 +1546,6 @@ static int pk_opaque_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
((void) p_rng);
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
#else /* !MBEDTLS_PK_CAN_ECDSA_SIGN && !MBEDTLS_RSA_C */
|
||||
const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t alg;
|
||||
psa_key_type_t type;
|
||||
|
@ -1489,7 +1555,7 @@ static int pk_opaque_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
|
||||
status = psa_get_key_attributes(*key, &attributes);
|
||||
status = psa_get_key_attributes(pk->priv_id, &attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
@ -1510,7 +1576,7 @@ static int pk_opaque_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
|
|||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
|
||||
/* make the signature */
|
||||
status = psa_sign_hash(*key, alg, hash, hash_len,
|
||||
status = psa_sign_hash(pk->priv_id, alg, hash, hash_len,
|
||||
sig, sig_size, sig_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
|
||||
|
@ -1551,8 +1617,8 @@ const mbedtls_pk_info_t mbedtls_pk_ecdsa_opaque_info = {
|
|||
NULL, /* decrypt - not relevant */
|
||||
NULL, /* encrypt - not relevant */
|
||||
NULL, /* check_pair - could be done later or left NULL */
|
||||
pk_opaque_alloc_wrap,
|
||||
pk_opaque_free_wrap,
|
||||
NULL, /* alloc - no need to allocate new data dynamically */
|
||||
NULL, /* free - as for the alloc, there is no data to free */
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
NULL, /* restart alloc - not relevant */
|
||||
NULL, /* restart free - not relevant */
|
||||
|
@ -1561,19 +1627,18 @@ const mbedtls_pk_info_t mbedtls_pk_ecdsa_opaque_info = {
|
|||
};
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
|
||||
static int pk_opaque_rsa_decrypt(void *ctx,
|
||||
static int pk_opaque_rsa_decrypt(mbedtls_pk_context *pk,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx;
|
||||
psa_status_t status;
|
||||
|
||||
/* PSA has its own RNG */
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
|
||||
status = psa_asymmetric_decrypt(*key, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
status = psa_asymmetric_decrypt(pk->priv_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
input, ilen,
|
||||
NULL, 0,
|
||||
output, osize, olen);
|
||||
|
@ -1603,8 +1668,8 @@ const mbedtls_pk_info_t mbedtls_pk_rsa_opaque_info = {
|
|||
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
|
||||
NULL, /* encrypt - will be done later */
|
||||
NULL, /* check_pair - could be done later or left NULL */
|
||||
pk_opaque_alloc_wrap,
|
||||
pk_opaque_free_wrap,
|
||||
NULL, /* alloc - no need to allocate new data dynamically */
|
||||
NULL, /* free - as for the alloc, there is no data to free */
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
NULL, /* restart alloc - not relevant */
|
||||
NULL, /* restart free - not relevant */
|
||||
|
|
|
@ -39,18 +39,18 @@ struct mbedtls_pk_info_t {
|
|||
const char *name;
|
||||
|
||||
/** Get key size in bits */
|
||||
size_t (*get_bitlen)(const void *);
|
||||
size_t (*get_bitlen)(mbedtls_pk_context *pk);
|
||||
|
||||
/** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */
|
||||
int (*can_do)(mbedtls_pk_type_t type);
|
||||
|
||||
/** Verify signature */
|
||||
int (*verify_func)(void *ctx, mbedtls_md_type_t md_alg,
|
||||
int (*verify_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len);
|
||||
|
||||
/** Make signature */
|
||||
int (*sign_func)(void *ctx, mbedtls_md_type_t md_alg,
|
||||
int (*sign_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
|
@ -58,13 +58,13 @@ struct mbedtls_pk_info_t {
|
|||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/** Verify signature (restartable) */
|
||||
int (*verify_rs_func)(void *ctx, mbedtls_md_type_t md_alg,
|
||||
int (*verify_rs_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len,
|
||||
void *rs_ctx);
|
||||
|
||||
/** Make signature (restartable) */
|
||||
int (*sign_rs_func)(void *ctx, mbedtls_md_type_t md_alg,
|
||||
int (*sign_rs_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
|
@ -72,19 +72,19 @@ struct mbedtls_pk_info_t {
|
|||
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/** Decrypt message */
|
||||
int (*decrypt_func)(void *ctx, const unsigned char *input, size_t ilen,
|
||||
int (*decrypt_func)(mbedtls_pk_context *pk, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** Encrypt message */
|
||||
int (*encrypt_func)(void *ctx, const unsigned char *input, size_t ilen,
|
||||
int (*encrypt_func)(mbedtls_pk_context *pk, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** Check public-private key pair */
|
||||
int (*check_pair_func)(const void *pub, const void *prv,
|
||||
int (*check_pair_func)(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
|
@ -103,7 +103,7 @@ struct mbedtls_pk_info_t {
|
|||
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/** Interface with the debug module */
|
||||
void (*debug_func)(const void *ctx, mbedtls_pk_debug_item *items);
|
||||
void (*debug_func)(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items);
|
||||
|
||||
};
|
||||
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
||||
|
@ -120,7 +120,7 @@ typedef struct {
|
|||
extern const mbedtls_pk_info_t mbedtls_rsa_info;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
extern const mbedtls_pk_info_t mbedtls_eckey_info;
|
||||
extern const mbedtls_pk_info_t mbedtls_eckeydh_info;
|
||||
#endif
|
||||
|
|
|
@ -32,8 +32,9 @@
|
|||
#if defined(MBEDTLS_RSA_C)
|
||||
#include "mbedtls/rsa.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#include "mbedtls/ecp.h"
|
||||
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
|
||||
#include "pkwrite.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
#include "mbedtls/ecdsa.h"
|
||||
|
@ -48,6 +49,14 @@
|
|||
#include "mbedtls/pkcs12.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#include "mbedtls/psa_util.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
|
@ -155,7 +164,7 @@ int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context *ctx, const char *path)
|
|||
}
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
|
||||
*
|
||||
* ECParameters ::= CHOICE {
|
||||
|
@ -224,7 +233,7 @@ static int pk_group_from_specified(const mbedtls_asn1_buf *params, mbedtls_ecp_g
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *p = params->p;
|
||||
const unsigned char * const end = params->p + params->len;
|
||||
const unsigned char *const end = params->p + params->len;
|
||||
const unsigned char *end_field, *end_curve;
|
||||
size_t len;
|
||||
int ver;
|
||||
|
@ -396,7 +405,6 @@ static int pk_group_id_from_group(const mbedtls_ecp_group *grp, mbedtls_ecp_grou
|
|||
mbedtls_mpi_get_bit(&grp->G.Y, 0) == mbedtls_mpi_get_bit(&ref.G.Y, 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -487,6 +495,119 @@ static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_ecp_group *gr
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/*
|
||||
* Helper function for deriving a public key from its private counterpart.
|
||||
*/
|
||||
static int pk_derive_public_key(mbedtls_ecp_keypair *eck,
|
||||
const unsigned char *d, size_t d_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
int ret;
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status, destruction_status;
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
size_t curve_bits;
|
||||
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
|
||||
/* This buffer is used to store the private key at first and then the
|
||||
* public one (but not at the same time). Therefore we size it for the
|
||||
* latter since it's bigger. */
|
||||
unsigned char key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
|
||||
size_t key_len;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
|
||||
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
|
||||
|
||||
status = psa_import_key(&key_attr, d, d_len, &key_id);
|
||||
ret = psa_pk_status_to_mbedtls(status);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(key_buf, sizeof(key_buf));
|
||||
|
||||
status = psa_export_public_key(key_id, key_buf, sizeof(key_buf), &key_len);
|
||||
ret = psa_pk_status_to_mbedtls(status);
|
||||
destruction_status = psa_destroy_key(key_id);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
} else if (destruction_status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(destruction_status);
|
||||
}
|
||||
|
||||
ret = mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, key_buf, key_len);
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
(void) d;
|
||||
(void) d_len;
|
||||
|
||||
ret = mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng);
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
|
||||
/*
|
||||
* Load an RFC8410 EC key, which doesn't have any parameters
|
||||
*/
|
||||
static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params,
|
||||
mbedtls_ecp_group_id grp_id,
|
||||
mbedtls_ecp_group *grp)
|
||||
{
|
||||
if (params->tag != 0 || params->len != 0) {
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
return mbedtls_ecp_group_load(grp, grp_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse an RFC 8410 encoded private EC key
|
||||
*
|
||||
* CurvePrivateKey ::= OCTET STRING
|
||||
*/
|
||||
static int pk_parse_key_rfc8410_der(mbedtls_ecp_keypair *eck,
|
||||
unsigned char *key, size_t keylen, const unsigned char *end,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&key, (key + keylen), &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
if (key + len != end) {
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_mpi_read_binary_le(&eck->d, key, len)) != 0) {
|
||||
mbedtls_ecp_keypair_free(eck);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
// pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys,
|
||||
// which never contain a public key. As such, derive the public key
|
||||
// unconditionally.
|
||||
if ((ret = pk_derive_public_key(eck, key, len, f_rng, p_rng)) != 0) {
|
||||
mbedtls_ecp_keypair_free(eck);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
|
||||
mbedtls_ecp_keypair_free(eck);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/*
|
||||
* EC public key is an EC point
|
||||
*
|
||||
|
@ -511,7 +632,7 @@ static int pk_get_ecpubkey(unsigned char **p, const unsigned char *end,
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
/*
|
||||
|
@ -583,7 +704,8 @@ static int pk_get_rsapubkey(unsigned char **p,
|
|||
*/
|
||||
static int pk_get_pk_alg(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params)
|
||||
mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params,
|
||||
mbedtls_ecp_group_id *ec_grp_id)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_asn1_buf alg_oid;
|
||||
|
@ -594,7 +716,18 @@ static int pk_get_pk_alg(unsigned char **p,
|
|||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_ALG, ret);
|
||||
}
|
||||
|
||||
if (mbedtls_oid_get_pk_alg(&alg_oid, pk_alg) != 0) {
|
||||
ret = mbedtls_oid_get_pk_alg(&alg_oid, pk_alg);
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (ret == MBEDTLS_ERR_OID_NOT_FOUND) {
|
||||
ret = mbedtls_oid_get_ec_grp_algid(&alg_oid, ec_grp_id);
|
||||
if (ret == 0) {
|
||||
*pk_alg = MBEDTLS_PK_ECKEY;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) ec_grp_id;
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
|
||||
}
|
||||
|
||||
|
@ -622,6 +755,7 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
|
|||
size_t len;
|
||||
mbedtls_asn1_buf alg_params;
|
||||
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
|
||||
mbedtls_ecp_group_id ec_grp_id = MBEDTLS_ECP_DP_NONE;
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
|
@ -631,7 +765,7 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
|
|||
|
||||
end = *p + len;
|
||||
|
||||
if ((ret = pk_get_pk_alg(p, end, &pk_alg, &alg_params)) != 0) {
|
||||
if ((ret = pk_get_pk_alg(p, end, &pk_alg, &alg_params, &ec_grp_id)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -657,14 +791,21 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
|
|||
ret = pk_get_rsapubkey(p, end, mbedtls_pk_rsa(*pk));
|
||||
} else
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY) {
|
||||
ret = pk_use_ecparams(&alg_params, &mbedtls_pk_ec(*pk)->grp);
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) {
|
||||
ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, &mbedtls_pk_ec(*pk)->grp);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ret = pk_use_ecparams(&alg_params, &mbedtls_pk_ec(*pk)->grp);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = pk_get_ecpubkey(p, end, mbedtls_pk_ec(*pk));
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
|
||||
|
||||
if (ret == 0 && *p != end) {
|
||||
|
@ -868,7 +1009,7 @@ cleanup:
|
|||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/*
|
||||
* Parse a SEC1 encoded private EC key
|
||||
*/
|
||||
|
@ -878,9 +1019,10 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int version, pubkey_done;
|
||||
size_t len;
|
||||
size_t len, d_len;
|
||||
mbedtls_asn1_buf params = { 0, 0, NULL };
|
||||
unsigned char *p = (unsigned char *) key;
|
||||
unsigned char *d;
|
||||
unsigned char *end = p + keylen;
|
||||
unsigned char *end2;
|
||||
|
||||
|
@ -913,6 +1055,8 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
|
|||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
d = p;
|
||||
d_len = len;
|
||||
if ((ret = mbedtls_mpi_read_binary(&eck->d, p, len)) != 0) {
|
||||
mbedtls_ecp_keypair_free(eck);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
|
||||
|
@ -975,11 +1119,11 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
|
|||
}
|
||||
}
|
||||
|
||||
if (!pubkey_done &&
|
||||
(ret = mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G,
|
||||
f_rng, p_rng)) != 0) {
|
||||
mbedtls_ecp_keypair_free(eck);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
|
||||
if (!pubkey_done) {
|
||||
if ((ret = pk_derive_public_key(eck, d, d_len, f_rng, p_rng)) != 0) {
|
||||
mbedtls_ecp_keypair_free(eck);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
|
||||
|
@ -989,7 +1133,7 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/*
|
||||
* Parse an unencrypted PKCS#8 encoded private key
|
||||
|
@ -1015,9 +1159,10 @@ static int pk_parse_key_pkcs8_unencrypted_der(
|
|||
unsigned char *p = (unsigned char *) key;
|
||||
unsigned char *end = p + keylen;
|
||||
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
|
||||
mbedtls_ecp_group_id ec_grp_id = MBEDTLS_ECP_DP_NONE;
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
|
||||
#if !defined(MBEDTLS_ECP_C)
|
||||
#if !defined(MBEDTLS_ECP_LIGHT)
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
#endif
|
||||
|
@ -1053,7 +1198,7 @@ static int pk_parse_key_pkcs8_unencrypted_der(
|
|||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_VERSION, ret);
|
||||
}
|
||||
|
||||
if ((ret = pk_get_pk_alg(&p, end, &pk_alg, ¶ms)) != 0) {
|
||||
if ((ret = pk_get_pk_alg(&p, end, &pk_alg, ¶ms, &ec_grp_id)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1082,15 +1227,29 @@ static int pk_parse_key_pkcs8_unencrypted_der(
|
|||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) {
|
||||
if ((ret = pk_use_ecparams(¶ms, &mbedtls_pk_ec(*pk)->grp)) != 0 ||
|
||||
(ret = pk_parse_key_sec1_der(mbedtls_pk_ec(*pk), p, len, f_rng, p_rng)) != 0) {
|
||||
mbedtls_pk_free(pk);
|
||||
return ret;
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) {
|
||||
if ((ret =
|
||||
pk_use_ecparams_rfc8410(¶ms, ec_grp_id, &mbedtls_pk_ec(*pk)->grp)) != 0 ||
|
||||
(ret =
|
||||
pk_parse_key_rfc8410_der(mbedtls_pk_ec(*pk), p, len, end, f_rng,
|
||||
p_rng)) != 0) {
|
||||
mbedtls_pk_free(pk);
|
||||
return ret;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if ((ret = pk_use_ecparams(¶ms, &mbedtls_pk_ec(*pk)->grp)) != 0 ||
|
||||
(ret = pk_parse_key_sec1_der(mbedtls_pk_ec(*pk), p, len, f_rng, p_rng)) != 0) {
|
||||
mbedtls_pk_free(pk);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
|
||||
|
||||
return 0;
|
||||
|
@ -1257,7 +1416,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
|
|||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if (key[keylen - 1] != '\0') {
|
||||
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
|
@ -1286,7 +1445,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
|
|||
} else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if (key[keylen - 1] != '\0') {
|
||||
|
@ -1392,7 +1551,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
|
|||
mbedtls_pk_init(pk);
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
|
||||
if (mbedtls_pk_setup(pk, pk_info) == 0 &&
|
||||
pk_parse_key_sec1_der(mbedtls_pk_ec(*pk),
|
||||
|
@ -1400,7 +1559,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
|
|||
return 0;
|
||||
}
|
||||
mbedtls_pk_free(pk);
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
|
||||
* it is ok to leave the PK context initialized but not
|
||||
|
@ -1488,7 +1647,7 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
|
|||
*/
|
||||
p = pem.buf;
|
||||
|
||||
ret = mbedtls_pk_parse_subpubkey(&p, p + pem.buflen, ctx);
|
||||
ret = mbedtls_pk_parse_subpubkey(&p, p + pem.buflen, ctx);
|
||||
mbedtls_pem_free(&pem);
|
||||
return ret;
|
||||
} else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
|
||||
|
|
|
@ -98,7 +98,7 @@ end_of_export:
|
|||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/*
|
||||
* EC public key is an EC point
|
||||
*/
|
||||
|
@ -131,14 +131,14 @@ static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
|
|||
* }
|
||||
*/
|
||||
static int pk_write_ec_param(unsigned char **p, unsigned char *start,
|
||||
mbedtls_ecp_keypair *ec)
|
||||
mbedtls_ecp_group_id grp_id)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
const char *oid;
|
||||
size_t oid_len;
|
||||
|
||||
if ((ret = mbedtls_oid_get_oid_by_ec_grp(ec->grp.id, &oid, &oid_len)) != 0) {
|
||||
if ((ret = mbedtls_oid_get_oid_by_ec_grp(grp_id, &oid, &oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ exit:
|
|||
mbedtls_platform_zeroize(tmp, byte_length);
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
|
||||
const mbedtls_pk_context *key)
|
||||
|
@ -180,7 +180,7 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
|
|||
MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, mbedtls_pk_rsa(*key)));
|
||||
} else
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, mbedtls_pk_ec(*key)));
|
||||
} else
|
||||
|
@ -188,14 +188,13 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
|
|||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
|
||||
size_t buffer_size;
|
||||
mbedtls_svc_key_id_t *key_id = (mbedtls_svc_key_id_t *) key->pk_ctx;
|
||||
|
||||
if (*p < start) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
buffer_size = (size_t) (*p - start);
|
||||
if (psa_export_public_key(*key_id, start, buffer_size, &len)
|
||||
if (psa_export_public_key(key->priv_id, start, buffer_size, &len)
|
||||
!= PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
} else {
|
||||
|
@ -213,8 +212,12 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *c;
|
||||
size_t len = 0, par_len = 0, oid_len;
|
||||
int has_par = 1;
|
||||
size_t len = 0, par_len = 0, oid_len = 0;
|
||||
mbedtls_pk_type_t pk_type;
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
mbedtls_ecp_group_id ec_grp_id = MBEDTLS_ECP_DP_NONE;
|
||||
#endif
|
||||
const char *oid;
|
||||
|
||||
if (size == 0) {
|
||||
|
@ -241,63 +244,74 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_BIT_STRING));
|
||||
|
||||
pk_type = mbedtls_pk_get_type(key);
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (pk_type == MBEDTLS_PK_ECKEY) {
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, mbedtls_pk_ec(*key)));
|
||||
ec_grp_id = mbedtls_pk_ec(*key)->grp.id;
|
||||
}
|
||||
#endif
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if (pk_type == MBEDTLS_PK_OPAQUE) {
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t key_type;
|
||||
mbedtls_svc_key_id_t key_id;
|
||||
psa_ecc_family_t curve;
|
||||
size_t bits;
|
||||
|
||||
key_id = *((mbedtls_svc_key_id_t *) key->pk_ctx);
|
||||
if (PSA_SUCCESS != psa_get_key_attributes(key_id, &attributes)) {
|
||||
if (PSA_SUCCESS != psa_get_key_attributes(key->priv_id,
|
||||
&attributes)) {
|
||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
}
|
||||
key_type = psa_get_key_type(&attributes);
|
||||
bits = psa_get_key_bits(&attributes);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) {
|
||||
psa_ecc_family_t curve;
|
||||
|
||||
curve = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type);
|
||||
if (curve == 0) {
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
if (curve != 0) {
|
||||
ec_grp_id = mbedtls_ecc_group_of_psa(curve, psa_get_key_bits(&attributes), 0);
|
||||
if (ec_grp_id != MBEDTLS_ECP_DP_NONE) {
|
||||
/* The rest of the function works as for legacy EC contexts. */
|
||||
pk_type = MBEDTLS_PK_ECKEY;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mbedtls_psa_get_ecc_oid_from_id(curve, bits,
|
||||
&oid, &oid_len);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* Write EC algorithm parameters; that's akin
|
||||
* to pk_write_ec_param() above. */
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_oid(&c, buf,
|
||||
oid,
|
||||
oid_len));
|
||||
|
||||
/* The rest of the function works as for legacy EC contexts. */
|
||||
pk_type = MBEDTLS_PK_ECKEY;
|
||||
} else if (PSA_KEY_TYPE_IS_RSA(key_type)) {
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
if (PSA_KEY_TYPE_IS_RSA(key_type)) {
|
||||
/* The rest of the function works as for legacy RSA contexts. */
|
||||
pk_type = MBEDTLS_PK_RSA;
|
||||
} else {
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
}
|
||||
/* `pk_type` will have been changed to non-opaque by here if this function can handle it */
|
||||
if (pk_type == MBEDTLS_PK_OPAQUE) {
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if ((ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid,
|
||||
&oid_len)) != 0) {
|
||||
return ret;
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (pk_type == MBEDTLS_PK_ECKEY) {
|
||||
/* Some groups have their own AlgorithmIdentifier OID, others are handled by mbedtls_oid_get_oid_by_pk_alg() below */
|
||||
ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len);
|
||||
|
||||
if (ret == 0) {
|
||||
/* Currently, none of the supported algorithms that have their own AlgorithmIdentifier OID have any parameters */
|
||||
has_par = 0;
|
||||
} else if (ret == MBEDTLS_ERR_OID_NOT_FOUND) {
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec_grp_id));
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
if (oid_len == 0) {
|
||||
if ((ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid,
|
||||
&oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier(&c, buf, oid, oid_len,
|
||||
par_len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier_ext(&c, buf, oid, oid_len,
|
||||
par_len, has_par));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
|
@ -306,6 +320,55 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
|
|||
return (int) len;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
/*
|
||||
* RFC8410
|
||||
*
|
||||
* OneAsymmetricKey ::= SEQUENCE {
|
||||
* version Version,
|
||||
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
|
||||
* privateKey PrivateKey,
|
||||
* attributes [0] IMPLICIT Attributes OPTIONAL,
|
||||
* ...,
|
||||
* [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]],
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* CurvePrivateKey ::= OCTET STRING
|
||||
*/
|
||||
static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf,
|
||||
mbedtls_ecp_keypair *ec)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
size_t oid_len = 0;
|
||||
const char *oid;
|
||||
|
||||
/* privateKey */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, ec));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING));
|
||||
|
||||
/* privateKeyAlgorithm */
|
||||
if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec->grp.id, &oid, &oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_algorithm_identifier_ext(p, buf, oid, oid_len, 0, 0));
|
||||
|
||||
/* version */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
@ -404,11 +467,17 @@ end_of_export:
|
|||
MBEDTLS_ASN1_SEQUENCE));
|
||||
} else
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
|
||||
mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*key);
|
||||
size_t pub_len = 0, par_len = 0;
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
if (mbedtls_pk_is_rfc8410_curve(ec->grp.id)) {
|
||||
return pk_write_ec_rfc8410_der(&c, buf, ec);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RFC 5915, or SEC1 Appendix C.4
|
||||
*
|
||||
|
@ -439,7 +508,7 @@ end_of_export:
|
|||
len += pub_len;
|
||||
|
||||
/* parameters */
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec));
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec->grp.id));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(&c, buf, par_len));
|
||||
MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(&c, buf,
|
||||
|
@ -472,6 +541,8 @@ end_of_export:
|
|||
#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
|
||||
#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
|
||||
#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
|
||||
#define PEM_BEGIN_PRIVATE_KEY_PKCS8 "-----BEGIN PRIVATE KEY-----\n"
|
||||
#define PEM_END_PRIVATE_KEY_PKCS8 "-----END PRIVATE KEY-----\n"
|
||||
|
||||
#define PUB_DER_MAX_BYTES \
|
||||
(MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES > MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ? \
|
||||
|
@ -517,10 +588,18 @@ int mbedtls_pk_write_key_pem(const mbedtls_pk_context *key, unsigned char *buf,
|
|||
end = PEM_END_PRIVATE_KEY_RSA;
|
||||
} else
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_EC;
|
||||
end = PEM_END_PRIVATE_KEY_EC;
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
if (mbedtls_pk_is_rfc8410_curve(mbedtls_pk_ec(*key)->grp.id)) {
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_PKCS8;
|
||||
end = PEM_END_PRIVATE_KEY_PKCS8;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
begin = PEM_BEGIN_PRIVATE_KEY_EC;
|
||||
end = PEM_END_PRIVATE_KEY_EC;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
|
|
|
@ -105,4 +105,27 @@
|
|||
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#include "mbedtls/ecp.h"
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
#define MBEDTLS_PK_HAVE_RFC8410_CURVES
|
||||
|
||||
static inline int mbedtls_pk_is_rfc8410_curve(mbedtls_ecp_group_id id)
|
||||
{
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||
if (id == MBEDTLS_ECP_DP_CURVE25519) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
if (id == MBEDTLS_ECP_DP_CURVE448) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED || MBEDTLS_ECP_DP_CURVE448_ENABLED */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#endif /* MBEDTLS_PK_WRITE_H */
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "psa_crypto_invasive.h"
|
||||
#include "psa_crypto_driver_wrappers.h"
|
||||
#include "psa_crypto_ecp.h"
|
||||
#include "psa_crypto_ffdh.h"
|
||||
#include "psa_crypto_hash.h"
|
||||
#include "psa_crypto_mac.h"
|
||||
#include "psa_crypto_rsa.h"
|
||||
|
@ -91,10 +92,6 @@
|
|||
#define BUILTIN_ALG_ANY_HKDF 1
|
||||
#endif
|
||||
|
||||
/* The only two JPAKE user/peer identifiers supported for the time being. */
|
||||
static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
|
||||
static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
|
||||
|
||||
/****************************************************************/
|
||||
/* Global data, support functions and library management */
|
||||
/****************************************************************/
|
||||
|
@ -132,6 +129,21 @@ int psa_can_do_hash(psa_algorithm_t hash_alg)
|
|||
(void) hash_alg;
|
||||
return global_data.drivers_initialized;
|
||||
}
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
|
||||
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR)
|
||||
static int psa_is_dh_key_size_valid(size_t bits)
|
||||
{
|
||||
if (bits != 2048 && bits != 3072 && bits != 4096 &&
|
||||
bits != 6144 && bits != 8192) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR ||
|
||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
|
||||
PSA_WANT_KEY_TYPE_DH_KEY_PAIR */
|
||||
|
||||
psa_status_t mbedtls_to_psa_error(int ret)
|
||||
{
|
||||
|
@ -378,7 +390,7 @@ static void psa_wipe_tag_output_buffer(uint8_t *output_buffer, psa_status_t stat
|
|||
/* Key management */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
|
||||
size_t bits,
|
||||
int bits_is_sloppy)
|
||||
|
@ -470,7 +482,7 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
|
|||
(void) bits_is_sloppy;
|
||||
return MBEDTLS_ECP_DP_NONE;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_ECP_C) */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type,
|
||||
size_t bits)
|
||||
|
@ -628,6 +640,23 @@ psa_status_t psa_import_key_into_slot(
|
|||
|
||||
return PSA_SUCCESS;
|
||||
} else if (PSA_KEY_TYPE_IS_ASYMMETRIC(type)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
if (PSA_KEY_TYPE_IS_DH(type)) {
|
||||
if (psa_is_dh_key_size_valid(PSA_BYTES_TO_BITS(data_length)) == 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/* Copy the key material. */
|
||||
memcpy(key_buffer, data, data_length);
|
||||
*key_buffer_length = data_length;
|
||||
*bits = PSA_BYTES_TO_BITS(data_length);
|
||||
(void) key_buffer_size;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
if (PSA_KEY_TYPE_IS_ECC(type)) {
|
||||
|
@ -1330,7 +1359,8 @@ psa_status_t psa_export_key_internal(
|
|||
|
||||
if (key_type_is_raw_bytes(type) ||
|
||||
PSA_KEY_TYPE_IS_RSA(type) ||
|
||||
PSA_KEY_TYPE_IS_ECC(type)) {
|
||||
PSA_KEY_TYPE_IS_ECC(type) ||
|
||||
PSA_KEY_TYPE_IS_DH(type)) {
|
||||
return psa_export_key_buffer_internal(
|
||||
key_buffer, key_buffer_size,
|
||||
data, data_size, data_length);
|
||||
|
@ -1396,47 +1426,54 @@ psa_status_t psa_export_public_key_internal(
|
|||
{
|
||||
psa_key_type_t type = attributes->core.type;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type)) {
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
|
||||
/* Exporting public -> public */
|
||||
return psa_export_key_buffer_internal(
|
||||
key_buffer, key_buffer_size,
|
||||
data, data_size, data_length);
|
||||
}
|
||||
|
||||
if (PSA_KEY_TYPE_IS_RSA(type)) {
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
|
||||
(PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type) ||
|
||||
PSA_KEY_TYPE_IS_DH(type))) {
|
||||
/* Exporting public -> public */
|
||||
return psa_export_key_buffer_internal(
|
||||
key_buffer, key_buffer_size,
|
||||
data, data_size, data_length);
|
||||
} else if (PSA_KEY_TYPE_IS_RSA(type)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
return mbedtls_psa_rsa_export_public_key(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length);
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
return mbedtls_psa_rsa_export_public_key(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length);
|
||||
#else
|
||||
/* We don't know how to convert a private RSA key to public. */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
/* We don't know how to convert a private RSA key to public. */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
|
||||
} else {
|
||||
} else if (PSA_KEY_TYPE_IS_ECC(type)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
return mbedtls_psa_ecp_export_public_key(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length);
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
return mbedtls_psa_ecp_export_public_key(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length);
|
||||
#else
|
||||
/* We don't know how to convert a private ECC key to public */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
/* We don't know how to convert a private ECC key to public */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
|
||||
}
|
||||
} else if (PSA_KEY_TYPE_IS_DH(type)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
return mbedtls_psa_export_ffdh_public_key(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data, data_size,
|
||||
data_length);
|
||||
#else
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
|
||||
} else {
|
||||
/* This shouldn't happen in the reference implementation, but
|
||||
it is valid for a special-purpose implementation to omit
|
||||
support for exporting certain key types. */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
@ -5552,7 +5589,7 @@ static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper(
|
|||
uint8_t **data
|
||||
)
|
||||
{
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
unsigned key_out_of_range = 1;
|
||||
mbedtls_mpi k;
|
||||
mbedtls_mpi diff_N_2;
|
||||
|
@ -5636,13 +5673,13 @@ cleanup:
|
|||
mbedtls_mpi_free(&k);
|
||||
mbedtls_mpi_free(&diff_N_2);
|
||||
return status;
|
||||
#else /* MBEDTLS_ECP_C */
|
||||
#else /* MBEDTLS_ECP_LIGHT */
|
||||
(void) slot;
|
||||
(void) bits;
|
||||
(void) operation;
|
||||
(void) data;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
}
|
||||
|
||||
/* ECC keys on a Montgomery elliptic curve draws a byte string whose length
|
||||
|
@ -5961,6 +5998,11 @@ static psa_status_t psa_key_agreement_try_support(psa_algorithm_t alg)
|
|||
if (alg == PSA_ALG_ECDH) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_FFDH)
|
||||
if (alg == PSA_ALG_FFDH) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
(void) alg;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
|
@ -6481,6 +6523,27 @@ exit:
|
|||
return status;
|
||||
}
|
||||
|
||||
static psa_status_t psa_key_derivation_input_integer_internal(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
uint64_t value)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
|
||||
|
||||
{
|
||||
(void) step;
|
||||
(void) value;
|
||||
(void) kdf_alg;
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_key_derivation_abort(operation);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_key_derivation_input_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
|
@ -6492,6 +6555,14 @@ psa_status_t psa_key_derivation_input_bytes(
|
|||
data, data_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_key_derivation_input_integer(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
uint64_t value)
|
||||
{
|
||||
return psa_key_derivation_input_integer_internal(operation, step, value);
|
||||
}
|
||||
|
||||
psa_status_t psa_key_derivation_input_key(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
|
@ -6550,6 +6621,19 @@ psa_status_t psa_key_agreement_raw_builtin(const psa_key_attributes_t *attribute
|
|||
shared_secret_size,
|
||||
shared_secret_length);
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
|
||||
case PSA_ALG_FFDH:
|
||||
return mbedtls_psa_key_agreement_ffdh(attributes,
|
||||
peer_key,
|
||||
peer_key_length,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
shared_secret,
|
||||
shared_secret_size,
|
||||
shared_secret_length);
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
||||
|
||||
default:
|
||||
(void) attributes;
|
||||
(void) key_buffer;
|
||||
|
@ -6931,6 +7015,14 @@ static psa_status_t psa_validate_key_type_and_size_for_key_generation(
|
|||
return PSA_SUCCESS;
|
||||
} else
|
||||
#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR)
|
||||
if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
|
||||
if (psa_is_dh_key_size_valid(bits) == 0) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
} else
|
||||
#endif /* defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR) */
|
||||
{
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -6982,6 +7074,15 @@ psa_status_t psa_generate_key_internal(
|
|||
key_buffer_length);
|
||||
} else
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR)
|
||||
if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
|
||||
return mbedtls_psa_ffdh_generate_key(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
key_buffer_length);
|
||||
} else
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) */
|
||||
{
|
||||
(void) key_buffer_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
|
@ -7208,19 +7309,6 @@ psa_status_t psa_crypto_driver_pake_get_password(
|
|||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_driver_pake_get_role(
|
||||
const psa_crypto_driver_pake_inputs_t *inputs,
|
||||
psa_pake_role_t *role)
|
||||
{
|
||||
if (inputs->role == PSA_PAKE_ROLE_NONE) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
*role = inputs->role;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_driver_pake_get_user_len(
|
||||
const psa_crypto_driver_pake_inputs_t *inputs,
|
||||
size_t *user_len)
|
||||
|
@ -7316,6 +7404,8 @@ psa_status_t psa_pake_setup(
|
|||
memset(&operation->data.inputs, 0, sizeof(operation->data.inputs));
|
||||
|
||||
operation->alg = cipher_suite->algorithm;
|
||||
operation->primitive = PSA_PAKE_PRIMITIVE(cipher_suite->type,
|
||||
cipher_suite->family, cipher_suite->bits);
|
||||
operation->data.inputs.cipher_suite = *cipher_suite;
|
||||
|
||||
#if defined(PSA_WANT_ALG_JPAKE)
|
||||
|
@ -7413,15 +7503,6 @@ psa_status_t psa_pake_set_user(
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* Allow only "client" or "server" values (temporary restriction). */
|
||||
if ((user_id_len != sizeof(jpake_server_id) ||
|
||||
memcmp(user_id, jpake_server_id, user_id_len) != 0) &&
|
||||
(user_id_len != sizeof(jpake_client_id) ||
|
||||
memcmp(user_id, jpake_client_id, user_id_len) != 0)) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
operation->data.inputs.user = mbedtls_calloc(1, user_id_len);
|
||||
if (operation->data.inputs.user == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
|
@ -7459,15 +7540,6 @@ psa_status_t psa_pake_set_peer(
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* Allow only "client" or "server" values (temporary restriction). */
|
||||
if ((peer_id_len != sizeof(jpake_server_id) ||
|
||||
memcmp(peer_id, jpake_server_id, peer_id_len) != 0) &&
|
||||
(peer_id_len != sizeof(jpake_client_id) ||
|
||||
memcmp(peer_id, jpake_client_id, peer_id_len) != 0)) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
operation->data.inputs.peer = mbedtls_calloc(1, peer_id_len);
|
||||
if (operation->data.inputs.peer == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
|
@ -7585,19 +7657,6 @@ static psa_status_t psa_pake_complete_inputs(
|
|||
if (inputs.user_len == 0 || inputs.peer_len == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
if (memcmp(inputs.user, jpake_client_id, inputs.user_len) == 0 &&
|
||||
memcmp(inputs.peer, jpake_server_id, inputs.peer_len) == 0) {
|
||||
inputs.role = PSA_PAKE_ROLE_CLIENT;
|
||||
} else
|
||||
if (memcmp(inputs.user, jpake_server_id, inputs.user_len) == 0 &&
|
||||
memcmp(inputs.peer, jpake_client_id, inputs.peer_len) == 0) {
|
||||
inputs.role = PSA_PAKE_ROLE_SERVER;
|
||||
}
|
||||
|
||||
if (inputs.role != PSA_PAKE_ROLE_CLIENT &&
|
||||
inputs.role != PSA_PAKE_ROLE_SERVER) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear driver context */
|
||||
|
@ -7900,6 +7959,9 @@ psa_status_t psa_pake_input(
|
|||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID;
|
||||
const size_t max_input_length = (size_t) PSA_PAKE_INPUT_SIZE(operation->alg,
|
||||
operation->primitive,
|
||||
step);
|
||||
|
||||
if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
|
||||
status = psa_pake_complete_inputs(operation);
|
||||
|
@ -7913,7 +7975,7 @@ psa_status_t psa_pake_input(
|
|||
goto exit;
|
||||
}
|
||||
|
||||
if (input_length == 0 || input_length > PSA_PAKE_INPUT_MAX_SIZE) {
|
||||
if (input_length == 0 || input_length > max_input_length) {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_driver_common.h"
|
||||
|
||||
#if defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)
|
||||
#include "../3rdparty/p256-m/p256-m_driver_entrypoints.h"
|
||||
#endif /* MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED */
|
||||
|
||||
/*
|
||||
* Initialization and termination functions
|
||||
*/
|
||||
|
|
262
library/psa_crypto_ffdh.c
Normal file
262
library/psa_crypto_ffdh.c
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* PSA FFDH layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_ffdh.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size,
|
||||
mbedtls_mpi *P,
|
||||
mbedtls_mpi *G)
|
||||
{
|
||||
const unsigned char *dhm_P = NULL;
|
||||
const unsigned char *dhm_G = NULL;
|
||||
size_t dhm_size_P = 0;
|
||||
size_t dhm_size_G = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (P == NULL && G == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
static const unsigned char dhm_P_2048[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN;
|
||||
static const unsigned char dhm_P_3072[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
|
||||
static const unsigned char dhm_P_4096[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
|
||||
static const unsigned char dhm_P_6144[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN;
|
||||
static const unsigned char dhm_P_8192[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN;
|
||||
static const unsigned char dhm_G_2048[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN;
|
||||
static const unsigned char dhm_G_3072[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN;
|
||||
static const unsigned char dhm_G_4096[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN;
|
||||
static const unsigned char dhm_G_6144[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN;
|
||||
static const unsigned char dhm_G_8192[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN;
|
||||
|
||||
switch (key_size) {
|
||||
case sizeof(dhm_P_2048):
|
||||
dhm_P = dhm_P_2048;
|
||||
dhm_G = dhm_G_2048;
|
||||
dhm_size_P = sizeof(dhm_P_2048);
|
||||
dhm_size_G = sizeof(dhm_G_2048);
|
||||
break;
|
||||
case sizeof(dhm_P_3072):
|
||||
dhm_P = dhm_P_3072;
|
||||
dhm_G = dhm_G_3072;
|
||||
dhm_size_P = sizeof(dhm_P_3072);
|
||||
dhm_size_G = sizeof(dhm_G_3072);
|
||||
break;
|
||||
case sizeof(dhm_P_4096):
|
||||
dhm_P = dhm_P_4096;
|
||||
dhm_G = dhm_G_4096;
|
||||
dhm_size_P = sizeof(dhm_P_4096);
|
||||
dhm_size_G = sizeof(dhm_G_4096);
|
||||
break;
|
||||
case sizeof(dhm_P_6144):
|
||||
dhm_P = dhm_P_6144;
|
||||
dhm_G = dhm_G_6144;
|
||||
dhm_size_P = sizeof(dhm_P_6144);
|
||||
dhm_size_G = sizeof(dhm_G_6144);
|
||||
break;
|
||||
case sizeof(dhm_P_8192):
|
||||
dhm_P = dhm_P_8192;
|
||||
dhm_G = dhm_G_8192;
|
||||
dhm_size_P = sizeof(dhm_P_8192);
|
||||
dhm_size_G = sizeof(dhm_G_8192);
|
||||
break;
|
||||
default:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (P != NULL) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(P, dhm_P,
|
||||
dhm_size_P));
|
||||
}
|
||||
if (G != NULL) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(G, dhm_G,
|
||||
dhm_size_G));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
|
||||
psa_status_t mbedtls_psa_key_agreement_ffdh(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi P, G, X, GY, K;
|
||||
const size_t calculated_shared_secret_size = peer_key_length;
|
||||
|
||||
if (peer_key_length != key_buffer_size ||
|
||||
calculated_shared_secret_size > shared_secret_size) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!PSA_KEY_TYPE_IS_DH_KEY_PAIR(psa_get_key_type(attributes))) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
|
||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&GY);
|
||||
mbedtls_mpi_init(&K);
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(
|
||||
PSA_BITS_TO_BYTES(attributes->core.bits), &P, &G);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
||||
key_buffer_size));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&GY, peer_key,
|
||||
peer_key_length));
|
||||
|
||||
/* Calculate shared secret public key: K = G^(XY) mod P = GY^X mod P */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &GY, &X, &P, NULL));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K, shared_secret,
|
||||
calculated_shared_secret_size));
|
||||
|
||||
*shared_secret_length = calculated_shared_secret_size;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
||||
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GY);
|
||||
mbedtls_mpi_free(&K);
|
||||
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
||||
|
||||
psa_status_t mbedtls_psa_export_ffdh_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi GX, G, X, P;
|
||||
(void) attributes;
|
||||
|
||||
mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
|
||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(data_size, &P, &G);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
||||
key_buffer_size));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&GX, &G, &X, &P, NULL));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&GX, data, data_size));
|
||||
|
||||
*data_length = data_size;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
||||
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GX);
|
||||
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ffdh_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||
{
|
||||
mbedtls_mpi X, P;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi_init(&P); mbedtls_mpi_init(&X);
|
||||
(void) attributes;
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(key_buffer_size, &P, NULL);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* RFC7919: Traditional finite field Diffie-Hellman has each peer choose their
|
||||
secret exponent from the range [2, P-2].
|
||||
Select random value in range [3, P-1] and decrease it by 1. */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_random(&X, 3, &P, mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &X, 1));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&X, key_buffer, key_buffer_size));
|
||||
*key_buffer_length = key_buffer_size;
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&X);
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR ||
|
||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
115
library/psa_crypto_ffdh.h
Normal file
115
library/psa_crypto_ffdh.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* PSA FFDH layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_FFDH_H
|
||||
#define PSA_CRYPTO_FFDH_H
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include <mbedtls/dhm.h>
|
||||
|
||||
/** Perform a key agreement and return the FFDH shared secret.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] peer_key The buffer containing the key context
|
||||
* of the peer's public key.
|
||||
* \param[in] peer_key_length Size of the \p peer_key buffer in
|
||||
* bytes.
|
||||
* \param[in] key_buffer The buffer containing the private key
|
||||
* context.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret The buffer to which the shared secret
|
||||
* is to be written.
|
||||
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret_length On success, the number of bytes that make
|
||||
* up the returned shared secret.
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Shared secret successfully calculated.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p key_buffer_size, \p peer_key_length, \p shared_secret_size
|
||||
* do not match
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
psa_status_t mbedtls_psa_key_agreement_ffdh(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length);
|
||||
|
||||
/** Export a public key or the public part of a DH key pair in binary format.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to export.
|
||||
* \param[in] key_buffer Material or context of the key to export.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[out] data Buffer where the key data is to be written.
|
||||
* \param[in] data_size Size of the \p data buffer in bytes.
|
||||
* \param[out] data_length On success, the number of bytes written in
|
||||
* \p data
|
||||
*
|
||||
* \retval #PSA_SUCCESS The public key was exported successfully.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
psa_status_t mbedtls_psa_export_ffdh_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/**
|
||||
* \brief Generate DH key.
|
||||
*
|
||||
* \note The signature of the function is that of a PSA driver generate_key
|
||||
* entry point.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to generate.
|
||||
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||
* \param[in] key_buffer_size Size of \p key_buffer in bytes.
|
||||
* \param[out] key_buffer_length On success, the number of bytes written in
|
||||
* \p key_buffer.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was generated successfully.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* Key size in bits is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
psa_status_t mbedtls_psa_ffdh_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length);
|
||||
|
||||
#endif /* PSA_CRYPTO_FFDH_H */
|
|
@ -168,13 +168,11 @@ static psa_status_t mbedtls_ecjpake_to_psa_error(int ret)
|
|||
static psa_status_t psa_pake_ecjpake_setup(mbedtls_psa_pake_operation_t *operation)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecjpake_role role = (operation->role == PSA_PAKE_ROLE_CLIENT) ?
|
||||
MBEDTLS_ECJPAKE_CLIENT : MBEDTLS_ECJPAKE_SERVER;
|
||||
|
||||
mbedtls_ecjpake_init(&operation->ctx.jpake);
|
||||
|
||||
ret = mbedtls_ecjpake_setup(&operation->ctx.jpake,
|
||||
role,
|
||||
operation->role,
|
||||
MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_ECP_DP_SECP256R1,
|
||||
operation->password,
|
||||
|
@ -190,21 +188,30 @@ static psa_status_t psa_pake_ecjpake_setup(mbedtls_psa_pake_operation_t *operati
|
|||
}
|
||||
#endif
|
||||
|
||||
/* The only two JPAKE user/peer identifiers supported in built-in implementation. */
|
||||
static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
|
||||
static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
|
||||
|
||||
psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
||||
const psa_crypto_driver_pake_inputs_t *inputs)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t password_len = 0;
|
||||
psa_pake_role_t role = PSA_PAKE_ROLE_NONE;
|
||||
size_t user_len = 0, peer_len = 0, password_len = 0;
|
||||
uint8_t *peer = NULL, *user = NULL;
|
||||
size_t actual_user_len = 0, actual_peer_len = 0, actual_password_len = 0;
|
||||
psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
|
||||
size_t actual_password_len = 0;
|
||||
|
||||
status = psa_crypto_driver_pake_get_password_len(inputs, &password_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_role(inputs, &role);
|
||||
psa_crypto_driver_pake_get_user_len(inputs, &user_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_crypto_driver_pake_get_peer_len(inputs, &peer_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
@ -216,7 +223,20 @@ psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
|||
|
||||
operation->password = mbedtls_calloc(1, password_len);
|
||||
if (operation->password == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
user = mbedtls_calloc(1, user_len);
|
||||
if (user == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
peer = mbedtls_calloc(1, peer_len);
|
||||
if (peer == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_password(inputs, operation->password,
|
||||
|
@ -225,6 +245,18 @@ psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
|||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_user(inputs, user,
|
||||
user_len, &actual_user_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_peer(inputs, peer,
|
||||
peer_len, &actual_peer_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
operation->password_len = actual_password_len;
|
||||
operation->alg = cipher_suite.algorithm;
|
||||
|
||||
|
@ -238,7 +270,24 @@ psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
|||
goto error;
|
||||
}
|
||||
|
||||
operation->role = role;
|
||||
const size_t user_peer_len = sizeof(jpake_client_id); // client and server have the same length
|
||||
if (actual_user_len != user_peer_len ||
|
||||
actual_peer_len != user_peer_len) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (memcmp(user, jpake_client_id, actual_user_len) == 0 &&
|
||||
memcmp(peer, jpake_server_id, actual_peer_len) == 0) {
|
||||
operation->role = MBEDTLS_ECJPAKE_CLIENT;
|
||||
} else
|
||||
if (memcmp(user, jpake_server_id, actual_user_len) == 0 &&
|
||||
memcmp(peer, jpake_client_id, actual_peer_len) == 0) {
|
||||
operation->role = MBEDTLS_ECJPAKE_SERVER;
|
||||
} else {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
|
@ -248,6 +297,9 @@ psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* Role has been set, release user/peer buffers. */
|
||||
mbedtls_free(user); mbedtls_free(peer);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
|
@ -257,6 +309,7 @@ psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
|||
{ status = PSA_ERROR_NOT_SUPPORTED; }
|
||||
|
||||
error:
|
||||
mbedtls_free(user); mbedtls_free(peer);
|
||||
/* In case of failure of the setup of a multipart operation, the PSA driver interface
|
||||
* specifies that the core does not call any other driver entry point thus does not
|
||||
* call mbedtls_psa_pake_abort(). Therefore call it here to do the needed clean
|
||||
|
@ -332,7 +385,7 @@ static psa_status_t mbedtls_psa_pake_output_internal(
|
|||
* information is already available.
|
||||
*/
|
||||
if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE &&
|
||||
operation->role == PSA_PAKE_ROLE_SERVER) {
|
||||
operation->role == MBEDTLS_ECJPAKE_SERVER) {
|
||||
/* Skip ECParameters, with is 3 bytes (RFC 8422) */
|
||||
operation->buffer_offset += 3;
|
||||
}
|
||||
|
@ -423,7 +476,7 @@ static psa_status_t mbedtls_psa_pake_input_internal(
|
|||
* we're a client.
|
||||
*/
|
||||
if (step == PSA_JPAKE_X4S_STEP_KEY_SHARE &&
|
||||
operation->role == PSA_PAKE_ROLE_CLIENT) {
|
||||
operation->role == MBEDTLS_ECJPAKE_CLIENT) {
|
||||
/* We only support secp256r1. */
|
||||
/* This is the ECParameters structure defined by RFC 8422. */
|
||||
unsigned char ecparameters[3] = {
|
||||
|
@ -541,7 +594,7 @@ psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation)
|
|||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
operation->role = PSA_PAKE_ROLE_NONE;
|
||||
operation->role = MBEDTLS_ECJPAKE_NONE;
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "mbedtls/ssl_cache.h"
|
||||
#include "ssl_misc.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -50,7 +51,7 @@ static int ssl_cache_find_entry(mbedtls_ssl_cache_context *cache,
|
|||
size_t session_id_len,
|
||||
mbedtls_ssl_cache_entry **dst)
|
||||
{
|
||||
int ret = 1;
|
||||
int ret = MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND;
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t t = mbedtls_time(NULL);
|
||||
#endif
|
||||
|
@ -87,7 +88,7 @@ int mbedtls_ssl_cache_get(void *data,
|
|||
size_t session_id_len,
|
||||
mbedtls_ssl_session *session)
|
||||
{
|
||||
int ret = 1;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
|
||||
mbedtls_ssl_cache_entry *entry;
|
||||
|
||||
|
@ -197,7 +198,7 @@ static int ssl_cache_pick_writing_slot(mbedtls_ssl_cache_context *cache,
|
|||
/* Create new entry */
|
||||
cur = mbedtls_calloc(1, sizeof(mbedtls_ssl_cache_entry));
|
||||
if (cur == NULL) {
|
||||
return 1;
|
||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
/* Append to the end of the linked list. */
|
||||
|
@ -218,12 +219,13 @@ static int ssl_cache_pick_writing_slot(mbedtls_ssl_cache_context *cache,
|
|||
if (old == NULL) {
|
||||
/* This should only happen on an ill-configured cache
|
||||
* with max_entries == 0. */
|
||||
return 1;
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
#else /* MBEDTLS_HAVE_TIME */
|
||||
/* Reuse first entry in chain, but move to last place. */
|
||||
if (cache->chain == NULL) {
|
||||
return 1;
|
||||
/* This should never happen */
|
||||
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
old = cache->chain;
|
||||
|
@ -259,7 +261,7 @@ int mbedtls_ssl_cache_set(void *data,
|
|||
size_t session_id_len,
|
||||
const mbedtls_ssl_session *session)
|
||||
{
|
||||
int ret = 1;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
|
||||
mbedtls_ssl_cache_entry *cur;
|
||||
|
||||
|
@ -283,7 +285,6 @@ int mbedtls_ssl_cache_set(void *data,
|
|||
* and allocate a sufficiently large buffer. */
|
||||
ret = mbedtls_ssl_session_save(session, NULL, 0, &session_serialized_len);
|
||||
if (ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) {
|
||||
ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -303,7 +304,7 @@ int mbedtls_ssl_cache_set(void *data,
|
|||
}
|
||||
|
||||
if (session_id_len > sizeof(cur->session_id)) {
|
||||
ret = 1;
|
||||
ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
goto exit;
|
||||
}
|
||||
cur->session_id_len = session_id_len;
|
||||
|
@ -335,7 +336,7 @@ int mbedtls_ssl_cache_remove(void *data,
|
|||
unsigned char const *session_id,
|
||||
size_t session_id_len)
|
||||
{
|
||||
int ret = 1;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
|
||||
mbedtls_ssl_cache_entry *entry;
|
||||
mbedtls_ssl_cache_entry *prev;
|
||||
|
|
|
@ -257,7 +257,7 @@ static int ssl_write_supported_groups_ext(mbedtls_ssl_context *ssl,
|
|||
for (; *group_list != 0; group_list++) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("got supported group(%04x)", *group_list));
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if ((mbedtls_ssl_conf_is_tls13_enabled(ssl->conf) &&
|
||||
mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) ||
|
||||
(mbedtls_ssl_conf_is_tls12_enabled(ssl->conf) &&
|
||||
|
@ -273,7 +273,7 @@ static int ssl_write_supported_groups_ext(mbedtls_ssl_context *ssl,
|
|||
mbedtls_ssl_get_curve_name_from_tls_id(*group_list),
|
||||
*group_list));
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
/* Add DHE groups here */
|
||||
|
||||
}
|
||||
|
@ -769,7 +769,6 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl)
|
|||
ssl->tls_version = session_negotiate->tls_version;
|
||||
ssl->handshake->min_tls_version = ssl->tls_version;
|
||||
} else {
|
||||
ssl->tls_version = ssl->conf->max_tls_version;
|
||||
ssl->handshake->min_tls_version = ssl->conf->min_tls_version;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1553,10 +1553,10 @@ int mbedtls_ssl_set_calc_verify_md(mbedtls_ssl_context *ssl, int md);
|
|||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_check_curve_tls_id(const mbedtls_ssl_context *ssl, uint16_t tls_id);
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_check_curve(const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id);
|
||||
#endif
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/**
|
||||
* \brief Return PSA EC info for the specified TLS ID.
|
||||
|
@ -2048,6 +2048,33 @@ int mbedtls_ssl_tls13_fetch_handshake_msg(mbedtls_ssl_context *ssl,
|
|||
unsigned char **buf,
|
||||
size_t *buf_len);
|
||||
|
||||
/**
|
||||
* \brief Detect if a list of extensions contains a supported_versions
|
||||
* extension or not.
|
||||
*
|
||||
* \param[in] ssl SSL context
|
||||
* \param[in] buf Address of the first byte of the extensions vector.
|
||||
* \param[in] end End of the buffer containing the list of extensions.
|
||||
* \param[out] supported_versions_data If the extension is present, address of
|
||||
* its first byte of data, NULL otherwise.
|
||||
* \param[out] supported_versions_data_end If the extension is present, address
|
||||
* of the first byte immediately
|
||||
* following the extension data, NULL
|
||||
* otherwise.
|
||||
* \return 0 if the list of extensions does not contain a supported_versions
|
||||
* extension.
|
||||
* \return 1 if the list of extensions contains a supported_versions
|
||||
* extension.
|
||||
* \return A negative value if an error occurred while parsing the
|
||||
* extensions.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf, const unsigned char *end,
|
||||
const unsigned char **supported_versions_data,
|
||||
const unsigned char **supported_versions_data_end);
|
||||
|
||||
/*
|
||||
* Handler of TLS 1.3 server certificate message
|
||||
*/
|
||||
|
|
|
@ -1148,7 +1148,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
|
|||
* mbedtls_ssl_conf_curves returns void and so can't return
|
||||
* any error codes.
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/* Heap allocate and translate curve_list from internal to IANA group ids */
|
||||
if (ssl->conf->curve_list != NULL) {
|
||||
|
@ -1184,7 +1184,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
|
|||
ssl->handshake->group_list_heap_allocated = 0;
|
||||
}
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
|
@ -1325,12 +1325,6 @@ static int ssl_conf_version_check(const mbedtls_ssl_context *ssl)
|
|||
return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if (conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("TLS 1.3 server is not supported yet."));
|
||||
return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(4, ("The SSL configuration is TLS 1.3 or TLS 1.2."));
|
||||
return 0;
|
||||
}
|
||||
|
@ -1393,6 +1387,7 @@ int mbedtls_ssl_setup(mbedtls_ssl_context *ssl,
|
|||
if ((ret = ssl_conf_check(ssl)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
ssl->tls_version = ssl->conf->max_tls_version;
|
||||
|
||||
/*
|
||||
* Prepare base structures
|
||||
|
@ -2928,7 +2923,7 @@ void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf,
|
|||
}
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/*
|
||||
* Set the allowed elliptic curves
|
||||
|
@ -2945,7 +2940,7 @@ void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
|
|||
conf->group_list = NULL;
|
||||
}
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
/*
|
||||
* Set the allowed groups
|
||||
|
@ -3882,22 +3877,23 @@ int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if (mbedtls_ssl_conf_is_tls13_only(ssl->conf)) {
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
|
||||
ret = mbedtls_ssl_tls13_handshake_server_step(ssl);
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if (mbedtls_ssl_conf_is_tls12_only(ssl->conf)) {
|
||||
} else {
|
||||
ret = mbedtls_ssl_handshake_server_step(ssl);
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
}
|
||||
#elif defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
ret = mbedtls_ssl_handshake_server_step(ssl);
|
||||
#else
|
||||
ret = mbedtls_ssl_tls13_handshake_server_step(ssl);
|
||||
#endif
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
|
||||
if (ret != 0) {
|
||||
/* handshake_step return error. And it is same
|
||||
|
@ -4087,14 +4083,14 @@ void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl)
|
|||
return;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
if (ssl->handshake->group_list_heap_allocated) {
|
||||
mbedtls_free((void *) handshake->group_list);
|
||||
}
|
||||
handshake->group_list = NULL;
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
|
@ -4977,7 +4973,7 @@ static uint16_t ssl_preset_default_groups[] = {
|
|||
MBEDTLS_SSL_IANA_TLS_GROUP_NONE
|
||||
};
|
||||
|
||||
static int ssl_preset_suiteb_ciphersuites[] = {
|
||||
static const int ssl_preset_suiteb_ciphersuites[] = {
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
0
|
||||
|
@ -5304,14 +5300,8 @@ int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
|
|||
#endif
|
||||
} else {
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
} else {
|
||||
/* Hybrid TLS 1.2 / 1.3 is not supported on server side yet */
|
||||
conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
}
|
||||
conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
#elif defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
|
@ -5565,7 +5555,7 @@ int mbedtls_ssl_check_curve_tls_id(const mbedtls_ssl_context *ssl, uint16_t tls_
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/*
|
||||
* Same as mbedtls_ssl_check_curve_tls_id() but with a mbedtls_ecp_group_id.
|
||||
*/
|
||||
|
@ -5579,7 +5569,7 @@ int mbedtls_ssl_check_curve(const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id
|
|||
|
||||
return mbedtls_ssl_check_curve_tls_id(ssl, tls_id);
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
#define EC_NAME(_name_) _name_
|
||||
|
@ -7387,7 +7377,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
|
|||
* Secondary checks: always done, but change 'ret' only if it was 0
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
{
|
||||
const mbedtls_pk_context *pk = &chain->pk;
|
||||
|
||||
|
@ -7415,7 +7405,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
if (mbedtls_ssl_check_cert_usage(chain,
|
||||
ciphersuite_info,
|
||||
|
|
|
@ -920,12 +920,15 @@ read_record_header:
|
|||
* If renegotiating, then the input was read with mbedtls_ssl_read_record(),
|
||||
* otherwise read it ourselves manually in order to support SSLv2
|
||||
* ClientHello, which doesn't use the same record layer format.
|
||||
* Otherwise in a scenario of TLS 1.3/TLS 1.2 version negotiation, the
|
||||
* ClientHello has been already fully fetched by the TLS 1.3 code and the
|
||||
* flag ssl->keep_current_message is raised.
|
||||
*/
|
||||
renegotiating = 0;
|
||||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||
renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE);
|
||||
#endif
|
||||
if (!renegotiating) {
|
||||
if (!renegotiating && !ssl->keep_current_message) {
|
||||
if ((ret = mbedtls_ssl_fetch_input(ssl, 5)) != 0) {
|
||||
/* No alert on a read error. */
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
|
||||
|
@ -1000,24 +1003,28 @@ read_record_header:
|
|||
} else
|
||||
#endif
|
||||
{
|
||||
if (msg_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
|
||||
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
|
||||
}
|
||||
if (ssl->keep_current_message) {
|
||||
ssl->keep_current_message = 0;
|
||||
} else {
|
||||
if (msg_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
|
||||
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_ssl_fetch_input(ssl,
|
||||
mbedtls_ssl_in_hdr_len(ssl) + msg_len)) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = mbedtls_ssl_fetch_input(ssl,
|
||||
mbedtls_ssl_in_hdr_len(ssl) + msg_len)) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Done reading this record, get ready for the next one */
|
||||
/* Done reading this record, get ready for the next one */
|
||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
|
||||
ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len(ssl);
|
||||
} else
|
||||
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
|
||||
ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len(ssl);
|
||||
} else
|
||||
#endif
|
||||
ssl->in_left = 0;
|
||||
ssl->in_left = 0;
|
||||
}
|
||||
}
|
||||
|
||||
buf = ssl->in_msg;
|
||||
|
@ -2206,11 +2213,37 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl)
|
|||
p += 4;
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 28)) != 0) {
|
||||
if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 20)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
p += 20;
|
||||
|
||||
p += 28;
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
/*
|
||||
* RFC 8446
|
||||
* TLS 1.3 has a downgrade protection mechanism embedded in the server's
|
||||
* random value. TLS 1.3 servers which negotiate TLS 1.2 or below in
|
||||
* response to a ClientHello MUST set the last 8 bytes of their Random
|
||||
* value specially in their ServerHello.
|
||||
*/
|
||||
if (mbedtls_ssl_conf_is_tls13_enabled(ssl->conf)) {
|
||||
static const unsigned char magic_tls12_downgrade_string[] =
|
||||
{ 'D', 'O', 'W', 'N', 'G', 'R', 'D', 1 };
|
||||
|
||||
MBEDTLS_STATIC_ASSERT(
|
||||
sizeof(magic_tls12_downgrade_string) == 8,
|
||||
"magic_tls12_downgrade_string does not have the expected size");
|
||||
|
||||
memcpy(p, magic_tls12_downgrade_string,
|
||||
sizeof(magic_tls12_downgrade_string));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 8)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
p += 8;
|
||||
|
||||
memcpy(ssl->handshake->randbytes + 32, buf + 6, 32);
|
||||
|
||||
|
@ -2581,8 +2614,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
|
|||
return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
ssl->handshake->ecdh_psa_privkey =
|
||||
*((mbedtls_svc_key_id_t *) pk->pk_ctx);
|
||||
ssl->handshake->ecdh_psa_privkey = pk->priv_id;
|
||||
|
||||
/* Key should not be destroyed in the TLS library */
|
||||
ssl->handshake->ecdh_psa_privkey_is_external = 1;
|
||||
|
|
|
@ -117,7 +117,8 @@ static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl,
|
|||
}
|
||||
|
||||
if (&buf[2] != end) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("supported_versions ext data length incorrect"));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1, ("supported_versions ext data length incorrect"));
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
|
||||
MBEDTLS_ERR_SSL_DECODE_ERROR);
|
||||
return MBEDTLS_ERR_SSL_DECODE_ERROR;
|
||||
|
@ -227,8 +228,8 @@ static int ssl_tls13_get_default_group_id(mbedtls_ssl_context *ssl,
|
|||
}
|
||||
|
||||
for (; *group_list != 0; group_list++) {
|
||||
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(*group_list,
|
||||
NULL, NULL) == PSA_SUCCESS) &&
|
||||
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
|
||||
*group_list, NULL, NULL) == PSA_SUCCESS) &&
|
||||
mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) {
|
||||
*group_id = *group_list;
|
||||
return 0;
|
||||
|
@ -352,7 +353,8 @@ static int ssl_tls13_write_key_share_ext(mbedtls_ssl_context *ssl,
|
|||
/* Output the total length of key_share extension. */
|
||||
*out_len = p - buf;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, key_share extension", buf, *out_len);
|
||||
MBEDTLS_SSL_DEBUG_BUF(
|
||||
3, "client hello, key_share extension", buf, *out_len);
|
||||
|
||||
mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_KEY_SHARE);
|
||||
|
||||
|
@ -402,8 +404,8 @@ static int ssl_tls13_parse_hrr_key_share_ext(mbedtls_ssl_context *ssl,
|
|||
* then the client MUST abort the handshake with an "illegal_parameter" alert.
|
||||
*/
|
||||
for (; *group_list != 0; group_list++) {
|
||||
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(*group_list,
|
||||
NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) ||
|
||||
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
|
||||
*group_list, NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) ||
|
||||
*group_list != selected_group) {
|
||||
continue;
|
||||
}
|
||||
|
@ -472,9 +474,9 @@ static int ssl_tls13_parse_key_share_ext(mbedtls_ssl_context *ssl,
|
|||
/* Check that the chosen group matches the one we offered. */
|
||||
offered_group = ssl->handshake->offered_group_id;
|
||||
if (offered_group != group) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1,
|
||||
("Invalid server key share, our group %u, their group %u",
|
||||
(unsigned) offered_group, (unsigned) group));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1, ("Invalid server key share, our group %u, their group %u",
|
||||
(unsigned) offered_group, (unsigned) group));
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
|
@ -488,8 +490,9 @@ static int ssl_tls13_parse_key_share_ext(mbedtls_ssl_context *ssl,
|
|||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("ECDH curve: %s",
|
||||
mbedtls_ssl_get_curve_name_from_tls_id(group)));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
2,
|
||||
("ECDH curve: %s", mbedtls_ssl_get_curve_name_from_tls_id(group)));
|
||||
|
||||
ret = mbedtls_ssl_tls13_read_public_ecdhe_share(ssl, p, end - p);
|
||||
if (ret != 0) {
|
||||
|
@ -1324,8 +1327,8 @@ static int ssl_tls13_is_supported_versions_ext_present(
|
|||
{
|
||||
const unsigned char *p = buf;
|
||||
size_t legacy_session_id_echo_len;
|
||||
size_t extensions_len;
|
||||
const unsigned char *extensions_end;
|
||||
const unsigned char *supported_versions_data;
|
||||
const unsigned char *supported_versions_data_end;
|
||||
|
||||
/*
|
||||
* Check there is enough data to access the legacy_session_id_echo vector
|
||||
|
@ -1347,45 +1350,9 @@ static int ssl_tls13_is_supported_versions_ext_present(
|
|||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_echo_len + 4);
|
||||
p += legacy_session_id_echo_len + 4;
|
||||
|
||||
/* Case of no extension */
|
||||
if (p == end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ...
|
||||
* Extension extensions<6..2^16-1>;
|
||||
* ...
|
||||
* struct {
|
||||
* ExtensionType extension_type; (2 bytes)
|
||||
* opaque extension_data<0..2^16-1>;
|
||||
* } Extension;
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
|
||||
extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
p += 2;
|
||||
|
||||
/* Check extensions do not go beyond the buffer of data. */
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
|
||||
extensions_end = p + extensions_len;
|
||||
|
||||
while (p < extensions_end) {
|
||||
unsigned int extension_type;
|
||||
size_t extension_data_len;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4);
|
||||
extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
|
||||
p += 4;
|
||||
|
||||
if (extension_type == MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len);
|
||||
p += extension_data_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts(
|
||||
ssl, p, end,
|
||||
&supported_versions_data, &supported_versions_data_end);
|
||||
}
|
||||
|
||||
/* Returns a negative value on failure, and otherwise
|
||||
|
@ -1446,8 +1413,8 @@ static int ssl_server_hello_is_hrr(mbedtls_ssl_context *ssl,
|
|||
* } ServerHello;
|
||||
*
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end,
|
||||
2 + sizeof(mbedtls_ssl_tls13_hello_retry_request_magic));
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(
|
||||
buf, end, 2 + sizeof(mbedtls_ssl_tls13_hello_retry_request_magic));
|
||||
|
||||
if (memcmp(buf + 2, mbedtls_ssl_tls13_hello_retry_request_magic,
|
||||
sizeof(mbedtls_ssl_tls13_hello_retry_request_magic)) == 0) {
|
||||
|
@ -1491,11 +1458,18 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
|
|||
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version 1.2 of the protocol has been negotiated, set the
|
||||
* ssl->keep_current_message flag for the ServerHello to be kept and
|
||||
* parsed as a TLS 1.2 ServerHello. We also change ssl->tls_version to
|
||||
* MBEDTLS_SSL_VERSION_TLS1_2 thus from now on mbedtls_ssl_handshake_step()
|
||||
* will dispatch to the TLS 1.2 state machine.
|
||||
*/
|
||||
ssl->keep_current_message = 1;
|
||||
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_SERVER_HELLO,
|
||||
buf, (size_t) (end - buf)));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_SERVER_HELLO,
|
||||
buf, (size_t) (end - buf)));
|
||||
|
||||
if (mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
|
||||
ret = ssl_tls13_reset_key_share(ssl);
|
||||
|
@ -1521,15 +1495,16 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
|
|||
break;
|
||||
case SSL_SERVER_HELLO_HRR:
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("received HelloRetryRequest message"));
|
||||
/* If a client receives a second
|
||||
* HelloRetryRequest in the same connection (i.e., where the ClientHello
|
||||
* was itself in response to a HelloRetryRequest), it MUST abort the
|
||||
* handshake with an "unexpected_message" alert.
|
||||
/* If a client receives a second HelloRetryRequest in the same
|
||||
* connection (i.e., where the ClientHello was itself in response
|
||||
* to a HelloRetryRequest), it MUST abort the handshake with an
|
||||
* "unexpected_message" alert.
|
||||
*/
|
||||
if (handshake->hello_retry_request_count > 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received"));
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
||||
}
|
||||
/*
|
||||
|
@ -1890,20 +1865,25 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
|
|||
* exchange mode is EPHEMERAL-only.
|
||||
*/
|
||||
switch (handshake->received_extensions &
|
||||
(MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | MBEDTLS_SSL_EXT_MASK(KEY_SHARE))) {
|
||||
(MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) |
|
||||
MBEDTLS_SSL_EXT_MASK(KEY_SHARE))) {
|
||||
/* Only the pre_shared_key extension was received */
|
||||
case MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY):
|
||||
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
|
||||
handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
|
||||
break;
|
||||
|
||||
/* Only the key_share extension was received */
|
||||
case MBEDTLS_SSL_EXT_MASK(KEY_SHARE):
|
||||
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
|
||||
handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
|
||||
break;
|
||||
|
||||
/* Both the pre_shared_key and key_share extensions were received */
|
||||
case (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | MBEDTLS_SSL_EXT_MASK(KEY_SHARE)):
|
||||
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
|
||||
case (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) |
|
||||
MBEDTLS_SSL_EXT_MASK(KEY_SHARE)):
|
||||
handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
|
||||
break;
|
||||
|
||||
/* Neither pre_shared_key nor key_share extension was received */
|
||||
|
@ -1946,15 +1926,15 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
|
|||
if (!mbedtls_ssl_conf_tls13_check_kex_modes(
|
||||
ssl, handshake->key_exchange_mode)) {
|
||||
ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2,
|
||||
("Key exchange mode(%s) is not supported.",
|
||||
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
2, ("Key exchange mode(%s) is not supported.",
|
||||
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(3,
|
||||
("Selected key exchange mode: %s",
|
||||
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ("Selected key exchange mode: %s",
|
||||
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
|
||||
|
||||
/* Start the TLS 1.3 key scheduling if not already done.
|
||||
*
|
||||
|
@ -2038,9 +2018,8 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> %s", __func__));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_SERVER_HELLO,
|
||||
&buf, &buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, &buf, &buf_len));
|
||||
|
||||
ret = ssl_tls13_preprocess_server_hello(ssl, buf, buf + buf_len);
|
||||
if (ret < 0) {
|
||||
|
@ -2061,9 +2040,8 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
|
|||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_reset_transcript_for_hrr(ssl));
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_SERVER_HELLO, buf,
|
||||
buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, buf_len));
|
||||
|
||||
if (is_hrr) {
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_hrr(ssl));
|
||||
|
@ -2072,8 +2050,8 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
|
|||
* immediately before its second flight. This may either be before
|
||||
* its second ClientHello or before its encrypted handshake flight.
|
||||
*/
|
||||
mbedtls_ssl_handshake_set_state(ssl,
|
||||
MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO);
|
||||
mbedtls_ssl_handshake_set_state(
|
||||
ssl, MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO);
|
||||
#else
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
|
||||
|
@ -2153,7 +2131,8 @@ static int ssl_tls13_parse_encrypted_extensions(mbedtls_ssl_context *ssl,
|
|||
case MBEDTLS_TLS_EXT_ALPN:
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
|
||||
|
||||
if ((ret = ssl_tls13_parse_alpn_ext(ssl, p, (size_t) extension_data_len)) != 0) {
|
||||
if ((ret = ssl_tls13_parse_alpn_ext(
|
||||
ssl, p, (size_t) extension_data_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2177,10 +2156,12 @@ static int ssl_tls13_parse_encrypted_extensions(mbedtls_ssl_context *ssl,
|
|||
case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT:
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("found record_size_limit extension"));
|
||||
|
||||
ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(ssl, p, p + extension_data_len);
|
||||
ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(
|
||||
ssl, p, p + extension_data_len);
|
||||
|
||||
/* TODO: Return unconditionally here until we handle the record size limit correctly.
|
||||
* Once handled correctly, only return in case of errors. */
|
||||
/* TODO: Return unconditionally here until we handle the record
|
||||
* size limit correctly. Once handled correctly, only return in
|
||||
* case of errors. */
|
||||
return ret;
|
||||
|
||||
break;
|
||||
|
@ -2219,9 +2200,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse encrypted extensions"));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||
&buf, &buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||
&buf, &buf_len));
|
||||
|
||||
/* Process the message contents */
|
||||
MBEDTLS_SSL_PROC_CHK(
|
||||
|
@ -2234,9 +2215,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
|
|||
}
|
||||
#endif
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||
buf, buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||
buf, buf_len));
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
|
||||
|
@ -2472,16 +2453,16 @@ static int ssl_tls13_process_certificate_request(mbedtls_ssl_context *ssl)
|
|||
unsigned char *buf;
|
||||
size_t buf_len;
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||
&buf, &buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||
&buf, &buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request(ssl,
|
||||
buf, buf + buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request(
|
||||
ssl, buf, buf + buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||
buf, buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||
buf, buf_len));
|
||||
} else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) {
|
||||
ret = 0;
|
||||
} else {
|
||||
|
@ -2643,8 +2624,8 @@ static int ssl_tls13_write_client_finished(mbedtls_ssl_context *ssl)
|
|||
|
||||
ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
"mbedtls_ssl_tls13_compute_resumption_master_secret ", ret);
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "mbedtls_ssl_tls13_compute_resumption_master_secret ", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3024,7 +3005,8 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
|
|||
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret == 0) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
|
||||
mbedtls_ssl_handshake_set_state(
|
||||
ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -86,6 +86,61 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf, const unsigned char *end,
|
||||
const unsigned char **supported_versions_data,
|
||||
const unsigned char **supported_versions_data_end)
|
||||
{
|
||||
const unsigned char *p = buf;
|
||||
size_t extensions_len;
|
||||
const unsigned char *extensions_end;
|
||||
|
||||
*supported_versions_data = NULL;
|
||||
*supported_versions_data_end = NULL;
|
||||
|
||||
/* Case of no extension */
|
||||
if (p == end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ...
|
||||
* Extension extensions<x..2^16-1>;
|
||||
* ...
|
||||
* struct {
|
||||
* ExtensionType extension_type; (2 bytes)
|
||||
* opaque extension_data<0..2^16-1>;
|
||||
* } Extension;
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
|
||||
extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
p += 2;
|
||||
|
||||
/* Check extensions do not go beyond the buffer of data. */
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
|
||||
extensions_end = p + extensions_len;
|
||||
|
||||
while (p < extensions_end) {
|
||||
unsigned int extension_type;
|
||||
size_t extension_data_len;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4);
|
||||
extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
|
||||
p += 4;
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len);
|
||||
|
||||
if (extension_type == MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS) {
|
||||
*supported_versions_data = p;
|
||||
*supported_versions_data_end = p + extension_data_len;
|
||||
return 1;
|
||||
}
|
||||
p += extension_data_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
/*
|
||||
* STATE HANDLING: Read CertificateVerify
|
||||
|
@ -192,15 +247,17 @@ static int ssl_tls13_parse_certificate_verify(mbedtls_ssl_context *ssl,
|
|||
|
||||
/* RFC 8446 section 4.4.3
|
||||
*
|
||||
* If the CertificateVerify message is sent by a server, the signature algorithm
|
||||
* MUST be one offered in the client's "signature_algorithms" extension unless
|
||||
* no valid certificate chain can be produced without unsupported algorithms
|
||||
* If the CertificateVerify message is sent by a server, the signature
|
||||
* algorithm MUST be one offered in the client's "signature_algorithms"
|
||||
* extension unless no valid certificate chain can be produced without
|
||||
* unsupported algorithms
|
||||
*
|
||||
* RFC 8446 section 4.4.2.2
|
||||
*
|
||||
* If the client cannot construct an acceptable chain using the provided
|
||||
* certificates and decides to abort the handshake, then it MUST abort the handshake
|
||||
* with an appropriate certificate-related alert (by default, "unsupported_certificate").
|
||||
* certificates and decides to abort the handshake, then it MUST abort the
|
||||
* handshake with an appropriate certificate-related alert
|
||||
* (by default, "unsupported_certificate").
|
||||
*
|
||||
* Check if algorithm is an offered signature algorithm.
|
||||
*/
|
||||
|
@ -295,17 +352,18 @@ int mbedtls_ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl)
|
|||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(
|
||||
mbedtls_ssl_tls13_fetch_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, &buf, &buf_len));
|
||||
mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, &buf, &buf_len));
|
||||
|
||||
/* Need to calculate the hash of the transcript first
|
||||
* before reading the message since otherwise it gets
|
||||
* included in the transcript
|
||||
*/
|
||||
ret = mbedtls_ssl_get_handshake_transcript(ssl,
|
||||
ssl->handshake->ciphersuite_info->mac,
|
||||
transcript, sizeof(transcript),
|
||||
&transcript_len);
|
||||
ret = mbedtls_ssl_get_handshake_transcript(
|
||||
ssl,
|
||||
ssl->handshake->ciphersuite_info->mac,
|
||||
transcript, sizeof(transcript),
|
||||
&transcript_len);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR,
|
||||
|
@ -325,13 +383,13 @@ int mbedtls_ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl)
|
|||
MBEDTLS_SSL_IS_CLIENT);
|
||||
|
||||
/* Process the message contents */
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_verify(ssl, buf,
|
||||
buf + buf_len, verify_buffer,
|
||||
verify_buffer_len));
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_verify(
|
||||
ssl, buf, buf + buf_len,
|
||||
verify_buffer, verify_buffer_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE_VERIFY,
|
||||
buf, buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY,
|
||||
buf, buf_len));
|
||||
|
||||
cleanup:
|
||||
|
||||
|
@ -545,7 +603,8 @@ exit:
|
|||
return MBEDTLS_ERR_SSL_DECODE_ERROR;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_CRT(3, "peer certificate", ssl->session_negotiate->peer_cert);
|
||||
MBEDTLS_SSL_DEBUG_CRT(3, "peer certificate",
|
||||
ssl->session_negotiate->peer_cert);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -611,8 +670,9 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
|
|||
if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL) {
|
||||
return 0;
|
||||
} else {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_NO_CERT,
|
||||
MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE);
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_NO_CERT,
|
||||
MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE);
|
||||
return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
|
@ -699,7 +759,8 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
|
|||
Pick one and send the corresponding alert. Which alert to send
|
||||
may be a subject of debate in some cases. */
|
||||
if (verify_result & MBEDTLS_X509_BADCERT_OTHER) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED, ret);
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED, ret);
|
||||
} else if (verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_BAD_CERT, ret);
|
||||
} else if (verify_result & (MBEDTLS_X509_BADCERT_KEY_USAGE |
|
||||
|
@ -707,15 +768,19 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
|
|||
MBEDTLS_X509_BADCERT_NS_CERT_TYPE |
|
||||
MBEDTLS_X509_BADCERT_BAD_PK |
|
||||
MBEDTLS_X509_BADCERT_BAD_KEY)) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT, ret);
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT, ret);
|
||||
} else if (verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED, ret);
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED, ret);
|
||||
} else if (verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED, ret);
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED, ret);
|
||||
} else if (verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA, ret);
|
||||
} else {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN, ret);
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN, ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -760,9 +825,8 @@ int mbedtls_ssl_tls13_process_certificate(mbedtls_ssl_context *ssl)
|
|||
/* Validate the certificate chain and set the verification results. */
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_validate_certificate(ssl));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE, buf,
|
||||
buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE, buf, buf_len));
|
||||
|
||||
cleanup:
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
@ -868,18 +932,16 @@ int mbedtls_ssl_tls13_write_certificate(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate"));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE, &buf,
|
||||
&buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE, &buf, &buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_body(ssl,
|
||||
buf,
|
||||
buf + buf_len,
|
||||
&msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE, buf,
|
||||
msg_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE, buf, msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
|
||||
ssl, buf_len, msg_len));
|
||||
|
@ -962,11 +1024,9 @@ static int ssl_tls13_write_certificate_verify_body(mbedtls_ssl_context *ssl,
|
|||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_get_handshake_transcript(ssl,
|
||||
ssl->handshake->ciphersuite_info->mac,
|
||||
handshake_hash,
|
||||
sizeof(handshake_hash),
|
||||
&handshake_hash_len);
|
||||
ret = mbedtls_ssl_get_handshake_transcript(
|
||||
ssl, ssl->handshake->ciphersuite_info->mac,
|
||||
handshake_hash, sizeof(handshake_hash), &handshake_hash_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1073,16 +1133,16 @@ int mbedtls_ssl_tls13_write_certificate_verify(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify"));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, &buf,
|
||||
&buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY,
|
||||
&buf, &buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_verify_body(
|
||||
ssl, buf, buf + buf_len, &msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, buf,
|
||||
msg_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY,
|
||||
buf, msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
|
||||
ssl, buf_len, msg_len));
|
||||
|
@ -1108,13 +1168,13 @@ static int ssl_tls13_preprocess_finished_message(mbedtls_ssl_context *ssl)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = mbedtls_ssl_tls13_calculate_verify_data(ssl,
|
||||
ssl->handshake->state_local.finished_in.digest,
|
||||
sizeof(ssl->handshake->state_local.finished_in.
|
||||
digest),
|
||||
&ssl->handshake->state_local.finished_in.digest_len,
|
||||
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ?
|
||||
MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT);
|
||||
ret = mbedtls_ssl_tls13_calculate_verify_data(
|
||||
ssl,
|
||||
ssl->handshake->state_local.finished_in.digest,
|
||||
sizeof(ssl->handshake->state_local.finished_in.digest),
|
||||
&ssl->handshake->state_local.finished_in.digest_len,
|
||||
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ?
|
||||
MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_calculate_verify_data", ret);
|
||||
return ret;
|
||||
|
@ -1173,17 +1233,17 @@ int mbedtls_ssl_tls13_process_finished_message(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse finished message"));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_FINISHED,
|
||||
&buf, &buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_FINISHED, &buf, &buf_len));
|
||||
|
||||
/* Preprocessing step: Compute handshake digest */
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_preprocess_finished_message(ssl));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_finished_message(ssl, buf, buf + buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_finished_message(
|
||||
ssl, buf, buf + buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
||||
MBEDTLS_SSL_HS_FINISHED, buf, buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_FINISHED, buf, buf_len));
|
||||
|
||||
cleanup:
|
||||
|
||||
|
@ -1471,9 +1531,8 @@ int mbedtls_ssl_tls13_generate_and_write_ecdh_key_exchange(
|
|||
MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
|
||||
|
||||
/* Convert EC's TLS ID to PSA key type. */
|
||||
if (mbedtls_ssl_get_psa_curve_info_from_tls_id(named_group,
|
||||
&ec_psa_family,
|
||||
&ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
|
||||
if (mbedtls_ssl_get_psa_curve_info_from_tls_id(
|
||||
named_group, &ec_psa_family, &ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR(ec_psa_family);
|
||||
|
@ -1583,7 +1642,8 @@ int mbedtls_ssl_tls13_parse_record_size_limit_ext(mbedtls_ssl_context *ssl,
|
|||
uint16_t record_size_limit;
|
||||
const size_t extension_data_len = end - buf;
|
||||
|
||||
if (extension_data_len != MBEDTLS_SSL_RECORD_SIZE_LIMIT_EXTENSION_DATA_LENGTH) {
|
||||
if (extension_data_len !=
|
||||
MBEDTLS_SSL_RECORD_SIZE_LIMIT_EXTENSION_DATA_LENGTH) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(2,
|
||||
("record_size_limit extension has invalid length: %"
|
||||
MBEDTLS_PRINTF_SIZET " Bytes",
|
||||
|
@ -1613,9 +1673,8 @@ int mbedtls_ssl_tls13_parse_record_size_limit_ext(mbedtls_ssl_context *ssl,
|
|||
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2,
|
||||
(
|
||||
"record_size_limit extension is still in development. Aborting handshake."));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
2, ("record_size_limit extension is still in development. Aborting handshake."));
|
||||
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
|
||||
|
|
|
@ -455,25 +455,27 @@ int mbedtls_ssl_tls13_derive_early_secrets(
|
|||
*/
|
||||
|
||||
/* Create client_early_traffic_secret */
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
early_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_e_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->client_early_traffic_secret,
|
||||
hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
early_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_e_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->client_early_traffic_secret,
|
||||
hash_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create early exporter */
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
early_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(e_exp_master),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->early_exporter_master_secret,
|
||||
hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
early_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(e_exp_master),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->early_exporter_master_secret,
|
||||
hash_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -515,13 +517,14 @@ int mbedtls_ssl_tls13_derive_handshake_secrets(
|
|||
* Derive-Secret( ., "c hs traffic", ClientHello...ServerHello )
|
||||
*/
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
handshake_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_hs_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->client_handshake_traffic_secret,
|
||||
hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
handshake_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_hs_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->client_handshake_traffic_secret,
|
||||
hash_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -531,13 +534,14 @@ int mbedtls_ssl_tls13_derive_handshake_secrets(
|
|||
* Derive-Secret( ., "s hs traffic", ClientHello...ServerHello )
|
||||
*/
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
handshake_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_hs_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->server_handshake_traffic_secret,
|
||||
hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
handshake_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_hs_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->server_handshake_traffic_secret,
|
||||
hash_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -578,35 +582,38 @@ int mbedtls_ssl_tls13_derive_application_secrets(
|
|||
*
|
||||
*/
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
application_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_ap_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->client_application_traffic_secret_N,
|
||||
hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
application_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_ap_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->client_application_traffic_secret_N,
|
||||
hash_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
application_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_ap_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->server_application_traffic_secret_N,
|
||||
hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
application_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_ap_traffic),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->server_application_traffic_secret_N,
|
||||
hash_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
application_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exp_master),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->exporter_master_secret,
|
||||
hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
application_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exp_master),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->exporter_master_secret,
|
||||
hash_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -633,13 +640,14 @@ int mbedtls_ssl_tls13_derive_resumption_master_secret(
|
|||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
application_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_master),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->resumption_master_secret,
|
||||
hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
application_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_master),
|
||||
transcript, transcript_len,
|
||||
MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
|
||||
derived->resumption_master_secret,
|
||||
hash_len);
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
|
@ -675,17 +683,19 @@ static int ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl)
|
|||
/*
|
||||
* Compute MasterSecret
|
||||
*/
|
||||
ret = mbedtls_ssl_tls13_evolve_secret(hash_alg,
|
||||
handshake->tls13_master_secrets.handshake,
|
||||
NULL, 0,
|
||||
handshake->tls13_master_secrets.app);
|
||||
ret = mbedtls_ssl_tls13_evolve_secret(
|
||||
hash_alg,
|
||||
handshake->tls13_master_secrets.handshake,
|
||||
NULL, 0,
|
||||
handshake->tls13_master_secrets.app);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF(4, "Master secret",
|
||||
handshake->tls13_master_secrets.app, PSA_HASH_LENGTH(hash_alg));
|
||||
MBEDTLS_SSL_DEBUG_BUF(
|
||||
4, "Master secret",
|
||||
handshake->tls13_master_secrets.app, PSA_HASH_LENGTH(hash_alg));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -810,7 +820,8 @@ int mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context *ssl,
|
|||
}
|
||||
MBEDTLS_SSL_DEBUG_BUF(4, "handshake hash", transcript, transcript_len);
|
||||
|
||||
ret = ssl_tls13_calc_finished_core(hash_alg, base_key, transcript, dst, actual_len);
|
||||
ret = ssl_tls13_calc_finished_core(hash_alg, base_key,
|
||||
transcript, dst, actual_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
@ -873,18 +884,20 @@ int mbedtls_ssl_tls13_create_psk_binder(mbedtls_ssl_context *ssl,
|
|||
early_secret, hash_len);
|
||||
|
||||
if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
early_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_binder),
|
||||
NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
|
||||
binder_key, hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
early_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_binder),
|
||||
NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
|
||||
binder_key, hash_len);
|
||||
MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'res binder'"));
|
||||
} else {
|
||||
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
|
||||
early_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(ext_binder),
|
||||
NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
|
||||
binder_key, hash_len);
|
||||
ret = mbedtls_ssl_tls13_derive_secret(
|
||||
hash_alg,
|
||||
early_secret, hash_len,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(ext_binder),
|
||||
NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
|
||||
binder_key, hash_len);
|
||||
MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'ext binder'"));
|
||||
}
|
||||
|
||||
|
@ -913,11 +926,11 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_tls13_populate_transform(mbedtls_ssl_transform *transform,
|
||||
int endpoint,
|
||||
int ciphersuite,
|
||||
mbedtls_ssl_key_set const *traffic_keys,
|
||||
mbedtls_ssl_context *ssl /* DEBUG ONLY */)
|
||||
int mbedtls_ssl_tls13_populate_transform(
|
||||
mbedtls_ssl_transform *transform,
|
||||
int endpoint, int ciphersuite,
|
||||
mbedtls_ssl_key_set const *traffic_keys,
|
||||
mbedtls_ssl_context *ssl /* DEBUG ONLY */)
|
||||
{
|
||||
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
int ret;
|
||||
|
@ -1044,7 +1057,8 @@ int mbedtls_ssl_tls13_populate_transform(mbedtls_ssl_transform *transform,
|
|||
&alg,
|
||||
&key_type,
|
||||
&key_bits)) != PSA_SUCCESS) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_cipher_to_psa", PSA_TO_MBEDTLS_ERR(status));
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "mbedtls_ssl_cipher_to_psa", PSA_TO_MBEDTLS_ERR(status));
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
|
@ -1059,7 +1073,8 @@ int mbedtls_ssl_tls13_populate_transform(mbedtls_ssl_transform *transform,
|
|||
key_enc,
|
||||
PSA_BITS_TO_BYTES(key_bits),
|
||||
&transform->psa_key_enc)) != PSA_SUCCESS) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status));
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status));
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
|
@ -1069,7 +1084,8 @@ int mbedtls_ssl_tls13_populate_transform(mbedtls_ssl_transform *transform,
|
|||
key_dec,
|
||||
PSA_BITS_TO_BYTES(key_bits),
|
||||
&transform->psa_key_dec)) != PSA_SUCCESS) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status));
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status));
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
}
|
||||
|
@ -1134,7 +1150,8 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
|
|||
mbedtls_ssl_tls13_early_secrets tls13_early_secrets;
|
||||
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = handshake->ciphersuite_info;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
handshake->ciphersuite_info;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_early_key"));
|
||||
|
||||
|
@ -1333,8 +1350,10 @@ static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
|
|||
size_t iv_len;
|
||||
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = handshake->ciphersuite_info;
|
||||
mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets = &handshake->tls13_hs_secrets;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
handshake->ciphersuite_info;
|
||||
mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets =
|
||||
&handshake->tls13_hs_secrets;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_handshake_keys"));
|
||||
|
||||
|
@ -1360,9 +1379,9 @@ static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_handshake_secrets(hash_alg,
|
||||
handshake->tls13_master_secrets.handshake,
|
||||
transcript, transcript_len, tls13_hs_secrets);
|
||||
ret = mbedtls_ssl_tls13_derive_handshake_secrets(
|
||||
hash_alg, handshake->tls13_master_secrets.handshake,
|
||||
transcript, transcript_len, tls13_hs_secrets);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_handshake_secrets",
|
||||
ret);
|
||||
|
@ -1380,27 +1399,30 @@ static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
|
|||
* Export client handshake traffic secret
|
||||
*/
|
||||
if (ssl->f_export_keys != NULL) {
|
||||
ssl->f_export_keys(ssl->p_export_keys,
|
||||
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
|
||||
tls13_hs_secrets->client_handshake_traffic_secret,
|
||||
hash_len,
|
||||
handshake->randbytes,
|
||||
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
|
||||
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
|
||||
ssl->f_export_keys(
|
||||
ssl->p_export_keys,
|
||||
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
|
||||
tls13_hs_secrets->client_handshake_traffic_secret,
|
||||
hash_len,
|
||||
handshake->randbytes,
|
||||
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
|
||||
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
|
||||
|
||||
ssl->f_export_keys(ssl->p_export_keys,
|
||||
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET,
|
||||
tls13_hs_secrets->server_handshake_traffic_secret,
|
||||
hash_len,
|
||||
handshake->randbytes,
|
||||
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
|
||||
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
|
||||
ssl->f_export_keys(
|
||||
ssl->p_export_keys,
|
||||
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET,
|
||||
tls13_hs_secrets->server_handshake_traffic_secret,
|
||||
hash_len,
|
||||
handshake->randbytes,
|
||||
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
|
||||
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_tls13_make_traffic_keys(hash_alg,
|
||||
tls13_hs_secrets->client_handshake_traffic_secret,
|
||||
tls13_hs_secrets->server_handshake_traffic_secret,
|
||||
hash_len, key_len, iv_len, traffic_keys);
|
||||
ret = mbedtls_ssl_tls13_make_traffic_keys(
|
||||
hash_alg,
|
||||
tls13_hs_secrets->client_handshake_traffic_secret,
|
||||
tls13_hs_secrets->server_handshake_traffic_secret,
|
||||
hash_len, key_len, iv_len, traffic_keys);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret);
|
||||
goto exit;
|
||||
|
@ -1510,10 +1532,10 @@ static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
|
|||
/*
|
||||
* Compute the Handshake Secret
|
||||
*/
|
||||
ret = mbedtls_ssl_tls13_evolve_secret(hash_alg,
|
||||
handshake->tls13_master_secrets.early,
|
||||
shared_secret, shared_secret_len,
|
||||
handshake->tls13_master_secrets.handshake);
|
||||
ret = mbedtls_ssl_tls13_evolve_secret(
|
||||
hash_alg, handshake->tls13_master_secrets.early,
|
||||
shared_secret, shared_secret_len,
|
||||
handshake->tls13_master_secrets.handshake);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
|
||||
goto cleanup;
|
||||
|
@ -1601,22 +1623,22 @@ static int ssl_tls13_generate_application_keys(
|
|||
|
||||
/* Compute application secrets from master secret and transcript hash. */
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_application_secrets(hash_alg,
|
||||
handshake->tls13_master_secrets.app,
|
||||
transcript, transcript_len,
|
||||
app_secrets);
|
||||
ret = mbedtls_ssl_tls13_derive_application_secrets(
|
||||
hash_alg, handshake->tls13_master_secrets.app,
|
||||
transcript, transcript_len, app_secrets);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
"mbedtls_ssl_tls13_derive_application_secrets", ret);
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "mbedtls_ssl_tls13_derive_application_secrets", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Derive first epoch of IV + Key for application traffic. */
|
||||
|
||||
ret = mbedtls_ssl_tls13_make_traffic_keys(hash_alg,
|
||||
app_secrets->client_application_traffic_secret_N,
|
||||
app_secrets->server_application_traffic_secret_N,
|
||||
hash_len, key_len, iv_len, traffic_keys);
|
||||
ret = mbedtls_ssl_tls13_make_traffic_keys(
|
||||
hash_alg,
|
||||
app_secrets->client_application_traffic_secret_N,
|
||||
app_secrets->server_application_traffic_secret_N,
|
||||
hash_len, key_len, iv_len, traffic_keys);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret);
|
||||
goto cleanup;
|
||||
|
@ -1634,21 +1656,23 @@ static int ssl_tls13_generate_application_keys(
|
|||
* Export client/server application traffic secret 0
|
||||
*/
|
||||
if (ssl->f_export_keys != NULL) {
|
||||
ssl->f_export_keys(ssl->p_export_keys,
|
||||
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET,
|
||||
app_secrets->client_application_traffic_secret_N, hash_len,
|
||||
handshake->randbytes,
|
||||
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
|
||||
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
|
||||
a new constant for TLS 1.3! */);
|
||||
ssl->f_export_keys(
|
||||
ssl->p_export_keys,
|
||||
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET,
|
||||
app_secrets->client_application_traffic_secret_N, hash_len,
|
||||
handshake->randbytes,
|
||||
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
|
||||
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
|
||||
a new constant for TLS 1.3! */);
|
||||
|
||||
ssl->f_export_keys(ssl->p_export_keys,
|
||||
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET,
|
||||
app_secrets->server_application_traffic_secret_N, hash_len,
|
||||
handshake->randbytes,
|
||||
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
|
||||
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
|
||||
a new constant for TLS 1.3! */);
|
||||
ssl->f_export_keys(
|
||||
ssl->p_export_keys,
|
||||
MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET,
|
||||
app_secrets->server_application_traffic_secret_N, hash_len,
|
||||
handshake->randbytes,
|
||||
handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
|
||||
MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
|
||||
a new constant for TLS 1.3! */);
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF(4, "client application_write_key:",
|
||||
|
@ -1729,8 +1753,8 @@ int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl)
|
|||
unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
|
||||
size_t transcript_len;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2,
|
||||
("=> mbedtls_ssl_tls13_compute_resumption_master_secret"));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
2, ("=> mbedtls_ssl_tls13_compute_resumption_master_secret"));
|
||||
|
||||
md_type = handshake->ciphersuite_info->mac;
|
||||
|
||||
|
@ -1754,12 +1778,13 @@ int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl)
|
|||
mbedtls_platform_zeroize(&handshake->tls13_master_secrets,
|
||||
sizeof(handshake->tls13_master_secrets));
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF(4, "Resumption master secret",
|
||||
ssl->session_negotiate->app_secrets.resumption_master_secret,
|
||||
PSA_HASH_LENGTH(mbedtls_psa_translate_md(md_type)));
|
||||
MBEDTLS_SSL_DEBUG_BUF(
|
||||
4, "Resumption master secret",
|
||||
ssl->session_negotiate->app_secrets.resumption_master_secret,
|
||||
PSA_HASH_LENGTH(mbedtls_psa_translate_md(md_type)));
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2,
|
||||
("<= mbedtls_ssl_tls13_compute_resumption_master_secret"));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
2, ("<= mbedtls_ssl_tls13_compute_resumption_master_secret"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -317,11 +317,10 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
|||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_offered_psks_check_binder_match(mbedtls_ssl_context *ssl,
|
||||
const unsigned char *binder,
|
||||
size_t binder_len,
|
||||
int psk_type,
|
||||
psa_algorithm_t psk_hash_alg)
|
||||
static int ssl_tls13_offered_psks_check_binder_match(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *binder, size_t binder_len,
|
||||
int psk_type, psa_algorithm_t psk_hash_alg)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
|
@ -490,11 +489,12 @@ static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst,
|
|||
* } PreSharedKeyExtension;
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl,
|
||||
const unsigned char *pre_shared_key_ext,
|
||||
const unsigned char *pre_shared_key_ext_end,
|
||||
const unsigned char *ciphersuites,
|
||||
const unsigned char *ciphersuites_end)
|
||||
static int ssl_tls13_parse_pre_shared_key_ext(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *pre_shared_key_ext,
|
||||
const unsigned char *pre_shared_key_ext_end,
|
||||
const unsigned char *ciphersuites,
|
||||
const unsigned char *ciphersuites_end)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const unsigned char *identities = pre_shared_key_ext;
|
||||
|
@ -621,8 +621,8 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl,
|
|||
mbedtls_ssl_session_free(&session);
|
||||
#endif
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Invalid binder."));
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
"ssl_tls13_offered_psks_check_binder_match", ret);
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "ssl_tls13_offered_psks_check_binder_match", ret);
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||
|
@ -656,9 +656,8 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl,
|
|||
}
|
||||
|
||||
/* Update the handshake transcript with the binder list. */
|
||||
ret = ssl->handshake->update_checksum(ssl,
|
||||
identities_end,
|
||||
(size_t) (binders_end - identities_end));
|
||||
ret = ssl->handshake->update_checksum(
|
||||
ssl, identities_end, (size_t) (binders_end - identities_end));
|
||||
if (0 != ret) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
|
||||
return ret;
|
||||
|
@ -738,7 +737,7 @@ static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl,
|
|||
size_t versions_len;
|
||||
const unsigned char *versions_end;
|
||||
uint16_t tls_version;
|
||||
int tls13_supported = 0;
|
||||
int found_supported_version = 0;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1);
|
||||
versions_len = p[0];
|
||||
|
@ -751,25 +750,30 @@ static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl,
|
|||
tls_version = mbedtls_ssl_read_version(p, ssl->conf->transport);
|
||||
p += 2;
|
||||
|
||||
/* In this implementation we only support TLS 1.3 and DTLS 1.3. */
|
||||
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
|
||||
tls13_supported = 1;
|
||||
if (MBEDTLS_SSL_VERSION_TLS1_3 == tls_version) {
|
||||
found_supported_version = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((MBEDTLS_SSL_VERSION_TLS1_2 == tls_version) &&
|
||||
mbedtls_ssl_conf_is_tls12_enabled(ssl->conf)) {
|
||||
found_supported_version = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tls13_supported) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("TLS 1.3 is not supported by the client"));
|
||||
if (!found_supported_version) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("No supported version found."));
|
||||
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION,
|
||||
MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION);
|
||||
return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Negotiated version. Supported is [%04x]",
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Negotiated version: [%04x]",
|
||||
(unsigned int) tls_version));
|
||||
|
||||
return 0;
|
||||
return (int) tls_version;
|
||||
}
|
||||
|
||||
#if defined(PSA_WANT_ALG_ECDH)
|
||||
|
@ -835,13 +839,14 @@ static int ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl,
|
|||
#if defined(PSA_WANT_ALG_ECDH)
|
||||
/*
|
||||
* ssl_tls13_parse_key_shares_ext() verifies whether the information in the
|
||||
* extension is correct and stores the first acceptable key share and its associated group.
|
||||
* extension is correct and stores the first acceptable key share and its
|
||||
* associated group.
|
||||
*
|
||||
* Possible return values are:
|
||||
* - 0: Successful processing of the client provided key share extension.
|
||||
* - SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH: The key shares provided by the client
|
||||
* does not match a group supported by the server. A HelloRetryRequest will
|
||||
* be needed.
|
||||
* - SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH: The key shares provided by
|
||||
* the client does not match a group supported by the server. A
|
||||
* HelloRetryRequest will be needed.
|
||||
* - A negative value for fatal errors.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
|
@ -1037,7 +1042,8 @@ static int ssl_tls13_determine_key_exchange_mode(mbedtls_ssl_context *ssl)
|
|||
* 3 ) Plain PSK Mode ( psk )
|
||||
*/
|
||||
|
||||
ssl->handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
|
||||
ssl->handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
|
||||
|
||||
if (ssl_tls13_check_psk_ephemeral_key_exchange(ssl)) {
|
||||
ssl->handshake->key_exchange_mode =
|
||||
|
@ -1233,6 +1239,7 @@ static int ssl_tls13_pick_key_cert(mbedtls_ssl_context *ssl)
|
|||
|
||||
#define SSL_CLIENT_HELLO_OK 0
|
||||
#define SSL_CLIENT_HELLO_HRR_REQUIRED 1
|
||||
#define SSL_CLIENT_HELLO_TLS1_2 2
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
|
@ -1241,16 +1248,20 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const unsigned char *p = buf;
|
||||
const unsigned char *random;
|
||||
size_t legacy_session_id_len;
|
||||
const unsigned char *legacy_session_id;
|
||||
size_t cipher_suites_len;
|
||||
const unsigned char *cipher_suites;
|
||||
const unsigned char *cipher_suites_end;
|
||||
size_t extensions_len;
|
||||
const unsigned char *extensions_end;
|
||||
const unsigned char *supported_versions_data;
|
||||
const unsigned char *supported_versions_data_end;
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
int hrr_required = 0;
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
const unsigned char *cipher_suites;
|
||||
const unsigned char *pre_shared_key_ext = NULL;
|
||||
const unsigned char *pre_shared_key_ext_end = NULL;
|
||||
#endif
|
||||
|
@ -1291,55 +1302,38 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
}
|
||||
p += 2;
|
||||
|
||||
/*
|
||||
* Only support TLS 1.3 currently, temporarily set the version.
|
||||
*/
|
||||
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
/* Store minor version for later use with ticket serialization. */
|
||||
ssl->session_negotiate->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
ssl->session_negotiate->endpoint = ssl->conf->endpoint;
|
||||
#endif
|
||||
|
||||
/* ...
|
||||
* Random random;
|
||||
* ...
|
||||
* with Random defined as:
|
||||
* opaque Random[32];
|
||||
*/
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes",
|
||||
p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
|
||||
|
||||
memcpy(&handshake->randbytes[0], p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
|
||||
random = p;
|
||||
p += MBEDTLS_CLIENT_HELLO_RANDOM_LEN;
|
||||
|
||||
/* ...
|
||||
* opaque legacy_session_id<0..32>;
|
||||
* ...
|
||||
*/
|
||||
legacy_session_id_len = p[0];
|
||||
p++;
|
||||
legacy_session_id_len = *(p++);
|
||||
legacy_session_id = p;
|
||||
|
||||
if (legacy_session_id_len > sizeof(ssl->session_negotiate->id)) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
|
||||
return MBEDTLS_ERR_SSL_DECODE_ERROR;
|
||||
}
|
||||
|
||||
ssl->session_negotiate->id_len = legacy_session_id_len;
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id",
|
||||
p, legacy_session_id_len);
|
||||
/*
|
||||
* Check we have enough data for the legacy session identifier
|
||||
* and the ciphersuite list length.
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_len + 2);
|
||||
|
||||
memcpy(&ssl->session_negotiate->id[0], p, legacy_session_id_len);
|
||||
p += legacy_session_id_len;
|
||||
|
||||
/* ...
|
||||
* CipherSuite cipher_suites<2..2^16-2>;
|
||||
* ...
|
||||
* with CipherSuite defined as:
|
||||
* uint8 CipherSuite[2];
|
||||
*/
|
||||
cipher_suites_len = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
p += 2;
|
||||
cipher_suites = p;
|
||||
|
||||
/*
|
||||
* The length of the ciphersuite list has to be even.
|
||||
|
@ -1358,33 +1352,95 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
* extensions_len 2 bytes
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cipher_suites_len + 2 + 2);
|
||||
p += cipher_suites_len;
|
||||
cipher_suites_end = p;
|
||||
|
||||
/* ...
|
||||
* CipherSuite cipher_suites<2..2^16-2>;
|
||||
* ...
|
||||
* with CipherSuite defined as:
|
||||
* uint8 CipherSuite[2];
|
||||
/*
|
||||
* Search for the supported versions extension and parse it to determine
|
||||
* if the client supports TLS 1.3.
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
cipher_suites = p;
|
||||
ret = mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts(
|
||||
ssl, p + 2, end,
|
||||
&supported_versions_data, &supported_versions_data_end);
|
||||
if (ret < 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
("mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
return SSL_CLIENT_HELLO_TLS1_2;
|
||||
}
|
||||
|
||||
if (ret == 1) {
|
||||
ret = ssl_tls13_parse_supported_versions_ext(ssl,
|
||||
supported_versions_data,
|
||||
supported_versions_data_end);
|
||||
if (ret < 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
("ssl_tls13_parse_supported_versions_ext"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The supported versions extension was parsed successfully as the
|
||||
* value returned by ssl_tls13_parse_supported_versions_ext() is
|
||||
* positive. The return value is then equal to
|
||||
* MBEDTLS_SSL_VERSION_TLS1_2 or MBEDTLS_SSL_VERSION_TLS1_3, defining
|
||||
* the TLS version to negotiate.
|
||||
*/
|
||||
if (MBEDTLS_SSL_VERSION_TLS1_2 == ret) {
|
||||
return SSL_CLIENT_HELLO_TLS1_2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We negotiate TLS 1.3.
|
||||
*/
|
||||
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
/* Store minor version for later use with ticket serialization. */
|
||||
ssl->session_negotiate->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
ssl->session_negotiate->endpoint = ssl->conf->endpoint;
|
||||
#endif
|
||||
cipher_suites_end = p + cipher_suites_len;
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, ciphersuitelist",
|
||||
p, cipher_suites_len);
|
||||
|
||||
/*
|
||||
* We are negotiating the version 1.3 of the protocol. Do what we have
|
||||
* postponed: copy of the client random bytes, copy of the legacy session
|
||||
* identifier and selection of the TLS 1.3 cipher suite.
|
||||
*/
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes",
|
||||
random, MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
|
||||
memcpy(&handshake->randbytes[0], random, MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
|
||||
|
||||
if (legacy_session_id_len > sizeof(ssl->session_negotiate->id)) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
|
||||
return MBEDTLS_ERR_SSL_DECODE_ERROR;
|
||||
}
|
||||
ssl->session_negotiate->id_len = legacy_session_id_len;
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id",
|
||||
legacy_session_id, legacy_session_id_len);
|
||||
memcpy(&ssl->session_negotiate->id[0],
|
||||
legacy_session_id, legacy_session_id_len);
|
||||
|
||||
/*
|
||||
* Search for a matching ciphersuite
|
||||
*/
|
||||
for (; p < cipher_suites_end; p += 2) {
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, list of cipher suites",
|
||||
cipher_suites, cipher_suites_len);
|
||||
for (const unsigned char *cipher_suites_p = cipher_suites;
|
||||
cipher_suites_p < cipher_suites_end; cipher_suites_p += 2) {
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
/*
|
||||
* "cipher_suite_end - p is even" is an invariant of the loop. As
|
||||
* cipher_suites_end - p > 0, we have cipher_suites_end - p >= 2 and
|
||||
* it is thus safe to read two bytes.
|
||||
* "cipher_suites_end - cipher_suites_p is even" is an invariant of the
|
||||
* loop. As cipher_suites_end - cipher_suites_p > 0, we have
|
||||
* cipher_suites_end - cipher_suites_p >= 2 and it is thus safe to read
|
||||
* two bytes.
|
||||
*/
|
||||
cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
cipher_suite = MBEDTLS_GET_UINT16_BE(cipher_suites_p, 0);
|
||||
ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(
|
||||
ssl, cipher_suite);
|
||||
if (ciphersuite_info == NULL) {
|
||||
|
@ -1404,7 +1460,6 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
p = cipher_suites_end;
|
||||
|
||||
/* ...
|
||||
* opaque legacy_compression_methods<1..2^8-1>;
|
||||
|
@ -1433,7 +1488,6 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
extensions_end = p + extensions_len;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", p, extensions_len);
|
||||
|
||||
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
|
||||
|
||||
while (p < extensions_end) {
|
||||
|
@ -1499,8 +1553,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
ret = ssl_tls13_parse_supported_groups_ext(
|
||||
ssl, p, extension_data_end);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
"mbedtls_ssl_parse_supported_groups_ext", ret);
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "ssl_tls13_parse_supported_groups_ext", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1535,20 +1589,13 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
#endif /* PSA_WANT_ALG_ECDH */
|
||||
|
||||
case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS:
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("found supported versions extension"));
|
||||
|
||||
ret = ssl_tls13_parse_supported_versions_ext(
|
||||
ssl, p, extension_data_end);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
("ssl_tls13_parse_supported_versions_ext"), ret);
|
||||
return ret;
|
||||
}
|
||||
/* Already parsed */
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
case MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES:
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("found psk key exchange modes extension"));
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ("found psk key exchange modes extension"));
|
||||
|
||||
ret = ssl_tls13_parse_key_exchange_modes_ext(
|
||||
ssl, p, extension_data_end);
|
||||
|
@ -1600,10 +1647,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
ret = mbedtls_ssl_parse_sig_alg_ext(
|
||||
ssl, p, extension_data_end);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1,
|
||||
(
|
||||
"ssl_parse_supported_signature_algorithms_server_ext ( %d )",
|
||||
ret));
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "mbedtls_ssl_parse_sig_alg_ext", ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
@ -1613,10 +1658,14 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT:
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("found record_size_limit extension"));
|
||||
|
||||
ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(ssl, p, extension_data_end);
|
||||
ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(
|
||||
ssl, p, extension_data_end);
|
||||
|
||||
/* TODO: Return unconditionally here until we handle the record size limit correctly.
|
||||
* Once handled correctly, only return in case of errors. */
|
||||
/*
|
||||
* TODO: Return unconditionally here until we handle the record
|
||||
* size limit correctly.
|
||||
* Once handled correctly, only return in case of errors.
|
||||
*/
|
||||
return ret;
|
||||
|
||||
break;
|
||||
|
@ -1741,15 +1790,27 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_parse_client_hello(ssl, buf,
|
||||
buf + buflen));
|
||||
parse_client_hello_ret = ret; /* Store return value of parse_client_hello,
|
||||
* only SSL_CLIENT_HELLO_OK or
|
||||
* SSL_CLIENT_HELLO_HRR_REQUIRED at this
|
||||
* stage as negative error codes are handled
|
||||
parse_client_hello_ret = ret; /* Store positive return value of
|
||||
* parse_client_hello,
|
||||
* as negative error codes are handled
|
||||
* by MBEDTLS_SSL_PROC_CHK_NEG. */
|
||||
|
||||
/*
|
||||
* Version 1.2 of the protocol has been chosen, set the
|
||||
* ssl->keep_current_message flag for the ClientHello to be kept and parsed
|
||||
* as a TLS 1.2 ClientHello. We also change ssl->tls_version to
|
||||
* MBEDTLS_SSL_VERSION_TLS1_2 thus from now on mbedtls_ssl_handshake_step()
|
||||
* will dispatch to the TLS 1.2 state machine.
|
||||
*/
|
||||
if (SSL_CLIENT_HELLO_TLS1_2 == parse_client_hello_ret) {
|
||||
ssl->keep_current_message = 1;
|
||||
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_client_hello(ssl));
|
||||
|
||||
if (parse_client_hello_ret == SSL_CLIENT_HELLO_OK) {
|
||||
if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
|
||||
} else {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HELLO_RETRY_REQUEST);
|
||||
|
@ -2182,9 +2243,8 @@ static int ssl_tls13_write_server_hello(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_prepare_server_hello(ssl));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_SERVER_HELLO, &buf,
|
||||
&buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, &buf, &buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_server_hello_body(ssl, buf,
|
||||
buf + buf_len,
|
||||
|
@ -2356,15 +2416,16 @@ static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write encrypted extensions"));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, &buf,
|
||||
&buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||
&buf, &buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_encrypted_extensions_body(
|
||||
ssl, buf, buf + buf_len, &msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, msg_len));
|
||||
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||
buf, msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
|
||||
ssl, buf_len, msg_len));
|
||||
|
@ -2489,15 +2550,16 @@ static int ssl_tls13_write_certificate_request(mbedtls_ssl_context *ssl)
|
|||
unsigned char *buf;
|
||||
size_t buf_len, msg_len;
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||
&buf, &buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||
&buf, &buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_request_body(
|
||||
ssl, buf, buf + buf_len, &msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, buf, msg_len));
|
||||
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||
buf, msg_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(
|
||||
ssl, buf_len, msg_len));
|
||||
|
@ -2608,8 +2670,8 @@ static int ssl_tls13_process_client_finished(mbedtls_ssl_context *ssl)
|
|||
|
||||
ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
"mbedtls_ssl_tls13_compute_resumption_master_secret", ret);
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "mbedtls_ssl_tls13_compute_resumption_master_secret", ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP);
|
||||
|
@ -2634,7 +2696,8 @@ static int ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl)
|
|||
*/
|
||||
/* Sent NewSessionTicket message only when client supports PSK */
|
||||
if (mbedtls_ssl_tls13_some_psk_enabled(ssl)) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
|
||||
mbedtls_ssl_handshake_set_state(
|
||||
ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -2897,9 +2960,9 @@ static int ssl_tls13_write_new_session_ticket(mbedtls_ssl_context *ssl)
|
|||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_prepare_new_session_ticket(
|
||||
ssl, ticket_nonce, sizeof(ticket_nonce)));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl,
|
||||
MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
|
||||
&buf, &buf_len));
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
|
||||
ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
|
||||
&buf, &buf_len));
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_new_session_ticket_body(
|
||||
ssl, buf, buf + buf_len, &msg_len,
|
||||
|
@ -3067,7 +3130,8 @@ int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl)
|
|||
if (ssl->handshake->new_session_tickets_count == 0) {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
|
||||
} else {
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
|
||||
mbedtls_ssl_handshake_set_state(
|
||||
ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -1201,53 +1201,19 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* SubjectAltName ::= GeneralNames
|
||||
/* Check mbedtls_x509_get_subject_alt_name for detailed description.
|
||||
*
|
||||
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
*
|
||||
* GeneralName ::= CHOICE {
|
||||
* otherName [0] OtherName,
|
||||
* rfc822Name [1] IA5String,
|
||||
* dNSName [2] IA5String,
|
||||
* x400Address [3] ORAddress,
|
||||
* directoryName [4] Name,
|
||||
* ediPartyName [5] EDIPartyName,
|
||||
* uniformResourceIdentifier [6] IA5String,
|
||||
* iPAddress [7] OCTET STRING,
|
||||
* registeredID [8] OBJECT IDENTIFIER }
|
||||
*
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
*
|
||||
* EDIPartyName ::= SEQUENCE {
|
||||
* nameAssigner [0] DirectoryString OPTIONAL,
|
||||
* partyName [1] DirectoryString }
|
||||
*
|
||||
* We list all types, but use the following GeneralName types from RFC 5280:
|
||||
* "dnsName", "uniformResourceIdentifier" and "hardware_module_name"
|
||||
* of type "otherName", as defined in RFC 4108.
|
||||
* In some cases while parsing subject alternative names the sequence tag is optional
|
||||
* (e.g. CertSerialNumber). This function is designed to handle such case.
|
||||
*/
|
||||
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 ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len, tag_len;
|
||||
size_t tag_len;
|
||||
mbedtls_asn1_sequence *cur = subject_alt_name;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (*p + len != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
while (*p < end) {
|
||||
mbedtls_x509_subject_alternative_name dummy_san_buf;
|
||||
mbedtls_x509_buf tmp_san_buf;
|
||||
|
@ -1315,6 +1281,55 @@ int mbedtls_x509_get_subject_alt_name(unsigned char **p,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* SubjectAltName ::= GeneralNames
|
||||
*
|
||||
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
*
|
||||
* GeneralName ::= CHOICE {
|
||||
* otherName [0] OtherName,
|
||||
* rfc822Name [1] IA5String,
|
||||
* dNSName [2] IA5String,
|
||||
* x400Address [3] ORAddress,
|
||||
* directoryName [4] Name,
|
||||
* ediPartyName [5] EDIPartyName,
|
||||
* uniformResourceIdentifier [6] IA5String,
|
||||
* iPAddress [7] OCTET STRING,
|
||||
* registeredID [8] OBJECT IDENTIFIER }
|
||||
*
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
*
|
||||
* EDIPartyName ::= SEQUENCE {
|
||||
* nameAssigner [0] DirectoryString OPTIONAL,
|
||||
* partyName [1] DirectoryString }
|
||||
*
|
||||
* We list all types, but use the following GeneralName types from RFC 5280:
|
||||
* "dnsName", "uniformResourceIdentifier" and "hardware_module_name"
|
||||
* of type "otherName", as defined in RFC 4108.
|
||||
*/
|
||||
int mbedtls_x509_get_subject_alt_name(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_sequence *subject_alt_name)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (*p + len != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return mbedtls_x509_get_subject_alt_name_ext(p, end, subject_alt_name);
|
||||
}
|
||||
|
||||
int mbedtls_x509_get_ns_cert_type(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned char *ns_cert_type)
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "mbedtls/psa_util.h"
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
#include "hash_info.h"
|
||||
#include "x509_invasive.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
|
@ -58,6 +59,10 @@
|
|||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
|
@ -101,7 +106,7 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
|
|||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
|
||||
0xFFFFFFF, /* Any PK alg */
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/* Curves at or above 128-bit security level. Note that this selection
|
||||
* should be aligned with ssl_preset_default_curves in ssl_tls.c. */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
|
||||
|
@ -111,9 +116,9 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
|
|||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP384R1) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP512R1) |
|
||||
0,
|
||||
#else
|
||||
#else /* MBEDTLS_ECP_LIGHT */
|
||||
0,
|
||||
#endif
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
2048,
|
||||
};
|
||||
|
||||
|
@ -152,13 +157,13 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
|
|||
/* Only ECDSA */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY),
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/* Only NIST P-256 and P-384 */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
|
||||
#else
|
||||
#else /* MBEDTLS_ECP_LIGHT */
|
||||
0,
|
||||
#endif
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
0,
|
||||
};
|
||||
|
||||
|
@ -226,9 +231,9 @@ static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile,
|
|||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
if (pk_alg == MBEDTLS_PK_ECDSA ||
|
||||
pk_alg == MBEDTLS_PK_ECKEY ||
|
||||
pk_alg == MBEDTLS_PK_ECKEY_DH) {
|
||||
|
@ -244,7 +249,7 @@ static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile,
|
|||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#endif /* MBEDTLS_ECP_LIGHT */
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -586,6 +591,114 @@ static int x509_get_ext_key_usage(unsigned char **p,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* SubjectKeyIdentifier ::= KeyIdentifier
|
||||
*
|
||||
* KeyIdentifier ::= OCTET STRING
|
||||
*/
|
||||
static int x509_get_subject_key_id(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_buf *subject_key_id)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0u;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_OCTET_STRING)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
subject_key_id->len = len;
|
||||
subject_key_id->tag = MBEDTLS_ASN1_OCTET_STRING;
|
||||
subject_key_id->p = *p;
|
||||
*p += len;
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AuthorityKeyIdentifier ::= SEQUENCE {
|
||||
* keyIdentifier [0] KeyIdentifier OPTIONAL,
|
||||
* authorityCertIssuer [1] GeneralNames OPTIONAL,
|
||||
* authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
|
||||
*
|
||||
* KeyIdentifier ::= OCTET STRING
|
||||
*/
|
||||
static int x509_get_authority_key_id(unsigned char **p,
|
||||
unsigned char *end,
|
||||
mbedtls_x509_authority *authority_key_id)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0u;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (*p + len != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC);
|
||||
|
||||
/* KeyIdentifier is an OPTIONAL field */
|
||||
if (ret == 0) {
|
||||
authority_key_id->keyIdentifier.len = len;
|
||||
authority_key_id->keyIdentifier.p = *p;
|
||||
/* Setting tag of the keyIdentfier intentionally to 0x04.
|
||||
* Although the .keyIdentfier field is CONTEXT_SPECIFIC ([0] OPTIONAL),
|
||||
* its tag with the content is the payload of on OCTET STRING primitive */
|
||||
authority_key_id->keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING;
|
||||
|
||||
*p += len;
|
||||
} else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (*p < end) {
|
||||
/* Getting authorityCertIssuer using the required specific class tag [1] */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
|
||||
1)) != 0) {
|
||||
/* authorityCertIssuer and authorityCertSerialNumber MUST both
|
||||
be present or both be absent. At this point we expect to have both. */
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
/* "end" also includes the CertSerialNumber field so "len" shall be used */
|
||||
ret = mbedtls_x509_get_subject_alt_name_ext(p,
|
||||
(*p+len),
|
||||
&authority_key_id->authorityCertIssuer);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Getting authorityCertSerialNumber using the required specific class tag [2] */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
authority_key_id->authorityCertSerialNumber.len = len;
|
||||
authority_key_id->authorityCertSerialNumber.p = *p;
|
||||
authority_key_id->authorityCertSerialNumber.tag = MBEDTLS_ASN1_INTEGER;
|
||||
*p += len;
|
||||
}
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
|
||||
*
|
||||
|
@ -884,8 +997,25 @@ static int x509_get_crt_ext(unsigned char **p,
|
|||
}
|
||||
break;
|
||||
|
||||
case MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER:
|
||||
/* Parse subject key identifier */
|
||||
if ((ret = x509_get_subject_key_id(p, end_ext_data,
|
||||
&crt->subject_key_id)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER:
|
||||
/* Parse authority key identifier */
|
||||
if ((ret = x509_get_authority_key_id(p, end_ext_octet,
|
||||
&crt->authority_key_id)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
|
||||
/* Parse subject alt name */
|
||||
/* Parse subject alt name
|
||||
* SubjectAltName ::= GeneralNames
|
||||
*/
|
||||
if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_octet,
|
||||
&crt->subject_alt_names)) != 0) {
|
||||
return ret;
|
||||
|
@ -1545,6 +1675,27 @@ cleanup:
|
|||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
#define PRINT_ITEM(i) \
|
||||
do { \
|
||||
ret = mbedtls_snprintf(p, n, "%s" i, sep); \
|
||||
MBEDTLS_X509_SAFE_SNPRINTF; \
|
||||
sep = ", "; \
|
||||
} while (0)
|
||||
|
||||
#define CERT_TYPE(type, name) \
|
||||
do { \
|
||||
if (ns_cert_type & (type)) { \
|
||||
PRINT_ITEM(name); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define KEY_USAGE(code, name) \
|
||||
do { \
|
||||
if (key_usage & (code)) { \
|
||||
PRINT_ITEM(name); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int x509_info_ext_key_usage(char **buf, size_t *size,
|
||||
const mbedtls_x509_sequence *extended_key_usage)
|
||||
{
|
||||
|
@ -2524,6 +2675,194 @@ find_parent:
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#elif (defined(__MINGW32__) || defined(__MINGW64__)) && _WIN32_WINNT >= 0x0600
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#elif defined(__sun)
|
||||
/* Solaris requires -lsocket -lnsl for inet_pton() */
|
||||
#elif defined(__has_include)
|
||||
#if __has_include(<sys/socket.h>)
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#if __has_include(<arpa/inet.h>)
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use whether or not AF_INET6 is defined to indicate whether or not to use
|
||||
* the platform inet_pton() or a local implementation (below). The local
|
||||
* implementation may be used even in cases where the platform provides
|
||||
* inet_pton(), e.g. when there are different includes required and/or the
|
||||
* platform implementation requires dependencies on additional libraries.
|
||||
* Specifically, Windows requires custom includes and additional link
|
||||
* dependencies, and Solaris requires additional link dependencies.
|
||||
* Also, as a coarse heuristic, use the local implementation if the compiler
|
||||
* does not support __has_include(), or if the definition of AF_INET6 is not
|
||||
* provided by headers included (or not) via __has_include() above.
|
||||
* MBEDTLS_TEST_SW_INET_PTON is a bypass define to force testing of this code //no-check-names
|
||||
* despite having a platform that has inet_pton. */
|
||||
#if !defined(AF_INET6) || defined(MBEDTLS_TEST_SW_INET_PTON) //no-check-names
|
||||
/* Definition located further below to possibly reduce compiler inlining */
|
||||
static int x509_inet_pton_ipv4(const char *src, void *dst);
|
||||
|
||||
#define li_cton(c, n) \
|
||||
(((n) = (c) - '0') <= 9 || (((n) = ((c)&0xdf) - 'A') <= 5 ? ((n) += 10) : 0))
|
||||
|
||||
static int x509_inet_pton_ipv6(const char *src, void *dst)
|
||||
{
|
||||
const unsigned char *p = (const unsigned char *) src;
|
||||
int nonzero_groups = 0, num_digits, zero_group_start = -1;
|
||||
uint16_t addr[8];
|
||||
do {
|
||||
/* note: allows excess leading 0's, e.g. 1:0002:3:... */
|
||||
uint16_t group = num_digits = 0;
|
||||
for (uint8_t digit; num_digits < 4; num_digits++) {
|
||||
if (li_cton(*p, digit) == 0) {
|
||||
break;
|
||||
}
|
||||
group = (group << 4) | digit;
|
||||
p++;
|
||||
}
|
||||
if (num_digits != 0) {
|
||||
addr[nonzero_groups++] = MBEDTLS_IS_BIG_ENDIAN ? group :
|
||||
(group << 8) | (group >> 8);
|
||||
if (*p == '\0') {
|
||||
break;
|
||||
} else if (*p == '.') {
|
||||
/* Don't accept IPv4 too early or late */
|
||||
if ((nonzero_groups == 0 && zero_group_start == -1) ||
|
||||
nonzero_groups >= 7) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Walk back to prior ':', then parse as IPv4-mapped */
|
||||
int steps = 4;
|
||||
do {
|
||||
p--;
|
||||
steps--;
|
||||
} while (*p != ':' && steps > 0);
|
||||
|
||||
if (*p != ':') {
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
nonzero_groups--;
|
||||
if (x509_inet_pton_ipv4((const char *) p,
|
||||
addr + nonzero_groups) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
nonzero_groups += 2;
|
||||
p = (const unsigned char *) "";
|
||||
break;
|
||||
} else if (*p != ':') {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Don't accept a second zero group or an invalid delimiter */
|
||||
if (zero_group_start != -1 || *p != ':') {
|
||||
return -1;
|
||||
}
|
||||
zero_group_start = nonzero_groups;
|
||||
|
||||
/* Accept a zero group at start, but it has to be a double colon */
|
||||
if (zero_group_start == 0 && *++p != ':') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p[1] == '\0') {
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++p;
|
||||
} while (nonzero_groups < 8);
|
||||
|
||||
if (*p != '\0') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zero_group_start != -1) {
|
||||
if (nonzero_groups > 6) {
|
||||
return -1;
|
||||
}
|
||||
int zero_groups = 8 - nonzero_groups;
|
||||
int groups_after_zero = nonzero_groups - zero_group_start;
|
||||
|
||||
/* Move the non-zero part to after the zeroes */
|
||||
if (groups_after_zero) {
|
||||
memmove(addr + zero_group_start + zero_groups,
|
||||
addr + zero_group_start,
|
||||
groups_after_zero * sizeof(*addr));
|
||||
}
|
||||
memset(addr + zero_group_start, 0, zero_groups * sizeof(*addr));
|
||||
} else {
|
||||
if (nonzero_groups != 8) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
memcpy(dst, addr, sizeof(addr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int x509_inet_pton_ipv4(const char *src, void *dst)
|
||||
{
|
||||
/* note: allows leading 0's, e.g. 000.000.000.000 */
|
||||
const unsigned char *p = (const unsigned char *) src;
|
||||
uint8_t *res = (uint8_t *) dst;
|
||||
uint8_t digit, num_digits = 0;
|
||||
uint8_t num_octets = 0;
|
||||
uint16_t octet;
|
||||
|
||||
do {
|
||||
octet = num_digits = 0;
|
||||
do {
|
||||
digit = *p - '0';
|
||||
if (digit > 9) {
|
||||
break;
|
||||
}
|
||||
octet = octet * 10 + digit;
|
||||
num_digits++;
|
||||
p++;
|
||||
} while (num_digits < 3);
|
||||
|
||||
if (octet >= 256 || num_digits > 3 || num_digits == 0) {
|
||||
break;
|
||||
}
|
||||
*res++ = (uint8_t) octet;
|
||||
num_octets++;
|
||||
} while (num_octets < 4 && *p++ == '.');
|
||||
return num_octets == 4 && *p == '\0' ? 0 : -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int x509_inet_pton_ipv6(const char *src, void *dst)
|
||||
{
|
||||
return inet_pton(AF_INET6, src, dst) == 1 ? 0 : -1;
|
||||
}
|
||||
|
||||
static int x509_inet_pton_ipv4(const char *src, void *dst)
|
||||
{
|
||||
return inet_pton(AF_INET, src, dst) == 1 ? 0 : -1;
|
||||
}
|
||||
|
||||
#endif /* !AF_INET6 || MBEDTLS_TEST_SW_INET_PTON */ //no-check-names
|
||||
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst)
|
||||
{
|
||||
return strchr(cn, ':') == NULL
|
||||
? x509_inet_pton_ipv4(cn, dst) == 0 ? 4 : 0
|
||||
: x509_inet_pton_ipv6(cn, dst) == 0 ? 16 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for CN match
|
||||
*/
|
||||
|
@ -2544,24 +2883,51 @@ static int x509_crt_check_cn(const mbedtls_x509_buf *name,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int x509_crt_check_san_ip(const mbedtls_x509_sequence *san,
|
||||
const char *cn, size_t cn_len)
|
||||
{
|
||||
uint32_t ip[4];
|
||||
cn_len = mbedtls_x509_crt_parse_cn_inet_pton(cn, ip);
|
||||
if (cn_len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
|
||||
const unsigned char san_type = (unsigned char) cur->buf.tag &
|
||||
MBEDTLS_ASN1_TAG_VALUE_MASK;
|
||||
if (san_type == MBEDTLS_X509_SAN_IP_ADDRESS &&
|
||||
cur->buf.len == cn_len && memcmp(cur->buf.p, ip, cn_len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for SAN match, see RFC 5280 Section 4.2.1.6
|
||||
*/
|
||||
static int x509_crt_check_san(const mbedtls_x509_buf *name,
|
||||
static int x509_crt_check_san(const mbedtls_x509_sequence *san,
|
||||
const char *cn, size_t cn_len)
|
||||
{
|
||||
const unsigned char san_type = (unsigned char) name->tag &
|
||||
MBEDTLS_ASN1_TAG_VALUE_MASK;
|
||||
|
||||
/* dNSName */
|
||||
if (san_type == MBEDTLS_X509_SAN_DNS_NAME) {
|
||||
return x509_crt_check_cn(name, cn, cn_len);
|
||||
int san_ip = 0;
|
||||
for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
|
||||
switch ((unsigned char) cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) {
|
||||
case MBEDTLS_X509_SAN_DNS_NAME: /* dNSName */
|
||||
if (x509_crt_check_cn(&cur->buf, cn, cn_len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case MBEDTLS_X509_SAN_IP_ADDRESS: /* iPAddress */
|
||||
san_ip = 1;
|
||||
break;
|
||||
/* (We may handle other types here later.) */
|
||||
default: /* Unrecognized type */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* (We may handle other types here later.) */
|
||||
|
||||
/* Unrecognized type */
|
||||
return -1;
|
||||
return san_ip ? x509_crt_check_san_ip(san, cn, cn_len) : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2572,31 +2938,23 @@ static void x509_crt_verify_name(const mbedtls_x509_crt *crt,
|
|||
uint32_t *flags)
|
||||
{
|
||||
const mbedtls_x509_name *name;
|
||||
const mbedtls_x509_sequence *cur;
|
||||
size_t cn_len = strlen(cn);
|
||||
|
||||
if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
|
||||
for (cur = &crt->subject_alt_names; cur != NULL; cur = cur->next) {
|
||||
if (x509_crt_check_san(&cur->buf, cn, cn_len) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur == NULL) {
|
||||
*flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
|
||||
if (x509_crt_check_san(&crt->subject_alt_names, cn, cn_len) == 0) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
for (name = &crt->subject; name != NULL; name = name->next) {
|
||||
if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0 &&
|
||||
x509_crt_check_cn(&name->val, cn, cn_len) == 0) {
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
*flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
*flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
53
library/x509_invasive.h
Normal file
53
library/x509_invasive.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* \file x509_invasive.h
|
||||
*
|
||||
* \brief x509 module: interfaces for invasive testing only.
|
||||
*
|
||||
* The interfaces in this file are intended for testing purposes only.
|
||||
* They SHOULD NOT be made available in library integrations except when
|
||||
* building the library for testing.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_X509_INVASIVE_H
|
||||
#define MBEDTLS_X509_INVASIVE_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
|
||||
/**
|
||||
* \brief This function parses a CN string as an IP address.
|
||||
*
|
||||
* \param cn The CN string to parse. CN string MUST be NUL-terminated.
|
||||
* \param dst The target buffer to populate with the binary IP address.
|
||||
* The buffer MUST be 16 bytes to save IPv6, and should be
|
||||
* 4-byte aligned if the result will be used as struct in_addr.
|
||||
* e.g. uint32_t dst[4]
|
||||
*
|
||||
* \note \cn is parsed as an IPv6 address if string contains ':',
|
||||
* else \cn is parsed as an IPv4 address.
|
||||
*
|
||||
* \return Length of binary IP address; num bytes written to target.
|
||||
* \return \c 0 on failure to parse CN string as an IP address.
|
||||
*/
|
||||
size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst);
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#endif /* MBEDTLS_X509_INVASIVE_H */
|
|
@ -78,6 +78,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
mbedtls_entropy_init(&entropy);
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy,
|
||||
(const unsigned char *) pers, strlen(pers)) != 0) {
|
||||
goto exit;
|
||||
|
@ -175,6 +182,9 @@ exit:
|
|||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_ssl_config_free(&conf);
|
||||
mbedtls_ssl_free(&ssl);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#else
|
||||
(void) Data;
|
||||
|
|
|
@ -61,6 +61,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
mbedtls_entropy_init(&entropy);
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
srand(1);
|
||||
if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy,
|
||||
(const unsigned char *) pers, strlen(pers)) != 0) {
|
||||
|
@ -119,6 +126,9 @@ exit:
|
|||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_ssl_config_free(&conf);
|
||||
mbedtls_ssl_free(&ssl);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#else
|
||||
(void) Data;
|
||||
|
|
|
@ -50,6 +50,20 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
mbedtls_entropy_init(&entropy);
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_x509_crt_init(&srvcert);
|
||||
mbedtls_pk_init(&pkey);
|
||||
#endif
|
||||
mbedtls_ssl_init(&ssl);
|
||||
mbedtls_ssl_config_init(&conf);
|
||||
mbedtls_ssl_cookie_init(&cookie_ctx);
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy,
|
||||
(const unsigned char *) pers, strlen(pers)) != 0) {
|
||||
|
@ -58,8 +72,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
|
||||
if (initialized == 0) {
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_x509_crt_init(&srvcert);
|
||||
mbedtls_pk_init(&pkey);
|
||||
|
||||
if (mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_srv_crt,
|
||||
mbedtls_test_srv_crt_len) != 0) {
|
||||
return 1;
|
||||
|
@ -78,9 +91,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
|
||||
initialized = 1;
|
||||
}
|
||||
mbedtls_ssl_init(&ssl);
|
||||
mbedtls_ssl_config_init(&conf);
|
||||
mbedtls_ssl_cookie_init(&cookie_ctx);
|
||||
|
||||
if (mbedtls_ssl_config_defaults(&conf,
|
||||
MBEDTLS_SSL_IS_SERVER,
|
||||
|
@ -154,9 +164,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
exit:
|
||||
mbedtls_ssl_cookie_free(&cookie_ctx);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pk_free(&pkey);
|
||||
mbedtls_x509_crt_free(&srvcert);
|
||||
#endif
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_ssl_config_free(&conf);
|
||||
mbedtls_ssl_free(&ssl);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#else
|
||||
(void) Data;
|
||||
|
|
|
@ -30,13 +30,20 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
mbedtls_entropy_init(&entropy);
|
||||
mbedtls_pk_init(&pk);
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy,
|
||||
(const unsigned char *) pers, strlen(pers)) != 0) {
|
||||
return 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_pk_init(&pk);
|
||||
ret = mbedtls_pk_parse_key(&pk, Data, Size, NULL, 0,
|
||||
dummy_random, &ctr_drbg);
|
||||
if (ret == 0) {
|
||||
|
@ -83,7 +90,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
abort();
|
||||
}
|
||||
}
|
||||
exit:
|
||||
mbedtls_entropy_free(&entropy);
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_pk_free(&pk);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
#else
|
||||
(void) Data;
|
||||
(void) Size;
|
||||
|
|
|
@ -11,6 +11,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
mbedtls_pk_context pk;
|
||||
|
||||
mbedtls_pk_init(&pk);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
ret = mbedtls_pk_parse_public_key(&pk, Data, Size);
|
||||
if (ret == 0) {
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
|
@ -66,6 +72,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
abort();
|
||||
}
|
||||
}
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
exit:
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
mbedtls_pk_free(&pk);
|
||||
#else
|
||||
(void) Data;
|
||||
|
|
|
@ -58,6 +58,21 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
mbedtls_entropy_init(&entropy);
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_x509_crt_init(&srvcert);
|
||||
mbedtls_pk_init(&pkey);
|
||||
#endif
|
||||
mbedtls_ssl_init(&ssl);
|
||||
mbedtls_ssl_config_init(&conf);
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C)
|
||||
mbedtls_ssl_ticket_init(&ticket_ctx);
|
||||
#endif
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy,
|
||||
(const unsigned char *) pers, strlen(pers)) != 0) {
|
||||
|
@ -67,8 +82,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
if (initialized == 0) {
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_x509_crt_init(&srvcert);
|
||||
mbedtls_pk_init(&pkey);
|
||||
if (mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_srv_crt,
|
||||
mbedtls_test_srv_crt_len) != 0) {
|
||||
return 1;
|
||||
|
@ -92,11 +105,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
|
||||
initialized = 1;
|
||||
}
|
||||
mbedtls_ssl_init(&ssl);
|
||||
mbedtls_ssl_config_init(&conf);
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C)
|
||||
mbedtls_ssl_ticket_init(&ticket_ctx);
|
||||
#endif
|
||||
|
||||
if (mbedtls_ssl_config_defaults(&conf,
|
||||
MBEDTLS_SSL_IS_SERVER,
|
||||
|
@ -193,8 +201,14 @@ exit:
|
|||
mbedtls_entropy_free(&entropy);
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_ssl_config_free(&conf);
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_x509_crt_free(&srvcert);
|
||||
mbedtls_pk_free(&pkey);
|
||||
#endif
|
||||
mbedtls_ssl_free(&ssl);
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif
|
||||
#else
|
||||
(void) Data;
|
||||
(void) Size;
|
||||
|
|
|
@ -11,6 +11,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
unsigned char buf[4096];
|
||||
|
||||
mbedtls_x509_crl_init(&crl);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
ret = mbedtls_x509_crl_parse(&crl, Data, Size);
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
if (ret == 0) {
|
||||
|
@ -20,6 +26,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
((void) ret);
|
||||
((void) buf);
|
||||
#endif /* !MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
exit:
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
mbedtls_x509_crl_free(&crl);
|
||||
#else
|
||||
(void) Data;
|
||||
|
|
|
@ -11,6 +11,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
unsigned char buf[4096];
|
||||
|
||||
mbedtls_x509_crt_init(&crt);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
ret = mbedtls_x509_crt_parse(&crt, Data, Size);
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
if (ret == 0) {
|
||||
|
@ -20,6 +26,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
((void) ret);
|
||||
((void) buf);
|
||||
#endif /* !MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
exit:
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
#else
|
||||
(void) Data;
|
||||
|
|
|
@ -11,6 +11,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
unsigned char buf[4096];
|
||||
|
||||
mbedtls_x509_csr_init(&csr);
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
ret = mbedtls_x509_csr_parse(&csr, Data, Size);
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
if (ret == 0) {
|
||||
|
@ -20,6 +26,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
|||
((void) ret);
|
||||
((void) buf);
|
||||
#endif /* !MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
exit:
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
mbedtls_x509_csr_free(&csr);
|
||||
#else
|
||||
(void) Data;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
/* md.h is included this early since MD_CAN_XXX macros are defined there. */
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \
|
||||
defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \
|
||||
|
@ -45,13 +47,13 @@
|
|||
!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_SHA1_C)
|
||||
int main(void)
|
||||
{
|
||||
mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C "
|
||||
"and/or MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
|
||||
"MBEDTLS_MD_CAN_SHA256 and/or MBEDTLS_FS_IO and/or "
|
||||
"MBEDTLS_CTR_DRBG_C not defined.\n");
|
||||
"MBEDTLS_CTR_DRBG_C and/or MBEDTLS_SHA1_C not defined.\n");
|
||||
mbedtls_exit(0);
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
/* md.h is included this early since MD_CAN_XXX macros are defined there. */
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \
|
||||
defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \
|
||||
|
@ -45,13 +47,13 @@
|
|||
!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_SHA1_C)
|
||||
int main(void)
|
||||
{
|
||||
mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C "
|
||||
"and/or MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
|
||||
"MBEDTLS_MD_CAN_SHA256 and/or MBEDTLS_FS_IO and/or "
|
||||
"MBEDTLS_CTR_DRBG_C not defined.\n");
|
||||
"MBEDTLS_CTR_DRBG_C and/or MBEDTLS_SHA1_C not defined.\n");
|
||||
mbedtls_exit(0);
|
||||
}
|
||||
#else
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue