Merge remote-tracking branch 'origin/development' into prefer-intrinsics

This commit is contained in:
Dave Rodgman 2023-06-16 17:46:16 +01:00
commit e1dd6e9e8f
391 changed files with 15151 additions and 5893 deletions

3
.gitignore vendored
View file

@ -60,3 +60,6 @@ massif-*
/TAGS
/cscope*.out
/tags
# Clangd compilation database
compile_commands.json

View file

@ -12,7 +12,7 @@ build:
python: "3.9"
jobs:
pre_build:
- make apidoc
- ./scripts/apidoc_full.sh
- breathe-apidoc -o docs/api apidoc/xml
post_build:
- |

View file

@ -1,6 +1,7 @@
/*
* Implementation of curve P-256 (ECDH and ECDSA)
*
* Copyright The Mbed TLS Contributors
* Author: Manuel Pégourié-Gonnard.
* SPDX-License-Identifier: Apache-2.0
*/

View file

@ -1,6 +1,7 @@
/*
* Interface of curve P-256 (ECDH and ECDSA)
*
* Copyright The Mbed TLS Contributors
* Author: Manuel Pégourié-Gonnard.
* SPDX-License-Identifier: Apache-2.0
*/

View file

@ -0,0 +1,4 @@
Features
* Add support to restrict AES to 128-bit keys in order to save code size.
A new configuration option, MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH, can be
used to enable this feature.

View file

@ -0,0 +1,6 @@
Features
* It is now possible to generate certificates with SubjectAltNames.
Currently supported subtypes: DnsName, UniformResourceIdentifier,
IP address, OtherName, and DirectoryName, as defined in RFC 5280.
See mbedtls_x509write_crt_set_subject_alternative_name for
more information.

4
ChangeLog.d/aes-perf.txt Normal file
View file

@ -0,0 +1,4 @@
Features
* AES performance improvements on 64-bit architectures. Uplift
varies by platform, toolchain, optimisation flags and mode,
in the 0 - 84% range. Aarch64, gcc and GCM/XTS benefit the most.

View file

@ -0,0 +1,7 @@
Bugfix
* Fix clang and armclang compilation error when targeting certain Arm
M-class CPUs (Cortex-M0, Cortex-M0+, Cortex-M1, Cortex-M23,
SecurCore SC000). Fixes #1077.
Changes
* Enable Arm / Thumb bignum assembly for most Arm platforms when
compiling with gcc, clang or armclang and -O0.

View file

@ -0,0 +1,4 @@
Features
* X.509 hostname verification now partially supports URI Subject Alternate
Names. Only exact matching, without any normalization procedures
described in 7.4 of RFC5280, will result in a positive URI verification.

View file

@ -0,0 +1,3 @@
Features
* Add a driver dispatch layer for FFDH keys, enabling alternative
implementations of FFDH through the driver entry points.

View file

@ -0,0 +1,4 @@
Bugfix
* Fix "unterminated '#pragma clang attribute push'" in sha256/sha512.c when
built with MBEDTLS_SHAxxx_USE_A64_CRYPTO_IF_PRESENT but don't have a
way to detect the crypto extensions required. A warning is still issued.

View file

@ -0,0 +1,3 @@
Features
* Add function mbedtls_oid_from_numeric_string() to parse an OID from a
string to a DER-encoded mbedtls_asn1_buf.

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

@ -0,0 +1,3 @@
Features
* Add SHA-3 family hash functions.

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/**
* \file psa/crypto_config.h
* \brief PSA crypto configuration options (set of defines)
*
*/
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
/**
* When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in mbedtls_config.h,
* this file determines which cryptographic mechanisms are enabled
* through the PSA Cryptography API (\c psa_xxx() functions).
*
* To enable a cryptographic mechanism, uncomment the definition of
* the corresponding \c PSA_WANT_xxx preprocessor symbol.
* To disable a cryptographic mechanism, comment out the definition of
* the corresponding \c PSA_WANT_xxx preprocessor symbol.
* The names of cryptographic mechanisms correspond to values
* defined in psa/crypto_values.h, with the prefix \c PSA_WANT_ instead
* of \c PSA_.
*
* Note that many cryptographic mechanisms involve two symbols: one for
* the key type (\c PSA_WANT_KEY_TYPE_xxx) and one for the algorithm
* (\c PSA_WANT_ALG_xxx). Mechanisms with additional parameters may involve
* additional symbols.
*/
#else
/**
* When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in mbedtls_config.h,
* this file is not used, and cryptographic mechanisms are supported
* through the PSA API if and only if they are supported through the
* mbedtls_xxx API.
*/
#endif
#ifndef PROFILE_M_PSA_CRYPTO_CONFIG_H
#define PROFILE_M_PSA_CRYPTO_CONFIG_H
/*
* CBC-MAC is not yet supported via the PSA API in Mbed TLS.
*/
//#define PSA_WANT_ALG_CBC_MAC 1
//#define PSA_WANT_ALG_CBC_NO_PADDING 1
//#define PSA_WANT_ALG_CBC_PKCS7 1
#define PSA_WANT_ALG_CCM 1
//#define PSA_WANT_ALG_CMAC 1
//#define PSA_WANT_ALG_CFB 1
//#define PSA_WANT_ALG_CHACHA20_POLY1305 1
//#define PSA_WANT_ALG_CTR 1
#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_ECDSA 1
//#define PSA_WANT_ALG_GCM 1
#define PSA_WANT_ALG_HKDF 1
#define PSA_WANT_ALG_HMAC 1
//#define PSA_WANT_ALG_MD5 1
//#define PSA_WANT_ALG_OFB 1
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
//#define PSA_WANT_ALG_PBKDF2_HMAC 1
//#define PSA_WANT_ALG_RIPEMD160 1
//#define PSA_WANT_ALG_RSA_OAEP 1
//#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
//#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
//#define PSA_WANT_ALG_RSA_PSS 1
//#define PSA_WANT_ALG_SHA_1 1
#define PSA_WANT_ALG_SHA_224 1
#define PSA_WANT_ALG_SHA_256 1
//#define PSA_WANT_ALG_SHA_384 1
//#define PSA_WANT_ALG_SHA_512 1
//#define PSA_WANT_ALG_STREAM_CIPHER 1
#define PSA_WANT_ALG_TLS12_PRF 1
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
//#define PSA_WANT_ALG_XTS 1
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1
//#define PSA_WANT_ECC_MONTGOMERY_255 1
//#define PSA_WANT_ECC_MONTGOMERY_448 1
//#define PSA_WANT_ECC_SECP_K1_192 1
/*
* SECP224K1 is buggy via the PSA API in Mbed TLS
* (https://github.com/Mbed-TLS/mbedtls/issues/3541). Thus, do not enable it by
* default.
*/
//#define PSA_WANT_ECC_SECP_K1_224 1
//#define PSA_WANT_ECC_SECP_K1_256 1
//#define PSA_WANT_ECC_SECP_R1_192 1
//#define PSA_WANT_ECC_SECP_R1_224 1
#define PSA_WANT_ECC_SECP_R1_256 1
//#define PSA_WANT_ECC_SECP_R1_384 1
//#define PSA_WANT_ECC_SECP_R1_521 1
#define PSA_WANT_KEY_TYPE_DERIVE 1
#define PSA_WANT_KEY_TYPE_HMAC 1
#define PSA_WANT_KEY_TYPE_AES 1
//#define PSA_WANT_KEY_TYPE_ARIA 1
//#define PSA_WANT_KEY_TYPE_CAMELLIA 1
//#define PSA_WANT_KEY_TYPE_CHACHA20 1
//#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_RAW_DATA 1
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1
//#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
#endif /* PROFILE_M_PSA_CRYPTO_CONFIG_H */

View file

@ -0,0 +1,629 @@
/**
* \file config.h
*
* \brief Configuration options (set of defines)
*
* This set of compile-time options may be used to enable
* or disable features selectively, and reduce the global
* memory footprint.
*/
/*
* Copyright (C) 2006-2022, ARM Limited, All Rights Reserved
* 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.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef PROFILE_M_MBEDTLS_CONFIG_H
#define PROFILE_M_MBEDTLS_CONFIG_H
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
/**
* \name SECTION: System support
*
* This section sets system specific settings.
* \{
*/
/**
* \def MBEDTLS_HAVE_ASM
*
* The compiler has support for asm().
*
* Requires support for asm() in compiler.
*
* Used in:
* library/aria.c
* library/timing.c
* include/mbedtls/bn_mul.h
*
* Required by:
* MBEDTLS_AESNI_C
* MBEDTLS_PADLOCK_C
*
* Comment to disable the use of assembly code.
*/
#define MBEDTLS_HAVE_ASM
/**
* \def MBEDTLS_PLATFORM_MEMORY
*
* Enable the memory allocation layer.
*
* By default mbed TLS uses the system-provided calloc() and free().
* This allows different allocators (self-implemented or provided) to be
* provided to the platform abstraction layer.
*
* Enabling MBEDTLS_PLATFORM_MEMORY without the
* MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
* "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
* free() function pointer at runtime.
*
* Enabling MBEDTLS_PLATFORM_MEMORY and specifying
* MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
* alternate function at compile time.
*
* Requires: MBEDTLS_PLATFORM_C
*
* Enable this layer to allow use of alternative memory allocators.
*/
#define MBEDTLS_PLATFORM_MEMORY
/* \} name SECTION: System support */
/**
* \name SECTION: mbed TLS feature support
*
* This section sets support for features that are or are not needed
* within the modules that are enabled.
* \{
*/
/**
* \def MBEDTLS_MD2_PROCESS_ALT
*
* MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
* alternate core implementation of symmetric crypto or hash function. Keep in
* mind that function prototypes should remain the same.
*
* This replaces only one function. The header file from mbed TLS is still
* used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
*
* Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
* no longer provide the mbedtls_sha1_process() function, but it will still provide
* the other function (using your mbedtls_sha1_process() function) and the definition
* of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
* with this definition.
*
* \note Because of a signature change, the core AES encryption and decryption routines are
* currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
* respectively. When setting up alternative implementations, these functions should
* be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
* must stay untouched.
*
* \note If you use the AES_xxx_ALT macros, then is is recommended to also set
* MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
* tables.
*
* Uncomment a macro to enable alternate implementation of the corresponding
* function.
*
* \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
* constitutes a security risk. If possible, we recommend avoiding
* dependencies on them, and considering stronger message digests
* and ciphers instead.
*
*/
#define MBEDTLS_AES_SETKEY_DEC_ALT
#define MBEDTLS_AES_DECRYPT_ALT
/**
* \def MBEDTLS_AES_ROM_TABLES
*
* Use precomputed AES tables stored in ROM.
*
* Uncomment this macro to use precomputed AES tables stored in ROM.
* Comment this macro to generate AES tables in RAM at runtime.
*
* Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
* (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
* initialization time before the first AES operation can be performed.
* It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
* MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
* performance if ROM access is slower than RAM access.
*
* This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
*
*/
#define MBEDTLS_AES_ROM_TABLES
/**
* \def MBEDTLS_AES_FEWER_TABLES
*
* Use less ROM/RAM for AES tables.
*
* Uncommenting this macro omits 75% of the AES tables from
* ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
* by computing their values on the fly during operations
* (the tables are entry-wise rotations of one another).
*
* Tradeoff: Uncommenting this reduces the RAM / ROM footprint
* by ~6kb but at the cost of more arithmetic operations during
* runtime. Specifically, one has to compare 4 accesses within
* different tables to 4 accesses with additional arithmetic
* operations within the same table. The performance gain/loss
* depends on the system and memory details.
*
* This option is independent of \c MBEDTLS_AES_ROM_TABLES.
*
*/
#define MBEDTLS_AES_FEWER_TABLES
/**
* \def MBEDTLS_ECP_NIST_OPTIM
*
* Enable specific 'modulo p' routines for each NIST prime.
* Depending on the prime and architecture, makes operations 4 to 8 times
* faster on the corresponding curve.
*
* Comment this macro to disable NIST curves optimisation.
*/
#define MBEDTLS_ECP_NIST_OPTIM
/**
* \def MBEDTLS_ERROR_STRERROR_DUMMY
*
* Enable a dummy error function to make use of mbedtls_strerror() in
* third party libraries easier when MBEDTLS_ERROR_C is disabled
* (no effect when MBEDTLS_ERROR_C is enabled).
*
* You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
* not using mbedtls_strerror() or error_strerror() in your application.
*
* Disable if you run into name conflicts and want to really remove the
* mbedtls_strerror()
*/
#define MBEDTLS_ERROR_STRERROR_DUMMY
/**
* \def MBEDTLS_NO_PLATFORM_ENTROPY
*
* Do not use built-in platform entropy functions.
* This is useful if your platform does not support
* standards like the /dev/urandom or Windows CryptoAPI.
*
* Uncomment this macro to disable the built-in platform entropy functions.
*/
#define MBEDTLS_NO_PLATFORM_ENTROPY
/**
* \def MBEDTLS_ENTROPY_NV_SEED
*
* Enable the non-volatile (NV) seed file-based entropy source.
* (Also enables the NV seed read/write functions in the platform layer)
*
* This is crucial (if not required) on systems that do not have a
* cryptographic entropy source (in hardware or kernel) available.
*
* Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
*
* \note The read/write functions that are used by the entropy source are
* determined in the platform layer, and can be modified at runtime and/or
* compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
*
* \note If you use the default implementation functions that read a seedfile
* with regular fopen(), please make sure you make a seedfile with the
* proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
* least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
* and written to or you will get an entropy source error! The default
* implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
* bytes from the file.
*
* \note The entropy collector will write to the seed file before entropy is
* given to an external source, to update it.
*/
// This macro is enabled in TFM Medium but is disabled here because it is
// incompatible with baremetal builds in Mbed TLS.
//#define MBEDTLS_ENTROPY_NV_SEED
/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
*
* Enable key identifiers that encode a key owner identifier.
*
* This is only meaningful when building the library as part of a
* multi-client service. When you activate this option, you must provide an
* implementation of the type mbedtls_key_owner_id_t and a translation from
* mbedtls_svc_key_id_t to file name in all the storage backends that you
* you wish to support.
*
* Note that while this define has been removed from TF-M's copy of this config
* file, TF-M still passes this option to Mbed TLS during the build via CMake.
* Therefore we keep it in our copy. See discussion on PR #7426 for more info.
*
*/
#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
/**
* \def MBEDTLS_PSA_CRYPTO_SPM
*
* When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure
* Partition Manager) integration which separates the code into two parts: a
* NSPE (Non-Secure Process Environment) and an SPE (Secure Process
* Environment).
*
* Module: library/psa_crypto.c
* Requires: MBEDTLS_PSA_CRYPTO_C
*
*/
#define MBEDTLS_PSA_CRYPTO_SPM
/**
* \def MBEDTLS_SHA256_SMALLER
*
* Enable an implementation of SHA-256 that has lower ROM footprint but also
* lower performance.
*
* The default implementation is meant to be a reasonnable compromise between
* performance and size. This version optimizes more aggressively for size at
* the expense of performance. Eg on Cortex-M4 it reduces the size of
* mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
* 30%.
*
* Uncomment to enable the smaller implementation of SHA256.
*/
#define MBEDTLS_SHA256_SMALLER
/**
* \def MBEDTLS_PSA_CRYPTO_CONFIG
*
* This setting allows support for cryptographic mechanisms through the PSA
* API to be configured separately from support through the mbedtls API.
*
* When this option is disabled, the PSA API exposes the cryptographic
* mechanisms that can be implemented on top of the `mbedtls_xxx` API
* configured with `MBEDTLS_XXX` symbols.
*
* When this option is enabled, the PSA API exposes the cryptographic
* mechanisms requested by the `PSA_WANT_XXX` symbols defined in
* include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are
* automatically enabled if required (i.e. if no PSA driver provides the
* mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols
* in mbedtls_config.h.
*
* If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies
* an alternative header to include instead of include/psa/crypto_config.h.
*
* This feature is still experimental and is not ready for production since
* it is not completed.
*/
#define MBEDTLS_PSA_CRYPTO_CONFIG
/* \} name SECTION: mbed TLS feature support */
/**
* \name SECTION: mbed TLS modules
*
* This section enables or disables entire modules in mbed TLS
* \{
*/
/**
* \def MBEDTLS_AES_C
*
* Enable the AES block cipher.
*
* Module: library/aes.c
* Caller: library/cipher.c
* library/pem.c
* library/ctr_drbg.c
*
* This module is required to support the TLS ciphersuites that use the AES
* cipher.
*
* PEM_PARSE uses AES for decrypting encrypted keys.
*/
#define MBEDTLS_AES_C
/**
* \def MBEDTLS_CIPHER_C
*
* Enable the generic cipher layer.
*
* Module: library/cipher.c
*
* Uncomment to enable generic cipher wrappers.
*/
#define MBEDTLS_CIPHER_C
/**
* \def MBEDTLS_CTR_DRBG_C
*
* Enable the CTR_DRBG AES-based random generator.
* The CTR_DRBG generator uses AES-256 by default.
* To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
*
* Module: library/ctr_drbg.c
* Caller:
*
* Requires: MBEDTLS_AES_C
*
* This module provides the CTR_DRBG AES random number generator.
*/
#define MBEDTLS_CTR_DRBG_C
/**
* \def MBEDTLS_ENTROPY_C
*
* Enable the platform-specific entropy code.
*
* Module: library/entropy.c
* Caller:
*
* Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
*
* This module provides a generic entropy pool
*/
#define MBEDTLS_ENTROPY_C
/**
* \def MBEDTLS_ERROR_C
*
* Enable error code to error string conversion.
*
* Module: library/error.c
* Caller:
*
* This module enables mbedtls_strerror().
*/
#define MBEDTLS_ERROR_C
/**
* \def MBEDTLS_HKDF_C
*
* Enable the HKDF algorithm (RFC 5869).
*
* Module: library/hkdf.c
* Caller:
*
* Requires: MBEDTLS_MD_C
*
* This module adds support for the Hashed Message Authentication Code
* (HMAC)-based key derivation function (HKDF).
*/
#define MBEDTLS_HKDF_C /* Used for HUK deriviation */
/**
* \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
*
* Enable the buffer allocator implementation that makes use of a (stack)
* based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
* calls)
*
* Module: library/memory_buffer_alloc.c
*
* Requires: MBEDTLS_PLATFORM_C
* MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
*
* Enable this module to enable the buffer memory allocator.
*/
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
/**
* \def MBEDTLS_PK_C
*
* Enable the generic public (asymetric) key layer.
*
* Module: library/pk.c
*
* Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
*
* Uncomment to enable generic public key wrappers.
*/
#define MBEDTLS_PK_C
/**
* \def MBEDTLS_PK_PARSE_C
*
* Enable the generic public (asymetric) key parser.
*
* Module: library/pkparse.c
*
* Requires: MBEDTLS_PK_C
*
* Uncomment to enable generic public key parse functions.
*/
#define MBEDTLS_PK_PARSE_C
/**
* \def MBEDTLS_PK_WRITE_C
*
* Enable the generic public (asymetric) key writer.
*
* Module: library/pkwrite.c
*
* Requires: MBEDTLS_PK_C
*
* Uncomment to enable generic public key write functions.
*/
#define MBEDTLS_PK_WRITE_C
/**
* \def MBEDTLS_PLATFORM_C
*
* Enable the platform abstraction layer that allows you to re-assign
* functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
*
* Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
* or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
* above to be specified at runtime or compile time respectively.
*
* \note This abstraction layer must be enabled on Windows (including MSYS2)
* as other module rely on it for a fixed snprintf implementation.
*
* Module: library/platform.c
* Caller: Most other .c files
*
* This module enables abstraction of common (libc) functions.
*/
#define MBEDTLS_PLATFORM_C
/**
* \def MBEDTLS_PSA_CRYPTO_C
*
* Enable the Platform Security Architecture cryptography API.
*
* Module: library/psa_crypto.c
*
* Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
*
*/
#define MBEDTLS_PSA_CRYPTO_C
/**
* \def MBEDTLS_PSA_CRYPTO_STORAGE_C
*
* Enable the Platform Security Architecture persistent key storage.
*
* Module: library/psa_crypto_storage.c
*
* Requires: MBEDTLS_PSA_CRYPTO_C,
* either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
* the PSA ITS interface
*/
// This macro is enabled in TFM Medium but is disabled here because it is
// incompatible with baremetal builds in Mbed TLS.
//#define MBEDTLS_PSA_CRYPTO_STORAGE_C
/* \} name SECTION: mbed TLS modules */
/**
* \name SECTION: General configuration options
*
* This section contains Mbed TLS build settings that are not associated
* with a particular module.
*
* \{
*/
/**
* \def MBEDTLS_CONFIG_FILE
*
* If defined, this is a header which will be included instead of
* `"mbedtls/mbedtls_config.h"`.
* This header file specifies the compile-time configuration of Mbed TLS.
* Unlike other configuration options, this one must be defined on the
* compiler command line: a definition in `mbedtls_config.h` would have
* no effect.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h"
/**
* \def MBEDTLS_USER_CONFIG_FILE
*
* If defined, this is a header which will be included after
* `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE.
* This allows you to modify the default configuration, including the ability
* to undefine options that are enabled by default.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_USER_CONFIG_FILE "/dev/null"
/**
* \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE
*
* If defined, this is a header which will be included instead of
* `"psa/crypto_config.h"`.
* This header file specifies which cryptographic mechanisms are available
* through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and
* is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h"
/**
* \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
*
* If defined, this is a header which will be included after
* `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE.
* This allows you to modify the default configuration, including the ability
* to undefine options that are enabled by default.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null"
/** \} name SECTION: General configuration options */
/**
* \name SECTION: Module configuration options
*
* This section allows for the setting of module specific sizes and
* configuration options. The default values are already present in the
* relevant header files and should suffice for the regular use cases.
*
* Our advice is to enable options and change their values here
* only if you have a good reason and know the consequences.
*
* Please check the respective header file for documentation on these
* parameters (to prevent duplicate documentation).
* \{
*/
/* ECP options */
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Disable fixed-point speed-up */
/* \} name SECTION: Customisation configuration options */
#if CRYPTO_NV_SEED
#include "tfm_mbedcrypto_config_extra_nv_seed.h"
#endif /* CRYPTO_NV_SEED */
#if !defined(CRYPTO_HW_ACCELERATOR) && defined(MBEDTLS_ENTROPY_NV_SEED)
#include "mbedtls_entropy_nv_seed_config.h"
#endif
#ifdef CRYPTO_HW_ACCELERATOR
#include "mbedtls_accelerator_config.h"
#endif
#endif /* PROFILE_M_MBEDTLS_CONFIG_H */

View file

@ -301,25 +301,289 @@ TODO
TODO
#### Operation family `"key_derivation"`
### Driver entry points for key derivation
This family requires the following type and entry points:
Key derivation is more complex than other multipart operations for several reasons:
* Type `"key_derivation_operation_t"`: the type of a key derivation operation context.
* `"key_derivation_setup"`: called by `psa_key_derivation_setup()`.
* `"key_derivation_set_capacity"`: called by `psa_key_derivation_set_capacity()`. The core will always enforce the capacity, therefore this function does not need to do anything for algorithms where the output stream only depends on the effective generated length and not on the capacity.
* `"key_derivation_input_bytes"`: called by `psa_key_derivation_input_bytes()` and `psa_key_derivation_input_key()`. For transparent drivers, when processing a call to `psa_key_derivation_input_key()`, the core always calls the applicable driver's `"key_derivation_input_bytes"` entry point.
* `"key_derivation_input_integer"`: called by `psa_key_derivation_input_integer()`.
* `"key_derivation_input_key"` (opaque drivers only)
* `"key_derivation_output_bytes"`: called by `psa_key_derivation_output_bytes()`; also by `psa_key_derivation_output_key()` for transparent drivers.
* `"key_derivation_output_key"`: called by `psa_key_derivation_output_key()` for transparent drivers when deriving an asymmetric key pair, and also for opaque drivers.
* `"key_derivation_verify_bytes"` (opaque drivers only).
* `"key_derivation_verify_key"` (opaque drivers only).
* `"key_derivation_abort"`: called by all key derivation functions of the PSA Cryptography API.
* There are multiple inputs and outputs.
* Multiple drivers can be involved. This happens when an operation combines a key agreement and a subsequent symmetric key derivation, each of which can have independent drivers. This also happens when deriving an asymmetric key, where processing the secret input and generating the key output might involve different drivers.
* When multiple drivers are involved, they are not always independent: if the secret input is managed by an opaque driver, it might not allow the core to retrieve the intermediate output and pass it to another driver.
* The involvement of an opaque driver cannot be determined as soon as the operation is set up (since `psa_key_derivation_setup()` does not determine the key input).
TODO: key input and output for opaque drivers; deterministic key generation for transparent drivers
#### Key derivation driver dispatch logic
TODO
The core decides whether to dispatch a key derivation operation to a driver based on the location associated with the input step `PSA_KEY_DERIVATION_INPUT_SECRET`.
1. If this step is passed via `psa_key_derivation_input_key()` for a key in a secure element:
* If the driver for this secure element implements the `"key_derivation"` family for the specified algorithm, the core calls that driver's `"key_derivation_setup"` and subsequent entry points.
Note that for all currently specified algorithms, the key type for the secret input does not matter.
* Otherwise the core calls the secure element driver's [`"export_key"`](#key-management-with-opaque-drivers) entry point.
2. Otherwise ([or on fallback?](#fallback-for-key-derivation-in-opaque-drivers)), if there is a transparent driver for the specified algorithm, the core calls that driver's `"key_derivation_setup"` and subsequent entry points.
3. Otherwise, or on fallback, the core uses its built-in implementation.
#### Summary of entry points for the operation family `"key_derivation"`
A key derivation driver has the following entry points:
* `"key_derivation_setup"` (mandatory): always the first entry point to be called. This entry point provides the [initial inputs](#key-derivation-driver-initial-inputs). See [“Key derivation driver setup”](#key-derivation-driver-setup).
* `"key_derivation_input_step"` (mandatory if the driver supports a key derivation algorithm with long inputs, otherwise ignored): provide an extra input for the key derivation. This entry point is only mandatory in drivers that support algorithms that have extra inputs. See [“Key derivation driver long inputs”](#key-derivation-driver-long-inputs).
* `"key_derivation_output_bytes"` (mandatory): derive cryptographic material and output it. See [“Key derivation driver outputs”](#key-derivation-driver-outputs).
* `"key_derivation_output_key"`, `"key_derivation_verify_bytes"`, `"key_derivation_verify_key"` (optional, opaque drivers only): derive key material which remains inside the same secure element. See [“Key derivation driver outputs”](#key-derivation-driver-outputs).
* `"key_derivation_set_capacity"` (mandatory for opaque drivers that implement `"key_derivation_output_key"` for “cooked”, i.e. non-raw-data key types; ignored for other opaque drivers; not permitted for transparent drivers): update the capacity policy on the operation. See [“Key derivation driver operation capacity”](#key-derivation-driver-operation-capacity).
* `"key_derivation_abort"` (mandatory): always the last entry point to be called.
For naming purposes, here and in the following subsection, this specification takes the example of a driver with the prefix `"acme"` that implements the `"key_derivation"` entry point family with a capability that does not use the `"names"` property to declare different type and entry point names. Such a driver must implement the following type and functions, as well as the entry points listed above and described in the following subsections:
```
typedef ... acme_key_derivation_operation_t;
psa_status_t acme_key_derivation_abort(acme_key_derivation_operation_t *operation);
```
#### Key derivation driver initial inputs
The core conveys the initial inputs for a key derivation via an opaque data structure of type `psa_crypto_driver_key_derivation_inputs_t`.
```
typedef ... psa_crypto_driver_key_derivation_inputs_t; // implementation-specific type
```
A driver receiving an argument that points to a `psa_crypto_driver_key_derivation_inputs_t` can retrieve its contents by calling one of the type-specific functions below. To determine the correct function, the driver can call `psa_crypto_driver_key_derivation_get_input_type()`.
```
enum psa_crypto_driver_key_derivation_input_type_t {
PSA_KEY_DERIVATION_INPUT_TYPE_INVALID = 0,
PSA_KEY_DERIVATION_INPUT_TYPE_OMITTED,
PSA_KEY_DERIVATION_INPUT_TYPE_BYTES,
PSA_KEY_DERIVATION_INPUT_TYPE_KEY,
PSA_KEY_DERIVATION_INPUT_TYPE_INTEGER,
// Implementations may add other values, and may freely choose the
// numerical values for each identifer except as explicitly specified
// above.
};
psa_crypto_driver_key_derivation_input_type_t psa_crypto_driver_key_derivation_get_input_type(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step);
```
The function `psa_crypto_driver_key_derivation_get_input_type()` determines whether a given step is present and how to access its value:
* `PSA_KEY_DERIVATION_INPUT_TYPE_INVALID`: the step is invalid for the algorithm of the operation that the inputs are for.
* `PSA_KEY_DERIVATION_INPUT_TYPE_OMITTED`: the step is optional for the algorithm of the operation that the inputs are for, and has been omitted.
* `PSA_KEY_DERIVATION_INPUT_TYPE_BYTES`: the step is valid and present and is a transparent byte string. Call `psa_crypto_driver_key_derivation_get_input_size()` to obtain the size of the input data. Call `psa_crypto_driver_key_derivation_get_input_bytes()` to make a copy of the input data (design note: [why a copy?](#key-derivation-inputs-and-buffer-ownership)).
* `PSA_KEY_DERIVATION_INPUT_TYPE_KEY`: the step is valid and present and is a byte string passed via a key object. Call `psa_crypto_driver_key_derivation_get_input_key()` to obtain a pointer to the key context.
* `PSA_KEY_DERIVATION_INPUT_TYPE_INTEGER`: the step is valid and present and is an integer. Call `psa_crypto_driver_key_derivation_get_input_integer()` to retrieve the integer value.
```
psa_status_t psa_crypto_driver_key_derivation_get_input_size(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step,
size_t *size);
psa_status_t psa_crypto_driver_key_derivation_get_input_bytes(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step,
uint8_t *buffer, size_t buffer_size, size_t *buffer_length);
psa_status_t psa_crypto_driver_key_derivation_get_input_key(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step,
const psa_key_attributes_t *attributes,
uint8_t** p_key_buffer, size_t *key_buffer_size);
psa_status_t psa_crypto_driver_key_derivation_get_input_integer(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step,
uint64_t *value);
```
The get-data functions take the following parameters:
* The first parameter `inputs` must be a pointer passed by the core to a key derivation driver setup entry point which has not returned yet.
* The `step` parameter indicates the input step whose content the driver wants to retrieve.
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_size`, the core sets `*size` to the size of the specified input in bytes.
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_bytes`, the core fills the first *N* bytes of `buffer` with the specified input and sets `*buffer_length` to *N*, where *N* is the length of the input in bytes. The value of `buffer_size` must be at least *N*, otherwise this function fails with the status `PSA_ERROR_BUFFER_TOO_SMALL`.
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_key`, the core sets `*key_buffer` to a pointer to a buffer containing the key context and `*key_buffer_size` to the size of the key context in bytes. The key context buffer remains valid for the duration of the driver entry point. If the driver needs to access the key context after the current entry point returns, it must make a copy of the key context.
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_integer`, the core sets `*value` to the value of the specified input.
These functions can return the following statuses:
* `PSA_SUCCESS`: the call succeeded and the requested value has been copied to the output parameter (`size`, `buffer`, `value` or `p_key_buffer`) and if applicable the size of the value has been written to the applicable parameter (`buffer_length`, `key_buffer_size`).
* `PSA_ERROR_DOES_NOT_EXIST`: the input step is valid for this particular algorithm, but it is not part of the initial inputs. This is not a fatal error. The driver will receive the input later as a [long input](#key-derivation-driver-long-inputs).
* `PSA_ERROR_INVALID_ARGUMENT`: the input type is not compatible with this function or was omitted. Call `psa_crypto_driver_key_derivation_get_input_type()` to find out the actual type of this input step. This is not a fatal error and the driver can, for example, subsequently call the appropriate function on the same step.
* `PSA_ERROR_BUFFER_TOO_SMALL` (`psa_crypto_driver_key_derivation_get_input_bytes` only): the output buffer is too small. This is not a fatal error and the driver can, for example, subsequently call the same function again with a larger buffer. Call `psa_crypto_driver_key_derivation_get_input_size` to obtain the required size.
* The core may return other errors such as `PSA_ERROR_CORRUPTION_DETECTED` or `PSA_ERROR_COMMUNICATION_FAILURE` to convey implementation-specific error conditions. Portable drivers should treat such conditions as fatal errors.
#### Key derivation driver setup
A key derivation driver must implement the following entry point:
```
psa_status_t acme_key_derivation_setup(
acme_key_derivation_operation_t *operation,
psa_algorithm_t alg,
const psa_crypto_driver_key_derivation_inputs_t *inputs);
```
* `operation` is a zero-initialized operation object.
* `alg` is the algorithm for the key derivation operation. It does not include a key agreement component.
* `inputs` is an opaque pointer to the [initial inputs](#key-derivation-driver-initial-inputs) for the key derivation.
#### Key derivation driver long inputs
Some key derivation algorithms take long inputs which it would not be practical to pass in the [initial inputs](#key-derivation-driver-initial-inputs). A driver that implements a key derivation algorithm that takes such inputs must provide a `"key_derivation_input_step"` entry point. The core calls this entry point for all the long inputs after calling `"acme_key_derivation_setup"`. A long input step may be fragmented into multiple calls of `psa_key_derivation_input_bytes()`, and the core may reassemble or refragment those fragments before passing them to the driver. Calls to this entry point for different step values occur in an unspecified order and may be interspersed.
```
psa_status_t acme_key_derivation_input_step(
acme_key_derivation_operation_t *operation,
psa_key_derivation_step_t step,
const uint8_t *input, size_t input_length);
```
At the time of writing, no standard key derivation algorithm has long inputs. It is likely that such algorithms will be added in the future.
#### Key derivation driver operation capacity
The core keeps track of an operation's capacity and enforces it. The core guarantees that it will not request output beyond the capacity of the operation, with one exception: opaque drivers that support [`"key_derivation_output_key"`](#key-derivation-driver-outputs), i.e. for key types where the derived key material is not a direct copy of the key derivation's output stream.
Such drivers must enforce the capacity limitation and must return `PSA_ERROR_INSUFFICIENT_CAPACITY` from any output request that exceeds the operation's capacity. Such drivers must provide the following entry point:
```
psa_status_t acme_key_derivation_set_capacity(
acme_key_derivation_operation_t *operation,
size_t capacity);
```
`capacity` is guaranteed to be less or equal to any value previously set through this entry point, and is guaranteed not to be `PSA_KEY_DERIVATION_UNLIMITED_CAPACITY`.
If this entry point has not been called, the operation has an unlimited capacity.
#### Key derivation driver outputs
A key derivation driver must provide the following entry point:
```
psa_status_t acme_key_derivation_output_bytes(
acme_key_derivation_operation_t *operation,
uint8_t *output, size_t length);
```
An opaque key derivation driver may provide the following entry points:
```
psa_status_t acme_key_derivation_output_key(
const psa_key_attributes_t *attributes,
acme_key_derivation_operation_t *operation,
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
psa_status_t acme_key_derivation_verify_bytes(
acme_key_derivation_operation_t *operation,
const uint8_t *expected output, size_t length);
psa_status_t acme_key_derivation_verify_key(
acme_key_derivation_operation_t *operation,
uint8_t *key_buffer, size_t key_buffer_size);
```
The core calls a key derivation driver's output entry point when the application calls `psa_key_derivation_output_bytes()`, `psa_key_derivation_output_key()`, `psa_key_derivation_verify_bytes()` or `psa_key_derivation_verify_key()`.
If the key derivation's `PSA_KEY_DERIVATION_INPUT_SECRET` input is in a secure element and the derivation operation is handled by that secure element, the core performs the following steps:
* For a call to `psa_key_derivation_output_key()`:
1. If the derived key is in the same secure element, if the driver has an `"key_derivation_output_key"` entry point, call that entry point. If the driver has no such entry point, or if that entry point returns `PSA_ERROR_NOT_SUPPORTED`, continue with the following steps, otherwise stop.
1. If the driver's capabilities indicate that its `"import_key"` entry point does not support the derived key, stop and return `PSA_ERROR_NOT_SUPPORTED`.
1. Otherwise proceed as for `psa_key_derivation_output_bytes()`, then import the resulting key material.
* For a call to `psa_key_derivation_verify_key()`:
1. If the driver has a `"key_derivation_verify_key"` entry point, call it and stop.
1. Call the driver's `"export_key"` entry point on the key object that contains the expected value, then proceed as for `psa_key_derivation_verify_bytes()`.
* For a call to `psa_key_derivation_verify_bytes()`:
1. If the driver has a `"key_derivation_verify_bytes"` entry point, call that entry point on the expected output, then stop.
1. Otherwise, proceed as for `psa_key_derivation_output_bytes()`, and compare the resulting output to the expected output inside the core.
* For a call to `psa_key_derivation_output_bytes()`:
1. Call the `"key_derivation_output_bytes"` entry point. The core may call this entry point multiple times to implement a single call from the application when deriving a cooked (non-raw) key as described below, or if the output size exceeds some implementation limit.
If the key derivation operation is not handled by an opaque driver as described above, the core calls the `"key_derivation_output_bytes"` from the applicable transparent driver (or multiple drivers in succession if fallback applies). In some cases, the core then calls additional entry points in the same or another driver:
* For a call to `psa_key_derivation_output_key()` for some key types, the core calls a transparent driver's `"derive_key"` entry point. See [“Transparent cooked key derivation”](#transparent-cooked-key-derivation).
* For a call to `psa_key_derivation_output_key()` where the derived key is in a secure element, call that secure element driver's `"import_key"` entry point.
#### Transparent cooked key derivation
Key derivation is said to be *raw* for some key types, where the key material of a derived (8×*n*)-bit key consists of the next *n* bytes of output from the key derivation, and *cooked* otherwise. When deriving a raw key, the core only calls the driver's `"output_bytes"` entry point, except when deriving a key entirely inside a secure element as described in [“Key derivation driver outputs”](#key-derivation-driver-outputs). When deriving a cooked key, the core calls a transparent driver's `"derive_key"` entry point if available.
A capability for cooked key derivation contains the following properties (this is not a subset of [the usual entry point properties](#capability-syntax)):
* `"entry_points"` (mandatory, list of strings). Must be `["derive_key"]`.
* `"derived_types"` (mandatory, list of strings). Each element is a [key type specification](#key-type-specifications). This capability only applies when deriving a key of the specified type.
* `"derived_sizes"` (optional, list of integers). Each element is a size for the derived key, in bits. This capability only applies when deriving a key of the specified sizes. If absent, this capability applies to all sizes for the specified types.
* `"memory"` (optional, boolean). If present and true, the driver must define a type `"derive_key_memory_t"` and the core will allocate an object of that type as specified below.
* `"names"` (optional, object). A mapping from entry point names to C function and type names, as usual.
* `"fallback"` (optional, boolean). If present and true, the driver may return `PSA_ERROR_NOT_SUPPORTED` if it only partially supports the specified mechanism, as usual.
A transparent driver with the prefix `"acme"` that implements cooked key derivation must provide the following type and function:
```
typedef ... acme_derive_key_memory_t; // only if the "memory" property is true
psa_status_t acme_derive_key(
const psa_key_attributes_t *attributes,
const uint8_t *input, size_t input_length,
acme_derive_key_memory_t *memory, // if the "memory" property is false: void*
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
```
* `attributes` contains the attributes of the specified key. Note that only the key type and the bit-size are guaranteed to be set.
* `input` is a buffer of `input_length` bytes which contains the raw key stream, i.e. the data that `psa_key_derivation_output_bytes()` would return.
* If `"memory"` property in the driver capability is true, `memory` is a data structure that the driver may use to store data between successive calls of the `"derive_key"` entry point to derive the same key. If the `"memory"` property is false or absent, the `memory` parameter is a null pointer.
* `key_buffer` is a buffer for the output material, in the appropriate [export format](#key-format-for-transparent-drivers) for the key type. Its size is `key_buffer_size` bytes.
* On success, `*key_buffer_length` must contain the number of bytes written to `key_buffer`.
This entry point may return the following statuses:
* `PSA_SUCCESS`: a key was derived successfully. The driver has placed the representation of the key in `key_buffer`.
* `PSA_ERROR_NOT_SUPPORTED` (for the first call only) (only if fallback is enabled): the driver cannot fulfill this request, but a fallback driver might.
* `PSA_ERROR_INSUFFICIENT_DATA`: the core must call the `"derive_key"` entry point again with the same `memory` object and with subsequent data from the key stream.
* Any other error is a fatal error.
The core calls the `"derive_key"` entry point in a loop until it returns a status other than `PSA_ERROR_INSUFFICIENT_DATA`. Each call has a successive fragment of the key stream. The `memory` object is guaranteed to be the same for successive calls, but note that its address may change between calls. Before the first call, `*memory` is initialized to all-bits-zero.
For standard key types, the `"derive_key"` entry point is called with a certain input length as follows:
* `PSA_KEY_TYPE_DES`: the length of the key.
* `PSA_KEY_TYPE_ECC_KEY_PAIR(…)`, `PSA_KEY_TYPE_DH_KEY_PAIR(…)`: $m$ bytes, where the bit-size of the key $n$ satisfies $8 (m-1) < n \le 8 m$.
* `PSA_KEY_TYPE_RSA_KEY_PAIR`: an implementation-defined length. A future version of this specification may specify a length.
* Other key types: not applicable.
See [“Open questions around cooked key derivation”](#open-questions-around-cooked-key-derivation) for some points that may not be fully settled.
#### Key agreement
The core always decouples key agreement from symmetric key derivation.
To implement a call to `psa_key_derivation_key_agreement()` where the private key is in a secure element that has a `"key_agreement_to_key"` entry point which is applicable for the given key type and algorithm, the core calls the secure element driver as follows:
1. Call the `"key_agreement_to_key"` entry point to create a key object containing the shared secret. The key object is volatile and has the type `PSA_KEY_TYPE_DERIVE`.
2. Call the `"key_derivation_setup"` entry point, passing the resulting key object .
3. Perform the rest of the key derivation, up to and including the call to the `"key_derivation_abort"` entry point.
4. Call the `"destroy_key"` entry point to destroy the key containing the key object.
In other cases, the core treats `psa_key_derivation_key_agreement()` as if it was a call to `psa_raw_key_agreement()` followed by a call to `psa_key_derivation_input_bytes()` on the shared secret.
The entry points related to key agreement have the following prototypes for a driver with the prefix `"acme"`:
```
psa_status_t acme_key_agreement(psa_algorithm_t alg,
const psa_key_attributes_t *our_attributes,
const uint8_t *our_key_buffer,
size_t our_key_buffer_length,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t acme_key_agreement_to_key(psa_algorithm_t alg,
const psa_key_attributes_t *our_attributes,
const uint8_t *our_key_buffer,
size_t our_key_buffer_length,
const uint8_t *peer_key,
size_t peer_key_length,
const psa_key_attributes_t *shared_secret_attributes,
uint8_t *shared_secret_key_buffer,
size_t shared_secret_key_buffer_size,
size_t *shared_secret_key_buffer_length);
```
Note that unlike most other key creation entry points, in `"acme_key_agreement_to_key"`, the attributes for the shared secret are not placed near the beginning, but rather grouped with the other parameters related to the shared secret at the end of the parameter list. This is to avoid potential confusion with the attributes of the private key that is passed as an input.
### Driver entry points for PAKE
@ -506,8 +770,9 @@ psa_status_t acme_generate_key(const psa_key_attributes_t *attributes,
size_t key_buffer_size,
size_t *key_buffer_length);
```
Additionally, opaque drivers can create keys through their [`"key_derivation_output_key"`](#key-derivation-driver-outputs) and [`"key_agreement_key"`](#key-agreement) entry points. Transparent drivers can create key material through their [`"derive_key"`](#transparent-cooked-key-derivation) entry point.
TODO: derivation, copy
TODO: copy
* The key attributes (`attributes`) have the same semantics as in the PSA Cryptography application interface.
* For the `"import_key"` entry point, the input in the `data` buffer is either the export format or an implementation-specific format that the core documents as an acceptable input format for `psa_import_key()`.
@ -640,7 +905,7 @@ psa_status_t acme_import_key(const psa_key_attributes_t *attributes,
This entry point has several roles:
1. Parse the key data in the input buffer `data`. The driver must support the export format for the key types that the entry point is declared for. It may support additional formats as specified in the description of [`psa_import_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_key) in the PSA Cryptography API specification.
2. Validate the key data. The necessary validation is described in the section [“Key validation with transparent drivers”](#key-validation-with-transparent-drivers) above.
2. Validate the key data. The necessary validation is described in the section [“Key validation”](#key-validation) above.
3. [Determine the key size](#key-size-determination-on-import) and output it through `*bits`.
4. Copy the validated key data from `data` to `key_buffer`. The output must be in the canonical format documented for [`psa_export_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_key) or [`psa_export_public_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_public_key), so if the input is not in this format, the entry point must convert it.
@ -830,7 +1095,7 @@ If the key is stored in wrapped form outside the secure element, and the wrapped
Opaque drivers may provide the following key management entry points:
* `"export_key"`: called by `psa_export_key()`, or by `psa_copy_key()` when copying a key from or to a different [location](#lifetimes-and-locations).
* `"export_key"`: called by `psa_export_key()`, or by `psa_copy_key()` when copying a key from or to a different [location](#lifetimes-and-locations), or [as a fallback for key derivation](#key-derivation-driver-dispatch-logic).
* `"export_public_key"`: called by the core to obtain the public key of a key pair. The core may call this entry point at any time to obtain the public key, which can be for `psa_export_public_key()` but also at other times, including during a cryptographic operation that requires the public key such as a call to `psa_verify_message()` on a key pair object.
* `"import_key"`: called by `psa_import_key()`, or by `psa_copy_key()` when copying a key from another location.
* `"generate_key"`: called by `psa_generate_key()`.
@ -1101,6 +1366,12 @@ Should drivers really have to cope with overlap?
Should the core guarantee that the output buffer size has the size indicated by the applicable buffer size macro (which may be an overestimation)?
#### Key derivation inputs and buffer ownership
Why is `psa_crypto_driver_key_derivation_get_input_bytes` a copy, rather than giving a pointer?
The main reason is to avoid complex buffer ownership. A driver entry point does not own memory after the entry point return. This is generally necessary because an API function does not own memory after the entry point returns. In the case of key derivation inputs, this could be relaxed because the driver entry point is making callbacks to the core: these functions could return a pointer that is valid until the driver entry point returns, which would allow the driver to process the data immediately (e.g. hash it rather than copy it).
### Partial computations in drivers
#### Substitution points
@ -1144,6 +1415,18 @@ An example use case for updating the persistent state at arbitrary times is to r
`psa_crypto_driver_get_persistent_state` does not identify the calling driver, so the driver needs to remember which driver it's calling. This may require a thread-local variable in a multithreaded core. Is this ok?
#### Open questions around cooked key derivation
`"derive_key"` is not a clear name. Can we use a better one?
For the `"derive_key"` entry point, how does the core choose `input_length`? Doesn't the driver know better? Should there be a driver entry point to determine the length, or should there be a callback that allows the driver to retrieve the input? Note that for some key types, it's impossible to predict the amount of input in advance, because it depends on some complex calculation or even on random data, e.g. if doing a randomized pseudo-primality test. However, for all key types except RSA, the specification mandates how the key is derived, which practically dictates how the pseudorandom key stream is consumed. So it's probably ok.
#### Fallback for key derivation in opaque drivers
Should [dispatch to an opaque driver](#key-derivation-driver-dispatch-logic) allow fallback, so that if `"key_derivation_setup"` returns `PSA_ERROR_NOT_SUPPORTED` then the core exports the key from the secure element instead?
Should the ["`key_derivation_output_key`"](#key-derivation-driver-outputs) capability indicate which key types the driver can derive? How should fallback work? For example, consider a secure element that implements HMAC, HKDF and ECDSA, and that can derive an HMAC key from HKDF without exporting intermediate material but can only import or randomly generate ECC keys. How does this driver convey that it can't derive an ECC key with HKDF, but it can let the core do this and import the resulting key?
### Randomness
#### Input to `"add_entropy"`

View file

@ -76,6 +76,10 @@ typedef struct mbedtls_aes_context {
int MBEDTLS_PRIVATE(nr); /*!< The number of rounds. */
size_t MBEDTLS_PRIVATE(rk_offset); /*!< The offset in array elements to AES
round keys in the buffer. */
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_PADLOCK_C)
uint32_t MBEDTLS_PRIVATE(buf)[44]; /*!< Aligned data buffer to hold
10 round keys for 128-bit case. */
#else
uint32_t MBEDTLS_PRIVATE(buf)[68]; /*!< Unaligned data buffer. This buffer can
hold 32 extra Bytes, which can be used for
one of the following purposes:
@ -84,6 +88,7 @@ typedef struct mbedtls_aes_context {
<li>Simplifying key expansion in the 256-bit
case by generating an extra round key.
</li></ul> */
#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH && !MBEDTLS_PADLOCK_C */
}
mbedtls_aes_context;

View file

@ -80,6 +80,14 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
/* Auto-enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY if
* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH and MBEDTLS_CTR_DRBG_C defined
* to ensure a 128-bit key size in CTR_DRBG.
*/
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && defined(MBEDTLS_CTR_DRBG_C)
#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
#endif
/* Auto-enable MBEDTLS_MD_C if needed by a module that didn't require it
* in a previous release, to ensure backwards compatibility.
*/
@ -87,6 +95,18 @@
#define MBEDTLS_MD_C
#endif
/* PSA crypto specific configuration options
* - If config_psa.h reads a configuration option in preprocessor directive,
* this symbol should be set before its inclusion. (e.g. MBEDTLS_MD_C)
* - If config_psa.h writes a configuration option in conditional directive,
* this symbol should be consulted after its inclusion.
* (e.g. MBEDTLS_MD_LIGHT)
*/
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \
defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */
#include "mbedtls/config_psa.h"
#endif
/* Auto-enable MBEDTLS_MD_LIGHT based on MBEDTLS_MD_C.
* This allows checking for MD_LIGHT rather than MD_LIGHT || MD_C.
*/
@ -100,8 +120,12 @@
#if defined(MBEDTLS_ECJPAKE_C) || \
defined(MBEDTLS_PEM_PARSE_C) || \
defined(MBEDTLS_ENTROPY_C) || \
defined(MBEDTLS_PK_C) || \
defined(MBEDTLS_PKCS12_C) || \
defined(MBEDTLS_RSA_C)
defined(MBEDTLS_RSA_C) || \
defined(MBEDTLS_SSL_TLS_C) || \
defined(MBEDTLS_X509_USE_C) || \
defined(MBEDTLS_X509_CREATE_C)
#define MBEDTLS_MD_LIGHT
#endif
@ -185,11 +209,6 @@
/* Make sure all configuration symbols are set before including check_config.h,
* even the ones that are calculated programmatically. */
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \
defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */
#include "mbedtls/config_psa.h"
#endif
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_BUILD_INFO_H */

View file

@ -268,6 +268,15 @@ extern "C" {
#define MBEDTLS_SHA512_C
#endif
#if defined(PSA_WANT_ALG_PBKDF2_HMAC)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC 1
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */
#endif /* !MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_WANT_ALG_PBKDF2_HMAC */
#if defined(PSA_WANT_ALG_TLS12_PRF)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1

View file

@ -73,6 +73,7 @@
* SHA1 1 0x0035-0x0035 0x0073-0x0073
* SHA256 1 0x0037-0x0037 0x0074-0x0074
* SHA512 1 0x0039-0x0039 0x0075-0x0075
* SHA-3 1 0x0076-0x0076
* CHACHA20 3 0x0051-0x0055
* POLY1305 3 0x0057-0x005B
* CHACHAPOLY 2 0x0054-0x0056

View file

@ -496,7 +496,6 @@
* performance if ROM access is slower than RAM access.
*
* This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
*
*/
//#define MBEDTLS_AES_ROM_TABLES
@ -518,10 +517,26 @@
* depends on the system and memory details.
*
* This option is independent of \c MBEDTLS_AES_ROM_TABLES.
*
*/
//#define MBEDTLS_AES_FEWER_TABLES
/**
* \def MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
*
* Use only 128-bit keys in AES operations to save ROM.
*
* Uncomment this macro to remove support for AES operations that use 192-
* or 256-bit keys.
*
* Uncommenting this macro reduces the size of AES code by ~300 bytes
* on v8-M/Thumb2.
*
* Module: library/aes.c
*
* Requires: MBEDTLS_AES_C
*/
//#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
/**
* \def MBEDTLS_CAMELLIA_SMALL_MEMORY
*
@ -640,7 +655,8 @@
/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
*
* Uncomment this macro to use a 128-bit key in the CTR_DRBG module.
* By default, CTR_DRBG uses a 256-bit key.
* Without this, CTR_DRBG uses a 256-bit key
* unless \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set.
*/
//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
@ -2414,6 +2430,8 @@
* The CTR_DRBG generator uses AES-256 by default.
* To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
*
* \note AES-128 will be used if \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set.
*
* \note To achieve a 256-bit security strength with CTR_DRBG,
* you must use AES-256 *and* use sufficient entropy.
* See ctr_drbg.h for more details.
@ -3164,6 +3182,17 @@
*/
#define MBEDTLS_SHA512_C
/**
* \def MBEDTLS_SHA3_C
*
* Enable the SHA3 cryptographic hash algorithm.
*
* Module: library/sha3.c
*
* This module adds support for SHA3.
*/
#define MBEDTLS_SHA3_C
/**
* \def MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
*

View file

@ -112,6 +112,12 @@
#define MBEDTLS_MD_CAN_SHA512
#define MBEDTLS_MD_SOME_LEGACY
#endif
#if defined(MBEDTLS_SHA3_C)
#define MBEDTLS_MD_CAN_SHA3_224
#define MBEDTLS_MD_CAN_SHA3_256
#define MBEDTLS_MD_CAN_SHA3_384
#define MBEDTLS_MD_CAN_SHA3_512
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#define MBEDTLS_MD_CAN_RIPEMD160
#define MBEDTLS_MD_SOME_LEGACY
@ -149,23 +155,43 @@ typedef enum {
MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */
MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */
MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
MBEDTLS_MD_SHA3_224, /**< The SHA3-224 message digest. */
MBEDTLS_MD_SHA3_256, /**< The SHA3-256 message digest. */
MBEDTLS_MD_SHA3_384, /**< The SHA3-384 message digest. */
MBEDTLS_MD_SHA3_512, /**< The SHA3-512 message digest. */
} mbedtls_md_type_t;
#if defined(MBEDTLS_MD_CAN_SHA512)
/* Note: this should always be >= PSA_HASH_MAX_SIZE
* in all builds with both CRYPTO_C and MD_LIGHT.
*
* This is to make things easier for modules such as TLS that may define a
* buffer size using MD_MAX_SIZE in a part of the code that's common to PSA
* and legacy, then assume the buffer's size is PSA_HASH_MAX_SIZE in another
* part of the code based on PSA.
*/
#if defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA3_512)
#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */
#elif defined(MBEDTLS_MD_CAN_SHA384)
#elif defined(MBEDTLS_MD_CAN_SHA384) || defined(MBEDTLS_MD_CAN_SHA3_384)
#define MBEDTLS_MD_MAX_SIZE 48 /* longest known is SHA384 */
#elif defined(MBEDTLS_MD_CAN_SHA256)
#elif defined(MBEDTLS_MD_CAN_SHA256) || defined(MBEDTLS_MD_CAN_SHA3_256)
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 */
#elif defined(MBEDTLS_MD_CAN_SHA224)
#elif defined(MBEDTLS_MD_CAN_SHA224) || defined(MBEDTLS_MD_CAN_SHA3_224)
#define MBEDTLS_MD_MAX_SIZE 28 /* longest known is SHA224 */
#else
#define MBEDTLS_MD_MAX_SIZE 20 /* longest known is SHA1 or RIPE MD-160
or smaller (MD5 and earlier) */
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
#if defined(MBEDTLS_MD_CAN_SHA3_224)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 144 /* the longest known is SHA3-224 */
#elif defined(MBEDTLS_MD_CAN_SHA3_256)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 136
#elif defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA384)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
#elif defined(MBEDTLS_MD_CAN_SHA3_384)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 104
#elif defined(MBEDTLS_MD_CAN_SHA3_512)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 72
#else
#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
#endif
@ -310,6 +336,20 @@ int mbedtls_md_clone(mbedtls_md_context_t *dst,
*/
unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info);
/**
* \brief This function gives the message-digest size associated to
* message-digest type.
*
* \param md_type The message-digest type.
*
* \return The size of the message-digest output in Bytes,
* or 0 if the message-digest type is not known.
*/
static inline unsigned char mbedtls_md_get_size_from_type(mbedtls_md_type_t md_type)
{
return mbedtls_md_get_size(mbedtls_md_info_from_type(md_type));
}
/**
* \brief This function extracts the message-digest type from the
* message-digest information structure.

View file

@ -63,6 +63,11 @@
#define MBEDTLS_OID_X509_EXT_FRESHEST_CRL (1 << 14)
#define MBEDTLS_OID_X509_EXT_NS_CERT_TYPE (1 << 16)
/*
* Maximum number of OID components allowed
*/
#define MBEDTLS_OID_MAX_COMPONENTS 128
/*
* Top level OID tuples
*/
@ -478,6 +483,25 @@ typedef struct mbedtls_oid_descriptor_t {
*/
int mbedtls_oid_get_numeric_string(char *buf, size_t size, const mbedtls_asn1_buf *oid);
/**
* \brief Translate a string containing a dotted-decimal
* representation of an ASN.1 OID into its encoded form
* (e.g. "1.2.840.113549" into "\x2A\x86\x48\x86\xF7\x0D").
* On success, this function allocates oid->buf from the
* heap. It must be freed by the caller using mbedtls_free().
*
* \param oid #mbedtls_asn1_buf to populate with the DER-encoded OID
* \param oid_str string representation of the OID to parse
* \param size length of the OID string, not including any null terminator
*
* \return 0 if successful
* \return #MBEDTLS_ERR_ASN1_INVALID_DATA if \p oid_str does not
* represent a valid OID
* \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if the function fails to
* allocate oid->buf
*/
int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid, const char *oid_str, size_t size);
/**
* \brief Translate an X.509 extension OID into local values
*

View file

@ -202,6 +202,27 @@ typedef struct mbedtls_pk_rsassa_pss_options {
#define MBEDTLS_PK_CAN_ECDH
#endif
/* Internal helper to define which fields in the pk_context structure below
* should be used for EC keys: legacy ecp_keypair or the raw (PSA friendly)
* format. It should be noticed that this only affect how data is stored, not
* which functions are used for various operations. The overall picture looks
* like this:
* - if ECP_C is defined then use legacy functions
* - if USE_PSA is defined and
* - if ECP_C then use ecp_keypair structure, convert data to a PSA friendly
* format and use PSA functions
* - if !ECP_C then use new raw data and PSA functions directly.
*
* The main reason for the "intermediate" (USE_PSA + ECP_C) above is that as long
* as ECP_C is defined mbedtls_pk_ec() gives the user a read/write access to the
* ecp_keypair structure inside the pk_context so he/she can modify it using
* ECP functions which are not under PK module's control.
*/
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_ECP_C) && \
defined(MBEDTLS_ECP_LIGHT)
#define MBEDTLS_PK_USE_PSA_EC_DATA
#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_ECP_C */
/**
* \brief Types for interfacing with the debug module
*/
@ -209,6 +230,7 @@ typedef enum {
MBEDTLS_PK_DEBUG_NONE = 0,
MBEDTLS_PK_DEBUG_MPI,
MBEDTLS_PK_DEBUG_ECP,
MBEDTLS_PK_DEBUG_PSA_EC,
} mbedtls_pk_debug_type;
/**
@ -232,19 +254,59 @@ typedef struct mbedtls_pk_debug_item {
*/
typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
#define MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN \
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
/**
* \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 */
/* The following field is used to store the ID of a private key in the
* following cases:
* - opaque key when MBEDTLS_PSA_CRYPTO_C is defined
* - normal key when MBEDTLS_PK_USE_PSA_EC_DATA is defined. In this case:
* - the pk_ctx above is not not used to store the private key anymore.
* Actually that field not populated at all in this case because also
* the public key will be stored in raw format as explained below
* - this ID is used for all private key operations (ex: sign, check
* key pair, key write, etc) using PSA functions
*
* Note: this private key storing solution only affects EC keys, not the
* other ones. The latters still use the pk_ctx to store their own
* context.
*
* Note: this priv_id is guarded by MBEDTLS_PSA_CRYPTO_C and not by
* MBEDTLS_PK_USE_PSA_EC_DATA (as the public counterpart below) because,
* when working with opaque keys, it can be used also in
* mbedtls_pk_sign_ext for RSA keys. */
#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 */
/* The following fields are meant for storing the public key in raw format
* which is handy for:
* - easily importing it into the PSA context
* - reducing the ECP module dependencies in the PK one.
*
* When MBEDTLS_PK_USE_PSA_EC_DATA is enabled:
* - the pk_ctx above is not used anymore for storing the public key
* inside the ecp_keypair structure
* - the following fields are used for all public key operations: signature
* verify, key pair check and key write.
* Of course, when MBEDTLS_PK_USE_PSA_EC_DATA is not enabled, the legacy
* ecp_keypair structure is used for storing the public key and performing
* all the operations.
*
* Note: This new public key storing solution only works for EC keys, not
* other ones. The latters still use pk_ctx to store their own
* context.
*/
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
uint8_t MBEDTLS_PRIVATE(pub_raw)[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN]; /**< Raw public key */
size_t MBEDTLS_PRIVATE(pub_raw_len); /**< Valid bytes in "pub_raw" */
psa_ecc_family_t MBEDTLS_PRIVATE(ec_family); /**< EC family of pk */
size_t MBEDTLS_PRIVATE(ec_bits); /**< Curve's bits of pk */
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
} mbedtls_pk_context;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)

View file

@ -139,6 +139,8 @@ extern "C" {
#if defined(MBEDTLS_PLATFORM_MEMORY)
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
#undef mbedtls_free
#undef mbedtls_calloc
#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO
#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO
#else
@ -160,6 +162,8 @@ int mbedtls_platform_set_calloc_free(void *(*calloc_func)(size_t, size_t),
void (*free_func)(void *));
#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
#else /* !MBEDTLS_PLATFORM_MEMORY */
#undef mbedtls_free
#undef mbedtls_calloc
#define mbedtls_free free
#define mbedtls_calloc calloc
#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
@ -184,6 +188,7 @@ extern int (*mbedtls_fprintf)(FILE *stream, const char *format, ...);
int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *stream, const char *,
...));
#else
#undef mbedtls_fprintf
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO
#else
@ -208,6 +213,7 @@ extern int (*mbedtls_printf)(const char *format, ...);
*/
int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...));
#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
#undef mbedtls_printf
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO
#else
@ -243,6 +249,7 @@ extern int (*mbedtls_snprintf)(char *s, size_t n, const char *format, ...);
int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n,
const char *format, ...));
#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
#undef mbedtls_snprintf
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO
#else
@ -279,6 +286,7 @@ extern int (*mbedtls_vsnprintf)(char *s, size_t n, const char *format, va_list a
int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n,
const char *format, va_list arg));
#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
#undef mbedtls_vsnprintf
#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO
#else
@ -320,7 +328,9 @@ extern void (*mbedtls_setbuf)(FILE *stream, char *buf);
*/
int mbedtls_platform_set_setbuf(void (*setbuf_func)(
FILE *stream, char *buf));
#elif defined(MBEDTLS_PLATFORM_SETBUF_MACRO)
#else
#undef mbedtls_setbuf
#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO)
/**
* \brief Macro defining the function for the library to
* call for `setbuf` functionality (changing the
@ -334,7 +344,8 @@ int mbedtls_platform_set_setbuf(void (*setbuf_func)(
#define mbedtls_setbuf MBEDTLS_PLATFORM_SETBUF_MACRO
#else
#define mbedtls_setbuf setbuf
#endif /* MBEDTLS_PLATFORM_SETBUF_ALT / MBEDTLS_PLATFORM_SETBUF_MACRO */
#endif /* MBEDTLS_PLATFORM_SETBUF_MACRO */
#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */
/*
* The function pointers for exit
@ -353,6 +364,7 @@ extern void (*mbedtls_exit)(int status);
*/
int mbedtls_platform_set_exit(void (*exit_func)(int status));
#else
#undef mbedtls_exit
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO
#else
@ -405,6 +417,8 @@ int mbedtls_platform_set_nv_seed(
int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len)
);
#else
#undef mbedtls_nv_seed_read
#undef mbedtls_nv_seed_write
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO

View file

@ -29,6 +29,8 @@
#include "mbedtls/build_info.h"
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "psa/crypto.h"
@ -120,49 +122,6 @@ static inline psa_key_usage_t mbedtls_psa_translate_cipher_operation(
}
}
/* Translations for hashing. */
/* Note: this function should not be used from inside the library, use
* mbedtls_hash_info_psa_from_md() from the internal hash_info.h instead.
* It is kept only for compatibility in case applications were using it. */
static inline psa_algorithm_t mbedtls_psa_translate_md(mbedtls_md_type_t md_alg)
{
switch (md_alg) {
#if defined(MBEDTLS_MD5_C) || defined(PSA_WANT_ALG_MD5)
case MBEDTLS_MD_MD5:
return PSA_ALG_MD5;
#endif
#if defined(MBEDTLS_SHA1_C) || defined(PSA_WANT_ALG_SHA_1)
case MBEDTLS_MD_SHA1:
return PSA_ALG_SHA_1;
#endif
#if defined(MBEDTLS_SHA224_C) || defined(PSA_WANT_ALG_SHA_224)
case MBEDTLS_MD_SHA224:
return PSA_ALG_SHA_224;
#endif
#if defined(MBEDTLS_SHA256_C) || defined(PSA_WANT_ALG_SHA_256)
case MBEDTLS_MD_SHA256:
return PSA_ALG_SHA_256;
#endif
#if defined(MBEDTLS_SHA384_C) || defined(PSA_WANT_ALG_SHA_384)
case MBEDTLS_MD_SHA384:
return PSA_ALG_SHA_384;
#endif
#if defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512)
case MBEDTLS_MD_SHA512:
return PSA_ALG_SHA_512;
#endif
#if defined(MBEDTLS_RIPEMD160_C) || defined(PSA_WANT_ALG_RIPEMD160)
case MBEDTLS_MD_RIPEMD160:
return PSA_ALG_RIPEMD160;
#endif
case MBEDTLS_MD_NONE:
return 0;
default:
return 0;
}
}
/* Translations for ECC. */
static inline int mbedtls_psa_get_ecc_oid_from_id(
@ -248,6 +207,22 @@ static inline int mbedtls_psa_get_ecc_oid_from_id(
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
}
break;
case PSA_ECC_FAMILY_MONTGOMERY:
switch (bits) {
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
case 255:
*oid = MBEDTLS_OID_X25519;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_X25519);
return 0;
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
case 448:
*oid = MBEDTLS_OID_X448;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_X448);
return 0;
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
}
break;
}
(void) oid;
(void) oid_len;
@ -353,7 +328,7 @@ typedef struct {
int16_t mbedtls_error;
} mbedtls_error_pair_t;
#if !defined(MBEDTLS_MD_C) || !defined(MBEDTLS_MD5_C) || defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_MD_LIGHT)
extern const mbedtls_error_pair_t psa_to_md_errors[4];
#endif

184
include/mbedtls/sha3.h Normal file
View file

@ -0,0 +1,184 @@
/**
* \file sha3.h
*
* \brief This file contains SHA-3 definitions and functions.
*
* The Secure Hash Algorithms cryptographic
* hash functions are defined in <em>FIPS 202: SHA-3 Standard:
* Permutation-Based Hash and Extendable-Output Functions </em>.
*/
/*
* 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_SHA3_H
#define MBEDTLS_SHA3_H
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** SHA-3 input data was malformed. */
#define MBEDTLS_ERR_SHA3_BAD_INPUT_DATA -0x0076
/**
* SHA-3 family id.
*
* It identifies the family (SHA3-256, SHA3-512, etc.)
*/
typedef enum {
MBEDTLS_SHA3_NONE = 0, /*!< Operation not defined. */
MBEDTLS_SHA3_224, /*!< SHA3-224 */
MBEDTLS_SHA3_256, /*!< SHA3-256 */
MBEDTLS_SHA3_384, /*!< SHA3-384 */
MBEDTLS_SHA3_512, /*!< SHA3-512 */
} mbedtls_sha3_id;
/**
* \brief The SHA-3 context structure.
*
* The structure is used SHA-3 checksum calculations.
*/
typedef struct {
uint64_t MBEDTLS_PRIVATE(state[25]);
uint32_t MBEDTLS_PRIVATE(index);
uint16_t MBEDTLS_PRIVATE(olen);
uint16_t MBEDTLS_PRIVATE(max_block_size);
}
mbedtls_sha3_context;
/**
* \brief This function initializes a SHA-3 context.
*
* \param ctx The SHA-3 context to initialize. This must not be \c NULL.
*/
void mbedtls_sha3_init(mbedtls_sha3_context *ctx);
/**
* \brief This function clears a SHA-3 context.
*
* \param ctx The SHA-3 context to clear. This may be \c NULL, in which
* case this function returns immediately. If it is not \c NULL,
* it must point to an initialized SHA-3 context.
*/
void mbedtls_sha3_free(mbedtls_sha3_context *ctx);
/**
* \brief This function clones the state of a SHA-3 context.
*
* \param dst The destination context. This must be initialized.
* \param src The context to clone. This must be initialized.
*/
void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
const mbedtls_sha3_context *src);
/**
* \brief This function starts a SHA-3 checksum
* calculation.
*
* \param ctx The context to use. This must be initialized.
* \param id The id of the SHA-3 family.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id);
/**
* \brief This function feeds an input buffer into an ongoing
* SHA-3 checksum calculation.
*
* \param ctx The SHA-3 context. This must be initialized
* and have a hash operation started.
* \param input The buffer holding the data. This must be a readable
* buffer of length \p ilen Bytes.
* \param ilen The length of the input data in Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
const uint8_t *input,
size_t ilen);
/**
* \brief This function finishes the SHA-3 operation, and writes
* the result to the output buffer.
*
* \param ctx The SHA-3 context. This must be initialized
* and have a hash operation started.
* \param output The SHA-3 checksum result.
* This must be a writable buffer of length \c olen bytes.
* \param olen Defines the length of output buffer (in bytes). For SHA-3 224, SHA-3 256,
* SHA-3 384 and SHA-3 512 \c olen must equal to 28, 32, 48 and 64,
* respectively.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
uint8_t *output, size_t olen);
/**
* \brief This function calculates the SHA-3
* checksum of a buffer.
*
* The function allocates the context, performs the
* calculation, and frees the context.
*
* The SHA-3 result is calculated as
* output = SHA-3(id, input buffer, d).
*
* \param id The id of the SHA-3 family.
* \param input The buffer holding the data. This must be a readable
* buffer of length \p ilen Bytes.
* \param ilen The length of the input data in Bytes.
* \param output The SHA-3 checksum result.
* This must be a writable buffer of length \c olen bytes.
* \param olen Defines the length of output buffer (in bytes). For SHA-3 224, SHA-3 256,
* SHA-3 384 and SHA-3 512 \c olen must equal to 28, 32, 48 and 64,
* respectively.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
size_t ilen,
uint8_t *output,
size_t olen);
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine for the algorithms implemented
* by this module: SHA3-224, SHA3-256, SHA3-384, SHA3-512.
*
* \return 0 if successful, or 1 if the test failed.
*/
int mbedtls_sha3_self_test(int verbose);
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_sha3.h */

View file

@ -304,7 +304,7 @@ mbedtls_x509_san_other_name;
typedef struct mbedtls_x509_subject_alternative_name {
int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
union {
mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
mbedtls_x509_san_other_name other_name;
mbedtls_x509_name directory_name;
mbedtls_x509_buf unstructured_name; /**< The buffer for the unstructured types. rfc822Name, dnsName and uniformResourceIdentifier are currently supported. */
}
@ -312,6 +312,12 @@ typedef struct mbedtls_x509_subject_alternative_name {
}
mbedtls_x509_subject_alternative_name;
typedef struct mbedtls_x509_san_list {
mbedtls_x509_subject_alternative_name node;
struct mbedtls_x509_san_list *next;
}
mbedtls_x509_san_list;
/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
/**
@ -401,7 +407,8 @@ int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
* of the subject alternative name encoded in \p san_raw.
*
* \note Supported GeneralName types, as defined in RFC 5280:
* "rfc822Name", "dnsName", "uniformResourceIdentifier" and "hardware_module_name"
* "rfc822Name", "dnsName", "directoryName",
* "uniformResourceIdentifier" and "hardware_module_name"
* of type "otherName", as defined in RFC 4108.
*
* \note This function should be called on a single raw data of

View file

@ -75,7 +75,7 @@ typedef struct mbedtls_x509_crt {
mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */
mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName, uniformResourceIdentifier, DirectoryName and OtherName are listed). */
mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension. These can be later parsed by mbedtls_x509_parse_subject_alt_name. */
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. */
@ -241,6 +241,21 @@ typedef struct mbedtls_x509write_cert {
}
mbedtls_x509write_cert;
/**
* \brief Set Subject Alternative Name
*
* \param ctx Certificate context to use
* \param san_list List of SAN values
*
* \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
*
* \note "dnsName", "uniformResourceIdentifier", "IP address",
* "otherName", and "DirectoryName", as defined in RFC 5280,
* are supported.
*/
int mbedtls_x509write_crt_set_subject_alternative_name(mbedtls_x509write_cert *ctx,
const mbedtls_x509_san_list *san_list);
/**
* Item in a verification chain: cert and flags for it
*/
@ -641,8 +656,12 @@ 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. DNS names and IP addresses are supported. This
* may be \c NULL if the CN need not be verified.
* Subject name. DNS names and IP addresses are fully
* supported, while the URI subtype is partially supported:
* only exact matching, without any normalization procedures
* described in 7.4 of RFC5280, will result in a positive
* URI verification.
* 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
* set to (uint32_t) -1.

View file

@ -60,7 +60,7 @@ typedef struct mbedtls_x509_csr {
unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */
unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */
mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */
mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension. These can be later parsed by mbedtls_x509_parse_subject_alt_name. */
int MBEDTLS_PRIVATE(ext_types); /**< Bit string containing detected and parsed extensions */
@ -83,12 +83,6 @@ typedef struct mbedtls_x509write_csr {
}
mbedtls_x509write_csr;
typedef struct mbedtls_x509_san_list {
mbedtls_x509_subject_alternative_name node;
struct mbedtls_x509_san_list *next;
}
mbedtls_x509_san_list;
#if defined(MBEDTLS_X509_CSR_PARSE_C)
/**
* \brief Load a Certificate Signing Request (CSR) in DER format

View file

@ -105,5 +105,23 @@ typedef struct psa_tls12_prf_key_derivation_s {
} psa_tls12_prf_key_derivation_t;
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
typedef enum {
PSA_PBKDF2_STATE_INIT, /* no input provided */
PSA_PBKDF2_STATE_INPUT_COST_SET, /* input cost has been set */
PSA_PBKDF2_STATE_SALT_SET, /* salt has been set */
PSA_PBKDF2_STATE_PASSWORD_SET, /* password has been set */
PSA_PBKDF2_STATE_OUTPUT /* output has been started */
} psa_pbkdf2_key_derivation_state_t;
typedef struct {
psa_pbkdf2_key_derivation_state_t MBEDTLS_PRIVATE(state);
uint64_t MBEDTLS_PRIVATE(input_cost);
uint8_t *MBEDTLS_PRIVATE(salt);
size_t MBEDTLS_PRIVATE(salt_length);
uint8_t MBEDTLS_PRIVATE(password)[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
size_t MBEDTLS_PRIVATE(password_length);
} psa_pbkdf2_key_derivation_t;
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_CRYPTO_BUILTIN_KEY_DERIVATION_H */

View file

@ -75,9 +75,7 @@
#define PSA_WANT_ALG_HMAC 1
#define PSA_WANT_ALG_MD5 1
#define PSA_WANT_ALG_OFB 1
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
//#define PSA_WANT_ALG_PBKDF2_HMAC 1
#define PSA_WANT_ALG_PBKDF2_HMAC 1
#define PSA_WANT_ALG_RIPEMD160 1
#define PSA_WANT_ALG_RSA_OAEP 1
#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
@ -93,8 +91,7 @@
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
#define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS 1
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
/* Note: when adding support, also adjust include/mbedtls/config_psa.h */
//#define PSA_WANT_ALG_XTS 1
#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1

View file

@ -55,6 +55,9 @@ typedef union {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
psa_tls12_ecjpake_to_pms_t MBEDTLS_PRIVATE(tls12_ecjpake_to_pms);
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
psa_pbkdf2_key_derivation_t MBEDTLS_PRIVATE(pbkdf2);
#endif
} psa_driver_key_derivation_context_t;
#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_KEY_DERIVATION_H */

View file

@ -83,7 +83,7 @@ static inline int mbedtls_key_owner_id_equal(mbedtls_key_owner_id_t id1,
*/
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
#define PSA_CRYPTO_SECURE 1
#include "crypto_spe.h"
#include "../tests/include/spe/crypto_spe.h"
#endif // MBEDTLS_PSA_CRYPTO_SPM
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)

View file

@ -128,12 +128,23 @@
/* Note: for HMAC-SHA-3, the block size is 144 bytes for HMAC-SHA3-226,
* 136 bytes for HMAC-SHA3-256, 104 bytes for SHA3-384, 72 bytes for
* HMAC-SHA3-512. */
#if defined(PSA_WANT_ALG_SHA_512) || defined(PSA_WANT_ALG_SHA_384)
/* Note: PSA_HASH_MAX_SIZE should be kept in sync with MBEDTLS_MD_MAX_SIZE,
* see the note on MBEDTLS_MD_MAX_SIZE for details. */
#if defined(PSA_WANT_ALG_SHA_512)
#define PSA_HASH_MAX_SIZE 64
#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128
#else
#elif defined(PSA_WANT_ALG_SHA_384)
#define PSA_HASH_MAX_SIZE 48
#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128
#elif defined(PSA_WANT_ALG_SHA_256)
#define PSA_HASH_MAX_SIZE 32
#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64
#elif defined(PSA_WANT_ALG_SHA_224)
#define PSA_HASH_MAX_SIZE 28
#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64
#else /* SHA-1 or smaller */
#define PSA_HASH_MAX_SIZE 20
#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64
#endif
/** \def PSA_MAC_MAX_SIZE
@ -261,6 +272,10 @@
* curve. */
#define PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE 32
/* The maximum number of iterations for PBKDF2 on this implementation, in bits.
* This is a vendor-specific macro. This can be configured if necessary */
#define PSA_VENDOR_PBKDF2_MAX_ITERATIONS 0xffffffff
/** The maximum size of a block cipher. */
#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE 16

View file

@ -2102,7 +2102,8 @@
*/
#define PSA_ALG_IS_PBKDF2_HMAC(alg) \
(((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_PBKDF2_HMAC_BASE)
#define PSA_ALG_PBKDF2_HMAC_GET_HASH(pbkdf2_alg) \
(PSA_ALG_CATEGORY_HASH | ((pbkdf2_alg) & PSA_ALG_HASH_MASK))
/** The PBKDF2-AES-CMAC-PRF-128 password hashing / key stretching algorithm.
*
* PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2).

View file

@ -42,7 +42,6 @@ set(src_crypto
entropy_poll.c
error.c
gcm.c
hash_info.c
hkdf.c
hmac_drbg.c
lmots.c
@ -85,6 +84,7 @@ set(src_crypto
sha1.c
sha256.c
sha512.c
sha3.c
threading.c
timing.c
version.c

View file

@ -107,7 +107,6 @@ OBJS_CRYPTO= \
entropy_poll.o \
error.o \
gcm.o \
hash_info.o \
hkdf.o \
hmac_drbg.o \
lmots.o \
@ -150,6 +149,7 @@ OBJS_CRYPTO= \
sha1.o \
sha256.o \
sha512.o \
sha3.o \
threading.o \
timing.o \
version.o \

View file

@ -563,8 +563,10 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
switch (keybits) {
case 128: ctx->nr = 10; break;
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
case 192: ctx->nr = 12; break;
case 256: ctx->nr = 14; break;
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}
@ -610,6 +612,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
}
break;
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
case 12:
for (i = 0; i < 8; i++, RK += 6) {
@ -651,6 +654,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
RK[15] = RK[7] ^ RK[14];
}
break;
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
}
return 0;
@ -1035,6 +1039,24 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#if defined(__ARM_NEON) && defined(__aarch64__)
/* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
* the result for the next block in CBC, and the cost of transferring that data from
* NEON registers, it is faster to use the following on aarch64.
* For 32-bit arm, NEON should be faster. */
#define CBC_XOR_16(r, a, b) do { \
mbedtls_put_unaligned_uint64(r, \
mbedtls_get_unaligned_uint64(a) ^ \
mbedtls_get_unaligned_uint64(b)); \
mbedtls_put_unaligned_uint64(r + 8, \
mbedtls_get_unaligned_uint64(a + 8) ^ \
mbedtls_get_unaligned_uint64(b + 8)); \
} while (0)
#else
#define CBC_XOR_16(r, a, b) mbedtls_xor(r, a, b, 16)
#endif
/*
* AES-CBC buffer encryption/decryption
*/
@ -1068,6 +1090,8 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
}
#endif
const unsigned char *ivp = iv;
if (mode == MBEDTLS_AES_DECRYPT) {
while (length > 0) {
memcpy(temp, input, 16);
@ -1075,8 +1099,7 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
if (ret != 0) {
goto exit;
}
mbedtls_xor(output, output, iv, 16);
CBC_XOR_16(output, output, iv);
memcpy(iv, temp, 16);
@ -1086,18 +1109,19 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
}
} else {
while (length > 0) {
mbedtls_xor(output, input, iv, 16);
CBC_XOR_16(output, input, ivp);
ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
if (ret != 0) {
goto exit;
}
memcpy(iv, output, 16);
ivp = output;
input += 16;
output += 16;
length -= 16;
}
memcpy(iv, ivp, 16);
}
ret = 0;
@ -1172,7 +1196,7 @@ int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
}
while (blocks--) {
if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
/* We are on the last block in a decrypt operation that has
* leftover bytes, so we need to use the next tweak for this block,
* and this tweak for the leftover bytes. Save the current tweak for
@ -1437,45 +1461,53 @@ exit:
*
* http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
*/
static const unsigned char aes_test_ecb_dec[3][16] =
static const unsigned char aes_test_ecb_dec[][16] =
{
{ 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
{ 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
#endif
};
static const unsigned char aes_test_ecb_enc[3][16] =
static const unsigned char aes_test_ecb_enc[][16] =
{
{ 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
{ 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
#endif
};
#if defined(MBEDTLS_CIPHER_MODE_CBC)
static const unsigned char aes_test_cbc_dec[3][16] =
static const unsigned char aes_test_cbc_dec[][16] =
{
{ 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
{ 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
#endif
};
static const unsigned char aes_test_cbc_enc[3][16] =
static const unsigned char aes_test_cbc_enc[][16] =
{
{ 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
{ 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
#endif
};
#endif /* MBEDTLS_CIPHER_MODE_CBC */
@ -1485,10 +1517,11 @@ static const unsigned char aes_test_cbc_enc[3][16] =
*
* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
*/
static const unsigned char aes_test_cfb128_key[3][32] =
static const unsigned char aes_test_cfb128_key[][32] =
{
{ 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
@ -1496,6 +1529,7 @@ static const unsigned char aes_test_cfb128_key[3][32] =
0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
#endif
};
static const unsigned char aes_test_cfb128_iv[16] =
@ -1516,7 +1550,7 @@ static const unsigned char aes_test_cfb128_pt[64] =
0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
};
static const unsigned char aes_test_cfb128_ct[3][64] =
static const unsigned char aes_test_cfb128_ct[][64] =
{
{ 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
@ -1526,6 +1560,7 @@ static const unsigned char aes_test_cfb128_ct[3][64] =
0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
@ -1542,6 +1577,7 @@ static const unsigned char aes_test_cfb128_ct[3][64] =
0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
#endif
};
#endif /* MBEDTLS_CIPHER_MODE_CFB */
@ -1551,10 +1587,11 @@ static const unsigned char aes_test_cfb128_ct[3][64] =
*
* https://csrc.nist.gov/publications/detail/sp/800-38a/final
*/
static const unsigned char aes_test_ofb_key[3][32] =
static const unsigned char aes_test_ofb_key[][32] =
{
{ 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
@ -1562,6 +1599,7 @@ static const unsigned char aes_test_ofb_key[3][32] =
0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
#endif
};
static const unsigned char aes_test_ofb_iv[16] =
@ -1582,7 +1620,7 @@ static const unsigned char aes_test_ofb_pt[64] =
0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
};
static const unsigned char aes_test_ofb_ct[3][64] =
static const unsigned char aes_test_ofb_ct[][64] =
{
{ 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
@ -1592,6 +1630,7 @@ static const unsigned char aes_test_ofb_ct[3][64] =
0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
@ -1608,6 +1647,7 @@ static const unsigned char aes_test_ofb_ct[3][64] =
0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
#endif
};
#endif /* MBEDTLS_CIPHER_MODE_OFB */
@ -1618,7 +1658,7 @@ static const unsigned char aes_test_ofb_ct[3][64] =
* http://www.faqs.org/rfcs/rfc3686.html
*/
static const unsigned char aes_test_ctr_key[3][16] =
static const unsigned char aes_test_ctr_key[][16] =
{
{ 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
@ -1628,7 +1668,7 @@ static const unsigned char aes_test_ctr_key[3][16] =
0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
};
static const unsigned char aes_test_ctr_nonce_counter[3][16] =
static const unsigned char aes_test_ctr_nonce_counter[][16] =
{
{ 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
@ -1638,11 +1678,10 @@ static const unsigned char aes_test_ctr_nonce_counter[3][16] =
0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
};
static const unsigned char aes_test_ctr_pt[3][48] =
static const unsigned char aes_test_ctr_pt[][48] =
{
{ 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
@ -1655,7 +1694,7 @@ static const unsigned char aes_test_ctr_pt[3][48] =
0x20, 0x21, 0x22, 0x23 }
};
static const unsigned char aes_test_ctr_ct[3][48] =
static const unsigned char aes_test_ctr_ct[][48] =
{
{ 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
@ -1801,290 +1840,315 @@ int mbedtls_aes_self_test(int verbose)
/*
* ECB mode
*/
for (i = 0; i < 6; i++) {
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
{
static const int num_tests =
sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
if (verbose != 0) {
mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
for (i = 0; i < num_tests << 1; i++) {
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
memset(buf, 0, 16);
if (verbose != 0) {
mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
if (mode == MBEDTLS_AES_DECRYPT) {
ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
aes_tests = aes_test_ecb_dec[u];
} else {
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
aes_tests = aes_test_ecb_enc[u];
}
memset(buf, 0, 16);
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
mbedtls_printf("skipped\n");
continue;
} else if (ret != 0) {
goto exit;
}
if (mode == MBEDTLS_AES_DECRYPT) {
ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
aes_tests = aes_test_ecb_dec[u];
} else {
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
aes_tests = aes_test_ecb_enc[u];
}
for (j = 0; j < 10000; j++) {
ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
if (ret != 0) {
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
mbedtls_printf("skipped\n");
continue;
} else if (ret != 0) {
goto exit;
}
for (j = 0; j < 10000; j++) {
ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
if (ret != 0) {
goto exit;
}
}
if (memcmp(buf, aes_tests, 16) != 0) {
ret = 1;
goto exit;
}
if (verbose != 0) {
mbedtls_printf("passed\n");
}
}
if (memcmp(buf, aes_tests, 16) != 0) {
ret = 1;
goto exit;
}
if (verbose != 0) {
mbedtls_printf("passed\n");
mbedtls_printf("\n");
}
}
if (verbose != 0) {
mbedtls_printf("\n");
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* CBC mode
*/
for (i = 0; i < 6; i++) {
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
{
static const int num_tests =
sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
if (verbose != 0) {
mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
for (i = 0; i < num_tests << 1; i++) {
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
memset(iv, 0, 16);
memset(prv, 0, 16);
memset(buf, 0, 16);
if (mode == MBEDTLS_AES_DECRYPT) {
ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
aes_tests = aes_test_cbc_dec[u];
} else {
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
aes_tests = aes_test_cbc_enc[u];
}
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
mbedtls_printf("skipped\n");
continue;
} else if (ret != 0) {
goto exit;
}
for (j = 0; j < 10000; j++) {
if (mode == MBEDTLS_AES_ENCRYPT) {
unsigned char tmp[16];
memcpy(tmp, prv, 16);
memcpy(prv, buf, 16);
memcpy(buf, tmp, 16);
if (verbose != 0) {
mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
if (ret != 0) {
memset(iv, 0, 16);
memset(prv, 0, 16);
memset(buf, 0, 16);
if (mode == MBEDTLS_AES_DECRYPT) {
ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
aes_tests = aes_test_cbc_dec[u];
} else {
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
aes_tests = aes_test_cbc_enc[u];
}
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
mbedtls_printf("skipped\n");
continue;
} else if (ret != 0) {
goto exit;
}
}
for (j = 0; j < 10000; j++) {
if (mode == MBEDTLS_AES_ENCRYPT) {
unsigned char tmp[16];
if (memcmp(buf, aes_tests, 16) != 0) {
ret = 1;
goto exit;
memcpy(tmp, prv, 16);
memcpy(prv, buf, 16);
memcpy(buf, tmp, 16);
}
ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
if (ret != 0) {
goto exit;
}
}
if (memcmp(buf, aes_tests, 16) != 0) {
ret = 1;
goto exit;
}
if (verbose != 0) {
mbedtls_printf("passed\n");
}
}
if (verbose != 0) {
mbedtls_printf("passed\n");
mbedtls_printf("\n");
}
}
if (verbose != 0) {
mbedtls_printf("\n");
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/*
* CFB128 mode
*/
for (i = 0; i < 6; i++) {
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
{
static const int num_tests =
sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
if (verbose != 0) {
mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
for (i = 0; i < num_tests << 1; i++) {
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
memcpy(iv, aes_test_cfb128_iv, 16);
memcpy(key, aes_test_cfb128_key[u], keybits / 8);
if (verbose != 0) {
mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
offset = 0;
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
mbedtls_printf("skipped\n");
continue;
} else if (ret != 0) {
goto exit;
}
memcpy(iv, aes_test_cfb128_iv, 16);
memcpy(key, aes_test_cfb128_key[u], keybits / 8);
if (mode == MBEDTLS_AES_DECRYPT) {
memcpy(buf, aes_test_cfb128_ct[u], 64);
aes_tests = aes_test_cfb128_pt;
} else {
memcpy(buf, aes_test_cfb128_pt, 64);
aes_tests = aes_test_cfb128_ct[u];
}
offset = 0;
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
mbedtls_printf("skipped\n");
continue;
} else if (ret != 0) {
goto exit;
}
ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
if (ret != 0) {
goto exit;
}
if (mode == MBEDTLS_AES_DECRYPT) {
memcpy(buf, aes_test_cfb128_ct[u], 64);
aes_tests = aes_test_cfb128_pt;
} else {
memcpy(buf, aes_test_cfb128_pt, 64);
aes_tests = aes_test_cfb128_ct[u];
}
if (memcmp(buf, aes_tests, 64) != 0) {
ret = 1;
goto exit;
ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
if (ret != 0) {
goto exit;
}
if (memcmp(buf, aes_tests, 64) != 0) {
ret = 1;
goto exit;
}
if (verbose != 0) {
mbedtls_printf("passed\n");
}
}
if (verbose != 0) {
mbedtls_printf("passed\n");
mbedtls_printf("\n");
}
}
if (verbose != 0) {
mbedtls_printf("\n");
}
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/*
* OFB mode
*/
for (i = 0; i < 6; i++) {
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
{
static const int num_tests =
sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
if (verbose != 0) {
mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
for (i = 0; i < num_tests << 1; i++) {
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
memcpy(iv, aes_test_ofb_iv, 16);
memcpy(key, aes_test_ofb_key[u], keybits / 8);
if (verbose != 0) {
mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
offset = 0;
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
mbedtls_printf("skipped\n");
continue;
} else if (ret != 0) {
goto exit;
}
memcpy(iv, aes_test_ofb_iv, 16);
memcpy(key, aes_test_ofb_key[u], keybits / 8);
if (mode == MBEDTLS_AES_DECRYPT) {
memcpy(buf, aes_test_ofb_ct[u], 64);
aes_tests = aes_test_ofb_pt;
} else {
memcpy(buf, aes_test_ofb_pt, 64);
aes_tests = aes_test_ofb_ct[u];
}
offset = 0;
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
mbedtls_printf("skipped\n");
continue;
} else if (ret != 0) {
goto exit;
}
ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
if (ret != 0) {
goto exit;
}
if (mode == MBEDTLS_AES_DECRYPT) {
memcpy(buf, aes_test_ofb_ct[u], 64);
aes_tests = aes_test_ofb_pt;
} else {
memcpy(buf, aes_test_ofb_pt, 64);
aes_tests = aes_test_ofb_ct[u];
}
if (memcmp(buf, aes_tests, 64) != 0) {
ret = 1;
goto exit;
ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
if (ret != 0) {
goto exit;
}
if (memcmp(buf, aes_tests, 64) != 0) {
ret = 1;
goto exit;
}
if (verbose != 0) {
mbedtls_printf("passed\n");
}
}
if (verbose != 0) {
mbedtls_printf("passed\n");
mbedtls_printf("\n");
}
}
if (verbose != 0) {
mbedtls_printf("\n");
}
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/*
* CTR mode
*/
for (i = 0; i < 6; i++) {
u = i >> 1;
mode = i & 1;
{
static const int num_tests =
sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
if (verbose != 0) {
mbedtls_printf(" AES-CTR-128 (%s): ",
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
for (i = 0; i < num_tests << 1; i++) {
u = i >> 1;
mode = i & 1;
memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
memcpy(key, aes_test_ctr_key[u], 16);
if (verbose != 0) {
mbedtls_printf(" AES-CTR-128 (%s): ",
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
offset = 0;
if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
goto exit;
}
memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
memcpy(key, aes_test_ctr_key[u], 16);
len = aes_test_ctr_len[u];
offset = 0;
if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
goto exit;
}
if (mode == MBEDTLS_AES_DECRYPT) {
memcpy(buf, aes_test_ctr_ct[u], len);
aes_tests = aes_test_ctr_pt[u];
} else {
memcpy(buf, aes_test_ctr_pt[u], len);
aes_tests = aes_test_ctr_ct[u];
}
len = aes_test_ctr_len[u];
ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
stream_block, buf, buf);
if (ret != 0) {
goto exit;
}
if (mode == MBEDTLS_AES_DECRYPT) {
memcpy(buf, aes_test_ctr_ct[u], len);
aes_tests = aes_test_ctr_pt[u];
} else {
memcpy(buf, aes_test_ctr_pt[u], len);
aes_tests = aes_test_ctr_ct[u];
}
if (memcmp(buf, aes_tests, len) != 0) {
ret = 1;
goto exit;
}
ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
stream_block, buf, buf);
if (ret != 0) {
goto exit;
}
if (verbose != 0) {
mbedtls_printf("passed\n");
if (memcmp(buf, aes_tests, len) != 0) {
ret = 1;
goto exit;
}
if (verbose != 0) {
mbedtls_printf("passed\n");
}
}
}
@ -2094,14 +2158,14 @@ int mbedtls_aes_self_test(int verbose)
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/*
* XTS mode
*/
{
static const int num_tests =
sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
mbedtls_aes_xts_context ctx_xts;
/*
* XTS mode
*/
mbedtls_aes_xts_init(&ctx_xts);
for (i = 0; i < num_tests << 1; i++) {

View file

@ -251,6 +251,7 @@ static void aesce_setkey_enc(unsigned char *rk,
/* Do not write overflow words.*/
continue;
}
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
switch (key_bit_length) {
case 128:
break;
@ -265,6 +266,7 @@ static void aesce_setkey_enc(unsigned char *rk,
rko[7] = rko[6] ^ rki[7];
break;
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
}
}

View file

@ -273,6 +273,7 @@ static void aesni_setkey_enc_128(unsigned char *rk_bytes,
/*
* Key expansion, 192-bit case
*/
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
static void aesni_set_rk_192(__m128i *state0, __m128i *state1, __m128i xword,
unsigned char *rk)
{
@ -327,10 +328,12 @@ static void aesni_setkey_enc_192(unsigned char *rk,
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x40), rk + 24 * 7);
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x80), rk + 24 * 8);
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
/*
* Key expansion, 256-bit case
*/
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
static void aesni_set_rk_256(__m128i state0, __m128i state1, __m128i xword,
__m128i *rk0, __m128i *rk1)
{
@ -387,6 +390,7 @@ static void aesni_setkey_enc_256(unsigned char *rk_bytes,
aesni_set_rk_256(rk[10], rk[11], _mm_aeskeygenassist_si128(rk[11], 0x20), &rk[12], &rk[13]);
aesni_set_rk_256(rk[12], rk[13], _mm_aeskeygenassist_si128(rk[13], 0x40), &rk[14], &rk[15]);
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
#else /* MBEDTLS_AESNI_HAVE_CODE == 1 */
@ -656,6 +660,7 @@ static void aesni_setkey_enc_128(unsigned char *rk,
/*
* Key expansion, 192-bit case
*/
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
static void aesni_setkey_enc_192(unsigned char *rk,
const unsigned char *key)
{
@ -709,10 +714,12 @@ static void aesni_setkey_enc_192(unsigned char *rk,
: "r" (rk), "r" (key)
: "memory", "cc", "0");
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
/*
* Key expansion, 256-bit case
*/
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
static void aesni_setkey_enc_256(unsigned char *rk,
const unsigned char *key)
{
@ -775,6 +782,7 @@ static void aesni_setkey_enc_256(unsigned char *rk,
: "r" (rk), "r" (key)
: "memory", "cc", "0");
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
#endif /* MBEDTLS_AESNI_HAVE_CODE */
@ -787,8 +795,10 @@ int mbedtls_aesni_setkey_enc(unsigned char *rk,
{
switch (bits) {
case 128: aesni_setkey_enc_128(rk, key); break;
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
case 192: aesni_setkey_enc_192(rk, key); break;
case 256: aesni_setkey_enc_256(rk, key); break;
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}

View file

@ -658,6 +658,20 @@
#endif /* TriCore */
#if defined(__arm__)
#if defined(__thumb__) && !defined(__thumb2__)
#if !defined(__ARMCC_VERSION) && !defined(__clang__) \
&& !defined(__llvm__) && !defined(__INTEL_COMPILER)
/*
* Thumb 1 ISA. This code path has only been tested successfully on gcc;
* it does not compile on clang or armclang.
*
* Other compilers which define __GNUC__ may not work. The above macro
* attempts to exclude these untested compilers.
*/
#if !defined(__OPTIMIZE__) && defined(__GNUC__)
/*
* Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about
* our use of r7 below, unless -fomit-frame-pointer is passed.
@ -666,32 +680,39 @@
* x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
* clang and armcc5 under the same conditions).
*
* So, only use the optimized assembly below for optimized build, which avoids
* the build error and is pretty reasonable anyway.
* If gcc needs to use r7, we use r1 as a scratch register and have a few extra
* instructions to preserve/restore it; otherwise, we can use r7 and avoid
* the preserve/restore overhead.
*/
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
#define MULADDC_CANNOT_USE_R7
#endif
#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7)
#if defined(__thumb__) && !defined(__thumb2__)
#define MULADDC_SCRATCH "RS .req r1 \n\t"
#define MULADDC_PRESERVE_SCRATCH "mov r10, r1 \n\t"
#define MULADDC_RESTORE_SCRATCH "mov r1, r10 \n\t"
#define MULADDC_SCRATCH_CLOBBER "r10"
#else /* !defined(__OPTIMIZE__) && defined(__GNUC__) */
#define MULADDC_SCRATCH "RS .req r7 \n\t"
#define MULADDC_PRESERVE_SCRATCH ""
#define MULADDC_RESTORE_SCRATCH ""
#define MULADDC_SCRATCH_CLOBBER "r7"
#endif /* !defined(__OPTIMIZE__) && defined(__GNUC__) */
#define MULADDC_X1_INIT \
asm( \
MULADDC_SCRATCH \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t" \
"lsr r7, r3, #16 \n\t" \
"mov r9, r7 \n\t" \
"lsl r7, r3, #16 \n\t" \
"lsr r7, r7, #16 \n\t" \
"mov r8, r7 \n\t"
"lsr r4, r3, #16 \n\t" \
"mov r9, r4 \n\t" \
"lsl r4, r3, #16 \n\t" \
"lsr r4, r4, #16 \n\t" \
"mov r8, r4 \n\t" \
#define MULADDC_X1_CORE \
MULADDC_PRESERVE_SCRATCH \
"ldmia r0!, {r6} \n\t" \
"lsr r7, r6, #16 \n\t" \
"lsr RS, r6, #16 \n\t" \
"lsl r6, r6, #16 \n\t" \
"lsr r6, r6, #16 \n\t" \
"mov r4, r8 \n\t" \
@ -699,12 +720,12 @@
"mov r3, r9 \n\t" \
"mul r6, r3 \n\t" \
"mov r5, r9 \n\t" \
"mul r5, r7 \n\t" \
"mul r5, RS \n\t" \
"mov r3, r8 \n\t" \
"mul r7, r3 \n\t" \
"mul RS, r3 \n\t" \
"lsr r3, r6, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"lsr r3, r7, #16 \n\t" \
"lsr r3, RS, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"add r4, r4, r2 \n\t" \
"mov r2, #0 \n\t" \
@ -712,9 +733,10 @@
"lsl r3, r6, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r7, #16 \n\t" \
"lsl r3, RS, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
MULADDC_RESTORE_SCRATCH \
"ldr r3, [r1] \n\t" \
"add r4, r4, r3 \n\t" \
"adc r2, r5 \n\t" \
@ -727,11 +749,15 @@
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "r8", "r9", "cc" \
"r6", MULADDC_SCRATCH_CLOBBER, "r8", "r9", "cc" \
);
#endif /* !defined(__ARMCC_VERSION) && !defined(__clang__) */
#elif (__ARM_ARCH >= 6) && \
defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
/* Armv6-M (or later) with DSP Instruction Set Extensions.
* Requires support for either Thumb 2 or Arm ISA.
*/
#define MULADDC_X1_INIT \
{ \
@ -796,7 +822,7 @@
); \
}
#else
#else /* Thumb 2 or Arm ISA, without DSP extensions */
#define MULADDC_X1_INIT \
asm( \
@ -810,9 +836,9 @@
"mov r5, #0 \n\t" \
"ldr r6, [r1] \n\t" \
"umlal r2, r5, r3, r4 \n\t" \
"adds r7, r6, r2 \n\t" \
"adds r4, r6, r2 \n\t" \
"adc r2, r5, #0 \n\t" \
"str r7, [r1], #4 \n\t"
"str r4, [r1], #4 \n\t"
#define MULADDC_X1_STOP \
"str r2, %0 \n\t" \
@ -821,12 +847,12 @@
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "cc" \
"r6", "cc" \
);
#endif /* Thumb */
#endif /* ISA codepath selection */
#endif /* ARMv3 */
#endif /* defined(__arm__) */
#if defined(__alpha__)

View file

@ -521,6 +521,7 @@ static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTL
};
/* CMAC-AES192 Test Data */
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
static const unsigned char aes_192_key[24] = {
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
@ -561,8 +562,10 @@ static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTL
0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
}
};
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
/* CMAC-AES256 Test Data */
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
static const unsigned char aes_256_key[32] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
@ -604,6 +607,7 @@ static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTL
0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
}
};
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_DES_C)
@ -951,6 +955,7 @@ int mbedtls_cmac_self_test(int verbose)
}
/* AES-192 */
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
if ((ret = cmac_test_subkeys(verbose,
"AES 192",
aes_192_key,
@ -974,8 +979,10 @@ int mbedtls_cmac_self_test(int verbose)
NB_CMAC_TESTS_PER_KEY)) != 0) {
return ret;
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
/* AES-256 */
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
if ((ret = cmac_test_subkeys(verbose,
"AES 256",
aes_256_key,
@ -999,6 +1006,7 @@ int mbedtls_cmac_self_test(int verbose)
NB_CMAC_TESTS_PER_KEY)) != 0) {
return ret;
}
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_DES_C)

View file

@ -31,6 +31,10 @@
#include <stdint.h>
#include <stddef.h>
#if defined(__ARM_NEON)
#include <arm_neon.h>
#endif /* __ARM_NEON */
/** Helper to define a function as static except when building invasive tests.
*
* If a function is only used inside its own source file and should be
@ -125,10 +129,25 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
{
size_t i = 0;
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
#if defined(__ARM_NEON)
for (; (i + 16) <= n; i += 16) {
uint8x16_t v1 = vld1q_u8(a + i);
uint8x16_t v2 = vld1q_u8(b + i);
uint8x16_t x = veorq_u8(v1, v2);
vst1q_u8(r + i, x);
}
#elif defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__)
/* This codepath probably only makes sense on architectures with 64-bit registers */
for (; (i + 8) <= n; i += 8) {
uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
mbedtls_put_unaligned_uint64(r + i, x);
}
#else
for (; (i + 4) <= n; i += 4) {
uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
mbedtls_put_unaligned_uint32(r + i, x);
}
#endif
#endif
for (; i < n; i++) {
r[i] = a[i] ^ b[i];
@ -164,4 +183,16 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
#define MBEDTLS_STATIC_ASSERT(expr, msg)
#endif
/* Define compiler branch hints */
#if defined(__has_builtin)
#if __has_builtin(__builtin_expect)
#define MBEDTLS_LIKELY(x) __builtin_expect((x), 1)
#define MBEDTLS_UNLIKELY(x) __builtin_expect((x), 0)
#endif
#endif
#if !defined(MBEDTLS_LIKELY)
#define MBEDTLS_LIKELY(x) x
#define MBEDTLS_UNLIKELY(x) x
#endif
#endif /* MBEDTLS_LIBRARY_COMMON_H */

View file

@ -203,6 +203,52 @@ void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_BIGNUM_C)
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
void mbedtls_debug_print_psa_ec(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_pk_context *pk)
{
char str[DEBUG_BUF_SIZE];
mbedtls_mpi mpi;
const uint8_t *mpi_start;
size_t mpi_len;
int ret;
if (NULL == ssl ||
NULL == ssl->conf ||
NULL == ssl->conf->f_dbg ||
level > debug_threshold) {
return;
}
/* For the description of pk->pk_raw content please refer to the description
* psa_export_public_key() function. */
mpi_len = (pk->pub_raw_len - 1)/2;
/* X coordinate */
mbedtls_mpi_init(&mpi);
mpi_start = pk->pub_raw + 1;
ret = mbedtls_mpi_read_binary(&mpi, mpi_start, mpi_len);
if (ret != 0) {
return;
}
mbedtls_snprintf(str, sizeof(str), "%s(X)", text);
mbedtls_debug_print_mpi(ssl, level, file, line, str, &mpi);
mbedtls_mpi_free(&mpi);
/* Y coordinate */
mbedtls_mpi_init(&mpi);
mpi_start = mpi_start + mpi_len;
ret = mbedtls_mpi_read_binary(&mpi, mpi_start, mpi_len);
if (ret != 0) {
return;
}
mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
mbedtls_debug_print_mpi(ssl, level, file, line, str, &mpi);
mbedtls_mpi_free(&mpi);
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X)
@ -285,6 +331,11 @@ static void debug_print_pk(const mbedtls_ssl_context *ssl, int level,
if (items[i].type == MBEDTLS_PK_DEBUG_ECP) {
mbedtls_debug_print_ecp(ssl, level, file, line, name, items[i].value);
} else
#endif
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if (items[i].type == MBEDTLS_PK_DEBUG_PSA_EC) {
mbedtls_debug_print_psa_ec(ssl, level, file, line, name, items[i].value);
} else
#endif
{ debug_send_line(ssl, level, file, line,
"should not happen\n"); }

View file

@ -30,8 +30,6 @@
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "hash_info.h"
#include <string.h>
#if !defined(MBEDTLS_ECJPAKE_ALT)
@ -217,7 +215,7 @@ static int ecjpake_hash(const mbedtls_md_type_t md_type,
unsigned char *p = buf;
const unsigned char *end = buf + sizeof(buf);
const size_t id_len = strlen(id);
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
/* Write things to temporary buffer */
MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, G));
@ -244,7 +242,7 @@ static int ecjpake_hash(const mbedtls_md_type_t md_type,
/* Turn it into an integer mod n */
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(h, hash,
mbedtls_hash_info_get_size(md_type)));
mbedtls_md_get_size_from_type(md_type)));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(h, h, &grp->N));
cleanup:
@ -780,7 +778,7 @@ int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
size_t x_bytes;
*olen = mbedtls_hash_info_get_size(ctx->md_type);
*olen = mbedtls_md_get_size_from_type(ctx->md_type);
if (len < *olen) {
return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
}

View file

@ -22,6 +22,7 @@
#if defined(MBEDTLS_ECP_LIGHT)
#include "mbedtls/ecp.h"
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@ -4604,26 +4605,28 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n);
/* Additional forward declarations */
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
static int ecp_mod_p255(mbedtls_mpi *);
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#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 *);
int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *, size_t);
#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 *);
int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#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 *);
int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#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 *);
int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif
#if defined(ECP_LOAD_GROUP)
@ -5417,27 +5420,57 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs)
*/
static int ecp_mod_p255(mbedtls_mpi *N)
{
mbedtls_mpi_uint Mp[P255_WIDTH];
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t expected_width = 2 * P255_WIDTH;
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
ret = mbedtls_ecp_mod_p255_raw(N->p, expected_width);
cleanup:
return ret;
}
/* Helper references for top part of N */
mbedtls_mpi_uint * const NT_p = N->p + P255_WIDTH;
const size_t NT_n = N->n - P255_WIDTH;
if (N->n <= P255_WIDTH) {
return 0;
}
if (NT_n > P255_WIDTH) {
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs)
{
if (X_Limbs != 2 * P255_WIDTH) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
/* Split N as N + 2^256 M */
memcpy(Mp, NT_p, sizeof(mbedtls_mpi_uint) * NT_n);
memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n);
mbedtls_mpi_uint *carry = mbedtls_calloc(P255_WIDTH, ciL);
if (carry == NULL) {
return MBEDTLS_ERR_ECP_ALLOC_FAILED;
}
/* N = A0 + 38 * A1 */
mbedtls_mpi_core_mla(N->p, P255_WIDTH + 1,
Mp, NT_n,
38);
/* Step 1: Reduction to P255_WIDTH limbs */
if (X_Limbs > P255_WIDTH) {
/* Helper references for top part of X */
mbedtls_mpi_uint * const A1 = X + P255_WIDTH;
const size_t A1_limbs = X_Limbs - P255_WIDTH;
/* X = A0 + 38 * A1, capture carry out */
*carry = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38);
/* Clear top part */
memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs);
}
/* Step 2: Reduce to <2p
* Split as A0 + 2^255*c, with c a scalar, and compute A0 + 19*c */
*carry <<= 1;
*carry += (X[P255_WIDTH - 1] >> (biL - 1));
*carry *= 19;
/* Clear top bit */
X[P255_WIDTH - 1] <<= 1; X[P255_WIDTH - 1] >>= 1;
/* Since the top bit for X has been cleared 0 + 0 + Carry
* will not overflow.
*
* Furthermore for 2p = 2^256-38. When a carry propagation on the highest
* limb occurs, X > 2^255 and all the remaining bits on the limb are zero.
* - If X < 2^255 ==> X < 2p
* - If X > 2^255 ==> X < 2^256 - 2^255 < 2p */
(void) mbedtls_mpi_core_add(X, X, carry, P255_WIDTH);
mbedtls_free(carry);
return 0;
}
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
@ -5455,71 +5488,108 @@ static int ecp_mod_p255(mbedtls_mpi *N)
static int ecp_mod_p448(mbedtls_mpi *N)
{
return mbedtls_ecp_mod_p448(N);
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t expected_width = 2 * ((448 + biL - 1) / biL);
/* This is required as some tests and use cases do not pass in a Bignum of
* the correct size, and expect the growth to be done automatically, which
* will no longer happen. */
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
ret = mbedtls_ecp_mod_p448(N->p, N->n);
cleanup:
return ret;
}
/*
* 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
* A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
* implementation of Curve448, which uses its own special 56-bit limbs rather
* than a generic bignum library. We could squeeze some extra speed out on
* 32-bit machines by splitting N up into 32-bit limbs and doing the
* arithmetic using the limbs directly as we do for the NIST primes above,
* 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.
* Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 +
* (B0 + B1) * 2^224. This is different to the reference implementation of
* Curve448, which uses its own special 56-bit limbs rather than a generic
* bignum library. We could squeeze some extra speed out on 32-bit machines by
* splitting N up into 32-bit limbs and doing the arithmetic using the limbs
* directly as we do for the NIST primes above, but for 64-bit targets it should
* use half the number of operations if we do the reduction with 224-bit limbs,
* since mpi_core_add will then use 64-bit adds.
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p448(mbedtls_mpi *N)
int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *X, size_t X_limbs)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M, Q;
mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if (N->n <= P448_WIDTH) {
if (X_limbs <= P448_WIDTH) {
return 0;
}
/* M = A1 */
M.s = 1;
M.n = N->n - (P448_WIDTH);
if (M.n > P448_WIDTH) {
/* Shouldn't be called with N larger than 2^896! */
size_t M_limbs = X_limbs - (P448_WIDTH);
const size_t Q_limbs = M_limbs;
if (M_limbs > P448_WIDTH) {
/* Shouldn't be called with X larger than 2^896! */
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
M.p = Mp;
memset(Mp, 0, sizeof(Mp));
memcpy(Mp, N->p + P448_WIDTH, M.n * sizeof(mbedtls_mpi_uint));
/* N = A0 */
for (i = P448_WIDTH; i < N->n; i++) {
N->p[i] = 0;
/* Extra limb for carry below. */
M_limbs++;
mbedtls_mpi_uint *M = mbedtls_calloc(M_limbs, ciL);
if (M == NULL) {
return MBEDTLS_ERR_ECP_ALLOC_FAILED;
}
/* N += A1 */
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
mbedtls_mpi_uint *Q = mbedtls_calloc(Q_limbs, ciL);
/* Q = B1, N += B1 */
Q = M;
Q.p = Qp;
memcpy(Qp, Mp, sizeof(Qp));
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Q, 224));
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &Q));
if (Q == NULL) {
ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
goto cleanup;
}
/* M = (B0 + B1) * 2^224, N += M */
/* M = A1 */
memset(M, 0, (M_limbs * ciL));
/* Do not copy into the overflow limb, as this would read past the end of
* X. */
memcpy(M, X + P448_WIDTH, ((M_limbs - 1) * ciL));
/* X = A0 */
for (i = P448_WIDTH; i < X_limbs; i++) {
X[i] = 0;
}
/* X += A1 - Carry here dealt with by oversize M and X. */
(void) mbedtls_mpi_core_add(X, X, M, M_limbs);
/* Q = B1, X += B1 */
memcpy(Q, M, (Q_limbs * ciL));
mbedtls_mpi_core_shift_r(Q, Q_limbs, 224);
/* No carry here - only max 224 bits */
(void) mbedtls_mpi_core_add(X, X, Q, Q_limbs);
/* M = (B0 + B1) * 2^224, X += M */
if (sizeof(mbedtls_mpi_uint) > 4) {
Mp[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
M[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
}
for (i = P224_WIDTH_MAX; i < M.n; ++i) {
Mp[i] = 0;
for (i = P224_WIDTH_MAX; i < M_limbs; ++i) {
M[i] = 0;
}
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&M, &M, &Q));
M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&M, 224));
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
(void) mbedtls_mpi_core_add(M, M, Q, Q_limbs);
/* Shifted carry bit from the addition is dealt with by oversize M */
mbedtls_mpi_core_shift_l(M, M_limbs, 224);
(void) mbedtls_mpi_core_add(X, X, M, M_limbs);
ret = 0;
cleanup:
mbedtls_free(M);
mbedtls_free(Q);
return ret;
}
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
@ -5532,7 +5602,7 @@ cleanup:
* Fast quasi-reduction modulo P = 2^s - R,
* with R about 33 bits, used by the Koblitz curves.
*
* Write N as A0 + 2^224 A1, return A0 + R * A1.
* Write X as A0 + 2^224 A1, return A0 + R * A1.
*/
#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R
@ -5629,81 +5699,95 @@ static int ecp_mod_p192k1(mbedtls_mpi *N)
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t expected_width = 2 * ((192 + biL - 1) / biL);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
ret = mbedtls_ecp_mod_p192k1(N);
ret = mbedtls_ecp_mod_p192k1_raw(N->p, expected_width);
cleanup:
return ret;
}
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p192k1(mbedtls_mpi *N)
int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
{
static mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00)
};
return ecp_mod_koblitz(N->p, N->n, Rp, 192);
if (X_limbs != 2 * ((192 + biL - 1) / biL)) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
return ecp_mod_koblitz(X, X_limbs, Rp, 192);
}
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
/*
* 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)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t expected_width = 2 * 224 / biL;
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
ret = mbedtls_ecp_mod_p224k1(N);
ret = mbedtls_ecp_mod_p224k1_raw(N->p, expected_width);
cleanup:
return ret;
}
/*
* 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
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p224k1(mbedtls_mpi *N)
int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
{
static mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00)
};
return ecp_mod_koblitz(N->p, N->n, Rp, 224);
if (X_limbs != 2 * 224 / biL) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
return ecp_mod_koblitz(X, X_limbs, Rp, 224);
}
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
/*
* 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)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t expected_width = 2 * ((256 + biL - 1) / biL);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
ret = mbedtls_ecp_mod_p256k1(N);
ret = mbedtls_ecp_mod_p256k1_raw(N->p, expected_width);
cleanup:
return ret;
}
/*
* Fast quasi-reduction modulo p256k1 = 2^256 - R,
* with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p256k1(mbedtls_mpi *N)
int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
{
static mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00)
};
return ecp_mod_koblitz(N->p, N->n, Rp, 256);
if (X_limbs != 2 * ((256 + biL - 1) / biL)) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
return ecp_mod_koblitz(X, X_limbs, Rp, 256);
}
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
#if defined(MBEDTLS_TEST_HOOKS)

View file

@ -171,32 +171,101 @@ int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#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
/** Fast quasi-reduction modulo p192k1 = 2^192 - R,
* with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9
*
* \param[in,out] X The address of the MPI to be converted.
* Must have exact limb size that stores a 384-bit MPI
* (double the bitlength of the modulus).
* Upon return holds the reduced value which is
* in range `0 <= X < 2 * N` (where N is the modulus).
* The bitlength of the reduced value is the same as
* that of the modulus (192 bits).
* \param[in] X_limbs The length of \p X in limbs.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
* twice as many limbs as the modulus.
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p192k1(mbedtls_mpi *N);
int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
/** 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
*
* \param[in,out] X The address of the MPI to be converted.
* Must have exact limb size that stores a 448-bit MPI
* (double the bitlength of the modulus).
* Upon return holds the reduced value which is
* in range `0 <= X < 2 * N` (where N is the modulus).
* The bitlength of the reduced value is the same as
* that of the modulus (224 bits).
* \param[in] X_limbs The length of \p X in limbs.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
* twice as many limbs as the modulus.
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p224k1(mbedtls_mpi *N);
int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
/** Fast quasi-reduction modulo p256k1 = 2^256 - R,
* with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
*
* \param[in,out] X The address of the MPI to be converted.
* Must have exact limb size that stores a 512-bit MPI
* (double the bitlength of the modulus).
* Upon return holds the reduced value which is
* in range `0 <= X < 2 * N` (where N is the modulus).
* The bitlength of the reduced value is the same as
* that of the modulus (256 bits).
* \param[in] X_limbs The length of \p X in limbs.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
* twice as many limbs as the modulus.
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p256k1(mbedtls_mpi *N);
int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
/** Fast quasi-reduction modulo p255 = 2^255 - 19
*
* \param[in,out] X The address of the MPI to be converted.
* Must have exact limb size that stores a 510-bit MPI
* (double the bitlength of the modulus).
* Upon return holds the reduced value which is
* in range `0 <= X < 2 * N` (where N is the modulus).
* \param[in] X_limbs The length of \p X in limbs.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
* twice as many limbs as the modulus.
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
*/
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
MBEDTLS_STATIC_TESTABLE
int mbedtls_ecp_mod_p448(mbedtls_mpi *N);
int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */

View file

@ -645,7 +645,7 @@ void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
static const int key_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
static const unsigned char key_test_data[MAX_TESTS][32] =
static const unsigned char key_test_data[][32] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -663,7 +663,7 @@ static const size_t iv_len_test_data[MAX_TESTS] =
static const int iv_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 2 };
static const unsigned char iv_test_data[MAX_TESTS][64] =
static const unsigned char iv_test_data[][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
@ -685,7 +685,7 @@ static const size_t add_len_test_data[MAX_TESTS] =
static const int add_index_test_data[MAX_TESTS] =
{ 0, 0, 0, 1, 1, 1 };
static const unsigned char additional_test_data[MAX_TESTS][64] =
static const unsigned char additional_test_data[][64] =
{
{ 0x00 },
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
@ -699,7 +699,7 @@ static const size_t pt_len_test_data[MAX_TESTS] =
static const int pt_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
static const unsigned char pt_test_data[MAX_TESTS][64] =
static const unsigned char pt_test_data[][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@ -713,7 +713,7 @@ static const unsigned char pt_test_data[MAX_TESTS][64] =
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
};
static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
static const unsigned char ct_test_data[][64] =
{
{ 0x00 },
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
@ -750,6 +750,7 @@ static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
0x4c, 0x34, 0xae, 0xe5 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x00 },
{ 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
@ -820,9 +821,10 @@ static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
0x44, 0xae, 0x7e, 0x3f },
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
};
static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
static const unsigned char tag_test_data[][16] =
{
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
@ -836,6 +838,7 @@ static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
{ 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
{ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
@ -860,6 +863,7 @@ static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
{ 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
};
int mbedtls_gcm_self_test(int verbose)
@ -884,17 +888,20 @@ int mbedtls_gcm_self_test(int verbose)
#endif /* MBEDTLS_GCM_ALT */
}
for (j = 0; j < 3; j++) {
static const int loop_limit =
(sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
for (j = 0; j < loop_limit; j++) {
int key_len = 128 + 64 * j;
for (i = 0; i < MAX_TESTS; i++) {
mbedtls_gcm_init(&ctx);
if (verbose != 0) {
mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
key_len, i, "enc");
}
mbedtls_gcm_init(&ctx);
ret = mbedtls_gcm_setkey(&ctx, cipher,
key_test_data[key_index_test_data[i]],
key_len);

View file

@ -1,122 +0,0 @@
/*
* Hash information that's independent from the crypto implementation.
*
* (See the corresponding header file for usage notes.)
*/
/*
* 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 "hash_info.h"
#include "mbedtls/error.h"
typedef struct {
psa_algorithm_t psa_alg;
mbedtls_md_type_t md_type;
unsigned char size;
unsigned char block_size;
} hash_entry;
static const hash_entry hash_table[] = {
#if defined(MBEDTLS_MD_CAN_MD5)
{ PSA_ALG_MD5, MBEDTLS_MD_MD5, 16, 64 },
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
{ PSA_ALG_RIPEMD160, MBEDTLS_MD_RIPEMD160, 20, 64 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
{ PSA_ALG_SHA_1, MBEDTLS_MD_SHA1, 20, 64 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
{ PSA_ALG_SHA_224, MBEDTLS_MD_SHA224, 28, 64 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
{ PSA_ALG_SHA_256, MBEDTLS_MD_SHA256, 32, 64 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
{ PSA_ALG_SHA_384, MBEDTLS_MD_SHA384, 48, 128 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
{ PSA_ALG_SHA_512, MBEDTLS_MD_SHA512, 64, 128 },
#endif
{ PSA_ALG_NONE, MBEDTLS_MD_NONE, 0, 0 },
};
/* Get size from MD type */
unsigned char mbedtls_hash_info_get_size(mbedtls_md_type_t md_type)
{
const hash_entry *entry = hash_table;
while (entry->md_type != MBEDTLS_MD_NONE &&
entry->md_type != md_type) {
entry++;
}
return entry->size;
}
/* Get block size from MD type */
unsigned char mbedtls_hash_info_get_block_size(mbedtls_md_type_t md_type)
{
const hash_entry *entry = hash_table;
while (entry->md_type != MBEDTLS_MD_NONE &&
entry->md_type != md_type) {
entry++;
}
return entry->block_size;
}
/* Get PSA from MD */
psa_algorithm_t mbedtls_hash_info_psa_from_md(mbedtls_md_type_t md_type)
{
const hash_entry *entry = hash_table;
while (entry->md_type != MBEDTLS_MD_NONE &&
entry->md_type != md_type) {
entry++;
}
return entry->psa_alg;
}
/* Get MD from PSA */
mbedtls_md_type_t mbedtls_hash_info_md_from_psa(psa_algorithm_t psa_alg)
{
const hash_entry *entry = hash_table;
while (entry->md_type != MBEDTLS_MD_NONE &&
entry->psa_alg != psa_alg) {
entry++;
}
return entry->md_type;
}
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_md_error_from_psa(psa_status_t status)
{
switch (status) {
case PSA_SUCCESS:
return 0;
case PSA_ERROR_NOT_SUPPORTED:
return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
case PSA_ERROR_INVALID_ARGUMENT:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
case PSA_ERROR_INSUFFICIENT_MEMORY:
return MBEDTLS_ERR_MD_ALLOC_FAILED;
default:
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
}
}
#endif /* !MBEDTLS_DEPRECATED_REMOVED */

View file

@ -1,101 +0,0 @@
/**
* Hash information that's independent from the crypto implementation.
*
* This can be used by:
* - code based on PSA
* - code based on the legacy API
* - code based on either of them depending on MBEDTLS_USE_PSA_CRYPTO
* - code based on either of them depending on what's available
*
* Note: this internal module will go away when everything becomes based on
* PSA Crypto; it is a helper for the transition while hash algorithms are
* still represented using mbedtls_md_type_t in most places even when PSA is
* used for the actual crypto computations.
*
* 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_HASH_INFO_H
#define MBEDTLS_HASH_INFO_H
#include "common.h"
#include "mbedtls/md.h"
#include "psa/crypto.h"
#include "mbedtls/platform_util.h"
/** \def MBEDTLS_HASH_MAX_SIZE
*
* Maximum size of a hash based on configuration.
*/
#if defined(MBEDTLS_MD_C) && ( \
!defined(MBEDTLS_PSA_CRYPTO_C) || \
MBEDTLS_MD_MAX_SIZE >= PSA_HASH_MAX_SIZE)
#define MBEDTLS_HASH_MAX_SIZE MBEDTLS_MD_MAX_SIZE
#elif defined(MBEDTLS_PSA_CRYPTO_C) && ( \
!defined(MBEDTLS_MD_C) || \
PSA_HASH_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE)
#define MBEDTLS_HASH_MAX_SIZE PSA_HASH_MAX_SIZE
#endif
/** Get the output length of the given hash type from its MD type.
*
* \note To get the output length from the PSA alg, use \c PSA_HASH_LENGTH().
*
* \param md_type The hash MD type.
*
* \return The output length in bytes, or 0 if not known.
*/
unsigned char mbedtls_hash_info_get_size(mbedtls_md_type_t md_type);
/** Get the block size of the given hash type from its MD type.
*
* \note To get the output length from the PSA alg, use
* \c PSA_HASH_BLOCK_LENGTH().
*
* \param md_type The hash MD type.
*
* \return The block size in bytes, or 0 if not known.
*/
unsigned char mbedtls_hash_info_get_block_size(mbedtls_md_type_t md_type);
/** Get the PSA alg from the MD type.
*
* \param md_type The hash MD type.
*
* \return The corresponding PSA algorithm identifier,
* or PSA_ALG_NONE if not known.
*/
psa_algorithm_t mbedtls_hash_info_psa_from_md(mbedtls_md_type_t md_type);
/** Get the MD type alg from the PSA algorithm identifier.
*
* \param psa_alg The PSA hash algorithm.
*
* \return The corresponding MD type,
* or MBEDTLS_MD_NONE if not known.
*/
mbedtls_md_type_t mbedtls_hash_info_md_from_psa(psa_algorithm_t psa_alg);
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/** Convert PSA status to MD error code.
*
* \param status PSA status.
*
* \return The corresponding MD error code,
*/
int MBEDTLS_DEPRECATED mbedtls_md_error_from_psa(psa_status_t status);
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_HASH_INFO_H */

View file

@ -51,9 +51,15 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "mbedtls/sha3.h"
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include <psa/crypto.h>
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#endif
#if defined(MBEDTLS_MD_SOME_PSA)
#include <psa/crypto.h>
#include "psa_crypto_core.h"
#endif
@ -65,6 +71,11 @@
#include <stdio.h>
#endif
/* See comment above MBEDTLS_MD_MAX_SIZE in md.h */
#if defined(MBEDTLS_PSA_CRYPTO_C) && MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE
#error "Internal error: MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE"
#endif
#if defined(MBEDTLS_MD_CAN_MD5)
const mbedtls_md_info_t mbedtls_md5_info = {
"MD5",
@ -128,6 +139,42 @@ const mbedtls_md_info_t mbedtls_sha512_info = {
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
const mbedtls_md_info_t mbedtls_sha3_224_info = {
"SHA3-224",
MBEDTLS_MD_SHA3_224,
28,
144,
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
const mbedtls_md_info_t mbedtls_sha3_256_info = {
"SHA3-256",
MBEDTLS_MD_SHA3_256,
32,
136,
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
const mbedtls_md_info_t mbedtls_sha3_384_info = {
"SHA3-384",
MBEDTLS_MD_SHA3_384,
48,
104,
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
const mbedtls_md_info_t mbedtls_sha3_512_info = {
"SHA3-512",
MBEDTLS_MD_SHA3_512,
64,
72,
};
#endif
const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type)
{
switch (md_type) {
@ -158,6 +205,22 @@ const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type)
#if defined(MBEDTLS_MD_CAN_SHA512)
case MBEDTLS_MD_SHA512:
return &mbedtls_sha512_info;
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
case MBEDTLS_MD_SHA3_224:
return &mbedtls_sha3_224_info;
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
case MBEDTLS_MD_SHA3_256:
return &mbedtls_sha3_256_info;
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
case MBEDTLS_MD_SHA3_384:
return &mbedtls_sha3_384_info;
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
case MBEDTLS_MD_SHA3_512:
return &mbedtls_sha3_512_info;
#endif
default:
return NULL;
@ -210,20 +273,6 @@ static int md_can_use_psa(const mbedtls_md_info_t *info)
return psa_can_do_hash(alg);
}
static int mbedtls_md_error_from_psa(psa_status_t status)
{
switch (status) {
case PSA_SUCCESS:
return 0;
case PSA_ERROR_NOT_SUPPORTED:
return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
case PSA_ERROR_INSUFFICIENT_MEMORY:
return MBEDTLS_ERR_MD_ALLOC_FAILED;
default:
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
}
}
#endif /* MBEDTLS_MD_SOME_PSA */
void mbedtls_md_init(mbedtls_md_context_t *ctx)
@ -279,6 +328,14 @@ void mbedtls_md_free(mbedtls_md_context_t *ctx)
case MBEDTLS_MD_SHA512:
mbedtls_sha512_free(ctx->md_ctx);
break;
#endif
#if defined(MBEDTLS_SHA3_C)
case MBEDTLS_MD_SHA3_224:
case MBEDTLS_MD_SHA3_256:
case MBEDTLS_MD_SHA3_384:
case MBEDTLS_MD_SHA3_512:
mbedtls_sha3_free(ctx->md_ctx);
break;
#endif
default:
/* Shouldn't happen */
@ -357,6 +414,14 @@ int mbedtls_md_clone(mbedtls_md_context_t *dst,
case MBEDTLS_MD_SHA512:
mbedtls_sha512_clone(dst->md_ctx, src->md_ctx);
break;
#endif
#if defined(MBEDTLS_SHA3_C)
case MBEDTLS_MD_SHA3_224:
case MBEDTLS_MD_SHA3_256:
case MBEDTLS_MD_SHA3_384:
case MBEDTLS_MD_SHA3_512:
mbedtls_sha3_clone(dst->md_ctx, src->md_ctx);
break;
#endif
default:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
@ -376,7 +441,12 @@ int mbedtls_md_clone(mbedtls_md_context_t *dst,
int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac)
{
if (md_info == NULL || ctx == NULL) {
#if defined(MBEDTLS_MD_C)
if (ctx == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
#endif
if (md_info == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
@ -434,6 +504,14 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info
case MBEDTLS_MD_SHA512:
ALLOC(sha512);
break;
#endif
#if defined(MBEDTLS_SHA3_C)
case MBEDTLS_MD_SHA3_224:
case MBEDTLS_MD_SHA3_256:
case MBEDTLS_MD_SHA3_384:
case MBEDTLS_MD_SHA3_512:
ALLOC(sha3);
break;
#endif
default:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
@ -455,9 +533,11 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info
int mbedtls_md_starts(mbedtls_md_context_t *ctx)
{
#if defined(MBEDTLS_MD_C)
if (ctx == NULL || ctx->md_info == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
#endif
#if defined(MBEDTLS_MD_SOME_PSA)
if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
@ -496,6 +576,16 @@ int mbedtls_md_starts(mbedtls_md_context_t *ctx)
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA512:
return mbedtls_sha512_starts(ctx->md_ctx, 0);
#endif
#if defined(MBEDTLS_SHA3_C)
case MBEDTLS_MD_SHA3_224:
return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_224);
case MBEDTLS_MD_SHA3_256:
return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_256);
case MBEDTLS_MD_SHA3_384:
return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_384);
case MBEDTLS_MD_SHA3_512:
return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_512);
#endif
default:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
@ -504,9 +594,11 @@ int mbedtls_md_starts(mbedtls_md_context_t *ctx)
int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen)
{
#if defined(MBEDTLS_MD_C)
if (ctx == NULL || ctx->md_info == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
#endif
#if defined(MBEDTLS_MD_SOME_PSA)
if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
@ -543,6 +635,13 @@ int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, siz
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA512:
return mbedtls_sha512_update(ctx->md_ctx, input, ilen);
#endif
#if defined(MBEDTLS_SHA3_C)
case MBEDTLS_MD_SHA3_224:
case MBEDTLS_MD_SHA3_256:
case MBEDTLS_MD_SHA3_384:
case MBEDTLS_MD_SHA3_512:
return mbedtls_sha3_update(ctx->md_ctx, input, ilen);
#endif
default:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
@ -551,9 +650,11 @@ int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, siz
int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output)
{
#if defined(MBEDTLS_MD_C)
if (ctx == NULL || ctx->md_info == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
#endif
#if defined(MBEDTLS_MD_SOME_PSA)
if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
@ -592,6 +693,13 @@ int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output)
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA512:
return mbedtls_sha512_finish(ctx->md_ctx, output);
#endif
#if defined(MBEDTLS_SHA3_C)
case MBEDTLS_MD_SHA3_224:
case MBEDTLS_MD_SHA3_256:
case MBEDTLS_MD_SHA3_384:
case MBEDTLS_MD_SHA3_512:
return mbedtls_sha3_finish(ctx->md_ctx, output, ctx->md_info->size);
#endif
default:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
@ -643,6 +751,16 @@ int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, siz
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA512:
return mbedtls_sha512(input, ilen, output, 0);
#endif
#if defined(MBEDTLS_SHA3_C)
case MBEDTLS_MD_SHA3_224:
return mbedtls_sha3(MBEDTLS_SHA3_224, input, ilen, output, md_info->size);
case MBEDTLS_MD_SHA3_256:
return mbedtls_sha3(MBEDTLS_SHA3_256, input, ilen, output, md_info->size);
case MBEDTLS_MD_SHA3_384:
return mbedtls_sha3(MBEDTLS_SHA3_384, input, ilen, output, md_info->size);
case MBEDTLS_MD_SHA3_512:
return mbedtls_sha3(MBEDTLS_SHA3_512, input, ilen, output, md_info->size);
#endif
default:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
@ -667,6 +785,87 @@ mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info)
return md_info->type;
}
#if defined(MBEDTLS_PSA_CRYPTO_C)
psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type)
{
switch (md_type) {
#if defined(MBEDTLS_MD_CAN_MD5)
case MBEDTLS_MD_MD5:
return PSA_ALG_MD5;
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
case MBEDTLS_MD_RIPEMD160:
return PSA_ALG_RIPEMD160;
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
case MBEDTLS_MD_SHA1:
return PSA_ALG_SHA_1;
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
case MBEDTLS_MD_SHA224:
return PSA_ALG_SHA_224;
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
case MBEDTLS_MD_SHA256:
return PSA_ALG_SHA_256;
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
case MBEDTLS_MD_SHA384:
return PSA_ALG_SHA_384;
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
case MBEDTLS_MD_SHA512:
return PSA_ALG_SHA_512;
#endif
default:
return PSA_ALG_NONE;
}
}
mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg)
{
switch (psa_alg) {
#if defined(MBEDTLS_MD_CAN_MD5)
case PSA_ALG_MD5:
return MBEDTLS_MD_MD5;
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
case PSA_ALG_RIPEMD160:
return MBEDTLS_MD_RIPEMD160;
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
case PSA_ALG_SHA_1:
return MBEDTLS_MD_SHA1;
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
case PSA_ALG_SHA_224:
return MBEDTLS_MD_SHA224;
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
case PSA_ALG_SHA_256:
return MBEDTLS_MD_SHA256;
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
case PSA_ALG_SHA_384:
return MBEDTLS_MD_SHA384;
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
case PSA_ALG_SHA_512:
return MBEDTLS_MD_SHA512;
#endif
default:
return MBEDTLS_MD_NONE;
}
}
int mbedtls_md_error_from_psa(psa_status_t status)
{
return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_md_errors,
psa_generic_status_to_mbedtls);
}
#endif /* MBEDTLS_PSA_CRYPTO_C */
/************************************************************************
* Functions above this separator are part of MBEDTLS_MD_LIGHT, *
* functions below are only available when MBEDTLS_MD_C is set. *
@ -705,6 +904,22 @@ static const int supported_digests[] = {
MBEDTLS_MD_MD5,
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
MBEDTLS_MD_SHA3_224,
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
MBEDTLS_MD_SHA3_256,
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
MBEDTLS_MD_SHA3_384,
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
MBEDTLS_MD_SHA3_512,
#endif
MBEDTLS_MD_NONE
};
@ -754,6 +969,26 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name)
if (!strcmp("SHA512", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
if (!strcmp("SHA3-224", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_224);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
if (!strcmp("SHA3-256", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_256);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
if (!strcmp("SHA3-384", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_384);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
if (!strcmp("SHA3-512", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_512);
}
#endif
return NULL;
}

60
library/md_psa.h Normal file
View file

@ -0,0 +1,60 @@
/**
* Translation between MD and PSA identifiers (algorithms, errors).
*
* Note: this internal module will go away when everything becomes based on
* PSA Crypto; it is a helper for the transition period.
*
* 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_MD_PSA_H
#define MBEDTLS_MD_PSA_H
#include "common.h"
#include "mbedtls/md.h"
#include "psa/crypto.h"
/**
* \brief This function returns the PSA algorithm identifier
* associated with the given digest type.
*
* \param md_type The type of digest to search for.
*
* \return The PSA algorithm identifier associated with \p md_type.
* \return PSA_ALG_NONE if the algorithm is not supported.
*/
psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type);
/**
* \brief This function returns the given digest type
* associated with the PSA algorithm identifier.
*
* \param psa_alg The PSA algorithm identifier to search for.
*
* \return The MD type associated with \p psa_alg.
* \return MBEDTLS_MD_NONE if the algorithm is not supported.
*/
mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg);
/** Convert PSA status to MD error code.
*
* \param status PSA status.
*
* \return The corresponding MD error code,
*/
int mbedtls_md_error_from_psa(psa_status_t status);
#endif /* MBEDTLS_MD_PSA_H */

View file

@ -73,6 +73,12 @@ extern const mbedtls_md_info_t mbedtls_sha384_info;
#if defined(MBEDTLS_SHA512_C)
extern const mbedtls_md_info_t mbedtls_sha512_info;
#endif
#if defined(MBEDTLS_SHA3_C)
extern const mbedtls_md_info_t mbedtls_sha3_224_info;
extern const mbedtls_md_info_t mbedtls_sha3_256_info;
extern const mbedtls_md_info_t mbedtls_sha3_384_info;
extern const mbedtls_md_info_t mbedtls_sha3_512_info;
#endif
#ifdef __cplusplus
}

View file

@ -169,7 +169,7 @@
*
*/
typedef size_t mbedtls_mps_stored_size_t;
#define MBEDTLS_MPS_STORED_SIZE_MAX ((mbedtls_mps_stored_size_t) -1)
#define MBEDTLS_MPS_STORED_SIZE_MAX (SIZE_MAX)
/** \brief The type of buffer sizes and offsets used in the MPS API
* and implementation.
@ -183,7 +183,7 @@ typedef size_t mbedtls_mps_stored_size_t;
* so almost 10%.
*/
typedef size_t mbedtls_mps_size_t;
#define MBEDTLS_MPS_SIZE_MAX ((mbedtls_mps_size_t) -1)
#define MBEDTLS_MPS_SIZE_MAX (SIZE_MAX)
#if MBEDTLS_MPS_STORED_SIZE_MAX > MBEDTLS_MPS_SIZE_MAX
#error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t."

View file

@ -465,17 +465,22 @@ cleanup:
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
#define KW_TESTS 3
/*
* Test vectors taken from NIST
* https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW
*/
static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 };
static const unsigned int key_len[] = {
16,
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
24,
32
#endif
};
static const unsigned char kw_key[KW_TESTS][32] = {
static const unsigned char kw_key[][32] = {
{ 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2,
0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b,
0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d,
0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 },
@ -483,11 +488,13 @@ static const unsigned char kw_key[KW_TESTS][32] = {
0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33,
0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d,
0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 }
#endif
};
static const unsigned char kw_msg[KW_TESTS][40] = {
static const unsigned char kw_msg[][40] = {
{ 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea,
0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb,
0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d,
0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45,
@ -496,14 +503,28 @@ static const unsigned char kw_msg[KW_TESTS][40] = {
{ 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7,
0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8,
0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 }
#endif
};
static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 };
static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 };
static const unsigned char kw_res[KW_TESTS][48] = {
static const size_t kw_msg_len[] = {
16,
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
40,
24
#endif
};
static const size_t kw_out_len[] = {
24,
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
48,
32
#endif
};
static const unsigned char kw_res[][48] = {
{ 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d,
0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3,
0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91,
0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec,
0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d,
@ -514,11 +535,13 @@ static const unsigned char kw_res[KW_TESTS][48] = {
0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87,
0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9,
0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 }
#endif
};
static const unsigned char kwp_key[KW_TESTS][32] = {
static const unsigned char kwp_key[][32] = {
{ 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a,
0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98,
0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7,
0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 },
@ -526,23 +549,33 @@ static const unsigned char kwp_key[KW_TESTS][32] = {
0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f,
0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae,
0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a }
#endif
};
static const unsigned char kwp_msg[KW_TESTS][31] = {
static const unsigned char kwp_msg[][31] = {
{ 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8,
0x96 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb,
0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19,
0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66,
0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f },
{ 0xd1 }
#endif
};
static const size_t kwp_msg_len[] = {
9,
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
31,
1
#endif
};
static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 };
static const unsigned char kwp_res[KW_TESTS][48] = {
static const unsigned char kwp_res[][48] = {
{ 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e,
0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7,
0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 },
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
{ 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13,
0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88,
0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63,
@ -550,8 +583,15 @@ static const unsigned char kwp_res[KW_TESTS][48] = {
0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 },
{ 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd,
0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 }
#endif
};
static const size_t kwp_out_len[] = {
24,
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
40,
16
#endif
};
static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 };
int mbedtls_nist_kw_self_test(int verbose)
{
@ -562,114 +602,128 @@ int mbedtls_nist_kw_self_test(int verbose)
int ret = 0;
mbedtls_nist_kw_init(&ctx);
for (i = 0; i < KW_TESTS; i++) {
if (verbose != 0) {
mbedtls_printf(" KW-AES-%u ", (unsigned int) key_len[i] * 8);
}
/*
* KW mode
*/
{
static const int num_tests = sizeof(kw_key) / sizeof(*kw_key);
ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
kw_key[i], key_len[i] * 8, 1);
if (ret != 0) {
for (i = 0; i < num_tests; i++) {
if (verbose != 0) {
mbedtls_printf(" KW: setup failed ");
mbedtls_printf(" KW-AES-%u ", (unsigned int) key_len[i] * 8);
}
goto end;
}
ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
kw_key[i], key_len[i] * 8, 1);
if (ret != 0) {
if (verbose != 0) {
mbedtls_printf(" KW: setup failed ");
}
ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, kw_msg[i],
kw_msg_len[i], out, &olen, sizeof(out));
if (ret != 0 || kw_out_len[i] != olen ||
memcmp(out, kw_res[i], kw_out_len[i]) != 0) {
if (verbose != 0) {
mbedtls_printf("failed. ");
goto end;
}
ret = 1;
goto end;
}
ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, kw_msg[i],
kw_msg_len[i], out, &olen, sizeof(out));
if (ret != 0 || kw_out_len[i] != olen ||
memcmp(out, kw_res[i], kw_out_len[i]) != 0) {
if (verbose != 0) {
mbedtls_printf("failed. ");
}
if ((ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
kw_key[i], key_len[i] * 8, 0))
!= 0) {
if (verbose != 0) {
mbedtls_printf(" KW: setup failed ");
ret = 1;
goto end;
}
goto end;
}
if ((ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
kw_key[i], key_len[i] * 8, 0))
!= 0) {
if (verbose != 0) {
mbedtls_printf(" KW: setup failed ");
}
ret = mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW,
out, olen, out, &olen, sizeof(out));
if (ret != 0 || olen != kw_msg_len[i] ||
memcmp(out, kw_msg[i], kw_msg_len[i]) != 0) {
if (verbose != 0) {
mbedtls_printf("failed\n");
goto end;
}
ret = 1;
goto end;
}
ret = mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW,
out, olen, out, &olen, sizeof(out));
if (verbose != 0) {
mbedtls_printf(" passed\n");
if (ret != 0 || olen != kw_msg_len[i] ||
memcmp(out, kw_msg[i], kw_msg_len[i]) != 0) {
if (verbose != 0) {
mbedtls_printf("failed\n");
}
ret = 1;
goto end;
}
if (verbose != 0) {
mbedtls_printf(" passed\n");
}
}
}
for (i = 0; i < KW_TESTS; i++) {
olen = sizeof(out);
if (verbose != 0) {
mbedtls_printf(" KWP-AES-%u ", (unsigned int) key_len[i] * 8);
}
/*
* KWP mode
*/
{
static const int num_tests = sizeof(kwp_key) / sizeof(*kwp_key);
ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i],
key_len[i] * 8, 1);
if (ret != 0) {
for (i = 0; i < num_tests; i++) {
olen = sizeof(out);
if (verbose != 0) {
mbedtls_printf(" KWP: setup failed ");
mbedtls_printf(" KWP-AES-%u ", (unsigned int) key_len[i] * 8);
}
goto end;
}
ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i],
kwp_msg_len[i], out, &olen, sizeof(out));
ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i],
key_len[i] * 8, 1);
if (ret != 0) {
if (verbose != 0) {
mbedtls_printf(" KWP: setup failed ");
}
if (ret != 0 || kwp_out_len[i] != olen ||
memcmp(out, kwp_res[i], kwp_out_len[i]) != 0) {
if (verbose != 0) {
mbedtls_printf("failed. ");
goto end;
}
ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i],
kwp_msg_len[i], out, &olen, sizeof(out));
if (ret != 0 || kwp_out_len[i] != olen ||
memcmp(out, kwp_res[i], kwp_out_len[i]) != 0) {
if (verbose != 0) {
mbedtls_printf("failed. ");
}
ret = 1;
goto end;
}
ret = 1;
goto end;
}
if ((ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
kwp_key[i], key_len[i] * 8, 0))
!= 0) {
if (verbose != 0) {
mbedtls_printf(" KWP: setup failed ");
}
if ((ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
kwp_key[i], key_len[i] * 8, 0))
!= 0) {
if (verbose != 0) {
mbedtls_printf(" KWP: setup failed ");
goto end;
}
goto end;
}
ret = mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KWP, out,
olen, out, &olen, sizeof(out));
ret = mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KWP, out,
olen, out, &olen, sizeof(out));
if (ret != 0 || olen != kwp_msg_len[i] ||
memcmp(out, kwp_msg[i], kwp_msg_len[i]) != 0) {
if (verbose != 0) {
mbedtls_printf("failed. ");
}
if (ret != 0 || olen != kwp_msg_len[i] ||
memcmp(out, kwp_msg[i], kwp_msg_len[i]) != 0) {
if (verbose != 0) {
mbedtls_printf("failed. ");
ret = 1;
goto end;
}
ret = 1;
goto end;
}
if (verbose != 0) {
mbedtls_printf(" passed\n");
if (verbose != 0) {
mbedtls_printf(" passed\n");
}
}
}
end:

View file

@ -933,4 +933,180 @@ int mbedtls_oid_get_numeric_string(char *buf, size_t size,
return (int) (size - n);
}
static int oid_parse_number(unsigned int *num, const char **p, const char *bound)
{
int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
*num = 0;
while (*p < bound && **p >= '0' && **p <= '9') {
ret = 0;
if (*num > (UINT_MAX / 10)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
*num *= 10;
*num += **p - '0';
(*p)++;
}
return ret;
}
static size_t oid_subidentifier_num_bytes(unsigned int value)
{
size_t num_bytes = 0;
do {
value >>= 7;
num_bytes++;
} while (value != 0);
return num_bytes;
}
static int oid_subidentifier_encode_into(unsigned char **p,
unsigned char *bound,
unsigned int value)
{
size_t num_bytes = oid_subidentifier_num_bytes(value);
if ((size_t) (bound - *p) < num_bytes) {
return MBEDTLS_ERR_OID_BUF_TOO_SMALL;
}
(*p)[num_bytes - 1] = (unsigned char) (value & 0x7f);
value >>= 7;
for (size_t i = 2; i <= num_bytes; i++) {
(*p)[num_bytes - i] = 0x80 | (unsigned char) (value & 0x7f);
value >>= 7;
}
*p += num_bytes;
return 0;
}
/* Return the OID for the given x.y.z.... style numeric string */
int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid,
const char *oid_str, size_t size)
{
int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
const char *str_ptr = oid_str;
const char *str_bound = oid_str + size;
unsigned int val = 0;
unsigned int component1, component2;
size_t encoded_len;
unsigned char *resized_mem;
/* Count the number of dots to get a worst-case allocation size. */
size_t num_dots = 0;
for (size_t i = 0; i < size; i++) {
if (oid_str[i] == '.') {
num_dots++;
}
}
/* Allocate maximum possible required memory:
* There are (num_dots + 1) integer components, but the first 2 share the
* same subidentifier, so we only need num_dots subidentifiers maximum. */
if (num_dots == 0 || (num_dots > MBEDTLS_OID_MAX_COMPONENTS - 1)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
/* Each byte can store 7 bits, calculate number of bytes for a
* subidentifier:
*
* bytes = ceil(subidentifer_size * 8 / 7)
*/
size_t bytes_per_subidentifier = (((sizeof(unsigned int) * 8) - 1) / 7)
+ 1;
size_t max_possible_bytes = num_dots * bytes_per_subidentifier;
oid->p = mbedtls_calloc(max_possible_bytes, 1);
if (oid->p == NULL) {
return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
}
unsigned char *out_ptr = oid->p;
unsigned char *out_bound = oid->p + max_possible_bytes;
ret = oid_parse_number(&component1, &str_ptr, str_bound);
if (ret != 0) {
goto error;
}
if (component1 > 2) {
/* First component can't be > 2 */
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
goto error;
}
if (str_ptr >= str_bound || *str_ptr != '.') {
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
goto error;
}
str_ptr++;
ret = oid_parse_number(&component2, &str_ptr, str_bound);
if (ret != 0) {
goto error;
}
if ((component1 < 2) && (component2 > 39)) {
/* Root nodes 0 and 1 may have up to 40 children, numbered 0-39 */
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
goto error;
}
if (str_ptr < str_bound) {
if (*str_ptr == '.') {
str_ptr++;
} else {
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
goto error;
}
}
if (component2 > (UINT_MAX - (component1 * 40))) {
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
goto error;
}
ret = oid_subidentifier_encode_into(&out_ptr, out_bound,
(component1 * 40) + component2);
if (ret != 0) {
goto error;
}
while (str_ptr < str_bound) {
ret = oid_parse_number(&val, &str_ptr, str_bound);
if (ret != 0) {
goto error;
}
if (str_ptr < str_bound) {
if (*str_ptr == '.') {
str_ptr++;
} else {
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
goto error;
}
}
ret = oid_subidentifier_encode_into(&out_ptr, out_bound, val);
if (ret != 0) {
goto error;
}
}
encoded_len = out_ptr - oid->p;
resized_mem = mbedtls_calloc(encoded_len, 1);
if (resized_mem == NULL) {
ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED;
goto error;
}
memcpy(resized_mem, oid->p, encoded_len);
mbedtls_free(oid->p);
oid->p = resized_mem;
oid->len = encoded_len;
oid->tag = MBEDTLS_ASN1_OID;
return 0;
error:
mbedtls_free(oid->p);
oid->p = NULL;
oid->len = 0;
return ret;
}
#endif /* MBEDTLS_OID_C */

View file

@ -29,7 +29,6 @@
#include "mbedtls/cipher.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "hash_info.h"
#include <string.h>

View file

@ -25,8 +25,6 @@
#include "pkwrite.h"
#include "pk_internal.h"
#include "hash_info.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@ -42,13 +40,7 @@
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h"
#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_pk_rsa_errors, \
psa_pk_status_to_mbedtls)
#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_pk_ecdsa_errors, \
psa_pk_status_to_mbedtls)
#include "md_psa.h"
#endif
#include <limits.h>
@ -64,6 +56,12 @@ void mbedtls_pk_init(mbedtls_pk_context *ctx)
#if defined(MBEDTLS_PSA_CRYPTO_C)
ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT;
#endif /* MBEDTLS_PSA_CRYPTO_C */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw));
ctx->pub_raw_len = 0;
ctx->ec_family = 0;
ctx->ec_bits = 0;
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
}
/*
@ -79,6 +77,14 @@ void mbedtls_pk_free(mbedtls_pk_context *ctx)
ctx->pk_info->ctx_free_func(ctx->pk_ctx);
}
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
/* The ownership of the priv_id key for opaque keys is external of the PK
* module. It's the user responsibility to clear it after use. */
if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) {
psa_destroy_key(ctx->priv_id);
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
}
@ -144,7 +150,7 @@ int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
if ((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;
}
@ -190,6 +196,42 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
int mbedtls_pk_update_public_key_from_keypair(mbedtls_pk_context *pk,
mbedtls_ecp_keypair *ecp_keypair)
{
int ret = MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
if (pk == NULL) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* The raw public key storing mechanism is only supported for EC keys so
* we fail silently for other ones. */
if ((pk->pk_info->type != MBEDTLS_PK_ECKEY) &&
(pk->pk_info->type != MBEDTLS_PK_ECKEY_DH) &&
(pk->pk_info->type != MBEDTLS_PK_ECDSA)) {
return 0;
}
ret = mbedtls_ecp_point_write_binary(&ecp_keypair->grp, &ecp_keypair->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&pk->pub_raw_len,
pk->pub_raw,
MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN);
if (ret != 0) {
return ret;
}
pk->ec_family = mbedtls_ecc_group_to_psa(ecp_keypair->grp.id,
&pk->ec_bits);
if (pk->ec_family == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
return 0;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/*
* Initialize an RSA-alt context
@ -375,7 +417,7 @@ static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len)
return 0;
}
*hash_len = mbedtls_hash_info_get_size(md_alg);
*hash_len = mbedtls_md_get_size_from_type(md_alg);
if (*hash_len == 0) {
return -1;
@ -524,7 +566,7 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
psa_status_t status = PSA_ERROR_DATA_CORRUPT;
psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT;
psa_algorithm_t psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg);
psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg);
@ -692,7 +734,7 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
}
#if defined(MBEDTLS_RSA_C)
psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg);
psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
if (psa_md_alg == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@ -782,7 +824,8 @@ int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
} else {
if (pub->pk_info != prv->pk_info) {
if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) &&
(pub->pk_info != prv->pk_info)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
}
@ -869,24 +912,35 @@ int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
#else /* !MBEDTLS_ECP_LIGHT && !MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
mbedtls_ecp_keypair *ec;
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
size_t d_len;
psa_ecc_family_t curve_id;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t key_type;
size_t bits;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status;
/* export the private key material in the format PSA wants */
ec = mbedtls_pk_ec_rw(*pk);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
unsigned char d[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
status = psa_export_key(pk->priv_id, d, sizeof(d), &d_len);
if (status != PSA_SUCCESS) {
return psa_pk_status_to_mbedtls(status);
}
curve_id = pk->ec_family;
bits = pk->ec_bits;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
d_len = PSA_BITS_TO_BYTES(ec->grp.nbits);
if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) {
return ret;
}
curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
/* prepare the key attributes */

View file

@ -23,18 +23,35 @@
#ifndef MBEDTLS_PK_INTERNAL_H
#define MBEDTLS_PK_INTERNAL_H
#include "mbedtls/pk.h"
#if defined(MBEDTLS_ECP_LIGHT)
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h"
#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_pk_rsa_errors, \
psa_pk_status_to_mbedtls)
#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_pk_ecdsa_errors, \
psa_pk_status_to_mbedtls)
#endif
#if defined(MBEDTLS_ECP_LIGHT)
/**
* Public function mbedtls_pk_ec() can be used to get direct access to the
* wrapped ecp_keypair strucure pointed to the pk_ctx. However this is not
* ideal because it bypasses the PK module on the control of its internal's
* wrapped ecp_keypair structure pointed to the pk_ctx. However this is not
* ideal because it bypasses the PK module on the control of its internal
* structure (pk_context) fields.
* For backward compatibility we keep mbedtls_pk_ec() when ECP_C is defined, but
* we provide 2 very similar function when only ECP_LIGHT is enabled and not
* we provide 2 very similar functions when only ECP_LIGHT is enabled and not
* ECP_C.
* These variants embed the "ro" or "rw" keywords in their name to make the
* usage of the returned pointer explicit. Of course the returned value is
@ -63,6 +80,56 @@ static inline mbedtls_ecp_keypair *mbedtls_pk_ec_rw(const mbedtls_pk_context pk)
return NULL;
}
}
static inline mbedtls_ecp_group_id mbedtls_pk_get_group_id(const mbedtls_pk_context *pk)
{
mbedtls_ecp_group_id id;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t opaque_key_type;
psa_ecc_family_t curve;
if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) {
return MBEDTLS_ECP_DP_NONE;
}
opaque_key_type = psa_get_key_type(&opaque_attrs);
curve = PSA_KEY_TYPE_ECC_GET_FAMILY(opaque_key_type);
id = mbedtls_ecc_group_of_psa(curve, psa_get_key_bits(&opaque_attrs), 0);
psa_reset_key_attributes(&opaque_attrs);
} else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0);
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
id = mbedtls_pk_ec_ro(*pk)->grp.id;
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
}
return id;
}
/* Helper for Montgomery curves */
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
#define MBEDTLS_PK_HAVE_RFC8410_CURVES
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED || MBEDTLS_ECP_DP_CURVE448_ENABLED */
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
/**
* \brief Copy the public key content in raw format from "ctx->pk_ctx"
* (which is an ecp_keypair) into the internal "ctx->pub_raw" buffer.
*
* \note This is a temporary function that can be removed as soon as the pk
* module is free from ECP_C
*
* \param pk It is the pk_context which is going to be updated. It acts both
* as input and output.
*/
int mbedtls_pk_update_public_key_from_keypair(mbedtls_pk_context *pk,
mbedtls_ecp_keypair *ecp_keypair);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#endif /* MBEDTLS_PK_INTERNAL_H */

View file

@ -23,7 +23,9 @@
#if defined(MBEDTLS_PK_C)
#include "pk_wrap.h"
#include "pk_internal.h"
#include "mbedtls/error.h"
#include "md_psa.h"
/* Even if RSA not activated, for the sake of RSA-alt */
#include "mbedtls/rsa.h"
@ -42,18 +44,10 @@
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h"
#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_pk_rsa_errors, \
psa_pk_status_to_mbedtls)
#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_pk_ecdsa_errors, \
psa_pk_status_to_mbedtls)
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "hash_info.h"
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
#include "mbedtls/asn1write.h"
@ -211,7 +205,7 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
psa_algorithm_t psa_alg_md =
PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_hash_info_psa_from_md(md_alg));
PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
size_t rsa_len = mbedtls_rsa_get_len(rsa);
if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
@ -363,7 +357,7 @@ static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
((void) p_rng);
psa_algorithm_t psa_md_alg;
psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg);
psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
if (psa_md_alg == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@ -653,8 +647,12 @@ static int eckey_can_do(mbedtls_pk_type_t type)
static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
{
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
return pk->ec_bits;
#else
mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
return ecp->grp.pbits;
#endif
}
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
@ -724,11 +722,20 @@ static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len)
{
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;
psa_status_t status;
unsigned char *p;
psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
size_t signature_len;
((void) md_alg);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
unsigned char buf[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
psa_ecc_family_t curve = pk->ec_family;
size_t curve_bits = pk->ec_bits;
#else
mbedtls_ecp_keypair *ctx = pk->pk_ctx;
size_t key_len;
/* This buffer will initially contain the public key and then the signature
* but at different points in time. For all curves except secp224k1, which
@ -736,13 +743,10 @@ static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
* (header byte + 2 numbers, while the signature is only 2 numbers),
* so use that as the buffer size. */
unsigned char buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
unsigned char *p;
psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
size_t curve_bits;
psa_ecc_family_t curve =
mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
const size_t signature_part_size = (ctx->grp.nbits + 7) / 8;
((void) md_alg);
#endif
if (curve == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@ -752,6 +756,11 @@ static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&attributes, psa_sig_md);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
status = psa_import_key(&attributes,
pk->pub_raw, pk->pub_raw_len,
&key_id);
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&key_len, buf, sizeof(buf));
@ -762,27 +771,30 @@ static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
status = psa_import_key(&attributes,
buf, key_len,
&key_id);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
if (status != PSA_SUCCESS) {
ret = PSA_PK_TO_MBEDTLS_ERR(status);
goto cleanup;
}
/* We don't need the exported key anymore and can
* reuse its buffer for signature extraction. */
if (2 * signature_part_size > sizeof(buf)) {
signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
if (signature_len > sizeof(buf)) {
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
goto cleanup;
}
p = (unsigned char *) sig;
/* extract_ecdsa_sig's last parameter is the size
* of each integer to be parsed, so it's actually half
* the size of the signature. */
if ((ret = extract_ecdsa_sig(&p, sig + sig_len, buf,
signature_part_size)) != 0) {
signature_len/2)) != 0) {
goto cleanup;
}
status = psa_verify_hash(key_id, psa_sig_md,
hash, hash_len,
buf, 2 * signature_part_size);
buf, signature_len);
if (status != PSA_SUCCESS) {
ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
goto cleanup;
@ -913,23 +925,27 @@ static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
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 = 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;
psa_status_t status;
unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
psa_algorithm_t psa_sig_md =
PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_hash_info_psa_from_md(md_alg));
PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg));
#else
psa_algorithm_t psa_sig_md =
PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(md_alg));
PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(md_alg));
#endif
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_ecc_family_t curve = pk->ec_family;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
mbedtls_ecp_keypair *ctx = pk->pk_ctx;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
size_t curve_bits;
psa_ecc_family_t curve =
mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
size_t key_len = PSA_BITS_TO_BYTES(curve_bits);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/* PSA has its own RNG */
((void) f_rng);
@ -939,6 +955,12 @@ static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(pk->priv_id) == PSA_KEY_ID_NULL) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
key_id = pk->priv_id;
#else
if (key_len > sizeof(buf)) {
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
@ -958,6 +980,7 @@ static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
ret = PSA_PK_TO_MBEDTLS_ERR(status);
goto cleanup;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
status = psa_sign_hash(key_id, psa_sig_md, hash, hash_len,
sig, sig_size, sig_len);
@ -969,8 +992,11 @@ static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
ret = pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size);
cleanup:
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
mbedtls_platform_zeroize(buf, sizeof(buf));
status = psa_destroy_key(key_id);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
if (ret == 0 && status != PSA_SUCCESS) {
ret = PSA_PK_TO_MBEDTLS_ERR(status);
}
@ -1110,28 +1136,43 @@ cleanup:
*/
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;
psa_status_t status;
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;
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
mbedtls_svc_key_id_t key_id = prv->priv_id;
status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
&prv_key_len);
ret = PSA_PK_TO_MBEDTLS_ERR(status);
if (ret != 0) {
return ret;
}
if (memcmp(prv_key_buf, pub->pub_raw, pub->pub_raw_len) != 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
#else /* !MBEDTLS_PK_USE_PSA_EC_DATA */
psa_status_t destruction_status;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
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);
mbedtls_ecc_group_to_psa(mbedtls_pk_ec_ro(*prv)->grp.id, &curve_bits);
const size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits);
if (curve == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
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);
ret = mbedtls_mpi_write_binary(&mbedtls_pk_ec_ro(*prv)->d,
prv_key_buf, curve_bytes);
if (ret != 0) {
return ret;
}
@ -1154,7 +1195,8 @@ static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv
return PSA_PK_TO_MBEDTLS_ERR(destruction_status);
}
ret = mbedtls_ecp_point_write_binary(&pub_ctx->grp, &pub_ctx->Q,
ret = mbedtls_ecp_point_write_binary(&mbedtls_pk_ec_rw(*pub)->grp,
&mbedtls_pk_ec_rw(*pub)->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&pub_key_len, pub_key_buf,
sizeof(pub_key_buf));
@ -1165,6 +1207,7 @@ static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv
if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return 0;
}
@ -1187,6 +1230,7 @@ static int eckey_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
#endif
}
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static void *eckey_alloc_wrap(void)
{
void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
@ -1203,13 +1247,20 @@ static void eckey_free_wrap(void *ctx)
mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx);
mbedtls_free(ctx);
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
static void eckey_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
{
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
items->type = MBEDTLS_PK_DEBUG_PSA_EC;
items->name = "eckey.Q";
items->value = pk;
#else
mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
items->type = MBEDTLS_PK_DEBUG_ECP;
items->name = "eckey.Q";
items->value = &(ecp->Q);
#endif
}
const mbedtls_pk_info_t mbedtls_eckey_info = {
@ -1234,8 +1285,13 @@ const mbedtls_pk_info_t mbedtls_eckey_info = {
NULL,
NULL,
eckey_check_pair,
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
NULL,
NULL,
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
eckey_alloc_wrap,
eckey_free_wrap,
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
eckey_rs_alloc,
eckey_rs_free,
@ -1266,8 +1322,13 @@ const mbedtls_pk_info_t mbedtls_eckeydh_info = {
NULL,
NULL,
eckey_check_pair,
eckey_alloc_wrap, /* Same underlying key structure */
eckey_free_wrap, /* Same underlying key structure */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
NULL,
NULL,
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
eckey_alloc_wrap, /* Same underlying key structure */
eckey_free_wrap, /* Same underlying key structure */
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
@ -1356,8 +1417,13 @@ const mbedtls_pk_info_t mbedtls_ecdsa_info = {
NULL,
NULL,
eckey_check_pair, /* Compatible key structures */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
NULL,
NULL,
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
eckey_alloc_wrap, /* Compatible key structures */
eckey_free_wrap, /* Compatible key structures */
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
ecdsa_rs_alloc,
ecdsa_rs_free,
@ -1565,12 +1631,12 @@ static int pk_opaque_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
alg = PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(md_alg));
alg = PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(md_alg));
} else
#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
#if defined(MBEDTLS_RSA_C)
if (PSA_KEY_TYPE_IS_RSA(type)) {
alg = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_hash_info_psa_from_md(md_alg));
alg = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
} else
#endif /* MBEDTLS_RSA_C */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
@ -1603,6 +1669,53 @@ static int pk_opaque_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
#endif /* !MBEDTLS_PK_CAN_ECDSA_SIGN && !MBEDTLS_RSA_C */
}
static int pk_opaque_ec_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
/* The main difference between this function and eckey_check_pair_psa() is
* that in the opaque case the private key is always stored in PSA side no
* matter if MBEDTLS_PK_USE_PSA_EC_DATA is enabled or not.
* When MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we can simply use the
* eckey_check_pair_psa(). */
(void) f_rng;
(void) p_rng;
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
return eckey_check_pair_psa(pub, prv);
#elif defined(MBEDTLS_ECP_LIGHT)
psa_status_t status;
uint8_t exp_pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
size_t exp_pub_key_len = 0;
uint8_t pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
size_t pub_key_len = 0;
int ret;
status = psa_export_public_key(prv->priv_id, exp_pub_key, sizeof(exp_pub_key),
&exp_pub_key_len);
if (status != PSA_SUCCESS) {
ret = psa_pk_status_to_mbedtls(status);
return ret;
}
ret = mbedtls_ecp_point_write_binary(&(mbedtls_pk_ec_ro(*pub)->grp),
&(mbedtls_pk_ec_ro(*pub)->Q),
MBEDTLS_ECP_PF_UNCOMPRESSED,
&pub_key_len, pub_key, sizeof(pub_key));
if (ret != 0) {
return ret;
}
if ((exp_pub_key_len != pub_key_len) ||
memcmp(exp_pub_key, pub_key, exp_pub_key_len)) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
return 0;
#else
(void) pub;
(void) prv;
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
}
const mbedtls_pk_info_t mbedtls_pk_ecdsa_opaque_info = {
MBEDTLS_PK_OPAQUE,
"Opaque",
@ -1616,7 +1729,7 @@ const mbedtls_pk_info_t mbedtls_pk_ecdsa_opaque_info = {
#endif
NULL, /* decrypt - not relevant */
NULL, /* encrypt - not relevant */
NULL, /* check_pair - could be done later or left NULL */
pk_opaque_ec_check_pair,
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)

View file

@ -39,7 +39,6 @@
#include "mbedtls/des.h"
#endif
#include "hash_info.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
@ -290,7 +289,7 @@ int mbedtls_pkcs12_derivation(unsigned char *data, size_t datalen,
unsigned char diversifier[128];
unsigned char salt_block[128], pwd_block[128], hash_block[128] = { 0 };
unsigned char hash_output[MBEDTLS_HASH_MAX_SIZE];
unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
unsigned char *p;
unsigned char c;
int use_password = 0;
@ -314,7 +313,7 @@ int mbedtls_pkcs12_derivation(unsigned char *data, size_t datalen,
use_password = (pwd && pwdlen != 0);
use_salt = (salt && saltlen != 0);
hlen = mbedtls_hash_info_get_size(md_type);
hlen = mbedtls_md_get_size_from_type(md_type);
if (hlen <= 32) {
v = 64;

View file

@ -44,7 +44,6 @@
#include "mbedtls/platform.h"
#include "hash_info.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_ASN1_PARSE_C)

View file

@ -37,6 +37,9 @@
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
#include "pkwrite.h"
#endif
#if defined(MBEDTLS_ECP_LIGHT)
#include "pk_internal.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
#include "mbedtls/ecdsa.h"
#endif
@ -60,6 +63,12 @@
#include "mbedtls/platform.h"
/* Helper for Montgomery curves */
#if defined(MBEDTLS_ECP_LIGHT) && defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
#define MBEDTLS_PK_IS_RFC8410_GROUP_ID(id) \
((id == MBEDTLS_ECP_DP_CURVE25519) || (id == MBEDTLS_ECP_DP_CURVE448))
#endif /* MBEDTLS_ECP_LIGHT && MBEDTLS_PK_HAVE_RFC8410_CURVES */
#if defined(MBEDTLS_FS_IO)
/*
* Load all data from a file into a given buffer.
@ -455,6 +464,29 @@ cleanup:
}
#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
/* Functions pk_use_ecparams() and pk_use_ecparams_rfc8410() update the
* ecp_keypair structure with proper group ID. The purpose of this helper
* function is to update ec_family and ec_bits accordingly. */
static int pk_update_psa_ecparams(mbedtls_pk_context *pk,
mbedtls_ecp_group_id grp_id)
{
psa_ecc_family_t ec_family;
size_t bits;
ec_family = mbedtls_ecc_group_to_psa(grp_id, &bits);
if ((pk->ec_family != 0) && (pk->ec_family != ec_family)) {
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
pk->ec_family = ec_family;
pk->ec_bits = bits;
return 0;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/*
* Use EC parameters to initialise an EC group
*
@ -463,7 +495,7 @@ cleanup:
* specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
* -- implicitCurve NULL
*/
static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp)
static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group_id grp_id;
@ -482,43 +514,52 @@ static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_ecp_group *gr
#endif
}
/*
* grp may already be initialized; if so, make sure IDs match
*/
if (grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id) {
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
ret = pk_update_psa_ecparams(pk, grp_id);
#else
/* grp may already be initialized; if so, make sure IDs match */
if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE &&
mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) {
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
if ((ret = mbedtls_ecp_group_load(grp, grp_id)) != 0) {
if ((ret = mbedtls_ecp_group_load(&(mbedtls_pk_ec_rw(*pk)->grp),
grp_id)) != 0) {
return ret;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
return 0;
return ret;
}
#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,
static int pk_derive_public_key(mbedtls_pk_context *pk,
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. */
psa_status_t status;
(void) f_rng;
(void) p_rng;
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
(void) d;
(void) d_len;
status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw),
&pk->pub_raw_len);
ret = psa_pk_status_to_mbedtls(status);
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
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_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);
psa_status_t destruction_status;
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
@ -529,8 +570,6 @@ static int pk_derive_public_key(mbedtls_ecp_keypair *eck,
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);
@ -539,9 +578,10 @@ static int pk_derive_public_key(mbedtls_ecp_keypair *eck,
} 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);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#else /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
(void) d;
(void) d_len;
@ -557,13 +597,24 @@ static int pk_derive_public_key(mbedtls_ecp_keypair *eck,
*/
static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params,
mbedtls_ecp_group_id grp_id,
mbedtls_ecp_group *grp)
mbedtls_pk_context *pk)
{
int ret;
if (params->tag != 0 || params->len != 0) {
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
return mbedtls_ecp_group_load(grp, grp_id);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
ret = pk_update_psa_ecparams(pk, grp_id);
#else
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk);
ret = mbedtls_ecp_group_load(&(ecp->grp), grp_id);
if (ret != 0) {
return ret;
}
#endif
return ret;
}
/*
@ -571,7 +622,7 @@ static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params,
*
* CurvePrivateKey ::= OCTET STRING
*/
static int pk_parse_key_rfc8410_der(mbedtls_ecp_keypair *eck,
static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
unsigned char *key, size_t keylen, const unsigned char *end,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
@ -586,28 +637,87 @@ static int pk_parse_key_rfc8410_der(mbedtls_ecp_keypair *eck,
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status;
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT |
PSA_KEY_USAGE_DERIVE);
psa_set_key_algorithm(&attributes, PSA_ALG_ECDH);
status = psa_import_key(&attributes, key, len, &pk->priv_id);
if (status != PSA_SUCCESS) {
ret = psa_pk_status_to_mbedtls(status);
return ret;
}
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
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);
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
// 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) {
/* 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(pk, key, len, f_rng, p_rng)) != 0) {
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
mbedtls_ecp_keypair_free(eck);
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return ret;
}
/* When MBEDTLS_PK_USE_PSA_EC_DATA the key is checked while importing it
* into PSA. */
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
mbedtls_ecp_keypair_free(eck);
return ret;
}
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return 0;
}
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
/*
* Create a temporary ecp_keypair for converting an EC point in compressed
* format to an uncompressed one
*/
static int pk_convert_compressed_ec(mbedtls_pk_context *pk,
const unsigned char *in_start, size_t in_len,
size_t *out_buf_len, unsigned char *out_buf,
size_t out_buf_size)
{
mbedtls_ecp_keypair ecp_key;
mbedtls_ecp_group_id ecp_group_id;
int ret;
ecp_group_id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0);
mbedtls_ecp_keypair_init(&ecp_key);
ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);
if (ret != 0) {
return ret;
}
ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q,
in_start, in_len);
if (ret != 0) {
goto exit;
}
ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
out_buf_len, out_buf, out_buf_size);
exit:
mbedtls_ecp_keypair_free(&ecp_key);
return ret;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/*
* EC public key is an EC point
@ -617,15 +727,61 @@ static int pk_parse_key_rfc8410_der(mbedtls_ecp_keypair *eck,
* return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
*/
static int pk_get_ecpubkey(unsigned char **p, const unsigned char *end,
mbedtls_ecp_keypair *key)
mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ((ret = mbedtls_ecp_point_read_binary(&key->grp, &key->Q,
(const unsigned char *) *p, end - *p)) == 0) {
ret = mbedtls_ecp_check_pubkey(&key->grp, &key->Q);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
mbedtls_svc_key_id_t key;
psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
size_t len = (end - *p);
if (len > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* Compressed point format are not supported yet by PSA crypto. As a
* consequence ecp functions are used to "convert" the point to
* uncompressed format */
if ((**p == 0x02) || (**p == 0x03)) {
ret = pk_convert_compressed_ec(pk, *p, len,
&(pk->pub_raw_len), pk->pub_raw,
PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
if (ret != 0) {
return ret;
}
} else {
/* Uncompressed format */
if ((end - *p) > MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN) {
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
}
memcpy(pk->pub_raw, *p, (end - *p));
pk->pub_raw_len = end - *p;
}
/* Validate the key by trying to importing it */
psa_set_key_usage_flags(&key_attrs, 0);
psa_set_key_algorithm(&key_attrs, PSA_ALG_ECDSA_ANY);
psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family));
psa_set_key_bits(&key_attrs, pk->ec_bits);
if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len,
&key) != PSA_SUCCESS) ||
(psa_destroy_key(key) != PSA_SUCCESS)) {
mbedtls_platform_zeroize(pk->pub_raw, MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN);
pk->pub_raw_len = 0;
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
ret = 0;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx;
if ((ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q,
(const unsigned char *) *p,
end - *p)) == 0) {
ret = mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q);
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/*
* We know mbedtls_ecp_point_read_binary consumed all bytes or failed
*/
@ -795,15 +951,15 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
#if defined(MBEDTLS_ECP_LIGHT)
if (pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY) {
#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_rw(*pk)->grp);
if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) {
ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, pk);
} else
#endif
{
ret = pk_use_ecparams(&alg_params, &mbedtls_pk_ec_rw(*pk)->grp);
ret = pk_use_ecparams(&alg_params, pk);
}
if (ret == 0) {
ret = pk_get_ecpubkey(p, end, mbedtls_pk_ec_rw(*pk));
ret = pk_get_ecpubkey(p, end, pk);
}
} else
#endif /* MBEDTLS_ECP_LIGHT */
@ -1014,7 +1170,7 @@ cleanup:
/*
* Parse a SEC1 encoded private EC key
*/
static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
const unsigned char *key, size_t keylen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
@ -1026,6 +1182,11 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
unsigned char *d;
unsigned char *end = p + keylen;
unsigned char *end2;
mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status;
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/*
* RFC 5915, or SEC1 Appendix C.4
@ -1058,10 +1219,13 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
d = p;
d_len = len;
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
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);
}
#endif
p += len;
@ -1074,7 +1238,7 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
0)) == 0) {
if ((ret = pk_get_ecparams(&p, p + len, &params)) != 0 ||
(ret = pk_use_ecparams(&params, &eck->grp)) != 0) {
(ret = pk_use_ecparams(&params, pk)) != 0) {
mbedtls_ecp_keypair_free(eck);
return ret;
}
@ -1103,7 +1267,7 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
if ((ret = pk_get_ecpubkey(&p, end2, eck)) == 0) {
if ((ret = pk_get_ecpubkey(&p, end2, pk)) == 0) {
pubkey_done = 1;
} else {
/*
@ -1120,17 +1284,40 @@ static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
}
}
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
/* Setting largest masks for usage and key algorithms */
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH |
PSA_KEY_USAGE_SIGN_MESSAGE |
PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE);
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
psa_set_key_algorithm(&attributes,
PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH));
#else
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
#endif
psa_set_key_enrollment_algorithm(&attributes, PSA_ALG_ECDH);
status = psa_import_key(&attributes, d, d_len, &pk->priv_id);
if (status != PSA_SUCCESS) {
ret = psa_pk_status_to_mbedtls(status);
return ret;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
if (!pubkey_done) {
if ((ret = pk_derive_public_key(eck, d, d_len, f_rng, p_rng)) != 0) {
if ((ret = pk_derive_public_key(pk, d, d_len, f_rng, p_rng)) != 0) {
mbedtls_ecp_keypair_free(eck);
return ret;
}
}
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
mbedtls_ecp_keypair_free(eck);
return ret;
}
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return 0;
}
@ -1231,11 +1418,11 @@ static int pk_parse_key_pkcs8_unencrypted_der(
#if defined(MBEDTLS_ECP_LIGHT)
if (pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) {
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) {
if ((ret = pk_use_ecparams_rfc8410(&params, ec_grp_id,
&mbedtls_pk_ec_rw(*pk)->grp)) != 0 ||
if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) {
if ((ret =
pk_use_ecparams_rfc8410(&params, ec_grp_id, pk)) != 0 ||
(ret =
pk_parse_key_rfc8410_der(mbedtls_pk_ec_rw(*pk), p, len, end, f_rng,
pk_parse_key_rfc8410_der(pk, p, len, end, f_rng,
p_rng)) != 0) {
mbedtls_pk_free(pk);
return ret;
@ -1243,8 +1430,8 @@ static int pk_parse_key_pkcs8_unencrypted_der(
} else
#endif
{
if ((ret = pk_use_ecparams(&params, &mbedtls_pk_ec_rw(*pk)->grp)) != 0 ||
(ret = pk_parse_key_sec1_der(mbedtls_pk_ec_rw(*pk), p, len, f_rng, p_rng)) != 0) {
if ((ret = pk_use_ecparams(&params, pk)) != 0 ||
(ret = pk_parse_key_sec1_der(pk, p, len, f_rng, p_rng)) != 0) {
mbedtls_pk_free(pk);
return ret;
}
@ -1431,7 +1618,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 ||
(ret = pk_parse_key_sec1_der(mbedtls_pk_ec_rw(*pk),
(ret = pk_parse_key_sec1_der(pk,
pem.buf, pem.buflen,
f_rng, p_rng)) != 0) {
mbedtls_pk_free(pk);
@ -1555,18 +1742,18 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
#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_rw(*pk),
pk_parse_key_sec1_der(pk,
key, keylen, f_rng, p_rng) == 0) {
return 0;
}
mbedtls_pk_free(pk);
#endif /* MBEDTLS_ECP_LIGHT */
/* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
/* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_LIGHT isn't,
* it is ok to leave the PK context initialized but not
* freed: It is the caller's responsibility to call pk_init()
* before calling this function, and to call pk_free()
* when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
* when it fails. If MBEDTLS_ECP_LIGHT is defined but MBEDTLS_RSA_C
* isn't, this leads to mbedtls_pk_free() being called
* twice, once here and once by the caller, but this is
* also ok and in line with the mbedtls_pk_free() calls

View file

@ -38,7 +38,10 @@
#include "mbedtls/ecp.h"
#include "mbedtls/platform_util.h"
#endif
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
#if defined(MBEDTLS_ECP_LIGHT)
#include "pk_internal.h"
#endif
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_LIGHT)
#include "pkwrite.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
@ -54,6 +57,61 @@
#endif
#include "mbedtls/platform.h"
/* Helper for Montgomery curves */
#if defined(MBEDTLS_ECP_LIGHT)
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk)
{
mbedtls_ecp_group_id id = mbedtls_pk_get_group_id(pk);
#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;
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* It is assumed that the input key is opaque */
static psa_ecc_family_t pk_get_opaque_ec_family(const mbedtls_pk_context *pk)
{
psa_ecc_family_t ec_family = 0;
psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
if (psa_get_key_attributes(pk->priv_id, &key_attrs) != PSA_SUCCESS) {
return 0;
}
ec_family = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attrs));
psa_reset_key_attributes(&key_attrs);
return ec_family;
}
#endif /* MBETLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* It is assumed that the input key is opaque */
static psa_key_type_t pk_get_opaque_key_type(const mbedtls_pk_context *pk)
{
psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t opaque_key_type;
if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) {
return 0;
}
opaque_key_type = psa_get_key_type(&opaque_attrs);
psa_reset_key_attributes(&opaque_attrs);
return opaque_key_type;
}
#endif /* MBETLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
@ -62,11 +120,12 @@
* }
*/
static int pk_write_rsa_pubkey(unsigned char **p, unsigned char *start,
mbedtls_rsa_context *rsa)
const mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_mpi T;
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
mbedtls_mpi_init(&T);
@ -100,20 +159,20 @@ end_of_export:
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
/*
* EC public key is an EC point
*/
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec)
const mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
uint8_t buf[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&len, buf, sizeof(buf))) != 0) {
return ret;
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
} else {
len = pk->pub_raw_len;
memcpy(buf, pk->pub_raw, len);
}
if (*p < start || (size_t) (*p - start) < len) {
@ -125,6 +184,47 @@ static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
return (int) len;
}
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *pk)
{
size_t len = 0;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
uint8_t buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
#else
unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk);
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
*p -= len;
memcpy(*p, buf, len);
return (int) len;
} else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&len, buf, sizeof(buf))) != 0) {
return ret;
}
}
if (*p < start || (size_t) (*p - start) < len) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
*p -= len;
memcpy(*p, buf, len);
return (int) len;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/*
* ECParameters ::= CHOICE {
@ -151,25 +251,97 @@ static int pk_write_ec_param(unsigned char **p, unsigned char *start,
/*
* privateKey OCTET STRING -- always of length ceil(log2(n)/8)
*/
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static int pk_write_ec_private(unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec)
const mbedtls_pk_context *pk)
{
size_t byte_length;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t byte_length = (ec->grp.pbits + 7) / 8;
unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
psa_status_t status;
ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
if (ret != 0) {
goto exit;
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
if (status != PSA_SUCCESS) {
ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
return ret;
}
} else {
status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
if (status != PSA_SUCCESS) {
ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
goto exit;
}
}
ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
exit:
mbedtls_platform_zeroize(tmp, byte_length);
mbedtls_platform_zeroize(tmp, sizeof(tmp));
return ret;
}
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
static int pk_write_ec_private(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *pk)
{
size_t byte_length;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
psa_status_t status;
#else
unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
if (status != PSA_SUCCESS) {
ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
return ret;
}
} else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
byte_length = (ec->grp.pbits + 7) / 8;
ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
if (ret != 0) {
goto exit;
}
}
ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
exit:
mbedtls_platform_zeroize(tmp, sizeof(tmp));
return ret;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *pk)
{
size_t buffer_size;
size_t len = 0;
if (*p < start) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
buffer_size = (size_t) (*p - start);
if (psa_export_public_key(pk->priv_id, start, buffer_size,
&len) != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
*p -= len;
memmove(*p, start, len);
return (int) len;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *key)
{
@ -178,30 +350,17 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
#if defined(MBEDTLS_RSA_C)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, mbedtls_pk_rsa(*key)));
MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, key));
} else
#endif
#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_rw(*key)));
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, key));
} else
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
size_t buffer_size;
if (*p < start) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
buffer_size = (size_t) (*p - start);
if (psa_export_public_key(key->priv_id, start, buffer_size, &len)
!= PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
} else {
*p -= len;
memmove(*p, start, len);
}
MBEDTLS_ASN1_CHK_ADD(len, pk_write_opaque_pubkey(p, start, key));
} else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
@ -247,40 +406,22 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
pk_type = mbedtls_pk_get_type(key);
#if defined(MBEDTLS_ECP_LIGHT)
if (pk_type == MBEDTLS_PK_ECKEY) {
ec_grp_id = mbedtls_pk_ec_ro(*key)->grp.id;
ec_grp_id = mbedtls_pk_get_group_id(key);
}
#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;
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);
psa_key_type_t opaque_key_type = pk_get_opaque_key_type(key);
#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) {
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;
}
}
}
if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) {
pk_type = MBEDTLS_PK_ECKEY;
ec_grp_id = mbedtls_pk_get_group_id(key);
} else
#endif /* MBEDTLS_ECP_LIGHT */
if (PSA_KEY_TYPE_IS_RSA(key_type)) {
if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) {
/* The rest of the function works as for legacy RSA contexts. */
pk_type = MBEDTLS_PK_RSA;
}
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) {
@ -290,11 +431,13 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
#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 */
/* 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 */
/* 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));
@ -324,7 +467,7 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
#if defined(MBEDTLS_ECP_LIGHT)
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
/*
* RFC8410
* RFC8410 section 7
*
* OneAsymmetricKey ::= SEQUENCE {
* version Version,
@ -335,24 +478,26 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu
* [[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)
const mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
size_t oid_len = 0;
const char *oid;
mbedtls_ecp_group_id grp_id;
/* privateKey */
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, ec));
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
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));
grp_id = mbedtls_pk_get_group_id(pk);
/* privateKeyAlgorithm */
if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec->grp.id, &oid, &oid_len)) != 0) {
if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(grp_id, &oid, &oid_len)) != 0) {
return ret;
}
MBEDTLS_ASN1_CHK_ADD(len,
@ -368,24 +513,91 @@ static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf,
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)
/*
* RFC 5915, or SEC1 Appendix C.4
*
* ECPrivateKey ::= SEQUENCE {
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
* privateKey OCTET STRING,
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
* publicKey [1] BIT STRING OPTIONAL
* }
*/
static int pk_write_ec_der(unsigned char **p, unsigned char *buf,
const mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *c;
size_t len = 0;
int ret;
size_t pub_len = 0, par_len = 0;
mbedtls_ecp_group_id grp_id;
if (size == 0) {
/* publicKey */
MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(p, buf, pk));
if (*p - buf < 1) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
(*p)--;
**p = 0;
pub_len += 1;
c = buf + size;
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_BIT_STRING));
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf,
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED | 1));
len += pub_len;
/* parameters */
grp_id = mbedtls_pk_get_group_id(pk);
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id));
MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len));
MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf,
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED | 0));
len += par_len;
/* privateKey */
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
/* version */
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 1));
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_ECP_LIGHT */
#if defined(MBEDTLS_RSA_C)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
const mbedtls_pk_context *pk)
{
size_t len = 0;
int ret;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
size_t tmp_len = 0;
if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
*p -= tmp_len;
memcpy(*p, tmp, tmp_len);
len += tmp_len;
mbedtls_platform_zeroize(tmp, sizeof(tmp));
} else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
mbedtls_mpi T; /* Temporary holding the exported parameters */
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*key);
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
/*
* Export the parameters one after another to avoid simultaneous copies.
@ -395,21 +607,21 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf,
/* Export QP */
if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export DQ */
if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export DP */
if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@ -417,7 +629,7 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf,
/* Export Q */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
&T, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@ -425,7 +637,7 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf,
/* Export P */
if ((ret = mbedtls_rsa_export(rsa, NULL, &T,
NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@ -433,7 +645,7 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf,
/* Export D */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
NULL, &T, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@ -441,7 +653,7 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf,
/* Export E */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@ -449,7 +661,7 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf,
/* Export N */
if ((ret = mbedtls_rsa_export(rsa, &T, NULL,
NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@ -461,73 +673,64 @@ end_of_export:
return ret;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 0));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c,
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_RSA_C */
int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
{
unsigned char *c;
size_t len = 0;
#if defined(MBEDTLS_RSA_C)
int is_rsa_opaque = 0;
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
int is_ec_opaque = 0;
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_key_type_t opaque_key_type;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if (size == 0) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
c = buf + size;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
opaque_key_type = pk_get_opaque_key_type(key);
#if defined(MBEDTLS_RSA_C)
is_rsa_opaque = PSA_KEY_TYPE_IS_RSA(opaque_key_type);
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
is_ec_opaque = PSA_KEY_TYPE_IS_ECC(opaque_key_type);
#endif /* MBEDTLS_ECP_LIGHT */
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_RSA_C)
if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) || is_rsa_opaque) {
return pk_write_rsa_der(&c, buf, key);
} else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*key);
size_t pub_len = 0, par_len = 0;
if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) || is_ec_opaque) {
#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);
if (mbedtls_pk_is_rfc8410(key)) {
return pk_write_ec_rfc8410_der(&c, buf, key);
}
#endif
/*
* RFC 5915, or SEC1 Appendix C.4
*
* ECPrivateKey ::= SEQUENCE {
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
* privateKey OCTET STRING,
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
* publicKey [1] BIT STRING OPTIONAL
* }
*/
/* publicKey */
MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(&c, buf, ec));
if (c - buf < 1) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
*--c = 0;
pub_len += 1;
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(&c, buf, pub_len));
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_BIT_STRING));
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(&c, buf, pub_len));
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(&c, buf,
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED | 1));
len += pub_len;
/* parameters */
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,
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED | 0));
len += par_len;
/* privateKey */
MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(&c, buf, ec));
/* version */
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 1));
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 |
MBEDTLS_ASN1_SEQUENCE));
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
return pk_write_ec_der(&c, buf, key);
} else
#endif /* MBEDTLS_ECP_C */
#endif /* MBEDTLS_ECP_LIGHT */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
return (int) len;
@ -578,21 +781,50 @@ int mbedtls_pk_write_key_pem(const mbedtls_pk_context *key, unsigned char *buf,
unsigned char output_buf[PRV_DER_MAX_BYTES];
const char *begin, *end;
size_t olen = 0;
#if defined(MBEDTLS_ECP_LIGHT)
int is_ec_opaque = 0;
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
int is_montgomery_opaque = 0;
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_RSA_C)
int is_rsa_opaque = 0;
#endif
if ((ret = mbedtls_pk_write_key_der(key, output_buf, sizeof(output_buf))) < 0) {
return ret;
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
psa_key_type_t opaque_key_type = pk_get_opaque_key_type(key);
#if defined(MBEDTLS_RSA_C)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
is_rsa_opaque = PSA_KEY_TYPE_IS_RSA(opaque_key_type);
#endif
#if defined(MBEDTLS_ECP_LIGHT)
is_ec_opaque = PSA_KEY_TYPE_IS_ECC(opaque_key_type);
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
if (pk_get_opaque_ec_family(key) == PSA_ECC_FAMILY_MONTGOMERY) {
is_montgomery_opaque = 1;
}
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
#endif /* MBEDTLS_ECP_LIGHT */
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_RSA_C)
if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) || is_rsa_opaque) {
begin = PEM_BEGIN_PRIVATE_KEY_RSA;
end = PEM_END_PRIVATE_KEY_RSA;
} else
#endif
#if defined(MBEDTLS_ECP_LIGHT)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) || is_ec_opaque) {
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
if (mbedtls_pk_is_rfc8410_curve(mbedtls_pk_ec_ro(*key)->grp.id)) {
if (is_montgomery_opaque ||
((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) &&
(mbedtls_pk_is_rfc8410(key)))) {
begin = PEM_BEGIN_PRIVATE_KEY_PKCS8;
end = PEM_END_PRIVATE_KEY_PKCS8;
} else

View file

@ -73,7 +73,7 @@
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
#if defined(MBEDTLS_ECP_LIGHT)
/*
* EC public keys:
* SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
@ -98,34 +98,10 @@
*/
#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES (29 + 3 * MBEDTLS_ECP_MAX_BYTES)
#else /* MBEDTLS_ECP_C */
#else /* MBEDTLS_ECP_LIGHT */
#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES 0
#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES 0
#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 */

View file

@ -82,7 +82,7 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "hash_info.h"
#include "md_psa.h"
#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array)))
@ -646,14 +646,11 @@ psa_status_t psa_import_key_into_slot(
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;
return mbedtls_psa_ffdh_import_key(attributes,
data, data_length,
key_buffer, key_buffer_size,
key_buffer_length,
bits);
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
@ -1474,6 +1471,11 @@ psa_status_t psa_export_public_key_internal(
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
} else {
(void) key_buffer;
(void) key_buffer_size;
(void) data;
(void) data_size;
(void) data_length;
return PSA_ERROR_NOT_SUPPORTED;
}
}
@ -3608,7 +3610,7 @@ psa_status_t mbedtls_psa_sign_hash_start(
operation->ctx->grp.nbits);
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
operation->md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
operation->md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
operation->alg = alg;
/* We only need to store the same length of hash as the private key size
@ -5030,7 +5032,8 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
#if defined(BUILTIN_ALG_ANY_HKDF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
#define AT_LEAST_ONE_BUILTIN_KDF
#endif /* At least one builtin KDF */
@ -5134,6 +5137,17 @@ psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation)
sizeof(operation->ctx.tls12_ecjpake_to_pms.data));
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
if (operation->ctx.pbkdf2.salt != NULL) {
mbedtls_platform_zeroize(operation->ctx.pbkdf2.salt,
operation->ctx.pbkdf2.salt_length);
mbedtls_free(operation->ctx.pbkdf2.salt);
}
status = PSA_SUCCESS;
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) */
{
status = PSA_ERROR_BAD_STATE;
}
@ -5513,6 +5527,15 @@ psa_status_t psa_key_derivation_output_bytes(
&operation->ctx.tls12_ecjpake_to_pms, output, output_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
/* As output functionality is not added yet return
* PSA_ERROR_NOT_SUPPORTED for now if inputs are passed correctly.
* If input validation fails operation is aborted and output_bytes
* will return PSA_ERROR_BAD_STATE */
status = PSA_ERROR_NOT_SUPPORTED;
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
{
(void) kdf_alg;
@ -5930,6 +5953,11 @@ static int is_kdf_alg_supported(psa_algorithm_t kdf_alg)
if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
return 1;
}
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
return 1;
}
#endif
return 0;
}
@ -6424,6 +6452,130 @@ static psa_status_t psa_tls12_ecjpake_to_pms_input(
return PSA_SUCCESS;
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
static psa_status_t psa_pbkdf2_set_input_cost(
psa_pbkdf2_key_derivation_t *pbkdf2,
psa_key_derivation_step_t step,
uint64_t data)
{
if (step != PSA_KEY_DERIVATION_INPUT_COST) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (pbkdf2->state != PSA_PBKDF2_STATE_INIT) {
return PSA_ERROR_BAD_STATE;
}
if (data > PSA_VENDOR_PBKDF2_MAX_ITERATIONS) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (data == 0) {
return PSA_ERROR_INVALID_ARGUMENT;
}
pbkdf2->input_cost = data;
pbkdf2->state = PSA_PBKDF2_STATE_INPUT_COST_SET;
return PSA_SUCCESS;
}
static psa_status_t psa_pbkdf2_set_salt(psa_pbkdf2_key_derivation_t *pbkdf2,
const uint8_t *data,
size_t data_length)
{
if (pbkdf2->state != PSA_PBKDF2_STATE_INPUT_COST_SET &&
pbkdf2->state != PSA_PBKDF2_STATE_SALT_SET) {
return PSA_ERROR_BAD_STATE;
}
if (pbkdf2->state == PSA_PBKDF2_STATE_INPUT_COST_SET) {
pbkdf2->salt = mbedtls_calloc(1, data_length);
if (pbkdf2->salt == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
memcpy(pbkdf2->salt, data, data_length);
pbkdf2->salt_length = data_length;
} else if (pbkdf2->state == PSA_PBKDF2_STATE_SALT_SET) {
uint8_t *next_salt;
next_salt = mbedtls_calloc(1, data_length + pbkdf2->salt_length);
if (next_salt == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
memcpy(next_salt, pbkdf2->salt, pbkdf2->salt_length);
memcpy(next_salt + pbkdf2->salt_length, data, data_length);
pbkdf2->salt_length += data_length;
mbedtls_free(pbkdf2->salt);
pbkdf2->salt = next_salt;
}
pbkdf2->state = PSA_PBKDF2_STATE_SALT_SET;
return PSA_SUCCESS;
}
static psa_status_t psa_pbkdf2_hmac_set_password(psa_algorithm_t hash_alg,
const uint8_t *input,
size_t input_len,
uint8_t *output,
size_t *output_len)
{
psa_status_t status = PSA_SUCCESS;
if (input_len > PSA_HASH_BLOCK_LENGTH(hash_alg)) {
status = psa_hash_compute(hash_alg, input, input_len, output,
PSA_HMAC_MAX_HASH_BLOCK_SIZE, output_len);
} else {
memcpy(output, input, input_len);
*output_len = PSA_HASH_BLOCK_LENGTH(hash_alg);
}
return status;
}
static psa_status_t psa_pbkdf2_set_password(psa_pbkdf2_key_derivation_t *pbkdf2,
psa_algorithm_t kdf_alg,
const uint8_t *data,
size_t data_length)
{
psa_status_t status = PSA_SUCCESS;
if (pbkdf2->state != PSA_PBKDF2_STATE_SALT_SET) {
return PSA_ERROR_BAD_STATE;
}
if (data_length != 0) {
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
psa_algorithm_t hash_alg = PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg);
status = psa_pbkdf2_hmac_set_password(hash_alg, data, data_length,
pbkdf2->password,
&pbkdf2->password_length);
}
}
pbkdf2->state = PSA_PBKDF2_STATE_PASSWORD_SET;
return status;
}
static psa_status_t psa_pbkdf2_input(psa_pbkdf2_key_derivation_t *pbkdf2,
psa_algorithm_t kdf_alg,
psa_key_derivation_step_t step,
const uint8_t *data,
size_t data_length)
{
switch (step) {
case PSA_KEY_DERIVATION_INPUT_SALT:
return psa_pbkdf2_set_salt(pbkdf2, data, data_length);
case PSA_KEY_DERIVATION_INPUT_PASSWORD:
return psa_pbkdf2_set_password(pbkdf2, kdf_alg, data, data_length);
default:
return PSA_ERROR_INVALID_ARGUMENT;
}
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
/** Check whether the given key type is acceptable for the given
* input step of a key derivation.
*
@ -6465,6 +6617,17 @@ static int psa_key_derivation_check_input_type(
return PSA_SUCCESS;
}
break;
case PSA_KEY_DERIVATION_INPUT_PASSWORD:
if (key_type == PSA_KEY_TYPE_PASSWORD) {
return PSA_SUCCESS;
}
if (key_type == PSA_KEY_TYPE_DERIVE) {
return PSA_SUCCESS;
}
if (key_type == PSA_KEY_TYPE_NONE) {
return PSA_SUCCESS;
}
break;
}
return PSA_ERROR_INVALID_ARGUMENT;
}
@ -6508,6 +6671,12 @@ static psa_status_t psa_key_derivation_input_internal(
&operation->ctx.tls12_ecjpake_to_pms, step, data, data_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
status = psa_pbkdf2_input(&operation->ctx.pbkdf2, kdf_alg,
step, data, data_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
{
/* This can't happen unless the operation object was not initialized */
(void) data;
@ -6531,6 +6700,12 @@ static psa_status_t psa_key_derivation_input_integer_internal(
psa_status_t status;
psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
status = psa_pbkdf2_set_input_cost(
&operation->ctx.pbkdf2, step, value);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
{
(void) step;
(void) value;
@ -6579,9 +6754,10 @@ psa_status_t psa_key_derivation_input_key(
return status;
}
/* Passing a key object as a SECRET input unlocks the permission
* to output to a key object. */
if (step == PSA_KEY_DERIVATION_INPUT_SECRET) {
/* Passing a key object as a SECRET or PASSWORD input unlocks the
* permission to output to a key object. */
if (step == PSA_KEY_DERIVATION_INPUT_SECRET ||
step == PSA_KEY_DERIVATION_INPUT_PASSWORD) {
operation->can_output_key = 1;
}

View file

@ -26,7 +26,7 @@
#include "psa_crypto_core.h"
#include "psa_crypto_ecp.h"
#include "psa_crypto_random_impl.h"
#include "hash_info.h"
#include "md_psa.h"
#include <stdlib.h>
#include <string.h>
@ -366,7 +366,7 @@ psa_status_t mbedtls_psa_ecdsa_sign_hash(
if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
mbedtls_md_type_t md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext(
&ecp->grp, &r, &s,
&ecp->d, hash,

View file

@ -26,9 +26,11 @@
#include "psa_crypto_core.h"
#include "psa_crypto_ffdh.h"
#include "psa_crypto_random_impl.h"
#include "mbedtls/platform.h"
#if 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_DH_KEY_PAIR) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size,
mbedtls_mpi *P,
mbedtls_mpi *G)
@ -115,6 +117,119 @@ cleanup:
return PSA_SUCCESS;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR ||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
MBEDTLS_PSA_BUILTIN_ALG_FFDH */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
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;
psa_key_type_t type = attributes->core.type;
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
if (key_buffer_size > data_size) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
memcpy(data, key_buffer, key_buffer_size);
memset(data + key_buffer_size, 0,
data_size - key_buffer_size);
*data_length = key_buffer_size;
return PSA_SUCCESS;
}
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;
}
psa_status_t mbedtls_psa_ffdh_import_key(
const psa_key_attributes_t *attributes,
const uint8_t *data, size_t data_length,
uint8_t *key_buffer, size_t key_buffer_size,
size_t *key_buffer_length, size_t *bits)
{
(void) attributes;
if (key_buffer_size < data_length) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
memcpy(key_buffer, data, data_length);
*key_buffer_length = data_length;
*bits = PSA_BYTES_TO_BITS(data_length);
return PSA_SUCCESS;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR ||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
psa_status_t mbedtls_psa_key_agreement_ffdh(
@ -181,82 +296,4 @@ cleanup:
}
#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 */

View file

@ -112,4 +112,33 @@ psa_status_t mbedtls_psa_ffdh_generate_key(
size_t key_buffer_size,
size_t *key_buffer_length);
/**
* \brief Import DH key.
*
* \note The signature of the function is that of a PSA driver import_key
* entry point.
*
* \param[in] attributes The attributes for the key to import.
* \param[in] data The buffer containing the key data in import
* format.
* \param[in] data_length Size of the \p data buffer in bytes.
* \param[out] key_buffer The buffer containing the key data in output
* format.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This
* size is greater or equal to \p data_length.
* \param[out] key_buffer_length The length of the data written in \p
* key_buffer in bytes.
* \param[out] bits The key size in number of bits.
*
* \retval #PSA_SUCCESS
* The key was generated successfully.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of \p key_buffer is too small.
*/
psa_status_t mbedtls_psa_ffdh_import_key(
const psa_key_attributes_t *attributes,
const uint8_t *data, size_t data_length,
uint8_t *key_buffer, size_t key_buffer_size,
size_t *key_buffer_length, size_t *bits);
#endif /* PSA_CRYPTO_FFDH_H */

View file

@ -28,6 +28,7 @@
#include "psa_crypto_random_impl.h"
#include "psa_crypto_rsa.h"
#include "psa_crypto_hash.h"
#include "md_psa.h"
#include <stdlib.h>
#include <string.h>
@ -37,7 +38,6 @@
#include <mbedtls/error.h>
#include <mbedtls/pk.h>
#include "pk_wrap.h"
#include "hash_info.h"
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
@ -318,7 +318,7 @@ static psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg,
mbedtls_md_type_t *md_alg)
{
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
*md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
*md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
/* The Mbed TLS RSA module uses an unsigned int for hash length
* parameters. Validate that it fits so that we don't risk an
@ -332,7 +332,7 @@ static psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg,
if (*md_alg == MBEDTLS_MD_NONE) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (mbedtls_hash_info_get_size(*md_alg) != hash_length) {
if (mbedtls_md_get_size_from_type(*md_alg) != hash_length) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
@ -527,7 +527,7 @@ static int psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg,
mbedtls_rsa_context *rsa)
{
psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg);
mbedtls_md_type_t md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
}

View file

@ -33,7 +33,7 @@
/* PSA_SUCCESS is kept at the top of each error table since
* it's the most common status when everything functions properly. */
#if !defined(MBEDTLS_MD_C) || !defined(MBEDTLS_MD5_C) || defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_MD_LIGHT)
const mbedtls_error_pair_t psa_to_md_errors[] =
{
{ PSA_SUCCESS, 0 },

View file

@ -46,7 +46,7 @@
#include "mbedtls/error.h"
#include "constant_time_internal.h"
#include "mbedtls/constant_time.h"
#include "hash_info.h"
#include "md_psa.h"
#include <string.h>
@ -478,7 +478,7 @@ int mbedtls_rsa_set_padding(mbedtls_rsa_context *ctx, int padding,
if ((padding == MBEDTLS_RSA_PKCS_V21) &&
(hash_id != MBEDTLS_MD_NONE)) {
/* Just make sure this hash is supported in this build. */
if (mbedtls_hash_info_psa_from_md(hash_id) == PSA_ALG_NONE) {
if (mbedtls_md_info_from_type(hash_id) == NULL) {
return MBEDTLS_ERR_RSA_INVALID_PADDING;
}
}
@ -1076,7 +1076,7 @@ static int mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src,
unsigned char *p;
unsigned int hlen;
size_t i, use_len;
unsigned char mask[MBEDTLS_HASH_MAX_SIZE];
unsigned char mask[MBEDTLS_MD_MAX_SIZE];
int ret = 0;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
@ -1229,7 +1229,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
hlen = mbedtls_hash_info_get_size((mbedtls_md_type_t) ctx->hash_id);
hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
if (hlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@ -1380,7 +1380,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
size_t ilen, i, pad_len;
unsigned char *p, bad, pad_done;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
unsigned char lhash[MBEDTLS_HASH_MAX_SIZE];
unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
unsigned int hlen;
/*
@ -1396,7 +1396,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
hlen = mbedtls_hash_info_get_size((mbedtls_md_type_t) ctx->hash_id);
hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
if (hlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@ -1596,7 +1596,7 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
if (md_alg != MBEDTLS_MD_NONE) {
/* Gather length of hash to sign */
size_t exp_hashlen = mbedtls_hash_info_get_size(md_alg);
size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
if (exp_hashlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@ -1606,7 +1606,7 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
}
}
hlen = mbedtls_hash_info_get_size((mbedtls_md_type_t) ctx->hash_id);
hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
if (hlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@ -1744,7 +1744,7 @@ static int rsa_rsassa_pkcs1_v15_encode(mbedtls_md_type_t md_alg,
/* Are we signing hashed or raw data? */
if (md_alg != MBEDTLS_MD_NONE) {
unsigned char md_size = mbedtls_hash_info_get_size(md_alg);
unsigned char md_size = mbedtls_md_get_size_from_type(md_alg);
if (md_size == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@ -1966,7 +1966,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx,
size_t siglen;
unsigned char *p;
unsigned char *hash_start;
unsigned char result[MBEDTLS_HASH_MAX_SIZE];
unsigned char result[MBEDTLS_MD_MAX_SIZE];
unsigned int hlen;
size_t observed_salt_len, msb;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = { 0 };
@ -1995,7 +1995,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx,
if (md_alg != MBEDTLS_MD_NONE) {
/* Gather length of hash to sign */
size_t exp_hashlen = mbedtls_hash_info_get_size(md_alg);
size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
if (exp_hashlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@ -2005,7 +2005,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx,
}
}
hlen = mbedtls_hash_info_get_size(mgf1_hash_id);
hlen = mbedtls_md_get_size_from_type(mgf1_hash_id);
if (hlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}

View file

@ -399,6 +399,8 @@ int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
SHA256_BLOCK_SIZE) ? 0 : -1;
}
#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
#if defined(MBEDTLS_POP_TARGET_PRAGMA)
#if defined(__clang__)
#pragma clang attribute pop
@ -408,8 +410,6 @@ int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx,
#undef MBEDTLS_POP_TARGET_PRAGMA
#endif
#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */
#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT)
#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many
#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process

631
library/sha3.c Normal file
View file

@ -0,0 +1,631 @@
/*
* FIPS-202 compliant SHA3 implementation
*
* 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.
*/
/*
* The SHA-3 Secure Hash Standard was published by NIST in 2015.
*
* https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
*/
#include "common.h"
#if defined(MBEDTLS_SHA3_C)
#include "mbedtls/sha3.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#include "mbedtls/platform.h"
#endif /* MBEDTLS_SELF_TEST */
#define XOR_BYTE 0x6
typedef struct mbedtls_sha3_family_functions {
mbedtls_sha3_id id;
uint16_t r;
uint16_t olen;
}
mbedtls_sha3_family_functions;
/*
* List of supported SHA-3 families
*/
static mbedtls_sha3_family_functions sha3_families[] = {
{ MBEDTLS_SHA3_224, 1152, 224 },
{ MBEDTLS_SHA3_256, 1088, 256 },
{ MBEDTLS_SHA3_384, 832, 384 },
{ MBEDTLS_SHA3_512, 576, 512 },
{ MBEDTLS_SHA3_NONE, 0, 0 }
};
static const uint64_t rc[24] = {
0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
};
static const uint8_t rho[24] = {
1, 62, 28, 27, 36, 44, 6, 55, 20,
3, 10, 43, 25, 39, 41, 45, 15,
21, 8, 18, 2, 61, 56, 14
};
static const uint8_t pi[24] = {
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
};
#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
} while (0)
#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
/* The permutation function. */
static void keccak_f1600(mbedtls_sha3_context *ctx)
{
uint64_t lane[5];
uint64_t *s = ctx->state;
int i;
for (int round = 0; round < 24; round++) {
uint64_t t;
/* Theta */
lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
t = lane[4] ^ ROT64(lane[1], 1);
s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
t = lane[0] ^ ROT64(lane[2], 1);
s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
t = lane[1] ^ ROT64(lane[3], 1);
s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
t = lane[2] ^ ROT64(lane[4], 1);
s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
t = lane[3] ^ ROT64(lane[0], 1);
s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
/* Rho */
for (i = 1; i < 25; i++) {
s[i] = ROT64(s[i], rho[i-1]);
}
/* Pi */
t = s[1];
for (i = 0; i < 24; i++) {
SWAP(s[pi[i]], t);
}
/* Chi */
lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
s[0] ^= (~lane[1]) & lane[2];
s[1] ^= (~lane[2]) & lane[3];
s[2] ^= (~lane[3]) & lane[4];
s[3] ^= (~lane[4]) & lane[0];
s[4] ^= (~lane[0]) & lane[1];
lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
s[5] ^= (~lane[1]) & lane[2];
s[6] ^= (~lane[2]) & lane[3];
s[7] ^= (~lane[3]) & lane[4];
s[8] ^= (~lane[4]) & lane[0];
s[9] ^= (~lane[0]) & lane[1];
lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
s[10] ^= (~lane[1]) & lane[2];
s[11] ^= (~lane[2]) & lane[3];
s[12] ^= (~lane[3]) & lane[4];
s[13] ^= (~lane[4]) & lane[0];
s[14] ^= (~lane[0]) & lane[1];
lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
s[15] ^= (~lane[1]) & lane[2];
s[16] ^= (~lane[2]) & lane[3];
s[17] ^= (~lane[3]) & lane[4];
s[18] ^= (~lane[4]) & lane[0];
s[19] ^= (~lane[0]) & lane[1];
lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
s[20] ^= (~lane[1]) & lane[2];
s[21] ^= (~lane[2]) & lane[3];
s[22] ^= (~lane[3]) & lane[4];
s[23] ^= (~lane[4]) & lane[0];
s[24] ^= (~lane[0]) & lane[1];
/* Iota */
s[0] ^= rc[round];
}
}
void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
{
memset(ctx, 0, sizeof(mbedtls_sha3_context));
}
void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
{
if (ctx == NULL) {
return;
}
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
}
void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
const mbedtls_sha3_context *src)
{
*dst = *src;
}
/*
* SHA-3 context setup
*/
int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
{
mbedtls_sha3_family_functions *p = NULL;
for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
if (p->id == id) {
break;
}
}
if (p == NULL || p->id == MBEDTLS_SHA3_NONE) {
return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
}
ctx->olen = p->olen / 8;
ctx->max_block_size = p->r / 8;
memset(ctx->state, 0, sizeof(ctx->state));
ctx->index = 0;
return 0;
}
/*
* SHA-3 process buffer
*/
int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
const uint8_t *input,
size_t ilen)
{
if (ilen >= 8) {
// 8-byte align index
int align_bytes = 8 - (ctx->index % 8);
if (align_bytes) {
for (; align_bytes > 0; align_bytes--) {
ABSORB(ctx, ctx->index, *input++);
ilen--;
ctx->index++;
}
if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
keccak_f1600(ctx);
}
}
// process input in 8-byte chunks
while (ilen >= 8) {
ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
input += 8;
ilen -= 8;
if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
keccak_f1600(ctx);
}
}
}
// handle remaining bytes
while (ilen-- > 0) {
ABSORB(ctx, ctx->index, *input++);
if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
keccak_f1600(ctx);
}
}
return 0;
}
int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
uint8_t *output, size_t olen)
{
/* Catch SHA-3 families, with fixed output length */
if (ctx->olen > 0) {
if (ctx->olen > olen) {
return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
}
olen = ctx->olen;
}
ABSORB(ctx, ctx->index, XOR_BYTE);
ABSORB(ctx, ctx->max_block_size - 1, 0x80);
keccak_f1600(ctx);
ctx->index = 0;
while (olen-- > 0) {
*output++ = SQUEEZE(ctx, ctx->index);
if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
keccak_f1600(ctx);
}
}
return 0;
}
/*
* output = SHA-3( input buffer )
*/
int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
size_t ilen, uint8_t *output, size_t olen)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha3_context ctx;
mbedtls_sha3_init(&ctx);
/* Sanity checks are performed in every mbedtls_sha3_xxx() */
if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
goto exit;
}
if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
goto exit;
}
if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
goto exit;
}
exit:
mbedtls_sha3_free(&ctx);
return ret;
}
/**************** Self-tests ****************/
#if defined(MBEDTLS_SELF_TEST)
static const unsigned char test_data[2][4] =
{
"",
"abc",
};
static const size_t test_data_len[2] =
{
0, /* "" */
3 /* "abc" */
};
static const unsigned char test_hash_sha3_224[2][28] =
{
{ /* "" */
0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
0x5B, 0x5A, 0x6B, 0xC7
},
{ /* "abc" */
0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
0x73, 0xB4, 0x6F, 0xDF
}
};
static const unsigned char test_hash_sha3_256[2][32] =
{
{ /* "" */
0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
},
{ /* "abc" */
0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
}
};
static const unsigned char test_hash_sha3_384[2][48] =
{
{ /* "" */
0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
},
{ /* "abc" */
0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
}
};
static const unsigned char test_hash_sha3_512[2][64] =
{
{ /* "" */
0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
},
{ /* "abc" */
0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
}
};
static const unsigned char long_kat_hash_sha3_224[28] =
{
0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
0xA7, 0xFD, 0x65, 0x3C
};
static const unsigned char long_kat_hash_sha3_256[32] =
{
0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
};
static const unsigned char long_kat_hash_sha3_384[48] =
{
0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
};
static const unsigned char long_kat_hash_sha3_512[64] =
{
0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
};
static int mbedtls_sha3_kat_test(int verbose,
const char *type_name,
mbedtls_sha3_id id,
int test_num)
{
uint8_t hash[64];
int result;
result = mbedtls_sha3(id,
test_data[test_num], test_data_len[test_num],
hash, sizeof(hash));
if (result != 0) {
if (verbose != 0) {
mbedtls_printf(" %s test %d error code: %d\n",
type_name, test_num, result);
}
return result;
}
switch (id) {
case MBEDTLS_SHA3_224:
result = memcmp(hash, test_hash_sha3_224[test_num], 28);
break;
case MBEDTLS_SHA3_256:
result = memcmp(hash, test_hash_sha3_256[test_num], 32);
break;
case MBEDTLS_SHA3_384:
result = memcmp(hash, test_hash_sha3_384[test_num], 48);
break;
case MBEDTLS_SHA3_512:
result = memcmp(hash, test_hash_sha3_512[test_num], 64);
break;
default:
break;
}
if (0 != result) {
if (verbose != 0) {
mbedtls_printf(" %s test %d failed\n", type_name, test_num);
}
return -1;
}
if (verbose != 0) {
mbedtls_printf(" %s test %d passed\n", type_name, test_num);
}
return 0;
}
static int mbedtls_sha3_long_kat_test(int verbose,
const char *type_name,
mbedtls_sha3_id id)
{
mbedtls_sha3_context ctx;
unsigned char buffer[1000];
unsigned char hash[64];
int result = 0;
memset(buffer, 'a', 1000);
if (verbose != 0) {
mbedtls_printf(" %s long KAT test ", type_name);
}
mbedtls_sha3_init(&ctx);
result = mbedtls_sha3_starts(&ctx, id);
if (result != 0) {
if (verbose != 0) {
mbedtls_printf("setup failed\n ");
}
}
/* Process 1,000,000 (one million) 'a' characters */
for (int i = 0; i < 1000; i++) {
result = mbedtls_sha3_update(&ctx, buffer, 1000);
if (result != 0) {
if (verbose != 0) {
mbedtls_printf("update error code: %i\n", result);
}
goto cleanup;
}
}
result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
if (result != 0) {
if (verbose != 0) {
mbedtls_printf("finish error code: %d\n", result);
}
goto cleanup;
}
switch (id) {
case MBEDTLS_SHA3_224:
result = memcmp(hash, long_kat_hash_sha3_224, 28);
break;
case MBEDTLS_SHA3_256:
result = memcmp(hash, long_kat_hash_sha3_256, 32);
break;
case MBEDTLS_SHA3_384:
result = memcmp(hash, long_kat_hash_sha3_384, 48);
break;
case MBEDTLS_SHA3_512:
result = memcmp(hash, long_kat_hash_sha3_512, 64);
break;
default:
break;
}
if (result != 0) {
if (verbose != 0) {
mbedtls_printf("failed\n");
}
}
if (verbose != 0) {
mbedtls_printf("passed\n");
}
cleanup:
mbedtls_sha3_free(&ctx);
return result;
}
int mbedtls_sha3_self_test(int verbose)
{
int i;
/* SHA-3 Known Answer Tests (KAT) */
for (i = 0; i < 2; i++) {
if (0 != mbedtls_sha3_kat_test(verbose,
"SHA3-224", MBEDTLS_SHA3_224, i)) {
return 1;
}
if (0 != mbedtls_sha3_kat_test(verbose,
"SHA3-256", MBEDTLS_SHA3_256, i)) {
return 1;
}
if (0 != mbedtls_sha3_kat_test(verbose,
"SHA3-384", MBEDTLS_SHA3_384, i)) {
return 1;
}
if (0 != mbedtls_sha3_kat_test(verbose,
"SHA3-512", MBEDTLS_SHA3_512, i)) {
return 1;
}
}
/* SHA-3 long KAT tests */
if (0 != mbedtls_sha3_long_kat_test(verbose,
"SHA3-224", MBEDTLS_SHA3_224)) {
return 1;
}
if (0 != mbedtls_sha3_long_kat_test(verbose,
"SHA3-256", MBEDTLS_SHA3_256)) {
return 1;
}
if (0 != mbedtls_sha3_long_kat_test(verbose,
"SHA3-384", MBEDTLS_SHA3_384)) {
return 1;
}
if (0 != mbedtls_sha3_long_kat_test(verbose,
"SHA3-512", MBEDTLS_SHA3_512)) {
return 1;
}
if (verbose != 0) {
mbedtls_printf("\n");
}
return 0;
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_SHA3_C */

View file

@ -569,6 +569,8 @@ int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
SHA512_BLOCK_SIZE) ? 0 : -1;
}
#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
#if defined(MBEDTLS_POP_TARGET_PRAGMA)
#if defined(__clang__)
#pragma clang attribute pop
@ -578,8 +580,6 @@ int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx,
#undef MBEDTLS_POP_TARGET_PRAGMA
#endif
#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */
#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT)
#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many

View file

@ -28,6 +28,9 @@
#include "mbedtls/ssl_ciphersuites.h"
#include "mbedtls/ssl.h"
#include "ssl_misc.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "md_psa.h"
#endif
#include <string.h>
@ -1966,10 +1969,10 @@ psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_cip
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
return PSA_ALG_RSA_PKCS1V15_SIGN(
mbedtls_hash_info_psa_from_md(info->mac));
mbedtls_md_psa_alg_from_type(info->mac));
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(info->mac));
return PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(info->mac));
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:

View file

@ -36,6 +36,7 @@
#include <string.h>
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "md_psa.h"
#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_ssl_errors, \
psa_generic_status_to_mbedtls)
@ -114,7 +115,7 @@ int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx,
(void) f_rng;
(void) p_rng;
alg = mbedtls_hash_info_psa_from_md(COOKIE_MD);
alg = mbedtls_md_psa_alg_from_type(COOKIE_MD);
if (alg == 0) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
@ -364,10 +365,7 @@ int mbedtls_ssl_cookie_check(void *p_ctx,
cur_time = ctx->serial;
#endif
cookie_time = ((unsigned long) cookie[0] << 24) |
((unsigned long) cookie[1] << 16) |
((unsigned long) cookie[2] << 8) |
((unsigned long) cookie[3]);
cookie_time = (unsigned long) MBEDTLS_GET_UINT32_BE(cookie, 0);
if (ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout) {
ret = -1;

View file

@ -30,7 +30,6 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#include "hash_info.h"
#endif
#if defined(MBEDTLS_MD_CAN_MD5)

View file

@ -41,6 +41,7 @@
#include <string.h>
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "md_psa.h"
#include "mbedtls/psa_util.h"
#include "psa/crypto.h"
#endif
@ -843,11 +844,11 @@ int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_abort(&ssl->handshake->fin_sha256_psa);
if (status != PSA_SUCCESS) {
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
}
status = psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
}
#else
mbedtls_md_free(&ssl->handshake->fin_sha256);
@ -868,11 +869,11 @@ int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_abort(&ssl->handshake->fin_sha384_psa);
if (status != PSA_SUCCESS) {
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
}
status = psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384);
if (status != PSA_SUCCESS) {
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
}
#else
mbedtls_md_free(&ssl->handshake->fin_sha384);
@ -910,7 +911,7 @@ static int ssl_update_checksum_start(mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
if (status != PSA_SUCCESS) {
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
}
#else
ret = mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len);
@ -923,7 +924,7 @@ static int ssl_update_checksum_start(mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
if (status != PSA_SUCCESS) {
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
}
#else
ret = mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len);
@ -940,8 +941,8 @@ static int ssl_update_checksum_sha256(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
return PSA_TO_MD_ERR(psa_hash_update(
&ssl->handshake->fin_sha256_psa, buf, len));
return mbedtls_md_error_from_psa(psa_hash_update(
&ssl->handshake->fin_sha256_psa, buf, len));
#else
return mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len);
#endif
@ -953,8 +954,8 @@ static int ssl_update_checksum_sha384(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
return PSA_TO_MD_ERR(psa_hash_update(
&ssl->handshake->fin_sha384_psa, buf, len));
return mbedtls_md_error_from_psa(psa_hash_update(
&ssl->handshake->fin_sha384_psa, buf, len));
#else
return mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len);
#endif
@ -1155,8 +1156,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
size_t length;
const mbedtls_ecp_group_id *curve_list = ssl->conf->curve_list;
for (length = 0; (curve_list[length] != MBEDTLS_ECP_DP_NONE) &&
(length < MBEDTLS_ECP_DP_MAX); length++) {
for (length = 0; (curve_list[length] != MBEDTLS_ECP_DP_NONE); length++) {
}
/* Leave room for zero termination */
@ -4613,10 +4613,7 @@ static int ssl_context_load(mbedtls_ssl_context *ssl,
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
session_len = ((size_t) p[0] << 24) |
((size_t) p[1] << 16) |
((size_t) p[2] << 8) |
((size_t) p[3]);
session_len = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
/* This has been allocated by ssl_handshake_init(), called by
@ -4711,10 +4708,7 @@ static int ssl_context_load(mbedtls_ssl_context *ssl,
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
ssl->badmac_seen = ((uint32_t) p[0] << 24) |
((uint32_t) p[1] << 16) |
((uint32_t) p[2] << 8) |
((uint32_t) p[3]);
ssl->badmac_seen = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
@ -4722,24 +4716,10 @@ static int ssl_context_load(mbedtls_ssl_context *ssl,
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
ssl->in_window_top = ((uint64_t) p[0] << 56) |
((uint64_t) p[1] << 48) |
((uint64_t) p[2] << 40) |
((uint64_t) p[3] << 32) |
((uint64_t) p[4] << 24) |
((uint64_t) p[5] << 16) |
((uint64_t) p[6] << 8) |
((uint64_t) p[7]);
ssl->in_window_top = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
ssl->in_window = ((uint64_t) p[0] << 56) |
((uint64_t) p[1] << 48) |
((uint64_t) p[2] << 40) |
((uint64_t) p[3] << 32) |
((uint64_t) p[4] << 24) |
((uint64_t) p[5] << 16) |
((uint64_t) p[6] << 8) |
((uint64_t) p[7]);
ssl->in_window = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
@ -6647,7 +6627,7 @@ int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl,
exit:
psa_hash_abort(&sha256_psa);
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_context_t sha256;
@ -6709,7 +6689,7 @@ int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl,
exit:
psa_hash_abort(&sha384_psa);
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_context_t sha384;
@ -7388,13 +7368,12 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
/* and in the unlikely case the above assumption no longer holds
* we are making sure that pk_ec() here does not return a NULL
*/
const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
if (ec == NULL) {
MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_pk_ec_ro() returned NULL"));
mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(pk);
if (grp_id == MBEDTLS_ECP_DP_NONE) {
MBEDTLS_SSL_DEBUG_MSG(1, ("invalid group ID"));
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
if (mbedtls_ssl_check_curve(ssl, ec->grp.id) != 0) {
if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
ssl->session_negotiate->verify_result |=
MBEDTLS_X509_BADCERT_BAD_KEY;
@ -7763,7 +7742,7 @@ static int ssl_calc_finished_tls_sha256(
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&sha256_psa);
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
#else
mbedtls_md_free(&sha256);
return ret;
@ -7852,7 +7831,7 @@ static int ssl_calc_finished_tls_sha384(
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&sha384_psa);
return PSA_TO_MD_ERR(status);
return mbedtls_md_error_from_psa(status);
#else
mbedtls_md_free(&sha384);
return ret;
@ -8314,9 +8293,9 @@ static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform,
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mac_alg = mbedtls_hash_info_psa_from_md(ciphersuite_info->mac);
mac_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
if (mac_alg == 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_hash_info_psa_from_md for %u not found",
MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_md_psa_alg_from_type for %u not found",
(unsigned) ciphersuite_info->mac));
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
@ -8763,7 +8742,7 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl,
{
psa_status_t status;
psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(md_alg);
psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(md_alg);
MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based computation of digest of ServerKeyExchange"));
@ -8892,7 +8871,7 @@ unsigned int mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (ssl->handshake->key_cert && ssl->handshake->key_cert->key) {
psa_algorithm_t psa_hash_alg =
mbedtls_hash_info_psa_from_md(hash_alg_received);
mbedtls_md_psa_alg_from_type(hash_alg_received);
if (sig_alg_received == MBEDTLS_SSL_SIG_ECDSA &&
!mbedtls_pk_can_do_ext(ssl->handshake->key_cert->key,
@ -9102,14 +9081,7 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session,
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
start = ((uint64_t) p[0] << 56) |
((uint64_t) p[1] << 48) |
((uint64_t) p[2] << 40) |
((uint64_t) p[3] << 32) |
((uint64_t) p[4] << 24) |
((uint64_t) p[5] << 16) |
((uint64_t) p[6] << 8) |
((uint64_t) p[7]);
start = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
session->start = (time_t) start;
@ -9132,10 +9104,7 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session,
memcpy(session->master, p, 48);
p += 48;
session->verify_result = ((uint32_t) p[0] << 24) |
((uint32_t) p[1] << 16) |
((uint32_t) p[2] << 8) |
((uint32_t) p[3]);
session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
/* Immediately clear invalid pointer values that have been read, in case
@ -9254,10 +9223,7 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session,
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
session->ticket_lifetime = ((uint32_t) p[0] << 24) |
((uint32_t) p[1] << 16) |
((uint32_t) p[2] << 8) |
((uint32_t) p[3]);
session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */

View file

@ -50,8 +50,6 @@
#include "mbedtls/platform_util.h"
#endif
#include "hash_info.h"
#if defined(MBEDTLS_SSL_RENEGOTIATION)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
@ -1986,7 +1984,6 @@ MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_ecp_keypair *peer_key;
mbedtls_pk_context *peer_pk;
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
@ -2007,22 +2004,24 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
}
peer_key = mbedtls_pk_ec_ro(*peer_pk);
#if defined(MBEDTLS_ECP_C)
const mbedtls_ecp_keypair *peer_key = mbedtls_pk_ec_ro(*peer_pk);
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
size_t olen = 0;
uint16_t tls_id = 0;
psa_ecc_family_t ecc_family;
mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(peer_pk);
if (mbedtls_ssl_check_curve(ssl, peer_key->grp.id) != 0) {
if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
return MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
}
tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(peer_key->grp.id);
tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
if (tls_id == 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not suported",
peer_key->grp.id));
grp_id));
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
@ -2034,6 +2033,12 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
ssl->handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family);
/* Store peer's public key in psa format. */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
memcpy(ssl->handshake->ecdh_psa_peerkey, peer_pk->pub_raw, peer_pk->pub_raw_len);
ssl->handshake->ecdh_psa_peerkey_len = peer_pk->pub_raw_len;
ret = 0;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
size_t olen = 0;
ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED, &olen,
ssl->handshake->ecdh_psa_peerkey,
@ -2043,9 +2048,9 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret);
return ret;
}
ssl->handshake->ecdh_psa_peerkey_len = olen;
#else
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#else /* MBEDTLS_USE_PSA_CRYPTO */
if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, peer_key,
MBEDTLS_ECDH_THEIRS)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
@ -2056,7 +2061,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
return MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
}
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* We don't need the peer's public key anymore. Free it,
* so that more RAM is available for upcoming expensive
@ -2284,7 +2289,7 @@ start_processing:
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) {
size_t sig_len, hashlen;
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
@ -2401,7 +2406,7 @@ start_processing:
mbedtls_pk_rsassa_pss_options rsassa_pss_options;
rsassa_pss_options.mgf1_hash_id = md_alg;
rsassa_pss_options.expected_salt_len =
mbedtls_hash_info_get_size(md_alg);
mbedtls_md_get_size_from_type(md_alg);
if (rsassa_pss_options.expected_salt_len == 0) {
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}

View file

@ -30,7 +30,6 @@
#include "mbedtls/platform_util.h"
#include "constant_time_internal.h"
#include "mbedtls/constant_time.h"
#include "hash_info.h"
#include <string.h>
@ -1088,9 +1087,7 @@ read_record_header:
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
/* This couldn't be done in ssl_prepare_handshake_record() */
unsigned int cli_msg_seq = (ssl->in_msg[4] << 8) |
ssl->in_msg[5];
unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
if (cli_msg_seq != ssl->handshake->in_msg_seq) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
"%u (expected %u)", cli_msg_seq,
@ -1102,8 +1099,7 @@ read_record_header:
} else
#endif
{
unsigned int cli_msg_seq = (ssl->in_msg[4] << 8) |
ssl->in_msg[5];
unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
ssl->handshake->out_msg_seq = cli_msg_seq;
ssl->handshake->in_msg_seq = cli_msg_seq + 1;
}
@ -2600,7 +2596,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
psa_ecc_family_t ecc_family;
size_t key_len;
mbedtls_pk_context *pk;
mbedtls_ecp_keypair *key;
mbedtls_ecp_group_id grp_id;
pk = mbedtls_ssl_own_key(ssl);
@ -2608,6 +2604,10 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
mbedtls_ecp_keypair *key = mbedtls_pk_ec_rw(*pk);
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
switch (mbedtls_pk_get_type(pk)) {
case MBEDTLS_PK_OPAQUE:
if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) {
@ -2636,12 +2636,11 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
key = mbedtls_pk_ec_rw(*pk);
if (key == NULL) {
grp_id = mbedtls_pk_get_group_id(pk);
if (grp_id == MBEDTLS_ECP_DP_NONE) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(key->grp.id);
tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
if (tls_id == 0) {
/* This elliptic curve is not supported */
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
@ -2661,11 +2660,19 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->ecdh_psa_type));
psa_set_key_bits(&key_attributes, ssl->handshake->ecdh_bits);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
status = psa_export_key(pk->priv_id, buf, sizeof(buf), &key_len);
if (status != PSA_SUCCESS) {
ret = PSA_TO_MBEDTLS_ERR(status);
goto cleanup;
}
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
key_len = PSA_BITS_TO_BYTES(key->grp.pbits);
ret = mbedtls_ecp_write_key(key, buf, key_len);
if (ret != 0) {
goto cleanup;
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
status = psa_import_key(&key_attributes, buf, key_len,
&ssl->handshake->ecdh_psa_privkey);
@ -3073,7 +3080,7 @@ curve_matching_done:
size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
size_t hashlen = 0;
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

View file

@ -33,6 +33,7 @@
#include "ssl_client.h"
#include "ssl_tls13_keys.h"
#include "ssl_debug_helpers.h"
#include "md_psa.h"
#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_ssl_errors, \
@ -672,7 +673,7 @@ static psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg(int ciphersuite)
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
if (ciphersuite_info != NULL) {
return mbedtls_psa_translate_md(ciphersuite_info->mac);
return mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
}
return PSA_ALG_NONE;
@ -850,7 +851,7 @@ static int ssl_tls13_write_binder(mbedtls_ssl_context *ssl,
/* Get current state of handshake transcript. */
ret = mbedtls_ssl_get_handshake_transcript(
ssl, mbedtls_hash_info_md_from_psa(hash_alg),
ssl, mbedtls_md_type_from_psa_alg(hash_alg),
transcript, sizeof(transcript), &transcript_len);
if (ret != 0) {
return ret;
@ -1126,7 +1127,7 @@ static int ssl_tls13_parse_server_pre_shared_key_ext(mbedtls_ssl_context *ssl,
return ret;
}
if (mbedtls_psa_translate_md(ssl->handshake->ciphersuite_info->mac)
if (mbedtls_md_psa_alg_from_type(ssl->handshake->ciphersuite_info->mac)
!= hash_alg) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("Invalid ciphersuite for external psk."));
@ -1696,7 +1697,7 @@ static int ssl_tls13_parse_server_hello(mbedtls_ssl_context *ssl,
cipher_suite, ciphersuite_info->name));
#if defined(MBEDTLS_HAVE_TIME)
ssl->session_negotiate->start = time(NULL);
ssl->session_negotiate->start = mbedtls_time(NULL);
#endif /* MBEDTLS_HAVE_TIME */
/* ...
@ -2844,7 +2845,7 @@ static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl,
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
psa_hash_alg = mbedtls_psa_translate_md(ciphersuite_info->mac);
psa_hash_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
hash_length = PSA_HASH_LENGTH(psa_hash_alg);
if (hash_length == -1 ||
(size_t) hash_length > sizeof(session->resumption_key)) {

View file

@ -29,7 +29,7 @@
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#include "md_psa.h"
#include "ssl_misc.h"
#include "ssl_tls13_invasive.h"
@ -274,7 +274,7 @@ static int ssl_tls13_parse_certificate_verify(mbedtls_ssl_context *ssl,
goto error;
}
hash_alg = mbedtls_hash_info_psa_from_md(md_alg);
hash_alg = mbedtls_md_psa_alg_from_type(md_alg);
if (hash_alg == 0) {
goto error;
}
@ -1076,7 +1076,7 @@ static int ssl_tls13_write_certificate_verify_body(mbedtls_ssl_context *ssl,
}
/* Hash verify buffer with indicated hash function */
psa_algorithm = mbedtls_hash_info_psa_from_md(md_alg);
psa_algorithm = mbedtls_md_psa_alg_from_type(md_alg);
status = psa_hash_compute(psa_algorithm,
verify_buffer,
verify_buffer_len,

View file

@ -34,6 +34,7 @@
#include "ssl_tls13_invasive.h"
#include "psa/crypto.h"
#include "md_psa.h"
#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_ssl_errors, \
@ -677,7 +678,7 @@ static int ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
psa_algorithm_t const hash_alg = mbedtls_hash_info_psa_from_md(
psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type(
handshake->ciphersuite_info->mac);
/*
@ -792,7 +793,7 @@ int mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context *ssl,
mbedtls_md_type_t const md_type = ssl->handshake->ciphersuite_info->mac;
psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(
psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(
ssl->handshake->ciphersuite_info->mac);
size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
@ -1163,7 +1164,7 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
md_type = ciphersuite_info->mac;
hash_alg = mbedtls_hash_info_psa_from_md(ciphersuite_info->mac);
hash_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
hash_len = PSA_HASH_LENGTH(hash_alg);
ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
@ -1291,7 +1292,7 @@ int mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
hash_alg = mbedtls_hash_info_psa_from_md(handshake->ciphersuite_info->mac);
hash_alg = mbedtls_md_psa_alg_from_type(handshake->ciphersuite_info->mac);
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
ret = mbedtls_ssl_tls13_export_handshake_psk(ssl, &psk, &psk_len);
@ -1365,7 +1366,7 @@ static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
md_type = ciphersuite_info->mac;
hash_alg = mbedtls_hash_info_psa_from_md(ciphersuite_info->mac);
hash_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
hash_len = PSA_HASH_LENGTH(hash_alg);
ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
@ -1472,7 +1473,7 @@ static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
psa_algorithm_t const hash_alg = mbedtls_hash_info_psa_from_md(
psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type(
handshake->ciphersuite_info->mac);
unsigned char *shared_secret = NULL;
size_t shared_secret_len = 0;
@ -1608,7 +1609,7 @@ static int ssl_tls13_generate_application_keys(
md_type = handshake->ciphersuite_info->mac;
hash_alg = mbedtls_hash_info_psa_from_md(handshake->ciphersuite_info->mac);
hash_alg = mbedtls_md_psa_alg_from_type(handshake->ciphersuite_info->mac);
hash_len = PSA_HASH_LENGTH(hash_alg);
/* Compute current handshake transcript. It's the caller's responsibility
@ -1766,7 +1767,7 @@ int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl)
}
ret = mbedtls_ssl_tls13_derive_resumption_master_secret(
mbedtls_psa_translate_md(md_type),
mbedtls_md_psa_alg_from_type(md_type),
handshake->tls13_master_secrets.app,
transcript, transcript_len,
&ssl->session_negotiate->app_secrets);
@ -1781,7 +1782,7 @@ int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl)
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)));
PSA_HASH_LENGTH(mbedtls_md_psa_alg_from_type(md_type)));
MBEDTLS_SSL_DEBUG_MSG(
2, ("<= mbedtls_ssl_tls13_compute_resumption_master_secret"));

View file

@ -25,6 +25,7 @@
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
#include "md_psa.h"
#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
@ -332,7 +333,7 @@ static int ssl_tls13_offered_psks_check_binder_match(
/* Get current state of handshake transcript. */
ret = mbedtls_ssl_get_handshake_transcript(
ssl, mbedtls_hash_info_md_from_psa(psk_hash_alg),
ssl, mbedtls_md_type_from_psa_alg(psk_hash_alg),
transcript, sizeof(transcript), &transcript_len);
if (ret != 0) {
return ret;
@ -406,7 +407,7 @@ static int ssl_tls13_select_ciphersuite_for_psk(
/* MAC of selected ciphersuite MUST be same with PSK binder if exist.
* Otherwise, client should reject.
*/
if (psk_hash_alg == mbedtls_psa_translate_md(ciphersuite_info->mac)) {
if (psk_hash_alg == mbedtls_md_psa_alg_from_type(ciphersuite_info->mac)) {
*selected_ciphersuite = cipher_suite;
*selected_ciphersuite_info = ciphersuite_info;
return 0;
@ -612,7 +613,7 @@ static int ssl_tls13_parse_pre_shared_key_ext(
ret = ssl_tls13_offered_psks_check_binder_match(
ssl, binder, binder_len, psk_type,
mbedtls_psa_translate_md(ciphersuite_info->mac));
mbedtls_md_psa_alg_from_type(ciphersuite_info->mac));
if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) {
/* For security reasons, the handshake should be aborted when we
* fail to validate a binder value. See RFC 8446 section 4.2.11.2
@ -1846,7 +1847,7 @@ static int ssl_tls13_prepare_server_hello(mbedtls_ssl_context *ssl)
MBEDTLS_SERVER_HELLO_RANDOM_LEN);
#if defined(MBEDTLS_HAVE_TIME)
ssl->session_negotiate->start = time(NULL);
ssl->session_negotiate->start = mbedtls_time(NULL);
#endif /* MBEDTLS_HAVE_TIME */
return ret;
@ -2783,7 +2784,7 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
ciphersuite_info =
(mbedtls_ssl_ciphersuite_t *) ssl->handshake->ciphersuite_info;
psa_hash_alg = mbedtls_psa_translate_md(ciphersuite_info->mac);
psa_hash_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
hash_length = PSA_HASH_LENGTH(psa_hash_alg);
if (hash_length == -1 ||
(size_t) hash_length > sizeof(session->resumption_key)) {

View file

@ -1215,9 +1215,9 @@ int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p,
mbedtls_asn1_sequence *cur = subject_alt_name;
while (*p < end) {
mbedtls_x509_subject_alternative_name dummy_san_buf;
mbedtls_x509_subject_alternative_name tmp_san_name;
mbedtls_x509_buf tmp_san_buf;
memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
memset(&tmp_san_name, 0, sizeof(tmp_san_name));
tmp_san_buf.tag = **p;
(*p)++;
@ -1236,9 +1236,10 @@ int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p,
}
/*
* Check that the SAN is structured correctly.
* Check that the SAN is structured correctly by parsing it.
* The SAN structure is discarded afterwards.
*/
ret = mbedtls_x509_parse_subject_alt_name(&tmp_san_buf, &dummy_san_buf);
ret = mbedtls_x509_parse_subject_alt_name(&tmp_san_buf, &tmp_san_name);
/*
* In case the extension is malformed, return an error,
* and clear the allocated sequences.
@ -1249,7 +1250,7 @@ int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p,
return ret;
}
mbedtls_x509_free_subject_alt_name(&dummy_san_buf);
mbedtls_x509_free_subject_alt_name(&tmp_san_name);
/* Allocate and assign next pointer */
if (cur->buf.p != NULL) {
if (cur->next != NULL) {
@ -1437,9 +1438,24 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
san_buf, sizeof(*san_buf));
}
break;
/*
* RFC822 Name
* IP address
*/
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_IP_ADDRESS):
{
memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
san->type = MBEDTLS_X509_SAN_IP_ADDRESS;
// Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported
if (san_buf->len == 4 || san_buf->len == 16) {
memcpy(&san->san.unstructured_name,
san_buf, sizeof(*san_buf));
} else {
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
}
break;
/*
* rfc822Name
*/
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_RFC822_NAME):
{
@ -1448,7 +1464,6 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf));
}
break;
/*
* directoryName
*/
@ -1563,7 +1578,9 @@ int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
ret = mbedtls_snprintf(p, n, "\n%s uniformResourceIdentifier : ", prefix);
MBEDTLS_X509_SAFE_SNPRINTF;
if (san.san.unstructured_name.len >= n) {
*p = '\0';
if (n > 0) {
*p = '\0';
}
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
@ -1589,7 +1606,9 @@ int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
MBEDTLS_X509_SAN_DNS_NAME ? dns_name : rfc822_name);
MBEDTLS_X509_SAFE_SNPRINTF;
if (san.san.unstructured_name.len >= n) {
*p = '\0';
if (n > 0) {
*p = '\0';
}
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
@ -1598,7 +1617,41 @@ int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
n -= san.san.unstructured_name.len;
}
break;
/*
* iPAddress
*/
case MBEDTLS_X509_SAN_IP_ADDRESS:
{
ret = mbedtls_snprintf(p, n, "\n%s %s : ",
prefix, "iPAddress");
MBEDTLS_X509_SAFE_SNPRINTF;
if (san.san.unstructured_name.len >= n) {
if (n > 0) {
*p = '\0';
}
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
unsigned char *ip = san.san.unstructured_name.p;
// Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported
if (san.san.unstructured_name.len == 4) {
ret = mbedtls_snprintf(p, n, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
MBEDTLS_X509_SAFE_SNPRINTF;
} else if (san.san.unstructured_name.len == 16) {
ret = mbedtls_snprintf(p, n,
"%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X",
ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6],
ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13],
ip[14], ip[15]);
MBEDTLS_X509_SAFE_SNPRINTF;
} else {
if (n > 0) {
*p = '\0';
}
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
}
break;
/*
* directoryName
*/
@ -1614,6 +1667,9 @@ int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
if (ret < 0) {
mbedtls_x509_free_subject_alt_name(&san);
if (n > 0) {
*p = '\0';
}
return ret;
}

View file

@ -47,8 +47,8 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#include "md_psa.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#include "hash_info.h"
#include "x509_invasive.h"
#include "pk_internal.h"
@ -238,7 +238,7 @@ static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile,
if (pk_alg == MBEDTLS_PK_ECDSA ||
pk_alg == MBEDTLS_PK_ECKEY ||
pk_alg == MBEDTLS_PK_ECKEY_DH) {
const mbedtls_ecp_group_id gid = mbedtls_pk_ec_ro(*pk)->grp.id;
const mbedtls_ecp_group_id gid = mbedtls_pk_get_group_id(pk);
if (gid == MBEDTLS_ECP_DP_NONE) {
return -1;
@ -2024,7 +2024,7 @@ static int x509_crt_verifycrl(mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
const mbedtls_x509_crt_profile *profile)
{
int flags = 0;
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_algorithm_t psa_algorithm;
#else
@ -2064,7 +2064,7 @@ static int x509_crt_verifycrl(mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_algorithm = mbedtls_hash_info_psa_from_md(crl_list->sig_md);
psa_algorithm = mbedtls_md_psa_alg_from_type(crl_list->sig_md);
if (psa_hash_compute(psa_algorithm,
crl_list->tbs.p,
crl_list->tbs.len,
@ -2133,7 +2133,7 @@ static int x509_crt_check_signature(const mbedtls_x509_crt *child,
mbedtls_x509_crt_restart_ctx *rs_ctx)
{
size_t hash_len;
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
const mbedtls_md_info_t *md_info;
md_info = mbedtls_md_info_from_type(child->sig_md);
@ -2144,7 +2144,7 @@ static int x509_crt_check_signature(const mbedtls_x509_crt *child,
return -1;
}
#else
psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(child->sig_md);
psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(child->sig_md);
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_hash_compute(hash_alg,
@ -2911,6 +2911,21 @@ static int x509_crt_check_san_ip(const mbedtls_x509_sequence *san,
return -1;
}
static int x509_crt_check_san_uri(const mbedtls_x509_sequence *san,
const char *cn, size_t cn_len)
{
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_UNIFORM_RESOURCE_IDENTIFIER &&
cur->buf.len == cn_len && memcmp(cur->buf.p, cn, cn_len) == 0) {
return 0;
}
}
return -1;
}
/*
* Check for SAN match, see RFC 5280 Section 4.2.1.6
*/
@ -2918,23 +2933,38 @@ static int x509_crt_check_san(const mbedtls_x509_sequence *san,
const char *cn, size_t cn_len)
{
int san_ip = 0;
int san_uri = 0;
/* Prioritize DNS name over other subtypes due to popularity */
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 */
case MBEDTLS_X509_SAN_DNS_NAME:
if (x509_crt_check_cn(&cur->buf, cn, cn_len) == 0) {
return 0;
}
break;
case MBEDTLS_X509_SAN_IP_ADDRESS: /* iPAddress */
case MBEDTLS_X509_SAN_IP_ADDRESS:
san_ip = 1;
break;
case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
san_uri = 1;
break;
/* (We may handle other types here later.) */
default: /* Unrecognized type */
break;
}
}
if (san_ip) {
if (x509_crt_check_san_ip(san, cn, cn_len) == 0) {
return 0;
}
}
if (san_uri) {
if (x509_crt_check_san_uri(san, cn, cn_len) == 0) {
return 0;
}
}
return san_ip ? x509_crt_check_san_ip(san, cn, cn_len) : -1;
return -1;
}
/*

View file

@ -31,10 +31,12 @@
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/md.h"
#include <string.h>
#include <stdint.h>
#if defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
@ -43,9 +45,18 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#include "md_psa.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#include "hash_info.h"
#define CHECK_OVERFLOW_ADD(a, b) \
do \
{ \
if (a > SIZE_MAX - (b)) \
{ \
return MBEDTLS_ERR_X509_BAD_INPUT_DATA; \
} \
a += b; \
} while (0)
void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx)
{
@ -152,6 +163,137 @@ int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx,
return 0;
}
int mbedtls_x509write_crt_set_subject_alternative_name(mbedtls_x509write_cert *ctx,
const mbedtls_x509_san_list *san_list)
{
int ret = 0;
const mbedtls_x509_san_list *cur;
unsigned char *buf;
unsigned char *p;
size_t len;
size_t buflen = 0;
/* Determine the maximum size of the SubjectAltName list */
for (cur = san_list; cur != NULL; cur = cur->next) {
/* Calculate size of the required buffer */
switch (cur->node.type) {
case MBEDTLS_X509_SAN_DNS_NAME:
case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
case MBEDTLS_X509_SAN_IP_ADDRESS:
case MBEDTLS_X509_SAN_RFC822_NAME:
/* length of value for each name entry,
* maximum 4 bytes for the length field,
* 1 byte for the tag/type.
*/
CHECK_OVERFLOW_ADD(buflen, cur->node.san.unstructured_name.len);
CHECK_OVERFLOW_ADD(buflen, 4 + 1);
break;
case MBEDTLS_X509_SAN_DIRECTORY_NAME:
{
const mbedtls_asn1_named_data *chunk = &cur->node.san.directory_name;
while (chunk != NULL) {
// Max 4 bytes for length, +1 for tag,
// additional 4 max for length, +1 for tag.
// See x509_write_name for more information.
CHECK_OVERFLOW_ADD(buflen, 4 + 1 + 4 + 1);
CHECK_OVERFLOW_ADD(buflen, chunk->oid.len);
CHECK_OVERFLOW_ADD(buflen, chunk->val.len);
chunk = chunk->next;
}
CHECK_OVERFLOW_ADD(buflen, 4 + 1);
break;
}
default:
/* Not supported - return. */
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
}
}
/* Add the extra length field and tag */
CHECK_OVERFLOW_ADD(buflen, 4 + 1);
/* Allocate buffer */
buf = mbedtls_calloc(1, buflen);
if (buf == NULL) {
return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
}
p = buf + buflen;
/* Write ASN.1-based structure */
cur = san_list;
len = 0;
while (cur != NULL) {
size_t single_san_len = 0;
switch (cur->node.type) {
case MBEDTLS_X509_SAN_DNS_NAME:
case MBEDTLS_X509_SAN_RFC822_NAME:
case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
case MBEDTLS_X509_SAN_IP_ADDRESS:
{
const unsigned char *unstructured_name =
(const unsigned char *) cur->node.san.unstructured_name.p;
size_t unstructured_name_len = cur->node.san.unstructured_name.len;
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
mbedtls_asn1_write_raw_buffer(
&p, buf,
unstructured_name, unstructured_name_len));
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, mbedtls_asn1_write_len(
&p, buf, unstructured_name_len));
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
mbedtls_asn1_write_tag(
&p, buf,
MBEDTLS_ASN1_CONTEXT_SPECIFIC | cur->node.type));
}
break;
case MBEDTLS_X509_SAN_DIRECTORY_NAME:
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
mbedtls_x509_write_names(&p, buf,
(mbedtls_asn1_named_data *) &
cur->node
.san.directory_name));
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
mbedtls_asn1_write_len(&p, buf, single_san_len));
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
mbedtls_asn1_write_tag(&p, buf,
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_X509_SAN_DIRECTORY_NAME));
break;
default:
/* Error out on an unsupported SAN */
ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
goto cleanup;
}
cur = cur->next;
/* check for overflow */
if (len > SIZE_MAX - single_san_len) {
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
goto cleanup;
}
len += single_san_len;
}
MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
MBEDTLS_ASN1_CHK_CLEANUP_ADD(len,
mbedtls_asn1_write_tag(&p, buf,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
ret = mbedtls_x509write_crt_set_extension(
ctx,
MBEDTLS_OID_SUBJECT_ALT_NAME,
MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME),
0,
buf + buflen - len,
len);
cleanup:
mbedtls_free(buf);
return ret;
}
int mbedtls_x509write_crt_set_extension(mbedtls_x509write_cert *ctx,
const char *oid, size_t oid_len,
int critical,
@ -426,7 +568,7 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx,
unsigned char *c, *c2;
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
size_t hash_length = 0;
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_algorithm_t psa_algorithm;
@ -585,7 +727,7 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx,
/* Compute hash of CRT. */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_algorithm = mbedtls_hash_info_psa_from_md(ctx->md_alg);
psa_algorithm = mbedtls_md_psa_alg_from_type(ctx->md_alg);
status = psa_hash_compute(psa_algorithm,
c,

View file

@ -36,8 +36,8 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#include "md_psa.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#include "hash_info.h"
#include <string.h>
#include <stdlib.h>
@ -243,13 +243,13 @@ static int x509write_csr_der_internal(mbedtls_x509write_csr *ctx,
const char *sig_oid;
size_t sig_oid_len = 0;
unsigned char *c, *c2;
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
size_t len = 0;
mbedtls_pk_type_t pk_alg;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
size_t hash_len;
psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(ctx->md_alg);
psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(ctx->md_alg);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Write the CSR backwards starting from the end of buf */

View file

@ -39,6 +39,7 @@ int main(void)
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "mbedtls/sha3.h"
#include "mbedtls/des.h"
#include "mbedtls/aes.h"
@ -113,11 +114,12 @@ static void mbedtls_set_alarm(int seconds);
#define TITLE_LEN 25
#define OPTIONS \
"md5, ripemd160, sha1, sha256, sha512,\n" \
"des3, des, camellia, chacha20,\n" \
"md5, ripemd160, sha1, sha256, sha512,\n" \
"sha3_224, sha3_256, sha3_384, sha3_512,\n" \
"des3, des, camellia, chacha20,\n" \
"aes_cbc, aes_gcm, aes_ccm, aes_xts, chachapoly,\n" \
"aes_cmac, des3_cmac, poly1305\n" \
"ctr_drbg, hmac_drbg\n" \
"ctr_drbg, hmac_drbg\n" \
"rsa, dhm, ecdsa, ecdh.\n"
#if defined(MBEDTLS_ERROR_C)
@ -506,6 +508,7 @@ unsigned char buf[BUFSIZE];
typedef struct {
char md5, ripemd160, sha1, sha256, sha512,
sha3_224, sha3_256, sha3_384, sha3_512,
des3, des,
aes_cbc, aes_gcm, aes_ccm, aes_xts, chachapoly,
aes_cmac, des3_cmac,
@ -553,6 +556,14 @@ int main(int argc, char *argv[])
todo.sha256 = 1;
} else if (strcmp(argv[i], "sha512") == 0) {
todo.sha512 = 1;
} else if (strcmp(argv[i], "sha3_224") == 0) {
todo.sha3_224 = 1;
} else if (strcmp(argv[i], "sha3_256") == 0) {
todo.sha3_256 = 1;
} else if (strcmp(argv[i], "sha3_384") == 0) {
todo.sha3_384 = 1;
} else if (strcmp(argv[i], "sha3_512") == 0) {
todo.sha3_512 = 1;
} else if (strcmp(argv[i], "des3") == 0) {
todo.des3 = 1;
} else if (strcmp(argv[i], "des") == 0) {
@ -645,6 +656,20 @@ int main(int argc, char *argv[])
TIME_AND_TSC("SHA-512", mbedtls_sha512(buf, BUFSIZE, tmp, 0));
}
#endif
#if defined(MBEDTLS_SHA3_C)
if (todo.sha3_224) {
TIME_AND_TSC("SHA3-224", mbedtls_sha3(MBEDTLS_SHA3_224, buf, BUFSIZE, tmp, 28));
}
if (todo.sha3_256) {
TIME_AND_TSC("SHA3-256", mbedtls_sha3(MBEDTLS_SHA3_256, buf, BUFSIZE, tmp, 32));
}
if (todo.sha3_384) {
TIME_AND_TSC("SHA3-384", mbedtls_sha3(MBEDTLS_SHA3_384, buf, BUFSIZE, tmp, 48));
}
if (todo.sha3_512) {
TIME_AND_TSC("SHA3-512", mbedtls_sha3(MBEDTLS_SHA3_512, buf, BUFSIZE, tmp, 64));
}
#endif
#if defined(MBEDTLS_DES_C)
#if defined(MBEDTLS_CIPHER_MODE_CBC)

View file

@ -33,6 +33,7 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "mbedtls/sha3.h"
#include "mbedtls/des.h"
#include "mbedtls/aes.h"
#include "mbedtls/camellia.h"
@ -251,6 +252,9 @@ const selftest_t selftests[] =
#if defined(MBEDTLS_SHA512_C)
{ "sha512", mbedtls_sha512_self_test },
#endif
#if defined(MBEDTLS_SHA3_C)
{ "sha3", mbedtls_sha3_self_test },
#endif
#if defined(MBEDTLS_DES_C)
{ "des", mbedtls_des_self_test },
#endif

View file

@ -66,7 +66,7 @@ int main(void)
" output_file=%%s default: cert.req\n" \
" subject_name=%%s default: CN=Cert,O=mbed TLS,C=UK\n" \
" san=%%s default: (none)\n" \
" Comma-separated-list of values:\n" \
" Semicolon-separated-list of values:\n" \
" DNS:value\n" \
" URI:value\n" \
" IP:value (Only IPv4 is supported)\n" \
@ -119,7 +119,7 @@ struct options {
static void ip_string_to_bytes(const char *str, uint8_t *bytes, int maxBytes)
{
for (int i = 0; i < maxBytes; i++) {
bytes[i] = (uint8_t) strtoul(str, NULL, 16);
bytes[i] = (uint8_t) strtoul(str, NULL, 10);
str = strchr(str, '.');
if (str == NULL || *str == '\0') {
break;

View file

@ -79,6 +79,7 @@ int main(void)
#define DFL_NOT_AFTER "20301231235959"
#define DFL_SERIAL "1"
#define DFL_SERIAL_HEX "1"
#define DFL_EXT_SUBJECTALTNAME ""
#define DFL_SELFSIGN 0
#define DFL_IS_CA 0
#define DFL_MAX_PATHLEN -1
@ -134,6 +135,13 @@ int main(void)
" subject_identifier=%%s default: 1\n" \
" Possible values: 0, 1\n" \
" (Considered for v3 only)\n" \
" san=%%s default: (none)\n" \
" Semicolon-separated-list of values:\n" \
" DNS:value\n" \
" URI:value\n" \
" RFC822:value\n" \
" IP:value (Only IPv4 is supported)\n" \
" DN:list of comma separated key=value pairs\n" \
" authority_identifier=%%s default: 1\n" \
" Possible values: 0, 1\n" \
" (Considered for v3 only)\n" \
@ -188,6 +196,7 @@ struct options {
const char *issuer_pwd; /* password for the issuer key file */
const char *output_file; /* where to store the constructed CRT */
const char *subject_name; /* subject name for certificate */
mbedtls_x509_san_list *san_list; /* subjectAltName for certificate */
const char *issuer_name; /* issuer name for certificate */
const char *not_before; /* validity period not before */
const char *not_after; /* validity period not after */
@ -207,6 +216,18 @@ struct options {
int format; /* format */
} opt;
static void ip_string_to_bytes(const char *str, uint8_t *bytes, int maxBytes)
{
for (int i = 0; i < maxBytes; i++) {
bytes[i] = (uint8_t) strtoul(str, NULL, 10);
str = strchr(str, '.');
if (str == NULL || *str == '\0') {
break;
}
str++;
}
}
int write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
@ -314,7 +335,9 @@ int main(int argc, char *argv[])
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "crt example app";
mbedtls_x509_san_list *cur, *prev;
mbedtls_asn1_named_data *ext_san_dirname = NULL;
uint8_t ip[4] = { 0 };
/*
* Set to sane values
*/
@ -370,6 +393,7 @@ usage:
opt.authority_identifier = DFL_AUTH_IDENT;
opt.basic_constraints = DFL_CONSTRAINTS;
opt.format = DFL_FORMAT;
opt.san_list = NULL;
for (i = 1; i < argc; i++) {
@ -526,6 +550,92 @@ usage:
*tail = ext_key_usage;
tail = &ext_key_usage->next;
q = r;
}
} else if (strcmp(p, "san") == 0) {
char *subtype_value;
prev = NULL;
while (q != NULL) {
char *semicolon;
r = q;
/* Find the first non-escaped ; occurrence and remove escaped ones */
do {
if ((semicolon = strchr(r, ';')) != NULL) {
if (*(semicolon-1) != '\\') {
r = semicolon;
break;
}
/* Remove the escape character */
size_t size_left = strlen(semicolon);
memmove(semicolon-1, semicolon, size_left);
*(semicolon + size_left - 1) = '\0';
/* r will now point at the character after the semicolon */
r = semicolon;
}
} while (semicolon != NULL);
if (semicolon != NULL) {
*r++ = '\0';
} else {
r = NULL;
}
cur = mbedtls_calloc(1, sizeof(mbedtls_x509_san_list));
if (cur == NULL) {
mbedtls_printf("Not enough memory for subjectAltName list\n");
goto usage;
}
cur->next = NULL;
if ((subtype_value = strchr(q, ':')) != NULL) {
*subtype_value++ = '\0';
}
if (strcmp(q, "RFC822") == 0) {
cur->node.type = MBEDTLS_X509_SAN_RFC822_NAME;
} else if (strcmp(q, "URI") == 0) {
cur->node.type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
} else if (strcmp(q, "DNS") == 0) {
cur->node.type = MBEDTLS_X509_SAN_DNS_NAME;
} else if (strcmp(q, "IP") == 0) {
cur->node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
ip_string_to_bytes(subtype_value, ip, 4);
cur->node.san.unstructured_name.p = (unsigned char *) ip;
cur->node.san.unstructured_name.len = sizeof(ip);
} else if (strcmp(q, "DN") == 0) {
cur->node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
if ((ret = mbedtls_x509_string_to_names(&ext_san_dirname,
subtype_value)) != 0) {
mbedtls_strerror(ret, buf, sizeof(buf));
mbedtls_printf(
" failed\n ! mbedtls_x509_string_to_names "
"returned -0x%04x - %s\n\n",
(unsigned int) -ret, buf);
goto exit;
}
cur->node.san.directory_name = *ext_san_dirname;
} else {
mbedtls_free(cur);
goto usage;
}
if (cur->node.type == MBEDTLS_X509_SAN_RFC822_NAME ||
cur->node.type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER ||
cur->node.type == MBEDTLS_X509_SAN_DNS_NAME) {
cur->node.san.unstructured_name.p = (unsigned char *) subtype_value;
cur->node.san.unstructured_name.len = strlen(subtype_value);
}
if (prev == NULL) {
opt.san_list = cur;
} else {
prev->next = cur;
}
prev = cur;
q = r;
}
} else if (strcmp(p, "ns_cert_type") == 0) {
@ -833,6 +943,17 @@ usage:
mbedtls_printf(" ok\n");
}
if (opt.san_list != NULL) {
ret = mbedtls_x509write_crt_set_subject_alternative_name(&crt, opt.san_list);
if (ret != 0) {
mbedtls_printf(
" failed\n ! mbedtls_x509write_crt_set_subject_alternative_name returned %d",
ret);
goto exit;
}
}
if (opt.ext_key_usage) {
mbedtls_printf(" . Adding the Extended Key Usage extension ...");
fflush(stdout);
@ -888,6 +1009,7 @@ exit:
#if defined(MBEDTLS_X509_CSR_PARSE_C)
mbedtls_x509_csr_free(&csr);
#endif /* MBEDTLS_X509_CSR_PARSE_C */
mbedtls_asn1_free_named_data_list(&ext_san_dirname);
mbedtls_x509_crt_free(&issuer_crt);
mbedtls_x509write_crt_free(&crt);
mbedtls_pk_free(&loaded_subject_key);

View file

@ -1,8 +1,6 @@
#!/usr/bin/env python3
"""
Purpose
This script is for comparing the size of the library files from two
different Git revisions within an Mbed TLS repository.
The results of the comparison is formatted as csv and stored at a
@ -29,18 +27,103 @@ import argparse
import os
import subprocess
import sys
from enum import Enum
from mbedtls_dev import build_tree
class SupportedArch(Enum):
"""Supported architecture for code size measurement."""
AARCH64 = 'aarch64'
AARCH32 = 'aarch32'
ARMV8_M = 'armv8-m'
X86_64 = 'x86_64'
X86 = 'x86'
CONFIG_TFM_MEDIUM_MBEDCRYPTO_H = "../configs/tfm_mbedcrypto_config_profile_medium.h"
CONFIG_TFM_MEDIUM_PSA_CRYPTO_H = "../configs/crypto_config_profile_medium.h"
class SupportedConfig(Enum):
"""Supported configuration for code size measurement."""
DEFAULT = 'default'
TFM_MEDIUM = 'tfm-medium'
DETECT_ARCH_CMD = "cc -dM -E - < /dev/null"
def detect_arch() -> str:
"""Auto-detect host architecture."""
cc_output = subprocess.check_output(DETECT_ARCH_CMD, shell=True).decode()
if "__aarch64__" in cc_output:
return SupportedArch.AARCH64.value
if "__arm__" in cc_output:
return SupportedArch.AARCH32.value
if "__x86_64__" in cc_output:
return SupportedArch.X86_64.value
if "__x86__" in cc_output:
return SupportedArch.X86.value
else:
print("Unknown host architecture, cannot auto-detect arch.")
sys.exit(1)
class CodeSizeInfo: # pylint: disable=too-few-public-methods
"""Gather information used to measure code size.
It collects information about architecture, configuration in order to
infer build command for code size measurement.
"""
SupportedArchConfig = [
"-a " + SupportedArch.AARCH64.value + " -c " + SupportedConfig.DEFAULT.value,
"-a " + SupportedArch.AARCH32.value + " -c " + SupportedConfig.DEFAULT.value,
"-a " + SupportedArch.X86_64.value + " -c " + SupportedConfig.DEFAULT.value,
"-a " + SupportedArch.X86.value + " -c " + SupportedConfig.DEFAULT.value,
"-a " + SupportedArch.ARMV8_M.value + " -c " + SupportedConfig.TFM_MEDIUM.value,
]
def __init__(self, arch: str, config: str, sys_arch: str) -> None:
"""
arch: architecture to measure code size on.
config: configuration type to measure code size with.
make_command: command to build library (Inferred from arch and config).
"""
self.arch = arch
self.config = config
self.sys_arch = sys_arch
self.make_command = self.set_make_command()
def set_make_command(self) -> str:
"""Infer build command based on architecture and configuration."""
if self.config == SupportedConfig.DEFAULT.value and \
self.arch == self.sys_arch:
return 'make -j lib CFLAGS=\'-Os \' '
elif self.arch == SupportedArch.ARMV8_M.value and \
self.config == SupportedConfig.TFM_MEDIUM.value:
return \
'make -j lib CC=armclang \
CFLAGS=\'--target=arm-arm-none-eabi -mcpu=cortex-m33 -Os \
-DMBEDTLS_CONFIG_FILE=\\\"' + CONFIG_TFM_MEDIUM_MBEDCRYPTO_H + '\\\" \
-DMBEDTLS_PSA_CRYPTO_CONFIG_FILE=\\\"' + CONFIG_TFM_MEDIUM_PSA_CRYPTO_H + '\\\" \''
else:
print("Unsupported combination of architecture: {} and configuration: {}"
.format(self.arch, self.config))
print("\nPlease use supported combination of architecture and configuration:")
for comb in CodeSizeInfo.SupportedArchConfig:
print(comb)
print("\nFor your system, please use:")
for comb in CodeSizeInfo.SupportedArchConfig:
if "default" in comb and self.sys_arch not in comb:
continue
print(comb)
sys.exit(1)
class CodeSizeComparison:
"""Compare code size between two Git revisions."""
def __init__(self, old_revision, new_revision, result_dir):
def __init__(self, old_revision, new_revision, result_dir, code_size_info):
"""
old_revision: revision to compare against
old_revision: revision to compare against.
new_revision:
result_dir: directory for comparison result
result_dir: directory for comparison result.
code_size_info: an object containing information to build library.
"""
self.repo_path = "."
self.result_dir = os.path.abspath(result_dir)
@ -52,7 +135,9 @@ class CodeSizeComparison:
self.old_rev = old_revision
self.new_rev = new_revision
self.git_command = "git"
self.make_command = "make"
self.make_command = code_size_info.make_command
self.fname_suffix = "-" + code_size_info.arch + "-" +\
code_size_info.config
@staticmethod
def validate_revision(revision):
@ -75,21 +160,25 @@ class CodeSizeComparison:
git_worktree_path, revision], cwd=self.repo_path,
stderr=subprocess.STDOUT
)
return git_worktree_path
def _build_libraries(self, git_worktree_path):
"""Build libraries in the specified worktree."""
my_environment = os.environ.copy()
subprocess.check_output(
[self.make_command, "-j", "lib"], env=my_environment,
cwd=git_worktree_path, stderr=subprocess.STDOUT,
)
try:
subprocess.check_output(
self.make_command, env=my_environment, shell=True,
cwd=git_worktree_path, stderr=subprocess.STDOUT,
)
except subprocess.CalledProcessError as e:
self._handle_called_process_error(e, git_worktree_path)
def _gen_code_size_csv(self, revision, git_worktree_path):
"""Generate code size csv file."""
csv_fname = revision + ".csv"
csv_fname = revision + self.fname_suffix + ".csv"
if revision == "current":
print("Measuring code size in current work directory.")
else:
@ -117,7 +206,7 @@ class CodeSizeComparison:
"""Generate code size csv file for the specified git revision."""
# Check if the corresponding record exists
csv_fname = revision + ".csv"
csv_fname = revision + self.fname_suffix + ".csv"
if (revision != "current") and \
os.path.exists(os.path.join(self.csv_dir, csv_fname)):
print("Code size csv file for", revision, "already exists.")
@ -132,16 +221,20 @@ class CodeSizeComparison:
old and new. Measured code size results of these two revisions
must be available."""
old_file = open(os.path.join(self.csv_dir, self.old_rev + ".csv"), "r")
new_file = open(os.path.join(self.csv_dir, self.new_rev + ".csv"), "r")
res_file = open(os.path.join(self.result_dir, "compare-" + self.old_rev
+ "-" + self.new_rev + ".csv"), "w")
old_file = open(os.path.join(self.csv_dir, self.old_rev +
self.fname_suffix + ".csv"), "r")
new_file = open(os.path.join(self.csv_dir, self.new_rev +
self.fname_suffix + ".csv"), "r")
res_file = open(os.path.join(self.result_dir, "compare-" +
self.old_rev + "-" + self.new_rev +
self.fname_suffix +
".csv"), "w")
res_file.write("file_name, this_size, old_size, change, change %\n")
print("Generating comparison results.")
old_ds = {}
for line in old_file.readlines()[1:]:
for line in old_file.readlines():
cols = line.split(", ")
fname = cols[0]
size = int(cols[1])
@ -149,7 +242,7 @@ class CodeSizeComparison:
old_ds[fname] = size
new_ds = {}
for line in new_file.readlines()[1:]:
for line in new_file.readlines():
cols = line.split(", ")
fname = cols[0]
size = int(cols[1])
@ -175,30 +268,50 @@ class CodeSizeComparison:
self._get_code_size_for_rev(self.new_rev)
return self.compare_code_size()
def _handle_called_process_error(self, e: subprocess.CalledProcessError,
git_worktree_path):
"""Handle a CalledProcessError and quit the program gracefully.
Remove any extra worktrees so that the script may be called again."""
# Tell the user what went wrong
print("The following command: {} failed and exited with code {}"
.format(e.cmd, e.returncode))
print("Process output:\n {}".format(str(e.output, "utf-8")))
# Quit gracefully by removing the existing worktree
self._remove_worktree(git_worktree_path)
sys.exit(-1)
def main():
parser = argparse.ArgumentParser(
description=(
"""This script is for comparing the size of the library files
from two different Git revisions within an Mbed TLS repository.
The results of the comparison is formatted as csv, and stored at
a configurable location.
Note: must be run from Mbed TLS root."""
)
)
parser.add_argument(
parser = argparse.ArgumentParser(description=(__doc__))
group_required = parser.add_argument_group(
'required arguments',
'required arguments to parse for running ' + os.path.basename(__file__))
group_required.add_argument(
"-o", "--old-rev", type=str, required=True,
help="old revision for comparison.")
group_optional = parser.add_argument_group(
'optional arguments',
'optional arguments to parse for running ' + os.path.basename(__file__))
group_optional.add_argument(
"-r", "--result-dir", type=str, default="comparison",
help="directory where comparison result is stored, \
default is comparison",
)
parser.add_argument(
"-o", "--old-rev", type=str, help="old revision for comparison.",
required=True,
)
parser.add_argument(
default is comparison")
group_optional.add_argument(
"-n", "--new-rev", type=str, default=None,
help="new revision for comparison, default is the current work \
directory, including uncommitted changes."
)
directory, including uncommitted changes.")
group_optional.add_argument(
"-a", "--arch", type=str, default=detect_arch(),
choices=list(map(lambda s: s.value, SupportedArch)),
help="specify architecture for code size comparison, default is the\
host architecture.")
group_optional.add_argument(
"-c", "--config", type=str, default=SupportedConfig.DEFAULT.value,
choices=list(map(lambda s: s.value, SupportedConfig)),
help="specify configuration type for code size comparison,\
default is the current MbedTLS configuration.")
comp_args = parser.parse_args()
if os.path.isfile(comp_args.result_dir):
@ -214,8 +327,13 @@ def main():
else:
new_revision = "current"
code_size_info = CodeSizeInfo(comp_args.arch, comp_args.config,
detect_arch())
print("Measure code size for architecture: {}, configuration: {}"
.format(code_size_info.arch, code_size_info.config))
result_dir = comp_args.result_dir
size_compare = CodeSizeComparison(old_revision, new_revision, result_dir)
size_compare = CodeSizeComparison(old_revision, new_revision, result_dir,
code_size_info)
return_code = size_compare.get_comparision_results()
sys.exit(return_code)

View file

@ -189,6 +189,7 @@ def realfull_adapter(_name, active, section):
# * Options that remove features.
EXCLUDE_FROM_FULL = frozenset([
#pylint: disable=line-too-long
'MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH', # interacts with CTR_DRBG_128_BIT_KEY
'MBEDTLS_CTR_DRBG_USE_128_BIT_KEY', # interacts with ENTROPY_FORCE_SHA256
'MBEDTLS_DEPRECATED_REMOVED', # conflicts with deprecated options
'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options

View file

@ -49,7 +49,7 @@ my @low_level_modules = qw( AES ARIA ASN1 BASE64 BIGNUM
CAMELLIA CCM CHACHA20 CHACHAPOLY CMAC CTR_DRBG DES
ENTROPY ERROR GCM HKDF HMAC_DRBG LMS MD5
NET OID PADLOCK PBKDF2 PLATFORM POLY1305 RIPEMD160
SHA1 SHA256 SHA512 THREADING );
SHA1 SHA256 SHA512 SHA3 THREADING );
my @high_level_modules = qw( CIPHER DHM ECP MD
PEM PK PKCS12 PKCS5
RSA SSL X509 PKCS7 );

View file

@ -97,7 +97,7 @@ class EcpP192R1Raw(bignum_common.ModOperationCommon,
def is_valid(self) -> bool:
return True
def arguments(self):
def arguments(self)-> List[str]:
args = super().arguments()
return ["MBEDTLS_ECP_DP_SECP192R1"] + args
@ -174,7 +174,7 @@ class EcpP224R1Raw(bignum_common.ModOperationCommon,
def is_valid(self) -> bool:
return True
def arguments(self):
def arguments(self)-> List[str]:
args = super().arguments()
return ["MBEDTLS_ECP_DP_SECP224R1"] + args
@ -258,7 +258,7 @@ class EcpP256R1Raw(bignum_common.ModOperationCommon,
def is_valid(self) -> bool:
return True
def arguments(self):
def arguments(self)-> List[str]:
args = super().arguments()
return ["MBEDTLS_ECP_DP_SECP256R1"] + args
@ -380,7 +380,7 @@ class EcpP384R1Raw(bignum_common.ModOperationCommon,
def is_valid(self) -> bool:
return True
def arguments(self):
def arguments(self)-> List[str]:
args = super().arguments()
return ["MBEDTLS_ECP_DP_SECP384R1"] + args
@ -485,7 +485,7 @@ class EcpP521R1Raw(bignum_common.ModOperationCommon,
def is_valid(self) -> bool:
return True
def arguments(self):
def arguments(self)-> List[str]:
args = super().arguments()
return ["MBEDTLS_ECP_DP_SECP521R1"] + args
@ -494,8 +494,8 @@ class EcpP192K1Raw(bignum_common.ModOperationCommon,
EcpTarget):
"""Test cases for ECP P192K1 fast reduction."""
symbol = "-"
test_function = "ecp_mod_p192k1"
test_name = "ecp_mod_p192k1"
test_function = "ecp_mod_p_generic_raw"
test_name = "ecp_mod_p192k1_raw"
input_style = "fixed"
arity = 1
dependencies = ["MBEDTLS_ECP_DP_SECP192K1_ENABLED"]
@ -557,13 +557,17 @@ class EcpP192K1Raw(bignum_common.ModOperationCommon,
def is_valid(self) -> bool:
return True
def arguments(self):
args = super().arguments()
return ["MBEDTLS_ECP_DP_SECP192K1"] + args
class EcpP224K1Raw(bignum_common.ModOperationCommon,
EcpTarget):
"""Test cases for ECP P224 fast reduction."""
symbol = "-"
test_function = "ecp_mod_p224k1"
test_name = "ecp_mod_p224k1"
test_function = "ecp_mod_p_generic_raw"
test_name = "ecp_mod_p224k1_raw"
input_style = "fixed"
arity = 1
dependencies = ["MBEDTLS_ECP_DP_SECP224K1_ENABLED"]
@ -582,7 +586,7 @@ class EcpP224K1Raw(bignum_common.ModOperationCommon,
# 2^224 - 1
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
# Maximum canonical P224 multiplication result
# Maximum canonical P224K1 multiplication result
("fffffffffffffffffffffffffffffffffffffffffffffffdffffcad8"
"00000000000000000000000000000000000000010000352802c26590"),
@ -626,13 +630,17 @@ class EcpP224K1Raw(bignum_common.ModOperationCommon,
def is_valid(self) -> bool:
return True
def arguments(self):
args = super().arguments()
return ["MBEDTLS_ECP_DP_SECP224K1"] + args
class EcpP256K1Raw(bignum_common.ModOperationCommon,
EcpTarget):
"""Test cases for ECP P256 fast reduction."""
symbol = "-"
test_function = "ecp_mod_p256k1"
test_name = "ecp_mod_p256k1"
test_function = "ecp_mod_p_generic_raw"
test_name = "ecp_mod_p256k1_raw"
input_style = "fixed"
arity = 1
dependencies = ["MBEDTLS_ECP_DP_SECP256K1_ENABLED"]
@ -651,9 +659,13 @@ class EcpP256K1Raw(bignum_common.ModOperationCommon,
# 2^256 - 1
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
# Maximum canonical P256 multiplication result
("fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff85c0"
"00000000000000000000000000000000000000000000001000007a4000e9844"),
# Maximum canonical P256K1 multiplication result
("fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff85c"
"000000000000000000000000000000000000000000000001000007a4000e9844"),
# Test case for overflow during addition
("0000fffffc2f000e90a0c86a0a63234e5ba641f43a7e4aecc4040e67ec850562"
"00000000000000000000000000000000000000000000000000000000585674fd"),
# Test case for overflow during addition
("0000fffffc2f000e90a0c86a0a63234e5ba641f43a7e4aecc4040e67ec850562"
@ -694,6 +706,79 @@ class EcpP256K1Raw(bignum_common.ModOperationCommon,
def is_valid(self) -> bool:
return True
def arguments(self):
args = super().arguments()
return ["MBEDTLS_ECP_DP_SECP256K1"] + args
class EcpP255Raw(bignum_common.ModOperationCommon,
EcpTarget):
"""Test cases for ECP 25519 fast reduction."""
symbol = "-"
test_function = "ecp_mod_p_generic_raw"
test_name = "mbedtls_ecp_mod_p255_raw"
input_style = "fixed"
arity = 1
dependencies = ["MBEDTLS_ECP_DP_CURVE25519_ENABLED"]
moduli = [("7fffffffffffffffffffffffffffffffffffffffffffffffff"
"ffffffffffffed")] # type: List[str]
input_values = [
"0", "1",
# Modulus - 1
("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),
# Modulus + 1
("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee"),
# 2^255 - 1
("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
# Maximum canonical P255 multiplication result
("3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"
"0000000000000000000000000000000000000000000000000000000000000190"),
# First 8 number generated by random.getrandbits(510) - seed(2,2)
("1019f0d64ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124"
"5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"),
("20948fa1feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f6e405d93"
"ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd9b1f282e"),
("3a1893ea5186ee32ee8d7ee9770348a05d300cb90706a045defc044a09325626"
"e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57ebf30b94fa"),
("20a6923522fe99a22c70501e533c91352d3d854e061b90303b08c6e33c729578"
"2d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"),
("3a248138e8168561867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2"
"fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f15c14bc4a829e07b0"),
("2f450feab714210c665d7435c1066932f4767f26294365b2721dea3bf63f23d0"
"dbe53fcafb2147df5ca495fa5a91c89b97eeab64ca2ce6bc5d3fd983c34c769f"),
("1d199effe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e80371eb9"
"7f81375eecc1cb6347733e847d718d733ff98ff387c56473a7a83ee0761ebfd2"),
("3423c6ec531d6460f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f25"
"8ebdbfe3eb9ac688b9d39cca91551e8259cc60b17604e4b4e73695c3e652c71a"),
# Next 2 number generated by random.getrandbits(255)
("62f1243644a4a8f69dc8db48e86ec9c6e06f291b2a838af8d5c44a4eb3172062"),
("6a606e54b4c9e755cc9c3adcf515a8234da4daeb4f3f87777ad1f45ae9500ec9"),
]
@property
def arg_a(self) -> str:
return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits)
def result(self) -> List[str]:
result = self.int_a % self.int_n
return [self.format_result(result)]
@property
def is_valid(self) -> bool:
return True
def arguments(self)-> List[str]:
args = super().arguments()
return ["MBEDTLS_ECP_DP_CURVE25519"] + args
class EcpP448Raw(bignum_common.ModOperationCommon,
EcpTarget):

View file

@ -41,8 +41,8 @@ test_ca_key_file_rsa = test-ca.key
test_ca_pwd_rsa = PolarSSLTest
test_ca_config_file = test-ca.opensslconf
$(test_ca_key_file_rsa):$(test_ca_pwd_rsa)
$(OPENSSL) genrsa -aes-128-cbc -passout pass:$< -out $@ 2048
$(test_ca_key_file_rsa):
$(OPENSSL) genrsa -aes-128-cbc -passout pass:$(test_ca_pwd_rsa) -out $@ 2048
all_final += $(test_ca_key_file_rsa)
test-ca.req.sha256: $(test_ca_key_file_rsa)
@ -171,7 +171,30 @@ all_intermediate += test-ca2.req.sha256
test-ca2.crt: $(test_ca_key_file_ec) test-ca2.req.sha256
$(MBEDTLS_CERT_WRITE) is_ca=1 serial=13926223505202072808 request_file=test-ca2.req.sha256 selfsign=1 issuer_name="C=NL,O=PolarSSL,CN=Polarssl Test EC CA" issuer_key=$(test_ca_key_file_ec) not_before=20190210144400 not_after=20290210144400 md=SHA256 version=3 output_file=$@
all_final += test-ca.crt
all_final += test-ca2.crt
test-ca2-future.crt: $(test_ca_key_file_ec) test-ca2.req.sha256
$(MBEDTLS_CERT_WRITE) is_ca=1 serial=13926223505202072808 request_file=test-ca2.req.sha256 selfsign=1 \
issuer_name="C=NL,O=PolarSSL,CN=Polarssl Test EC CA" issuer_key=$(test_ca_key_file_ec) \
not_before=20290210144400 not_after=20390210144400 md=SHA256 version=3 output_file=$@
all_intermediate += test-ca2-future.crt
test_ca_ec_cat := # files that concatenate different crt
test-ca2_cat-future-invalid.crt: test-ca2-future.crt server6.crt
test_ca_ec_cat += test-ca2_cat-future-invalid.crt
test-ca2_cat-future-present.crt: test-ca2-future.crt test-ca2.crt
test_ca_ec_cat += test-ca2_cat-future-present.crt
test-ca2_cat-present-future.crt: test-ca2.crt test-ca2-future.crt
test_ca_ec_cat += test-ca2_cat-present-future.crt
test-ca2_cat-present-past.crt: test-ca2.crt test-ca2-expired.crt
test_ca_ec_cat += test-ca2_cat-present-past.crt
test-ca2_cat-past-invalid.crt: test-ca2-expired.crt server6.crt
test_ca_ec_cat += test-ca2_cat-past-invalid.crt
test-ca2_cat-past-present.crt: test-ca2-expired.crt test-ca2.crt
test_ca_ec_cat += test-ca2_cat-past-present.crt
$(test_ca_ec_cat):
cat $^ > $@
all_final += $(test_ca_ec_cat)
test-ca-any_policy.crt: $(test_ca_key_file_rsa) test-ca.req.sha256
$(OPENSSL) req -x509 -config $(test_ca_config_file) -extensions v3_any_policy_ca -key $(test_ca_key_file_rsa) -passin "pass:$(test_ca_pwd_rsa)" -set_serial 0 -days 3653 -sha256 -in test-ca.req.sha256 -out $@
@ -229,10 +252,37 @@ all_final += $(test_ca_crt_cat21)
test-int-ca.csr: test-int-ca.key $(test_ca_config_file)
$(OPENSSL) req -new -config $(test_ca_config_file) -key test-int-ca.key -subj "/C=NL/O=PolarSSL/CN=PolarSSL Test Intermediate CA" -out $@
all_intermediate += test-int-ca.csr
test-int-ca2.csr: test-int-ca2.key $(test_ca_config_file)
$(OPENSSL) req -new -config $(test_ca_config_file) -key test-int-ca2.key \
-subj "/C=NL/O=PolarSSL/CN=PolarSSL Test Intermediate EC CA" -out $@
test-int-ca3.csr: test-int-ca3.key $(test_ca_config_file)
$(OPENSSL) req -new -config $(test_ca_config_file) -key test-int-ca3.key \
-subj "/C=UK/O=mbed TLS/CN=mbed TLS Test intermediate CA 3" -out $@
all_intermediate += test-int-ca.csr test-int-ca2.csr test-int-ca3.csr
test-int-ca.crt: $(test_ca_crt_file_ec) $(test_ca_key_file_ec) $(test_ca_config_file) test-int-ca.csr
$(OPENSSL) x509 -req -extfile $(test_ca_config_file) -extensions v3_ca \
-CA $(test_ca_crt_file_ec) -CAkey $(test_ca_key_file_ec) \
-set_serial 14 -days 3653 -sha256 -in test-int-ca.csr -out $@
test-int-ca2.crt: $(test_ca_key_file_rsa) $(test_ca_crt) $(test_ca_config_file) test-int-ca2.csr
$(OPENSSL) x509 -req -extfile $(test_ca_config_file) -extensions v3_ca -CA $(test_ca_crt) \
-CAkey $(test_ca_key_file_rsa) -set_serial 15 -days 3653 -sha256 -in test-int-ca2.csr \
-passin "pass:$(test_ca_pwd_rsa)" -out $@
# Note: This requests openssl version >= 3.x.xx
test-int-ca3.crt: test-int-ca2.crt test-int-ca2.key $(test_ca_config_file) test-int-ca3.csr
$(OPENSSL) x509 -req -extfile $(test_ca_config_file) -extensions no_subj_auth_id \
-CA test-int-ca2.crt -CAkey test-int-ca2.key -set_serial 77 -days 3653 \
-sha256 -in test-int-ca3.csr -out $@
test-int-ca-exp.crt: $(test_ca_crt_file_ec) $(test_ca_key_file_ec) $(test_ca_config_file) test-int-ca.csr
$(FAKETIME) -f -3653d $(OPENSSL) x509 -req -extfile $(test_ca_config_file) -extensions v3_ca -CA $(test_ca_crt_file_ec) -CAkey $(test_ca_key_file_ec) -set_serial 14 -days 3653 -sha256 -in test-int-ca.csr -out $@
all_final += test-int-ca-exp.crt
all_final += test-int-ca-exp.crt test-int-ca.crt test-int-ca2.crt test-int-ca3.crt
enco-cert-utf8str.pem: rsa_pkcs1_1024_clear.pem
$(MBEDTLS_CERT_WRITE) subject_key=rsa_pkcs1_1024_clear.pem subject_name="CN=dw.yonan.net" issuer_crt=enco-ca-prstr.pem issuer_key=rsa_pkcs1_1024_clear.pem not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
@ -271,23 +321,74 @@ cli-rsa.key.der: $(cli_crt_key_file_rsa)
all_final += cli-rsa.key.der
test_ca_int_rsa1 = test-int-ca.crt
test_ca_int_ec = test-int-ca2.crt
test_ca_int_key_file_ec = test-int-ca2.key
# server7*
server7.csr: server7.key
$(OPENSSL) req -new -key server7.key -subj "/C=NL/O=PolarSSL/CN=localhost" -out $@
all_intermediate += server7.csr
server7.crt: server7.csr $(test_ca_int_rsa1)
$(OPENSSL) x509 -req -extfile $(cli_crt_extensions_file) -extensions cli-rsa \
-CA $(test_ca_int_rsa1) -CAkey test-int-ca.key \
-set_serial 16 -days 3653 -sha256 -in server7.csr > $@
all_final += server7.crt
server7-expired.crt: server7.csr $(test_ca_int_rsa1)
$(FAKETIME) -f -3653d $(OPENSSL) x509 -req -extfile $(cli_crt_extensions_file) -extensions cli-rsa -CA $(test_ca_int_rsa1) -CAkey test-int-ca.key -set_serial 16 -days 3653 -sha256 -in server7.csr | cat - $(test_ca_int_rsa1) > $@
all_final += server7-expired.crt
server7-future.crt: server7.csr $(test_ca_int_rsa1)
$(FAKETIME) -f +3653d $(OPENSSL) x509 -req -extfile $(cli_crt_extensions_file) -extensions cli-rsa -CA $(test_ca_int_rsa1) -CAkey test-int-ca.key -set_serial 16 -days 3653 -sha256 -in server7.csr | cat - $(test_ca_int_rsa1) > $@
all_final += server7-future.crt
server7-badsign.crt: server7.crt $(test_ca_int_rsa1)
{ head -n-2 $<; tail -n-2 $< | sed -e '1s/0\(=*\)$$/_\1/' -e '1s/[^_=]\(=*\)$$/0\1/' -e '1s/_/1/'; cat $(test_ca_int_rsa1); } > $@
all_final += server7-badsign.crt
server7_int-ca.crt: server7.crt $(test_ca_int_rsa1)
cat server7.crt $(test_ca_int_rsa1) > $@
all_final += server7_int-ca.crt
server7_pem_space.crt: server7.crt $(test_ca_int_rsa1)
cat server7.crt $(test_ca_int_rsa1) | sed '4s/\(.\)$$/ \1/' > $@
all_final += server7_pem_space.crt
server7_all_space.crt: server7.crt $(test_ca_int_rsa1)
{ cat server7.crt | sed '4s/\(.\)$$/ \1/'; cat test-int-ca.crt | sed '4s/\(.\)$$/ \1/'; } > $@
all_final += server7_all_space.crt
server7_trailing_space.crt: server7.crt $(test_ca_int_rsa1)
cat server7.crt $(test_ca_int_rsa1) | sed 's/\(.\)$$/\1 /' > $@
all_final += server7_trailing_space.crt
server7_int-ca_ca2.crt: server7.crt $(test_ca_int_rsa1) $(test_ca_crt_file_ec)
cat server7.crt $(test_ca_int_rsa1) $(test_ca_crt_file_ec) > $@
all_final += server7_int-ca_ca2.crt
server7_int-ca-exp.crt: server7.crt test-int-ca-exp.crt
cat server7.crt test-int-ca-exp.crt > $@
all_final += server7_int-ca-exp.crt
server7_spurious_int-ca.crt: server7.crt $(test_ca_int_ec) $(test_ca_int_rsa1)
cat server7.crt $(test_ca_int_ec) $(test_ca_int_rsa1) > $@
all_final += server7_spurious_int-ca.crt
# server8*
server8.crt: server8.key
$(MBEDTLS_CERT_WRITE) subject_key=$< subject_name="C=NL, O=PolarSSL, CN=localhost" serial=17 \
issuer_crt=$(test_ca_int_ec) issuer_key=$(test_ca_int_key_file_ec) \
not_before=20190210144406 not_after=20290210144406 \
md=SHA256 version=3 output_file=$@
all_final += server8.crt
server8_int-ca2.crt: server8.crt $(test_ca_int_ec)
cat $^ > $@
all_final += server8_int-ca2.crt
cli2.req.sha256: cli2.key
$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=PolarSSL,CN=PolarSSL Test Client 2" md=SHA256
@ -339,8 +440,12 @@ server5-unsupported_othername.crt: server5.key
server5-fan.crt: server5.key
$(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS FAN" -set_serial 77 -config $(test_ca_config_file) -extensions fan_cert -days 3650 -sha256 -key server5.key -out $@
server5-tricky-ip-san.crt: server5.key
$(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS Tricky IP SAN" -set_serial 77 -config $(test_ca_config_file) -extensions tricky_ip_san -days 3650 -sha256 -key server5.key -out $@
server5-tricky-ip-san.crt.der: server5.key
$(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS Tricky IP SAN" -set_serial 77 -config $(test_ca_config_file) -extensions tricky_ip_san -days 3650 -sha256 -key server5.key -outform der -out $@
# malformed IP length
server5-tricky-ip-san-malformed-len.crt.der: server5-tricky-ip-san.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/87046162636487106162/87056162636487106162/" | xxd -r -p > $@
server5-directoryname.crt.der: server5.key
$(OPENSSL) req -x509 -outform der -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS directoryName SAN" -set_serial 77 -config $(test_ca_config_file) -extensions directory_name_san -days 3650 -sha256 -key server5.key -out $@
@ -348,6 +453,30 @@ server5-directoryname.crt.der: server5.key
server5-two-directorynames.crt.der: server5.key
$(OPENSSL) req -x509 -outform der -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS directoryName SAN" -set_serial 77 -config $(test_ca_config_file) -extensions two_directorynames -days 3650 -sha256 -key server5.key -out $@
server5-der0.crt: server5.crt.der
cp $< $@
server5-der1a.crt: server5.crt.der
cp $< $@
echo '00' | xxd -r -p | dd of=$@ bs=1 seek=$$(wc -c <$<) conv=notrunc
server5-der1b.crt: server5.crt.der
cp $< $@
echo 'c1' | xxd -r -p | dd of=$@ bs=1 seek=$$(wc -c <$<) conv=notrunc
server5-der2.crt: server5.crt.der
cp $< $@
echo 'b90a' | xxd -r -p | dd of=$@ bs=1 seek=$$(wc -c <$<) conv=notrunc
server5-der4.crt: server5.crt.der
cp $< $@
echo 'a710945f' | xxd -r -p | dd of=$@ bs=1 seek=$$(wc -c <$<) conv=notrunc
server5-der8.crt: server5.crt.der
cp $< $@
echo 'a4a7ff27267aaa0f' | xxd -r -p | dd of=$@ bs=1 seek=$$(wc -c <$<) conv=notrunc
server5-der9.crt: server5.crt.der
cp $< $@
echo 'cff8303376ffa47a29' | xxd -r -p | dd of=$@ bs=1 seek=$$(wc -c <$<) conv=notrunc
all_final += server5-der0.crt server5-der1b.crt server5-der4.crt \
server5-der9.crt server5-der1a.crt server5-der2.crt \
server5-der8.crt
# directoryname sequence tag malformed
server5-directoryname-seq-malformed.crt.der: server5-two-directorynames.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/62A4473045310B/62A4473145310B/" | xxd -r -p > $@
@ -364,18 +493,37 @@ rsa_single_san_uri.crt.der: rsa_single_san_uri.key
rsa_multiple_san_uri.crt.der: rsa_multiple_san_uri.key
$(OPENSSL) req -x509 -outform der -nodes -days 7300 -newkey rsa:2048 -key $< -out $@ -addext "subjectAltName = URI:urn:example.com:5ff40f78-9210-494f-8206-c2c082f0609c, URI:urn:example.com:5ff40f78-9210-494f-8206-abcde1234567" -extensions 'v3_req' -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS URI SAN"
test-int-ca3-badsign.crt: test-int-ca3.crt
{ head -n-2 $<; tail -n-2 $< | sed -e '1s/0\(=*\)$$/_\1/' -e '1s/[^_=]\(=*\)$$/0\1/' -e '1s/_/1/'; } > $@
all_final += test-int-ca3-badsign.crt
# server10*
server10.crt: server10.key test-int-ca3.crt test-int-ca3.key
$(MBEDTLS_CERT_WRITE) subject_key=$< subject_name="CN=localhost" serial=75 \
issuer_crt=test-int-ca3.crt issuer_key=test-int-ca3.key \
subject_identifier=0 authority_identifier=0 \
not_before=20190210144406 not_after=20290210144406 \
md=SHA256 version=3 output_file=$@
all_final += server10.crt
server10-badsign.crt: server10.crt
{ head -n-2 $<; tail -n-2 $< | sed -e '1s/0\(=*\)$$/_\1/' -e '1s/[^_=]\(=*\)$$/0\1/' -e '1s/_/1/'; } > $@
all_final += server10-badsign.crt
server10-bs_int3.pem: server10-badsign.crt test-int-ca3.crt
cat server10-badsign.crt test-int-ca3.crt > $@
all_final += server10-bs_int3.pem
test-int-ca3-badsign.crt: test-int-ca3.crt
{ head -n-2 $<; tail -n-2 $< | sed -e '1s/0\(=*\)$$/_\1/' -e '1s/[^_=]\(=*\)$$/0\1/' -e '1s/_/1/'; } > $@
all_final += test-int-ca3-badsign.crt
server10_int3-bs.pem: server10.crt test-int-ca3-badsign.crt
cat server10.crt test-int-ca3-badsign.crt > $@
all_final += server10_int3-bs.pem
server10_int3_int-ca2.crt: server10.crt test-int-ca3.crt $(test_ca_int_ec)
cat $^ > $@
all_final += server10_int3_int-ca2.crt
server10_int3_int-ca2_ca.crt: server10.crt test-int-ca3.crt $(test_ca_int_ec) $(test_ca_crt)
cat $^ > $@
all_final += server10_int3_int-ca2_ca.crt
server10_int3_spurious_int-ca2.crt: server10.crt test-int-ca3.crt $(test_ca_int_rsa1) $(test_ca_int_ec)
cat $^ > $@
all_final += server10_int3_spurious_int-ca2.crt
rsa_pkcs1_2048_public.pem: server8.key
$(OPENSSL) rsa -in $< -outform PEM -RSAPublicKey_out -out $@
@ -393,6 +541,61 @@ rsa_pkcs8_2048_public.der: rsa_pkcs8_2048_public.pem
$(OPENSSL) rsa -pubin -in $< -outform DER -pubout -out $@
all_final += rsa_pkcs8_2048_public.der
# Generate crl_cat_*.pem
# - crt_cat_*.pem: (1+2) concatenations in various orders:
# ec = crl-ec-sha256.pem, ecfut = crl-future.pem
# rsa = crl.pem, rsabadpem = same with pem error, rsaexp = crl_expired.pem
crl_cat_ec-rsa.pem:crl-ec-sha256.pem crl.pem
cat $^ > $@
crl_cat_rsa-ec.pem:crl.pem crl-ec-sha256.pem
cat $^ > $@
all_final += crl_cat_ec-rsa.pem crl_cat_rsa-ec.pem
authorityKeyId_subjectKeyId.crt.der:
$(OPENSSL) req -x509 -nodes -days 7300 -key server2.key -outform DER -out $@ -config authorityKeyId_subjectKeyId.conf -extensions 'v3_req' -set_serial 593828494303792449134898749208168108403991951034
authorityKeyId_no_keyid.crt.der:
$(OPENSSL) req -x509 -nodes -days 7300 -key server2.key -outform DER -out $@ -config authorityKeyId_subjectKeyId.conf -extensions 'v3_req_authorityKeyId_no_keyid' -set_serial 593828494303792449134898749208168108403991951034
authorityKeyId_no_issuer.crt.der:
$(OPENSSL) req -x509 -nodes -days 7300 -key server2.key -outform DER -out $@ -config authorityKeyId_subjectKeyId.conf -extensions 'v3_req_authorityKeyId_no_issuer'
authorityKeyId_no_authorityKeyId.crt.der:
$(OPENSSL) req -x509 -nodes -days 7300 -key server2.key -outform DER -out $@ -config authorityKeyId_subjectKeyId.conf -extensions 'v3_req_no_authorityKeyId'
authorityKeyId_subjectKeyId_tag_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/0414A505E864B8DCDF600F50124D60A864AF4D8B4393/0114A505E864B8DCDF600F50124D60A864AF4D8B4393/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_tag_len_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/0414A505E864B8DCDF600F50124D60A864AF4D8B4393/0413A505E864B8DCDF600F50124D60A864AF4D8B4393/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_length_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/306D8014A505E864B8DC/306C8014A505E864B8DC/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_sequence_tag_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/6F306D8014A505E864B8/6F006D8014A505E864B8/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_keyid_tag_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/306D8014A505E864B8DC/306D0014A505E864B8DC/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_keyid_tag_len_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/306D8014A505E864B8DC/306D80FFA505E864B8DC/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_issuer_tag1_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/A13FA43D303B310B3009/003FA43D303B310B3009/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_issuer_tag2_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/A43D303B310B30090603/003D303B310B30090603/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_sn_tag_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/8214680430CD074DE63F/8114680430CD074DE63F/" | xxd -r -p > $@
authorityKeyId_subjectKeyId_sn_len_malformed.crt.der: authorityKeyId_subjectKeyId.crt.der
hexdump -ve '1/1 "%.2X"' $< | sed "s/8214680430CD074DE63F/8213680430CD074DE63F/" | xxd -r -p > $@
################################################################
#### Generate various RSA keys
################################################################
@ -1011,32 +1214,32 @@ ec_x25519_prv.der:
$(OPENSSL) genpkey -algorithm X25519 -out $@ -outform DER
all_final += ec_x25519_prv.der
ec_x25519_pub.der: ec_x25519_pub.der
$(OPENSSL) pkey -in $< -inform DER -out $@ -outform DER
ec_x25519_pub.der: ec_x25519_prv.der
$(OPENSSL) pkey -in $< -inform DER -out $@ -outform DER -pubout
all_final += ec_x25519_pub.der
ec_x25519_prv.pem: ec_x25519_prv.pem
ec_x25519_prv.pem: ec_x25519_prv.der
$(OPENSSL) pkey -in $< -inform DER -out $@
all_final += ec_x25519_prv.pem
ec_x25519_pub.pem: ec_x25519_pub.pem
$(OPENSSL) pkey -in $< -inform DER -out $@
ec_x25519_pub.pem: ec_x25519_prv.der
$(OPENSSL) pkey -in $< -inform DER -out $@ -pubout
all_final += ec_x25519_pub.pem
ec_x448_prv.der:
$(OPENSSL) genpkey -algorithm X448 -out $@ -outform DER
all_final += ec_x448_prv.der
ec_x448_pub.der: ec_x448_pub.der
$(OPENSSL) pkey -in $< -inform DER -out $@ -outform DER
ec_x448_pub.der: ec_x448_prv.der
$(OPENSSL) pkey -in $< -inform DER -out $@ -outform DER -pubout
all_final += ec_x448_pub.der
ec_x448_prv.pem: ec_x448_prv.pem
ec_x448_prv.pem: ec_x448_prv.der
$(OPENSSL) pkey -in $< -inform DER -out $@
all_final += ec_x448_prv.pem
ec_x448_pub.pem: ec_x448_pub.pem
$(OPENSSL) pkey -in $< -inform DER -out $@
ec_x448_pub.pem: ec_x448_prv.der
$(OPENSSL) pkey -in $< -inform DER -out $@ -pubout
all_final += ec_x448_pub.pem
################################################################
@ -1173,11 +1376,39 @@ all_final += server2.key.enc
# server5*
server5.csr: server5.key
$(OPENSSL) req -new -subj "/C=NL/O=PolarSSL/CN=localhost" \
-key $< -out $@
all_intermediate += server5.csr
server5.crt: server5-sha256.crt
cp $< $@
all_intermediate += server5-sha256.crt
server5-sha%.crt: server5.csr $(test_ca_crt_file_ec) $(test_ca_key_file_ec) server5.crt.openssl.v3_ext
$(OPENSSL) x509 -req -CA $(test_ca_crt_file_ec) -CAkey $(test_ca_key_file_ec) \
-extfile server5.crt.openssl.v3_ext -set_serial 9 -days 3650 \
-sha$(@:server5-sha%.crt=%) -in $< -out $@
all_final += server5.crt server5-sha1.crt server5-sha224.crt server5-sha384.crt server5-sha512.crt
server5-badsign.crt: server5.crt
{ head -n-2 $<; tail -n-2 $< | sed -e '1s/0\(=*\)$$/_\1/' -e '1s/[^_=]\(=*\)$$/0\1/' -e '1s/_/1/'; } > $@
all_final += server5-badsign.crt
# The use of 'Server 1' in the DN is intentional here, as the DN is hardcoded in the x509_write test suite.'
server5.req.ku.sha1: server5.key
$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< key_usage=digital_signature,non_repudiation subject_name="C=NL,O=PolarSSL,CN=PolarSSL Server 1" md=SHA1
all_final += server5.req.ku.sha1
# server6*
server6.csr: server6.key
$(OPENSSL) req -new -subj "/C=NL/O=PolarSSL/CN=localhost" \
-key $< -out $@
all_intermediate += server6.csr
server6.crt: server6.csr $(test_ca_crt_file_ec) $(test_ca_key_file_ec)
$(OPENSSL) x509 -req -CA $(test_ca_crt_file_ec) -CAkey $(test_ca_key_file_ec) \
-extfile server5.crt.openssl.v3_ext -set_serial 10 -days 3650 -sha256 -in $< -out $@
all_final += server6.crt
################################################################
### Generate certificates for CRT write check tests
################################################################
@ -1198,6 +1429,8 @@ test_ca_server1_config_file = test-ca.server1.opensslconf
server1.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
$(MBEDTLS_CERT_WRITE) request_file=server1.req.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
server1.allSubjectAltNames.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
$(MBEDTLS_CERT_WRITE) request_file=server1.req.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@ san=URI:http://pki.example.com\;IP:1.2.3.4\;DN:C=UK,O="Mbed TLS",CN="SubjectAltName test"\;DNS:example.com\;RFC822:mail@example.com
server1.long_serial.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
echo "112233445566778899aabbccddeeff0011223344" > test-ca.server1.tmp.serial
$(OPENSSL) ca -in server1.req.sha256 -key PolarSSLTest -config test-ca.server1.test_serial.opensslconf -notext -batch -out $@
@ -1324,6 +1557,24 @@ server2-sha256.crt: server2.req.sha256
$(MBEDTLS_CERT_WRITE) request_file=server2.req.sha256 serial=2 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20190210144406 not_after=20290210144406 md=SHA256 version=3 output_file=$@
all_final += server2-sha256.crt
# server3*
server3.crt: server3.key
$(MBEDTLS_CERT_WRITE) subject_key=$< subject_name="C=NL,O=PolarSSL,CN=localhost" serial=13 \
issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) \
not_before=20190210144406 not_after=20290210144406 \
md=SHA1 version=3 output_file=$@
all_final += server3.crt
# server4*
server4.crt: server4.key
$(MBEDTLS_CERT_WRITE) subject_key=$< subject_name="C=NL,O=PolarSSL,CN=localhost" serial=8 \
issuer_crt=$(test_ca_crt_file_ec) issuer_key=$(test_ca_key_file_ec) \
not_before=20190210144400 not_after=20290210144400 \
md=SHA256 version=3 output_file=$@
all_final += server4.crt
# MD5 test certificate
cert_md_test_key = $(cli_crt_key_file_rsa)
@ -1394,17 +1645,17 @@ all_final += pkcs7_data_1.bin
# Generate signing cert
pkcs7-rsa-sha256-1.crt:
$(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert 1" -sha256 -nodes -days 365 -newkey rsa:2048 -keyout pkcs7-rsa-sha256-1.key -out pkcs7-rsa-sha256-1.crt
$(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert 1" -sha256 -nodes -days 3653 -newkey rsa:2048 -keyout pkcs7-rsa-sha256-1.key -out pkcs7-rsa-sha256-1.crt
cat pkcs7-rsa-sha256-1.crt pkcs7-rsa-sha256-1.key > pkcs7-rsa-sha256-1.pem
all_final += pkcs7-rsa-sha256-1.crt
pkcs7-rsa-sha256-2.crt:
$(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert 2" -sha256 -nodes -days 365 -newkey rsa:2048 -keyout pkcs7-rsa-sha256-2.key -out pkcs7-rsa-sha256-2.crt
$(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert 2" -sha256 -nodes -days 3653 -newkey rsa:2048 -keyout pkcs7-rsa-sha256-2.key -out pkcs7-rsa-sha256-2.crt
cat pkcs7-rsa-sha256-2.crt pkcs7-rsa-sha256-2.key > pkcs7-rsa-sha256-2.pem
all_final += pkcs7-rsa-sha256-2.crt
pkcs7-rsa-sha256-3.crt:
$(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert 3" -sha256 -nodes -days 365 -newkey rsa:2048 -keyout pkcs7-rsa-sha256-3.key -out pkcs7-rsa-sha256-3.crt
$(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert 3" -sha256 -nodes -days 3653 -newkey rsa:2048 -keyout pkcs7-rsa-sha256-3.key -out pkcs7-rsa-sha256-3.crt
cat pkcs7-rsa-sha256-3.crt pkcs7-rsa-sha256-3.key > pkcs7-rsa-sha256-3.pem
all_final += pkcs7-rsa-sha256-3.crt
@ -1519,17 +1770,17 @@ all_final += pkcs7_data_signed_badsigner1_fuzzbad.der
pkcs7_data_signed_badsigner2_badsize.der: pkcs7_data_3_signed.der
cp pkcs7_data_3_signed.der $@
echo '72'| xxd -p -r | dd of=$@ bs=1 seek=813 conv=notrunc
all_final += pkcs7_data_signed_badsigner2_badsize
all_final += pkcs7_data_signed_badsigner2_badsize.der
pkcs7_data_signed_badsigner2_badtag.der: pkcs7_data_3_signed.der
cp pkcs7_data_3_signed.der $@
echo 'a1'| xxd -p -r | dd of=$@ bs=1 seek=817 conv=notrunc
all_final += pkcs7_data_signed_badsigner2_badtag
all_final += pkcs7_data_signed_badsigner2_badtag.der
pkcs7_data_signed_badsigner2_fuzzbad.der: pkcs7_data_3_signed.der
cp pkcs7_data_3_signed.der $@
echo 'a1'| xxd -p -r | dd of=$@ bs=1 seek=925 conv=notrunc
all_final += pkcs7_data_signed_badsigner2_fuzzbad
all_final += pkcs7_data_signed_badsigner2_fuzzbad.der
# pkcs7 file with version 2
pkcs7_data_cert_signed_v2.der: pkcs7_data_cert_signed_sha256.der
@ -1602,3 +1853,5 @@ clean:
neat: clean
rm -f $(all_final)
.PHONY: clean neat
.SECONDARY: $(all_intermediate)

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