1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-29 11:41:15 +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

@ -300,7 +300,7 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
add_library(${mbedcrypto_target} SHARED ${src_crypto})
set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.6.3 SOVERSION 16)
set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.6.4 SOVERSION 16)
target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
if(TARGET ${everest_target})
@ -312,11 +312,11 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
endif()
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})
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})
endif(USE_SHARED_MBEDTLS_LIBRARY)

View File

@ -48,8 +48,19 @@
*/
int mbedtls_aesni_has_support(unsigned int what)
{
static int done = 0;
static unsigned int c = 0;
/* To avoid a race condition, tell the compiler that the assignment
* `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 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;
(*p) -= len;
memcpy(*p, buf, len);
if (len != 0) {
memcpy(*p, buf, len);
}
return (int) len;
}
@ -412,6 +414,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
} else if (val_len == 0) {
mbedtls_free(cur->val.p);
cur->val.p = NULL;
cur->val.len = 0;
} else if (cur->val.len != val_len) {
/*
* Enlarge existing value buffer if needed

View File

@ -14,6 +14,7 @@
#include "mbedtls/base64.h"
#include "base64_internal.h"
#include "constant_time_internal.h"
#include "mbedtls/error.h"
#include <stdint.h>
@ -183,49 +184,72 @@ int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen,
n++;
}
if (n == 0) {
*olen = 0;
return 0;
/* In valid base64, the number of digits (n-equals) is always of the form
* 4*k, 4*k+2 or *4k+3. Also, the number n of digits plus the number of
* 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
* risk of integer overflow in n:
* n = ( ( n * 6 ) + 7 ) >> 3;
/* We've determined that the input is valid, and that it contains
* exactly k blocks of digits-or-equals, with n = 4 * k,
* 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);
n -= equals;
*olen = (n / 4) * 3 - equals;
if (dst == NULL || dlen < n) {
*olen = n;
/* If the output buffer is too small, signal this and stop here.
* 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;
}
equals = 0;
for (x = 0, p = dst; i > 0; i--, src++) {
if (*src == '\r' || *src == '\n' || *src == ' ') {
continue;
}
x = x << 6;
if (*src == '=') {
++equals;
} else {
x |= mbedtls_ct_base64_dec_value(*src);
/* We already know from the first loop that equal signs are
* only at the end. */
break;
}
x = x << 6;
x |= mbedtls_ct_base64_dec_value(*src);
if (++accumulated_digits == 4) {
accumulated_digits = 0;
*p++ = MBEDTLS_BYTE_2(x);
if (equals <= 1) {
*p++ = MBEDTLS_BYTE_1(x);
}
if (equals <= 0) {
*p++ = MBEDTLS_BYTE_0(x);
}
*p++ = MBEDTLS_BYTE_1(x);
*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;
}

View File

@ -14,6 +14,7 @@
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#include "cipher_invasive.h"
#include "cipher_wrap.h"
#include "mbedtls/platform_util.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;
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];
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);
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));
}
/* 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);
}
#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)
case MBEDTLS_PADDING_PKCS7:
ctx->add_padding = add_pkcs_padding;
ctx->get_padding = get_pkcs_padding;
ctx->get_padding = mbedtls_get_pkcs_padding;
break;
#endif
#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;
}
ctx->params.type = (mbedtls_lmots_algorithm_type_t)
MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
uint32_t type = 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)) {
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;
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();
status = psa_hash_setup(&op, PSA_ALG_SHA_256);
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,
const unsigned char *key, size_t key_size)
{
mbedtls_lms_algorithm_type_t type;
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) {
if (key_size < 4) {
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)) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
}
otstype = (mbedtls_lmots_algorithm_type_t)
MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET);
if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
uint32_t otstype = MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET);
if (otstype != (uint32_t) MBEDTLS_LMOTS_SHA256_N32_W8) {
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,
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;
}
create_merkle_leaf_value(
ret = create_merkle_leaf_value(
&ctx->params,
Kc_candidate_ots_pub_key,
MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
Tc_candidate_root_node);
if (ret != 0) {
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
}
curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) +
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);
}
create_merkle_internal_value(&ctx->params, left_node, right_node,
parent_node_id, Tc_candidate_root_node);
ret = create_merkle_internal_value(&ctx->params, left_node, right_node,
parent_node_id, Tc_candidate_root_node);
if (ret != 0) {
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
}
curr_node_id /= 2;
}

View File

@ -243,7 +243,10 @@ exit:
#if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
{
/* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */
/* 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 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];
size_t data_len = 0;
/* Clear existing chain if present */
mbedtls_asn1_free_named_data_list(head);
/* Ensure the output parameter is not already populated.
* (If it were, overwriting it would likely cause a memory leak.)
*/
if (*head != NULL) {
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
while (c <= end) {
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,
const char *subject_name)
{
mbedtls_asn1_free_named_data_list(&ctx->subject);
return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
}
int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx,
const char *issuer_name)
{
mbedtls_asn1_free_named_data_list(&ctx->issuer);
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,
const char *subject_name)
{
mbedtls_asn1_free_named_data_list(&ctx->subject);
return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
}