1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-30 22:43:08 +03:00

Merge pull request #1381 from Mbed-TLS/mbedtls-3.6.4-mergeback

Mbedtls 3.6.4 merge-back pr
This commit is contained in:
minosgalanakis
2025-06-30 22:06:11 +01:00
committed by GitHub
35 changed files with 583 additions and 125 deletions

View File

@ -40,12 +40,12 @@ cmake_policy(SET CMP0012 NEW)
if(TEST_CPP) if(TEST_CPP)
project("Mbed TLS" project("Mbed TLS"
LANGUAGES C CXX LANGUAGES C CXX
VERSION 3.6.3 VERSION 3.6.4
) )
else() else()
project("Mbed TLS" project("Mbed TLS"
LANGUAGES C LANGUAGES C
VERSION 3.6.3 VERSION 3.6.4
) )
endif() endif()
@ -476,7 +476,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
write_basic_package_version_file( write_basic_package_version_file(
"cmake/MbedTLSConfigVersion.cmake" "cmake/MbedTLSConfigVersion.cmake"
COMPATIBILITY SameMajorVersion COMPATIBILITY SameMajorVersion
VERSION 3.6.3) VERSION 3.6.4)
install( install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake" FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"

110
ChangeLog
View File

@ -1,5 +1,115 @@
Mbed TLS ChangeLog (Sorted per branch, date) Mbed TLS ChangeLog (Sorted per branch, date)
= Mbed TLS 3.6.4 branch released 2025-06-30
Features
* Add the function mbedtls_ssl_export_keying_material() which allows the
client and server to extract additional shared symmetric keys from an SSL
session, according to the TLS-Exporter specification in RFC 8446 and 5705.
This requires MBEDTLS_SSL_KEYING_MATERIAL_EXPORT to be defined in
mbedtls_config.h.
Security
* Fix a buffer overread in mbedtls_lms_import_public_key() when the input is
less than 3 bytes. Reported by Linh Le and Ngan Nguyen from Calif.
CVE-2025-49601
* Fix a vulnerability in LMS verification through which an adversary could
get an invalid signature accepted if they could cause a hash accelerator
to fail. Found and reported by Linh Le and Ngan Nguyen from Calif.
CVE-2025-49600
* On x86/amd64 platforms, with some compilers, when the library is
compiled with support for both AESNI and software AES and AESNI is
available in hardware, an adversary with fine control over which
threads make progress in a multithreaded program could force software
AES to be used for some time when the program starts. This could allow
the adversary to conduct timing attacks and potentially recover the
key. In particular, this attacker model may be possible against an SGX
enclave.
The same vulnerability affects GCM acceleration, which could allow
a similarly powerful adversary to craft GCM forgeries.
CVE-2025-52496
* Fix possible use-after-free or double-free in code calling
mbedtls_x509_string_to_names(). This was caused by the function calling
mbedtls_asn1_free_named_data_list() on its head argument, while the
documentation did no suggest it did, making it likely for callers relying
on the documented behaviour to still hold pointers to memory blocks after
they were free()d, resulting in high risk of use-after-free or double-free,
with consequences ranging up to arbitrary code execution.
In particular, the two sample programs x509/cert_write and x509/cert_req
were affected (use-after-free if the san string contains more than one DN).
Code that does not call mbedtls_string_to_names() directly is not affected.
Found by Linh Le and Ngan Nguyen from Calif.
CVE-2025-47917
* Fix a bug in mbedtls_asn1_store_named_data() where it would sometimes leave
an item in the output list in an inconsistent state with val.p == NULL but
val.len > 0. This impacts applications that call this function directly,
or indirectly via mbedtls_x509_string_to_names() or one of the
mbedtls_x509write_{crt,csr}_set_{subject,issuer}_name() functions. The
inconsistent state of the output could then cause a NULL dereference either
inside the same call to mbedtls_x509_string_to_names(), or in subsequent
users of the output structure, such as mbedtls_x509_write_names(). This
only affects applications that create (as opposed to consume) X.509
certificates, CSRs or CRLs, or that call mbedtls_asn1_store_named_data()
directly. Found by Linh Le and Ngan Nguyen from Calif.
CVE-2025-48965
* Fix an integer underflow that could occur when parsing malformed PEM
keys, which could be used by an attacker capable of feeding encrypted
PEM keys to a user. This could cause a crash or information disclosure.
Found and reported by Linh Le and Ngan Nguyen from Calif.
CVE-2025-52497
* Fix a timing side channel in the implementation of PKCS#7 padding
which would allow an attacker who can request decryption of arbitrary
ciphertexts to recover the plaintext through a timing oracle attack.
Reported by Ka Lok Wu from Stony Brook University and Doria Tang from
The Chinese University of Hong Kong.
CVE-2025-49087
Bugfix
* Fix failures of PSA multipart or interruptible operations when the
library or the application is built with a compiler where
"union foo x = {0}" does not initialize non-default members of the
union, such as GCC 15 and some versions of Clang 18. This affected MAC
multipart operations, MAC-based key derivation operations, interruptible
signature, interruptible verification, and potentially other operations
when using third-party drivers. This also affected one-shot MAC
operations using the built-in implementation. Fixes #9814.
* On entry to PSA driver entry points that set up a multipart operation
("xxx_setup"), the operation object is supposed to be all-bits-zero.
This was sometimes not the case when an operation object is reused,
or with compilers where "union foo x = {0}" does not initialize
non-default members of the union. The PSA core now ensures that this
guarantee is met in all cases. Fixes #9975.
* Resolved build issue with C++ projects using Mbed TLS 3.6 when compiling
with the MSVC toolset v142 and earlier. Fixes mbedtls issue #7087.
* Silence spurious -Wunterminated-string-initialization warnings introduced
by GCC 15. Fixes #9944.
* Fix a sloppy check in LMS public key import, which could lead to accepting
keys with a different LMS or LM-OTS types on some platforms. Specifically,
this could happen on platforms where enum types are smaller than 32 bits
and compiler optimization is enabled. Found and reported by Linh Le and
Ngan Nguyen from Calif.
* Fix a race condition on x86/amd64 platforms in AESNI support detection
that could lead to using software AES in some threads at the very
beginning of a multithreaded program. Reported by Solar Designer.
Fixes #9840.
* Fix mbedtls_base64_decode() on inputs that did not have the correct
number of trailing equal signs, or had 4*k+1 digits. They were accepted
as long as they had at most two trailing equal signs. They are now
rejected. Furthermore, before, on inputs with too few equal signs, the
function reported the correct size in *olen when it returned
MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, but truncated the output to the
last multiple of 3 bytes.
* When calling mbedtls_asn1_write_raw_buffer() with NULL, 0 as the last two
arguments, undefined behaviour would be triggered, in the form of a call to
memcpy(..., NULL, 0). This was harmless in practice, but could trigger
complains from sanitizers or static analyzers.
Changes
* The function mbedtls_x509_string_to_names() now requires its head argument
to point to NULL on entry. This makes it likely that existing risky uses of
this function (see the entry in the Security section) will be detected and
fixed.
= Mbed TLS 3.6.3 branch released 2025-03-24 = Mbed TLS 3.6.3 branch released 2025-03-24
Default behavior changes Default behavior changes

View File

@ -1,6 +0,0 @@
Features
* Add the function mbedtls_ssl_export_keying_material() which allows the
client and server to extract additional shared symmetric keys from an SSL
session, according to the TLS-Exporter specification in RFC 8446 and 5705.
This requires MBEDTLS_SSL_KEYING_MATERIAL_EXPORT to be defined in
mbedtls_config.h.

View File

@ -1,3 +0,0 @@
Bugfix
* Resolved build issue with C++ projects using Mbed TLS 3.6 when compiling
with the MSVC toolset v142 and earlier. Fixes mbedtls issue #7087.

View File

@ -1,15 +0,0 @@
Bugfix
* Fix failures of PSA multipart or interruptible operations when the
library or the application is built with a compiler where
"union foo x = {0}" does not initialize non-default members of the
union, such as GCC 15 and some versions of Clang 18. This affected MAC
multipart operations, MAC-based key derivation operations, interruptible
signature, interruptible verification, and potentially other operations
when using third-party drivers. This also affected one-shot MAC
operations using the built-in implementation. Fixes #9814.
* On entry to PSA driver entry points that set up a multipart operation
("xxx_setup"), the operation object is supposed to be all-bits-zero.
This was sometimes not the case when an operation object is reused,
or with compilers where "union foo x = {0}" does not initialize
non-default members of the union. The PSA core now ensures that this
guarantee is met in all cases. Fixes #9975.

View File

@ -1,3 +0,0 @@
Bugfix
* Silence spurious -Wunterminated-string-initialization warnings introduced
by GCC 15. Fixes #9944.

View File

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

View File

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

View File

@ -26,16 +26,16 @@
*/ */
#define MBEDTLS_VERSION_MAJOR 3 #define MBEDTLS_VERSION_MAJOR 3
#define MBEDTLS_VERSION_MINOR 6 #define MBEDTLS_VERSION_MINOR 6
#define MBEDTLS_VERSION_PATCH 3 #define MBEDTLS_VERSION_PATCH 4
/** /**
* The single version number has the following structure: * The single version number has the following structure:
* MMNNPP00 * MMNNPP00
* Major version | Minor version | Patch version * Major version | Minor version | Patch version
*/ */
#define MBEDTLS_VERSION_NUMBER 0x03060300 #define MBEDTLS_VERSION_NUMBER 0x03060400
#define MBEDTLS_VERSION_STRING "3.6.3" #define MBEDTLS_VERSION_STRING "3.6.4"
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.3" #define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.4"
/* Macros for build-time platform detection */ /* Macros for build-time platform detection */

View File

@ -332,7 +332,8 @@ int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn);
* call to mbedtls_asn1_free_named_data_list(). * call to mbedtls_asn1_free_named_data_list().
* *
* \param[out] head Address in which to store the pointer to the head of the * \param[out] head Address in which to store the pointer to the head of the
* allocated list of mbedtls_x509_name * allocated list of mbedtls_x509_name. Must point to NULL on
* entry.
* \param[in] name The string representation of a DN to convert * \param[in] name The string representation of a DN to convert
* *
* \return 0 on success, or a negative error code. * \return 0 on success, or a negative error code.

View File

@ -300,7 +300,7 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
add_library(${mbedcrypto_target} SHARED ${src_crypto}) add_library(${mbedcrypto_target} SHARED ${src_crypto})
set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.6.3 SOVERSION 16) set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.6.4 SOVERSION 16)
target_link_libraries(${mbedcrypto_target} PUBLIC ${libs}) target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
if(TARGET ${everest_target}) if(TARGET ${everest_target})
@ -312,11 +312,11 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
endif() endif()
add_library(${mbedx509_target} SHARED ${src_x509}) add_library(${mbedx509_target} SHARED ${src_x509})
set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.3 SOVERSION 7) set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.4 SOVERSION 7)
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target}) target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
add_library(${mbedtls_target} SHARED ${src_tls}) add_library(${mbedtls_target} SHARED ${src_tls})
set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.3 SOVERSION 21) set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.4 SOVERSION 21)
target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target}) target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
endif(USE_SHARED_MBEDTLS_LIBRARY) endif(USE_SHARED_MBEDTLS_LIBRARY)

View File

@ -48,8 +48,19 @@
*/ */
int mbedtls_aesni_has_support(unsigned int what) int mbedtls_aesni_has_support(unsigned int what)
{ {
static int done = 0; /* To avoid a race condition, tell the compiler that the assignment
static unsigned int c = 0; * `done = 1` and the assignment to `c` may not be reordered.
* https://github.com/Mbed-TLS/mbedtls/issues/9840
*
* Note that we may also be worried about memory access reordering,
* but fortunately the x86 memory model is not too wild: stores
* from the same thread are observed consistently by other threads.
* (See example 8-1 in Sewell et al., "x86-TSO: A Rigorous and Usable
* Programmers Model for x86 Multiprocessors", CACM, 2010,
* https://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf)
*/
static volatile int done = 0;
static volatile unsigned int c = 0;
if (!done) { if (!done) {
#if MBEDTLS_AESNI_HAVE_CODE == 2 #if MBEDTLS_AESNI_HAVE_CODE == 2

View File

@ -90,7 +90,9 @@ int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start,
len = size; len = size;
(*p) -= len; (*p) -= len;
memcpy(*p, buf, len); if (len != 0) {
memcpy(*p, buf, len);
}
return (int) len; return (int) len;
} }
@ -412,6 +414,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
} else if (val_len == 0) { } else if (val_len == 0) {
mbedtls_free(cur->val.p); mbedtls_free(cur->val.p);
cur->val.p = NULL; cur->val.p = NULL;
cur->val.len = 0;
} else if (cur->val.len != val_len) { } else if (cur->val.len != val_len) {
/* /*
* Enlarge existing value buffer if needed * Enlarge existing value buffer if needed

View File

@ -14,6 +14,7 @@
#include "mbedtls/base64.h" #include "mbedtls/base64.h"
#include "base64_internal.h" #include "base64_internal.h"
#include "constant_time_internal.h" #include "constant_time_internal.h"
#include "mbedtls/error.h"
#include <stdint.h> #include <stdint.h>
@ -183,49 +184,72 @@ int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen,
n++; n++;
} }
if (n == 0) { /* In valid base64, the number of digits (n-equals) is always of the form
*olen = 0; * 4*k, 4*k+2 or *4k+3. Also, the number n of digits plus the number of
return 0; * equal signs at the end is always a multiple of 4. */
if ((n - equals) % 4 == 1) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
}
if (n % 4 != 0) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
} }
/* The following expression is to calculate the following formula without /* We've determined that the input is valid, and that it contains
* risk of integer overflow in n: * exactly k blocks of digits-or-equals, with n = 4 * k,
* n = ( ( n * 6 ) + 7 ) >> 3; * and equals only present at the end of the last block if at all.
* Now we can calculate the length of the output.
*
* Each block of 4 digits in the input map to 3 bytes of output.
* For the last block:
* - abcd (where abcd are digits) is a full 3-byte block;
* - abc= means 1 byte less than a full 3-byte block of output;
* - ab== means 2 bytes less than a full 3-byte block of output;
* - a==== and ==== is rejected above.
*/ */
n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3); *olen = (n / 4) * 3 - equals;
n -= equals;
if (dst == NULL || dlen < n) { /* If the output buffer is too small, signal this and stop here.
*olen = n; * Also, as documented, stop here if `dst` is null, independently of
* `dlen`.
*
* There is an edge case when the output is empty: in this case,
* `dlen == 0` with `dst == NULL` is valid (on some platforms,
* `malloc(0)` returns `NULL`). Since the call is valid, we return
* 0 in this case.
*/
if ((*olen != 0 && dst == NULL) || dlen < *olen) {
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
} }
equals = 0;
for (x = 0, p = dst; i > 0; i--, src++) { for (x = 0, p = dst; i > 0; i--, src++) {
if (*src == '\r' || *src == '\n' || *src == ' ') { if (*src == '\r' || *src == '\n' || *src == ' ') {
continue; continue;
} }
x = x << 6;
if (*src == '=') { if (*src == '=') {
++equals; /* We already know from the first loop that equal signs are
} else { * only at the end. */
x |= mbedtls_ct_base64_dec_value(*src); break;
} }
x = x << 6;
x |= mbedtls_ct_base64_dec_value(*src);
if (++accumulated_digits == 4) { if (++accumulated_digits == 4) {
accumulated_digits = 0; accumulated_digits = 0;
*p++ = MBEDTLS_BYTE_2(x); *p++ = MBEDTLS_BYTE_2(x);
if (equals <= 1) { *p++ = MBEDTLS_BYTE_1(x);
*p++ = MBEDTLS_BYTE_1(x); *p++ = MBEDTLS_BYTE_0(x);
}
if (equals <= 0) {
*p++ = MBEDTLS_BYTE_0(x);
}
} }
} }
if (accumulated_digits == 3) {
*p++ = MBEDTLS_BYTE_2(x << 6);
*p++ = MBEDTLS_BYTE_1(x << 6);
} else if (accumulated_digits == 2) {
*p++ = MBEDTLS_BYTE_2(x << 12);
}
*olen = (size_t) (p - dst); if (*olen != (size_t) (p - dst)) {
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
return 0; return 0;
} }

View File

@ -14,6 +14,7 @@
#if defined(MBEDTLS_CIPHER_C) #if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#include "cipher_invasive.h"
#include "cipher_wrap.h" #include "cipher_wrap.h"
#include "mbedtls/platform_util.h" #include "mbedtls/platform_util.h"
#include "mbedtls/error.h" #include "mbedtls/error.h"
@ -838,8 +839,14 @@ static void add_pkcs_padding(unsigned char *output, size_t output_len,
} }
} }
static int get_pkcs_padding(unsigned char *input, size_t input_len, /*
size_t *data_len) * Get the length of the PKCS7 padding.
*
* Note: input_len must be the block size of the cipher.
*/
MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
size_t input_len,
size_t *data_len)
{ {
size_t i, pad_idx; size_t i, pad_idx;
unsigned char padding_len; unsigned char padding_len;
@ -849,10 +856,6 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len,
} }
padding_len = input[input_len - 1]; padding_len = input[input_len - 1];
if (padding_len == 0 || padding_len > input_len) {
return MBEDTLS_ERR_CIPHER_INVALID_PADDING;
}
*data_len = input_len - padding_len;
mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len); mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0)); bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
@ -866,6 +869,9 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len,
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different)); bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
} }
/* If the padding is invalid, set the output length to 0 */
*data_len = mbedtls_ct_if(bad, 0, input_len - padding_len);
return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING); return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
} }
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
@ -1144,7 +1150,7 @@ int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
case MBEDTLS_PADDING_PKCS7: case MBEDTLS_PADDING_PKCS7:
ctx->add_padding = add_pkcs_padding; ctx->add_padding = add_pkcs_padding;
ctx->get_padding = get_pkcs_padding; ctx->get_padding = mbedtls_get_pkcs_padding;
break; break;
#endif #endif
#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)

27
library/cipher_invasive.h Normal file
View File

@ -0,0 +1,27 @@
/**
* \file cipher_invasive.h
*
* \brief Cipher module: interfaces for invasive testing only.
*
* The interfaces in this file are intended for testing purposes only.
* They SHOULD NOT be made available in library integrations except when
* building the library for testing.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CIPHER_INVASIVE_H
#define MBEDTLS_CIPHER_INVASIVE_H
#include "common.h"
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_CIPHER_C)
MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
size_t input_len,
size_t *data_len);
#endif
#endif /* MBEDTLS_CIPHER_INVASIVE_H */

View File

@ -401,8 +401,11 @@ int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx,
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
} }
ctx->params.type = (mbedtls_lmots_algorithm_type_t) uint32_t type = MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET); if (type != (uint32_t) MBEDTLS_LMOTS_SHA256_N32_W8) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
}
ctx->params.type = (mbedtls_lmots_algorithm_type_t) type;
if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) { if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;

View File

@ -101,6 +101,9 @@ static int create_merkle_leaf_value(const mbedtls_lms_parameters_t *params,
size_t output_hash_len; size_t output_hash_len;
unsigned char r_node_idx_bytes[4]; unsigned char r_node_idx_bytes[4];
/* Always zeroize the output buffer because it may contain data from the previous invocation */
memset(out, 0, MBEDTLS_LMS_M_NODE_BYTES(params->type));
op = psa_hash_operation_init(); op = psa_hash_operation_init();
status = psa_hash_setup(&op, PSA_ALG_SHA_256); status = psa_hash_setup(&op, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) { if (status != PSA_SUCCESS) {
@ -239,25 +242,25 @@ void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx)
int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx, int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
const unsigned char *key, size_t key_size) const unsigned char *key, size_t key_size)
{ {
mbedtls_lms_algorithm_type_t type; if (key_size < 4) {
mbedtls_lmots_algorithm_type_t otstype;
type = (mbedtls_lms_algorithm_type_t) MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET);
if (type != MBEDTLS_LMS_SHA256_M32_H10) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
} }
ctx->params.type = type;
uint32_t type = MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET);
if (type != (uint32_t) MBEDTLS_LMS_SHA256_M32_H10) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
}
ctx->params.type = (mbedtls_lms_algorithm_type_t) type;
if (key_size != MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) { if (key_size != MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
} }
otstype = (mbedtls_lmots_algorithm_type_t) uint32_t otstype = MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET);
MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET); if (otstype != (uint32_t) MBEDTLS_LMOTS_SHA256_N32_W8) {
if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
} }
ctx->params.otstype = otstype; ctx->params.otstype = (mbedtls_lmots_algorithm_type_t) otstype;
memcpy(ctx->params.I_key_identifier, memcpy(ctx->params.I_key_identifier,
key + PUBLIC_KEY_I_KEY_ID_OFFSET, key + PUBLIC_KEY_I_KEY_ID_OFFSET,
@ -374,12 +377,16 @@ int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx,
return MBEDTLS_ERR_LMS_VERIFY_FAILED; return MBEDTLS_ERR_LMS_VERIFY_FAILED;
} }
create_merkle_leaf_value( ret = create_merkle_leaf_value(
&ctx->params, &ctx->params,
Kc_candidate_ots_pub_key, Kc_candidate_ots_pub_key,
MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier, MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
Tc_candidate_root_node); Tc_candidate_root_node);
if (ret != 0) {
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
}
curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) +
q_leaf_identifier; q_leaf_identifier;
@ -398,9 +405,11 @@ int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx,
height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type); height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
} }
create_merkle_internal_value(&ctx->params, left_node, right_node, ret = create_merkle_internal_value(&ctx->params, left_node, right_node,
parent_node_id, Tc_candidate_root_node); parent_node_id, Tc_candidate_root_node);
if (ret != 0) {
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
}
curr_node_id /= 2; curr_node_id /= 2;
} }

View File

@ -243,7 +243,10 @@ exit:
#if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) #if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len) static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
{ {
/* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */ /* input_len > 0 is not guaranteed by mbedtls_pem_read_buffer(). */
if (input_len < 1) {
return MBEDTLS_ERR_PEM_INVALID_DATA;
}
size_t pad_len = input[input_len - 1]; size_t pad_len = input[input_len - 1];
size_t i; size_t i;

View File

@ -292,8 +292,12 @@ int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *nam
unsigned char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; unsigned char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
size_t data_len = 0; size_t data_len = 0;
/* Clear existing chain if present */ /* Ensure the output parameter is not already populated.
mbedtls_asn1_free_named_data_list(head); * (If it were, overwriting it would likely cause a memory leak.)
*/
if (*head != NULL) {
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
while (c <= end) { while (c <= end) {
if (in_attr_type && *c == '=') { if (in_attr_type && *c == '=') {

View File

@ -84,12 +84,14 @@ void mbedtls_x509write_crt_set_issuer_key(mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx, int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx,
const char *subject_name) const char *subject_name)
{ {
mbedtls_asn1_free_named_data_list(&ctx->subject);
return mbedtls_x509_string_to_names(&ctx->subject, subject_name); return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
} }
int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx, int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx,
const char *issuer_name) const char *issuer_name)
{ {
mbedtls_asn1_free_named_data_list(&ctx->issuer);
return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name); return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name);
} }

View File

@ -66,6 +66,7 @@ void mbedtls_x509write_csr_set_key(mbedtls_x509write_csr *ctx, mbedtls_pk_contex
int mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr *ctx, int mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr *ctx,
const char *subject_name) const char *subject_name)
{ {
mbedtls_asn1_free_named_data_list(&ctx->subject);
return mbedtls_x509_string_to_names(&ctx->subject, subject_name); return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
} }

View File

@ -150,7 +150,6 @@ int main(int argc, char *argv[])
mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "csr example app"; const char *pers = "csr example app";
mbedtls_x509_san_list *cur, *prev; mbedtls_x509_san_list *cur, *prev;
mbedtls_asn1_named_data *ext_san_dirname = NULL;
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
uint8_t ip[4] = { 0 }; uint8_t ip[4] = { 0 };
#endif #endif
@ -274,7 +273,15 @@ usage:
cur->node.san.unstructured_name.len = sizeof(ip); cur->node.san.unstructured_name.len = sizeof(ip);
} else if (strcmp(q, "DN") == 0) { } else if (strcmp(q, "DN") == 0) {
cur->node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME; cur->node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
if ((ret = mbedtls_x509_string_to_names(&ext_san_dirname, /* Work around an API mismatch between string_to_names() and
* mbedtls_x509_subject_alternative_name, which holds an
* actual mbedtls_x509_name while a pointer to one would be
* more convenient here. (Note mbedtls_x509_name and
* mbedtls_asn1_named_data are synonymous, again
* string_to_names() uses one while
* cur->node.san.directory_name is nominally the other.) */
mbedtls_asn1_named_data *tmp_san_dirname = NULL;
if ((ret = mbedtls_x509_string_to_names(&tmp_san_dirname,
subtype_value)) != 0) { subtype_value)) != 0) {
mbedtls_strerror(ret, buf, sizeof(buf)); mbedtls_strerror(ret, buf, sizeof(buf));
mbedtls_printf( mbedtls_printf(
@ -283,7 +290,9 @@ usage:
(unsigned int) -ret, buf); (unsigned int) -ret, buf);
goto exit; goto exit;
} }
cur->node.san.directory_name = *ext_san_dirname; cur->node.san.directory_name = *tmp_san_dirname;
mbedtls_free(tmp_san_dirname);
tmp_san_dirname = NULL;
} else { } else {
mbedtls_free(cur); mbedtls_free(cur);
goto usage; goto usage;
@ -492,7 +501,6 @@ exit:
} }
mbedtls_x509write_csr_free(&req); mbedtls_x509write_csr_free(&req);
mbedtls_asn1_free_named_data_list(&ext_san_dirname);
mbedtls_pk_free(&key); mbedtls_pk_free(&key);
mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy); mbedtls_entropy_free(&entropy);
@ -502,12 +510,21 @@ exit:
cur = opt.san_list; cur = opt.san_list;
while (cur != NULL) { while (cur != NULL) {
prev = cur; mbedtls_x509_san_list *next = cur->next;
cur = cur->next; /* Note: mbedtls_x509_free_subject_alt_name() is not what we want here.
mbedtls_free(prev); * It's the right thing for entries that were parsed from a certificate,
* where pointers are to the raw certificate, but here all the
* pointers were allocated while parsing from a user-provided string. */
if (cur->node.type == MBEDTLS_X509_SAN_DIRECTORY_NAME) {
mbedtls_x509_name *dn = &cur->node.san.directory_name;
mbedtls_free(dn->oid.p);
mbedtls_free(dn->val.p);
mbedtls_asn1_free_named_data_list(&dn->next);
}
mbedtls_free(cur);
cur = next;
} }
mbedtls_exit(exit_code); mbedtls_exit(exit_code);
} }
#endif /* MBEDTLS_X509_CSR_WRITE_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO && #endif /* MBEDTLS_X509_CSR_WRITE_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&

View File

@ -312,7 +312,6 @@ int main(int argc, char *argv[])
mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "crt example app"; const char *pers = "crt example app";
mbedtls_x509_san_list *cur, *prev; mbedtls_x509_san_list *cur, *prev;
mbedtls_asn1_named_data *ext_san_dirname = NULL;
uint8_t ip[4] = { 0 }; uint8_t ip[4] = { 0 };
/* /*
* Set to sane values * Set to sane values
@ -595,7 +594,15 @@ usage:
cur->node.san.unstructured_name.len = sizeof(ip); cur->node.san.unstructured_name.len = sizeof(ip);
} else if (strcmp(q, "DN") == 0) { } else if (strcmp(q, "DN") == 0) {
cur->node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME; cur->node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
if ((ret = mbedtls_x509_string_to_names(&ext_san_dirname, /* Work around an API mismatch between string_to_names() and
* mbedtls_x509_subject_alternative_name, which holds an
* actual mbedtls_x509_name while a pointer to one would be
* more convenient here. (Note mbedtls_x509_name and
* mbedtls_asn1_named_data are synonymous, again
* string_to_names() uses one while
* cur->node.san.directory_name is nominally the other.) */
mbedtls_asn1_named_data *tmp_san_dirname = NULL;
if ((ret = mbedtls_x509_string_to_names(&tmp_san_dirname,
subtype_value)) != 0) { subtype_value)) != 0) {
mbedtls_strerror(ret, buf, sizeof(buf)); mbedtls_strerror(ret, buf, sizeof(buf));
mbedtls_printf( mbedtls_printf(
@ -604,7 +611,9 @@ usage:
(unsigned int) -ret, buf); (unsigned int) -ret, buf);
goto exit; goto exit;
} }
cur->node.san.directory_name = *ext_san_dirname; cur->node.san.directory_name = *tmp_san_dirname;
mbedtls_free(tmp_san_dirname);
tmp_san_dirname = NULL;
} else { } else {
mbedtls_free(cur); mbedtls_free(cur);
goto usage; goto usage;
@ -995,10 +1004,26 @@ usage:
exit_code = MBEDTLS_EXIT_SUCCESS; exit_code = MBEDTLS_EXIT_SUCCESS;
exit: exit:
cur = opt.san_list;
while (cur != NULL) {
mbedtls_x509_san_list *next = cur->next;
/* Note: mbedtls_x509_free_subject_alt_name() is not what we want here.
* It's the right thing for entries that were parsed from a certificate,
* where pointers are to the raw certificate, but here all the
* pointers were allocated while parsing from a user-provided string. */
if (cur->node.type == MBEDTLS_X509_SAN_DIRECTORY_NAME) {
mbedtls_x509_name *dn = &cur->node.san.directory_name;
mbedtls_free(dn->oid.p);
mbedtls_free(dn->val.p);
mbedtls_asn1_free_named_data_list(&dn->next);
}
mbedtls_free(cur);
cur = next;
}
#if defined(MBEDTLS_X509_CSR_PARSE_C) #if defined(MBEDTLS_X509_CSR_PARSE_C)
mbedtls_x509_csr_free(&csr); mbedtls_x509_csr_free(&csr);
#endif /* MBEDTLS_X509_CSR_PARSE_C */ #endif /* MBEDTLS_X509_CSR_PARSE_C */
mbedtls_asn1_free_named_data_list(&ext_san_dirname);
mbedtls_x509_crt_free(&issuer_crt); mbedtls_x509_crt_free(&issuer_crt);
mbedtls_x509write_crt_free(&crt); mbedtls_x509write_crt_free(&crt);
mbedtls_pk_free(&loaded_subject_key); mbedtls_pk_free(&loaded_subject_key);

View File

@ -550,6 +550,9 @@ void store_named_data_val_found(int old_len, int new_len)
} }
if (new_len == 0) { if (new_len == 0) {
TEST_ASSERT(found->val.p == NULL); TEST_ASSERT(found->val.p == NULL);
/* If new_len != 0, then new_val != NULL and the length has been checked
* above by TEST_MEMORY_COMPARE(). But not here, so we need to check. */
TEST_EQUAL(found->val.len, 0);
} else if (new_len == old_len) { } else if (new_len == old_len) {
TEST_ASSERT(found->val.p == old_val); TEST_ASSERT(found->val.p == old_val);
} else { } else {
@ -583,8 +586,10 @@ void store_named_data_val_new(int new_len, int set_new_val)
TEST_MEMORY_COMPARE(found->oid.p, found->oid.len, oid, oid_len); TEST_MEMORY_COMPARE(found->oid.p, found->oid.len, oid, oid_len);
if (new_len == 0) { if (new_len == 0) {
TEST_ASSERT(found->val.p == NULL); TEST_ASSERT(found->val.p == NULL);
TEST_EQUAL(found->val.len, 0);
} else if (new_val == NULL) { } else if (new_val == NULL) {
TEST_ASSERT(found->val.p != NULL); TEST_ASSERT(found->val.p != NULL);
TEST_EQUAL(found->val.len, new_len);
} else { } else {
TEST_ASSERT(found->val.p != new_val); TEST_ASSERT(found->val.p != new_val);
TEST_MEMORY_COMPARE(found->val.p, found->val.len, TEST_MEMORY_COMPARE(found->val.p, found->val.len,

View File

@ -76,6 +76,107 @@ mbedtls_base64_decode:"zm=masd":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode (Space inside string) Base64 decode (Space inside string)
mbedtls_base64_decode:"zm masd":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER mbedtls_base64_decode:"zm masd":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
# The next few test cases validate systematically for short inputs that
# we require the correct number of trailing equal signs.
# 4k+1 digits is always wrong (wouldn't encode more bytes than 4k digits)
Base64 decode: 1 digit, 0 equals (bad)
mbedtls_base64_decode:"Y":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 1 digit, 1 equals (bad)
mbedtls_base64_decode:"Y=":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 1 digit, 2 equals (bad)
mbedtls_base64_decode:"Y==":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 1 digit, 3 equals (bad)
mbedtls_base64_decode:"Y===":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 2 digits, 0 equals (bad)
mbedtls_base64_decode:"Yw":"c":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 2 digits, 1 equals (bad)
mbedtls_base64_decode:"Yw=":"c":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 2 digits, 2 equals (good)
mbedtls_base64_decode:"Yw==":"c":0
Base64 decode: 2 digits, 3 equals (bad)
mbedtls_base64_decode:"Yw===":"c":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 3 digits, 0 equals (bad)
mbedtls_base64_decode:"Y28":"co":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 3 digits, 1 equals (good)
mbedtls_base64_decode:"Y28=":"co":0
Base64 decode: 3 digits, 2 equals (bad)
mbedtls_base64_decode:"Y28==":"co":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 3 digits, 3 equals (bad)
mbedtls_base64_decode:"Y28===":"co":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 4 digits, 0 equals (good)
mbedtls_base64_decode:"Y29t":"com":0
Base64 decode: 4 digits, 1 equals (bad)
mbedtls_base64_decode:"Y29t=":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 4 digits, 2 equals (bad)
mbedtls_base64_decode:"Y29t==":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 4 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29t===":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
# 4k+1 digits is always wrong (wouldn't encode more bytes than 4k digits)
Base64 decode: 5 digits, 0 equals (bad)
mbedtls_base64_decode:"Y29tc":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 5 digits, 1 equals (bad)
mbedtls_base64_decode:"Y29tc=":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 5 digits, 2 equals (bad)
mbedtls_base64_decode:"Y29tc==":"":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 5 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29tc===":"com":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 6 digits, 0 equals (bad)
mbedtls_base64_decode:"Y29tcA":"comp":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 6 digits, 1 equals (bad)
mbedtls_base64_decode:"Y29tcA=":"comp":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 6 digits, 2 equals (good)
mbedtls_base64_decode:"Y29tcA==":"comp":0
Base64 decode: 6 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29tcA===":"comp":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 7 digits, 0 equals (bad)
mbedtls_base64_decode:"Y29tcG8":"compo":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 7 digits, 1 equals (good)
mbedtls_base64_decode:"Y29tcG8=":"compo":0
Base64 decode: 7 digits, 2 equals (bad)
mbedtls_base64_decode:"Y29tcG8==":"compo":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 7 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29tcG8===":"compo":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 8 digits, 0 equals (good)
mbedtls_base64_decode:"Y29tcG9z":"compos":0
Base64 decode: 8 digits, 1 equals (bad)
mbedtls_base64_decode:"Y29tcG9z=":"compos":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 8 digits, 2 equals (bad)
mbedtls_base64_decode:"Y29tcG9z==":"compos":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode: 8 digits, 3 equals (bad)
mbedtls_base64_decode:"Y29tcG9z===":"compos":MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Base64 decode "Zm9vYmFy" (no newline nor '\0' at end) Base64 decode "Zm9vYmFy" (no newline nor '\0' at end)
base64_decode_hex_src:"5a6d3976596d4679":"foobar":0 base64_decode_hex_src:"5a6d3976596d4679":"foobar":0

View File

@ -85,20 +85,67 @@ void mbedtls_base64_encode(char *src_string, char *dst_string,
/* BEGIN_CASE */ /* BEGIN_CASE */
void mbedtls_base64_decode(char *src_string, char *dst_string, int result) void mbedtls_base64_decode(char *src_string, char *dst_string, int result)
{ {
unsigned char src_str[1000]; unsigned char *src = NULL;
unsigned char dst_str[1000]; size_t src_len = strlen(src_string);
unsigned char *dst = NULL;
size_t correct_dst_len = strlen(dst_string);
size_t dst_size = correct_dst_len;
size_t len; size_t len;
int res;
memset(src_str, 0x00, 1000); /* Allocate exactly the size of the input, to ensure there's no buffer
memset(dst_str, 0x00, 1000); * overread in builds with ASan. (src_string has at least one extra null
* character at the end.) */
strncpy((char *) src_str, src_string, sizeof(src_str) - 1); TEST_CALLOC(src, src_len);
res = mbedtls_base64_decode(dst_str, sizeof(dst_str), &len, src_str, strlen((char *) src_str)); if (src_len != 0) {
TEST_ASSERT(res == result); memcpy(src, src_string, src_len);
if (result == 0) {
TEST_ASSERT(strcmp((char *) dst_str, dst_string) == 0);
} }
/* Allocate exactly the size of the input, to ensure there's no buffer
* overflow in builds with ASan. */
TEST_CALLOC(dst, dst_size);
/* Test normal operation */
TEST_EQUAL(mbedtls_base64_decode(dst, dst_size, &len,
src, src_len),
result);
if (result == 0) {
TEST_MEMORY_COMPARE(dst_string, correct_dst_len, dst, len);
}
/* Test an output buffer that's one byte too small */
if (result == 0 && dst_size != 0) {
mbedtls_free(dst);
dst = NULL;
TEST_CALLOC(dst, dst_size - 1);
TEST_EQUAL(mbedtls_base64_decode(dst, dst_size - 1, &len,
src, src_len),
MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
TEST_EQUAL(correct_dst_len, len);
}
/* Test an empty output buffer. `mbedtls_base64_decode()` must return
* `BUFFER_TOO_SMALL` but report the correct output length.
* Skip this when dst_size==0 since that would be a valid call to
* `mbedtls_base64_decode()` which should return 0.
*/
if (result == 0 && dst_size != 0) {
TEST_EQUAL(mbedtls_base64_decode(NULL, 0, &len,
src, src_len),
MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
TEST_EQUAL(correct_dst_len, len);
}
/* Test dst=NULL with dlen!=0 (explicitly documented as supported) */
if (result == 0 && dst_size != 0) {
TEST_EQUAL(mbedtls_base64_decode(NULL, 42, &len,
src, src_len),
MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
TEST_EQUAL(correct_dst_len, len);
}
exit:
mbedtls_free(src);
mbedtls_free(dst);
} }
/* END_CASE */ /* END_CASE */

View File

@ -6,6 +6,10 @@
#include "mbedtls/gcm.h" #include "mbedtls/gcm.h"
#endif #endif
#include "cipher_invasive.h"
#include "test/constant_flow.h"
#if defined(MBEDTLS_CIPHER_HAVE_SOME_AEAD_VIA_LEGACY_OR_USE_PSA) || defined(MBEDTLS_NIST_KW_C) #if defined(MBEDTLS_CIPHER_HAVE_SOME_AEAD_VIA_LEGACY_OR_USE_PSA) || defined(MBEDTLS_NIST_KW_C)
#define MBEDTLS_CIPHER_AUTH_CRYPT #define MBEDTLS_CIPHER_AUTH_CRYPT
#endif #endif
@ -1260,3 +1264,20 @@ exit:
mbedtls_free(key); mbedtls_free(key);
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
void get_pkcs_padding(data_t *decrypted_block, int exp_ret, int exp_len)
{
int ret;
size_t calculated_len;
TEST_CF_SECRET(decrypted_block->x, decrypted_block->len);
ret = mbedtls_get_pkcs_padding(decrypted_block->x, decrypted_block->len,
&calculated_len);
TEST_EQUAL(ret, exp_ret);
if (exp_ret == 0) {
TEST_EQUAL(calculated_len, exp_len);
}
}
/* END_CASE */

View File

@ -217,3 +217,18 @@ check_padding:MBEDTLS_PADDING_NONE:"DABBAD0001":0:5
Check no padding #3 (correct by definition) Check no padding #3 (correct by definition)
check_padding:MBEDTLS_PADDING_NONE:"":0:0 check_padding:MBEDTLS_PADDING_NONE:"":0:0
Constant-time PKCS7 padding, valid #1
get_pkcs_padding:"00112233445566778899AABBCCDDEE01":0:15
Constant-time PKCS7 padding, valid #2
get_pkcs_padding:"00112233445566778899AA0505050505":0:11
Constant-time PKCS7 padding, valid #3
get_pkcs_padding:"10101010101010101010101010101010":0:0
Constant-time PKCS7 padding, invalid zero
get_pkcs_padding:"00112233445566778899AABBCCDDEE00":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0
Constant-time PKCS7 padding, invalid > 16
get_pkcs_padding:"00112233445566778899AABBCCDDEE11":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0

View File

@ -186,6 +186,13 @@ LMS hsslms interop test #2
# print('lms_verify_test:"{}":"{}":"{}":0'.format(message.hex(), sig.hex(), public_key.get_pubkey().hex())) # print('lms_verify_test:"{}":"{}":"{}":0'.format(message.hex(), sig.hex(), public_key.get_pubkey().hex()))
lms_verify_test:"92d036bde8c45b8bb5dea2a072560b1e29fc4bb7dc4549ce90bccee8a6e962a1":"00000001000000042e758f2a0e8f301af58847b6973a15fe4856b91af88a1ff601e2f0e87bde33afbc39202a66e38931fbecd7d493cf957b37eeb57ed2e4d8f693b97adafa8241746d775cfb9471688d935e090581eb8586e7004d6b8855963d82ccb6f79df2d93dd35848556da6735def0f0c6c8fc969c1df692341f6a99626eff37d20226cef361c8802a995fa43535fe2336d8ae468c78eb6a7082e27c2c6317c034369b588e3d65a2eeac9804b427702dc49f681a841076813ed407399aa778259e7c34c750baa6d296a384e1274facaba9e2214d197628f5df7b2bf3896fedeab377b8edb775d6e8d67f1474ba3066794447f8f8e0c13552a007557a1f1c3b9bd2b41d9b446c6bcf36c828fd4c80850a31ee603065f5cc90d198df03835195b14e27da7bf727a16081fcc787f1dc7fa6da8b9ff908fb2c02d6f2a183486de0e39cd7da7fcdee0c8e96876c56ad9b0b18e4e4999e2c81a618aa4b27e050ce488dbb1e79089131afacc446cdf15b625f4e011f8d8160bb93f326bca3bb56fa41e34893d55f17d746fc142297997c5dbbba8f6b6c80678168ba455f12bac6982e5192de5462a46e14a45a01ce9e07279aa301dfd0fa9a12c6a55059b19a19d7afbe99779ea130ddeeb5ecb67d2ddb6c1c5d198e421b78091efa5aa429e1eb052760c0d8e2eb0c0ced000e93f7f265611a385f77c0cece0496eb29010f710e70a768d3713f0b7fc60c8ce372dc3234f27c7a1c2776a939ef70c7be869337b967df2223d4f20dca697e3bb6d0e53bbad153ff08d579f60c8535710f253b90e73ee9a19e1e57df66ec6c85ad1b4cea28a9d62fc5a4cf130f70b910dbc7e6f0e6b0cce1a1b5ff106b7f0b101405c0989084b2c94977116b98d15d6062a8d77d660aa813d432cf3338484308b7beed10236081f52da44eb807f9a75fd4cc1ba998ef3fc2e4791712597c786dd46431468bb4a1975a6cd854a1da23912fc99160f51df484efc9371c2d8e028d9468635cf93226f5a8834d14cead59e5d2a61dd6440d7b91c903ae8823907b75595c4828c7710036b347dcfb67f8561e835a53f569c8b3a1cd4317b2a6b2243100ee3d9468f9191acf2276d18dde9ebf2e11a48ba1fc1a15dc51091d3358d8d1f65ec7d84b97bb1669a9141f74065454f08e5ef25432b7635b8ec673ca70e4b3c25d07975a6fb725a56f28c1b5a81a6da2fe0a2c3474275926f9819a25b942462a68097e1cf6d9ae94f6b1f76b54addaeda04f9fc8db025fd6c453e1ad928f9323bf1381fce1893938828612728185d22a3d45d21ce762c066ab53a582c487d76d431e5b8f65a382142dd823d4620931e5572a4e6aee69986421afa119634bc8ea88aa6535c4d619ca0e0af94934637bc0c834e5e2a7a2853fa73835d00e13e5f26ad085ef66c8efb60097860cb199e03596a3b8f0ec78690d527bbc9363dd9702226788b1529871df74918ae2a4e02745043bd5ee8ab027826fb4cd54b0c27d99076757a1b41e2725ec02adc7926e8213796a8aa1740a2dc675437771e0364a83b0bd64c9620f6c203d92626ff29ef736eac0e13c71fd1957333ee0048000000061f7b7d6f916710efe9ed625ae689c67b3cc1cdf0d672e58c0b86b3839bbba2c243dcda2e63b26f5efa39ced6095a54625e67ab25d3df068e903eaaee894ac0f1fdeb4a2f1390f655db3608583eacfb0be4282f7bd1c42c5d748d524d7cdcd45878dea56cbc11a63bebbd74a5413ce72a931b1d4794c78c4cf16315bf2e055bb3305fe0272c8b916856cc27aa7a773ddce62afa7bb4da76c287e0ed3ed10452512de82c051f17b49c608b1a259e16a3812c0de684f2cb1ee59296c375376f146e2b0cc299ef41ed8e6fdf0557ec8d95fa026970f8d47c8347fed1e37e018413c5e813d1726ea18bc926ed02840349ab3b2adc8758a9cd57be38e9e76869762a81bb79721ca1c031c9dfdc3735fe9318064b62c2a7e8e2ec099963257b0705aac812dbc8cc3fbeea81af7c0d592c7e2ad1c21e877d4ae392b13ac1b57a8311d406":"000000060000000447cc5b29dd0cecd01c382434a6d16864d51b60cdb2a9eed2419015d8524c717ce38a865d7a37da6c84f94621ad595f5d":0 lms_verify_test:"92d036bde8c45b8bb5dea2a072560b1e29fc4bb7dc4549ce90bccee8a6e962a1":"00000001000000042e758f2a0e8f301af58847b6973a15fe4856b91af88a1ff601e2f0e87bde33afbc39202a66e38931fbecd7d493cf957b37eeb57ed2e4d8f693b97adafa8241746d775cfb9471688d935e090581eb8586e7004d6b8855963d82ccb6f79df2d93dd35848556da6735def0f0c6c8fc969c1df692341f6a99626eff37d20226cef361c8802a995fa43535fe2336d8ae468c78eb6a7082e27c2c6317c034369b588e3d65a2eeac9804b427702dc49f681a841076813ed407399aa778259e7c34c750baa6d296a384e1274facaba9e2214d197628f5df7b2bf3896fedeab377b8edb775d6e8d67f1474ba3066794447f8f8e0c13552a007557a1f1c3b9bd2b41d9b446c6bcf36c828fd4c80850a31ee603065f5cc90d198df03835195b14e27da7bf727a16081fcc787f1dc7fa6da8b9ff908fb2c02d6f2a183486de0e39cd7da7fcdee0c8e96876c56ad9b0b18e4e4999e2c81a618aa4b27e050ce488dbb1e79089131afacc446cdf15b625f4e011f8d8160bb93f326bca3bb56fa41e34893d55f17d746fc142297997c5dbbba8f6b6c80678168ba455f12bac6982e5192de5462a46e14a45a01ce9e07279aa301dfd0fa9a12c6a55059b19a19d7afbe99779ea130ddeeb5ecb67d2ddb6c1c5d198e421b78091efa5aa429e1eb052760c0d8e2eb0c0ced000e93f7f265611a385f77c0cece0496eb29010f710e70a768d3713f0b7fc60c8ce372dc3234f27c7a1c2776a939ef70c7be869337b967df2223d4f20dca697e3bb6d0e53bbad153ff08d579f60c8535710f253b90e73ee9a19e1e57df66ec6c85ad1b4cea28a9d62fc5a4cf130f70b910dbc7e6f0e6b0cce1a1b5ff106b7f0b101405c0989084b2c94977116b98d15d6062a8d77d660aa813d432cf3338484308b7beed10236081f52da44eb807f9a75fd4cc1ba998ef3fc2e4791712597c786dd46431468bb4a1975a6cd854a1da23912fc99160f51df484efc9371c2d8e028d9468635cf93226f5a8834d14cead59e5d2a61dd6440d7b91c903ae8823907b75595c4828c7710036b347dcfb67f8561e835a53f569c8b3a1cd4317b2a6b2243100ee3d9468f9191acf2276d18dde9ebf2e11a48ba1fc1a15dc51091d3358d8d1f65ec7d84b97bb1669a9141f74065454f08e5ef25432b7635b8ec673ca70e4b3c25d07975a6fb725a56f28c1b5a81a6da2fe0a2c3474275926f9819a25b942462a68097e1cf6d9ae94f6b1f76b54addaeda04f9fc8db025fd6c453e1ad928f9323bf1381fce1893938828612728185d22a3d45d21ce762c066ab53a582c487d76d431e5b8f65a382142dd823d4620931e5572a4e6aee69986421afa119634bc8ea88aa6535c4d619ca0e0af94934637bc0c834e5e2a7a2853fa73835d00e13e5f26ad085ef66c8efb60097860cb199e03596a3b8f0ec78690d527bbc9363dd9702226788b1529871df74918ae2a4e02745043bd5ee8ab027826fb4cd54b0c27d99076757a1b41e2725ec02adc7926e8213796a8aa1740a2dc675437771e0364a83b0bd64c9620f6c203d92626ff29ef736eac0e13c71fd1957333ee0048000000061f7b7d6f916710efe9ed625ae689c67b3cc1cdf0d672e58c0b86b3839bbba2c243dcda2e63b26f5efa39ced6095a54625e67ab25d3df068e903eaaee894ac0f1fdeb4a2f1390f655db3608583eacfb0be4282f7bd1c42c5d748d524d7cdcd45878dea56cbc11a63bebbd74a5413ce72a931b1d4794c78c4cf16315bf2e055bb3305fe0272c8b916856cc27aa7a773ddce62afa7bb4da76c287e0ed3ed10452512de82c051f17b49c608b1a259e16a3812c0de684f2cb1ee59296c375376f146e2b0cc299ef41ed8e6fdf0557ec8d95fa026970f8d47c8347fed1e37e018413c5e813d1726ea18bc926ed02840349ab3b2adc8758a9cd57be38e9e76869762a81bb79721ca1c031c9dfdc3735fe9318064b62c2a7e8e2ec099963257b0705aac812dbc8cc3fbeea81af7c0d592c7e2ad1c21e877d4ae392b13ac1b57a8311d406":"000000060000000447cc5b29dd0cecd01c382434a6d16864d51b60cdb2a9eed2419015d8524c717ce38a865d7a37da6c84f94621ad595f5d":0
LMS negative test (corrupt Merkle path byte)
# Corrupt one byte at index 200 in the Merkle authentication path to force internal failure.
# The test modifies a valid test's data so that the left_node parameter of create_merkle_internal_value becomes invalid.
# Since that corrupted data is not used by mbedtls_lms_verify before that invocation,
# the test targets the check of the value returned by create_merkle_internal_value.
lms_verify_test:"92d036bde8c45b8bb5dea2a072560b1e29fc4bb7dc4549ce90bccee8a6e962a1":"00000001000000042e758f2a0e8f301af58847b6973a15fe4856b91af88a1ff601e2f0e87bde33afbc39202a66e38931fbecd7d493cf957b37eeb57ed2e4d8f693b97adafa8241746d775cfb9471688d935e090581eb8586e7004d6b8855963d82ccb6f79df2d93dd35848556da6735def0f0c6c8fc969c1df692341f6a99626eff37d20226cef361c8802a995fa43535fe2336d8ae468c78eb6a7082e27c2c6317c034369b588e3d65a2eeac9804b427702dc49f681a841076813ed407399aa778259e7c34c750b556d296a384e1274facaba9e2214d197628f5df7b2bf3896fedeab377b8edb775d6e8d67f1474ba3066794447f8f8e0c13552a007557a1f1c3b9bd2b41d9b446c6bcf36c828fd4c80850a31ee603065f5cc90d198df03835195b14e27da7bf727a16081fcc787f1dc7fa6da8b9ff908fb2c02d6f2a183486de0e39cd7da7fcdee0c8e96876c56ad9b0b18e4e4999e2c81a618aa4b27e050ce488dbb1e79089131afacc446cdf15b625f4e011f8d8160bb93f326bca3bb56fa41e34893d55f17d746fc142297997c5dbbba8f6b6c80678168ba455f12bac6982e5192de5462a46e14a45a01ce9e07279aa301dfd0fa9a12c6a55059b19a19d7afbe99779ea130ddeeb5ecb67d2ddb6c1c5d198e421b78091efa5aa429e1eb052760c0d8e2eb0c0ced000e93f7f265611a385f77c0cece0496eb29010f710e70a768d3713f0b7fc60c8ce372dc3234f27c7a1c2776a939ef70c7be869337b967df2223d4f20dca697e3bb6d0e53bbad153ff08d579f60c8535710f253b90e73ee9a19e1e57df66ec6c85ad1b4cea28a9d62fc5a4cf130f70b910dbc7e6f0e6b0cce1a1b5ff106b7f0b101405c0989084b2c94977116b98d15d6062a8d77d660aa813d432cf3338484308b7beed10236081f52da44eb807f9a75fd4cc1ba998ef3fc2e4791712597c786dd46431468bb4a1975a6cd854a1da23912fc99160f51df484efc9371c2d8e028d9468635cf93226f5a8834d14cead59e5d2a61dd6440d7b91c903ae8823907b75595c4828c7710036b347dcfb67f8561e835a53f569c8b3a1cd4317b2a6b2243100ee3d9468f9191acf2276d18dde9ebf2e11a48ba1fc1a15dc51091d3358d8d1f65ec7d84b97bb1669a9141f74065454f08e5ef25432b7635b8ec673ca70e4b3c25d07975a6fb725a56f28c1b5a81a6da2fe0a2c3474275926f9819a25b942462a68097e1cf6d9ae94f6b1f76b54addaeda04f9fc8db025fd6c453e1ad928f9323bf1381fce1893938828612728185d22a3d45d21ce762c066ab53a582c487d76d431e5b8f65a382142dd823d4620931e5572a4e6aee69986421afa119634bc8ea88aa6535c4d619ca0e0af94934637bc0c834e5e2a7a2853fa73835d00e13e5f26ad085ef66c8efb60097860cb199e03596a3b8f0ec78690d527bbc9363dd9702226788b1529871df74918ae2a4e02745043bd5ee8ab027826fb4cd54b0c27d99076757a1b41e2725ec02adc7926e8213796a8aa1740a2dc675437771e0364a83b0bd64c9620f6c203d92626ff29ef736eac0e13c71fd1957333ee0048000000061f7b7d6f916710efe9ed625ae689c67b3cc1cdf0d672e58c0b86b3839bbba2c243dcda2e63b26f5efa39ced6095a54625e67ab25d3df068e903eaaee894ac0f1fdeb4a2f1390f655db3608583eacfb0be4282f7bd1c42c5d748d524d7cdcd45878dea56cbc11a63bebbd74a5413ce72a931b1d4794c78c4cf16315bf2e055bb3305fe0272c8b916856cc27aa7a773ddce62afa7bb4da76c287e0ed3ed10452512de82c051f17b49c608b1a259e16a3812c0de684f2cb1ee59296c375376f146e2b0cc299ef41ed8e6fdf0557ec8d95fa026970f8d47c8347fed1e37e018413c5e813d1726ea18bc926ed02840349ab3b2adc8758a9cd57be38e9e76869762a81bb79721ca1c031c9dfdc3735fe9318064b62c2a7e8e2ec099963257b0705aac812dbc8cc3fbeea81af7c0d592c7e2ad1c21e877d4ae392b13ac1b57a8311d406":"000000060000000447cc5b29dd0cecd01c382434a6d16864d51b60cdb2a9eed2419015d8524c717ce38a865d7a37da6c84f94621ad595f5d":MBEDTLS_ERR_LMS_VERIFY_FAILED
LMS negative test (invalid lms type) #1 LMS negative test (invalid lms type) #1
# This test uses the data from hash-sigs interop test #1. This test has a valid # This test uses the data from hash-sigs interop test #1. This test has a valid
# LMOTS type (0x4) but an invalid LMS type (0x5), and should fail. # LMOTS type (0x4) but an invalid LMS type (0x5), and should fail.
@ -212,6 +219,12 @@ LMS negative test (invalid leaf ID)
# test should fail to verify the signature. # test should fail to verify the signature.
lms_verify_test:"bfff9cd687351db88a98c71fd2f9b927a0ee600130a112533b791041d30cb91665fc369a5ac7cc9a04547414ac45288081d19d4a600579c73ac4bc953de03ad6":"0000040000000004e474c96c496b231ecedcd92566ab3e1cdfac83f7e56abaae6571401e212e59bdbcc18105e0709249510d13d7ae1091558c217033316ac70a36aae764bd0f4032e369453c634b81061079d216d03d3c55976a1aabc00287b307297ae03587ba20839460daae85d26dfcef7638c10a1d8559612e5e9ced1a4205a52ca0ce88e58602e59cf9ab34adf2e958e56570573297b99f733fbbf58d2440526fd4dc15c5509e8a11405f6c08772abcf58731fbf9a73642670e3247c5f70905f0fa81f6174bf32977209923507525a170fcd260e81f04193583fbcd305ac245c80eb337ca326fd1105e73748fab8a1f0c8d8a99f011718e7aae027a34d2a85ff18769fa277810126a86b51b096a04d8e28a4fb8c5e14e50a67cb1ee88e43e5cc077902442f5d9c55ac2b8acdd76c67bc740c6083aba4e3cb404c23f1f3118337563fef6a4b01fb476810c5b5682d0aecdccd55c85a4af50e9150f7d83dcccd8e822a302e6e5a52e00505e6e65338dcfb9cfbe22594e9e18ebde36af29450c5ea31523019cf64fd6eca8c77d98c2a146dcedd51bf6c61c1f7cacbce3ab20c8606930cc42737e17f2703cf0980aef560768d1ac5585c05a60a5f94db15f5ac4d4df5cbd81430878d4e9b77346e3a6538b80b80873e3e6c37860470091979296631440adb8cc71991aba2a4dd2884764878306fe774a25512cfbf080f2829ea2903ffa748dd187c21aef918ee3436a1bd336c3d09cc1f748d7528db90a98f69078b82c4d23de7bcec092a292d2b8cac71a5c87d008f128b89a5e608a4501aef41e9f17e4056ed4767957188f780159daebf327751386980b0fca5a2d36b141acff957f46ce2381897099619475db9d3a613e7ef98b056f42b4d6eafb1d62eebbe46a7502f893fbd36ccfb12a280f45ffb93f050eb280bf0a6cd640abdea8590bffb98bdb29ee3a31daa0fa3ab35fee11dc1b7d1fcea82b0e284b2e35b34e77c3f401ed887e7fc6c97b327f76f99caca2f355afa2753a8923bfb06fb2a9df08d31c93882e34ef5a3cccc9d078855334bdf909ae418b177724c42fb1d586d212c4474932acce295236030f4379158957300fe9fdc5cc9145e3ded50cf9f5a8e19321961536c4a47fffc3eb4383fb78a5d2aeed5b45b92132b5e2a53e3b67841fa2e1bd217ee2c30812c4eb1bd4f8c85b328e23d27f12a2fad5c6b236c87f8fd1aad441416e53ebd4d45d4bf601b94eb37dc9a065218ae58e69dba1250bb20626baeda961b3ef11d217697e73f41fa3870d726a032bc4a388fb12c023822945df058e22f54e5f6377eab34297c57883515204fc189d0d4b0ad9bacb24acf7f9d55e7c6368bb8ababd7622f586ec22683306c5d88d5244219a3952adbd85c89893a441a58b532e15600cd5afdbb5b441e1670b72656c7995189bdf993154e09912db8c4ddaff0e75591720230cf99c8b71cd841dffc4372c5e0f9ff906a379d28d6884351609bf7c849ebfabfb049ae986bbb8467251dbf5ccdd05a86ff6ce1392f7ca1bd49595ad9ad805d71b389afab1865f7f69dc24662af19934f025ced212536509500c132aec000000068b991bed50319a6cb9ff040b92f1563889b3787c37145fc9737d4643f66ade33ebd85a2c29b8c64a581cff01b89d59807d6fade2d2c88872f77d0ed83d97c4b5438681d0b95feb973125e4ee70ebe11699290b831e86571e36513a71f159d48ce563f6814cc2a89851d2520c5275b34cc83614cab14c0d197166580d800ee6b9004b8fd72daac8d73c36c1623c37be93ba49a06c4efde238a3a10a05daba5d4942f7de52648af2be31f33e723b3605346282f5d5e356c5d0004eea40fe0b80abf658f6c96c56319ab53d7fefb5879e0136d1cf320973a2f47c1ee3d21554910f09d17afac4607657c4309890957a4954bf86e2a8491ba37dd88b2c3fe3c7edebd767c400bc23e40d165b27133c726b90bc26cbb2a86a6aa400c47aa7ffc538388de8490b9349afa53b814ffe2a56ff16a496e9648284193754f989f6f12aeb6e":"0000000600000004d96bb26744d99ef624e32161c36d3d6efcdd0484e2b17a6dd183125be4b1af1cda931a91a3acb1151877c174f7943fd9":MBEDTLS_ERR_LMS_VERIFY_FAILED lms_verify_test:"bfff9cd687351db88a98c71fd2f9b927a0ee600130a112533b791041d30cb91665fc369a5ac7cc9a04547414ac45288081d19d4a600579c73ac4bc953de03ad6":"0000040000000004e474c96c496b231ecedcd92566ab3e1cdfac83f7e56abaae6571401e212e59bdbcc18105e0709249510d13d7ae1091558c217033316ac70a36aae764bd0f4032e369453c634b81061079d216d03d3c55976a1aabc00287b307297ae03587ba20839460daae85d26dfcef7638c10a1d8559612e5e9ced1a4205a52ca0ce88e58602e59cf9ab34adf2e958e56570573297b99f733fbbf58d2440526fd4dc15c5509e8a11405f6c08772abcf58731fbf9a73642670e3247c5f70905f0fa81f6174bf32977209923507525a170fcd260e81f04193583fbcd305ac245c80eb337ca326fd1105e73748fab8a1f0c8d8a99f011718e7aae027a34d2a85ff18769fa277810126a86b51b096a04d8e28a4fb8c5e14e50a67cb1ee88e43e5cc077902442f5d9c55ac2b8acdd76c67bc740c6083aba4e3cb404c23f1f3118337563fef6a4b01fb476810c5b5682d0aecdccd55c85a4af50e9150f7d83dcccd8e822a302e6e5a52e00505e6e65338dcfb9cfbe22594e9e18ebde36af29450c5ea31523019cf64fd6eca8c77d98c2a146dcedd51bf6c61c1f7cacbce3ab20c8606930cc42737e17f2703cf0980aef560768d1ac5585c05a60a5f94db15f5ac4d4df5cbd81430878d4e9b77346e3a6538b80b80873e3e6c37860470091979296631440adb8cc71991aba2a4dd2884764878306fe774a25512cfbf080f2829ea2903ffa748dd187c21aef918ee3436a1bd336c3d09cc1f748d7528db90a98f69078b82c4d23de7bcec092a292d2b8cac71a5c87d008f128b89a5e608a4501aef41e9f17e4056ed4767957188f780159daebf327751386980b0fca5a2d36b141acff957f46ce2381897099619475db9d3a613e7ef98b056f42b4d6eafb1d62eebbe46a7502f893fbd36ccfb12a280f45ffb93f050eb280bf0a6cd640abdea8590bffb98bdb29ee3a31daa0fa3ab35fee11dc1b7d1fcea82b0e284b2e35b34e77c3f401ed887e7fc6c97b327f76f99caca2f355afa2753a8923bfb06fb2a9df08d31c93882e34ef5a3cccc9d078855334bdf909ae418b177724c42fb1d586d212c4474932acce295236030f4379158957300fe9fdc5cc9145e3ded50cf9f5a8e19321961536c4a47fffc3eb4383fb78a5d2aeed5b45b92132b5e2a53e3b67841fa2e1bd217ee2c30812c4eb1bd4f8c85b328e23d27f12a2fad5c6b236c87f8fd1aad441416e53ebd4d45d4bf601b94eb37dc9a065218ae58e69dba1250bb20626baeda961b3ef11d217697e73f41fa3870d726a032bc4a388fb12c023822945df058e22f54e5f6377eab34297c57883515204fc189d0d4b0ad9bacb24acf7f9d55e7c6368bb8ababd7622f586ec22683306c5d88d5244219a3952adbd85c89893a441a58b532e15600cd5afdbb5b441e1670b72656c7995189bdf993154e09912db8c4ddaff0e75591720230cf99c8b71cd841dffc4372c5e0f9ff906a379d28d6884351609bf7c849ebfabfb049ae986bbb8467251dbf5ccdd05a86ff6ce1392f7ca1bd49595ad9ad805d71b389afab1865f7f69dc24662af19934f025ced212536509500c132aec000000068b991bed50319a6cb9ff040b92f1563889b3787c37145fc9737d4643f66ade33ebd85a2c29b8c64a581cff01b89d59807d6fade2d2c88872f77d0ed83d97c4b5438681d0b95feb973125e4ee70ebe11699290b831e86571e36513a71f159d48ce563f6814cc2a89851d2520c5275b34cc83614cab14c0d197166580d800ee6b9004b8fd72daac8d73c36c1623c37be93ba49a06c4efde238a3a10a05daba5d4942f7de52648af2be31f33e723b3605346282f5d5e356c5d0004eea40fe0b80abf658f6c96c56319ab53d7fefb5879e0136d1cf320973a2f47c1ee3d21554910f09d17afac4607657c4309890957a4954bf86e2a8491ba37dd88b2c3fe3c7edebd767c400bc23e40d165b27133c726b90bc26cbb2a86a6aa400c47aa7ffc538388de8490b9349afa53b814ffe2a56ff16a496e9648284193754f989f6f12aeb6e":"0000000600000004d96bb26744d99ef624e32161c36d3d6efcdd0484e2b17a6dd183125be4b1af1cda931a91a3acb1151877c174f7943fd9":MBEDTLS_ERR_LMS_VERIFY_FAILED
LMS public key import: truncated input below minimum valid size
# This test provides an input buffer that is one byte shorter than the minimum required
# size (MBEDTLS_LMS_TYPE_LEN - 1). The import operation is expected to fail gracefully,
# without attempting to read beyond the end of the buffer.
lms_import_export_test:"000000":MBEDTLS_ERR_LMS_BAD_INPUT_DATA
LMS import/export test LMS import/export test
# This test uses the key from hsslms interop test 1, imports it, exports it and # This test uses the key from hsslms interop test 1, imports it, exports it and
# tests that it is the same. It also checks if the export correctly fail when # tests that it is the same. It also checks if the export correctly fail when

View File

@ -49,10 +49,22 @@ PEM read (malformed PEM DES-EDE3-CBC)
depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-EDE3-CBC,AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:"" mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: DES-EDE3-CBC,AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:""
PEM read (malformed PEM AES-128-CBC) PEM read (malformed PEM AES-128-CBC: 3-byte ciphertext)
depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,AA94892A169FA426AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:"" mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,AA94892A169FA426AA94892A169FA426\n\nMAAA\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:""
PEM read (malformed PEM AES-128-CBC: 1-byte ciphertext)
depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,7BA38DE00F67851E4207216809C3BB15\n\n8Q==-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:""
PEM read (malformed PEM AES-128-CBC: empty ciphertext)
depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,7BA38DE00F67851E4207216809C3BB15\n\n-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_PEM_BAD_INPUT_DATA:""
PEM read (malformed PEM AES-128-CBC: base64 with missing equals)
depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
mbedtls_pem_read_buffer:"-----BEGIN EC PRIVATE KEY-----":"-----END EC PRIVATE KEY-----":"-----BEGIN EC PRIVATE KEY-----\nProc-Type\: 4,ENCRYPTED\nDEK-Info\: AES-128-CBC,7BA38DE00F67851E4207216809C3BB15\n\n8Q-----END EC PRIVATE KEY-----":"pwd":MBEDTLS_ERR_PEM_INVALID_DATA + MBEDTLS_ERR_BASE64_INVALID_CHARACTER:""
# The output sequence's length is not multiple of block size (16 bytes). This # The output sequence's length is not multiple of block size (16 bytes). This
# proves that the pem_context->len value is properly updated based on the SEQUENCE # proves that the pem_context->len value is properly updated based on the SEQUENCE
# length read from the decoded ASN.1 data (i.e. extra padding, if any, is ignored). # length read from the decoded ASN.1 data (i.e. extra padding, if any, is ignored).

View File

@ -15,16 +15,16 @@ void mbedtls_pem_write_buffer(char *start, char *end, data_t *buf,
ret = mbedtls_pem_write_buffer(start, end, buf->x, buf->len, NULL, 0, &olen); ret = mbedtls_pem_write_buffer(start, end, buf->x, buf->len, NULL, 0, &olen);
TEST_ASSERT(ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL); TEST_EQUAL(ret, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
check_buf = (unsigned char *) mbedtls_calloc(1, olen); check_buf = (unsigned char *) mbedtls_calloc(1, olen);
TEST_ASSERT(check_buf != NULL); TEST_ASSERT(check_buf != NULL);
ret = mbedtls_pem_write_buffer(start, end, buf->x, buf->len, check_buf, olen, &olen2); ret = mbedtls_pem_write_buffer(start, end, buf->x, buf->len, check_buf, olen, &olen2);
TEST_ASSERT(olen2 <= olen); TEST_LE_U(olen2, olen);
TEST_ASSERT(olen > strlen((char *) result_str)); TEST_LE_U(strlen((char *) result_str) + 1, olen);
TEST_ASSERT(ret == 0); TEST_EQUAL(ret, 0);
TEST_ASSERT(strncmp((char *) check_buf, (char *) result_str, olen) == 0); TEST_ASSERT(strncmp((char *) check_buf, (char *) result_str, olen) == 0);
exit: exit:
@ -76,15 +76,14 @@ void mbedtls_pem_read_buffer(char *header, char *footer, char *data,
ret = mbedtls_pem_read_buffer(&ctx, header, footer, (unsigned char *) data, ret = mbedtls_pem_read_buffer(&ctx, header, footer, (unsigned char *) data,
(unsigned char *) pwd, pwd_len, &use_len); (unsigned char *) pwd, pwd_len, &use_len);
TEST_ASSERT(ret == res); TEST_EQUAL(ret, res);
if (ret != 0) { if (ret != 0) {
goto exit; goto exit;
} }
use_len = 0; use_len = 0;
buf = mbedtls_pem_get_buffer(&ctx, &use_len); buf = mbedtls_pem_get_buffer(&ctx, &use_len);
TEST_EQUAL(use_len, out->len); TEST_MEMORY_COMPARE(out->x, out->len, buf, use_len);
TEST_ASSERT(memcmp(out->x, buf, out->len) == 0);
exit: exit:
mbedtls_pem_free(&ctx); mbedtls_pem_free(&ctx);

View File

@ -1,8 +1,8 @@
Check compile time library version Check compile time library version
check_compiletime_version:"3.6.3" check_compiletime_version:"3.6.4"
Check runtime library version Check runtime library version
check_runtime_version:"3.6.3" check_runtime_version:"3.6.4"
Check for MBEDTLS_VERSION_C Check for MBEDTLS_VERSION_C
check_feature:"MBEDTLS_VERSION_C":0 check_feature:"MBEDTLS_VERSION_C":0

View File

@ -254,6 +254,27 @@ mbedtls_x509_string_to_names:"C=NL, O=Of\\CCspark, OU=PolarSSL":"C=NL, O=Of\\CCs
X509 String to Names #20 (Reject empty AttributeValue) X509 String to Names #20 (Reject empty AttributeValue)
mbedtls_x509_string_to_names:"C=NL, O=, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0 mbedtls_x509_string_to_names:"C=NL, O=, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
# Note: the behaviour is incorrect, output from string->names->string should be
# the same as the input, rather than just the last component, see
# https://github.com/Mbed-TLS/mbedtls/issues/10189
# Still including tests for the current incorrect behaviour because of the
# variants below where we want to ensure at least that no memory corruption
# happens (which would be a lot worse than just a functional bug).
X509 String to Names (repeated OID)
mbedtls_x509_string_to_names:"CN=ab,CN=cd,CN=ef":"CN=ef":0:0
# Note: when a value starts with a # sign, it's treated as the hex encoding of
# the DER encoding of the value. Here, 0400 is a zero-length OCTET STRING.
# The tag actually doesn't matter for our purposes, only the length.
X509 String to Names (repeated OID, 1st is zero-length)
mbedtls_x509_string_to_names:"CN=#0400,CN=cd,CN=ef":"CN=ef":0:0
X509 String to Names (repeated OID, middle is zero-length)
mbedtls_x509_string_to_names:"CN=ab,CN=#0400,CN=ef":"CN=ef":0:0
X509 String to Names (repeated OID, last is zero-length)
mbedtls_x509_string_to_names:"CN=ab,CN=cd,CN=#0400":"CN=#0000":0:MAY_FAIL_GET_NAME
X509 Round trip test (Escaped characters) X509 Round trip test (Escaped characters)
mbedtls_x509_string_to_names:"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":0:0 mbedtls_x509_string_to_names:"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":0:0

View File

@ -731,6 +731,11 @@ void mbedtls_x509_string_to_names(char *name, char *parsed_name,
TEST_LE_S(1, ret); TEST_LE_S(1, ret);
TEST_ASSERT(strcmp((char *) out, parsed_name) == 0); TEST_ASSERT(strcmp((char *) out, parsed_name) == 0);
/* Check that calling a 2nd time with the same param (now non-NULL)
* returns an error as expected. */
ret = mbedtls_x509_string_to_names(&names, name);
TEST_EQUAL(ret, MBEDTLS_ERR_X509_BAD_INPUT_DATA);
exit: exit:
mbedtls_asn1_free_named_data_list(&names); mbedtls_asn1_free_named_data_list(&names);