mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-08-08 17:42:09 +03:00
Merge branch 'development' into driver-wrapper-key-agreement
This commit is contained in:
@@ -44,6 +44,8 @@ set(src_crypto
|
||||
hash_info.c
|
||||
hkdf.c
|
||||
hmac_drbg.c
|
||||
lmots.c
|
||||
lms.c
|
||||
md.c
|
||||
md5.c
|
||||
memory_buffer_alloc.c
|
||||
|
@@ -109,6 +109,8 @@ OBJS_CRYPTO= \
|
||||
hash_info.o \
|
||||
hkdf.o \
|
||||
hmac_drbg.o \
|
||||
lmots.o \
|
||||
lms.o \
|
||||
md.o \
|
||||
md5.o \
|
||||
memory_buffer_alloc.o \
|
||||
@@ -197,6 +199,7 @@ all: shared static
|
||||
endif
|
||||
|
||||
static: libmbedcrypto.a libmbedx509.a libmbedtls.a
|
||||
cd ../tests && echo "This is a seedfile that contains 64 bytes (65 on Windows)......" > seedfile
|
||||
|
||||
shared: libmbedcrypto.$(DLEXT) libmbedx509.$(DLEXT) libmbedtls.$(DLEXT)
|
||||
|
||||
|
@@ -1690,7 +1690,8 @@ int mbedtls_aes_self_test( int verbose )
|
||||
unsigned char key[32];
|
||||
unsigned char buf[64];
|
||||
const unsigned char *aes_tests;
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
|
||||
defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||
unsigned char iv[16];
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
|
@@ -888,15 +888,17 @@ static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext
|
||||
};
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#define ARIA_SELF_TEST_IF_FAIL \
|
||||
{ \
|
||||
if( verbose ) \
|
||||
mbedtls_printf( "failed\n" ); \
|
||||
goto exit; \
|
||||
} else { \
|
||||
if( verbose ) \
|
||||
mbedtls_printf( "passed\n" ); \
|
||||
}
|
||||
#define ARIA_SELF_TEST_ASSERT( cond ) \
|
||||
do { \
|
||||
if( cond ) { \
|
||||
if( verbose ) \
|
||||
mbedtls_printf( "failed\n" ); \
|
||||
goto exit; \
|
||||
} else { \
|
||||
if( verbose ) \
|
||||
mbedtls_printf( "passed\n" ); \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
@@ -930,16 +932,18 @@ int mbedtls_aria_self_test( int verbose )
|
||||
mbedtls_printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i );
|
||||
mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i );
|
||||
mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk );
|
||||
if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
|
||||
ARIA_SELF_TEST_IF_FAIL;
|
||||
ARIA_SELF_TEST_ASSERT(
|
||||
memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE )
|
||||
!= 0 );
|
||||
|
||||
/* test ECB decryption */
|
||||
if( verbose )
|
||||
mbedtls_printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i );
|
||||
mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i );
|
||||
mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk );
|
||||
if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
|
||||
ARIA_SELF_TEST_IF_FAIL;
|
||||
ARIA_SELF_TEST_ASSERT(
|
||||
memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE )
|
||||
!= 0 );
|
||||
}
|
||||
if( verbose )
|
||||
mbedtls_printf( "\n" );
|
||||
@@ -958,8 +962,8 @@ int mbedtls_aria_self_test( int verbose )
|
||||
memset( buf, 0x55, sizeof( buf ) );
|
||||
mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
|
||||
aria_test2_pt, buf );
|
||||
if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 )
|
||||
ARIA_SELF_TEST_IF_FAIL;
|
||||
ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_cbc_ct[i], 48 )
|
||||
!= 0 );
|
||||
|
||||
/* Test CBC decryption */
|
||||
if( verbose )
|
||||
@@ -969,8 +973,7 @@ int mbedtls_aria_self_test( int verbose )
|
||||
memset( buf, 0xAA, sizeof( buf ) );
|
||||
mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
|
||||
aria_test2_cbc_ct[i], buf );
|
||||
if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
|
||||
ARIA_SELF_TEST_IF_FAIL;
|
||||
ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 );
|
||||
}
|
||||
if( verbose )
|
||||
mbedtls_printf( "\n" );
|
||||
@@ -989,8 +992,7 @@ int mbedtls_aria_self_test( int verbose )
|
||||
j = 0;
|
||||
mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
|
||||
aria_test2_pt, buf );
|
||||
if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 )
|
||||
ARIA_SELF_TEST_IF_FAIL;
|
||||
ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 );
|
||||
|
||||
/* Test CFB decryption */
|
||||
if( verbose )
|
||||
@@ -1001,8 +1003,7 @@ int mbedtls_aria_self_test( int verbose )
|
||||
j = 0;
|
||||
mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
|
||||
iv, aria_test2_cfb_ct[i], buf );
|
||||
if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
|
||||
ARIA_SELF_TEST_IF_FAIL;
|
||||
ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 );
|
||||
}
|
||||
if( verbose )
|
||||
mbedtls_printf( "\n" );
|
||||
@@ -1020,8 +1021,7 @@ int mbedtls_aria_self_test( int verbose )
|
||||
j = 0;
|
||||
mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
|
||||
aria_test2_pt, buf );
|
||||
if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 )
|
||||
ARIA_SELF_TEST_IF_FAIL;
|
||||
ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 );
|
||||
|
||||
/* Test CTR decryption */
|
||||
if( verbose )
|
||||
@@ -1032,8 +1032,7 @@ int mbedtls_aria_self_test( int verbose )
|
||||
j = 0;
|
||||
mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
|
||||
aria_test2_ctr_ct[i], buf );
|
||||
if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
|
||||
ARIA_SELF_TEST_IF_FAIL;
|
||||
ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 );
|
||||
}
|
||||
if( verbose )
|
||||
mbedtls_printf( "\n" );
|
||||
|
@@ -72,9 +72,11 @@ int mbedtls_asn1_write_len( unsigned char **p, const unsigned char *start, size_
|
||||
return( 4 );
|
||||
}
|
||||
|
||||
int len_is_valid = 1;
|
||||
#if SIZE_MAX > 0xFFFFFFFF
|
||||
if( len <= 0xFFFFFFFF )
|
||||
len_is_valid = ( len <= 0xFFFFFFFF );
|
||||
#endif
|
||||
if( len_is_valid )
|
||||
{
|
||||
if( *p - start < 5 )
|
||||
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||
@@ -87,9 +89,7 @@ int mbedtls_asn1_write_len( unsigned char **p, const unsigned char *start, size_
|
||||
return( 5 );
|
||||
}
|
||||
|
||||
#if SIZE_MAX > 0xFFFFFFFF
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
#endif
|
||||
}
|
||||
|
||||
int mbedtls_asn1_write_tag( unsigned char **p, const unsigned char *start, unsigned char tag )
|
||||
|
108
library/bignum.c
108
library/bignum.c
@@ -771,42 +771,9 @@ cleanup:
|
||||
*/
|
||||
int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
|
||||
{
|
||||
size_t i, v0, v1;
|
||||
mbedtls_mpi_uint r0 = 0, r1;
|
||||
MPI_VALIDATE_RET( X != NULL );
|
||||
|
||||
v0 = count / biL;
|
||||
v1 = count & (biL - 1);
|
||||
|
||||
if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
|
||||
return mbedtls_mpi_lset( X, 0 );
|
||||
|
||||
/*
|
||||
* shift by count / limb_size
|
||||
*/
|
||||
if( v0 > 0 )
|
||||
{
|
||||
for( i = 0; i < X->n - v0; i++ )
|
||||
X->p[i] = X->p[i + v0];
|
||||
|
||||
for( ; i < X->n; i++ )
|
||||
X->p[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* shift by count % limb_size
|
||||
*/
|
||||
if( v1 > 0 )
|
||||
{
|
||||
for( i = X->n; i > 0; i-- )
|
||||
{
|
||||
r1 = X->p[i - 1] << (biL - v1);
|
||||
X->p[i - 1] >>= v1;
|
||||
X->p[i - 1] |= r0;
|
||||
r0 = r1;
|
||||
}
|
||||
}
|
||||
|
||||
if( X->n != 0 )
|
||||
mbedtls_mpi_core_shift_r( X->p, X->n, count );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@@ -900,8 +867,7 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
|
||||
int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t i, j;
|
||||
mbedtls_mpi_uint *o, *p, c, tmp;
|
||||
size_t j;
|
||||
MPI_VALIDATE_RET( X != NULL );
|
||||
MPI_VALIDATE_RET( A != NULL );
|
||||
MPI_VALIDATE_RET( B != NULL );
|
||||
@@ -915,7 +881,7 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
|
||||
|
||||
/*
|
||||
* X should always be positive as a result of unsigned additions.
|
||||
* X must always be positive as a result of unsigned additions.
|
||||
*/
|
||||
X->s = 1;
|
||||
|
||||
@@ -925,27 +891,25 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
|
||||
|
||||
o = B->p; p = X->p; c = 0;
|
||||
/* j is the number of non-zero limbs of B. Add those to X. */
|
||||
|
||||
/*
|
||||
* tmp is used because it might happen that p == o
|
||||
*/
|
||||
for( i = 0; i < j; i++, o++, p++ )
|
||||
{
|
||||
tmp= *o;
|
||||
*p += c; c = ( *p < c );
|
||||
*p += tmp; c += ( *p < tmp );
|
||||
}
|
||||
mbedtls_mpi_uint *p = X->p;
|
||||
|
||||
mbedtls_mpi_uint c = mbedtls_mpi_core_add( p, p, B->p, j );
|
||||
|
||||
p += j;
|
||||
|
||||
/* Now propagate any carry */
|
||||
|
||||
while( c != 0 )
|
||||
{
|
||||
if( i >= X->n )
|
||||
if( j >= X->n )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
|
||||
p = X->p + i;
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j + 1 ) );
|
||||
p = X->p + j;
|
||||
}
|
||||
|
||||
*p += c; c = ( *p < c ); i++; p++;
|
||||
*p += c; c = ( *p < c ); j++; p++;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
@@ -1967,39 +1931,11 @@ cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Fill X with n_bytes random bytes.
|
||||
* X must already have room for those bytes.
|
||||
* The ordering of the bytes returned from the RNG is suitable for
|
||||
* deterministic ECDSA (see RFC 6979 §3.3 and mbedtls_mpi_random()).
|
||||
* The size and sign of X are unchanged.
|
||||
* n_bytes must not be 0.
|
||||
*/
|
||||
static int mpi_fill_random_internal(
|
||||
mbedtls_mpi *X, size_t n_bytes,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const size_t limbs = CHARS_TO_LIMBS( n_bytes );
|
||||
const size_t overhead = ( limbs * ciL ) - n_bytes;
|
||||
|
||||
if( X->n < limbs )
|
||||
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
|
||||
|
||||
memset( X->p, 0, overhead );
|
||||
memset( (unsigned char *) X->p + limbs * ciL, 0, ( X->n - limbs ) * ciL );
|
||||
MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X->p + overhead, n_bytes ) );
|
||||
mbedtls_mpi_core_bigendian_to_host( X->p, limbs );
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill X with size bytes of random.
|
||||
*
|
||||
* Use a temporary bytes representation to make sure the result is the same
|
||||
* regardless of the platform endianness (useful when f_rng is actually
|
||||
* deterministic, eg for tests).
|
||||
* The bytes returned from the RNG are used in a specific order which
|
||||
* is suitable for deterministic ECDSA (see the specification of
|
||||
* mbedtls_mpi_random() and the implementation in mbedtls_mpi_fill_random()).
|
||||
*/
|
||||
int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
@@ -2016,7 +1952,7 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
|
||||
if( size == 0 )
|
||||
return( 0 );
|
||||
|
||||
ret = mpi_fill_random_internal( X, size, f_rng, p_rng );
|
||||
ret = mbedtls_mpi_core_fill_random( X->p, X->n, size, f_rng, p_rng );
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
@@ -2078,7 +2014,9 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
|
||||
*/
|
||||
do
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mpi_fill_random_internal( X, n_bytes, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_core_fill_random( X->p, X->n,
|
||||
n_bytes,
|
||||
f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, 8 * n_bytes - n_bits ) );
|
||||
|
||||
if( --count == 0 )
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
@@ -153,6 +154,36 @@ void mbedtls_mpi_core_bigendian_to_host( mbedtls_mpi_uint *A,
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_mpi_core_cond_assign( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs,
|
||||
unsigned char assign )
|
||||
{
|
||||
if( X == A )
|
||||
return;
|
||||
|
||||
mbedtls_ct_mpi_uint_cond_assign( limbs, X, A, assign );
|
||||
}
|
||||
|
||||
void mbedtls_mpi_core_cond_swap( mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint *Y,
|
||||
size_t limbs,
|
||||
unsigned char swap )
|
||||
{
|
||||
if( X == Y )
|
||||
return;
|
||||
|
||||
/* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
|
||||
mbedtls_mpi_uint limb_mask = mbedtls_ct_mpi_uint_mask( swap );
|
||||
|
||||
for( size_t i = 0; i < limbs; i++ )
|
||||
{
|
||||
mbedtls_mpi_uint tmp = X[i];
|
||||
X[i] = ( X[i] & ~limb_mask ) | ( Y[i] & limb_mask );
|
||||
Y[i] = ( Y[i] & ~limb_mask ) | ( tmp & limb_mask );
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_mpi_core_read_le( mbedtls_mpi_uint *X,
|
||||
size_t X_limbs,
|
||||
const unsigned char *input,
|
||||
@@ -285,6 +316,67 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *X,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs,
|
||||
size_t count )
|
||||
{
|
||||
size_t i, v0, v1;
|
||||
mbedtls_mpi_uint r0 = 0, r1;
|
||||
|
||||
v0 = count / biL;
|
||||
v1 = count & (biL - 1);
|
||||
|
||||
if( v0 > limbs || ( v0 == limbs && v1 > 0 ) )
|
||||
{
|
||||
memset( X, 0, limbs * ciL );
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* shift by count / limb_size
|
||||
*/
|
||||
if( v0 > 0 )
|
||||
{
|
||||
for( i = 0; i < limbs - v0; i++ )
|
||||
X[i] = X[i + v0];
|
||||
|
||||
for( ; i < limbs; i++ )
|
||||
X[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* shift by count % limb_size
|
||||
*/
|
||||
if( v1 > 0 )
|
||||
{
|
||||
for( i = limbs; i > 0; i-- )
|
||||
{
|
||||
r1 = X[i - 1] << (biL - v1);
|
||||
X[i - 1] >>= v1;
|
||||
X[i - 1] |= r0;
|
||||
r0 = r1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_add( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
size_t limbs )
|
||||
{
|
||||
mbedtls_mpi_uint c = 0;
|
||||
|
||||
for( size_t i = 0; i < limbs; i++ )
|
||||
{
|
||||
mbedtls_mpi_uint t = c + A[i];
|
||||
c = ( t < A[i] );
|
||||
t += B[i];
|
||||
c += ( t < B[i] );
|
||||
X[i] = t;
|
||||
}
|
||||
|
||||
return( c );
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_add_if( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs,
|
||||
@@ -434,4 +526,98 @@ void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X,
|
||||
mbedtls_ct_mpi_uint_cond_assign( AN_limbs, X, T, (unsigned char) ( carry ^ borrow ) );
|
||||
}
|
||||
|
||||
int mbedtls_mpi_core_get_mont_r2_unsafe( mbedtls_mpi *X,
|
||||
const mbedtls_mpi *N )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( X, N->n * 2 * biL ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( X, X, N ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( X, N->n ) );
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
void mbedtls_mpi_core_ct_uint_table_lookup( mbedtls_mpi_uint *dest,
|
||||
const mbedtls_mpi_uint *table,
|
||||
size_t limbs,
|
||||
size_t count,
|
||||
size_t index )
|
||||
{
|
||||
for( size_t i = 0; i < count; i++, table += limbs )
|
||||
{
|
||||
unsigned char assign = mbedtls_ct_size_bool_eq( i, index );
|
||||
mbedtls_mpi_core_cond_assign( dest, table, limbs, assign );
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill X with n_bytes random bytes.
|
||||
* X must already have room for those bytes.
|
||||
* The ordering of the bytes returned from the RNG is suitable for
|
||||
* deterministic ECDSA (see RFC 6979 §3.3 and the specification of
|
||||
* mbedtls_mpi_core_random()).
|
||||
*/
|
||||
int mbedtls_mpi_core_fill_random(
|
||||
mbedtls_mpi_uint *X, size_t X_limbs,
|
||||
size_t n_bytes,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const size_t limbs = CHARS_TO_LIMBS( n_bytes );
|
||||
const size_t overhead = ( limbs * ciL ) - n_bytes;
|
||||
|
||||
if( X_limbs < limbs )
|
||||
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
|
||||
|
||||
memset( X, 0, overhead );
|
||||
memset( (unsigned char *) X + limbs * ciL, 0, ( X_limbs - limbs ) * ciL );
|
||||
MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X + overhead, n_bytes ) );
|
||||
mbedtls_mpi_core_bigendian_to_host( X, limbs );
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* BEGIN MERGE SLOT 1 */
|
||||
|
||||
/* END MERGE SLOT 1 */
|
||||
|
||||
/* BEGIN MERGE SLOT 2 */
|
||||
|
||||
/* END MERGE SLOT 2 */
|
||||
|
||||
/* BEGIN MERGE SLOT 3 */
|
||||
|
||||
/* END MERGE SLOT 3 */
|
||||
|
||||
/* BEGIN MERGE SLOT 4 */
|
||||
|
||||
/* END MERGE SLOT 4 */
|
||||
|
||||
/* BEGIN MERGE SLOT 5 */
|
||||
|
||||
/* END MERGE SLOT 5 */
|
||||
|
||||
/* BEGIN MERGE SLOT 6 */
|
||||
|
||||
/* END MERGE SLOT 6 */
|
||||
|
||||
/* BEGIN MERGE SLOT 7 */
|
||||
|
||||
/* END MERGE SLOT 7 */
|
||||
|
||||
/* BEGIN MERGE SLOT 8 */
|
||||
|
||||
/* END MERGE SLOT 8 */
|
||||
|
||||
/* BEGIN MERGE SLOT 9 */
|
||||
|
||||
/* END MERGE SLOT 9 */
|
||||
|
||||
/* BEGIN MERGE SLOT 10 */
|
||||
|
||||
/* END MERGE SLOT 10 */
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
@@ -6,6 +6,61 @@
|
||||
* modules should use the high-level modular bignum interface (bignum_mod.h)
|
||||
* or the legacy bignum interface (bignum.h).
|
||||
*
|
||||
* This module is about processing non-negative integers with a fixed upper
|
||||
* bound that's of the form 2^n-1 where n is a multiple of #biL.
|
||||
* These can be thought of integers written in base 2^#biL with a fixed
|
||||
* number of digits. Digits in this base are called *limbs*.
|
||||
* Many operations treat these numbers as the principal representation of
|
||||
* a number modulo 2^n or a smaller bound.
|
||||
*
|
||||
* The functions in this module obey the following conventions unless
|
||||
* explicitly indicated otherwise:
|
||||
*
|
||||
* - **Overflow**: some functions indicate overflow from the range
|
||||
* [0, 2^n-1] by returning carry parameters, while others operate
|
||||
* modulo and so cannot overflow. This should be clear from the function
|
||||
* documentation.
|
||||
* - **Bignum parameters**: Bignums are passed as pointers to an array of
|
||||
* limbs. A limb has the type #mbedtls_mpi_uint. Unless otherwise specified:
|
||||
* - Bignum parameters called \p A, \p B, ... are inputs, and are
|
||||
* not modified by the function.
|
||||
* - For operations modulo some number, the modulus is called \p N
|
||||
* and is input-only.
|
||||
* - Bignum parameters called \p X, \p Y are outputs or input-output.
|
||||
* The initial content of output-only parameters is ignored.
|
||||
* - Some functions use different names that reflect traditional
|
||||
* naming of operands of certain operations (e.g.
|
||||
* divisor/dividend/quotient/remainder).
|
||||
* - \p T is a temporary storage area. The initial content of such
|
||||
* parameter is ignored and the final content is unspecified.
|
||||
* - **Bignum sizes**: bignum sizes are always expressed in limbs.
|
||||
* Most functions work on bignums of a given size and take a single
|
||||
* \p limbs parameter that applies to all parameters that are limb arrays.
|
||||
* All bignum sizes must be at least 1 and must be significantly less than
|
||||
* #SIZE_MAX. The behavior if a size is 0 is undefined. The behavior if the
|
||||
* total size of all parameters overflows #SIZE_MAX is undefined.
|
||||
* - **Parameter ordering**: for bignum parameters, outputs come before inputs.
|
||||
* Temporaries come last.
|
||||
* - **Aliasing**: in general, output bignums may be aliased to one or more
|
||||
* inputs. As an exception, parameters that are documented as a modulus value
|
||||
* may not be aliased to an output. Outputs may not be aliased to one another.
|
||||
* Temporaries may not be aliased to any other parameter.
|
||||
* - **Overlap**: apart from aliasing of limb array pointers (where two
|
||||
* arguments are equal pointers), overlap is not supported and may result
|
||||
* in undefined behavior.
|
||||
* - **Error handling**: This is a low-level module. Functions generally do not
|
||||
* try to protect against invalid arguments such as nonsensical sizes or
|
||||
* null pointers. Note that some functions that operate on bignums of
|
||||
* different sizes have constraints about their size, and violating those
|
||||
* constraints may lead to buffer overflows.
|
||||
* - **Modular representatives**: functions that operate modulo \p N expect
|
||||
* all modular inputs to be in the range [0, \p N - 1] and guarantee outputs
|
||||
* in the range [0, \p N - 1]. If an input is out of range, outputs are
|
||||
* fully unspecified, though bignum values out of range should not cause
|
||||
* buffer overflows (beware that this is not extensively tested).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -31,9 +86,9 @@
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
#define ciL ( sizeof(mbedtls_mpi_uint) ) /* chars in limb */
|
||||
#define biL ( ciL << 3 ) /* bits in limb */
|
||||
#define biH ( ciL << 2 ) /* half limb size */
|
||||
#define ciL ( sizeof(mbedtls_mpi_uint) ) /** chars in limb */
|
||||
#define biL ( ciL << 3 ) /** bits in limb */
|
||||
#define biH ( ciL << 2 ) /** half limb size */
|
||||
|
||||
/*
|
||||
* Convert between bits/chars and number of limbs
|
||||
@@ -74,6 +129,58 @@ size_t mbedtls_mpi_core_bitlen( const mbedtls_mpi_uint *A, size_t A_limbs );
|
||||
void mbedtls_mpi_core_bigendian_to_host( mbedtls_mpi_uint *A,
|
||||
size_t A_limbs );
|
||||
|
||||
/**
|
||||
* \brief Perform a safe conditional copy of an MPI which doesn't reveal
|
||||
* whether assignment was done or not.
|
||||
*
|
||||
* \param[out] X The address of the destination MPI.
|
||||
* This must be initialized. Must have enough limbs to
|
||||
* store the full value of \p A.
|
||||
* \param[in] A The address of the source MPI. This must be initialized.
|
||||
* \param limbs The number of limbs of \p A.
|
||||
* \param assign The condition deciding whether to perform the
|
||||
* assignment or not. Must be either 0 or 1:
|
||||
* * \c 1: Perform the assignment `X = A`.
|
||||
* * \c 0: Keep the original value of \p X.
|
||||
*
|
||||
* \note This function avoids leaking any information about whether
|
||||
* the assignment was done or not.
|
||||
*
|
||||
* \warning If \p assign is neither 0 nor 1, the result of this function
|
||||
* is indeterminate, and the resulting value in \p X might be
|
||||
* neither its original value nor the value in \p A.
|
||||
*/
|
||||
void mbedtls_mpi_core_cond_assign( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs,
|
||||
unsigned char assign );
|
||||
|
||||
/**
|
||||
* \brief Perform a safe conditional swap of two MPIs which doesn't reveal
|
||||
* whether the swap was done or not.
|
||||
*
|
||||
* \param[in,out] X The address of the first MPI.
|
||||
* This must be initialized.
|
||||
* \param[in,out] Y The address of the second MPI.
|
||||
* This must be initialized.
|
||||
* \param limbs The number of limbs of \p X and \p Y.
|
||||
* \param swap The condition deciding whether to perform
|
||||
* the swap or not. Must be either 0 or 1:
|
||||
* * \c 1: Swap the values of \p X and \p Y.
|
||||
* * \c 0: Keep the original values of \p X and \p Y.
|
||||
*
|
||||
* \note This function avoids leaking any information about whether
|
||||
* the swap was done or not.
|
||||
*
|
||||
* \warning If \p swap is neither 0 nor 1, the result of this function
|
||||
* is indeterminate, and both \p X and \p Y might end up with
|
||||
* values different to either of the original ones.
|
||||
*/
|
||||
void mbedtls_mpi_core_cond_swap( mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint *Y,
|
||||
size_t limbs,
|
||||
unsigned char swap );
|
||||
|
||||
/** Import X from unsigned binary data, little-endian.
|
||||
*
|
||||
* The MPI needs to have enough limbs to store the full value (including any
|
||||
@@ -155,6 +262,43 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *A,
|
||||
unsigned char *output,
|
||||
size_t output_length );
|
||||
|
||||
/** \brief Shift an MPI right in place by a number of bits.
|
||||
*
|
||||
* Shifting by more bits than there are bit positions
|
||||
* in \p X is valid and results in setting \p X to 0.
|
||||
*
|
||||
* This function's execution time depends on the value
|
||||
* of \p count (and of course \p limbs).
|
||||
*
|
||||
* \param[in,out] X The number to shift.
|
||||
* \param limbs The number of limbs of \p X. This must be at least 1.
|
||||
* \param count The number of bits to shift by.
|
||||
*/
|
||||
void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs,
|
||||
size_t count );
|
||||
|
||||
/**
|
||||
* \brief Add two fixed-size large unsigned integers, returning the carry.
|
||||
*
|
||||
* Calculates `A + B` where `A` and `B` have the same size.
|
||||
*
|
||||
* This function operates modulo `2^(biL*limbs)` and returns the carry
|
||||
* (1 if there was a wraparound, and 0 otherwise).
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B.
|
||||
*
|
||||
* \param[out] X The result of the addition.
|
||||
* \param[in] A Little-endian presentation of the left operand.
|
||||
* \param[in] B Little-endian presentation of the right operand.
|
||||
* \param limbs Number of limbs of \p X, \p A and \p B.
|
||||
*
|
||||
* \return 1 if `A + B >= 2^(biL*limbs)`, 0 otherwise.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_add( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
size_t limbs );
|
||||
|
||||
/**
|
||||
* \brief Conditional addition of two fixed-size large unsigned integers,
|
||||
* returning the carry.
|
||||
@@ -290,4 +434,104 @@ void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *N, size_t AN_limbs,
|
||||
mbedtls_mpi_uint mm, mbedtls_mpi_uint *T );
|
||||
|
||||
/**
|
||||
* \brief Calculate the square of the Montgomery constant. (Needed
|
||||
* for conversion and operations in Montgomery form.)
|
||||
*
|
||||
* \param[out] X A pointer to the result of the calculation of
|
||||
* the square of the Montgomery constant:
|
||||
* 2^{2*n*biL} mod N.
|
||||
* \param[in] N Little-endian presentation of the modulus, which must be odd.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if there is not enough space
|
||||
* to store the value of Montgomery constant squared.
|
||||
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p N modulus is zero.
|
||||
* \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p N modulus is negative.
|
||||
*/
|
||||
int mbedtls_mpi_core_get_mont_r2_unsafe( mbedtls_mpi *X,
|
||||
const mbedtls_mpi *N );
|
||||
|
||||
/**
|
||||
* Copy an MPI from a table without leaking the index.
|
||||
*
|
||||
* \param dest The destination buffer. This must point to a writable
|
||||
* buffer of at least \p limbs limbs.
|
||||
* \param table The address of the table. This must point to a readable
|
||||
* array of \p count elements of \p limbs limbs each.
|
||||
* \param limbs The number of limbs in each table entry.
|
||||
* \param count The number of entries in \p table.
|
||||
* \param index The (secret) table index to look up. This must be in the
|
||||
* range `0 .. count-1`.
|
||||
*/
|
||||
void mbedtls_mpi_core_ct_uint_table_lookup( mbedtls_mpi_uint *dest,
|
||||
const mbedtls_mpi_uint *table,
|
||||
size_t limbs,
|
||||
size_t count,
|
||||
size_t index );
|
||||
|
||||
/**
|
||||
* \brief Fill an integer with a number of random bytes.
|
||||
*
|
||||
* \param X The destination MPI.
|
||||
* \param X_limbs The number of limbs of \p X.
|
||||
* \param bytes The number of random bytes to generate.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng doesn't need a context argument.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p X does not have
|
||||
* enough room for \p bytes bytes.
|
||||
* \return A negative error code on RNG failure.
|
||||
*
|
||||
* \note The bytes obtained from the RNG are interpreted
|
||||
* as a big-endian representation of an MPI; this can
|
||||
* be relevant in applications like deterministic ECDSA.
|
||||
*/
|
||||
int mbedtls_mpi_core_fill_random( mbedtls_mpi_uint *X, size_t X_limbs,
|
||||
size_t bytes,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/* BEGIN MERGE SLOT 1 */
|
||||
|
||||
/* END MERGE SLOT 1 */
|
||||
|
||||
/* BEGIN MERGE SLOT 2 */
|
||||
|
||||
/* END MERGE SLOT 2 */
|
||||
|
||||
/* BEGIN MERGE SLOT 3 */
|
||||
|
||||
/* END MERGE SLOT 3 */
|
||||
|
||||
/* BEGIN MERGE SLOT 4 */
|
||||
|
||||
/* END MERGE SLOT 4 */
|
||||
|
||||
/* BEGIN MERGE SLOT 5 */
|
||||
|
||||
/* END MERGE SLOT 5 */
|
||||
|
||||
/* BEGIN MERGE SLOT 6 */
|
||||
|
||||
/* END MERGE SLOT 6 */
|
||||
|
||||
/* BEGIN MERGE SLOT 7 */
|
||||
|
||||
/* END MERGE SLOT 7 */
|
||||
|
||||
/* BEGIN MERGE SLOT 8 */
|
||||
|
||||
/* END MERGE SLOT 8 */
|
||||
|
||||
/* BEGIN MERGE SLOT 9 */
|
||||
|
||||
/* END MERGE SLOT 9 */
|
||||
|
||||
/* BEGIN MERGE SLOT 10 */
|
||||
|
||||
/* END MERGE SLOT 10 */
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_CORE_H */
|
||||
|
@@ -77,7 +77,14 @@ void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m )
|
||||
switch( m->int_rep )
|
||||
{
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
mbedtls_free( m->rep.mont );
|
||||
if (m->rep.mont.rr != NULL)
|
||||
{
|
||||
mbedtls_platform_zeroize( (mbedtls_mpi_uint *) m->rep.mont.rr,
|
||||
m->limbs );
|
||||
mbedtls_free( (mbedtls_mpi_uint *)m->rep.mont.rr );
|
||||
m->rep.mont.rr = NULL;
|
||||
}
|
||||
m->rep.mont.mm = 0;
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
mbedtls_free( m->rep.ored );
|
||||
@@ -93,6 +100,41 @@ void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m )
|
||||
m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
|
||||
}
|
||||
|
||||
static int set_mont_const_square( const mbedtls_mpi_uint **X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi N;
|
||||
mbedtls_mpi RR;
|
||||
*X = NULL;
|
||||
|
||||
mbedtls_mpi_init( &N );
|
||||
mbedtls_mpi_init( &RR );
|
||||
|
||||
if ( A == NULL || limbs == 0 || limbs >= ( MBEDTLS_MPI_MAX_LIMBS / 2 ) - 2 )
|
||||
goto cleanup;
|
||||
|
||||
if ( mbedtls_mpi_grow( &N, limbs ) )
|
||||
goto cleanup;
|
||||
|
||||
memcpy( N.p, A, sizeof(mbedtls_mpi_uint) * limbs );
|
||||
|
||||
ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N);
|
||||
|
||||
if ( ret == 0 )
|
||||
{
|
||||
*X = RR.p;
|
||||
RR.p = NULL;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&N);
|
||||
mbedtls_mpi_free(&RR);
|
||||
ret = ( ret != 0 ) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0;
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs,
|
||||
@@ -120,7 +162,8 @@ int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m,
|
||||
{
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
m->int_rep = int_rep;
|
||||
m->rep.mont = NULL;
|
||||
m->rep.mont.mm = mbedtls_mpi_core_montmul_init( m->p );
|
||||
ret = set_mont_const_square( &m->rep.mont.rr, m->p, m->limbs );
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
m->int_rep = int_rep;
|
||||
@@ -141,4 +184,44 @@ exit:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* BEGIN MERGE SLOT 1 */
|
||||
|
||||
/* END MERGE SLOT 1 */
|
||||
|
||||
/* BEGIN MERGE SLOT 2 */
|
||||
|
||||
/* END MERGE SLOT 2 */
|
||||
|
||||
/* BEGIN MERGE SLOT 3 */
|
||||
|
||||
/* END MERGE SLOT 3 */
|
||||
|
||||
/* BEGIN MERGE SLOT 4 */
|
||||
|
||||
/* END MERGE SLOT 4 */
|
||||
|
||||
/* BEGIN MERGE SLOT 5 */
|
||||
|
||||
/* END MERGE SLOT 5 */
|
||||
|
||||
/* BEGIN MERGE SLOT 6 */
|
||||
|
||||
/* END MERGE SLOT 6 */
|
||||
|
||||
/* BEGIN MERGE SLOT 7 */
|
||||
|
||||
/* END MERGE SLOT 7 */
|
||||
|
||||
/* BEGIN MERGE SLOT 8 */
|
||||
|
||||
/* END MERGE SLOT 8 */
|
||||
|
||||
/* BEGIN MERGE SLOT 9 */
|
||||
|
||||
/* END MERGE SLOT 9 */
|
||||
|
||||
/* BEGIN MERGE SLOT 10 */
|
||||
|
||||
/* END MERGE SLOT 10 */
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
@@ -1,6 +1,10 @@
|
||||
/**
|
||||
* Modular bignum functions
|
||||
*
|
||||
* This module implements operations on integers modulo some fixed modulus.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -49,7 +53,11 @@ typedef struct
|
||||
size_t limbs;
|
||||
} mbedtls_mpi_mod_residue;
|
||||
|
||||
typedef void *mbedtls_mpi_mont_struct;
|
||||
typedef struct {
|
||||
mbedtls_mpi_uint const *rr; /* The residue for 2^{2*n*biL} mod N */
|
||||
mbedtls_mpi_uint mm; /* Montgomery const for -N^{-1} mod 2^{ciL} */
|
||||
} mbedtls_mpi_mont_struct;
|
||||
|
||||
typedef void *mbedtls_mpi_opt_red_struct;
|
||||
|
||||
typedef struct {
|
||||
@@ -140,4 +148,44 @@ int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m,
|
||||
*/
|
||||
void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m );
|
||||
|
||||
/* BEGIN MERGE SLOT 1 */
|
||||
|
||||
/* END MERGE SLOT 1 */
|
||||
|
||||
/* BEGIN MERGE SLOT 2 */
|
||||
|
||||
/* END MERGE SLOT 2 */
|
||||
|
||||
/* BEGIN MERGE SLOT 3 */
|
||||
|
||||
/* END MERGE SLOT 3 */
|
||||
|
||||
/* BEGIN MERGE SLOT 4 */
|
||||
|
||||
/* END MERGE SLOT 4 */
|
||||
|
||||
/* BEGIN MERGE SLOT 5 */
|
||||
|
||||
/* END MERGE SLOT 5 */
|
||||
|
||||
/* BEGIN MERGE SLOT 6 */
|
||||
|
||||
/* END MERGE SLOT 6 */
|
||||
|
||||
/* BEGIN MERGE SLOT 7 */
|
||||
|
||||
/* END MERGE SLOT 7 */
|
||||
|
||||
/* BEGIN MERGE SLOT 8 */
|
||||
|
||||
/* END MERGE SLOT 8 */
|
||||
|
||||
/* BEGIN MERGE SLOT 9 */
|
||||
|
||||
/* END MERGE SLOT 9 */
|
||||
|
||||
/* BEGIN MERGE SLOT 10 */
|
||||
|
||||
/* END MERGE SLOT 10 */
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_MOD_H */
|
||||
|
@@ -33,6 +33,22 @@
|
||||
#include "bignum_mod.h"
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
void mbedtls_mpi_mod_raw_cond_assign( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char assign )
|
||||
{
|
||||
mbedtls_mpi_core_cond_assign( X, A, N->limbs, assign );
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_raw_cond_swap( mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint *Y,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char swap )
|
||||
{
|
||||
mbedtls_mpi_core_cond_swap( X, Y, N->limbs, swap );
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_mod_modulus *m,
|
||||
const unsigned char *input,
|
||||
@@ -86,4 +102,44 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
|
||||
}
|
||||
}
|
||||
|
||||
/* BEGIN MERGE SLOT 1 */
|
||||
|
||||
/* END MERGE SLOT 1 */
|
||||
|
||||
/* BEGIN MERGE SLOT 2 */
|
||||
|
||||
/* END MERGE SLOT 2 */
|
||||
|
||||
/* BEGIN MERGE SLOT 3 */
|
||||
|
||||
/* END MERGE SLOT 3 */
|
||||
|
||||
/* BEGIN MERGE SLOT 4 */
|
||||
|
||||
/* END MERGE SLOT 4 */
|
||||
|
||||
/* BEGIN MERGE SLOT 5 */
|
||||
|
||||
/* END MERGE SLOT 5 */
|
||||
|
||||
/* BEGIN MERGE SLOT 6 */
|
||||
|
||||
/* END MERGE SLOT 6 */
|
||||
|
||||
/* BEGIN MERGE SLOT 7 */
|
||||
|
||||
/* END MERGE SLOT 7 */
|
||||
|
||||
/* BEGIN MERGE SLOT 8 */
|
||||
|
||||
/* END MERGE SLOT 8 */
|
||||
|
||||
/* BEGIN MERGE SLOT 9 */
|
||||
|
||||
/* END MERGE SLOT 9 */
|
||||
|
||||
/* BEGIN MERGE SLOT 10 */
|
||||
|
||||
/* END MERGE SLOT 10 */
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
@@ -6,6 +6,14 @@
|
||||
* modules should use the high-level modular bignum interface (bignum_mod.h)
|
||||
* or the legacy bignum interface (bignum.h).
|
||||
*
|
||||
* This is a low-level interface to operations on integers modulo which
|
||||
* has no protection against passing invalid arguments such as arrays of
|
||||
* the wrong size. The functions in bignum_mod.h provide a higher-level
|
||||
* interface that includes protections against accidental misuse, at the
|
||||
* expense of code size and sometimes more cumbersome memory management.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -33,6 +41,60 @@
|
||||
|
||||
#include "bignum_mod.h"
|
||||
|
||||
/**
|
||||
* \brief Perform a safe conditional copy of an MPI which doesn't reveal
|
||||
* whether the assignment was done or not.
|
||||
*
|
||||
* The size to copy is determined by \p N.
|
||||
*
|
||||
* \param[out] X The address of the destination MPI.
|
||||
* This must be initialized. Must have enough limbs to
|
||||
* store the full value of \p A.
|
||||
* \param[in] A The address of the source MPI. This must be initialized.
|
||||
* \param[in] N The address of the modulus related to \p X and \p A.
|
||||
* \param assign The condition deciding whether to perform the
|
||||
* assignment or not. Must be either 0 or 1:
|
||||
* * \c 1: Perform the assignment `X = A`.
|
||||
* * \c 0: Keep the original value of \p X.
|
||||
*
|
||||
* \note This function avoids leaking any information about whether
|
||||
* the assignment was done or not.
|
||||
*
|
||||
* \warning If \p assign is neither 0 nor 1, the result of this function
|
||||
* is indeterminate, and the resulting value in \p X might be
|
||||
* neither its original value nor the value in \p A.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_cond_assign( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char assign );
|
||||
|
||||
/**
|
||||
* \brief Perform a safe conditional swap of two MPIs which doesn't reveal
|
||||
* whether the swap was done or not.
|
||||
*
|
||||
* The size to swap is determined by \p N.
|
||||
*
|
||||
* \param[in,out] X The address of the first MPI. This must be initialized.
|
||||
* \param[in,out] Y The address of the second MPI. This must be initialized.
|
||||
* \param[in] N The address of the modulus related to \p X and \p Y.
|
||||
* \param swap The condition deciding whether to perform
|
||||
* the swap or not. Must be either 0 or 1:
|
||||
* * \c 1: Swap the values of \p X and \p Y.
|
||||
* * \c 0: Keep the original values of \p X and \p Y.
|
||||
*
|
||||
* \note This function avoids leaking any information about whether
|
||||
* the swap was done or not.
|
||||
*
|
||||
* \warning If \p swap is neither 0 nor 1, the result of this function
|
||||
* is indeterminate, and both \p X and \p Y might end up with
|
||||
* values different to either of the original ones.
|
||||
*/
|
||||
void mbedtls_mpi_mod_raw_cond_swap( mbedtls_mpi_uint *X,
|
||||
mbedtls_mpi_uint *Y,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char swap );
|
||||
|
||||
/** Import X from unsigned binary data.
|
||||
*
|
||||
* The MPI needs to have enough limbs to store the full value (including any
|
||||
@@ -76,4 +138,44 @@ int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
|
||||
unsigned char *output,
|
||||
size_t output_length );
|
||||
|
||||
/* BEGIN MERGE SLOT 1 */
|
||||
|
||||
/* END MERGE SLOT 1 */
|
||||
|
||||
/* BEGIN MERGE SLOT 2 */
|
||||
|
||||
/* END MERGE SLOT 2 */
|
||||
|
||||
/* BEGIN MERGE SLOT 3 */
|
||||
|
||||
/* END MERGE SLOT 3 */
|
||||
|
||||
/* BEGIN MERGE SLOT 4 */
|
||||
|
||||
/* END MERGE SLOT 4 */
|
||||
|
||||
/* BEGIN MERGE SLOT 5 */
|
||||
|
||||
/* END MERGE SLOT 5 */
|
||||
|
||||
/* BEGIN MERGE SLOT 6 */
|
||||
|
||||
/* END MERGE SLOT 6 */
|
||||
|
||||
/* BEGIN MERGE SLOT 7 */
|
||||
|
||||
/* END MERGE SLOT 7 */
|
||||
|
||||
/* BEGIN MERGE SLOT 8 */
|
||||
|
||||
/* END MERGE SLOT 8 */
|
||||
|
||||
/* BEGIN MERGE SLOT 9 */
|
||||
|
||||
/* END MERGE SLOT 9 */
|
||||
|
||||
/* BEGIN MERGE SLOT 10 */
|
||||
|
||||
/* END MERGE SLOT 10 */
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_MOD_RAW_H */
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "bignum_core.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C)
|
||||
@@ -678,21 +679,19 @@ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X,
|
||||
unsigned char assign )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t i;
|
||||
mbedtls_mpi_uint limb_mask;
|
||||
MPI_VALIDATE_RET( X != NULL );
|
||||
MPI_VALIDATE_RET( Y != NULL );
|
||||
|
||||
/* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
|
||||
limb_mask = mbedtls_ct_mpi_uint_mask( assign );;
|
||||
mbedtls_mpi_uint limb_mask = mbedtls_ct_mpi_uint_mask( assign );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
|
||||
|
||||
X->s = mbedtls_ct_cond_select_sign( assign, Y->s, X->s );
|
||||
|
||||
mbedtls_ct_mpi_uint_cond_assign( Y->n, X->p, Y->p, assign );
|
||||
mbedtls_mpi_core_cond_assign( X->p, Y->p, Y->n, assign );
|
||||
|
||||
for( i = Y->n; i < X->n; i++ )
|
||||
for( size_t i = Y->n; i < X->n; i++ )
|
||||
X->p[i] &= ~limb_mask;
|
||||
|
||||
cleanup:
|
||||
@@ -709,19 +708,14 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
|
||||
mbedtls_mpi *Y,
|
||||
unsigned char swap )
|
||||
{
|
||||
int ret, s;
|
||||
size_t i;
|
||||
mbedtls_mpi_uint limb_mask;
|
||||
mbedtls_mpi_uint tmp;
|
||||
int ret = 0;
|
||||
int s;
|
||||
MPI_VALIDATE_RET( X != NULL );
|
||||
MPI_VALIDATE_RET( Y != NULL );
|
||||
|
||||
if( X == Y )
|
||||
return( 0 );
|
||||
|
||||
/* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
|
||||
limb_mask = mbedtls_ct_mpi_uint_mask( swap );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
|
||||
|
||||
@@ -729,13 +723,7 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
|
||||
X->s = mbedtls_ct_cond_select_sign( swap, Y->s, X->s );
|
||||
Y->s = mbedtls_ct_cond_select_sign( swap, s, Y->s );
|
||||
|
||||
|
||||
for( i = 0; i < X->n; i++ )
|
||||
{
|
||||
tmp = X->p[i];
|
||||
X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
|
||||
Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
|
||||
}
|
||||
mbedtls_mpi_core_cond_swap( X->p, Y->p, X->n, swap );
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
|
@@ -46,7 +46,7 @@
|
||||
*/
|
||||
unsigned mbedtls_ct_uint_mask( unsigned value );
|
||||
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
|
||||
|
||||
/** Turn a value into a mask:
|
||||
* - if \p value == 0, return the all-bits 0 mask, aka 0
|
||||
@@ -61,7 +61,7 @@ unsigned mbedtls_ct_uint_mask( unsigned value );
|
||||
*/
|
||||
size_t mbedtls_ct_size_mask( size_t value );
|
||||
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
|
||||
|
@@ -71,10 +71,12 @@ static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp,
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* If multiplication is in progress, we already generated a privkey */
|
||||
int restarting = 0;
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( rs_ctx == NULL || rs_ctx->rsm == NULL )
|
||||
restarting = ( rs_ctx != NULL && rs_ctx->rsm != NULL );
|
||||
#endif
|
||||
/* If multiplication is in progress, we already generated a privkey */
|
||||
if( !restarting )
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G,
|
||||
|
@@ -2279,12 +2279,14 @@ cleanup:
|
||||
mbedtls_free( T );
|
||||
}
|
||||
|
||||
/* don't free R while in progress in case R == P */
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
|
||||
#endif
|
||||
/* prevent caller from using invalid value */
|
||||
if( ret != 0 )
|
||||
int should_free_R = ( ret != 0 );
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/* don't free R while in progress in case R == P */
|
||||
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
|
||||
should_free_R = 0;
|
||||
#endif
|
||||
if( should_free_R )
|
||||
mbedtls_ecp_point_free( R );
|
||||
|
||||
ECP_RS_LEAVE( rsm );
|
||||
@@ -2459,7 +2461,7 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
|
||||
|
||||
/* Loop invariant: R = result so far, RP = R + P */
|
||||
i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */
|
||||
i = grp->nbits + 1; /* one past the (zero-based) required msb for private keys */
|
||||
while( i-- > 0 )
|
||||
{
|
||||
b = mbedtls_mpi_get_bit( m, i );
|
||||
@@ -2529,10 +2531,12 @@ static int ecp_mul_restartable_internal( mbedtls_ecp_group *grp, mbedtls_ecp_poi
|
||||
MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
|
||||
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
||||
|
||||
int restarting = 0;
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/* skip argument check when restarting */
|
||||
if( rs_ctx == NULL || rs_ctx->rsm == NULL )
|
||||
restarting = ( rs_ctx != NULL && rs_ctx->rsm != NULL );
|
||||
#endif
|
||||
/* skip argument check when restarting */
|
||||
if( !restarting )
|
||||
{
|
||||
/* check_privkey is free */
|
||||
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK );
|
||||
@@ -2658,14 +2662,17 @@ static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
|
||||
|
||||
if( mbedtls_mpi_cmp_int( m, 0 ) == 0 )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_set_zero( R ) );
|
||||
}
|
||||
else if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
|
||||
}
|
||||
else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
|
||||
MPI_ECP_NEG( &R->Y );
|
||||
}
|
||||
|
826
library/lmots.c
Normal file
826
library/lmots.c
Normal file
@@ -0,0 +1,826 @@
|
||||
/*
|
||||
* The LM-OTS one-time public-key signature scheme
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following sources were referenced in the design of this implementation
|
||||
* of the LM-OTS algorithm:
|
||||
*
|
||||
* [1] IETF RFC8554
|
||||
* D. McGrew, M. Curcio, S.Fluhrer
|
||||
* https://datatracker.ietf.org/doc/html/rfc8554
|
||||
*
|
||||
* [2] NIST Special Publication 800-208
|
||||
* David A. Cooper et. al.
|
||||
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lmots.h"
|
||||
|
||||
#include "mbedtls/lms.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#define PUBLIC_KEY_TYPE_OFFSET (0)
|
||||
#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \
|
||||
MBEDTLS_LMOTS_TYPE_LEN)
|
||||
#define PUBLIC_KEY_Q_LEAF_ID_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN)
|
||||
#define PUBLIC_KEY_KEY_HASH_OFFSET (PUBLIC_KEY_Q_LEAF_ID_OFFSET + \
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN)
|
||||
|
||||
/* We only support parameter sets that use 8-bit digits, as it does not require
|
||||
* translation logic between digits and bytes */
|
||||
#define W_WINTERNITZ_PARAMETER (8u)
|
||||
#define CHECKSUM_LEN (2)
|
||||
#define I_DIGIT_IDX_LEN (2)
|
||||
#define J_HASH_IDX_LEN (1)
|
||||
#define D_CONST_LEN (2)
|
||||
|
||||
#define DIGIT_MAX_VALUE ((1u << W_WINTERNITZ_PARAMETER) - 1u)
|
||||
|
||||
#define D_CONST_LEN (2)
|
||||
static const unsigned char D_PUBLIC_CONSTANT_BYTES[D_CONST_LEN] = {0x80, 0x80};
|
||||
static const unsigned char D_MESSAGE_CONSTANT_BYTES[D_CONST_LEN] = {0x81, 0x81};
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
int( *mbedtls_lmots_sign_private_key_invalidated_hook )( unsigned char * ) = NULL;
|
||||
#endif /* defined(MBEDTLS_TEST_HOOKS) */
|
||||
|
||||
void mbedtls_lms_unsigned_int_to_network_bytes( unsigned int val, size_t len,
|
||||
unsigned char *bytes )
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
for ( idx = 0; idx < len; idx++ )
|
||||
{
|
||||
bytes[idx] = ( val >> ( ( len - 1 - idx ) * 8 ) ) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int mbedtls_lms_network_bytes_to_unsigned_int( size_t len,
|
||||
const unsigned char *bytes )
|
||||
{
|
||||
size_t idx;
|
||||
unsigned int val = 0;
|
||||
|
||||
for ( idx = 0; idx < len; idx++ )
|
||||
{
|
||||
val |= ( ( unsigned int )bytes[idx] ) << (8 * ( len - 1 - idx ) );
|
||||
}
|
||||
|
||||
return ( val );
|
||||
}
|
||||
|
||||
/* Calculate the checksum digits that are appended to the end of the LMOTS digit
|
||||
* string. See NIST SP800-208 section 3.1 or RFC8554 Algorithm 2 for details of
|
||||
* the checksum algorithm.
|
||||
*
|
||||
* params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* digest The digit string to create the digest from. As
|
||||
* this does not contain a checksum, it is the same
|
||||
* size as a hash output.
|
||||
*/
|
||||
static unsigned short lmots_checksum_calculate( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char* digest )
|
||||
{
|
||||
size_t idx;
|
||||
unsigned sum = 0;
|
||||
|
||||
for ( idx = 0; idx < MBEDTLS_LMOTS_N_HASH_LEN(params->type); idx++ )
|
||||
{
|
||||
sum += DIGIT_MAX_VALUE - digest[idx];
|
||||
}
|
||||
|
||||
return ( sum );
|
||||
}
|
||||
|
||||
/* Create the string of digest digits (in the base determined by the Winternitz
|
||||
* parameter with the checksum appended to the end (Q || cksm(Q)). See NIST
|
||||
* SP800-208 section 3.1 or RFC8554 Algorithm 3 step 5 (also used in Algorithm
|
||||
* 4b step 3) for details.
|
||||
*
|
||||
* params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* msg The message that will be hashed to create the
|
||||
* digest.
|
||||
*
|
||||
* msg_size The size of the message.
|
||||
*
|
||||
* C_random_value The random value that will be combined with the
|
||||
* message digest. This is always the same size as a
|
||||
* hash output for whichever hash algorithm is
|
||||
* determined by the parameter set.
|
||||
*
|
||||
* output An output containing the digit string (+
|
||||
* checksum) of length P digits (in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8, this means it is of
|
||||
* size P bytes).
|
||||
*/
|
||||
static int create_digit_array_with_checksum( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *msg,
|
||||
size_t msg_len,
|
||||
const unsigned char *C_random_value,
|
||||
unsigned char *out )
|
||||
{
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned short checksum;
|
||||
|
||||
status = psa_hash_setup( &op, PSA_ALG_SHA_256 );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, params->q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, D_MESSAGE_CONSTANT_BYTES, D_CONST_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, C_random_value,
|
||||
MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(params->type) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, msg, msg_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_finish( &op, out,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type),
|
||||
&output_hash_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
checksum = lmots_checksum_calculate( params, out );
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( checksum, CHECKSUM_LEN,
|
||||
out + MBEDTLS_LMOTS_N_HASH_LEN(params->type) );
|
||||
|
||||
exit:
|
||||
psa_hash_abort( &op );
|
||||
|
||||
return( mbedtls_lms_error_from_psa( status ) );
|
||||
}
|
||||
|
||||
/* Hash each element of the string of digits (+ checksum), producing a hash
|
||||
* output for each element. This is used in several places (by varying the
|
||||
* hash_idx_min/max_values) in order to calculate a public key from a private
|
||||
* key (RFC8554 Algorithm 1 step 4), in order to sign a message (RFC8554
|
||||
* Algorithm 3 step 5), and to calculate a public key candidate from a
|
||||
* signature and message (RFC8554 Algorithm 4b step 3).
|
||||
*
|
||||
* params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* x_digit_array The array of digits (of size P, 34 in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8).
|
||||
*
|
||||
* hash_idx_min_values An array of the starting values of the j iterator
|
||||
* for each of the members of the digit array. If
|
||||
* this value in NULL, then all iterators will start
|
||||
* at 0.
|
||||
*
|
||||
* hash_idx_max_values An array of the upper bound values of the j
|
||||
* iterator for each of the members of the digit
|
||||
* array. If this value in NULL, then iterator is
|
||||
* bounded to be less than 2^w - 1 (255 in the case
|
||||
* of MBEDTLS_LMOTS_SHA256_N32_W8)
|
||||
*
|
||||
* output An array containing a hash output for each member
|
||||
* of the digit string P. In the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8, this is of size 32 *
|
||||
* 34.
|
||||
*/
|
||||
static int hash_digit_array( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *x_digit_array,
|
||||
const unsigned char *hash_idx_min_values,
|
||||
const unsigned char *hash_idx_max_values,
|
||||
unsigned char *output )
|
||||
{
|
||||
unsigned int i_digit_idx;
|
||||
unsigned char i_digit_idx_bytes[I_DIGIT_IDX_LEN];
|
||||
unsigned int j_hash_idx;
|
||||
unsigned char j_hash_idx_bytes[J_HASH_IDX_LEN];
|
||||
unsigned int j_hash_idx_min;
|
||||
unsigned int j_hash_idx_max;
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned char tmp_hash[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
|
||||
for ( i_digit_idx = 0;
|
||||
i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type);
|
||||
i_digit_idx++ )
|
||||
{
|
||||
|
||||
memcpy( tmp_hash,
|
||||
&x_digit_array[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)],
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type) );
|
||||
|
||||
j_hash_idx_min = hash_idx_min_values != NULL ?
|
||||
hash_idx_min_values[i_digit_idx] : 0;
|
||||
j_hash_idx_max = hash_idx_max_values != NULL ?
|
||||
hash_idx_max_values[i_digit_idx] : DIGIT_MAX_VALUE;
|
||||
|
||||
for ( j_hash_idx = j_hash_idx_min;
|
||||
j_hash_idx < j_hash_idx_max;
|
||||
j_hash_idx++ )
|
||||
{
|
||||
status = psa_hash_setup( &op, PSA_ALG_SHA_256 );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op,
|
||||
params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op,
|
||||
params->q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( i_digit_idx,
|
||||
I_DIGIT_IDX_LEN,
|
||||
i_digit_idx_bytes );
|
||||
status = psa_hash_update( &op, i_digit_idx_bytes, I_DIGIT_IDX_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( j_hash_idx,
|
||||
J_HASH_IDX_LEN,
|
||||
j_hash_idx_bytes );
|
||||
status = psa_hash_update( &op, j_hash_idx_bytes, J_HASH_IDX_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, tmp_hash,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_finish( &op, tmp_hash, sizeof( tmp_hash ),
|
||||
&output_hash_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
psa_hash_abort( &op );
|
||||
}
|
||||
|
||||
memcpy( &output[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)],
|
||||
tmp_hash, MBEDTLS_LMOTS_N_HASH_LEN(params->type) );
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_hash_abort( &op );
|
||||
mbedtls_platform_zeroize( tmp_hash, sizeof( tmp_hash ) );
|
||||
|
||||
return( mbedtls_lms_error_from_psa( status ) );
|
||||
}
|
||||
|
||||
/* Combine the hashes of the digit array into a public key. This is used in
|
||||
* in order to calculate a public key from a private key (RFC8554 Algorithm 1
|
||||
* step 4), and to calculate a public key candidate from a signature and message
|
||||
* (RFC8554 Algorithm 4b step 3).
|
||||
*
|
||||
* params The LMOTS parameter set, I and q values which describe
|
||||
* the key being used.
|
||||
* y_hashed_digits The array of hashes, one hash for each digit of the
|
||||
* symbol array (which is of size P, 34 in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8)
|
||||
*
|
||||
* pub_key The output public key (or candidate public key in
|
||||
* case this is being run as part of signature
|
||||
* verification), in the form of a hash output.
|
||||
*/
|
||||
static int public_key_from_hashed_digit_array( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *y_hashed_digits,
|
||||
unsigned char *pub_key )
|
||||
{
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
|
||||
status = psa_hash_setup( &op, PSA_ALG_SHA_256 );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op,
|
||||
params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, params->q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, D_PUBLIC_CONSTANT_BYTES, D_CONST_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, y_hashed_digits,
|
||||
MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type) *
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_finish( &op, pub_key,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type),
|
||||
&output_hash_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
|
||||
exit:
|
||||
psa_hash_abort( &op );
|
||||
|
||||
return( mbedtls_lms_error_from_psa( status ) );
|
||||
}
|
||||
|
||||
int mbedtls_lms_error_from_psa( psa_status_t status )
|
||||
{
|
||||
switch( status )
|
||||
{
|
||||
case PSA_SUCCESS:
|
||||
return( 0 );
|
||||
case PSA_ERROR_HARDWARE_FAILURE:
|
||||
return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
|
||||
case PSA_ERROR_BUFFER_TOO_SMALL:
|
||||
return( MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL );
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
default:
|
||||
return( MBEDTLS_ERR_ERROR_GENERIC_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_lmots_public_init( mbedtls_lmots_public_t *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( *ctx ) ) ;
|
||||
}
|
||||
|
||||
void mbedtls_lmots_public_free( mbedtls_lmots_public_t *ctx )
|
||||
{
|
||||
mbedtls_platform_zeroize( ctx, sizeof( *ctx ) ) ;
|
||||
}
|
||||
|
||||
int mbedtls_lmots_import_public_key( mbedtls_lmots_public_t *ctx,
|
||||
const unsigned char *key, size_t key_len )
|
||||
{
|
||||
if( key_len < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
ctx->params.type =
|
||||
mbedtls_lms_network_bytes_to_unsigned_int( MBEDTLS_LMOTS_TYPE_LEN,
|
||||
key + MBEDTLS_LMOTS_SIG_TYPE_OFFSET );
|
||||
|
||||
if( key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
memcpy( ctx->params.I_key_identifier,
|
||||
key + PUBLIC_KEY_I_KEY_ID_OFFSET,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
|
||||
memcpy( ctx->params.q_leaf_identifier,
|
||||
key + PUBLIC_KEY_Q_LEAF_ID_OFFSET,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN );
|
||||
|
||||
memcpy( ctx->public_key,
|
||||
key + PUBLIC_KEY_KEY_HASH_OFFSET,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type) );
|
||||
|
||||
ctx->have_public_key = 1;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_lmots_export_public_key( const mbedtls_lmots_public_t *ctx,
|
||||
unsigned char *key, size_t key_size,
|
||||
size_t *key_len )
|
||||
{
|
||||
if( key_size < MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
if( ! ctx->have_public_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( ctx->params.type,
|
||||
MBEDTLS_LMOTS_TYPE_LEN,
|
||||
key + MBEDTLS_LMOTS_SIG_TYPE_OFFSET );
|
||||
|
||||
memcpy( key + PUBLIC_KEY_I_KEY_ID_OFFSET,
|
||||
ctx->params.I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
|
||||
memcpy( key + PUBLIC_KEY_Q_LEAF_ID_OFFSET,
|
||||
ctx->params.q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN );
|
||||
|
||||
memcpy( key + PUBLIC_KEY_KEY_HASH_OFFSET, ctx->public_key,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type) );
|
||||
|
||||
if( key_len != NULL )
|
||||
{
|
||||
*key_len = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type);
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_lmots_calculate_public_key_candidate( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *msg,
|
||||
size_t msg_size,
|
||||
const unsigned char *sig,
|
||||
size_t sig_size,
|
||||
unsigned char *out,
|
||||
size_t out_size,
|
||||
size_t *out_len )
|
||||
{
|
||||
unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX];
|
||||
unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( msg == NULL && msg_size != 0 )
|
||||
{
|
||||
return ( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( sig_size != MBEDTLS_LMOTS_SIG_LEN(params->type) ||
|
||||
out_size < MBEDTLS_LMOTS_N_HASH_LEN(params->type) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
ret = create_digit_array_with_checksum( params, msg, msg_size,
|
||||
sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET,
|
||||
tmp_digit_array );
|
||||
if( ret )
|
||||
{
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
ret = hash_digit_array( params,
|
||||
sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(params->type),
|
||||
tmp_digit_array, NULL, ( unsigned char * )y_hashed_digits );
|
||||
if( ret )
|
||||
{
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
ret = public_key_from_hashed_digit_array( params,
|
||||
( unsigned char * )y_hashed_digits,
|
||||
out );
|
||||
if( ret )
|
||||
{
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
if( out_len != NULL )
|
||||
{
|
||||
*out_len = MBEDTLS_LMOTS_N_HASH_LEN(params->type);
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_lmots_verify( const mbedtls_lmots_public_t *ctx,
|
||||
const unsigned char *msg, size_t msg_size,
|
||||
const unsigned char *sig, size_t sig_size )
|
||||
{
|
||||
unsigned char Kc_public_key_candidate[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( msg == NULL && msg_size != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( !ctx->have_public_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( ctx->params.type != MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( sig_size < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( mbedtls_lms_network_bytes_to_unsigned_int( MBEDTLS_LMOTS_TYPE_LEN,
|
||||
sig + MBEDTLS_LMOTS_SIG_TYPE_OFFSET ) != MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
ret = mbedtls_lmots_calculate_public_key_candidate( &ctx->params,
|
||||
msg, msg_size, sig, sig_size,
|
||||
Kc_public_key_candidate,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type),
|
||||
NULL );
|
||||
if( ret )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( memcmp( &Kc_public_key_candidate, ctx->public_key,
|
||||
sizeof( ctx->public_key ) ) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
|
||||
void mbedtls_lmots_private_init( mbedtls_lmots_private_t *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( *ctx ) ) ;
|
||||
}
|
||||
|
||||
void mbedtls_lmots_private_free( mbedtls_lmots_private_t *ctx )
|
||||
{
|
||||
mbedtls_platform_zeroize( ctx, sizeof( *ctx ) ) ;
|
||||
}
|
||||
|
||||
int mbedtls_lmots_generate_private_key( mbedtls_lmots_private_t *ctx,
|
||||
mbedtls_lmots_algorithm_type_t type,
|
||||
const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN],
|
||||
uint32_t q_leaf_identifier,
|
||||
const unsigned char *seed,
|
||||
size_t seed_size )
|
||||
{
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned int i_digit_idx;
|
||||
unsigned char i_digit_idx_bytes[2];
|
||||
unsigned char const_bytes[1];
|
||||
|
||||
if( ctx->have_private_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( type != MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
ctx->params.type = type;
|
||||
|
||||
memcpy( ctx->params.I_key_identifier,
|
||||
I_key_identifier,
|
||||
sizeof( ctx->params.I_key_identifier ) );
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN,
|
||||
ctx->params.q_leaf_identifier );
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( 0xFF, sizeof( const_bytes ),
|
||||
const_bytes );
|
||||
|
||||
for ( i_digit_idx = 0;
|
||||
i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type);
|
||||
i_digit_idx++ )
|
||||
{
|
||||
status = psa_hash_setup( &op, PSA_ALG_SHA_256 );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op,
|
||||
ctx->params.I_key_identifier,
|
||||
sizeof( ctx->params.I_key_identifier ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op,
|
||||
ctx->params.q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( i_digit_idx, I_DIGIT_IDX_LEN,
|
||||
i_digit_idx_bytes );
|
||||
status = psa_hash_update( &op, i_digit_idx_bytes, I_DIGIT_IDX_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, const_bytes, sizeof( const_bytes ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, seed, seed_size );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_finish( &op,
|
||||
ctx->private_key[i_digit_idx],
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type),
|
||||
&output_hash_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
psa_hash_abort( &op );
|
||||
}
|
||||
|
||||
ctx->have_private_key = 1;
|
||||
|
||||
exit:
|
||||
psa_hash_abort( &op );
|
||||
|
||||
return ( mbedtls_lms_error_from_psa( status ) );
|
||||
}
|
||||
|
||||
int mbedtls_lmots_calculate_public_key( mbedtls_lmots_public_t *ctx,
|
||||
const mbedtls_lmots_private_t *priv_ctx )
|
||||
{
|
||||
unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* Check that a private key is loaded */
|
||||
if( !priv_ctx->have_private_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
ret = hash_digit_array( &priv_ctx->params,
|
||||
( unsigned char * )priv_ctx->private_key, NULL,
|
||||
NULL, ( unsigned char * )y_hashed_digits );
|
||||
if( ret )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = public_key_from_hashed_digit_array( &priv_ctx->params,
|
||||
( unsigned char * )y_hashed_digits,
|
||||
ctx->public_key );
|
||||
if( ret )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy( &ctx->params, &priv_ctx->params,
|
||||
sizeof( ctx->params ) );
|
||||
|
||||
ctx->have_public_key = 1;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( y_hashed_digits, sizeof( y_hashed_digits ) );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_lmots_sign( mbedtls_lmots_private_t *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, const unsigned char *msg, size_t msg_size,
|
||||
unsigned char *sig, size_t sig_size, size_t* sig_len )
|
||||
{
|
||||
unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX];
|
||||
/* Create a temporary buffer to prepare the signature in. This allows us to
|
||||
* finish creating a signature (ensuring the process doesn't fail), and then
|
||||
* erase the private key **before** writing any data into the sig parameter
|
||||
* buffer. If data were directly written into the sig buffer, it might leak
|
||||
* a partial signature on failure, which effectively compromises the private
|
||||
* key.
|
||||
*/
|
||||
unsigned char tmp_sig[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
unsigned char tmp_c_random[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( msg == NULL && msg_size != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( sig_size < MBEDTLS_LMOTS_SIG_LEN(ctx->params.type) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
/* Check that a private key is loaded */
|
||||
if( !ctx->have_private_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
ret = f_rng( p_rng, tmp_c_random,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type) );
|
||||
if( ret )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
ret = create_digit_array_with_checksum( &ctx->params,
|
||||
msg, msg_size,
|
||||
tmp_c_random,
|
||||
tmp_digit_array );
|
||||
if( ret )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = hash_digit_array( &ctx->params, ( unsigned char * )ctx->private_key,
|
||||
NULL, tmp_digit_array, ( unsigned char * )tmp_sig );
|
||||
if( ret )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( ctx->params.type,
|
||||
MBEDTLS_LMOTS_TYPE_LEN,
|
||||
sig + MBEDTLS_LMOTS_SIG_TYPE_OFFSET );
|
||||
|
||||
/* Test hook to check if sig is being written to before we invalidate the
|
||||
* private key.
|
||||
*/
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
if( mbedtls_lmots_sign_private_key_invalidated_hook != NULL )
|
||||
{
|
||||
ret = ( *mbedtls_lmots_sign_private_key_invalidated_hook )( sig );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
#endif /* defined(MBEDTLS_TEST_HOOKS) */
|
||||
|
||||
/* We've got a valid signature now, so it's time to make sure the private
|
||||
* key can't be reused.
|
||||
*/
|
||||
ctx->have_private_key = 0;
|
||||
mbedtls_platform_zeroize( ctx->private_key,
|
||||
sizeof( ctx->private_key ) );
|
||||
|
||||
memcpy( sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, tmp_c_random,
|
||||
MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(ctx->params.type) );
|
||||
|
||||
memcpy( sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(ctx->params.type), tmp_sig,
|
||||
MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type)
|
||||
* MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type) );
|
||||
|
||||
if( sig_len != NULL )
|
||||
{
|
||||
*sig_len = MBEDTLS_LMOTS_SIG_LEN(ctx->params.type);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( tmp_digit_array, sizeof( tmp_digit_array ) );
|
||||
mbedtls_platform_zeroize( tmp_sig, sizeof( tmp_sig ) );
|
||||
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
#endif /* defined(MBEDTLS_LMS_C) */
|
322
library/lmots.h
Normal file
322
library/lmots.h
Normal file
@@ -0,0 +1,322 @@
|
||||
/**
|
||||
* \file lmots.h
|
||||
*
|
||||
* \brief This file provides an API for the LM-OTS post-quantum-safe one-time
|
||||
* public-key signature scheme as defined in RFC8554 and NIST.SP.200-208.
|
||||
* This implementation currently only supports a single parameter set
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8 in order to reduce complexity.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_LMOTS_H
|
||||
#define MBEDTLS_LMOTS_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "mbedtls/lms.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#define MBEDTLS_LMOTS_PUBLIC_KEY_LEN(type) (MBEDTLS_LMOTS_TYPE_LEN + \
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN + \
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN + \
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(type))
|
||||
|
||||
#define MBEDTLS_LMOTS_SIG_TYPE_OFFSET (0)
|
||||
#define MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET (MBEDTLS_LMOTS_SIG_TYPE_OFFSET + \
|
||||
MBEDTLS_LMOTS_TYPE_LEN)
|
||||
#define MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(type) (MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET + \
|
||||
MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
extern int( *mbedtls_lmots_sign_private_key_invalidated_hook )( unsigned char * );
|
||||
#endif /* defined(MBEDTLS_TEST_HOOKS) */
|
||||
|
||||
/**
|
||||
* \brief This function converts an unsigned int into a
|
||||
* network-byte-order (big endian) string.
|
||||
*
|
||||
* \param val The unsigned integer value
|
||||
* \param len The length of the string.
|
||||
* \param bytes The string to output into.
|
||||
*/
|
||||
void mbedtls_lms_unsigned_int_to_network_bytes( unsigned int val, size_t len,
|
||||
unsigned char *bytes );
|
||||
|
||||
/**
|
||||
* \brief This function converts a network-byte-order
|
||||
* (big endian) string into an unsigned integer.
|
||||
*
|
||||
* \param len The length of the string.
|
||||
* \param bytes The string.
|
||||
*
|
||||
* \return The corresponding LMS error code.
|
||||
*/
|
||||
unsigned int mbedtls_lms_network_bytes_to_unsigned_int( size_t len,
|
||||
const unsigned char *bytes );
|
||||
|
||||
/**
|
||||
* \brief This function converts a \ref psa_status_t to a
|
||||
* low-level LMS error code.
|
||||
*
|
||||
* \param status The psa_status_t to convert
|
||||
*
|
||||
* \return The corresponding LMS error code.
|
||||
*/
|
||||
int mbedtls_lms_error_from_psa( psa_status_t status );
|
||||
|
||||
|
||||
/**
|
||||
* \brief This function initializes a public LMOTS context
|
||||
*
|
||||
* \param ctx The uninitialized LMOTS context that will then be
|
||||
* initialized.
|
||||
*/
|
||||
void mbedtls_lmots_public_init( mbedtls_lmots_public_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function uninitializes a public LMOTS context
|
||||
*
|
||||
* \param ctx The initialized LMOTS context that will then be
|
||||
* uninitialized.
|
||||
*/
|
||||
void mbedtls_lmots_public_free( mbedtls_lmots_public_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function imports an LMOTS public key into a
|
||||
* LMOTS context.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized.
|
||||
*
|
||||
* \note See IETF RFC8554 for details of the encoding of
|
||||
* this public key.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context store the key in.
|
||||
* \param key The buffer from which the key will be read.
|
||||
* #MBEDTLS_LMOTS_PUBLIC_KEY_LEN bytes will be read
|
||||
* from this.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_import_public_key( mbedtls_lmots_public_t *ctx,
|
||||
const unsigned char *key, size_t key_size );
|
||||
|
||||
/**
|
||||
* \brief This function exports an LMOTS public key from a
|
||||
* LMOTS context that already contains a public key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and the context must contain
|
||||
* a public key.
|
||||
*
|
||||
* \note See IETF RFC8554 for details of the encoding of
|
||||
* this public key.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context that contains the
|
||||
* publc key.
|
||||
* \param key The buffer into which the key will be output. Must
|
||||
* be at least #MBEDTLS_LMOTS_PUBLIC_KEY_LEN in size.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_export_public_key( const mbedtls_lmots_public_t *ctx,
|
||||
unsigned char *key, size_t key_size,
|
||||
size_t *key_len );
|
||||
|
||||
/**
|
||||
* \brief This function creates a candidate public key from
|
||||
* an LMOTS signature. This can then be compared to
|
||||
* the real public key to determine the validity of
|
||||
* the signature.
|
||||
*
|
||||
* \note This function is exposed publicly to be used in LMS
|
||||
* signature verification, it is expected that
|
||||
* mbedtls_lmots_verify will be used for LMOTS
|
||||
* signature verification.
|
||||
*
|
||||
* \param params The LMOTS parameter set, q and I values as an
|
||||
* mbedtls_lmots_parameters_t struct.
|
||||
* \param msg The buffer from which the message will be read.
|
||||
* \param msg_size The size of the message that will be read.
|
||||
* \param sig The buffer from which the signature will be read.
|
||||
* #MBEDTLS_LMOTS_SIG_LEN bytes will be read from
|
||||
* this.
|
||||
* \param out The buffer where the candidate public key will be
|
||||
* stored. Must be at least #MBEDTLS_LMOTS_N_HASH_LEN
|
||||
* bytes in size.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_calculate_public_key_candidate( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *msg,
|
||||
size_t msg_size,
|
||||
const unsigned char *sig,
|
||||
size_t sig_size,
|
||||
unsigned char *out,
|
||||
size_t out_size,
|
||||
size_t *out_len );
|
||||
|
||||
/**
|
||||
* \brief This function verifies a LMOTS signature, using a
|
||||
* LMOTS context that contains a public key.
|
||||
*
|
||||
* \warning This function is **not intended for use in
|
||||
* production**, due to as-yet unsolved problems with
|
||||
* handling stateful keys. The API for this function
|
||||
* may change considerably in future versions.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and must contain a public key
|
||||
* (either by import or calculation from a private
|
||||
* key).
|
||||
*
|
||||
* \param ctx The initialized LMOTS context from which the public
|
||||
* key will be read.
|
||||
* \param msg The buffer from which the message will be read.
|
||||
* \param msg_size The size of the message that will be read.
|
||||
* \param sig The buf from which the signature will be read.
|
||||
* #MBEDTLS_LMOTS_SIG_LEN bytes will be read from
|
||||
* this.
|
||||
*
|
||||
* \return \c 0 on successful verification.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_verify( const mbedtls_lmots_public_t *ctx,
|
||||
const unsigned char *msg,
|
||||
size_t msg_size, const unsigned char *sig,
|
||||
size_t sig_size );
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
|
||||
/**
|
||||
* \brief This function initializes a private LMOTS context
|
||||
*
|
||||
* \param ctx The uninitialized LMOTS context that will then be
|
||||
* initialized.
|
||||
*/
|
||||
void mbedtls_lmots_private_init( mbedtls_lmots_private_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function uninitializes a private LMOTS context
|
||||
*
|
||||
* \param ctx The initialized LMOTS context that will then be
|
||||
* uninitialized.
|
||||
*/
|
||||
void mbedtls_lmots_private_free( mbedtls_lmots_private_t *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function calculates an LMOTS private key, and
|
||||
* stores in into an LMOTS context.
|
||||
*
|
||||
* \warning This function is **not intended for use in
|
||||
* production**, due to as-yet unsolved problems with
|
||||
* handling stateful keys. The API for this function
|
||||
* may change considerably in future versions.
|
||||
*
|
||||
* \note The seed must have at least 256 bits of entropy.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context to generate the key
|
||||
* into.
|
||||
* \param I_key_identifier The key identifier of the key, as a 16-byte string.
|
||||
* \param q_leaf_identifier The leaf identifier of key. If this LMOTS key is
|
||||
* not being used as part of an LMS key, this should
|
||||
* be set to 0.
|
||||
* \param seed The seed used to deterministically generate the
|
||||
* key.
|
||||
* \param seed_size The length of the seed.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_generate_private_key( mbedtls_lmots_private_t *ctx,
|
||||
mbedtls_lmots_algorithm_type_t type,
|
||||
const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN],
|
||||
uint32_t q_leaf_identifier,
|
||||
const unsigned char *seed,
|
||||
size_t seed_size );
|
||||
|
||||
/**
|
||||
* \brief This function generates an LMOTS public key from a
|
||||
* LMOTS context that already contains a private key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and the context must contain
|
||||
* a private key.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context to generate the key
|
||||
* from and store it into.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_calculate_public_key( mbedtls_lmots_public_t *ctx,
|
||||
const mbedtls_lmots_private_t *priv_ctx );
|
||||
|
||||
/**
|
||||
* \brief This function creates a LMOTS signature, using a
|
||||
* LMOTS context that contains a private key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and must contain a private
|
||||
* key.
|
||||
*
|
||||
* \note LMOTS private keys can only be used once, otherwise
|
||||
* attackers may be able to create forged signatures.
|
||||
* If the signing operation is successful, the private
|
||||
* key in the context will be erased, and no further
|
||||
* signing will be possible until another private key
|
||||
* is loaded
|
||||
*
|
||||
* \param ctx The initialized LMOTS context from which the
|
||||
* private key will be read.
|
||||
* \param f_rng The RNG function to be used for signature
|
||||
* generation.
|
||||
* \param p_rng The RNG context to be passed to f_rng
|
||||
* \param msg The buffer from which the message will be read.
|
||||
* \param msg_size The size of the message that will be read.
|
||||
* \param sig The buf into which the signature will be stored.
|
||||
* Must be at least #MBEDTLS_LMOTS_SIG_LEN in size.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lmots_sign( mbedtls_lmots_private_t *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, const unsigned char *msg, size_t msg_size,
|
||||
unsigned char *sig, size_t sig_size, size_t* sig_len );
|
||||
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_LMOTS_H */
|
789
library/lms.c
Normal file
789
library/lms.c
Normal file
@@ -0,0 +1,789 @@
|
||||
/*
|
||||
* The LMS stateful-hash public-key signature scheme
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following sources were referenced in the design of this implementation
|
||||
* of the LMS algorithm:
|
||||
*
|
||||
* [1] IETF RFC8554
|
||||
* D. McGrew, M. Curcio, S.Fluhrer
|
||||
* https://datatracker.ietf.org/doc/html/rfc8554
|
||||
*
|
||||
* [2] NIST Special Publication 800-208
|
||||
* David A. Cooper et. al.
|
||||
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lmots.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "mbedtls/lms.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#define SIG_Q_LEAF_ID_OFFSET (0)
|
||||
#define SIG_OTS_SIG_OFFSET (SIG_Q_LEAF_ID_OFFSET + \
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN)
|
||||
#define SIG_TYPE_OFFSET(otstype) (SIG_OTS_SIG_OFFSET + \
|
||||
MBEDTLS_LMOTS_SIG_LEN(otstype))
|
||||
#define SIG_PATH_OFFSET(otstype) (SIG_TYPE_OFFSET(otstype) + \
|
||||
MBEDTLS_LMS_TYPE_LEN)
|
||||
|
||||
#define PUBLIC_KEY_TYPE_OFFSET (0)
|
||||
#define PUBLIC_KEY_OTSTYPE_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \
|
||||
MBEDTLS_LMS_TYPE_LEN)
|
||||
#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_OTSTYPE_OFFSET + \
|
||||
MBEDTLS_LMOTS_TYPE_LEN)
|
||||
#define PUBLIC_KEY_ROOT_NODE_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN)
|
||||
|
||||
|
||||
/* Currently only support H=10 */
|
||||
#define H_TREE_HEIGHT_MAX 10
|
||||
#define MERKLE_TREE_NODE_AM_MAX (1u << (H_TREE_HEIGHT_MAX + 1u))
|
||||
#define MERKLE_TREE_NODE_AM(type) (1u << (MBEDTLS_LMS_H_TREE_HEIGHT(type) + 1u))
|
||||
#define MERKLE_TREE_LEAF_NODE_AM(type) (1u << MBEDTLS_LMS_H_TREE_HEIGHT(type))
|
||||
#define MERKLE_TREE_INTERNAL_NODE_AM(type) (1u << MBEDTLS_LMS_H_TREE_HEIGHT(type))
|
||||
|
||||
#define D_CONST_LEN (2)
|
||||
static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = {0x82, 0x82};
|
||||
static const unsigned char D_INTR_CONSTANT_BYTES[D_CONST_LEN] = {0x83, 0x83};
|
||||
|
||||
|
||||
/* Calculate the value of a leaf node of the Merkle tree (which is a hash of a
|
||||
* public key and some other parameters like the leaf index). This function
|
||||
* implements RFC8554 section 5.3, in the case where r >= 2^h.
|
||||
*
|
||||
* params The LMS parameter set, the underlying LMOTS
|
||||
* parameter set, and I value which describe the key
|
||||
* being used.
|
||||
*
|
||||
* pub_key The public key of the private whose index
|
||||
* corresponds to the index of this leaf node. This
|
||||
* is a hash output.
|
||||
*
|
||||
* r_node_idx The index of this node in the Merkle tree. Note
|
||||
* that the root node of the Merkle tree is
|
||||
* 1-indexed.
|
||||
*
|
||||
* out The output node value, which is a hash output.
|
||||
*/
|
||||
static int create_merkle_leaf_value( const mbedtls_lms_parameters_t *params,
|
||||
unsigned char *pub_key,
|
||||
unsigned int r_node_idx,
|
||||
unsigned char *out )
|
||||
{
|
||||
psa_hash_operation_t op;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned char r_node_idx_bytes[4];
|
||||
|
||||
op = psa_hash_operation_init( );
|
||||
status = psa_hash_setup( &op, PSA_ALG_SHA_256 );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( r_node_idx, 4, r_node_idx_bytes );
|
||||
status = psa_hash_update( &op, r_node_idx_bytes, 4 );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, D_LEAF_CONSTANT_BYTES, D_CONST_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, pub_key,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->otstype) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_finish( &op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type),
|
||||
&output_hash_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
psa_hash_abort( &op );
|
||||
|
||||
return ( mbedtls_lms_error_from_psa( status ) );
|
||||
}
|
||||
|
||||
/* Calculate the value of an internal node of the Merkle tree (which is a hash
|
||||
* of a public key and some other parameters like the node index). This function
|
||||
* implements RFC8554 section 5.3, in the case where r < 2^h.
|
||||
*
|
||||
* params The LMS parameter set, the underlying LMOTS
|
||||
* parameter set, and I value which describe the key
|
||||
* being used.
|
||||
*
|
||||
* left_node The value of the child of this node which is on
|
||||
* the left-hand side. As with all nodes on the
|
||||
* Merkle tree, this is a hash output.
|
||||
*
|
||||
* right_node The value of the child of this node which is on
|
||||
* the right-hand side. As with all nodes on the
|
||||
* Merkle tree, this is a hash output.
|
||||
*
|
||||
* r_node_idx The index of this node in the Merkle tree. Note
|
||||
* that the root node of the Merkle tree is
|
||||
* 1-indexed.
|
||||
*
|
||||
* out The output node value, which is a hash output.
|
||||
*/
|
||||
static int create_merkle_internal_value( const mbedtls_lms_parameters_t *params,
|
||||
const unsigned char *left_node,
|
||||
const unsigned char *right_node,
|
||||
unsigned int r_node_idx,
|
||||
unsigned char *out )
|
||||
{
|
||||
psa_hash_operation_t op;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned char r_node_idx_bytes[4];
|
||||
|
||||
op = psa_hash_operation_init( );
|
||||
status = psa_hash_setup( &op, PSA_ALG_SHA_256 );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( r_node_idx, 4, r_node_idx_bytes );
|
||||
status = psa_hash_update( &op, r_node_idx_bytes, 4 );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, D_INTR_CONSTANT_BYTES, D_CONST_LEN );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, left_node,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(params->type) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_update( &op, right_node,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(params->type) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
status = psa_hash_finish( &op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type),
|
||||
&output_hash_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
psa_hash_abort( &op );
|
||||
|
||||
return( mbedtls_lms_error_from_psa( status ) );
|
||||
}
|
||||
|
||||
void mbedtls_lms_public_init( mbedtls_lms_public_t *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( *ctx ) ) ;
|
||||
}
|
||||
|
||||
void mbedtls_lms_public_free( mbedtls_lms_public_t *ctx )
|
||||
{
|
||||
mbedtls_platform_zeroize( ctx, sizeof( *ctx ) );
|
||||
}
|
||||
|
||||
int mbedtls_lms_import_public_key( mbedtls_lms_public_t *ctx,
|
||||
const unsigned char *key, size_t key_size )
|
||||
{
|
||||
mbedtls_lms_algorithm_type_t type;
|
||||
mbedtls_lmots_algorithm_type_t otstype;
|
||||
|
||||
type = mbedtls_lms_network_bytes_to_unsigned_int( MBEDTLS_LMS_TYPE_LEN,
|
||||
key + PUBLIC_KEY_TYPE_OFFSET );
|
||||
if( type != MBEDTLS_LMS_SHA256_M32_H10 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
ctx->params.type = type;
|
||||
|
||||
if( key_size != MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
otstype = mbedtls_lms_network_bytes_to_unsigned_int( MBEDTLS_LMOTS_TYPE_LEN,
|
||||
key + PUBLIC_KEY_OTSTYPE_OFFSET );
|
||||
if( otstype != MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
ctx->params.otstype = otstype;
|
||||
|
||||
memcpy( ctx->params.I_key_identifier,
|
||||
key + PUBLIC_KEY_I_KEY_ID_OFFSET,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
memcpy( ctx->T_1_pub_key, key + PUBLIC_KEY_ROOT_NODE_OFFSET,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type) );
|
||||
|
||||
ctx->have_public_key = 1;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_lms_export_public_key( const mbedtls_lms_public_t *ctx,
|
||||
unsigned char *key,
|
||||
size_t key_size, size_t *key_len )
|
||||
{
|
||||
if( key_size < MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
if( ! ctx->have_public_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes(
|
||||
ctx->params.type,
|
||||
MBEDTLS_LMS_TYPE_LEN, key + PUBLIC_KEY_TYPE_OFFSET );
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( ctx->params.otstype,
|
||||
MBEDTLS_LMOTS_TYPE_LEN,
|
||||
key + PUBLIC_KEY_OTSTYPE_OFFSET );
|
||||
memcpy( key + PUBLIC_KEY_I_KEY_ID_OFFSET,
|
||||
ctx->params.I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
memcpy( key +PUBLIC_KEY_ROOT_NODE_OFFSET,
|
||||
ctx->T_1_pub_key,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type) );
|
||||
|
||||
if( key_len != NULL )
|
||||
{
|
||||
*key_len = MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type);
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_lms_verify( const mbedtls_lms_public_t *ctx,
|
||||
const unsigned char *msg, size_t msg_size,
|
||||
const unsigned char *sig, size_t sig_size )
|
||||
{
|
||||
unsigned int q_leaf_identifier;
|
||||
unsigned char Kc_candidate_ots_pub_key[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
unsigned char Tc_candidate_root_node[MBEDTLS_LMS_M_NODE_BYTES_MAX];
|
||||
unsigned int height;
|
||||
unsigned int curr_node_id;
|
||||
unsigned int parent_node_id;
|
||||
const unsigned char* left_node;
|
||||
const unsigned char* right_node;
|
||||
mbedtls_lmots_parameters_t ots_params;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( ! ctx->have_public_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( ctx->params.type
|
||||
!= MBEDTLS_LMS_SHA256_M32_H10 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( ctx->params.otstype
|
||||
!= MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( sig_size != MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( sig_size < SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_TYPE_LEN )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( mbedtls_lms_network_bytes_to_unsigned_int( MBEDTLS_LMOTS_TYPE_LEN,
|
||||
sig + SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_SIG_TYPE_OFFSET )
|
||||
!= MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( sig_size < SIG_TYPE_OFFSET(ctx->params.otstype) + MBEDTLS_LMS_TYPE_LEN )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( mbedtls_lms_network_bytes_to_unsigned_int( MBEDTLS_LMS_TYPE_LEN,
|
||||
sig + SIG_TYPE_OFFSET(ctx->params.otstype))
|
||||
!= MBEDTLS_LMS_SHA256_M32_H10 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
|
||||
q_leaf_identifier = mbedtls_lms_network_bytes_to_unsigned_int(
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN, sig + SIG_Q_LEAF_ID_OFFSET );
|
||||
|
||||
if( q_leaf_identifier >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
memcpy( ots_params.I_key_identifier,
|
||||
ctx->params.I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN,
|
||||
ots_params.q_leaf_identifier );
|
||||
ots_params.type = ctx->params.otstype;
|
||||
|
||||
ret = mbedtls_lmots_calculate_public_key_candidate( &ots_params, msg,
|
||||
msg_size, sig + SIG_OTS_SIG_OFFSET,
|
||||
MBEDTLS_LMOTS_SIG_LEN(ctx->params.otstype), Kc_candidate_ots_pub_key,
|
||||
sizeof( Kc_candidate_ots_pub_key ), NULL );
|
||||
if( ret != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
create_merkle_leaf_value(
|
||||
&ctx->params,
|
||||
Kc_candidate_ots_pub_key,
|
||||
MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
|
||||
Tc_candidate_root_node );
|
||||
|
||||
curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) +
|
||||
q_leaf_identifier;
|
||||
|
||||
for( height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type);
|
||||
height++ )
|
||||
{
|
||||
parent_node_id = curr_node_id / 2;
|
||||
|
||||
/* Left/right node ordering matters for the hash */
|
||||
if( curr_node_id & 1 )
|
||||
{
|
||||
left_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) +
|
||||
height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
|
||||
right_node = Tc_candidate_root_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_node = Tc_candidate_root_node;
|
||||
right_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) +
|
||||
height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
|
||||
}
|
||||
|
||||
create_merkle_internal_value( &ctx->params, left_node, right_node,
|
||||
parent_node_id, Tc_candidate_root_node);
|
||||
|
||||
curr_node_id /= 2;
|
||||
}
|
||||
|
||||
if( memcmp( Tc_candidate_root_node, ctx->T_1_pub_key,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
|
||||
/* Calculate a full Merkle tree based on a private key. This function
|
||||
* implements RFC8554 section 5.3, and is used to generate a public key (as the
|
||||
* public key is the root node of the Merkle tree).
|
||||
*
|
||||
* ctx The LMS private context, containing a parameter
|
||||
* set and private key material consisting of both
|
||||
* public and private OTS.
|
||||
*
|
||||
* tree The output tree, which is 2^(H + 1) hash outputs.
|
||||
* In the case of H=10 we have 2048 tree nodes (of
|
||||
* which 1024 of them are leaf nodes). Note that
|
||||
* because the Merkle tree root is 1-indexed, the 0
|
||||
* index tree node is never used.
|
||||
*/
|
||||
static int calculate_merkle_tree( const mbedtls_lms_private_t *ctx,
|
||||
unsigned char *tree )
|
||||
{
|
||||
unsigned int priv_key_idx;
|
||||
unsigned int r_node_idx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* First create the leaf nodes, in ascending order */
|
||||
for( priv_key_idx = 0;
|
||||
priv_key_idx < MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type);
|
||||
priv_key_idx++ )
|
||||
{
|
||||
r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + priv_key_idx;
|
||||
|
||||
ret = create_merkle_leaf_value( &ctx->params,
|
||||
ctx->ots_public_keys[priv_key_idx].public_key, r_node_idx,
|
||||
&tree[r_node_idx * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)] );
|
||||
if( ret != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
|
||||
/* Then the internal nodes, in reverse order so that we can guarantee the
|
||||
* parent has been created */
|
||||
for( r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) - 1;
|
||||
r_node_idx > 0;
|
||||
r_node_idx-- )
|
||||
{
|
||||
ret = create_merkle_internal_value( &ctx->params,
|
||||
&tree[( r_node_idx * 2 ) * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)],
|
||||
&tree[( r_node_idx * 2 + 1 ) * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)],
|
||||
r_node_idx,
|
||||
&tree[r_node_idx * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)] );
|
||||
if( ret != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Calculate a path from a leaf node of the Merkle tree to the root of the tree,
|
||||
* and return the full path. This function implements RFC8554 section 5.4.1, as
|
||||
* the Merkle path is the main component of an LMS signature.
|
||||
*
|
||||
* ctx The LMS private context, containing a parameter
|
||||
* set and private key material consisting of both
|
||||
* public and private OTS.
|
||||
*
|
||||
* leaf_node_id Which leaf node to calculate the path from.
|
||||
*
|
||||
* path The output path, which is H hash outputs.
|
||||
*/
|
||||
static int get_merkle_path( mbedtls_lms_private_t *ctx,
|
||||
unsigned int leaf_node_id,
|
||||
unsigned char *path )
|
||||
{
|
||||
unsigned char tree[MERKLE_TREE_NODE_AM_MAX][MBEDTLS_LMS_M_NODE_BYTES_MAX];
|
||||
unsigned int curr_node_id = leaf_node_id;
|
||||
unsigned int adjacent_node_id;
|
||||
unsigned int height;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
ret = calculate_merkle_tree( ctx, ( unsigned char * )tree );
|
||||
if( ret != 0 )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for( height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type);
|
||||
height++ )
|
||||
{
|
||||
adjacent_node_id = curr_node_id ^ 1;
|
||||
|
||||
memcpy( &path[height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)],
|
||||
&tree[adjacent_node_id],
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type) );
|
||||
|
||||
curr_node_id >>=1;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( tree, sizeof( tree ) );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
void mbedtls_lms_private_init( mbedtls_lms_private_t *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( *ctx ) ) ;
|
||||
}
|
||||
|
||||
void mbedtls_lms_private_free( mbedtls_lms_private_t *ctx )
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
if( ctx->have_private_key )
|
||||
{
|
||||
if( ctx->ots_private_keys != NULL )
|
||||
{
|
||||
for( idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++ )
|
||||
{
|
||||
mbedtls_lmots_private_free( &ctx->ots_private_keys[idx] );
|
||||
}
|
||||
}
|
||||
|
||||
if( ctx->ots_public_keys != NULL )
|
||||
{
|
||||
for( idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++ )
|
||||
{
|
||||
mbedtls_lmots_public_free( &ctx->ots_public_keys[idx] );
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_free( ctx->ots_private_keys );
|
||||
mbedtls_free( ctx->ots_public_keys );
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize( ctx, sizeof( *ctx ) );
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_lms_generate_private_key( mbedtls_lms_private_t *ctx,
|
||||
mbedtls_lms_algorithm_type_t type,
|
||||
mbedtls_lmots_algorithm_type_t otstype,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void* p_rng, const unsigned char *seed,
|
||||
size_t seed_size )
|
||||
{
|
||||
unsigned int idx = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( type != MBEDTLS_LMS_SHA256_M32_H10 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( otstype != MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( ctx->have_private_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
ctx->params.type = type;
|
||||
ctx->params.otstype = otstype;
|
||||
ctx->have_private_key = 1;
|
||||
|
||||
ret = f_rng( p_rng,
|
||||
ctx->params.I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN );
|
||||
if( ret != 0 )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Requires a cast to size_t to avoid an implicit cast warning on certain
|
||||
* platforms (particularly Windows) */
|
||||
ctx->ots_private_keys = mbedtls_calloc( ( size_t )MERKLE_TREE_LEAF_NODE_AM(ctx->params.type),
|
||||
sizeof( *ctx->ots_private_keys ) );
|
||||
if( ctx->ots_private_keys == NULL )
|
||||
{
|
||||
ret = MBEDTLS_ERR_LMS_ALLOC_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Requires a cast to size_t to avoid an implicit cast warning on certain
|
||||
* platforms (particularly Windows) */
|
||||
ctx->ots_public_keys = mbedtls_calloc( ( size_t )MERKLE_TREE_LEAF_NODE_AM(ctx->params.type),
|
||||
sizeof( *ctx->ots_public_keys ) );
|
||||
if( ctx->ots_public_keys == NULL )
|
||||
{
|
||||
ret = MBEDTLS_ERR_LMS_ALLOC_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for( idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++ )
|
||||
{
|
||||
mbedtls_lmots_private_init( &ctx->ots_private_keys[idx] );
|
||||
mbedtls_lmots_public_init( &ctx->ots_public_keys[idx] );
|
||||
}
|
||||
|
||||
|
||||
for( idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++ )
|
||||
{
|
||||
ret = mbedtls_lmots_generate_private_key( &ctx->ots_private_keys[idx],
|
||||
otstype,
|
||||
ctx->params.I_key_identifier,
|
||||
idx, seed, seed_size );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_lmots_calculate_public_key( &ctx->ots_public_keys[idx],
|
||||
&ctx->ots_private_keys[idx] );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ctx->q_next_usable_key = 0;
|
||||
|
||||
exit:
|
||||
if( ret != 0 )
|
||||
{
|
||||
mbedtls_lms_private_free(ctx);
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_lms_calculate_public_key( mbedtls_lms_public_t *ctx,
|
||||
const mbedtls_lms_private_t *priv_ctx )
|
||||
{
|
||||
unsigned char tree[MERKLE_TREE_NODE_AM_MAX][MBEDTLS_LMS_M_NODE_BYTES_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( ! priv_ctx->have_private_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( priv_ctx->params.type
|
||||
!= MBEDTLS_LMS_SHA256_M32_H10 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( priv_ctx->params.otstype
|
||||
!= MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
memcpy( &ctx->params, &priv_ctx->params,
|
||||
sizeof( mbedtls_lmots_parameters_t ) );
|
||||
|
||||
ret = calculate_merkle_tree( priv_ctx, ( unsigned char * )tree );
|
||||
if( ret != 0 )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Root node is always at position 1, due to 1-based indexing */
|
||||
memcpy( ctx->T_1_pub_key, &tree[1],
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type) );
|
||||
|
||||
ctx->have_public_key = 1;
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( tree, sizeof( tree ) );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_lms_sign( mbedtls_lms_private_t *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void* p_rng, const unsigned char *msg,
|
||||
unsigned int msg_size, unsigned char *sig, size_t sig_size,
|
||||
size_t *sig_len )
|
||||
{
|
||||
uint32_t q_leaf_identifier;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( ! ctx->have_private_key )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( sig_size < MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
if( ctx->params.type != MBEDTLS_LMS_SHA256_M32_H10 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( ctx->params.otstype
|
||||
!= MBEDTLS_LMOTS_SHA256_N32_W8 )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( ctx->q_next_usable_key >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type) )
|
||||
{
|
||||
return( MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS );
|
||||
}
|
||||
|
||||
|
||||
q_leaf_identifier = ctx->q_next_usable_key;
|
||||
/* This new value must _always_ be written back to the disk before the
|
||||
* signature is returned.
|
||||
*/
|
||||
ctx->q_next_usable_key += 1;
|
||||
|
||||
if ( MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)
|
||||
< SIG_OTS_SIG_OFFSET )
|
||||
{
|
||||
return ( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
ret = mbedtls_lmots_sign( &ctx->ots_private_keys[q_leaf_identifier],
|
||||
f_rng, p_rng, msg, msg_size,
|
||||
sig + SIG_OTS_SIG_OFFSET,
|
||||
MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype) - SIG_OTS_SIG_OFFSET,
|
||||
NULL );
|
||||
if( ret != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( ctx->params.type,
|
||||
MBEDTLS_LMS_TYPE_LEN,
|
||||
sig + SIG_TYPE_OFFSET(ctx->params.otstype) );
|
||||
mbedtls_lms_unsigned_int_to_network_bytes( q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN,
|
||||
sig + SIG_Q_LEAF_ID_OFFSET );
|
||||
|
||||
ret = get_merkle_path( ctx,
|
||||
MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
|
||||
sig + SIG_PATH_OFFSET(ctx->params.otstype) );
|
||||
if( ret != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( sig_len != NULL )
|
||||
{
|
||||
*sig_len = MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype);
|
||||
}
|
||||
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
#endif /* defined(MBEDTLS_LMS_C) */
|
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "psa_crypto_aead.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* PSA cipher driver entry points
|
||||
* PSA cipher driver entry points and associated auxiliary functions
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
|
@@ -246,22 +246,6 @@ psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
|
||||
*/
|
||||
psa_status_t mbedtls_to_psa_error( int ret );
|
||||
|
||||
/** Get Mbed TLS cipher information given the cipher algorithm PSA identifier
|
||||
* as well as the PSA type and size of the key to be used with the cipher
|
||||
* algorithm.
|
||||
*
|
||||
* \param alg PSA cipher algorithm identifier
|
||||
* \param key_type PSA key type
|
||||
* \param key_bits Size of the key in bits
|
||||
* \param[out] cipher_id Mbed TLS cipher algorithm identifier
|
||||
*
|
||||
* \return The Mbed TLS cipher information of the cipher algorithm.
|
||||
* \c NULL if the PSA cipher algorithm is not supported.
|
||||
*/
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
|
||||
psa_algorithm_t alg, psa_key_type_t key_type, size_t key_bits,
|
||||
mbedtls_cipher_id_t *cipher_id );
|
||||
|
||||
/** Import a key in binary format.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver
|
||||
|
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
#include "psa_crypto_mac.h"
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
|
@@ -230,7 +230,7 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
|
||||
operation->input_step = PSA_PAKE_STEP_X1_X2;
|
||||
operation->output_step = PSA_PAKE_STEP_X1_X2;
|
||||
|
||||
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
|
||||
@@ -385,7 +385,8 @@ static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
|
||||
}
|
||||
#endif
|
||||
|
||||
psa_status_t psa_pake_output( psa_pake_operation_t *operation,
|
||||
static psa_status_t psa_pake_output_internal(
|
||||
psa_pake_operation_t *operation,
|
||||
psa_pake_step_t step,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
@@ -427,10 +428,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
|
||||
if( operation->state == PSA_PAKE_STATE_SETUP ) {
|
||||
status = psa_pake_ecjpake_setup( operation );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
psa_pake_abort( operation );
|
||||
return( status );
|
||||
}
|
||||
}
|
||||
|
||||
if( operation->state != PSA_PAKE_STATE_READY &&
|
||||
@@ -491,15 +489,12 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
|
||||
{
|
||||
ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake,
|
||||
operation->buffer,
|
||||
PSA_PAKE_BUFFER_SIZE,
|
||||
MBEDTLS_PSA_PAKE_BUFFER_SIZE,
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE );
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_pake_abort( operation );
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
}
|
||||
|
||||
operation->buffer_offset = 0;
|
||||
}
|
||||
@@ -508,68 +503,47 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
|
||||
{
|
||||
ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake,
|
||||
operation->buffer,
|
||||
PSA_PAKE_BUFFER_SIZE,
|
||||
MBEDTLS_PSA_PAKE_BUFFER_SIZE,
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE );
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_pake_abort( operation );
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
}
|
||||
|
||||
operation->buffer_offset = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Steps sequences are stored as:
|
||||
* struct {
|
||||
* opaque point <1..2^8-1>;
|
||||
* } ECPoint;
|
||||
* mbedtls_ecjpake_write_round_xxx() outputs thing in the format
|
||||
* defined by draft-cragie-tls-ecjpake-01 section 7. The summary is
|
||||
* that the data for each step is prepended with a length byte, and
|
||||
* then they're concatenated. Additionally, the server's second round
|
||||
* output is prepended with a 3-bytes ECParameters structure.
|
||||
*
|
||||
* Where byte 0 stores the ECPoint curve point length.
|
||||
*
|
||||
* The sequence length is equal to:
|
||||
* - data length extracted from byte 0
|
||||
* - byte 0 size (1)
|
||||
* In PSA, we output each step separately, and don't prepend the
|
||||
* output with a length byte, even less a curve identifier, as that
|
||||
* information is already available.
|
||||
*/
|
||||
if( operation->state == PSA_PAKE_OUTPUT_X2S &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
|
||||
operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
|
||||
operation->role == PSA_PAKE_ROLE_SERVER )
|
||||
{
|
||||
if( operation->role == PSA_PAKE_ROLE_SERVER )
|
||||
/*
|
||||
* The X2S KEY SHARE Server steps sequence is stored as:
|
||||
* struct {
|
||||
* ECPoint X;
|
||||
* opaque r <1..2^8-1>;
|
||||
* } ECSchnorrZKP;
|
||||
*
|
||||
* And MbedTLS uses a 3 bytes Ephemeral public key ECPoint,
|
||||
* so byte 3 stores the r Schnorr signature length.
|
||||
*
|
||||
* The sequence length is equal to:
|
||||
* - curve storage size (3)
|
||||
* - data length extracted from byte 3
|
||||
* - byte 3 size (1)
|
||||
*/
|
||||
length = 3 + operation->buffer[3] + 1;
|
||||
else
|
||||
length = operation->buffer[0] + 1;
|
||||
/* Skip ECParameters, with is 3 bytes (RFC 8422) */
|
||||
operation->buffer_offset += 3;
|
||||
}
|
||||
else
|
||||
length = operation->buffer[operation->buffer_offset] + 1;
|
||||
|
||||
if( length > operation->buffer_length )
|
||||
/* Read the length byte then move past it to the data */
|
||||
length = operation->buffer[operation->buffer_offset];
|
||||
operation->buffer_offset += 1;
|
||||
|
||||
if( operation->buffer_offset + length > operation->buffer_length )
|
||||
return( PSA_ERROR_DATA_CORRUPT );
|
||||
|
||||
if( output_size < length )
|
||||
{
|
||||
psa_pake_abort( operation );
|
||||
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
memcpy( output,
|
||||
operation->buffer + operation->buffer_offset,
|
||||
operation->buffer + operation->buffer_offset,
|
||||
length );
|
||||
*output_length = length;
|
||||
|
||||
@@ -581,7 +555,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
|
||||
( operation->state == PSA_PAKE_OUTPUT_X2S &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
|
||||
{
|
||||
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
|
||||
@@ -599,14 +573,29 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
psa_status_t psa_pake_input( psa_pake_operation_t *operation,
|
||||
psa_status_t psa_pake_output( psa_pake_operation_t *operation,
|
||||
psa_pake_step_t step,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length )
|
||||
{
|
||||
psa_status_t status = psa_pake_output_internal(
|
||||
operation, step, output, output_size, output_length );
|
||||
|
||||
if( status != PSA_SUCCESS )
|
||||
psa_pake_abort( operation );
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
static psa_status_t psa_pake_input_internal(
|
||||
psa_pake_operation_t *operation,
|
||||
psa_pake_step_t step,
|
||||
const uint8_t *input,
|
||||
size_t input_length )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t buffer_remain;
|
||||
|
||||
if( operation->alg == PSA_ALG_NONE ||
|
||||
operation->state == PSA_PAKE_STATE_INVALID )
|
||||
@@ -638,14 +627,16 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
|
||||
step != PSA_PAKE_STEP_ZK_PROOF )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
const psa_pake_primitive_t prim = PSA_PAKE_PRIMITIVE(
|
||||
PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256 );
|
||||
if( input_length > (size_t) PSA_PAKE_INPUT_SIZE( PSA_ALG_JPAKE, prim, step ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
if( operation->state == PSA_PAKE_STATE_SETUP )
|
||||
{
|
||||
status = psa_pake_ecjpake_setup( operation );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
psa_pake_abort( operation );
|
||||
return( status );
|
||||
}
|
||||
}
|
||||
|
||||
if( operation->state != PSA_PAKE_STATE_READY &&
|
||||
@@ -675,15 +666,6 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
|
||||
operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
|
||||
}
|
||||
|
||||
buffer_remain = PSA_PAKE_BUFFER_SIZE - operation->buffer_length;
|
||||
|
||||
if( input_length == 0 ||
|
||||
input_length > buffer_remain )
|
||||
{
|
||||
psa_pake_abort( operation );
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
}
|
||||
|
||||
/* Check if step matches current sequence */
|
||||
switch( operation->sequence )
|
||||
{
|
||||
@@ -709,7 +691,35 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
/* Copy input to local buffer */
|
||||
/*
|
||||
* Copy input to local buffer and format it as the Mbed TLS API
|
||||
* expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
|
||||
* The summary is that the data for each step is prepended with a
|
||||
* length byte, and then they're concatenated. Additionally, the
|
||||
* server's second round output is prepended with a 3-bytes
|
||||
* ECParameters structure - which means we have to prepend that when
|
||||
* we're a client.
|
||||
*/
|
||||
if( operation->state == PSA_PAKE_INPUT_X4S &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
|
||||
operation->role == PSA_PAKE_ROLE_CLIENT )
|
||||
{
|
||||
/* We only support secp256r1. */
|
||||
/* This is the ECParameters structure defined by RFC 8422. */
|
||||
unsigned char ecparameters[3] = {
|
||||
3, /* named_curve */
|
||||
0, 23 /* secp256r1 */
|
||||
};
|
||||
memcpy( operation->buffer + operation->buffer_length,
|
||||
ecparameters, sizeof( ecparameters ) );
|
||||
operation->buffer_length += sizeof( ecparameters );
|
||||
}
|
||||
|
||||
/* Write the length byte */
|
||||
operation->buffer[operation->buffer_length] = (uint8_t) input_length;
|
||||
operation->buffer_length += 1;
|
||||
|
||||
/* Finally copy the data */
|
||||
memcpy( operation->buffer + operation->buffer_length,
|
||||
input, input_length );
|
||||
operation->buffer_length += input_length;
|
||||
@@ -722,14 +732,11 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
|
||||
operation->buffer,
|
||||
operation->buffer_length );
|
||||
|
||||
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_pake_abort( operation );
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
}
|
||||
}
|
||||
else if( operation->state == PSA_PAKE_INPUT_X4S &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF )
|
||||
@@ -738,14 +745,11 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
|
||||
operation->buffer,
|
||||
operation->buffer_length );
|
||||
|
||||
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_pake_abort( operation );
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( operation->state == PSA_PAKE_INPUT_X1_X2 &&
|
||||
@@ -767,6 +771,20 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
psa_status_t psa_pake_input( psa_pake_operation_t *operation,
|
||||
psa_pake_step_t step,
|
||||
const uint8_t *input,
|
||||
size_t input_length )
|
||||
{
|
||||
psa_status_t status = psa_pake_input_internal(
|
||||
operation, step, input, input_length );
|
||||
|
||||
if( status != PSA_SUCCESS )
|
||||
psa_pake_abort( operation );
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
|
||||
psa_key_derivation_operation_t *output)
|
||||
{
|
||||
@@ -784,7 +802,7 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
|
||||
{
|
||||
ret = mbedtls_ecjpake_write_shared_key( &operation->ctx.ecjpake,
|
||||
operation->buffer,
|
||||
PSA_PAKE_BUFFER_SIZE,
|
||||
MBEDTLS_PSA_PAKE_BUFFER_SIZE,
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE );
|
||||
@@ -799,7 +817,7 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
|
||||
operation->buffer,
|
||||
operation->buffer_length );
|
||||
|
||||
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
|
||||
psa_pake_abort( operation );
|
||||
|
||||
@@ -824,7 +842,7 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
|
||||
operation->output_step = PSA_PAKE_STEP_INVALID;
|
||||
operation->password = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
operation->role = PSA_PAKE_ROLE_NONE;
|
||||
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
mbedtls_ecjpake_free( &operation->ctx.ecjpake );
|
||||
|
@@ -655,9 +655,11 @@ int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
|
||||
MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
|
||||
MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
|
||||
|
||||
int truncated = 0;
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
if( ctx->is224 == 0 )
|
||||
truncated = ctx->is224;
|
||||
#endif
|
||||
if( !truncated )
|
||||
MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
|
||||
|
||||
return( 0 );
|
||||
|
@@ -810,9 +810,11 @@ int mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
|
||||
sha512_put_uint64_be( ctx->state[4], output, 32 );
|
||||
sha512_put_uint64_be( ctx->state[5], output, 40 );
|
||||
|
||||
int truncated = 0;
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
if( ctx->is384 == 0 )
|
||||
truncated = ctx->is384;
|
||||
#endif
|
||||
if( !truncated )
|
||||
{
|
||||
sha512_put_uint64_be( ctx->state[6], output, 48 );
|
||||
sha512_put_uint64_be( ctx->state[7], output, 56 );
|
||||
|
@@ -370,9 +370,11 @@ static int ssl_write_client_hello_cipher_suites(
|
||||
/*
|
||||
* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
|
||||
*/
|
||||
int renegotiating = 0;
|
||||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
|
||||
renegotiating = ( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE );
|
||||
#endif
|
||||
if( !renegotiating )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) );
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
|
||||
@@ -608,7 +610,7 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
if(
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
( propose_tls13 && mbedtls_ssl_conf_tls13_ephemeral_enabled( ssl ) ) ||
|
||||
@@ -623,7 +625,7 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl,
|
||||
return( ret );
|
||||
p += output_len;
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( propose_tls12 )
|
||||
@@ -637,8 +639,7 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/* The "pre_shared_key" extension (RFC 8446 Section 4.2.11)
|
||||
* MUST be the last extension in the ClientHello.
|
||||
*/
|
||||
@@ -650,7 +651,7 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl,
|
||||
return( ret );
|
||||
p += output_len;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
/* Write the length of the list of extensions. */
|
||||
extensions_len = p - p_extensions_len - 2;
|
||||
@@ -812,9 +813,12 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
||||
* RFC 5077 section 3.4: "When presenting a ticket, the client MAY
|
||||
* generate and include a Session ID in the TLS ClientHello."
|
||||
*/
|
||||
int renegotiating = 0;
|
||||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
|
||||
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
|
||||
renegotiating = 1;
|
||||
#endif
|
||||
if( !renegotiating )
|
||||
{
|
||||
if( ( session_negotiate->ticket != NULL ) &&
|
||||
( session_negotiate->ticket_len != 0 ) )
|
||||
@@ -957,8 +961,7 @@ int mbedtls_ssl_write_client_hello( mbedtls_ssl_context *ssl )
|
||||
mbedtls_ssl_add_hs_hdr_to_checksum( ssl, MBEDTLS_SSL_HS_CLIENT_HELLO,
|
||||
msg_len );
|
||||
ssl->handshake->update_checksum( ssl, buf, msg_len - binders_len );
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
if( binders_len > 0 )
|
||||
{
|
||||
MBEDTLS_SSL_PROC_CHK(
|
||||
@@ -967,7 +970,7 @@ int mbedtls_ssl_write_client_hello( mbedtls_ssl_context *ssl )
|
||||
ssl->handshake->update_checksum( ssl, buf + msg_len - binders_len,
|
||||
binders_len );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg( ssl,
|
||||
buf_len,
|
||||
|
@@ -38,8 +38,8 @@
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is
|
||||
* available. Try SHA-256 first, 512 wastes resources
|
||||
* If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-384 is
|
||||
* available. Try SHA-256 first, 384 wastes resources
|
||||
*/
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_224_VIA_LOWLEVEL_OR_PSA)
|
||||
#define COOKIE_MD MBEDTLS_MD_SHA224
|
||||
|
@@ -245,7 +245,7 @@
|
||||
|
||||
#define MBEDTLS_RECEIVED_SIG_ALGS_SIZE 20
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
|
||||
#define MBEDTLS_TLS_SIG_NONE MBEDTLS_TLS1_3_SIG_NONE
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
#define MBEDTLS_SSL_TLS12_HASH_ALG_FROM_SIG_AND_HASH_ALG(alg) (alg >> 8)
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
/*
|
||||
* Check that we obey the standard's message size bounds
|
||||
@@ -600,8 +600,6 @@ struct mbedtls_ssl_handshake_params
|
||||
size_t ecrs_n; /*!< place for saving a length */
|
||||
#endif
|
||||
|
||||
size_t pmslen; /*!< premaster length */
|
||||
|
||||
mbedtls_ssl_ciphersuite_t const *ciphersuite_info;
|
||||
|
||||
void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
|
||||
@@ -621,7 +619,7 @@ struct mbedtls_ssl_handshake_params
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/** selected_group of key_share extension in HelloRetryRequest message. */
|
||||
uint16_t hrr_selected_group;
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
uint8_t tls13_kex_modes; /*!< Key exchange modes supported by the client */
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
@@ -631,7 +629,7 @@ struct mbedtls_ssl_handshake_params
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
uint16_t received_sig_algs[MBEDTLS_RECEIVED_SIG_ALGS_SIZE];
|
||||
#endif
|
||||
|
||||
@@ -677,7 +675,7 @@ struct mbedtls_ssl_handshake_params
|
||||
const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_svc_key_id_t psk_opaque; /*!< Opaque PSK from the callback */
|
||||
uint8_t psk_opaque_is_internal;
|
||||
@@ -686,7 +684,7 @@ struct mbedtls_ssl_handshake_params
|
||||
size_t psk_len; /*!< Length of PSK from callback */
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
uint16_t selected_identity;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */
|
||||
@@ -853,15 +851,18 @@ struct mbedtls_ssl_handshake_params
|
||||
unsigned char randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN +
|
||||
MBEDTLS_SERVER_HELLO_RANDOM_LEN];
|
||||
/*!< random bytes */
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
unsigned char premaster[MBEDTLS_PREMASTER_SIZE];
|
||||
/*!< premaster secret */
|
||||
size_t pmslen; /*!< premaster length */
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
int extensions_present; /*!< extension presence; Each bitfield
|
||||
represents an extension and defined
|
||||
as \c MBEDTLS_SSL_EXT_XXX */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
unsigned char certificate_request_context_len;
|
||||
unsigned char *certificate_request_context;
|
||||
#endif
|
||||
@@ -1365,11 +1366,13 @@ MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl,
|
||||
mbedtls_key_exchange_type_t key_ex );
|
||||
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
|
||||
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_conf_has_static_psk( mbedtls_ssl_config const *conf );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
/**
|
||||
* Get the first defined opaque PSK by order of precedence:
|
||||
@@ -1422,7 +1425,7 @@ static inline int mbedtls_ssl_get_psk( const mbedtls_ssl_context *ssl,
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_PK_C)
|
||||
unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk );
|
||||
@@ -1784,7 +1787,8 @@ static inline int mbedtls_ssl_conf_tls13_some_psk_enabled( mbedtls_ssl_context *
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL ) );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_SRV_C) && \
|
||||
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/**
|
||||
* Given a list of key exchange modes, check if at least one of them is
|
||||
* supported.
|
||||
@@ -1831,7 +1835,8 @@ static inline int mbedtls_ssl_tls13_some_psk_enabled( mbedtls_ssl_context *ssl )
|
||||
return( ! mbedtls_ssl_tls13_check_kex_modes( ssl,
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL ) );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_SRV_C &&
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
/*
|
||||
* Helper functions to check the selected key exchange mode.
|
||||
@@ -1871,7 +1876,7 @@ int mbedtls_ssl_tls13_fetch_handshake_msg( mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_process_certificate( mbedtls_ssl_context *ssl );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
/*
|
||||
* Handler of TLS 1.3 write Certificate message
|
||||
*/
|
||||
@@ -1884,7 +1889,7 @@ int mbedtls_ssl_tls13_write_certificate( mbedtls_ssl_context *ssl );
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_write_certificate_verify( mbedtls_ssl_context *ssl );
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
* Generic handler of Certificate Verify
|
||||
@@ -1914,7 +1919,7 @@ int mbedtls_ssl_tls13_generate_and_write_ecdh_key_exchange(
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
/*
|
||||
* Parse TLS Signature Algorithm extension
|
||||
*/
|
||||
@@ -1922,7 +1927,7 @@ MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end );
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
/* Get handshake transcript */
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
@@ -2042,7 +2047,7 @@ static inline int mbedtls_ssl_named_group_is_supported( uint16_t named_group )
|
||||
static inline const void *mbedtls_ssl_get_sig_algs(
|
||||
const mbedtls_ssl_context *ssl )
|
||||
{
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
if( ssl->handshake != NULL &&
|
||||
@@ -2054,17 +2059,14 @@ static inline const void *mbedtls_ssl_get_sig_algs(
|
||||
#endif
|
||||
return( ssl->conf->sig_algs );
|
||||
|
||||
#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#else /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
((void) ssl);
|
||||
return( NULL );
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
}
|
||||
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
static inline int mbedtls_ssl_sig_alg_is_received( const mbedtls_ssl_context *ssl,
|
||||
uint16_t own_sig_alg )
|
||||
{
|
||||
@@ -2079,61 +2081,7 @@ static inline int mbedtls_ssl_sig_alg_is_received( const mbedtls_ssl_context *ss
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
static inline int mbedtls_ssl_sig_alg_is_offered( const mbedtls_ssl_context *ssl,
|
||||
uint16_t proposed_sig_alg )
|
||||
{
|
||||
const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs( ssl );
|
||||
if( sig_alg == NULL )
|
||||
return( 0 );
|
||||
|
||||
for( ; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++ )
|
||||
{
|
||||
if( *sig_alg == proposed_sig_alg )
|
||||
return( 1 );
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static inline int mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(
|
||||
uint16_t sig_alg, mbedtls_pk_type_t *pk_type, mbedtls_md_type_t *md_alg )
|
||||
{
|
||||
*pk_type = mbedtls_ssl_pk_alg_from_sig( sig_alg & 0xff );
|
||||
*md_alg = mbedtls_ssl_md_alg_from_hash( ( sig_alg >> 8 ) & 0xff );
|
||||
|
||||
if( *pk_type != MBEDTLS_PK_NONE && *md_alg != MBEDTLS_MD_NONE )
|
||||
return( 0 );
|
||||
|
||||
switch( sig_alg )
|
||||
{
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
*md_alg = MBEDTLS_MD_SHA256;
|
||||
*pk_type = MBEDTLS_PK_RSASSA_PSS;
|
||||
break;
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
*md_alg = MBEDTLS_MD_SHA384;
|
||||
*pk_type = MBEDTLS_PK_RSASSA_PSS;
|
||||
break;
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
*md_alg = MBEDTLS_MD_SHA512;
|
||||
*pk_type = MBEDTLS_PK_RSASSA_PSS;
|
||||
break;
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
#endif /* MBEDTLS_PKCS1_V21 */
|
||||
default:
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
static inline int mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported(
|
||||
const uint16_t sig_alg )
|
||||
{
|
||||
@@ -2201,7 +2149,63 @@ static inline int mbedtls_ssl_tls13_sig_alg_is_supported(
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_check_sig_alg_cert_key_match( uint16_t sig_alg,
|
||||
mbedtls_pk_context *key );
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
static inline int mbedtls_ssl_sig_alg_is_offered( const mbedtls_ssl_context *ssl,
|
||||
uint16_t proposed_sig_alg )
|
||||
{
|
||||
const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs( ssl );
|
||||
if( sig_alg == NULL )
|
||||
return( 0 );
|
||||
|
||||
for( ; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++ )
|
||||
{
|
||||
if( *sig_alg == proposed_sig_alg )
|
||||
return( 1 );
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static inline int mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(
|
||||
uint16_t sig_alg, mbedtls_pk_type_t *pk_type, mbedtls_md_type_t *md_alg )
|
||||
{
|
||||
*pk_type = mbedtls_ssl_pk_alg_from_sig( sig_alg & 0xff );
|
||||
*md_alg = mbedtls_ssl_md_alg_from_hash( ( sig_alg >> 8 ) & 0xff );
|
||||
|
||||
if( *pk_type != MBEDTLS_PK_NONE && *md_alg != MBEDTLS_MD_NONE )
|
||||
return( 0 );
|
||||
|
||||
switch( sig_alg )
|
||||
{
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
*md_alg = MBEDTLS_MD_SHA256;
|
||||
*pk_type = MBEDTLS_PK_RSASSA_PSS;
|
||||
break;
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
*md_alg = MBEDTLS_MD_SHA384;
|
||||
*pk_type = MBEDTLS_PK_RSASSA_PSS;
|
||||
break;
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
*md_alg = MBEDTLS_MD_SHA512;
|
||||
*pk_type = MBEDTLS_PK_RSASSA_PSS;
|
||||
break;
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
#endif /* MBEDTLS_PKCS1_V21 */
|
||||
default:
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
static inline int mbedtls_ssl_tls12_sig_alg_is_supported(
|
||||
@@ -2279,26 +2283,17 @@ static inline int mbedtls_ssl_sig_alg_is_supported(
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 )
|
||||
{
|
||||
return( mbedtls_ssl_tls13_sig_alg_is_supported( sig_alg ) );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
#endif
|
||||
((void) ssl);
|
||||
((void) sig_alg);
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_check_sig_alg_cert_key_match( uint16_t sig_alg,
|
||||
mbedtls_pk_context *key );
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
/* Corresponding PSA algorithm for MBEDTLS_CIPHER_NULL.
|
||||
@@ -2459,7 +2454,7 @@ int mbedtls_ssl_check_dtls_clihlo_cookie(
|
||||
unsigned char *obuf, size_t buf_len, size_t *olen );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/**
|
||||
* \brief Given an SSL context and its associated configuration, write the TLS
|
||||
* 1.3 specific Pre-Shared key extension.
|
||||
@@ -2492,7 +2487,7 @@ MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
|
||||
mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf, unsigned char *end );
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
|
@@ -1665,15 +1665,15 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
/*
|
||||
* The next two sizes are the minimum and maximum values of
|
||||
* data_len over all padlen values.
|
||||
*
|
||||
* They're independent of padlen, since we previously did
|
||||
* data_len -= padlen.
|
||||
*
|
||||
* Note that max_len + maclen is never more than the buffer
|
||||
* length, as we previously did in_msglen -= maclen too.
|
||||
*/
|
||||
* The next two sizes are the minimum and maximum values of
|
||||
* data_len over all padlen values.
|
||||
*
|
||||
* They're independent of padlen, since we previously did
|
||||
* data_len -= padlen.
|
||||
*
|
||||
* Note that max_len + maclen is never more than the buffer
|
||||
* length, as we previously did in_msglen -= maclen too.
|
||||
*/
|
||||
const size_t max_len = rec->data_len + padlen;
|
||||
const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
|
||||
|
||||
@@ -3847,8 +3847,8 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
|
||||
|
||||
if( ssl_record_is_in_progress( ssl ) == 0 )
|
||||
{
|
||||
int dtls_have_buffered = 0;
|
||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||
int have_buffered = 0;
|
||||
|
||||
/* We only check for buffered messages if the
|
||||
* current datagram is fully consumed. */
|
||||
@@ -3856,11 +3856,11 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
|
||||
ssl_next_record_is_in_datagram( ssl ) == 0 )
|
||||
{
|
||||
if( ssl_load_buffered_message( ssl ) == 0 )
|
||||
have_buffered = 1;
|
||||
dtls_have_buffered = 1;
|
||||
}
|
||||
|
||||
if( have_buffered == 0 )
|
||||
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
||||
if( dtls_have_buffered == 0 )
|
||||
{
|
||||
ret = ssl_get_next_record( ssl );
|
||||
if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
|
||||
|
@@ -604,6 +604,12 @@ static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
|
||||
mbedtls_sha512_update( &ssl->handshake->fin_sha384, buf, len );
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
|
||||
!defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
(void) ssl;
|
||||
(void) buf;
|
||||
(void) len;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
@@ -837,7 +843,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
/* Heap allocate and translate sig_hashes from internal hash identifiers to
|
||||
@@ -903,7 +909,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
|
||||
ssl->handshake->sig_algs_heap_allocated = 0;
|
||||
}
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@@ -1006,6 +1012,30 @@ static int ssl_conf_check(const mbedtls_ssl_context *ssl)
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
/* RFC 8446 section 4.4.3
|
||||
*
|
||||
* If the verification fails, the receiver MUST terminate the handshake with
|
||||
* a "decrypt_error" alert.
|
||||
*
|
||||
* If the client is configured as TLS 1.3 only with optional verify, return
|
||||
* bad config.
|
||||
*
|
||||
*/
|
||||
if( mbedtls_ssl_conf_tls13_ephemeral_enabled(
|
||||
(mbedtls_ssl_context *)ssl ) &&
|
||||
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
|
||||
ssl->conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
||||
ssl->conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
||||
ssl->conf->authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1, ( "Optional verify auth mode "
|
||||
"is not available for TLS 1.3 client" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_CONFIG );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
/* Space for further checks */
|
||||
|
||||
return( 0 );
|
||||
@@ -1218,9 +1248,11 @@ int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
|
||||
int free_cli_id = 1;
|
||||
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
|
||||
if( partial == 0 )
|
||||
free_cli_id = ( partial == 0 );
|
||||
#endif
|
||||
if( free_cli_id )
|
||||
{
|
||||
mbedtls_free( ssl->cli_id );
|
||||
ssl->cli_id = NULL;
|
||||
@@ -1419,6 +1451,14 @@ void mbedtls_ssl_conf_tls13_key_exchange_modes( mbedtls_ssl_config *conf,
|
||||
{
|
||||
conf->tls13_kex_modes = kex_modes & MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
void mbedtls_ssl_tls13_conf_early_data( mbedtls_ssl_config *conf,
|
||||
int early_data_enabled )
|
||||
{
|
||||
conf->early_data_enabled = early_data_enabled;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
@@ -1593,16 +1633,21 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_conf_psk_is_configured( mbedtls_ssl_config const *conf )
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
int mbedtls_ssl_conf_has_static_psk( mbedtls_ssl_config const *conf )
|
||||
{
|
||||
if( conf->psk_identity == NULL ||
|
||||
conf->psk_identity_len == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( !mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
|
||||
if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
|
||||
return( 1 );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
if( conf->psk != NULL )
|
||||
|
||||
if( conf->psk != NULL && conf->psk_len != 0 )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
@@ -1648,6 +1693,7 @@ static int ssl_conf_set_psk_identity( mbedtls_ssl_config *conf,
|
||||
{
|
||||
/* Identity len will be encoded on two bytes */
|
||||
if( psk_identity == NULL ||
|
||||
psk_identity_len == 0 ||
|
||||
( psk_identity_len >> 16 ) != 0 ||
|
||||
psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
|
||||
{
|
||||
@@ -1671,7 +1717,7 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* We currently only support one PSK, raw or opaque. */
|
||||
if( ssl_conf_psk_is_configured( conf ) )
|
||||
if( mbedtls_ssl_conf_has_static_psk( conf ) )
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
|
||||
/* Check and set raw PSK */
|
||||
@@ -1789,7 +1835,7 @@ int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* We currently only support one PSK, raw or opaque. */
|
||||
if( ssl_conf_psk_is_configured( conf ) )
|
||||
if( mbedtls_ssl_conf_has_static_psk( conf ) )
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
|
||||
/* Check and set opaque PSK */
|
||||
@@ -1830,7 +1876,7 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static mbedtls_ssl_mode_t mbedtls_ssl_get_base_mode(
|
||||
@@ -2383,7 +2429,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
|
||||
}
|
||||
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
/*
|
||||
* Set allowed/preferred hashes for handshake signatures
|
||||
@@ -2404,7 +2450,7 @@ void mbedtls_ssl_conf_sig_algs( mbedtls_ssl_config *conf,
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
conf->sig_algs = sig_algs;
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
@@ -3575,7 +3621,7 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
if ( ssl->handshake->sig_algs_heap_allocated )
|
||||
mbedtls_free( (void*) handshake->sig_algs );
|
||||
@@ -3587,7 +3633,7 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
|
||||
mbedtls_free( (void*) handshake->certificate_request_context );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
|
||||
@@ -3633,7 +3679,7 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
|
||||
mbedtls_free( (void *) handshake->curves );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
|
||||
{
|
||||
@@ -3653,7 +3699,7 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
|
||||
mbedtls_free( handshake->psk );
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
#endif
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
|
||||
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
@@ -4046,6 +4092,9 @@ static int ssl_context_load( mbedtls_ssl_context *ssl,
|
||||
const unsigned char * const end = buf + len;
|
||||
size_t session_len;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
tls_prf_fn prf_func = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The context should have been freshly setup or reset.
|
||||
@@ -4131,17 +4180,22 @@ static int ssl_context_load( mbedtls_ssl_context *ssl,
|
||||
ssl->transform_out = ssl->transform;
|
||||
ssl->transform_negotiate = NULL;
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
prf_func = ssl_tls12prf_from_cs( ssl->session->ciphersuite );
|
||||
if( prf_func == NULL )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
||||
/* Read random bytes and populate structure */
|
||||
if( (size_t)( end - p ) < sizeof( ssl->transform->randbytes ) )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
|
||||
ret = ssl_tls12_populate_transform( ssl->transform,
|
||||
ssl->session->ciphersuite,
|
||||
ssl->session->master,
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
|
||||
ssl->session->encrypt_then_mac,
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
|
||||
ssl_tls12prf_from_cs( ssl->session->ciphersuite ),
|
||||
prf_func,
|
||||
p, /* currently pointing to randbytes */
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, /* (D)TLS 1.2 is forced */
|
||||
ssl->conf->endpoint,
|
||||
@@ -4445,7 +4499,7 @@ static int ssl_preset_suiteb_ciphersuites[] = {
|
||||
0
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
|
||||
/* NOTICE:
|
||||
* For ssl_preset_*_sig_algs and ssl_tls12_preset_*_sig_algs, the following
|
||||
@@ -4590,7 +4644,7 @@ static uint16_t ssl_tls12_preset_suiteb_sig_algs[] = {
|
||||
};
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
static uint16_t ssl_preset_suiteb_groups[] = {
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
||||
@@ -4602,7 +4656,7 @@ static uint16_t ssl_preset_suiteb_groups[] = {
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_NONE
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
/* 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
|
||||
@@ -4626,7 +4680,7 @@ static int ssl_check_no_sig_alg_duplication( uint16_t * sig_algs )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_DEBUG_C && MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_DEBUG_C && MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
/*
|
||||
* Load default in mbedtls_ssl_config
|
||||
@@ -4638,7 +4692,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
if( ssl_check_no_sig_alg_duplication( ssl_preset_suiteb_sig_algs ) )
|
||||
{
|
||||
mbedtls_printf( "ssl_preset_suiteb_sig_algs has duplicated entries\n" );
|
||||
@@ -4664,7 +4718,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
|
||||
return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
#endif /* MBEDTLS_DEBUG_C && MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_DEBUG_C && MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
/* Use the functions here so that they are covered in tests,
|
||||
* but otherwise access member directly for efficiency */
|
||||
@@ -4795,14 +4849,14 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
|
||||
conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( mbedtls_ssl_conf_is_tls12_only( conf ) )
|
||||
conf->sig_algs = ssl_tls12_preset_suiteb_sig_algs;
|
||||
else
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
conf->sig_algs = ssl_preset_suiteb_sig_algs;
|
||||
#endif
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
conf->curve_list = NULL;
|
||||
@@ -4821,14 +4875,14 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
|
||||
conf->cert_profile = &mbedtls_x509_crt_profile_default;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( mbedtls_ssl_conf_is_tls12_only( conf ) )
|
||||
conf->sig_algs = ssl_tls12_preset_default_sig_algs;
|
||||
else
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
conf->sig_algs = ssl_preset_default_sig_algs;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
conf->curve_list = NULL;
|
||||
@@ -4853,7 +4907,7 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
|
||||
mbedtls_mpi_free( &conf->dhm_G );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
|
||||
{
|
||||
@@ -4875,7 +4929,7 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
|
||||
conf->psk_identity = NULL;
|
||||
conf->psk_identity_len = 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
ssl_key_cert_free( conf->key_cert );
|
||||
@@ -5157,6 +5211,10 @@ int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
#if !defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
|
||||
!defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
(void) ssl;
|
||||
#endif
|
||||
return( psa_ssl_status_to_mbedtls( status ) );
|
||||
}
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
@@ -5243,6 +5301,13 @@ int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/
|
||||
|
||||
default:
|
||||
#if !defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
|
||||
!defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
(void) ssl;
|
||||
(void) dst;
|
||||
(void) dst_len;
|
||||
(void) olen;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
@@ -5250,7 +5315,7 @@ int mbedtls_ssl_get_handshake_transcript( mbedtls_ssl_context *ssl,
|
||||
|
||||
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
/* mbedtls_ssl_parse_sig_alg_ext()
|
||||
*
|
||||
* The `extension_data` field of signature algorithm contains a `SignatureSchemeList`
|
||||
@@ -5358,7 +5423,7 @@ int mbedtls_ssl_parse_sig_alg_ext( mbedtls_ssl_context *ssl,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
|
||||
@@ -5429,6 +5494,8 @@ static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* de
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384) || \
|
||||
defined(PSA_WANT_ALG_SHA_256)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int tls_prf_generic( mbedtls_md_type_t md_type,
|
||||
const unsigned char *secret, size_t slen,
|
||||
@@ -5503,9 +5570,12 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* PSA_WANT_ALG_SHA_256 || PSA_WANT_ALG_SHA_384 */
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_MD_C) && \
|
||||
( defined(MBEDTLS_SHA256_C) || \
|
||||
defined(MBEDTLS_SHA384_C) )
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int tls_prf_generic( mbedtls_md_type_t md_type,
|
||||
const unsigned char *secret, size_t slen,
|
||||
@@ -5589,13 +5659,16 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
|
||||
exit:
|
||||
mbedtls_md_free( &md_ctx );
|
||||
|
||||
mbedtls_platform_zeroize( tmp, tmp_len );
|
||||
if ( tmp != NULL )
|
||||
mbedtls_platform_zeroize( tmp, tmp_len );
|
||||
|
||||
mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
|
||||
|
||||
mbedtls_free( tmp );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_MD_C && ( MBEDTLS_SHA256_C || MBEDTLS_SHA384_C ) */
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
@@ -5909,7 +5982,10 @@ int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
|
||||
default:
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
|
||||
!defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
(void) ssl;
|
||||
#endif
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@@ -7430,16 +7506,25 @@ exit:
|
||||
*/
|
||||
static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id )
|
||||
{
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
|
||||
mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
|
||||
|
||||
mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
if( ciphersuite_info != NULL && ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
|
||||
return( tls_prf_sha384 );
|
||||
#else
|
||||
(void) ciphersuite_id;
|
||||
else
|
||||
#endif
|
||||
return( tls_prf_sha256 );
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
{
|
||||
if( ciphersuite_info != NULL && ciphersuite_info->mac == MBEDTLS_MD_SHA256 )
|
||||
return( tls_prf_sha256 );
|
||||
}
|
||||
#endif
|
||||
#if !defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
|
||||
!defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
(void) ciphersuite_info;
|
||||
#endif
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
|
||||
|
||||
@@ -7676,11 +7761,16 @@ static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
|
||||
* sequence number).
|
||||
*/
|
||||
transform->ivlen = 12;
|
||||
|
||||
int is_chachapoly = 0;
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( key_type == PSA_KEY_TYPE_CHACHA20 )
|
||||
is_chachapoly = ( key_type == PSA_KEY_TYPE_CHACHA20 );
|
||||
#else
|
||||
if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
|
||||
is_chachapoly = ( mbedtls_cipher_info_get_mode( cipher_info )
|
||||
== MBEDTLS_MODE_CHACHAPOLY );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if( is_chachapoly )
|
||||
transform->fixed_ivlen = 12;
|
||||
else
|
||||
transform->fixed_ivlen = 4;
|
||||
@@ -8550,7 +8640,7 @@ int mbedtls_ssl_validate_ciphersuite(
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
/*
|
||||
* Function for writing a signature algorithm extension.
|
||||
*
|
||||
@@ -8653,7 +8743,7 @@ int mbedtls_ssl_write_sig_alg_ext( mbedtls_ssl_context *ssl, unsigned char *buf,
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
/*
|
||||
|
@@ -49,27 +49,6 @@
|
||||
|
||||
#include "hash_info.h"
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
int mbedtls_ssl_conf_has_static_psk( mbedtls_ssl_config const *conf )
|
||||
{
|
||||
if( conf->psk_identity == NULL ||
|
||||
conf->psk_identity_len == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
|
||||
return( 1 );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if( conf->psk != NULL && conf->psk_len != 0 )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
|
||||
@@ -1771,10 +1750,10 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl,
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
|
||||
unsigned char **p,
|
||||
@@ -1839,7 +1818,15 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
|
||||
#else
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
|
||||
{
|
||||
@@ -1869,6 +1856,15 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
|
||||
unsigned char **p,
|
||||
@@ -1904,11 +1900,10 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || \
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
|
||||
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
|
||||
@@ -2465,9 +2460,11 @@ start_processing:
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
int send_alert_msg = 1;
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
|
||||
send_alert_msg = ( ret != MBEDTLS_ERR_ECP_IN_PROGRESS );
|
||||
#endif
|
||||
if( send_alert_msg )
|
||||
mbedtls_ssl_send_alert_message(
|
||||
ssl,
|
||||
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
|
@@ -708,11 +708,13 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
|
||||
#endif
|
||||
list = ssl->conf->key_cert;
|
||||
|
||||
int pk_alg_is_none = 0;
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( pk_alg == PSA_ALG_NONE )
|
||||
pk_alg_is_none = ( pk_alg == PSA_ALG_NONE );
|
||||
#else
|
||||
if( pk_alg == MBEDTLS_PK_NONE )
|
||||
pk_alg_is_none = ( pk_alg == MBEDTLS_PK_NONE );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
if( pk_alg_is_none )
|
||||
return( 0 );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) );
|
||||
@@ -729,18 +731,21 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
|
||||
cur->cert );
|
||||
|
||||
int key_type_matches = 0;
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( ( ssl->conf->f_async_sign_start == NULL &&
|
||||
ssl->conf->f_async_decrypt_start == NULL &&
|
||||
! mbedtls_pk_can_do_ext( cur->key, pk_alg, pk_usage ) ) ||
|
||||
! mbedtls_pk_can_do_ext( &cur->cert->pk, pk_alg, pk_usage ) )
|
||||
key_type_matches = ( ( ssl->conf->f_async_sign_start != NULL ||
|
||||
ssl->conf->f_async_decrypt_start != NULL ||
|
||||
mbedtls_pk_can_do_ext( cur->key, pk_alg, pk_usage ) ) &&
|
||||
mbedtls_pk_can_do_ext( &cur->cert->pk, pk_alg, pk_usage ) );
|
||||
#else
|
||||
if( ! mbedtls_pk_can_do_ext( cur->key, pk_alg, pk_usage ) )
|
||||
key_type_matches = (
|
||||
mbedtls_pk_can_do_ext( cur->key, pk_alg, pk_usage ) );
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
#else
|
||||
if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) )
|
||||
key_type_matches = mbedtls_pk_can_do( &cur->cert->pk, pk_alg );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
if( !key_type_matches )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
|
||||
continue;
|
||||
@@ -917,6 +922,8 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
|
||||
|
||||
int renegotiating;
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
|
||||
read_record_header:
|
||||
#endif
|
||||
@@ -925,9 +932,11 @@ read_record_header:
|
||||
* otherwise read it ourselves manually in order to support SSLv2
|
||||
* ClientHello, which doesn't use the same record layer format.
|
||||
*/
|
||||
renegotiating = 0;
|
||||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
|
||||
renegotiating = ( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE );
|
||||
#endif
|
||||
if( !renegotiating )
|
||||
{
|
||||
if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 )
|
||||
{
|
||||
|
@@ -210,6 +210,7 @@ static int ssl_tls13_reset_key_share( mbedtls_ssl_context *ssl )
|
||||
/*
|
||||
* Functions for writing key_share extension.
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_get_default_group_id( mbedtls_ssl_context *ssl,
|
||||
uint16_t *group_id )
|
||||
@@ -364,7 +365,7 @@ cleanup:
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
* ssl_tls13_parse_hrr_key_share_ext()
|
||||
@@ -379,6 +380,7 @@ static int ssl_tls13_parse_hrr_key_share_ext( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_C)
|
||||
const mbedtls_ecp_curve_info *curve_info = NULL;
|
||||
const unsigned char *p = buf;
|
||||
int selected_group;
|
||||
@@ -435,6 +437,12 @@ static int ssl_tls13_parse_hrr_key_share_ext( mbedtls_ssl_context *ssl,
|
||||
ssl->handshake->offered_group_id = selected_group;
|
||||
|
||||
return( 0 );
|
||||
#else
|
||||
(void) ssl;
|
||||
(void) buf;
|
||||
(void) end;
|
||||
return( MBEDTLS_ERR_SSL_BAD_CONFIG );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -595,7 +603,7 @@ static int ssl_tls13_write_cookie_ext( mbedtls_ssl_context *ssl,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/*
|
||||
* ssl_tls13_write_psk_key_exchange_modes_ext() structure:
|
||||
*
|
||||
@@ -640,14 +648,6 @@ static int ssl_tls13_write_psk_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
|
||||
*/
|
||||
p += 5;
|
||||
|
||||
if( mbedtls_ssl_conf_tls13_psk_enabled( ssl ) )
|
||||
{
|
||||
*p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE;
|
||||
ke_modes_len++;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "Adding pure PSK key exchange mode" ) );
|
||||
}
|
||||
|
||||
if( mbedtls_ssl_conf_tls13_psk_ephemeral_enabled( ssl ) )
|
||||
{
|
||||
*p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE;
|
||||
@@ -656,6 +656,14 @@ static int ssl_tls13_write_psk_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "Adding PSK-ECDHE key exchange mode" ) );
|
||||
}
|
||||
|
||||
if( mbedtls_ssl_conf_tls13_psk_enabled( ssl ) )
|
||||
{
|
||||
*p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE;
|
||||
ke_modes_len++;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "Adding pure PSK key exchange mode" ) );
|
||||
}
|
||||
|
||||
/* Now write the extension and ke_modes length */
|
||||
MBEDTLS_PUT_UINT16_BE( ke_modes_len + 1, buf, 2 );
|
||||
buf[4] = ke_modes_len;
|
||||
@@ -721,11 +729,6 @@ static int ssl_tls13_ticket_get_psk( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
static int ssl_tls13_has_configured_psk( const mbedtls_ssl_config *conf )
|
||||
{
|
||||
return( conf->psk != NULL && conf->psk_identity != NULL );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_psk_get_identity( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
@@ -733,7 +736,7 @@ static int ssl_tls13_psk_get_identity( mbedtls_ssl_context *ssl,
|
||||
size_t *identity_len )
|
||||
{
|
||||
|
||||
if( !ssl_tls13_has_configured_psk( ssl->conf ) )
|
||||
if( ! mbedtls_ssl_conf_has_static_psk( ssl->conf ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = PSA_ALG_SHA_256;
|
||||
@@ -749,7 +752,7 @@ static int ssl_tls13_psk_get_psk( mbedtls_ssl_context *ssl,
|
||||
size_t *psk_len )
|
||||
{
|
||||
|
||||
if( !ssl_tls13_has_configured_psk( ssl->conf ) )
|
||||
if( ! mbedtls_ssl_conf_has_static_psk( ssl->conf ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = PSA_ALG_SHA_256;
|
||||
@@ -768,7 +771,7 @@ static int ssl_tls13_get_configured_psk_count( mbedtls_ssl_context *ssl )
|
||||
configured_psk_count++;
|
||||
}
|
||||
#endif
|
||||
if( ssl_tls13_has_configured_psk( ssl->conf ) )
|
||||
if( mbedtls_ssl_conf_has_static_psk( ssl->conf ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK is configured" ) );
|
||||
configured_psk_count++;
|
||||
@@ -1087,7 +1090,7 @@ static int ssl_tls13_parse_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( ssl_tls13_has_configured_psk( ssl->conf ) )
|
||||
if( mbedtls_ssl_conf_has_static_psk( ssl->conf ) )
|
||||
{
|
||||
ret = ssl_tls13_psk_get_psk( ssl, &hash_alg, &psk, &psk_len );
|
||||
}
|
||||
@@ -1110,8 +1113,7 @@ static int ssl_tls13_parse_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
@@ -1141,6 +1143,7 @@ int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl,
|
||||
return( ret );
|
||||
p += ext_len;
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
|
||||
if( mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
|
||||
{
|
||||
ret = ssl_tls13_write_key_share_ext( ssl, p, end, &ext_len );
|
||||
@@ -1148,8 +1151,9 @@ int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl,
|
||||
return( ret );
|
||||
p += ext_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/* For PSK-based key exchange we need the pre_shared_key extension
|
||||
* and the psk_key_exchange_modes extension.
|
||||
*
|
||||
@@ -1163,7 +1167,7 @@ int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl,
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
p += ext_len;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif
|
||||
|
||||
*out_len = p - buf;
|
||||
|
||||
@@ -1679,7 +1683,7 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found pre_shared_key extension" ) );
|
||||
if( is_hrr )
|
||||
@@ -1696,7 +1700,7 @@ static int ssl_tls13_parse_server_hello( mbedtls_ssl_context *ssl,
|
||||
return( ret );
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif
|
||||
|
||||
case MBEDTLS_TLS_EXT_KEY_SHARE:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found key_shares extension" ) );
|
||||
@@ -2063,7 +2067,7 @@ static int ssl_tls13_process_encrypted_extensions( mbedtls_ssl_context *ssl )
|
||||
mbedtls_ssl_add_hs_msg_to_checksum( ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||
buf, buf_len );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
if( mbedtls_ssl_tls13_key_exchange_mode_with_psk( ssl ) )
|
||||
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
|
||||
else
|
||||
@@ -2080,7 +2084,7 @@ cleanup:
|
||||
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
/*
|
||||
* STATE HANDLING: CertificateRequest
|
||||
*
|
||||
@@ -2317,7 +2321,7 @@ static int ssl_tls13_process_certificate_verify( mbedtls_ssl_context *ssl )
|
||||
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
* Handler for MBEDTLS_SSL_SERVER_FINISHED
|
||||
@@ -2363,7 +2367,7 @@ static int ssl_tls13_write_client_certificate( mbedtls_ssl_context *ssl )
|
||||
( "Switch to handshake traffic keys for outbound traffic" ) );
|
||||
mbedtls_ssl_set_outbound_transform( ssl, ssl->handshake->transform_handshake );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
if( ssl->handshake->client_auth )
|
||||
{
|
||||
int ret = mbedtls_ssl_tls13_write_certificate( ssl );
|
||||
@@ -2393,7 +2397,7 @@ static int ssl_tls13_write_client_certificate( mbedtls_ssl_context *ssl )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
/*
|
||||
* Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY
|
||||
*/
|
||||
@@ -2407,7 +2411,7 @@ static int ssl_tls13_write_client_certificate_verify( mbedtls_ssl_context *ssl )
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
* Handler for MBEDTLS_SSL_CLIENT_FINISHED
|
||||
@@ -2720,7 +2724,7 @@ int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl )
|
||||
ret = ssl_tls13_process_encrypted_extensions( ssl );
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
case MBEDTLS_SSL_CERTIFICATE_REQUEST:
|
||||
ret = ssl_tls13_process_certificate_request( ssl );
|
||||
break;
|
||||
@@ -2732,7 +2736,7 @@ int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl )
|
||||
case MBEDTLS_SSL_CERTIFICATE_VERIFY:
|
||||
ret = ssl_tls13_process_certificate_verify( ssl );
|
||||
break;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
case MBEDTLS_SSL_SERVER_FINISHED:
|
||||
ret = ssl_tls13_process_server_finished( ssl );
|
||||
@@ -2742,11 +2746,11 @@ int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl )
|
||||
ret = ssl_tls13_write_client_certificate( ssl );
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY:
|
||||
ret = ssl_tls13_write_client_certificate_verify( ssl );
|
||||
break;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
case MBEDTLS_SSL_CLIENT_FINISHED:
|
||||
ret = ssl_tls13_write_client_finished( ssl );
|
||||
|
@@ -83,7 +83,7 @@ cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
/*
|
||||
* STATE HANDLING: Read CertificateVerify
|
||||
*/
|
||||
@@ -285,12 +285,12 @@ error:
|
||||
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
int mbedtls_ssl_tls13_process_certificate_verify( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char verify_buffer[SSL_VERIFY_STRUCT_MAX_SIZE];
|
||||
size_t verify_buffer_len;
|
||||
@@ -348,7 +348,7 @@ cleanup:
|
||||
((void) ssl);
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -357,7 +357,7 @@ cleanup:
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
/*
|
||||
* Structure of Certificate message:
|
||||
@@ -534,9 +534,9 @@ int mbedtls_ssl_tls13_parse_certificate( mbedtls_ssl_context *ssl,
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
/* Validate certificate chain sent by the server. */
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
@@ -727,14 +727,14 @@ static int ssl_tls13_validate_certificate( mbedtls_ssl_context *ssl )
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
int mbedtls_ssl_tls13_process_certificate( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
unsigned char *buf;
|
||||
size_t buf_len;
|
||||
|
||||
@@ -752,12 +752,12 @@ int mbedtls_ssl_tls13_process_certificate( mbedtls_ssl_context *ssl )
|
||||
buf, buf_len );
|
||||
|
||||
cleanup:
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
|
||||
return( ret );
|
||||
}
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
/*
|
||||
* enum {
|
||||
* X509(0),
|
||||
@@ -1078,7 +1078,7 @@ cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@@ -331,9 +331,12 @@ int mbedtls_ssl_tls13_evolve_secret(
|
||||
int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t hlen, ilen;
|
||||
size_t hlen;
|
||||
unsigned char tmp_secret[ PSA_MAC_MAX_SIZE ] = { 0 };
|
||||
unsigned char tmp_input [ MBEDTLS_ECP_MAX_BYTES ] = { 0 };
|
||||
const unsigned char all_zeroes_input[ MBEDTLS_TLS1_3_MD_MAX_SIZE ] = { 0 };
|
||||
const unsigned char *l_input = NULL;
|
||||
size_t l_input_len;
|
||||
|
||||
psa_key_derivation_operation_t operation =
|
||||
PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
|
||||
@@ -361,12 +364,13 @@ int mbedtls_ssl_tls13_evolve_secret(
|
||||
|
||||
if( input != NULL && input_len != 0 )
|
||||
{
|
||||
memcpy( tmp_input, input, input_len );
|
||||
ilen = input_len;
|
||||
l_input = input;
|
||||
l_input_len = input_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
ilen = hlen;
|
||||
l_input = all_zeroes_input;
|
||||
l_input_len = hlen;
|
||||
}
|
||||
|
||||
status = psa_key_derivation_setup( &operation,
|
||||
@@ -385,8 +389,7 @@ int mbedtls_ssl_tls13_evolve_secret(
|
||||
|
||||
status = psa_key_derivation_input_bytes( &operation,
|
||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||
tmp_input,
|
||||
ilen );
|
||||
l_input, l_input_len );
|
||||
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
@@ -403,7 +406,6 @@ int mbedtls_ssl_tls13_evolve_secret(
|
||||
status = ( status == PSA_SUCCESS ? abort_status : status );
|
||||
ret = ( ret == 0 ? psa_ssl_status_to_mbedtls ( status ) : ret );
|
||||
mbedtls_platform_zeroize( tmp_secret, sizeof(tmp_secret) );
|
||||
mbedtls_platform_zeroize( tmp_input, sizeof(tmp_input) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
@@ -1065,7 +1067,7 @@ int mbedtls_ssl_tls13_key_schedule_stage_early( mbedtls_ssl_context *ssl )
|
||||
}
|
||||
|
||||
hash_alg = mbedtls_hash_info_psa_from_md( handshake->ciphersuite_info->mac );
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
if( mbedtls_ssl_tls13_key_exchange_mode_with_psk( ssl ) )
|
||||
{
|
||||
ret = mbedtls_ssl_tls13_export_handshake_psk( ssl, &psk, &psk_len );
|
||||
@@ -1081,7 +1083,7 @@ int mbedtls_ssl_tls13_key_schedule_stage_early( mbedtls_ssl_context *ssl )
|
||||
ret = mbedtls_ssl_tls13_evolve_secret( hash_alg, NULL, psk, psk_len,
|
||||
handshake->tls13_master_secrets.early );
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
mbedtls_free( (void*)psk );
|
||||
#endif
|
||||
if( ret != 0 )
|
||||
@@ -1248,14 +1250,13 @@ exit:
|
||||
int mbedtls_ssl_tls13_key_schedule_stage_handshake( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) && defined(MBEDTLS_ECDH_C)
|
||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED && MBEDTLS_ECDH_C */
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
psa_algorithm_t const hash_alg = mbedtls_hash_info_psa_from_md(
|
||||
handshake->ciphersuite_info->mac );
|
||||
unsigned char *shared_secret = NULL;
|
||||
size_t shared_secret_len = 0;
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
|
||||
/*
|
||||
* Compute ECDHE secret used to compute the handshake secret from which
|
||||
* client_handshake_traffic_secret and server_handshake_traffic_secret
|
||||
@@ -1267,60 +1268,75 @@ int mbedtls_ssl_tls13_key_schedule_stage_handshake( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_C)
|
||||
/* Compute ECDH shared secret. */
|
||||
status = psa_raw_key_agreement(
|
||||
PSA_ALG_ECDH, handshake->ecdh_psa_privkey,
|
||||
handshake->ecdh_psa_peerkey, handshake->ecdh_psa_peerkey_len,
|
||||
handshake->premaster, sizeof( handshake->premaster ),
|
||||
&handshake->pmslen );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
ret = psa_ssl_status_to_mbedtls( status );
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "psa_raw_key_agreement", ret );
|
||||
return( ret );
|
||||
}
|
||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
status = psa_destroy_key( handshake->ecdh_psa_privkey );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
ret = psa_ssl_status_to_mbedtls( status );
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "psa_destroy_key", ret );
|
||||
return( ret );
|
||||
}
|
||||
status = psa_get_key_attributes( handshake->ecdh_psa_privkey,
|
||||
&key_attributes );
|
||||
if( status != PSA_SUCCESS )
|
||||
ret = psa_ssl_status_to_mbedtls( status );
|
||||
|
||||
handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
shared_secret_len = PSA_BITS_TO_BYTES(
|
||||
psa_get_key_bits( &key_attributes ) );
|
||||
shared_secret = mbedtls_calloc( 1, shared_secret_len );
|
||||
if( shared_secret == NULL )
|
||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
|
||||
status = psa_raw_key_agreement(
|
||||
PSA_ALG_ECDH, handshake->ecdh_psa_privkey,
|
||||
handshake->ecdh_psa_peerkey, handshake->ecdh_psa_peerkey_len,
|
||||
shared_secret, shared_secret_len, &shared_secret_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
ret = psa_ssl_status_to_mbedtls( status );
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "psa_raw_key_agreement", ret );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_destroy_key( handshake->ecdh_psa_privkey );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
ret = psa_ssl_status_to_mbedtls( status );
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "psa_destroy_key", ret );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
#endif /* MBEDTLS_ECDH_C */
|
||||
}
|
||||
else if( mbedtls_ssl_tls13_named_group_is_dhe( handshake->offered_group_id ) )
|
||||
else
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHE not supported." ) );
|
||||
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Group not supported." ) );
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
}
|
||||
#else
|
||||
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
* Compute the Handshake Secret
|
||||
*/
|
||||
ret = mbedtls_ssl_tls13_evolve_secret( hash_alg,
|
||||
handshake->tls13_master_secrets.early,
|
||||
handshake->premaster, handshake->pmslen,
|
||||
shared_secret, shared_secret_len,
|
||||
handshake->tls13_master_secrets.handshake );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_evolve_secret", ret );
|
||||
return( ret );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "Handshake secret",
|
||||
handshake->tls13_master_secrets.handshake,
|
||||
PSA_HASH_LENGTH( hash_alg ) );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
|
||||
mbedtls_platform_zeroize( handshake->premaster, sizeof( handshake->premaster ) );
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */
|
||||
return( 0 );
|
||||
cleanup:
|
||||
if( shared_secret != NULL )
|
||||
{
|
||||
mbedtls_platform_zeroize( shared_secret, shared_secret_len );
|
||||
mbedtls_free( shared_secret );
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Generate application traffic keys since any records following a 1-RTT Finished message
|
||||
@@ -1598,7 +1614,7 @@ cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
int mbedtls_ssl_tls13_export_handshake_psk( mbedtls_ssl_context *ssl,
|
||||
unsigned char **psk,
|
||||
size_t *psk_len )
|
||||
@@ -1639,7 +1655,7 @@ int mbedtls_ssl_tls13_export_handshake_psk( mbedtls_ssl_context *ssl,
|
||||
return( 0 );
|
||||
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
|
@@ -691,7 +691,7 @@ int mbedtls_ssl_tls13_compute_handshake_transform( mbedtls_ssl_context *ssl );
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_compute_application_transform( mbedtls_ssl_context *ssl );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/**
|
||||
* \brief Export TLS 1.3 PSK from handshake context
|
||||
*
|
||||
@@ -707,7 +707,7 @@ MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_export_handshake_psk( mbedtls_ssl_context *ssl,
|
||||
unsigned char **psk,
|
||||
size_t *psk_len );
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
|
@@ -59,7 +59,7 @@ static const mbedtls_ssl_ciphersuite_t *ssl_tls13_validate_peer_ciphersuite(
|
||||
return( ciphersuite_info );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/* From RFC 8446:
|
||||
*
|
||||
* enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode;
|
||||
@@ -674,11 +674,13 @@ static int ssl_tls13_write_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
|
||||
*olen = 0;
|
||||
|
||||
int not_using_psk = 0;
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
|
||||
not_using_psk = ( mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) );
|
||||
#else
|
||||
if( ssl->handshake->psk == NULL )
|
||||
not_using_psk = ( ssl->handshake->psk == NULL );
|
||||
#endif
|
||||
if( not_using_psk )
|
||||
{
|
||||
/* We shouldn't have called this extension writer unless we've
|
||||
* chosen to use a PSK. */
|
||||
@@ -701,7 +703,7 @@ static int ssl_tls13_write_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
/* From RFC 8446:
|
||||
* struct {
|
||||
@@ -993,7 +995,7 @@ static int ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(
|
||||
MBEDTLS_SSL_EXT_SIG_ALG ) );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_client_hello_has_exts_for_psk_key_exchange(
|
||||
mbedtls_ssl_context *ssl )
|
||||
@@ -1015,7 +1017,7 @@ static int ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(
|
||||
MBEDTLS_SSL_EXT_PRE_SHARED_KEY |
|
||||
MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES ) );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_check_ephemeral_key_exchange( mbedtls_ssl_context *ssl )
|
||||
@@ -1027,7 +1029,7 @@ static int ssl_tls13_check_ephemeral_key_exchange( mbedtls_ssl_context *ssl )
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_check_psk_key_exchange( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
return( mbedtls_ssl_conf_tls13_psk_enabled( ssl ) &&
|
||||
mbedtls_ssl_tls13_psk_enabled( ssl ) &&
|
||||
ssl_tls13_client_hello_has_exts_for_psk_key_exchange( ssl ) );
|
||||
@@ -1040,7 +1042,7 @@ static int ssl_tls13_check_psk_key_exchange( mbedtls_ssl_context *ssl )
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_check_psk_ephemeral_key_exchange( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
return( mbedtls_ssl_conf_tls13_psk_ephemeral_enabled( ssl ) &&
|
||||
mbedtls_ssl_tls13_psk_ephemeral_enabled( ssl ) &&
|
||||
ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange( ssl ) );
|
||||
@@ -1104,7 +1106,7 @@ static int ssl_tls13_determine_key_exchange_mode( mbedtls_ssl_context *ssl )
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static psa_algorithm_t ssl_tls13_iana_sig_alg_to_psa_alg( uint16_t sig_alg )
|
||||
@@ -1229,7 +1231,7 @@ static int ssl_tls13_pick_key_cert( mbedtls_ssl_context *ssl )
|
||||
return( -1 );
|
||||
}
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C &&
|
||||
MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -1289,11 +1291,11 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *extensions_end;
|
||||
int hrr_required = 0;
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
const unsigned char *cipher_suites;
|
||||
const unsigned char *pre_shared_key_ext = NULL;
|
||||
const unsigned char *pre_shared_key_ext_end = NULL;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif
|
||||
|
||||
ssl->handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
|
||||
|
||||
@@ -1400,7 +1402,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
* with CipherSuite defined as:
|
||||
* uint8 CipherSuite[2];
|
||||
*/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
cipher_suites = p;
|
||||
#endif
|
||||
cipher_suites_end = p + cipher_suites_len;
|
||||
@@ -1581,7 +1583,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS;
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
case MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found psk key exchange modes extension" ) );
|
||||
|
||||
@@ -1596,7 +1598,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES;
|
||||
break;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif
|
||||
|
||||
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found pre_shared_key extension" ) );
|
||||
@@ -1608,14 +1610,14 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
}
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/* Delay processing of the PSK identity once we have
|
||||
* found out which algorithms to use. We keep a pointer
|
||||
* to the buffer and the size for later processing.
|
||||
*/
|
||||
pre_shared_key_ext = p;
|
||||
pre_shared_key_ext_end = extension_data_end;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
break;
|
||||
|
||||
@@ -1634,7 +1636,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
break;
|
||||
#endif /* MBEDTLS_SSL_ALPN */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
case MBEDTLS_TLS_EXT_SIG_ALG:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
|
||||
|
||||
@@ -1649,7 +1651,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SIG_ALG;
|
||||
break;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
default:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3,
|
||||
@@ -1669,7 +1671,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_HS_CLIENT_HELLO,
|
||||
p - buf );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/* Update checksum with either
|
||||
* - The entire content of the CH message, if no PSK extension is present
|
||||
* - The content up to but excluding the PSK extension, if present.
|
||||
@@ -1698,7 +1700,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
{
|
||||
ssl->handshake->update_checksum( ssl, buf, p - buf );
|
||||
}
|
||||
@@ -2154,7 +2156,7 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
|
||||
p += output_len;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
if( !is_hrr && mbedtls_ssl_tls13_key_exchange_mode_with_psk( ssl ) )
|
||||
{
|
||||
ret = ssl_tls13_write_server_pre_shared_key_ext( ssl, p, end, &output_len );
|
||||
@@ -2166,7 +2168,7 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
p += output_len;
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE( p - p_extensions_len - 2, p_extensions_len, 0 );
|
||||
|
||||
@@ -2390,7 +2392,7 @@ static int ssl_tls13_write_encrypted_extensions( mbedtls_ssl_context *ssl )
|
||||
MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg(
|
||||
ssl, buf_len, msg_len ) );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
if( mbedtls_ssl_tls13_key_exchange_mode_with_psk( ssl ) )
|
||||
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
|
||||
else
|
||||
@@ -2405,7 +2407,7 @@ cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
#define SSL_CERTIFICATE_REQUEST_SEND_REQUEST 0
|
||||
#define SSL_CERTIFICATE_REQUEST_SKIP 1
|
||||
/* Coordination:
|
||||
@@ -2429,7 +2431,10 @@ static int ssl_tls13_certificate_request_coordinate( mbedtls_ssl_context *ssl )
|
||||
authmode = ssl->conf->authmode;
|
||||
|
||||
if( authmode == MBEDTLS_SSL_VERIFY_NONE )
|
||||
{
|
||||
ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY;
|
||||
return( SSL_CERTIFICATE_REQUEST_SKIP );
|
||||
}
|
||||
|
||||
ssl->handshake->certificate_request_sent = 1;
|
||||
|
||||
@@ -2573,7 +2578,7 @@ static int ssl_tls13_write_certificate_verify( mbedtls_ssl_context *ssl )
|
||||
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
* Handler for MBEDTLS_SSL_SERVER_FINISHED
|
||||
@@ -2984,7 +2989,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
case MBEDTLS_SSL_CERTIFICATE_REQUEST:
|
||||
ret = ssl_tls13_write_certificate_request( ssl );
|
||||
break;
|
||||
@@ -2996,7 +3001,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
|
||||
case MBEDTLS_SSL_CERTIFICATE_VERIFY:
|
||||
ret = ssl_tls13_write_certificate_verify( ssl );
|
||||
break;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
* Injection of dummy-CCS's for middlebox compatibility
|
||||
@@ -3027,6 +3032,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
|
||||
ret = ssl_tls13_handshake_wrapup( ssl );
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
|
||||
ret = mbedtls_ssl_tls13_process_certificate( ssl );
|
||||
if( ret == 0 )
|
||||
@@ -3053,6 +3059,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
|
||||
ssl, MBEDTLS_SSL_CLIENT_FINISHED );
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
case MBEDTLS_SSL_NEW_SESSION_TICKET:
|
||||
|
@@ -459,6 +459,11 @@ static int x509_get_attr_type_value( unsigned char **p,
|
||||
* For the general case we still use a flat list, but we mark elements of the
|
||||
* same set so that they are "merged" together in the functions that consume
|
||||
* this list, eg mbedtls_x509_dn_gets().
|
||||
*
|
||||
* On success, this function may allocate a linked list starting at cur->next
|
||||
* that must later be free'd by the caller using mbedtls_free(). In error
|
||||
* cases, this function frees all allocated memory internally and the caller
|
||||
* has no freeing responsibilities.
|
||||
*/
|
||||
int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_name *cur )
|
||||
@@ -466,6 +471,8 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t set_len;
|
||||
const unsigned char *end_set;
|
||||
mbedtls_x509_name *head = cur;
|
||||
mbedtls_x509_name *prev, *allocated;
|
||||
|
||||
/* don't use recursion, we'd risk stack overflow if not optimized */
|
||||
while( 1 )
|
||||
@@ -475,14 +482,17 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
*/
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
|
||||
{
|
||||
ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret );
|
||||
goto error;
|
||||
}
|
||||
|
||||
end_set = *p + set_len;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
|
||||
return( ret );
|
||||
goto error;
|
||||
|
||||
if( *p == end_set )
|
||||
break;
|
||||
@@ -493,7 +503,10 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
|
||||
{
|
||||
ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
@@ -507,10 +520,30 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
|
||||
{
|
||||
ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
error:
|
||||
/* Skip the first element as we did not allocate it */
|
||||
allocated = head->next;
|
||||
|
||||
while( allocated != NULL )
|
||||
{
|
||||
prev = allocated;
|
||||
allocated = allocated->next;
|
||||
|
||||
mbedtls_platform_zeroize( prev, sizeof( *prev ) );
|
||||
mbedtls_free( prev );
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize( head, sizeof( *head ) );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static int x509_parse_int( unsigned char **p, size_t n, int *res )
|
||||
|
@@ -296,6 +296,43 @@ int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_ext_key_usage( mbedtls_x509write_cert *ctx,
|
||||
const mbedtls_asn1_sequence *exts )
|
||||
{
|
||||
unsigned char buf[256];
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
const mbedtls_asn1_sequence *last_ext = NULL;
|
||||
const mbedtls_asn1_sequence *ext;
|
||||
|
||||
memset( buf, 0, sizeof(buf) );
|
||||
|
||||
/* We need at least one extension: SEQUENCE SIZE (1..MAX) OF KeyPurposeId */
|
||||
if( exts == NULL )
|
||||
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
||||
|
||||
/* Iterate over exts backwards, so we write them out in the requested order */
|
||||
while( last_ext != exts )
|
||||
{
|
||||
for( ext = exts; ext->next != last_ext; ext = ext->next ) {}
|
||||
if( ext->buf.tag != MBEDTLS_ASN1_OID )
|
||||
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
||||
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( &c, buf, ext->buf.p, ext->buf.len ) );
|
||||
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, ext->buf.len ) );
|
||||
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OID ) );
|
||||
last_ext = ext;
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
|
||||
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
|
||||
|
||||
return mbedtls_x509write_crt_set_extension( ctx,
|
||||
MBEDTLS_OID_EXTENDED_KEY_USAGE,
|
||||
MBEDTLS_OID_SIZE( MBEDTLS_OID_EXTENDED_KEY_USAGE ),
|
||||
1, c, len );
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
|
||||
unsigned char ns_cert_type )
|
||||
{
|
||||
|
Reference in New Issue
Block a user