Merge branch 'Mbed-TLS:development' into threadsafe-key-locking

This commit is contained in:
Ryan Everett 2024-02-12 10:04:07 +00:00 committed by GitHub
commit e02b63ac89
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
156 changed files with 6545 additions and 2274 deletions

View file

@ -231,7 +231,7 @@ if(HAIKU)
endif(HAIKU)
if(LINK_WITH_PTHREAD)
set(libs ${libs} pthread)
set(libs ${libs} ${CMAKE_THREAD_LIBS_INIT})
endif()
if(LINK_WITH_TRUSTED_STORAGE)

View file

@ -53,28 +53,45 @@ typedef uint16_t __packed mbedtls_uint16_unaligned_t;
typedef uint32_t __packed mbedtls_uint32_unaligned_t;
typedef uint64_t __packed mbedtls_uint64_unaligned_t;
#elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \
((MBEDTLS_GCC_VERSION < 90300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)))
((MBEDTLS_GCC_VERSION < 60300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)))
/*
* Old versions of gcc, depending on how the target is specified, may generate a branch to memcpy
* for calls like `memcpy(dest, src, 4)` rather than generating some LDR or LDRB instructions
* (similar for stores).
* Recent versions where unaligned access is not enabled also do this.
* gcc may generate a branch to memcpy for calls like `memcpy(dest, src, 4)` rather than
* generating some LDR or LDRB instructions (similar for stores).
*
* This is architecture dependent: x86-64 seems fine even with old gcc; 32-bit Arm
* is affected. To keep it simple, we enable for all architectures.
*
* For versions of gcc < 5.4.0 this issue always happens.
* For gcc < 6.3.0, this issue happens at -O0
* For all versions, this issue happens iff unaligned access is not supported.
*
* For gcc 4.x, this implementation will generate byte-by-byte loads even if unaligned access is
* supported, which is correct but not optimal.
*
* For performance (and code size, in some cases), we want to avoid the branch and just generate
* some inline load/store instructions since the access is small and constant-size.
*
* The manual states:
* "The aligned attribute specifies a minimum alignment for the variable or structure field,
* measured in bytes."
* https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
* "The packed attribute specifies that a variable or structure field should have the smallest
* possible alignmentone byte for a variable"
* https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Variable-Attributes.html
*
* Tested with several versions of GCC from 4.5.0 up to 9.3.0
* Previous implementations used __attribute__((__aligned__(1)), but had issues with a gcc bug:
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94662
*
* Tested with several versions of GCC from 4.5.0 up to 13.2.0
* We don't enable for older than 4.5.0 as this has not been tested.
*/
#define UINT_UNALIGNED
typedef uint16_t __attribute__((__aligned__(1))) mbedtls_uint16_unaligned_t;
typedef uint32_t __attribute__((__aligned__(1))) mbedtls_uint32_unaligned_t;
typedef uint64_t __attribute__((__aligned__(1))) mbedtls_uint64_unaligned_t;
#define UINT_UNALIGNED_STRUCT
typedef struct {
uint16_t x;
} __attribute__((packed)) mbedtls_uint16_unaligned_t;
typedef struct {
uint32_t x;
} __attribute__((packed)) mbedtls_uint32_unaligned_t;
typedef struct {
uint64_t x;
} __attribute__((packed)) mbedtls_uint64_unaligned_t;
#endif
/*
@ -101,6 +118,9 @@ static inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
#if defined(UINT_UNALIGNED)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
r = *p16;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
r = p16->x;
#else
memcpy(&r, p, sizeof(r));
#endif
@ -124,6 +144,9 @@ static inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
#if defined(UINT_UNALIGNED)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
*p16 = x;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
p16->x = x;
#else
memcpy(p, &x, sizeof(x));
#endif
@ -147,6 +170,9 @@ static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = *p32;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
r = p32->x;
#else
memcpy(&r, p, sizeof(r));
#endif
@ -170,6 +196,9 @@ static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
#if defined(UINT_UNALIGNED)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
*p32 = x;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
p32->x = x;
#else
memcpy(p, &x, sizeof(x));
#endif
@ -193,6 +222,9 @@ static inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
#if defined(UINT_UNALIGNED)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
r = *p64;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
r = p64->x;
#else
memcpy(&r, p, sizeof(r));
#endif
@ -216,6 +248,9 @@ static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
#if defined(UINT_UNALIGNED)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
*p64 = x;
#elif defined(UINT_UNALIGNED_STRUCT)
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
p64->x = x;
#else
memcpy(p, &x, sizeof(x));
#endif

View file

@ -25,12 +25,6 @@
#include "mbedtls/platform_util.h"
/* Parameter validation macros */
#define ARIA_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA)
#define ARIA_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
/*
* modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
*
@ -363,8 +357,6 @@ int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
int i;
uint32_t w[4][4], *w2;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(key != NULL);
if (keybits != 128 && keybits != 192 && keybits != 256) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
@ -418,8 +410,6 @@ int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
const unsigned char *key, unsigned int keybits)
{
int i, j, k, ret;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(key != NULL);
ret = mbedtls_aria_setkey_enc(ctx, key, keybits);
if (ret != 0) {
@ -455,9 +445,6 @@ int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
int i;
uint32_t a, b, c, d;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(input != NULL);
ARIA_VALIDATE_RET(output != NULL);
a = MBEDTLS_GET_UINT32_LE(input, 0);
b = MBEDTLS_GET_UINT32_LE(input, 4);
@ -505,7 +492,6 @@ int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
/* Initialize context */
void mbedtls_aria_init(mbedtls_aria_context *ctx)
{
ARIA_VALIDATE(ctx != NULL);
memset(ctx, 0, sizeof(mbedtls_aria_context));
}
@ -532,12 +518,9 @@ int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx,
{
unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(mode == MBEDTLS_ARIA_ENCRYPT ||
mode == MBEDTLS_ARIA_DECRYPT);
ARIA_VALIDATE_RET(length == 0 || input != NULL);
ARIA_VALIDATE_RET(length == 0 || output != NULL);
ARIA_VALIDATE_RET(iv != NULL);
if ((mode != MBEDTLS_ARIA_ENCRYPT) && (mode != MBEDTLS_ARIA_DECRYPT)) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
}
if (length % MBEDTLS_ARIA_BLOCKSIZE) {
return MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH;
@ -588,19 +571,14 @@ int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
unsigned char c;
size_t n;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(mode == MBEDTLS_ARIA_ENCRYPT ||
mode == MBEDTLS_ARIA_DECRYPT);
ARIA_VALIDATE_RET(length == 0 || input != NULL);
ARIA_VALIDATE_RET(length == 0 || output != NULL);
ARIA_VALIDATE_RET(iv != NULL);
ARIA_VALIDATE_RET(iv_off != NULL);
if ((mode != MBEDTLS_ARIA_ENCRYPT) && (mode != MBEDTLS_ARIA_DECRYPT)) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
}
n = *iv_off;
/* An overly large value of n can lead to an unlimited
* buffer overflow. Therefore, guard against this
* outside of parameter validation. */
* buffer overflow. */
if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
}
@ -650,17 +628,9 @@ int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx,
int c, i;
size_t n;
ARIA_VALIDATE_RET(ctx != NULL);
ARIA_VALIDATE_RET(length == 0 || input != NULL);
ARIA_VALIDATE_RET(length == 0 || output != NULL);
ARIA_VALIDATE_RET(nonce_counter != NULL);
ARIA_VALIDATE_RET(stream_block != NULL);
ARIA_VALIDATE_RET(nc_off != NULL);
n = *nc_off;
/* An overly large value of n can lead to an unlimited
* buffer overflow. Therefore, guard against this
* outside of parameter validation. */
* buffer overflow. */
if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
}

View file

@ -7,7 +7,8 @@
#include "common.h"
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
#include "mbedtls/asn1.h"
#include "mbedtls/platform_util.h"
@ -73,7 +74,7 @@ int mbedtls_asn1_get_tag(unsigned char **p,
return mbedtls_asn1_get_len(p, end, len);
}
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_PARSE_C)
int mbedtls_asn1_get_bool(unsigned char **p,

View file

@ -7,7 +7,8 @@
#include "common.h"
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C)
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
@ -62,7 +63,7 @@ int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, unsign
return 1;
}
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_WRITE_C)
static int mbedtls_asn1_write_len_and_tag(unsigned char **p,

View file

@ -37,11 +37,6 @@
#include "mbedtls/platform.h"
#define MPI_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA)
#define MPI_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
/*
* Compare signed values in constant time
*/
@ -51,10 +46,6 @@ int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
{
mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
MPI_VALIDATE_RET(ret != NULL);
if (X->n != Y->n) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
@ -115,8 +106,6 @@ int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
unsigned char assign)
{
int ret = 0;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
@ -149,8 +138,6 @@ int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
{
int ret = 0;
int s;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
if (X == Y) {
return 0;
@ -179,8 +166,6 @@ cleanup:
*/
void mbedtls_mpi_init(mbedtls_mpi *X)
{
MPI_VALIDATE(X != NULL);
X->s = 1;
X->n = 0;
X->p = NULL;
@ -210,7 +195,6 @@ void mbedtls_mpi_free(mbedtls_mpi *X)
int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
{
mbedtls_mpi_uint *p;
MPI_VALIDATE_RET(X != NULL);
if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
@ -243,7 +227,6 @@ int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs)
{
mbedtls_mpi_uint *p;
size_t i;
MPI_VALIDATE_RET(X != NULL);
if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
@ -312,8 +295,6 @@ int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
{
int ret = 0;
size_t i;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
if (X == Y) {
return 0;
@ -355,8 +336,6 @@ cleanup:
void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y)
{
mbedtls_mpi T;
MPI_VALIDATE(X != NULL);
MPI_VALIDATE(Y != NULL);
memcpy(&T, X, sizeof(mbedtls_mpi));
memcpy(X, Y, sizeof(mbedtls_mpi));
@ -385,7 +364,6 @@ static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z)
int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MPI_VALIDATE_RET(X != NULL);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1));
memset(X->p, 0, X->n * ciL);
@ -403,8 +381,6 @@ cleanup:
*/
int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos)
{
MPI_VALIDATE_RET(X != NULL);
if (X->n * biL <= pos) {
return 0;
}
@ -420,7 +396,6 @@ int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val)
int ret = 0;
size_t off = pos / biL;
size_t idx = pos % biL;
MPI_VALIDATE_RET(X != NULL);
if (val != 0 && val != 1) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -448,7 +423,6 @@ cleanup:
size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
{
size_t i;
MBEDTLS_INTERNAL_VALIDATE_RET(X != NULL, 0);
#if defined(__has_builtin)
#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)
@ -530,8 +504,6 @@ int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s)
int sign = 1;
mbedtls_mpi_uint d;
mbedtls_mpi T;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(s != NULL);
if (radix < 2 || radix > 16) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -634,9 +606,6 @@ int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,
size_t n;
char *p;
mbedtls_mpi T;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(olen != NULL);
MPI_VALIDATE_RET(buflen == 0 || buf != NULL);
if (radix < 2 || radix > 16) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -726,9 +695,6 @@ int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin)
*/
char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(fin != NULL);
if (radix < 2 || radix > 16) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
@ -772,7 +738,6 @@ int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE
* newline characters and '\0'
*/
char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
MPI_VALIDATE_RET(X != NULL);
if (radix < 2 || radix > 16) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -844,9 +809,6 @@ int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buf
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const size_t limbs = CHARS_TO_LIMBS(buflen);
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(buflen == 0 || buf != NULL);
/* Ensure that target MPI has exactly the necessary number of limbs */
MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
@ -887,7 +849,6 @@ int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
MPI_VALIDATE_RET(X != NULL);
i = mbedtls_mpi_bitlen(X) + count;
@ -908,7 +869,6 @@ cleanup:
*/
int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)
{
MPI_VALIDATE_RET(X != NULL);
if (X->n != 0) {
mbedtls_mpi_core_shift_r(X->p, X->n, count);
}
@ -921,8 +881,6 @@ int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)
int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)
{
size_t i, j;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
for (i = X->n; i > 0; i--) {
if (X->p[i - 1] != 0) {
@ -964,8 +922,6 @@ int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)
int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y)
{
size_t i, j;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
for (i = X->n; i > 0; i--) {
if (X->p[i - 1] != 0) {
@ -1016,7 +972,6 @@ int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)
{
mbedtls_mpi Y;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET(X != NULL);
*p = mpi_sint_abs(z);
Y.s = TO_SIGN(z);
@ -1035,9 +990,6 @@ int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
size_t j;
mbedtls_mpi_uint *p;
mbedtls_mpi_uint c;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
if (X == B) {
const mbedtls_mpi *T = A; A = X; B = T;
@ -1098,9 +1050,6 @@ int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
mbedtls_mpi_uint carry;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
for (n = B->n; n > 0; n--) {
if (B->p[n - 1] != 0) {
@ -1152,9 +1101,6 @@ static int add_sub_mpi(mbedtls_mpi *X,
int flip_B)
{
int ret, s;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
s = A->s;
if (A->s * B->s * flip_B < 0) {
@ -1203,8 +1149,6 @@ int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b
{
mbedtls_mpi B;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = TO_SIGN(b);
@ -1221,8 +1165,6 @@ int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b
{
mbedtls_mpi B;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = TO_SIGN(b);
@ -1241,9 +1183,6 @@ int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
size_t i, j;
mbedtls_mpi TA, TB;
int result_is_zero = 0;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
mbedtls_mpi_init(&TA);
mbedtls_mpi_init(&TB);
@ -1300,9 +1239,6 @@ cleanup:
*/
int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b)
{
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
size_t n = A->n;
while (n > 0 && A->p[n - 1] == 0) {
--n;
@ -1448,8 +1384,6 @@ int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
size_t i, n, t, k;
mbedtls_mpi X, Y, Z, T1, T2;
mbedtls_mpi_uint TP2[3];
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
if (mbedtls_mpi_cmp_int(B, 0) == 0) {
return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
@ -1572,7 +1506,6 @@ int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
{
mbedtls_mpi B;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = TO_SIGN(b);
@ -1588,9 +1521,6 @@ int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MPI_VALIDATE_RET(R != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
if (mbedtls_mpi_cmp_int(B, 0) < 0) {
return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
@ -1618,8 +1548,6 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s
{
size_t i;
mbedtls_mpi_uint x, y, z;
MPI_VALIDATE_RET(r != NULL);
MPI_VALIDATE_RET(A != NULL);
if (b == 0) {
return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
@ -1763,11 +1691,6 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
mbedtls_mpi RR, T, W[(size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE], WW, Apos;
int neg;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(E != NULL);
MPI_VALIDATE_RET(N != NULL);
if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
@ -2054,10 +1977,6 @@ int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
size_t lz, lzt;
mbedtls_mpi TA, TB;
MPI_VALIDATE_RET(G != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL);
mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));
@ -2168,9 +2087,6 @@ int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const size_t limbs = CHARS_TO_LIMBS(size);
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(f_rng != NULL);
/* Ensure that target MPI has exactly the necessary number of limbs */
MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
if (size == 0) {
@ -2214,9 +2130,6 @@ int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(N != NULL);
if (mbedtls_mpi_cmp_int(N, 1) <= 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@ -2372,9 +2285,6 @@ static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds,
size_t i, j, k, s;
mbedtls_mpi W, R, T, A, RR;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(f_rng != NULL);
mbedtls_mpi_init(&W); mbedtls_mpi_init(&R);
mbedtls_mpi_init(&T); mbedtls_mpi_init(&A);
mbedtls_mpi_init(&RR);
@ -2462,8 +2372,6 @@ int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi XX;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(f_rng != NULL);
XX.s = 1;
XX.n = X->n;
@ -2513,9 +2421,6 @@ int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
mbedtls_mpi_uint r;
mbedtls_mpi Y;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(f_rng != NULL);
if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}

View file

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

172
library/debug_internal.h Normal file
View file

@ -0,0 +1,172 @@
/**
* \file debug_internal.h
*
* \brief Internal part of the public "debug.h".
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_DEBUG_INTERNAL_H
#define MBEDTLS_DEBUG_INTERNAL_H
#include "mbedtls/debug.h"
/**
* \brief Print a message to the debug output. This function is always used
* through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
* context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the message has occurred in
* \param line line number the message has occurred at
* \param format format specifier, in printf format
* \param ... variables used by the format specifier
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6);
/**
* \brief Print the return value of a function to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text the name of the function that returned the error
* \param ret the return code value
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret);
/**
* \brief Output a buffer of size len bytes to the debug output. This function
* is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the buffer being dumped. Normally the
* variable or buffer name
* \param buf the buffer to be outputted
* \param len length of the buffer
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text,
const unsigned char *buf, size_t len);
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Print a MPI variable to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the MPI being output. Normally the
* variable name
* \param X the MPI variable
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X);
#endif
#if defined(MBEDTLS_ECP_LIGHT)
/**
* \brief Print an ECP point to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the ECP point being output. Normally the
* variable name
* \param X the ECP point
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_ecp_point *X);
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
/**
* \brief Print a X.509 certificate structure to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the certificate being output
* \param crt X.509 certificate structure
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_x509_crt *crt);
#endif
/* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function
only works for the built-in implementation. */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \
defined(MBEDTLS_ECDH_C)
typedef enum {
MBEDTLS_DEBUG_ECDH_Q,
MBEDTLS_DEBUG_ECDH_QP,
MBEDTLS_DEBUG_ECDH_Z,
} mbedtls_debug_ecdh_attr;
/**
* \brief Print a field of the ECDH structure in the SSL context to the debug
* output. This function is always used through the
* MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
* and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param ecdh the ECDH context
* \param attr the identifier of the attribute being output
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const mbedtls_ecdh_context *ecdh,
mbedtls_debug_ecdh_attr attr);
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
MBEDTLS_ECDH_C */
#endif /* MBEDTLS_DEBUG_INTERNAL_H */

View file

@ -23,12 +23,6 @@
#if !defined(MBEDTLS_ECP_ALT)
/* Parameter validation macros based on platform_util.h */
#define ECP_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA)
#define ECP_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) }
#define ECP_MPI_INIT_ARRAY(x) \
@ -52,7 +46,7 @@
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
/* For these curves, we build the group parameters dynamically. */
#define ECP_LOAD_GROUP
static mbedtls_mpi_uint mpi_one[] = { 1 };
static const mbedtls_mpi_uint mpi_one[] = { 1 };
#endif
/*
@ -4511,7 +4505,7 @@ static inline void ecp_mpi_set1(mbedtls_mpi *X)
{
X->s = 1;
X->n = 1;
X->p = mpi_one;
X->p = (mbedtls_mpi_uint *) mpi_one; /* X->p will not be modified so the cast is safe */
}
/*
@ -4722,7 +4716,6 @@ cleanup:
*/
int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
{
ECP_VALIDATE_RET(grp != NULL);
mbedtls_ecp_group_free(grp);
mbedtls_ecp_group_init(grp);
@ -5318,7 +5311,7 @@ cleanup:
*/
#define P_KOBLITZ_MAX (256 / 8 / sizeof(mbedtls_mpi_uint)) // Max limbs in P
#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R
static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
static inline int ecp_mod_koblitz(mbedtls_mpi *N, const mbedtls_mpi_uint *Rp, size_t p_limbs,
size_t adjust, size_t shift, mbedtls_mpi_uint mask)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -5332,7 +5325,7 @@ static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p
/* Init R */
R.s = 1;
R.p = Rp;
R.p = (mbedtls_mpi_uint *) Rp; /* R.p will not be modified so the cast is safe */
R.n = P_KOBLITZ_R;
/* Common setup for M */
@ -5403,7 +5396,7 @@ cleanup:
*/
static int ecp_mod_p192k1(mbedtls_mpi *N)
{
static mbedtls_mpi_uint Rp[] = {
static const mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
};
@ -5420,7 +5413,7 @@ static int ecp_mod_p192k1(mbedtls_mpi *N)
*/
static int ecp_mod_p224k1(mbedtls_mpi *N)
{
static mbedtls_mpi_uint Rp[] = {
static const mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
};
@ -5442,7 +5435,7 @@ static int ecp_mod_p224k1(mbedtls_mpi *N)
*/
static int ecp_mod_p256k1(mbedtls_mpi *N)
{
static mbedtls_mpi_uint Rp[] = {
static const mbedtls_mpi_uint Rp[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00)
};

View file

@ -28,12 +28,6 @@
#if !defined(MBEDTLS_ECP_ALT)
/* Parameter validation macros based on platform_util.h */
#define ECP_VALIDATE_RET(cond) \
MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA)
#define ECP_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) }
#define ECP_MPI_INIT_ARRAY(x) \
@ -4764,7 +4758,6 @@ cleanup:
*/
int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
{
ECP_VALIDATE_RET(grp != NULL);
mbedtls_ecp_group_free(grp);
mbedtls_ecp_group_init(grp);

View file

@ -5,7 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#if defined(__linux__) && !defined(_GNU_SOURCE)
#if defined(__linux__) || defined(__midipix__) && !defined(_GNU_SOURCE)
/* Ensure that syscall() is available even when compiling with -std=c99 */
#define _GNU_SOURCE
#endif

View file

@ -354,9 +354,17 @@ int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
{
const unsigned char *p;
size_t use_len, offset;
uint64_t new_add_len;
/* IV is limited to 2^64 bits, so 2^61 bytes */
if ((uint64_t) add_len >> 61 != 0) {
/* AD is limited to 2^64 bits, ie 2^61 bytes
* Also check for possible overflow */
#if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL
if (add_len > 0xFFFFFFFFFFFFFFFFULL) {
return MBEDTLS_ERR_GCM_BAD_INPUT;
}
#endif
new_add_len = ctx->add_len + (uint64_t) add_len;
if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
return MBEDTLS_ERR_GCM_BAD_INPUT;
}
@ -539,6 +547,9 @@ int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
(void) output_size;
*output_length = 0;
/* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
* and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of
* the two multiplications would overflow. */
orig_len = ctx->len * 8;
orig_add_len = ctx->add_len * 8;

View file

@ -683,6 +683,18 @@ static const oid_cipher_alg_t oid_cipher_alg[] =
OID_DESCRIPTOR(MBEDTLS_OID_DES_EDE3_CBC, "des-ede3-cbc", "DES-EDE3-CBC"),
MBEDTLS_CIPHER_DES_EDE3_CBC,
},
{
OID_DESCRIPTOR(MBEDTLS_OID_AES_128_CBC, "aes128-cbc", "AES128-CBC"),
MBEDTLS_CIPHER_AES_128_CBC,
},
{
OID_DESCRIPTOR(MBEDTLS_OID_AES_192_CBC, "aes192-cbc", "AES192-CBC"),
MBEDTLS_CIPHER_AES_192_CBC,
},
{
OID_DESCRIPTOR(MBEDTLS_OID_AES_256_CBC, "aes256-cbc", "AES256-CBC"),
MBEDTLS_CIPHER_AES_256_CBC,
},
{
NULL_OID_DESCRIPTOR,
MBEDTLS_CIPHER_NONE,

View file

@ -29,7 +29,7 @@
#include "mbedtls/ecdsa.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include "psa_util_internal.h"
#include "mbedtls/psa_util.h"
#endif
@ -378,6 +378,209 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PSA_CRYPTO_C)
#if defined(MBEDTLS_RSA_C)
static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa,
int want_crypt)
{
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
if (want_crypt) {
mbedtls_md_type_t md_type = mbedtls_rsa_get_md_alg(rsa);
return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type));
} else {
return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH);
}
} else {
if (want_crypt) {
return PSA_ALG_RSA_PKCS1V15_CRYPT;
} else {
return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH);
}
}
}
#endif /* MBEDTLS_RSA_C */
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
psa_key_usage_t usage,
psa_key_attributes_t *attributes)
{
mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
psa_key_usage_t more_usage = usage;
if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) {
more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
} else if (usage == PSA_KEY_USAGE_SIGN_HASH) {
more_usage |= PSA_KEY_USAGE_VERIFY_HASH;
} else if (usage == PSA_KEY_USAGE_DECRYPT) {
more_usage |= PSA_KEY_USAGE_ENCRYPT;
}
more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE ||
usage == PSA_KEY_USAGE_VERIFY_HASH ||
usage == PSA_KEY_USAGE_ENCRYPT);
switch (pk_type) {
#if defined(MBEDTLS_RSA_C)
case MBEDTLS_PK_RSA:
{
int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
/* Nothing to do. */
break;
case PSA_KEY_USAGE_DECRYPT:
case PSA_KEY_USAGE_ENCRYPT:
want_crypt = 1;
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
/* Detect the presence of a private key in a way that works both
* in CRT and non-CRT configurations. */
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
int has_private = (mbedtls_rsa_check_privkey(rsa) == 0);
if (want_private && !has_private) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, (want_private ?
PSA_KEY_TYPE_RSA_KEY_PAIR :
PSA_KEY_TYPE_RSA_PUBLIC_KEY));
psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk));
psa_set_key_algorithm(attributes,
psa_algorithm_for_rsa(rsa, want_crypt));
break;
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
{
int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH);
int derive_ok = (pk_type != MBEDTLS_PK_ECDSA);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_ecc_family_t family = pk->ec_family;
size_t bits = pk->ec_bits;
int has_private = 0;
if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) {
has_private = 1;
}
#else
const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
int has_private = (ec->d.n != 0);
size_t bits = 0;
psa_ecc_family_t family =
mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
#endif
psa_algorithm_t alg = 0;
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
if (!sign_ok) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH);
#else
alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH);
#endif
break;
case PSA_KEY_USAGE_DERIVE:
alg = PSA_ALG_ECDH;
if (!derive_ok) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
if (want_private && !has_private) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, (want_private ?
PSA_KEY_TYPE_ECC_KEY_PAIR(family) :
PSA_KEY_TYPE_ECC_PUBLIC_KEY(family)));
psa_set_key_bits(attributes, bits);
psa_set_key_algorithm(attributes, alg);
break;
}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
case MBEDTLS_PK_RSA_ALT:
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
case MBEDTLS_PK_OPAQUE:
{
psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_get_key_attributes(pk->priv_id, &old_attributes);
if (status != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_key_type_t old_type = psa_get_key_type(&old_attributes);
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) ||
old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
case PSA_KEY_USAGE_DECRYPT:
case PSA_KEY_USAGE_ENCRYPT:
if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
case PSA_KEY_USAGE_DERIVE:
if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_key_type_t new_type = old_type;
/* Opaque keys are always key pairs, so we don't need a check
* on the input if the required usage is private. We just need
* to adjust the type correctly if the required usage is public. */
if (!want_private) {
new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type);
}
more_usage = psa_get_key_usage_flags(&old_attributes);
if ((usage & more_usage) == 0) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, new_type);
psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes));
psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes));
break;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
default:
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_set_key_usage_flags(attributes, more_usage);
psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE);
return 0;
}
#endif /* MBEDTLS_PSA_CRYPTO_C */
/*
* Helper for mbedtls_pk_sign and mbedtls_pk_verify
*/

View file

@ -144,4 +144,8 @@ MBEDTLS_STATIC_TESTABLE int mbedtls_pk_parse_key_pkcs8_encrypted_der(
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
#endif
#if defined(MBEDTLS_FS_IO)
int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n);
#endif
#endif /* MBEDTLS_PK_INTERNAL_H */

View file

@ -29,9 +29,11 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa_util_internal.h"
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_RSA_C)
#include "pkwrite.h"
#include "rsa_internal.h"
#endif
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
@ -69,9 +71,9 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
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;
mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
unsigned char *p = buf + sizeof(buf);
psa_algorithm_t psa_alg_md =
PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
size_t rsa_len = mbedtls_rsa_get_len(rsa);
@ -86,11 +88,7 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
return MBEDTLS_ERR_RSA_VERIFY_FAILED;
}
/* mbedtls_pk_write_pubkey_der() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &mbedtls_rsa_info;
key.pk_ctx = rsa;
key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@ -172,14 +170,15 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
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;
mbedtls_pk_context key;
int key_len;
unsigned char *buf = NULL;
unsigned char *p;
buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
if (buf == NULL) {
return MBEDTLS_ERR_PK_ALLOC_FAILED;
}
mbedtls_pk_info_t pk_info = mbedtls_rsa_info;
p = buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES;
*sig_len = mbedtls_rsa_get_len(rsa_ctx);
if (sig_size < *sig_len) {
@ -187,11 +186,7 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
}
/* mbedtls_pk_write_key_der() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &pk_info;
key.pk_ctx = rsa_ctx;
key_len = mbedtls_pk_write_key_der(&key, buf, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
key_len = mbedtls_rsa_write_key(rsa_ctx, buf, &p);
if (key_len <= 0) {
mbedtls_free(buf);
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@ -282,9 +277,9 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
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;
mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
unsigned char *p = buf + sizeof(buf);
((void) f_rng);
((void) p_rng);
@ -299,11 +294,7 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
/* mbedtls_pk_write_key_der() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &mbedtls_rsa_info;
key.pk_ctx = rsa;
key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf));
key_len = mbedtls_rsa_write_key(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@ -368,9 +359,9 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
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;
mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
unsigned char *p = buf + sizeof(buf);
((void) f_rng);
((void) p_rng);
@ -385,11 +376,7 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
}
/* mbedtls_pk_write_pubkey_der() expects a full PK context;
* re-construct one to make it happy */
key.pk_info = &mbedtls_rsa_info;
key.pk_ctx = rsa;
key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@ -536,66 +523,6 @@ static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
* those integers and convert it to the fixed-length encoding expected by PSA.
*/
static int extract_ecdsa_sig_int(unsigned char **from, const unsigned char *end,
unsigned char *to, size_t to_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t unpadded_len, padding_len;
if ((ret = mbedtls_asn1_get_tag(from, end, &unpadded_len,
MBEDTLS_ASN1_INTEGER)) != 0) {
return ret;
}
while (unpadded_len > 0 && **from == 0x00) {
(*from)++;
unpadded_len--;
}
if (unpadded_len > to_len || unpadded_len == 0) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
padding_len = to_len - unpadded_len;
memset(to, 0x00, padding_len);
memcpy(to + padding_len, *from, unpadded_len);
(*from) += unpadded_len;
return 0;
}
/*
* Convert a signature from an ASN.1 sequence of two integers
* to a raw {r,s} buffer. Note: the provided sig buffer must be at least
* twice as big as int_size.
*/
static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end,
unsigned char *sig, size_t int_size)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t tmp_size;
if ((ret = mbedtls_asn1_get_tag(p, end, &tmp_size,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return ret;
}
/* Extract r */
if ((ret = extract_ecdsa_sig_int(p, end, sig, int_size)) != 0) {
return ret;
}
/* Extract s */
if ((ret = extract_ecdsa_sig_int(p, end, sig + int_size, int_size)) != 0) {
return ret;
}
return 0;
}
/* Common helper for ECDSA verify using PSA functions. */
static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
psa_ecc_family_t curve, size_t curve_bits,
@ -607,6 +534,7 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
size_t converted_sig_len;
unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
unsigned char *p;
psa_status_t status;
@ -631,11 +559,14 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
}
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, extracted_sig,
signature_len/2)) != 0) {
ret = mbedtls_ecdsa_der_to_raw(curve_bits, p, sig_len, extracted_sig,
sizeof(extracted_sig), &converted_sig_len);
if (ret != 0) {
goto cleanup;
}
if (converted_sig_len != signature_len) {
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
goto cleanup;
}
@ -646,10 +577,6 @@ static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
goto cleanup;
}
if (p != sig + sig_len) {
ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
goto cleanup;
}
ret = 0;
cleanup:
@ -751,90 +678,6 @@ static int ecdsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* Simultaneously convert and move raw MPI from the beginning of a buffer
* to an ASN.1 MPI at the end of the buffer.
* See also mbedtls_asn1_write_mpi().
*
* p: pointer to the end of the output buffer
* start: start of the output buffer, and also of the mpi to write at the end
* n_len: length of the mpi to read from start
*/
static int asn1_write_mpibuf(unsigned char **p, unsigned char *start,
size_t n_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if ((size_t) (*p - start) < n_len) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
len = n_len;
*p -= len;
memmove(*p, start, len);
/* ASN.1 DER encoding requires minimal length, so skip leading 0s.
* Neither r nor s should be 0, but as a failsafe measure, still detect
* that rather than overflowing the buffer in case of a PSA error. */
while (len > 0 && **p == 0x00) {
++(*p);
--len;
}
/* this is only reached if the signature was invalid */
if (len == 0) {
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
}
/* if the msb is 1, ASN.1 requires that we prepend a 0.
* Neither r nor s can be 0, so we can assume len > 0 at all times. */
if (**p & 0x80) {
if (*p - start < 1) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
*--(*p) = 0x00;
len += 1;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
MBEDTLS_ASN1_INTEGER));
return (int) len;
}
/* Transcode signature from PSA format to ASN.1 sequence.
* See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
* MPIs, and in-place.
*
* [in/out] sig: the signature pre- and post-transcoding
* [in/out] sig_len: signature length pre- and post-transcoding
* [int] buf_len: the available size the in/out buffer
*/
static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len,
size_t buf_len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
const size_t rs_len = *sig_len / 2;
unsigned char *p = sig + buf_len;
MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig + rs_len, rs_len));
MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig, rs_len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, sig, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, sig,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
memmove(sig, p, len);
*sig_len = len;
return 0;
}
/* Common helper for ECDSA sign using PSA functions.
* Instead of extracting key's properties in order to check which kind of ECDSA
* signature it supports, we try both deterministic and non-deterministic.
@ -845,6 +688,15 @@ static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
size_t key_bits = 0;
status = psa_get_key_attributes(key_id, &key_attr);
if (status != PSA_SUCCESS) {
return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
}
key_bits = psa_get_key_bits(&key_attr);
psa_reset_key_attributes(&key_attr);
status = psa_sign_hash(key_id,
PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
@ -863,7 +715,7 @@ static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
}
done:
ret = pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size);
ret = mbedtls_ecdsa_raw_to_der(key_bits, sig, *sig_len, sig, sig_size, sig_len);
return ret;
}

View file

@ -7,7 +7,7 @@
#include "mbedtls/build_info.h"
#if defined(MBEDTLS_PKCS7_C)
#include "mbedtls/pkcs7.h"
#include "mbedtls/x509.h"
#include "x509_internal.h"
#include "mbedtls/asn1.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/x509_crl.h"

View file

@ -28,6 +28,7 @@
/* Key types */
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#include "rsa_internal.h"
#endif
/* Extended formats */
@ -757,68 +758,6 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
static int pk_get_rsapubkey(unsigned char **p,
const unsigned char *end,
mbedtls_rsa_context *rsa)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
}
if (*p + len != end) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
/* Import N */
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
}
if ((ret = mbedtls_rsa_import_raw(rsa, *p, len, NULL, 0, NULL, 0,
NULL, 0, NULL, 0)) != 0) {
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
}
*p += len;
/* Import E */
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
}
if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, *p, len)) != 0) {
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
}
*p += len;
if (mbedtls_rsa_complete(rsa) != 0 ||
mbedtls_rsa_check_pubkey(rsa) != 0) {
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
}
if (*p != end) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
return 0;
}
#endif /* MBEDTLS_RSA_C */
/* Get a PK algorithm identifier
*
* AlgorithmIdentifier ::= SEQUENCE {
@ -911,7 +850,17 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
#if defined(MBEDTLS_RSA_C)
if (pk_alg == MBEDTLS_PK_RSA) {
ret = pk_get_rsapubkey(p, end, mbedtls_pk_rsa(*pk));
ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), *p, (size_t) (end - *p));
if (ret == 0) {
/* On success all the input has been consumed by the parsing function. */
*p += end - *p;
} else if ((ret <= MBEDTLS_ERR_ASN1_OUT_OF_DATA) &&
(ret >= MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)) {
/* In case of ASN1 error codes add MBEDTLS_ERR_PK_INVALID_PUBKEY. */
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
} else {
ret = MBEDTLS_ERR_PK_INVALID_PUBKEY;
}
} else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
@ -944,195 +893,6 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
return ret;
}
#if defined(MBEDTLS_RSA_C)
/*
* Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
*
* The value zero is:
* - never a valid value for an RSA parameter
* - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
*
* Since values can't be omitted in PKCS#1, passing a zero value to
* rsa_complete() would be incorrect, so reject zero values early.
*/
static int asn1_get_nonzero_mpi(unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X)
{
int ret;
ret = mbedtls_asn1_get_mpi(p, end, X);
if (ret != 0) {
return ret;
}
if (mbedtls_mpi_cmp_int(X, 0) == 0) {
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
return 0;
}
/*
* Parse a PKCS#1 encoded private RSA key
*/
static int pk_parse_key_pkcs1_der(mbedtls_rsa_context *rsa,
const unsigned char *key,
size_t keylen)
{
int ret, version;
size_t len;
unsigned char *p, *end;
mbedtls_mpi T;
mbedtls_mpi_init(&T);
p = (unsigned char *) key;
end = p + keylen;
/*
* This function parses the RSAPrivateKey (PKCS#1)
*
* RSAPrivateKey ::= SEQUENCE {
* version Version,
* modulus INTEGER, -- n
* publicExponent INTEGER, -- e
* privateExponent INTEGER, -- d
* prime1 INTEGER, -- p
* prime2 INTEGER, -- q
* exponent1 INTEGER, -- d mod (p-1)
* exponent2 INTEGER, -- d mod (q-1)
* coefficient INTEGER, -- (inverse of q) mod p
* otherPrimeInfos OtherPrimeInfos OPTIONAL
* }
*/
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
end = p + len;
if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
if (version != 0) {
return MBEDTLS_ERR_PK_KEY_INVALID_VERSION;
}
/* Import N */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, &T, NULL, NULL,
NULL, NULL)) != 0) {
goto cleanup;
}
/* Import E */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
NULL, &T)) != 0) {
goto cleanup;
}
/* Import D */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
&T, NULL)) != 0) {
goto cleanup;
}
/* Import P */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, &T, NULL,
NULL, NULL)) != 0) {
goto cleanup;
}
/* Import Q */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, &T,
NULL, NULL)) != 0) {
goto cleanup;
}
#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
/*
* The RSA CRT parameters DP, DQ and QP are nominally redundant, in
* that they can be easily recomputed from D, P and Q. However by
* parsing them from the PKCS1 structure it is possible to avoid
* recalculating them which both reduces the overhead of loading
* RSA private keys into memory and also avoids side channels which
* can arise when computing those values, since all of D, P, and Q
* are secret. See https://eprint.iacr.org/2020/055 for a
* description of one such attack.
*/
/* Import DP */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) {
goto cleanup;
}
/* Import DQ */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) {
goto cleanup;
}
/* Import QP */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) {
goto cleanup;
}
#else
/* Verify existence of the CRT params */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) {
goto cleanup;
}
#endif
/* rsa_complete() doesn't complete anything with the default
* implementation but is still called:
* - for the benefit of alternative implementation that may want to
* pre-compute stuff beyond what's provided (eg Montgomery factors)
* - as is also sanity-checks the key
*
* Furthermore, we also check the public part for consistency with
* mbedtls_pk_parse_pubkey(), as it includes size minima for example.
*/
if ((ret = mbedtls_rsa_complete(rsa)) != 0 ||
(ret = mbedtls_rsa_check_pubkey(rsa)) != 0) {
goto cleanup;
}
if (p != end) {
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
cleanup:
mbedtls_mpi_free(&T);
if (ret != 0) {
/* Wrap error code if it's coming from a lower level */
if ((ret & 0xff80) == 0) {
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
} else {
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
mbedtls_rsa_free(rsa);
}
return ret;
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
/*
* Parse a SEC1 encoded private EC key
@ -1348,7 +1108,7 @@ static int pk_parse_key_pkcs8_unencrypted_der(
#if defined(MBEDTLS_RSA_C)
if (pk_alg == MBEDTLS_PK_RSA) {
if ((ret = pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), p, len)) != 0) {
if ((ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), p, len)) != 0) {
mbedtls_pk_free(pk);
return ret;
}
@ -1538,8 +1298,8 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
if (ret == 0) {
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 ||
(ret = pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk),
pem.buf, pem.buflen)) != 0) {
(ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk),
pem.buf, pem.buflen)) != 0) {
mbedtls_pk_free(pk);
}
@ -1679,7 +1439,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
if (mbedtls_pk_setup(pk, pk_info) == 0 &&
pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), key, keylen) == 0) {
mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), key, keylen) == 0) {
return 0;
}
@ -1754,7 +1514,7 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
return ret;
}
if ((ret = pk_get_rsapubkey(&p, p + pem.buflen, mbedtls_pk_rsa(*ctx))) != 0) {
if ((ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, pem.buflen)) != 0) {
mbedtls_pk_free(ctx);
}
@ -1801,13 +1561,12 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
}
p = (unsigned char *) key;
ret = pk_get_rsapubkey(&p, p + keylen, mbedtls_pk_rsa(*ctx));
ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, keylen);
if (ret == 0) {
return ret;
}
mbedtls_pk_free(ctx);
if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG))) {
if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
return ret;
}
#endif /* MBEDTLS_RSA_C */

View file

@ -32,6 +32,9 @@
#if defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
#endif
#if defined(MBEDTLS_RSA_C)
#include "rsa_internal.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
@ -56,60 +59,13 @@
* Internal functions for RSA keys.
******************************************************************************/
#if defined(MBEDTLS_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
static int pk_write_rsa_pubkey(unsigned char **p, unsigned char *start,
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);
/* Export E */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export N */
if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
end_of_export:
mbedtls_mpi_free(&T);
if (ret < 0) {
return ret;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
return (int) len;
}
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;
size_t len = 0, tmp_len = 0;
if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@ -118,94 +74,11 @@ static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
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(*pk);
/*
* Export the parameters one after another to avoid simultaneous copies.
*/
mbedtls_mpi_init(&T);
/* Export QP */
if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &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(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(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export Q */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
&T, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export P */
if ((ret = mbedtls_rsa_export(rsa, NULL, &T,
NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export D */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
NULL, &T, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export E */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export N */
if ((ret = mbedtls_rsa_export(rsa, &T, NULL,
NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
end_of_export:
mbedtls_mpi_free(&T);
if (ret < 0) {
return ret;
}
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;
}
return (int) len;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), buf, p);
}
#endif /* MBEDTLS_RSA_C */
@ -543,7 +416,7 @@ 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, key));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*key), start, p));
} else
#endif
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)

View file

@ -93,8 +93,6 @@ static void *(*const volatile memset_func)(void *, int, size_t) = memset;
void mbedtls_platform_zeroize(void *buf, size_t len)
{
MBEDTLS_INTERNAL_VALIDATE(len == 0 || buf != NULL);
if (len > 0) {
#if defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO)
explicit_bzero(buf, len);
@ -151,10 +149,10 @@ void mbedtls_zeroize_and_free(void *buf, size_t len)
#include <time.h>
#if !defined(_WIN32) && (defined(unix) || \
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
defined(__MACH__)))
defined(__MACH__)) || defined__midipix__)
#include <unistd.h>
#endif /* !_WIN32 && (unix || __unix || __unix__ ||
* (__APPLE__ && __MACH__)) */
* (__APPLE__ && __MACH__) || __midipix__) */
#if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \
(defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
@ -222,9 +220,10 @@ void (*mbedtls_test_hook_test_fail)(const char *, int, const char *);
#include <time.h>
#if !defined(_WIN32) && \
(defined(unix) || defined(__unix) || defined(__unix__) || \
(defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__))
(defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) || defined(__midipix__))
#include <unistd.h>
#endif /* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__) */
#endif \
/* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__ || __midipix__) */
#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 199309L) || defined(__HAIKU__)
mbedtls_ms_time_t mbedtls_ms_time(void)
{
@ -232,7 +231,7 @@ mbedtls_ms_time_t mbedtls_ms_time(void)
struct timespec tv;
mbedtls_ms_time_t current_ms;
#if defined(__linux__) && defined(CLOCK_BOOTTIME)
#if defined(__linux__) && defined(CLOCK_BOOTTIME) || defined(__midipix__)
ret = clock_gettime(CLOCK_BOOTTIME, &tv);
#else
ret = clock_gettime(CLOCK_MONOTONIC, &tv);

View file

@ -129,12 +129,30 @@ int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg)
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
static int psa_is_dh_key_size_valid(size_t bits)
{
if (bits != 2048 && bits != 3072 && bits != 4096 &&
bits != 6144 && bits != 8192) {
return 0;
switch (bits) {
#if defined(PSA_WANT_DH_RFC7919_2048)
case 2048:
return 1;
#endif /* PSA_WANT_DH_RFC7919_2048 */
#if defined(PSA_WANT_DH_RFC7919_3072)
case 3072:
return 1;
#endif /* PSA_WANT_DH_RFC7919_3072 */
#if defined(PSA_WANT_DH_RFC7919_4096)
case 4096:
return 1;
#endif /* PSA_WANT_DH_RFC7919_4096 */
#if defined(PSA_WANT_DH_RFC7919_6144)
case 6144:
return 1;
#endif /* PSA_WANT_DH_RFC7919_6144 */
#if defined(PSA_WANT_DH_RFC7919_8192)
case 8192:
return 1;
#endif /* PSA_WANT_DH_RFC7919_8192 */
default:
return 0;
}
return 1;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT ||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
@ -577,7 +595,7 @@ psa_status_t psa_import_key_into_slot(
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
if (PSA_KEY_TYPE_IS_DH(type)) {
if (psa_is_dh_key_size_valid(PSA_BYTES_TO_BITS(data_length)) == 0) {
return PSA_ERROR_INVALID_ARGUMENT;
return PSA_ERROR_NOT_SUPPORTED;
}
return mbedtls_psa_ffdh_import_key(attributes,
data, data_length,
@ -6096,6 +6114,91 @@ static psa_status_t psa_hash_try_support(psa_algorithm_t alg)
return status;
}
static psa_status_t psa_key_derivation_set_maximum_capacity(
psa_key_derivation_operation_t *operation,
psa_algorithm_t kdf_alg)
{
#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
operation->capacity = PSA_HASH_LENGTH(PSA_ALG_SHA_256);
return PSA_SUCCESS;
}
#endif
#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128)
if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
#if (SIZE_MAX > UINT32_MAX)
operation->capacity = UINT32_MAX * (size_t) PSA_MAC_LENGTH(
PSA_KEY_TYPE_AES,
128U,
PSA_ALG_CMAC);
#else
operation->capacity = SIZE_MAX;
#endif
return PSA_SUCCESS;
}
#endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */
/* After this point, if kdf_alg is not valid then value of hash_alg may be
* invalid or meaningless but it does not affect this function */
psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(kdf_alg);
size_t hash_size = PSA_HASH_LENGTH(hash_alg);
if (hash_size == 0) {
return PSA_ERROR_NOT_SUPPORTED;
}
/* Make sure that hash_alg is a supported hash algorithm. Otherwise
* we might fail later, which is somewhat unfriendly and potentially
* risk-prone. */
psa_status_t status = psa_hash_try_support(hash_alg);
if (status != PSA_SUCCESS) {
return status;
}
#if defined(PSA_WANT_ALG_HKDF)
if (PSA_ALG_IS_HKDF(kdf_alg)) {
operation->capacity = 255 * hash_size;
} else
#endif
#if defined(PSA_WANT_ALG_HKDF_EXTRACT)
if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
operation->capacity = hash_size;
} else
#endif
#if defined(PSA_WANT_ALG_HKDF_EXPAND)
if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
operation->capacity = 255 * hash_size;
} else
#endif
#if defined(PSA_WANT_ALG_TLS12_PRF)
if (PSA_ALG_IS_TLS12_PRF(kdf_alg) &&
(hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) {
operation->capacity = SIZE_MAX;
} else
#endif
#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS)
if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg) &&
(hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) {
/* Master Secret is always 48 bytes
* https://datatracker.ietf.org/doc/html/rfc5246.html#section-8.1 */
operation->capacity = 48U;
} else
#endif
#if defined(PSA_WANT_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
#if (SIZE_MAX > UINT32_MAX)
operation->capacity = UINT32_MAX * hash_size;
#else
operation->capacity = SIZE_MAX;
#endif
} else
#endif /* PSA_WANT_ALG_PBKDF2_HMAC */
{
(void) hash_size;
status = PSA_ERROR_NOT_SUPPORTED;
}
return status;
}
static psa_status_t psa_key_derivation_setup_kdf(
psa_key_derivation_operation_t *operation,
psa_algorithm_t kdf_alg)
@ -6109,43 +6212,9 @@ static psa_status_t psa_key_derivation_setup_kdf(
return PSA_ERROR_NOT_SUPPORTED;
}
/* All currently supported key derivation algorithms (apart from
* ecjpake to pms and pbkdf2_aes_cmac_128) are based on a hash algorithm. */
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
size_t hash_size = PSA_HASH_LENGTH(hash_alg);
if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
hash_size = PSA_HASH_LENGTH(PSA_ALG_SHA_256);
} else if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
hash_size = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC);
} else {
if (hash_size == 0) {
return PSA_ERROR_NOT_SUPPORTED;
}
/* Make sure that hash_alg is a supported hash algorithm. Otherwise
* we might fail later, which is somewhat unfriendly and potentially
* risk-prone. */
psa_status_t status = psa_hash_try_support(hash_alg);
if (status != PSA_SUCCESS) {
return status;
}
}
if ((PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) &&
!(hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) {
return PSA_ERROR_NOT_SUPPORTED;
}
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg) ||
(kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS)) {
operation->capacity = hash_size;
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT ||
MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
operation->capacity = 255 * hash_size;
return PSA_SUCCESS;
psa_status_t status = psa_key_derivation_set_maximum_capacity(operation,
kdf_alg);
return status;
}
static psa_status_t psa_key_agreement_try_support(psa_algorithm_t alg)

View file

@ -10,6 +10,12 @@
#if defined(MBEDTLS_PSA_CRYPTO_C)
/* This header is only needed because it defines
* MBEDTLS_DHM_RFC7919_FFDHEXXXX_[P|G]_BIN symbols that are used in
* mbedtls_psa_ffdh_set_prime_generator(). Apart from that, this module
* only uses bignum functions for arithmetic. */
#include <mbedtls/dhm.h>
#include <psa/crypto.h>
#include "psa_crypto_core.h"
#include "psa_crypto_ffdh.h"
@ -35,58 +41,78 @@ static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size,
return PSA_ERROR_INVALID_ARGUMENT;
}
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048)
static const unsigned char dhm_P_2048[] =
MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN;
static const unsigned char dhm_P_3072[] =
MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
static const unsigned char dhm_P_4096[] =
MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
static const unsigned char dhm_P_6144[] =
MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN;
static const unsigned char dhm_P_8192[] =
MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN;
static const unsigned char dhm_G_2048[] =
MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072)
static const unsigned char dhm_P_3072[] =
MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
static const unsigned char dhm_G_3072[] =
MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096)
static const unsigned char dhm_P_4096[] =
MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
static const unsigned char dhm_G_4096[] =
MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144)
static const unsigned char dhm_P_6144[] =
MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN;
static const unsigned char dhm_G_6144[] =
MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192)
static const unsigned char dhm_P_8192[] =
MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN;
static const unsigned char dhm_G_8192[] =
MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
switch (key_size) {
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048)
case sizeof(dhm_P_2048):
dhm_P = dhm_P_2048;
dhm_G = dhm_G_2048;
dhm_size_P = sizeof(dhm_P_2048);
dhm_size_G = sizeof(dhm_G_2048);
break;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072)
case sizeof(dhm_P_3072):
dhm_P = dhm_P_3072;
dhm_G = dhm_G_3072;
dhm_size_P = sizeof(dhm_P_3072);
dhm_size_G = sizeof(dhm_G_3072);
break;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096)
case sizeof(dhm_P_4096):
dhm_P = dhm_P_4096;
dhm_G = dhm_G_4096;
dhm_size_P = sizeof(dhm_P_4096);
dhm_size_G = sizeof(dhm_G_4096);
break;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144)
case sizeof(dhm_P_6144):
dhm_P = dhm_P_6144;
dhm_G = dhm_G_6144;
dhm_size_P = sizeof(dhm_P_6144);
dhm_size_G = sizeof(dhm_G_6144);
break;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192)
case sizeof(dhm_P_8192):
dhm_P = dhm_P_8192;
dhm_G = dhm_G_8192;
dhm_size_P = sizeof(dhm_P_8192);
dhm_size_G = sizeof(dhm_G_8192);
break;
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
default:
return PSA_ERROR_INVALID_ARGUMENT;
}

View file

@ -10,7 +10,6 @@
#define PSA_CRYPTO_FFDH_H
#include <psa/crypto.h>
#include <mbedtls/dhm.h>
/** Perform a key agreement and return the FFDH shared secret.
*

View file

@ -24,8 +24,7 @@
#include <mbedtls/rsa.h>
#include <mbedtls/error.h>
#include <mbedtls/pk.h>
#include "pk_wrap.h"
#include "rsa_internal.h"
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
@ -62,50 +61,38 @@ psa_status_t mbedtls_psa_rsa_load_representation(
mbedtls_rsa_context **p_rsa)
{
psa_status_t status;
mbedtls_pk_context ctx;
size_t bits;
mbedtls_pk_init(&ctx);
*p_rsa = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
if (*p_rsa == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
mbedtls_rsa_init(*p_rsa);
/* Parse the data. */
if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
status = mbedtls_to_psa_error(
mbedtls_pk_parse_key(&ctx, data, data_length, NULL, 0,
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE));
status = mbedtls_to_psa_error(mbedtls_rsa_parse_key(*p_rsa, data, data_length));
} else {
status = mbedtls_to_psa_error(
mbedtls_pk_parse_public_key(&ctx, data, data_length));
status = mbedtls_to_psa_error(mbedtls_rsa_parse_pubkey(*p_rsa, data, data_length));
}
if (status != PSA_SUCCESS) {
goto exit;
}
/* We have something that the pkparse module recognizes. If it is a
* valid RSA key, store it. */
if (mbedtls_pk_get_type(&ctx) != MBEDTLS_PK_RSA) {
status = PSA_ERROR_INVALID_ARGUMENT;
goto exit;
}
/* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
* supports non-byte-aligned key sizes, but not well. For example,
* mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(mbedtls_pk_rsa(ctx)));
bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(*p_rsa));
if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) {
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
status = psa_check_rsa_key_byte_aligned(mbedtls_pk_rsa(ctx));
status = psa_check_rsa_key_byte_aligned(*p_rsa);
if (status != PSA_SUCCESS) {
goto exit;
}
/* Copy out the pointer to the RSA context, and reset the PK context
* such that pk_free doesn't free the RSA context we just grabbed. */
*p_rsa = mbedtls_pk_rsa(ctx);
ctx.pk_info = NULL;
exit:
mbedtls_pk_free(&ctx);
return status;
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
@ -168,20 +155,15 @@ psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type,
size_t *data_length)
{
int ret;
mbedtls_pk_context pk;
uint8_t *pos = data + data_size;
mbedtls_pk_init(&pk);
pk.pk_info = &mbedtls_rsa_info;
pk.pk_ctx = rsa;
uint8_t *end = data + data_size;
/* PSA Crypto API defines the format of an RSA key as a DER-encoded
* representation of the non-encrypted PKCS#1 RSAPrivateKey for a
* private key and of the RFC3279 RSAPublicKey for a public key. */
if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
ret = mbedtls_pk_write_key_der(&pk, data, data_size);
ret = mbedtls_rsa_write_key(rsa, data, &end);
} else {
ret = mbedtls_pk_write_pubkey(&pos, data, &pk);
ret = mbedtls_rsa_write_pubkey(rsa, data, &end);
}
if (ret < 0) {

View file

@ -8,14 +8,20 @@
#include "common.h"
/* This is needed for MBEDTLS_ERR_XXX macros */
#include <mbedtls/error.h>
#if defined(MBEDTLS_ASN1_WRITE_C)
#include <mbedtls/asn1write.h>
#include <psa/crypto_sizes.h>
#endif
#include "psa_util_internal.h"
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include <psa/crypto.h>
#include "psa_util_internal.h"
/* The following includes are needed for MBEDTLS_ERR_XXX macros */
#include <mbedtls/error.h>
#if defined(MBEDTLS_MD_LIGHT)
#include <mbedtls/md.h>
#endif
@ -331,3 +337,239 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
#endif /* MBEDTLS_PSA_CRYPTO_C */
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/**
* \brief Convert a single raw coordinate to DER ASN.1 format. The output der
* buffer is filled backward (i.e. starting from its end).
*
* \param raw_buf Buffer containing the raw coordinate to be
* converted.
* \param raw_len Length of raw_buf in bytes. This must be > 0.
* \param der_buf_start Pointer to the beginning of the buffer which
* will be filled with the DER converted data.
* \param der_buf_end End of the buffer used to store the DER output.
*
* \return On success, the amount of data (in bytes) written to
* the DER buffer.
* \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
* buffer is too small to contain all the converted data.
* \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
* coordinate is null (i.e. all zeros).
*
* \warning Raw and der buffer must not be overlapping.
*/
static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
unsigned char *der_buf_start,
unsigned char *der_buf_end)
{
unsigned char *p = der_buf_end;
int len;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* ASN.1 DER encoding requires minimal length, so skip leading 0s.
* Provided input MPIs should not be 0, but as a failsafe measure, still
* detect that and return error in case. */
while (*raw_buf == 0x00) {
++raw_buf;
--raw_len;
if (raw_len == 0) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
}
len = (int) raw_len;
/* Copy the raw coordinate to the end of der_buf. */
if ((p - der_buf_start) < len) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
p -= len;
memcpy(p, raw_buf, len);
/* If MSb is 1, ASN.1 requires that we prepend a 0. */
if (*p & 0x80) {
if ((p - der_buf_start) < 1) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
--p;
*p = 0x00;
++len;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
return len;
}
int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
unsigned char *der, size_t der_size, size_t *der_len)
{
unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
size_t len = 0;
unsigned char *p = der + der_size;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if (raw_len != (2 * coordinate_len)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
/* Since raw and der buffers might overlap, dump r and s before starting
* the conversion. */
memcpy(r, raw, coordinate_len);
memcpy(s, raw + coordinate_len, coordinate_len);
/* der buffer will initially be written starting from its end so we pick s
* first and then r. */
ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
if (ret < 0) {
return ret;
}
p -= ret;
len += ret;
ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
if (ret < 0) {
return ret;
}
p -= ret;
len += ret;
/* Add ASN.1 header (len + tag). */
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
/* memmove the content of der buffer to its beginnig. */
memmove(der, p, len);
*der_len = len;
return 0;
}
/**
* \brief Convert a single integer from ASN.1 DER format to raw.
*
* \param der Buffer containing the DER integer value to be
* converted.
* \param der_len Length of the der buffer in bytes.
* \param raw Output buffer that will be filled with the
* converted data. This should be at least
* coordinate_size bytes and it must be zeroed before
* calling this function.
* \param coordinate_size Size (in bytes) of a single coordinate in raw
* format.
*
* \return On success, the amount of DER data parsed from the
* provided der buffer.
* \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
* is missing in the der buffer.
* \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
* is null (i.e. all zeros) or if the output raw buffer
* is too small to contain the converted raw value.
*
* \warning Der and raw buffers must not be overlapping.
*/
static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
unsigned char *raw, size_t coordinate_size)
{
unsigned char *p = der;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t unpadded_len, padding_len = 0;
/* Get the length of ASN.1 element (i.e. the integer we need to parse). */
ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
MBEDTLS_ASN1_INTEGER);
if (ret != 0) {
return ret;
}
/* It's invalid to have:
* - unpadded_len == 0.
* - MSb set without a leading 0x00 (leading 0x00 is checked below). */
if (((unpadded_len == 0) || (*p & 0x80) != 0)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
/* Skip possible leading zero */
if (*p == 0x00) {
p++;
unpadded_len--;
/* It is not allowed to have more than 1 leading zero.
* Ignore the case in which unpadded_len = 0 because that's a 0 encoded
* in ASN.1 format (i.e. 020100). */
if ((unpadded_len > 0) && (*p == 0x00)) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
}
if (unpadded_len > coordinate_size) {
/* Parsed number is longer than the maximum expected value. */
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
padding_len = coordinate_size - unpadded_len;
/* raw buffer was already zeroed by the calling function so zero-padding
* operation is skipped here. */
memcpy(raw + padding_len, p, unpadded_len);
p += unpadded_len;
return (int) (p - der);
}
int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
unsigned char *raw, size_t raw_size, size_t *raw_len)
{
unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
unsigned char *p = (unsigned char *) der;
size_t data_len;
size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
int ret;
/* The output raw buffer should be at least twice the size of a raw
* coordinate in order to store r and s. */
if (raw_size < coordinate_size * 2) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
/* Check that the provided input DER buffer has the right header. */
ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
if (ret != 0) {
return ret;
}
memset(raw_tmp, 0, 2 * coordinate_size);
/* Extract r */
ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
if (ret < 0) {
return ret;
}
p += ret;
data_len -= ret;
/* Extract s */
ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
coordinate_size);
if (ret < 0) {
return ret;
}
p += ret;
data_len -= ret;
/* Check that we consumed all the input der data. */
if ((size_t) (p - der) != der_len) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
memcpy(raw, raw_tmp, 2 * coordinate_size);
*raw_len = 2 * coordinate_size;
return 0;
}
#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */

View file

@ -32,6 +32,7 @@
#include "rsa_alt_helpers.h"
#include "rsa_internal.h"
#include "mbedtls/oid.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "constant_time_internal.h"
@ -46,6 +47,367 @@
#include "mbedtls/platform.h"
/*
* Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
*
* The value zero is:
* - never a valid value for an RSA parameter
* - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
*
* Since values can't be omitted in PKCS#1, passing a zero value to
* rsa_complete() would be incorrect, so reject zero values early.
*/
static int asn1_get_nonzero_mpi(unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X)
{
int ret;
ret = mbedtls_asn1_get_mpi(p, end, X);
if (ret != 0) {
return ret;
}
if (mbedtls_mpi_cmp_int(X, 0) == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
return 0;
}
int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen)
{
int ret, version;
size_t len;
unsigned char *p, *end;
mbedtls_mpi T;
mbedtls_mpi_init(&T);
p = (unsigned char *) key;
end = p + keylen;
/*
* This function parses the RSAPrivateKey (PKCS#1)
*
* RSAPrivateKey ::= SEQUENCE {
* version Version,
* modulus INTEGER, -- n
* publicExponent INTEGER, -- e
* privateExponent INTEGER, -- d
* prime1 INTEGER, -- p
* prime2 INTEGER, -- q
* exponent1 INTEGER, -- d mod (p-1)
* exponent2 INTEGER, -- d mod (q-1)
* coefficient INTEGER, -- (inverse of q) mod p
* otherPrimeInfos OtherPrimeInfos OPTIONAL
* }
*/
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return ret;
}
/* mbedtls_asn1_get_tag() already ensures that len is valid (i.e. p+len <= end)*/
end = p + len;
if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
return ret;
}
if (version != 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
/* Import N */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, &T, NULL, NULL,
NULL, NULL)) != 0) {
goto cleanup;
}
/* Import E */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
NULL, &T)) != 0) {
goto cleanup;
}
/* Import D */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
&T, NULL)) != 0) {
goto cleanup;
}
/* Import P */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, &T, NULL,
NULL, NULL)) != 0) {
goto cleanup;
}
/* Import Q */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_rsa_import(rsa, NULL, NULL, &T,
NULL, NULL)) != 0) {
goto cleanup;
}
#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
/*
* The RSA CRT parameters DP, DQ and QP are nominally redundant, in
* that they can be easily recomputed from D, P and Q. However by
* parsing them from the PKCS1 structure it is possible to avoid
* recalculating them which both reduces the overhead of loading
* RSA private keys into memory and also avoids side channels which
* can arise when computing those values, since all of D, P, and Q
* are secret. See https://eprint.iacr.org/2020/055 for a
* description of one such attack.
*/
/* Import DP */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) {
goto cleanup;
}
/* Import DQ */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) {
goto cleanup;
}
/* Import QP */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) {
goto cleanup;
}
#else
/* Verify existence of the CRT params */
if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
(ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) {
goto cleanup;
}
#endif
/* rsa_complete() doesn't complete anything with the default
* implementation but is still called:
* - for the benefit of alternative implementation that may want to
* pre-compute stuff beyond what's provided (eg Montgomery factors)
* - as is also sanity-checks the key
*
* Furthermore, we also check the public part for consistency with
* mbedtls_pk_parse_pubkey(), as it includes size minima for example.
*/
if ((ret = mbedtls_rsa_complete(rsa)) != 0 ||
(ret = mbedtls_rsa_check_pubkey(rsa)) != 0) {
goto cleanup;
}
if (p != end) {
ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
cleanup:
mbedtls_mpi_free(&T);
if (ret != 0) {
mbedtls_rsa_free(rsa);
}
return ret;
}
int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen)
{
unsigned char *p = (unsigned char *) key;
unsigned char *end = (unsigned char *) (key + keylen);
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return ret;
}
/* mbedtls_asn1_get_tag() already ensures that len is valid (i.e. p+len <= end)*/
end = p + len;
/* Import N */
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
return ret;
}
if ((ret = mbedtls_rsa_import_raw(rsa, p, len, NULL, 0, NULL, 0,
NULL, 0, NULL, 0)) != 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
p += len;
/* Import E */
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
return ret;
}
if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, p, len)) != 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
p += len;
if (mbedtls_rsa_complete(rsa) != 0 ||
mbedtls_rsa_check_pubkey(rsa) != 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
if (p != end) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
return 0;
}
int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start,
unsigned char **p)
{
size_t len = 0;
int ret;
mbedtls_mpi T; /* Temporary holding the exported parameters */
/*
* Export the parameters one after another to avoid simultaneous copies.
*/
mbedtls_mpi_init(&T);
/* Export QP */
if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &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(p, start, &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(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export Q */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, &T, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export P */
if ((ret = mbedtls_rsa_export(rsa, NULL, &T, NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export D */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, &T, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export E */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export N */
if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
end_of_export:
mbedtls_mpi_free(&T);
if (ret < 0) {
return ret;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, start, 0));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
return (int) len;
}
/*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start,
unsigned char **p)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_mpi T;
mbedtls_mpi_init(&T);
/* Export E */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export N */
if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
(ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
goto end_of_export;
}
len += ret;
end_of_export:
mbedtls_mpi_free(&T);
if (ret < 0) {
return ret;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
return (int) len;
}
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
@ -660,7 +1022,6 @@ size_t mbedtls_rsa_get_len(const mbedtls_rsa_context *ctx)
return ctx->len;
}
#if defined(MBEDTLS_GENPRIME)
/*

View file

@ -15,6 +15,85 @@
#define MBEDTLS_RSA_INTERNAL_H
#include "mbedtls/rsa.h"
#include "mbedtls/asn1.h"
/**
* \brief Parse a PKCS#1 (ASN.1) encoded private RSA key.
*
* \param rsa The RSA context where parsed data will be stored.
* \param key The buffer that contains the key.
* \param keylen The length of the key buffer in bytes.
*
* \return 0 on success.
* \return MBEDTLS_ERR_ASN1_xxx in case of ASN.1 parsing errors.
* \return MBEDTLS_ERR_RSA_xxx in case of RSA internal failures while
* parsing data.
* \return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if validity checks on the
* provided key fail.
*/
int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen);
/**
* \brief Parse a PKCS#1 (ASN.1) encoded public RSA key.
*
* \param rsa The RSA context where parsed data will be stored.
* \param key The buffer that contains the key.
* \param keylen The length of the key buffer in bytes.
*
* \return 0 on success.
* \return MBEDTLS_ERR_ASN1_xxx in case of ASN.1 parsing errors.
* \return MBEDTLS_ERR_RSA_xxx in case of RSA internal failures while
* parsing data.
* \return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if validity checks on the
* provided key fail.
*/
int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen);
/**
* \brief Write a PKCS#1 (ASN.1) encoded private RSA key.
*
* \param rsa The RSA context which contains the data to be written.
* \param start Beginning of the buffer that will be filled with the
* private key.
* \param p End of the buffer that will be filled with the private key.
* On successful return, the referenced pointer will be
* updated in order to point to the beginning of written data.
*
* \return On success, the number of bytes written to the output buffer
* (i.e. a value > 0).
* \return MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the RSA context does not
* contain a valid key pair.
* \return MBEDTLS_ERR_ASN1_xxx in case of failure while writing to the
* output buffer.
*
* \note The output buffer is filled backward, i.e. starting from its
* end and moving toward its start.
*/
int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start,
unsigned char **p);
/**
* \brief Parse a PKCS#1 (ASN.1) encoded public RSA key.
*
* \param rsa The RSA context which contains the data to be written.
* \param start Beginning of the buffer that will be filled with the
* private key.
* \param p End of the buffer that will be filled with the private key.
* On successful return, the referenced pointer will be
* updated in order to point to the beginning of written data.
*
* \return On success, the number of bytes written to the output buffer
* (i.e. a value > 0).
* \return MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the RSA context does not
* contain a valid public key.
* \return MBEDTLS_ERR_ASN1_xxx in case of failure while writing to the
* output buffer.
*
* \note The output buffer is filled backward, i.e. starting from its
* end and moving toward its start.
*/
int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start,
unsigned char **p);
#if defined(MBEDTLS_PKCS1_V21)
/**

View file

@ -37,7 +37,7 @@ mbedtls_sha3_family_functions;
/*
* List of supported SHA-3 families
*/
static mbedtls_sha3_family_functions sha3_families[] = {
static const mbedtls_sha3_family_functions sha3_families[] = {
{ MBEDTLS_SHA3_224, 1152, 224 },
{ MBEDTLS_SHA3_256, 1088, 256 },
{ MBEDTLS_SHA3_384, 832, 384 },
@ -180,7 +180,7 @@ void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
*/
int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
{
mbedtls_sha3_family_functions *p = NULL;
const mbedtls_sha3_family_functions *p = NULL;
for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
if (p->id == id) {

View file

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

View file

@ -0,0 +1,154 @@
/**
* \file ssl_ciphersuites_internal.h
*
* \brief Internal part of the public "ssl_ciphersuites.h".
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H
#define MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H
#include "mbedtls/pk.h"
#if defined(MBEDTLS_PK_C)
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info);
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info);
psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info);
#endif /* MBEDTLS_PK_C */
int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info);
int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info);
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
static inline int mbedtls_ssl_ciphersuite_has_pfs(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
static inline int mbedtls_ssl_ciphersuite_no_pfs(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_PSK:
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_ecdh(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
static inline int mbedtls_ssl_ciphersuite_cert_req_allowed(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return 1;
default:
return 0;
}
}
static inline int mbedtls_ssl_ciphersuite_uses_srv_cert(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return 1;
default:
return 0;
}
}
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_dhe(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_ecdhe(const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_server_signature(
const mbedtls_ssl_ciphersuite_t *info)
{
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return 1;
default:
return 0;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
#endif /* MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H */

View file

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

View file

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

View file

@ -18,7 +18,7 @@
#include "mbedtls/ssl.h"
#include "ssl_misc.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/version.h"
@ -3985,6 +3985,31 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
rec)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "ssl_decrypt_buf", ret);
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
/*
* Although the server rejected early data, it might receive early
* data as long as it has not received the client Finished message.
* It is encrypted with early keys and should be ignored as stated
* in section 4.2.10 of RFC 8446:
*
* "Ignore the extension and return a regular 1-RTT response. The
* server then skips past early data by attempting to deprotect
* received records using the handshake traffic key, discarding
* records which fail deprotection (up to the configured
* max_early_data_size). Once a record is deprotected successfully,
* it is treated as the start of the client's second flight and the
* server proceeds as with an ordinary 1-RTT handshake."
*/
if ((old_msg_type == MBEDTLS_SSL_MSG_APPLICATION_DATA) &&
(ssl->discard_early_data_record ==
MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) {
MBEDTLS_SSL_DEBUG_MSG(
3, ("EarlyData: deprotect and discard app data records."));
/* TODO: Add max_early_data_size check here, see issue 6347 */
ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
}
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
ssl->conf->ignore_unexpected_cid
@ -3994,9 +4019,27 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
/*
* The decryption of the record failed, no reason to ignore it,
* return in error with the decryption error code.
*/
return ret;
}
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
/*
* If the server were discarding protected records that it fails to
* deprotect because it has rejected early data, as we have just
* deprotected successfully a record, the server has to resume normal
* operation and fail the connection if the deprotection of a record
* fails.
*/
if (ssl->discard_early_data_record ==
MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD) {
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
}
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
if (old_msg_type != rec->type) {
MBEDTLS_SSL_DEBUG_MSG(4, ("record type after decrypt (before %d): %d",
old_msg_type, rec->type));
@ -4070,6 +4113,32 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
/*
* Although the server rejected early data because it needed to send an
* HelloRetryRequest message, it might receive early data as long as it has
* not received the client Finished message.
* The early data is encrypted with early keys and should be ignored as
* stated in section 4.2.10 of RFC 8446 (second case):
*
* "The server then ignores early data by skipping all records with an
* external content type of "application_data" (indicating that they are
* encrypted), up to the configured max_early_data_size. Ignore application
* data message before 2nd ClientHello when early_data was received in 1st
* ClientHello."
*/
if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) {
if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
MBEDTLS_SSL_DEBUG_MSG(
3, ("EarlyData: Ignore application message before 2nd ClientHello"));
/* TODO: Add max_early_data_size check here, see issue 6347 */
return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
} else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) {
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
}
}
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
mbedtls_ssl_dtls_replay_update(ssl);
@ -5647,13 +5716,54 @@ static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
/*
* brief Read at most 'len' application data bytes from the input
* buffer.
*
* param ssl SSL context:
* - First byte of application data not read yet in the input
* buffer located at address `in_offt`.
* - The number of bytes of data not read yet is `in_msglen`.
* param buf buffer that will hold the data
* param len maximum number of bytes to read
*
* note The function updates the fields `in_offt` and `in_msglen`
* according to the number of bytes read.
*
* return The number of bytes read.
*/
static int ssl_read_application_data(
mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen;
if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}
return (int) n;
}
/*
* Receive application data decrypted from the SSL layer
*/
int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
if (ssl == NULL || ssl->conf == NULL) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
@ -5817,32 +5927,34 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
#endif /* MBEDTLS_SSL_PROTO_DTLS */
}
n = (len < ssl->in_msglen)
? len : ssl->in_msglen;
if (len != 0) {
memcpy(buf, ssl->in_offt, n);
ssl->in_msglen -= n;
}
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize(ssl->in_offt, n);
if (ssl->in_msglen == 0) {
/* all bytes consumed */
ssl->in_offt = NULL;
ssl->keep_current_message = 0;
} else {
/* more data available */
ssl->in_offt += n;
}
ret = ssl_read_application_data(ssl, buf, len);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
return (int) n;
return ret;
}
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA)
int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
unsigned char *buf, size_t len)
{
if (ssl == NULL || (ssl->conf == NULL)) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
/*
* The server may receive early data only while waiting for the End of
* Early Data handshake message.
*/
if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) ||
(ssl->in_offt == NULL)) {
return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
}
return ssl_read_application_data(ssl, buf, len);
}
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */
/*
* Send application data to be encrypted by the SSL layer, taking care of max
* fragment length and buffer size.

View file

@ -20,7 +20,7 @@
#include "ssl_debug_helpers.h"
#include "ssl_misc.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/version.h"
@ -631,7 +631,7 @@ static const char *extension_name_table[] = {
[MBEDTLS_SSL_EXT_ID_RECORD_SIZE_LIMIT] = "record_size_limit"
};
static unsigned int extension_type_table[] = {
static const unsigned int extension_type_table[] = {
[MBEDTLS_SSL_EXT_ID_UNRECOGNIZED] = 0xff,
[MBEDTLS_SSL_EXT_ID_SERVERNAME] = MBEDTLS_TLS_EXT_SERVERNAME,
[MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH] = MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH,
@ -1098,6 +1098,15 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
#if defined(MBEDTLS_SSL_CLI_C)
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
#endif
#if defined(MBEDTLS_SSL_SRV_C)
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
#endif
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Initialize structures */
mbedtls_ssl_session_init(ssl->session_negotiate);
ssl_handshake_params_init(ssl->handshake);
@ -3702,7 +3711,7 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
(SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \
(SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT)))
static unsigned char ssl_serialized_session_header[] = {
static const unsigned char ssl_serialized_session_header[] = {
MBEDTLS_VERSION_MAJOR,
MBEDTLS_VERSION_MINOR,
MBEDTLS_VERSION_PATCH,
@ -4427,7 +4436,7 @@ void mbedtls_ssl_session_free(mbedtls_ssl_session *session)
(SSL_SERIALIZED_CONTEXT_CONFIG_ALPN << SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT) | \
0u))
static unsigned char ssl_serialized_context_header[] = {
static const unsigned char ssl_serialized_context_header[] = {
MBEDTLS_VERSION_MAJOR,
MBEDTLS_VERSION_MINOR,
MBEDTLS_VERSION_PATCH,
@ -5045,7 +5054,7 @@ void mbedtls_ssl_config_init(mbedtls_ssl_config *conf)
* See the documentation of mbedtls_ssl_conf_curves() for what we promise
* about this list.
*/
static uint16_t ssl_preset_default_groups[] = {
static const uint16_t ssl_preset_default_groups[] = {
#if defined(MBEDTLS_ECP_HAVE_CURVE25519)
MBEDTLS_SSL_IANA_TLS_GROUP_X25519,
#endif
@ -5096,7 +5105,7 @@ static const int ssl_preset_suiteb_ciphersuites[] = {
* - ssl_tls12_preset* is for TLS 1.2 use only.
* - ssl_preset_* is for TLS 1.3 only or hybrid TLS 1.3/1.2 handshakes.
*/
static uint16_t ssl_preset_default_sig_algs[] = {
static const uint16_t ssl_preset_default_sig_algs[] = {
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) && \
defined(MBEDTLS_MD_CAN_SHA256) && \
@ -5191,7 +5200,7 @@ static uint16_t ssl_tls12_preset_default_sig_algs[] = {
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
/* NOTICE: see above */
static uint16_t ssl_preset_suiteb_sig_algs[] = {
static const uint16_t ssl_preset_suiteb_sig_algs[] = {
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) && \
defined(MBEDTLS_MD_CAN_SHA256) && \
@ -5232,7 +5241,7 @@ static uint16_t ssl_tls12_preset_suiteb_sig_algs[] = {
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
static uint16_t ssl_preset_suiteb_groups[] = {
static const uint16_t ssl_preset_suiteb_groups[] = {
#if defined(MBEDTLS_ECP_HAVE_SECP256R1)
MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
#endif
@ -5246,7 +5255,7 @@ static uint16_t ssl_preset_suiteb_groups[] = {
/* Function for checking `ssl_preset_*_sig_algs` and `ssl_tls12_preset_*_sig_algs`
* to make sure there are no duplicated signature algorithm entries. */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_no_sig_alg_duplication(uint16_t *sig_algs)
static int ssl_check_no_sig_alg_duplication(const uint16_t *sig_algs)
{
size_t i, j;
int ret = 0;

View file

@ -14,7 +14,7 @@
#include "mbedtls/ssl.h"
#include "ssl_client.h"
#include "ssl_misc.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/constant_time.h"
@ -2005,9 +2005,9 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
}
#if defined(MBEDTLS_ECP_C)
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
const mbedtls_ecp_keypair *peer_key = mbedtls_pk_ec_ro(*peer_pk);
#endif /* MBEDTLS_ECP_C */
#endif /* !defined(MBEDTLS_PK_USE_PSA_EC_DATA) */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
uint16_t tls_id = 0;

View file

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

View file

@ -11,7 +11,7 @@
#include <string.h>
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
@ -1182,7 +1182,8 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
ssl_tls13_early_data_has_valid_ticket(ssl) &&
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED &&
ssl->handshake->hello_retry_request_count == 0) {
ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &ext_len);
@ -1236,10 +1237,6 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO);
#endif
MBEDTLS_SSL_DEBUG_MSG(
1, ("Set hs psk for early data when writing the first psk"));
@ -1294,6 +1291,15 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
return ret;
}
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO);
#else
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
#endif
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
return 0;
@ -3067,19 +3073,19 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
}
break;
#if defined(MBEDTLS_SSL_EARLY_DATA)
case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO:
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret == 0) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
#if defined(MBEDTLS_SSL_EARLY_DATA)
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
#endif
}
break;
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)

View file

@ -12,7 +12,7 @@
#include <string.h>
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
@ -1539,26 +1539,36 @@ static psa_status_t mbedtls_ssl_get_psa_ffdh_info_from_tls_id(
uint16_t tls_id, size_t *bits, psa_key_type_t *key_type)
{
switch (tls_id) {
#if defined(PSA_WANT_DH_RFC7919_2048)
case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048:
*bits = 2048;
*key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
return PSA_SUCCESS;
#endif /* PSA_WANT_DH_RFC7919_2048 */
#if defined(PSA_WANT_DH_RFC7919_3072)
case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE3072:
*bits = 3072;
*key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
return PSA_SUCCESS;
#endif /* PSA_WANT_DH_RFC7919_3072 */
#if defined(PSA_WANT_DH_RFC7919_4096)
case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE4096:
*bits = 4096;
*key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
return PSA_SUCCESS;
#endif /* PSA_WANT_DH_RFC7919_4096 */
#if defined(PSA_WANT_DH_RFC7919_6144)
case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE6144:
*bits = 6144;
*key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
return PSA_SUCCESS;
#endif /* PSA_WANT_DH_RFC7919_6144 */
#if defined(PSA_WANT_DH_RFC7919_8192)
case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192:
*bits = 8192;
*key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
return PSA_SUCCESS;
#endif /* PSA_WANT_DH_RFC7919_8192 */
default:
return PSA_ERROR_NOT_SUPPORTED;
}

View file

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

View file

@ -9,7 +9,7 @@
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
@ -1533,6 +1533,12 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
unsigned int extension_type;
size_t extension_data_len;
const unsigned char *extension_data_end;
uint32_t allowed_exts = MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH;
if (ssl->handshake->hello_retry_request_count > 0) {
/* Do not accept early data extension in 2nd ClientHello */
allowed_exts &= ~MBEDTLS_SSL_EXT_MASK(EARLY_DATA);
}
/* RFC 8446, section 4.2.11
*
@ -1560,7 +1566,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
ret = mbedtls_ssl_tls13_check_received_extension(
ssl, MBEDTLS_SSL_HS_CLIENT_HELLO, extension_type,
MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH);
allowed_exts);
if (ret != 0) {
return ret;
}
@ -1780,25 +1786,15 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
static int ssl_tls13_check_early_data_requirements(mbedtls_ssl_context *ssl)
{
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
if ((handshake->received_extensions &
MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: no early data extension received."));
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED;
return;
}
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) {
MBEDTLS_SSL_DEBUG_MSG(
1,
("EarlyData: rejected, feature disabled in server configuration."));
return;
return -1;
}
if (!handshake->resume) {
@ -1807,7 +1803,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
resumption. */
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, not a session resumption."));
return;
return -1;
}
/* RFC 8446 4.2.10
@ -1830,7 +1826,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected key in "
"`pre_shared_key` is not the first one."));
return;
return -1;
}
if (handshake->ciphersuite_info->id !=
@ -1838,7 +1834,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(
1, ("EarlyData: rejected, the selected ciphersuite is not the one "
"of the selected pre-shared key."));
return;
return -1;
}
@ -1847,18 +1843,18 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl)
1,
("EarlyData: rejected, early_data not allowed in ticket "
"permission bits."));
return;
return -1;
}
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
return 0;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Update the handshake state machine */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl,
int hrr_required)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -1882,17 +1878,26 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl)
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
/* There is enough information, update early data state. */
ssl_tls13_update_early_data_status(ssl);
if (ssl->handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) {
ssl->handshake->early_data_accepted =
(!hrr_required) && (ssl_tls13_check_early_data_requirements(ssl) == 0);
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
1, "mbedtls_ssl_tls13_compute_early_transform", ret);
return ret;
if (ssl->handshake->early_data_accepted) {
ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(
1, "mbedtls_ssl_tls13_compute_early_transform", ret);
return ret;
}
} else {
ssl->discard_early_data_record =
hrr_required ?
MBEDTLS_SSL_EARLY_DATA_DISCARD :
MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD;
}
}
#else
((void) hrr_required);
#endif /* MBEDTLS_SSL_EARLY_DATA */
return 0;
@ -1947,7 +1952,9 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl)
return 0;
}
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_client_hello(ssl));
MBEDTLS_SSL_PROC_CHK(
ssl_tls13_postprocess_client_hello(ssl, parse_client_hello_ret ==
SSL_CLIENT_HELLO_HRR_REQUIRED));
if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
@ -2530,7 +2537,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->handshake->early_data_accepted) {
ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &output_len);
if (ret != 0) {
@ -2857,7 +2864,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl)
}
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
if (ssl->handshake->early_data_accepted) {
/* See RFC 8446 section A.2 for more information */
MBEDTLS_SSL_DEBUG_MSG(
1, ("Switch to early keys for inbound traffic. "
@ -2911,6 +2918,17 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl)
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
/* RFC 8446 section 4.6.1
*
* A server receiving more than max_early_data_size bytes of 0-RTT data
* SHOULD terminate the connection with an "unexpected_message" alert.
*
* TODO: Add received data size check here.
*/
if (ssl->in_offt == NULL) {
/* Set the reading pointer */
ssl->in_offt = ssl->in_msg;
}
return SSL_GOT_EARLY_DATA;
}
@ -2936,37 +2954,6 @@ static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl,
return 0;
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_process_early_application_data(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
return ret;
}
/*
* Output early data
*
* For the time being, we print received data via debug message.
*
* TODO: Remove it when `mbedtls_ssl_read_early_data` is ready.
*/
ssl->in_msg[ssl->in_msglen] = 0;
MBEDTLS_SSL_DEBUG_MSG(3, ("\n%s", ssl->in_msg));
/* RFC 8446 section 4.6.1
*
* A server receiving more than max_early_data_size bytes of 0-RTT data
* SHOULD terminate the connection with an "unexpected_message" alert.
*
* TODO: Add received data size check here.
*/
return 0;
}
/*
* RFC 8446 section A.2
*
@ -3037,7 +3024,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl)
ssl_tls13_prepare_for_handshake_second_flight(ssl);
} else if (ret == SSL_GOT_EARLY_DATA) {
MBEDTLS_SSL_PROC_CHK(ssl_tls13_process_early_application_data(ssl));
ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA;
goto cleanup;
} else {
MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;

View file

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

View file

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

View file

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

View file

@ -22,6 +22,7 @@
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/x509_crt.h"
#include "x509_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"

View file

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

213
library/x509_internal.h Normal file
View file

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

View file

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

View file

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

View file

@ -14,7 +14,7 @@
#if defined(MBEDTLS_X509_CSR_WRITE_C)
#include "mbedtls/x509.h"
#include "x509_internal.h"
#include "mbedtls/x509_csr.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"