Merge branch 'Mbed-TLS:development' into threadsafe-key-locking
This commit is contained in:
commit
e02b63ac89
156 changed files with 6545 additions and 2274 deletions
|
@ -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)
|
||||
|
|
|
@ -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 alignment—one 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
172
library/debug_internal.h
Normal 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 */
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
205
library/pk.c
205
library/pk.c
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
363
library/rsa.c
363
library/rsa.c
|
@ -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)
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
154
library/ssl_ciphersuites_internal.h
Normal file
154
library/ssl_ciphersuites_internal.h
Normal 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 */
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/debug.h"
|
||||
#include "debug_internal.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
213
library/x509_internal.h
Normal 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 */
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue