Merge remote-tracking branch 'origin/development' into pr3431
This commit is contained in:
commit
f58172fe43
346 changed files with 23797 additions and 10093 deletions
|
@ -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
|
||||
|
@ -70,6 +72,7 @@ set(src_crypto
|
|||
psa_crypto_ecp.c
|
||||
psa_crypto_hash.c
|
||||
psa_crypto_mac.c
|
||||
psa_crypto_pake.c
|
||||
psa_crypto_rsa.c
|
||||
psa_crypto_se.c
|
||||
psa_crypto_slot_management.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 \
|
||||
|
@ -135,6 +137,7 @@ OBJS_CRYPTO= \
|
|||
psa_crypto_ecp.o \
|
||||
psa_crypto_hash.o \
|
||||
psa_crypto_mac.o \
|
||||
psa_crypto_pake.o \
|
||||
psa_crypto_rsa.o \
|
||||
psa_crypto_se.o \
|
||||
psa_crypto_slot_management.o \
|
||||
|
@ -197,6 +200,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)
|
||||
|
||||
|
|
|
@ -40,23 +40,10 @@
|
|||
#include "aesni.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_AES_ALT)
|
||||
|
||||
/* Parameter validation macros based on platform_util.h */
|
||||
#define AES_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
|
||||
#define AES_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#if defined(MBEDTLS_PADLOCK_C) && \
|
||||
( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
|
||||
static int aes_padlock_ace = -1;
|
||||
|
@ -489,8 +476,6 @@ static void aes_gen_tables( void )
|
|||
|
||||
void mbedtls_aes_init( mbedtls_aes_context *ctx )
|
||||
{
|
||||
AES_VALIDATE( ctx != NULL );
|
||||
|
||||
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
|
||||
}
|
||||
|
||||
|
@ -505,8 +490,6 @@ void mbedtls_aes_free( mbedtls_aes_context *ctx )
|
|||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
|
||||
{
|
||||
AES_VALIDATE( ctx != NULL );
|
||||
|
||||
mbedtls_aes_init( &ctx->crypt );
|
||||
mbedtls_aes_init( &ctx->tweak );
|
||||
}
|
||||
|
@ -531,9 +514,6 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
|
|||
unsigned int i;
|
||||
uint32_t *RK;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
switch( keybits )
|
||||
{
|
||||
case 128: ctx->nr = 10; break;
|
||||
|
@ -649,9 +629,6 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
|
|||
uint32_t *RK;
|
||||
uint32_t *SK;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
mbedtls_aes_init( &cty );
|
||||
|
||||
ctx->rk_offset = 0;
|
||||
|
@ -743,9 +720,6 @@ int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
|
|||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if( ret != 0 )
|
||||
|
@ -768,9 +742,6 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
|
|||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if( ret != 0 )
|
||||
|
@ -970,11 +941,8 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
|
|||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
if( mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT )
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
|
||||
|
@ -1014,12 +982,8 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char temp[16];
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
AES_VALIDATE_RET( iv != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
if( mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT )
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
|
||||
if( length % 16 )
|
||||
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
|
||||
|
@ -1123,12 +1087,8 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
|
|||
unsigned char prev_tweak[16];
|
||||
unsigned char tmp[16];
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
AES_VALIDATE_RET( data_unit != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
if( mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT )
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
|
||||
/* Data units must be at least 16 bytes long. */
|
||||
if( length < 16 )
|
||||
|
@ -1232,13 +1192,8 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
AES_VALIDATE_RET( iv_off != NULL );
|
||||
AES_VALIDATE_RET( iv != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
if( mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT )
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
|
||||
n = *iv_off;
|
||||
|
||||
|
@ -1301,12 +1256,8 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
|
|||
unsigned char c;
|
||||
unsigned char ov[17];
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
AES_VALIDATE_RET( iv != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
if( mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT )
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
while( length-- )
|
||||
{
|
||||
memcpy( ov, iv, 16 );
|
||||
|
@ -1345,12 +1296,6 @@ int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
|
|||
int ret = 0;
|
||||
size_t n;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( iv_off != NULL );
|
||||
AES_VALIDATE_RET( iv != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
|
||||
n = *iv_off;
|
||||
|
||||
if( n > 15 )
|
||||
|
@ -1392,13 +1337,6 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( nc_off != NULL );
|
||||
AES_VALIDATE_RET( nonce_counter != NULL );
|
||||
AES_VALIDATE_RET( stream_block != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
|
||||
n = *nc_off;
|
||||
|
||||
if ( n > 0x0F )
|
||||
|
@ -1752,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)
|
||||
|
|
|
@ -31,14 +31,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_ARIA_ALT)
|
||||
|
||||
|
@ -895,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
|
||||
|
@ -937,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" );
|
||||
|
@ -965,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 )
|
||||
|
@ -976,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" );
|
||||
|
@ -996,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 )
|
||||
|
@ -1008,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" );
|
||||
|
@ -1027,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 )
|
||||
|
@ -1039,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" );
|
||||
|
|
|
@ -31,13 +31,7 @@
|
|||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ASN.1 DER decoding routines
|
||||
|
@ -320,7 +314,6 @@ void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
|
|||
while( seq != NULL )
|
||||
{
|
||||
mbedtls_asn1_sequence *next = seq->next;
|
||||
mbedtls_platform_zeroize( seq, sizeof( *seq ) );
|
||||
mbedtls_free( seq );
|
||||
seq = next;
|
||||
}
|
||||
|
@ -438,6 +431,7 @@ int mbedtls_asn1_get_alg_null( unsigned char **p,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
|
||||
{
|
||||
if( cur == NULL )
|
||||
|
@ -448,6 +442,7 @@ void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
|
|||
|
||||
mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
|
||||
}
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
|
||||
{
|
||||
|
@ -456,11 +451,21 @@ void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
|
|||
while( ( cur = *head ) != NULL )
|
||||
{
|
||||
*head = cur->next;
|
||||
mbedtls_asn1_free_named_data( cur );
|
||||
mbedtls_free( cur->oid.p );
|
||||
mbedtls_free( cur->val.p );
|
||||
mbedtls_free( cur );
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_asn1_free_named_data_list_shallow( mbedtls_asn1_named_data *name )
|
||||
{
|
||||
for( mbedtls_asn1_named_data *next; name != NULL; name = next )
|
||||
{
|
||||
next = name->next;
|
||||
mbedtls_free( name );
|
||||
}
|
||||
}
|
||||
|
||||
const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
|
||||
const char *oid, size_t len )
|
||||
{
|
||||
|
|
|
@ -26,13 +26,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
int mbedtls_asn1_write_len( unsigned char **p, const unsigned char *start, size_t len )
|
||||
{
|
||||
|
@ -78,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 );
|
||||
|
@ -93,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 )
|
||||
|
|
|
@ -28,12 +28,7 @@
|
|||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#include <string.h>
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
|
||||
|
|
259
library/bignum.c
259
library/bignum.c
|
@ -38,7 +38,6 @@
|
|||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "bignum_internal.h"
|
||||
#include "bignum_core.h"
|
||||
#include "bn_mul.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
@ -48,15 +47,7 @@
|
|||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#define MPI_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
|
||||
|
@ -780,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 );
|
||||
}
|
||||
|
||||
|
@ -909,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 );
|
||||
|
@ -924,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;
|
||||
|
||||
|
@ -934,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:
|
||||
|
@ -962,40 +917,6 @@ cleanup:
|
|||
return( ret );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for mbedtls_mpi subtraction.
|
||||
*
|
||||
* Calculate l - r where l and r have the same size.
|
||||
* This function operates modulo (2^ciL)^n and returns the carry
|
||||
* (1 if there was a wraparound, i.e. if `l < r`, and 0 otherwise).
|
||||
*
|
||||
* d may be aliased to l or r.
|
||||
*
|
||||
* \param n Number of limbs of \p d, \p l and \p r.
|
||||
* \param[out] d The result of the subtraction.
|
||||
* \param[in] l The left operand.
|
||||
* \param[in] r The right operand.
|
||||
*
|
||||
* \return 1 if `l < r`.
|
||||
* 0 if `l >= r`.
|
||||
*/
|
||||
static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
|
||||
mbedtls_mpi_uint *d,
|
||||
const mbedtls_mpi_uint *l,
|
||||
const mbedtls_mpi_uint *r )
|
||||
{
|
||||
size_t i;
|
||||
mbedtls_mpi_uint c = 0, t, z;
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
z = ( l[i] < c ); t = l[i] - c;
|
||||
c = ( t < r[i] ) + z; d[i] = t - r[i];
|
||||
}
|
||||
|
||||
return( c );
|
||||
}
|
||||
|
||||
/*
|
||||
* Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)
|
||||
*/
|
||||
|
@ -1028,7 +949,7 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
|
|||
if( X->n > A->n )
|
||||
memset( X->p + A->n, 0, ( X->n - A->n ) * ciL );
|
||||
|
||||
carry = mpi_sub_hlp( n, X->p, A->p, B->p );
|
||||
carry = mbedtls_mpi_core_sub( X->p, A->p, B->p, n );
|
||||
if( carry != 0 )
|
||||
{
|
||||
/* Propagate the carry to the first nonzero limb of X. */
|
||||
|
@ -1157,38 +1078,6 @@ int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
|
|||
return( mbedtls_mpi_sub_mpi( X, A, &B ) );
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_mla( mbedtls_mpi_uint *d, size_t d_len,
|
||||
const mbedtls_mpi_uint *s, size_t s_len,
|
||||
mbedtls_mpi_uint b )
|
||||
{
|
||||
mbedtls_mpi_uint c = 0; /* carry */
|
||||
size_t excess_len = d_len - s_len;
|
||||
|
||||
size_t steps_x8 = s_len / 8;
|
||||
size_t steps_x1 = s_len & 7;
|
||||
|
||||
while( steps_x8-- )
|
||||
{
|
||||
MULADDC_X8_INIT
|
||||
MULADDC_X8_CORE
|
||||
MULADDC_X8_STOP
|
||||
}
|
||||
|
||||
while( steps_x1-- )
|
||||
{
|
||||
MULADDC_X1_INIT
|
||||
MULADDC_X1_CORE
|
||||
MULADDC_X1_STOP
|
||||
}
|
||||
|
||||
while( excess_len-- )
|
||||
{
|
||||
*d += c; c = ( *d < c ); d++;
|
||||
}
|
||||
|
||||
return( c );
|
||||
}
|
||||
|
||||
/*
|
||||
* Baseline multiplication: X = A * B (HAC 14.12)
|
||||
*/
|
||||
|
@ -1612,21 +1501,9 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast Montgomery initialization (thanks to Tom St Denis)
|
||||
*/
|
||||
static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
|
||||
{
|
||||
mbedtls_mpi_uint x, m0 = N->p[0];
|
||||
unsigned int i;
|
||||
|
||||
x = m0;
|
||||
x += ( ( m0 + 2 ) & 4 ) << 1;
|
||||
|
||||
for( i = biL; i >= 8; i /= 2 )
|
||||
x *= ( 2 - ( m0 * x ) );
|
||||
|
||||
*mm = ~x + 1;
|
||||
*mm = mbedtls_mpi_core_montmul_init( N->p );
|
||||
}
|
||||
|
||||
/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
|
||||
|
@ -1640,7 +1517,7 @@ static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
|
|||
* \param[in] B One of the numbers to multiply.
|
||||
* It must be nonzero and must not have more limbs than N
|
||||
* (B->n <= N->n).
|
||||
* \param[in] N The modulo. N must be odd.
|
||||
* \param[in] N The modulus. \p N must be odd.
|
||||
* \param mm The value calculated by `mpi_montg_init(&mm, N)`.
|
||||
* This is -N^-1 mod 2^ciL.
|
||||
* \param[in,out] T A bignum for temporary storage.
|
||||
|
@ -1648,59 +1525,13 @@ static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
|
|||
* (T->n >= 2 * N->n + 1).
|
||||
* Its initial content is unused and
|
||||
* its final content is indeterminate.
|
||||
* Note that unlike the usual convention in the library
|
||||
* for `const mbedtls_mpi*`, the content of T can change.
|
||||
* It does not get reallocated.
|
||||
*/
|
||||
static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
|
||||
const mbedtls_mpi *T )
|
||||
static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B,
|
||||
const mbedtls_mpi *N, mbedtls_mpi_uint mm,
|
||||
mbedtls_mpi *T )
|
||||
{
|
||||
size_t n, m;
|
||||
mbedtls_mpi_uint *d;
|
||||
|
||||
memset( T->p, 0, T->n * ciL );
|
||||
|
||||
d = T->p;
|
||||
n = N->n;
|
||||
m = ( B->n < n ) ? B->n : n;
|
||||
|
||||
for( size_t i = 0; i < n; i++ )
|
||||
{
|
||||
mbedtls_mpi_uint u0, u1;
|
||||
|
||||
/*
|
||||
* T = (T + u0*B + u1*N) / 2^biL
|
||||
*/
|
||||
u0 = A->p[i];
|
||||
u1 = ( d[0] + u0 * B->p[0] ) * mm;
|
||||
|
||||
(void) mbedtls_mpi_core_mla( d, n + 2,
|
||||
B->p, m,
|
||||
u0 );
|
||||
(void) mbedtls_mpi_core_mla( d, n + 2,
|
||||
N->p, n,
|
||||
u1 );
|
||||
d++;
|
||||
}
|
||||
|
||||
/* At this point, d is either the desired result or the desired result
|
||||
* plus N. We now potentially subtract N, avoiding leaking whether the
|
||||
* subtraction is performed through side channels. */
|
||||
|
||||
/* Copy the n least significant limbs of d to A, so that
|
||||
* A = d if d < N (recall that N has n limbs). */
|
||||
memcpy( A->p, d, n * ciL );
|
||||
/* If d >= N then we want to set A to d - N. To prevent timing attacks,
|
||||
* do the calculation without using conditional tests. */
|
||||
/* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */
|
||||
d[n] += 1;
|
||||
d[n] -= mpi_sub_hlp( n, d, d, N->p );
|
||||
/* If d0 < N then d < (2^biL)^n
|
||||
* so d[n] == 0 and we want to keep A as it is.
|
||||
* If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n
|
||||
* so d[n] == 1 and we want to set A to the result of the subtraction
|
||||
* which is d - (2^biL)^n, i.e. the n least significant limbs of d.
|
||||
* This exactly corresponds to a conditional assignment. */
|
||||
mbedtls_ct_mpi_uint_cond_assign( n, A->p, d, (unsigned char) d[n] );
|
||||
mbedtls_mpi_core_montmul( A->p, A->p, B->p, B->n, N->p, N->n, mm, T->p );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1709,7 +1540,7 @@ static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi
|
|||
* See mpi_montmul() regarding constraints and guarantees on the parameters.
|
||||
*/
|
||||
static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
|
||||
mbedtls_mpi_uint mm, const mbedtls_mpi *T )
|
||||
mbedtls_mpi_uint mm, mbedtls_mpi *T )
|
||||
{
|
||||
mbedtls_mpi_uint z = 1;
|
||||
mbedtls_mpi U;
|
||||
|
@ -2100,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),
|
||||
|
@ -2149,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 );
|
||||
|
@ -2211,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,18 +25,13 @@
|
|||
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "bignum_core.h"
|
||||
#include "bn_mul.h"
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
size_t mbedtls_mpi_core_clz( mbedtls_mpi_uint a )
|
||||
{
|
||||
|
@ -153,12 +148,42 @@ void mbedtls_mpi_core_bigendian_to_host( mbedtls_mpi_uint *A,
|
|||
mbedtls_mpi_uint tmp;
|
||||
/* Note that if cur_limb_left == cur_limb_right,
|
||||
* this code effectively swaps the bytes only once. */
|
||||
tmp = mpi_bigendian_to_host( *cur_limb_left );
|
||||
tmp = mpi_bigendian_to_host( *cur_limb_left );
|
||||
*cur_limb_left = mpi_bigendian_to_host( *cur_limb_right );
|
||||
*cur_limb_right = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -291,4 +316,308 @@ 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,
|
||||
unsigned cond )
|
||||
{
|
||||
mbedtls_mpi_uint c = 0;
|
||||
|
||||
/* all-bits 0 if cond is 0, all-bits 1 if cond is non-0 */
|
||||
const mbedtls_mpi_uint mask = mbedtls_ct_mpi_uint_mask( cond );
|
||||
|
||||
for( size_t i = 0; i < limbs; i++ )
|
||||
{
|
||||
mbedtls_mpi_uint add = mask & A[i];
|
||||
mbedtls_mpi_uint t = c + X[i];
|
||||
c = ( t < X[i] );
|
||||
t += add;
|
||||
c += ( t < add );
|
||||
X[i] = t;
|
||||
}
|
||||
|
||||
return( c );
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_sub( 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 z = ( A[i] < c );
|
||||
mbedtls_mpi_uint t = A[i] - c;
|
||||
c = ( t < B[i] ) + z;
|
||||
X[i] = t - B[i];
|
||||
}
|
||||
|
||||
return( c );
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_mla( mbedtls_mpi_uint *d, size_t d_len,
|
||||
const mbedtls_mpi_uint *s, size_t s_len,
|
||||
mbedtls_mpi_uint b )
|
||||
{
|
||||
mbedtls_mpi_uint c = 0; /* carry */
|
||||
/*
|
||||
* It is a documented precondition of this function that d_len >= s_len.
|
||||
* If that's not the case, we swap these round: this turns what would be
|
||||
* a buffer overflow into an incorrect result.
|
||||
*/
|
||||
if( d_len < s_len )
|
||||
s_len = d_len;
|
||||
size_t excess_len = d_len - s_len;
|
||||
size_t steps_x8 = s_len / 8;
|
||||
size_t steps_x1 = s_len & 7;
|
||||
|
||||
while( steps_x8-- )
|
||||
{
|
||||
MULADDC_X8_INIT
|
||||
MULADDC_X8_CORE
|
||||
MULADDC_X8_STOP
|
||||
}
|
||||
|
||||
while( steps_x1-- )
|
||||
{
|
||||
MULADDC_X1_INIT
|
||||
MULADDC_X1_CORE
|
||||
MULADDC_X1_STOP
|
||||
}
|
||||
|
||||
while( excess_len-- )
|
||||
{
|
||||
*d += c;
|
||||
c = ( *d < c );
|
||||
d++;
|
||||
}
|
||||
|
||||
return( c );
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast Montgomery initialization (thanks to Tom St Denis).
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_montmul_init( const mbedtls_mpi_uint *N )
|
||||
{
|
||||
mbedtls_mpi_uint x = N[0];
|
||||
|
||||
x += ( ( N[0] + 2 ) & 4 ) << 1;
|
||||
|
||||
for( unsigned int i = biL; i >= 8; i /= 2 )
|
||||
x *= ( 2 - ( N[0] * x ) );
|
||||
|
||||
return( ~x + 1 );
|
||||
}
|
||||
|
||||
void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
size_t B_limbs,
|
||||
const mbedtls_mpi_uint *N,
|
||||
size_t AN_limbs,
|
||||
mbedtls_mpi_uint mm,
|
||||
mbedtls_mpi_uint *T )
|
||||
{
|
||||
memset( T, 0, ( 2 * AN_limbs + 1 ) * ciL );
|
||||
|
||||
for( size_t i = 0; i < AN_limbs; i++ )
|
||||
{
|
||||
/* T = (T + u0*B + u1*N) / 2^biL */
|
||||
mbedtls_mpi_uint u0 = A[i];
|
||||
mbedtls_mpi_uint u1 = ( T[0] + u0 * B[0] ) * mm;
|
||||
|
||||
(void) mbedtls_mpi_core_mla( T, AN_limbs + 2, B, B_limbs, u0 );
|
||||
(void) mbedtls_mpi_core_mla( T, AN_limbs + 2, N, AN_limbs, u1 );
|
||||
|
||||
T++;
|
||||
}
|
||||
|
||||
/*
|
||||
* The result we want is (T >= N) ? T - N : T.
|
||||
*
|
||||
* For better constant-time properties in this function, we always do the
|
||||
* subtraction, with the result in X.
|
||||
*
|
||||
* We also look to see if there was any carry in the final additions in the
|
||||
* loop above.
|
||||
*/
|
||||
|
||||
mbedtls_mpi_uint carry = T[AN_limbs];
|
||||
mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub( X, T, N, AN_limbs );
|
||||
|
||||
/*
|
||||
* Using R as the Montgomery radix (auxiliary modulus) i.e. 2^(biL*AN_limbs):
|
||||
*
|
||||
* T can be in one of 3 ranges:
|
||||
*
|
||||
* 1) T < N : (carry, borrow) = (0, 1): we want T
|
||||
* 2) N <= T < R : (carry, borrow) = (0, 0): we want X
|
||||
* 3) T >= R : (carry, borrow) = (1, 1): we want X
|
||||
*
|
||||
* and (carry, borrow) = (1, 0) can't happen.
|
||||
*
|
||||
* So the correct return value is already in X if (carry ^ borrow) = 0,
|
||||
* but is in (the lower AN_limbs limbs of) T if (carry ^ borrow) = 1.
|
||||
*/
|
||||
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,6 +86,20 @@
|
|||
#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 */
|
||||
|
||||
/*
|
||||
* Convert between bits/chars and number of limbs
|
||||
* Divide first in order to avoid potential overflows
|
||||
*/
|
||||
#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
|
||||
#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
|
||||
/* Get a specific byte, without range checks. */
|
||||
#define GET_BYTE( X, i ) \
|
||||
( ( (X)[(i) / ciL] >> ( ( (i) % ciL ) * 8 ) ) & 0xff )
|
||||
|
||||
/** Count leading zero bits in a given integer.
|
||||
*
|
||||
* \param a Integer to count leading zero bits.
|
||||
|
@ -60,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
|
||||
|
@ -141,18 +262,276 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *A,
|
|||
unsigned char *output,
|
||||
size_t output_length );
|
||||
|
||||
#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
|
||||
* Divide first in order to avoid potential overflows
|
||||
/** \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.
|
||||
*/
|
||||
#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
|
||||
#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
|
||||
/* Get a specific byte, without range checks. */
|
||||
#define GET_BYTE( X, i ) \
|
||||
( ( (X)[(i) / ciL] >> ( ( (i) % ciL ) * 8 ) ) & 0xff )
|
||||
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.
|
||||
*
|
||||
* Functionally equivalent to
|
||||
*
|
||||
* ```
|
||||
* if( cond )
|
||||
* X += A;
|
||||
* return carry;
|
||||
* ```
|
||||
*
|
||||
* This function operates modulo `2^(biL*limbs)`.
|
||||
*
|
||||
* \param[in,out] X The pointer to the (little-endian) array
|
||||
* representing the bignum to accumulate onto.
|
||||
* \param[in] A The pointer to the (little-endian) array
|
||||
* representing the bignum to conditionally add
|
||||
* to \p X. This may be aliased to \p X but may not
|
||||
* overlap otherwise.
|
||||
* \param limbs Number of limbs of \p X and \p A.
|
||||
* \param cond Condition bit dictating whether addition should
|
||||
* happen or not. This must be \c 0 or \c 1.
|
||||
*
|
||||
* \warning If \p cond is neither 0 nor 1, the result of this function
|
||||
* is unspecified, and the resulting value in \p X might be
|
||||
* neither its original value nor \p X + \p A.
|
||||
*
|
||||
* \return 1 if `X + cond * A >= 2^(biL*limbs)`, 0 otherwise.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_add_if( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs,
|
||||
unsigned cond );
|
||||
|
||||
/**
|
||||
* \brief Subtract two fixed-size large unsigned integers, returning the borrow.
|
||||
*
|
||||
* Calculate `A - B` where \p A and \p B have the same size.
|
||||
* This function operates modulo `2^(biL*limbs)` and returns the carry
|
||||
* (1 if there was a wraparound, i.e. if `A < B`, and 0 otherwise).
|
||||
*
|
||||
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
|
||||
* either otherwise.
|
||||
*
|
||||
* \param[out] X The result of the subtraction.
|
||||
* \param[in] A Little-endian presentation of left operand.
|
||||
* \param[in] B Little-endian presentation of right operand.
|
||||
* \param limbs Number of limbs of \p X, \p A and \p B.
|
||||
*
|
||||
* \return 1 if `A < B`.
|
||||
* 0 if `A >= B`.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_sub( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B,
|
||||
size_t limbs );
|
||||
|
||||
/**
|
||||
* \brief Perform a fixed-size multiply accumulate operation: X += b * A
|
||||
*
|
||||
* \p X may be aliased to \p A (when \p X_limbs == \p A_limbs), but may not
|
||||
* otherwise overlap.
|
||||
*
|
||||
* This function operates modulo `2^(biL*X_limbs)`.
|
||||
*
|
||||
* \param[in,out] X The pointer to the (little-endian) array
|
||||
* representing the bignum to accumulate onto.
|
||||
* \param X_limbs The number of limbs of \p X. This must be
|
||||
* at least \p A_limbs.
|
||||
* \param[in] A The pointer to the (little-endian) array
|
||||
* representing the bignum to multiply with.
|
||||
* This may be aliased to \p X but may not overlap
|
||||
* otherwise.
|
||||
* \param A_limbs The number of limbs of \p A.
|
||||
* \param b X scalar to multiply with.
|
||||
*
|
||||
* \return The carry at the end of the operation.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_mla( mbedtls_mpi_uint *X, size_t X_limbs,
|
||||
const mbedtls_mpi_uint *A, size_t A_limbs,
|
||||
mbedtls_mpi_uint b );
|
||||
|
||||
/**
|
||||
* \brief Calculate initialisation value for fast Montgomery modular
|
||||
* multiplication
|
||||
*
|
||||
* \param[in] N Little-endian presentation of the modulus. This must have
|
||||
* at least one limb.
|
||||
*
|
||||
* \return The initialisation value for fast Montgomery modular multiplication
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_montmul_init( const mbedtls_mpi_uint *N );
|
||||
|
||||
/**
|
||||
* \brief Montgomery multiplication: X = A * B * R^-1 mod N (HAC 14.36)
|
||||
*
|
||||
* \p A and \p B must be in canonical form. That is, < \p N.
|
||||
*
|
||||
* \p X may be aliased to \p A or \p N, or even \p B (if \p AN_limbs ==
|
||||
* \p B_limbs) but may not overlap any parameters otherwise.
|
||||
*
|
||||
* \p A and \p B may alias each other, if \p AN_limbs == \p B_limbs. They may
|
||||
* not alias \p N (since they must be in canonical form, they cannot == \p N).
|
||||
*
|
||||
* \param[out] X The destination MPI, as a little-endian array of
|
||||
* length \p AN_limbs.
|
||||
* On successful completion, X contains the result of
|
||||
* the multiplication `A * B * R^-1` mod N where
|
||||
* `R = 2^(biL*AN_limbs)`.
|
||||
* \param[in] A Little-endian presentation of first operand.
|
||||
* Must have the same number of limbs as \p N.
|
||||
* \param[in] B Little-endian presentation of second operand.
|
||||
* \param[in] B_limbs The number of limbs in \p B.
|
||||
* Must be <= \p AN_limbs.
|
||||
* \param[in] N Little-endian presentation of the modulus.
|
||||
* This must be odd, and have exactly the same number
|
||||
* of limbs as \p A.
|
||||
* It may alias \p X, but must not alias or otherwise
|
||||
* overlap any of the other parameters.
|
||||
* \param[in] AN_limbs The number of limbs in \p X, \p A and \p N.
|
||||
* \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL.
|
||||
* This can be calculated by `mbedtls_mpi_core_montmul_init()`.
|
||||
* \param[in,out] T Temporary storage of size at least 2*AN_limbs+1 limbs.
|
||||
* Its initial content is unused and
|
||||
* its final content is indeterminate.
|
||||
* It must not alias or otherwise overlap any of the
|
||||
* other parameters.
|
||||
*/
|
||||
void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *B, size_t B_limbs,
|
||||
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 */
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/**
|
||||
* Internal bignum functions
|
||||
*
|
||||
* 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_BIGNUM_INTERNAL_H
|
||||
#define MBEDTLS_BIGNUM_INTERNAL_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
/** Perform a known-size multiply accumulate operation
|
||||
*
|
||||
* Add \p b * \p s to \p d.
|
||||
*
|
||||
* \param[in,out] d The pointer to the (little-endian) array
|
||||
* representing the bignum to accumulate onto.
|
||||
* \param d_len The number of limbs of \p d. This must be
|
||||
* at least \p s_len.
|
||||
* \param[in] s The pointer to the (little-endian) array
|
||||
* representing the bignum to multiply with.
|
||||
* This may be the same as \p d. Otherwise,
|
||||
* it must be disjoint from \p d.
|
||||
* \param s_len The number of limbs of \p s.
|
||||
* \param b A scalar to multiply with.
|
||||
*
|
||||
* \return c The carry at the end of the operation.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_mla( mbedtls_mpi_uint *d, size_t d_len ,
|
||||
const mbedtls_mpi_uint *s, size_t s_len,
|
||||
mbedtls_mpi_uint b );
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_INTERNAL_H */
|
|
@ -27,15 +27,7 @@
|
|||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "bignum_core.h"
|
||||
#include "bignum_mod.h"
|
||||
|
@ -85,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 );
|
||||
|
@ -101,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,
|
||||
|
@ -128,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;
|
||||
|
@ -149,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 */
|
||||
|
|
|
@ -26,21 +26,29 @@
|
|||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "bignum_core.h"
|
||||
#include "bignum_mod_raw.h"
|
||||
#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,
|
||||
|
@ -94,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 */
|
||||
|
|
|
@ -32,23 +32,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_CAMELLIA_ALT)
|
||||
|
||||
/* Parameter validation macros */
|
||||
#define CAMELLIA_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA )
|
||||
#define CAMELLIA_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
static const unsigned char SIGMA_CHARS[6][8] =
|
||||
{
|
||||
{ 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
|
||||
|
@ -298,7 +285,6 @@ static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
|
|||
|
||||
void mbedtls_camellia_init( mbedtls_camellia_context *ctx )
|
||||
{
|
||||
CAMELLIA_VALIDATE( ctx != NULL );
|
||||
memset( ctx, 0, sizeof( mbedtls_camellia_context ) );
|
||||
}
|
||||
|
||||
|
@ -325,9 +311,6 @@ int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
|
|||
uint32_t KC[16];
|
||||
uint32_t TK[20];
|
||||
|
||||
CAMELLIA_VALIDATE_RET( ctx != NULL );
|
||||
CAMELLIA_VALIDATE_RET( key != NULL );
|
||||
|
||||
RK = ctx->rk;
|
||||
|
||||
memset( t, 0, 64 );
|
||||
|
@ -431,8 +414,6 @@ int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
|
|||
mbedtls_camellia_context cty;
|
||||
uint32_t *RK;
|
||||
uint32_t *SK;
|
||||
CAMELLIA_VALIDATE_RET( ctx != NULL );
|
||||
CAMELLIA_VALIDATE_RET( key != NULL );
|
||||
|
||||
mbedtls_camellia_init( &cty );
|
||||
|
||||
|
@ -480,11 +461,8 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
|
|||
{
|
||||
int NR;
|
||||
uint32_t *RK, X[4];
|
||||
CAMELLIA_VALIDATE_RET( ctx != NULL );
|
||||
CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
|
||||
mode == MBEDTLS_CAMELLIA_DECRYPT );
|
||||
CAMELLIA_VALIDATE_RET( input != NULL );
|
||||
CAMELLIA_VALIDATE_RET( output != NULL );
|
||||
if( mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT )
|
||||
return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
|
||||
|
||||
( (void) mode );
|
||||
|
||||
|
@ -550,12 +528,8 @@ int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
|
|||
{
|
||||
int i;
|
||||
unsigned char temp[16];
|
||||
CAMELLIA_VALIDATE_RET( ctx != NULL );
|
||||
CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
|
||||
mode == MBEDTLS_CAMELLIA_DECRYPT );
|
||||
CAMELLIA_VALIDATE_RET( iv != NULL );
|
||||
CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
|
||||
if( mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT )
|
||||
return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
|
||||
|
||||
if( length % 16 )
|
||||
return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
|
||||
|
@ -611,13 +585,8 @@ int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
|
|||
{
|
||||
int c;
|
||||
size_t n;
|
||||
CAMELLIA_VALIDATE_RET( ctx != NULL );
|
||||
CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
|
||||
mode == MBEDTLS_CAMELLIA_DECRYPT );
|
||||
CAMELLIA_VALIDATE_RET( iv != NULL );
|
||||
CAMELLIA_VALIDATE_RET( iv_off != NULL );
|
||||
CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
|
||||
if( mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT )
|
||||
return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
|
||||
|
||||
n = *iv_off;
|
||||
if( n >= 16 )
|
||||
|
@ -670,12 +639,6 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
|
|||
{
|
||||
int c, i;
|
||||
size_t n;
|
||||
CAMELLIA_VALIDATE_RET( ctx != NULL );
|
||||
CAMELLIA_VALIDATE_RET( nonce_counter != NULL );
|
||||
CAMELLIA_VALIDATE_RET( stream_block != NULL );
|
||||
CAMELLIA_VALIDATE_RET( nc_off != NULL );
|
||||
CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
|
||||
|
||||
n = *nc_off;
|
||||
if( n >= 16 )
|
||||
|
|
|
@ -32,14 +32,7 @@
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_CHACHA20_ALT)
|
||||
|
||||
|
@ -48,12 +41,6 @@
|
|||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Parameter validation macros */
|
||||
#define CHACHA20_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
|
||||
#define CHACHA20_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#define ROTL32( value, amount ) \
|
||||
( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
|
||||
|
||||
|
@ -172,8 +159,6 @@ static void chacha20_block( const uint32_t initial_state[16],
|
|||
|
||||
void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
|
||||
{
|
||||
CHACHA20_VALIDATE( ctx != NULL );
|
||||
|
||||
mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
|
||||
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
|
||||
|
||||
|
@ -192,9 +177,6 @@ void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
|
|||
int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
|
||||
const unsigned char key[32] )
|
||||
{
|
||||
CHACHA20_VALIDATE_RET( ctx != NULL );
|
||||
CHACHA20_VALIDATE_RET( key != NULL );
|
||||
|
||||
/* ChaCha20 constants - the string "expand 32-byte k" */
|
||||
ctx->state[0] = 0x61707865;
|
||||
ctx->state[1] = 0x3320646e;
|
||||
|
@ -218,9 +200,6 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
|
|||
const unsigned char nonce[12],
|
||||
uint32_t counter )
|
||||
{
|
||||
CHACHA20_VALIDATE_RET( ctx != NULL );
|
||||
CHACHA20_VALIDATE_RET( nonce != NULL );
|
||||
|
||||
/* Counter */
|
||||
ctx->state[12] = counter;
|
||||
|
||||
|
@ -245,10 +224,6 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
|
|||
size_t offset = 0U;
|
||||
size_t i;
|
||||
|
||||
CHACHA20_VALIDATE_RET( ctx != NULL );
|
||||
CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
|
||||
CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
|
||||
|
||||
/* Use leftover keystream bytes, if available */
|
||||
while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
|
||||
{
|
||||
|
@ -312,11 +287,6 @@ int mbedtls_chacha20_crypt( const unsigned char key[32],
|
|||
mbedtls_chacha20_context ctx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
CHACHA20_VALIDATE_RET( key != NULL );
|
||||
CHACHA20_VALIDATE_RET( nonce != NULL );
|
||||
CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
|
||||
CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
|
||||
|
||||
mbedtls_chacha20_init( &ctx );
|
||||
|
||||
ret = mbedtls_chacha20_setkey( &ctx, key );
|
||||
|
|
|
@ -28,23 +28,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_CHACHAPOLY_ALT)
|
||||
|
||||
/* Parameter validation macros */
|
||||
#define CHACHAPOLY_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
|
||||
#define CHACHAPOLY_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#define CHACHAPOLY_STATE_INIT ( 0 )
|
||||
#define CHACHAPOLY_STATE_AAD ( 1 )
|
||||
#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
|
||||
|
@ -91,8 +78,6 @@ static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx )
|
|||
|
||||
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
|
||||
{
|
||||
CHACHAPOLY_VALIDATE( ctx != NULL );
|
||||
|
||||
mbedtls_chacha20_init( &ctx->chacha20_ctx );
|
||||
mbedtls_poly1305_init( &ctx->poly1305_ctx );
|
||||
ctx->aad_len = 0U;
|
||||
|
@ -118,8 +103,6 @@ int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
|
|||
const unsigned char key[32] )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( key != NULL );
|
||||
|
||||
ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
|
||||
|
||||
|
@ -132,8 +115,6 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char poly1305_key[64];
|
||||
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( nonce != NULL );
|
||||
|
||||
/* Set counter = 0, will be update to 1 when generating Poly1305 key */
|
||||
ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
|
||||
|
@ -170,9 +151,6 @@ int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
|
|||
const unsigned char *aad,
|
||||
size_t aad_len )
|
||||
{
|
||||
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
|
||||
|
||||
if( ctx->state != CHACHAPOLY_STATE_AAD )
|
||||
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
|
||||
|
||||
|
@ -187,9 +165,6 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
|
|||
unsigned char *output )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );
|
||||
|
||||
if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
|
||||
( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
|
||||
|
@ -237,8 +212,6 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char len_block[16];
|
||||
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( mac != NULL );
|
||||
|
||||
if( ctx->state == CHACHAPOLY_STATE_INIT )
|
||||
{
|
||||
|
@ -314,13 +287,6 @@ int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
|
|||
unsigned char *output,
|
||||
unsigned char tag[16] )
|
||||
{
|
||||
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( nonce != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( tag != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL );
|
||||
|
||||
return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
|
||||
length, nonce, aad, aad_len,
|
||||
input, output, tag ) );
|
||||
|
@ -339,12 +305,6 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
|
|||
unsigned char check_tag[16];
|
||||
size_t i;
|
||||
int diff;
|
||||
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( nonce != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( tag != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL );
|
||||
|
||||
if( ( ret = chachapoly_crypt_and_tag( ctx,
|
||||
MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
|
||||
|
|
|
@ -93,4 +93,9 @@
|
|||
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) && \
|
||||
!defined(PSA_WANT_ALG_SHA_256)
|
||||
#error "PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CHECK_CRYPTO_CONFIG_H */
|
||||
|
|
|
@ -63,17 +63,7 @@
|
|||
#include "mbedtls/nist_kw.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#define CIPHER_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
|
||||
#define CIPHER_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
static int supported_init = 0;
|
||||
|
||||
|
@ -143,7 +133,6 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
|
|||
|
||||
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
CIPHER_VALIDATE( ctx != NULL );
|
||||
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
|
||||
}
|
||||
|
||||
|
@ -193,7 +182,6 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
|
|||
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
|
||||
const mbedtls_cipher_info_t *cipher_info )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
if( cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -257,10 +245,8 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
|
|||
int key_bitlen,
|
||||
const mbedtls_operation_t operation )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( key != NULL );
|
||||
CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
|
||||
operation == MBEDTLS_DECRYPT );
|
||||
if( operation != MBEDTLS_ENCRYPT && operation != MBEDTLS_DECRYPT )
|
||||
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
if( ctx->cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -356,8 +342,6 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
|
|||
{
|
||||
size_t actual_iv_size;
|
||||
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
|
||||
if( ctx->cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
@ -453,7 +437,6 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
|
|||
|
||||
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
if( ctx->cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -475,8 +458,6 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
|
|||
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *ad, size_t ad_len )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
|
||||
if( ctx->cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -529,10 +510,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t block_size;
|
||||
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
CIPHER_VALIDATE_RET( output != NULL );
|
||||
CIPHER_VALIDATE_RET( olen != NULL );
|
||||
if( ctx->cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -952,9 +929,6 @@ static int get_no_padding( unsigned char *input, size_t input_len,
|
|||
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
|
||||
unsigned char *output, size_t *olen )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( output != NULL );
|
||||
CIPHER_VALIDATE_RET( olen != NULL );
|
||||
if( ctx->cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -1054,8 +1028,6 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
|
|||
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
|
||||
mbedtls_cipher_padding_t mode )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
|
||||
{
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
@ -1117,8 +1089,6 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
|
|||
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
|
||||
unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||
if( ctx->cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -1168,8 +1138,6 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
|
|||
unsigned char check_tag[16];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||
if( ctx->cipher_info == NULL )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -1261,12 +1229,6 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t finish_olen;
|
||||
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
|
||||
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
CIPHER_VALIDATE_RET( output != NULL );
|
||||
CIPHER_VALIDATE_RET( olen != NULL );
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( ctx->psa_enabled == 1 )
|
||||
{
|
||||
|
@ -1542,13 +1504,6 @@ int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx,
|
|||
unsigned char *output, size_t output_len,
|
||||
size_t *olen, size_t tag_len )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
|
||||
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
|
||||
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
CIPHER_VALIDATE_RET( output != NULL );
|
||||
CIPHER_VALIDATE_RET( olen != NULL );
|
||||
|
||||
#if defined(MBEDTLS_NIST_KW_C)
|
||||
if(
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
@ -1598,13 +1553,6 @@ int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx,
|
|||
unsigned char *output, size_t output_len,
|
||||
size_t *olen, size_t tag_len )
|
||||
{
|
||||
CIPHER_VALIDATE_RET( ctx != NULL );
|
||||
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
|
||||
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
|
||||
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
CIPHER_VALIDATE_RET( output_len == 0 || output != NULL );
|
||||
CIPHER_VALIDATE_RET( olen != NULL );
|
||||
|
||||
#if defined(MBEDTLS_NIST_KW_C)
|
||||
if(
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
|
|
@ -68,13 +68,7 @@
|
|||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
/* shared by all GCM ciphers */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "bignum_core.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C)
|
||||
|
@ -81,7 +82,7 @@ unsigned mbedtls_ct_uint_mask( unsigned value )
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
|
||||
|
||||
size_t mbedtls_ct_size_mask( size_t value )
|
||||
{
|
||||
|
@ -97,7 +98,7 @@ size_t mbedtls_ct_size_mask( size_t value )
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
|
||||
|
@ -404,7 +405,7 @@ static void mbedtls_ct_mem_move_to_left( void *start,
|
|||
|
||||
#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
|
||||
|
||||
void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
|
||||
const unsigned char *src,
|
||||
|
@ -654,7 +655,7 @@ cleanup:
|
|||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_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)
|
||||
|
||||
|
@ -138,6 +138,7 @@ unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
|
|||
* \param B The right-hand MPI. This must point to an array of limbs
|
||||
* with the same allocated length as \p A.
|
||||
* \param limbs The number of limbs in \p A and \p B.
|
||||
* This must not be 0.
|
||||
*
|
||||
* \return The result of the comparison:
|
||||
* \c 1 if \p A is less than \p B.
|
||||
|
@ -213,7 +214,7 @@ signed char mbedtls_ct_base64_dec_value( unsigned char c );
|
|||
|
||||
#endif /* MBEDTLS_BASE64_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
|
||||
|
||||
/** Conditional memcpy without branches.
|
||||
*
|
||||
|
@ -321,7 +322,7 @@ int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
|
|||
unsigned char *output );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
|
||||
|
||||
|
|
|
@ -36,14 +36,7 @@
|
|||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
/*
|
||||
* CTR_DRBG context initialization
|
||||
|
|
|
@ -21,16 +21,7 @@
|
|||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_time_t time_t
|
||||
#define mbedtls_snprintf snprintf
|
||||
#define mbedtls_vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
|
|
@ -33,14 +33,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_DES_ALT)
|
||||
|
||||
|
|
|
@ -43,23 +43,10 @@
|
|||
#include "mbedtls/asn1.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_DHM_ALT)
|
||||
|
||||
#define DHM_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
|
||||
#define DHM_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/*
|
||||
* helper to validate the mbedtls_mpi size and import it
|
||||
*/
|
||||
|
@ -120,7 +107,6 @@ cleanup:
|
|||
|
||||
void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
|
||||
{
|
||||
DHM_VALIDATE( ctx != NULL );
|
||||
memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
|
||||
}
|
||||
|
||||
|
@ -173,9 +159,6 @@ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
|
|||
const unsigned char *end )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( p != NULL && *p != NULL );
|
||||
DHM_VALIDATE_RET( end != NULL );
|
||||
|
||||
if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
|
||||
( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
|
||||
|
@ -252,10 +235,6 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
|
|||
int ret;
|
||||
size_t n1, n2, n3;
|
||||
unsigned char *p;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( output != NULL );
|
||||
DHM_VALIDATE_RET( olen != NULL );
|
||||
DHM_VALIDATE_RET( f_rng != NULL );
|
||||
|
||||
ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
|
||||
if( ret != 0 )
|
||||
|
@ -300,9 +279,6 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
|
|||
const mbedtls_mpi *G )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( P != NULL );
|
||||
DHM_VALIDATE_RET( G != NULL );
|
||||
|
||||
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
|
||||
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
|
||||
|
@ -320,8 +296,6 @@ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
|
|||
const unsigned char *input, size_t ilen )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( input != NULL );
|
||||
|
||||
if( ilen < 1 || ilen > mbedtls_dhm_get_len( ctx ) )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
@ -341,9 +315,6 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
|
|||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( output != NULL );
|
||||
DHM_VALIDATE_RET( f_rng != NULL );
|
||||
|
||||
if( olen < 1 || olen > mbedtls_dhm_get_len( ctx ) )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
@ -440,9 +411,6 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi GYb;
|
||||
DHM_VALIDATE_RET( ctx != NULL );
|
||||
DHM_VALIDATE_RET( output != NULL );
|
||||
DHM_VALIDATE_RET( olen != NULL );
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
@ -518,9 +486,6 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
|
|||
mbedtls_pem_context pem;
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
|
||||
DHM_VALIDATE_RET( dhm != NULL );
|
||||
DHM_VALIDATE_RET( dhmin != NULL );
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pem_init( &pem );
|
||||
|
||||
|
@ -667,8 +632,6 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
unsigned char *buf;
|
||||
DHM_VALIDATE_RET( dhm != NULL );
|
||||
DHM_VALIDATE_RET( path != NULL );
|
||||
|
||||
if( ( ret = load_file( path, &buf, &n ) ) != 0 )
|
||||
return( ret );
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -36,13 +36,7 @@
|
|||
#include "mbedtls/hmac_drbg.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
|
|
@ -236,7 +236,7 @@ static int ecjpake_hash( const mbedtls_md_type_t md_type,
|
|||
unsigned char *p = buf;
|
||||
const unsigned char *end = buf + sizeof( buf );
|
||||
const size_t id_len = strlen( id );
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
|
||||
|
||||
/* Write things to temporary buffer */
|
||||
MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) );
|
||||
|
@ -760,22 +760,14 @@ cleanup:
|
|||
/*
|
||||
* Derive PMS (7.4.2.7 / 7.4.2.8)
|
||||
*/
|
||||
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
|
||||
unsigned char *buf, size_t len, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
static int mbedtls_ecjpake_derive_k( mbedtls_ecjpake_context *ctx,
|
||||
mbedtls_ecp_point *K,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_point K;
|
||||
mbedtls_mpi m_xm2_s, one;
|
||||
unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
|
||||
size_t x_bytes;
|
||||
|
||||
*olen = mbedtls_hash_info_get_size( ctx->md_type );
|
||||
if( len < *olen )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
mbedtls_ecp_point_init( &K );
|
||||
mbedtls_mpi_init( &m_xm2_s );
|
||||
mbedtls_mpi_init( &one );
|
||||
|
||||
|
@ -788,12 +780,39 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
|
|||
*/
|
||||
MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
|
||||
&ctx->grp.N, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, K,
|
||||
&one, &ctx->Xp,
|
||||
&m_xm2_s, &ctx->Xp2 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, K, &ctx->xm2, K,
|
||||
f_rng, p_rng ) );
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free( &m_xm2_s );
|
||||
mbedtls_mpi_free( &one );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
|
||||
unsigned char *buf, size_t len, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_point K;
|
||||
unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
|
||||
size_t x_bytes;
|
||||
|
||||
*olen = mbedtls_hash_info_get_size( ctx->md_type );
|
||||
if( len < *olen )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
mbedtls_ecp_point_init( &K );
|
||||
|
||||
ret = mbedtls_ecjpake_derive_k(ctx, &K, f_rng, p_rng);
|
||||
if( ret )
|
||||
goto cleanup;
|
||||
|
||||
/* PMS = SHA-256( K.X ) */
|
||||
x_bytes = ( ctx->grp.pbits + 7 ) / 8;
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
|
||||
|
@ -802,8 +821,31 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
|
|||
|
||||
cleanup:
|
||||
mbedtls_ecp_point_free( &K );
|
||||
mbedtls_mpi_free( &m_xm2_s );
|
||||
mbedtls_mpi_free( &one );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_ecjpake_write_shared_key( mbedtls_ecjpake_context *ctx,
|
||||
unsigned char *buf, size_t len, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_point K;
|
||||
|
||||
mbedtls_ecp_point_init( &K );
|
||||
|
||||
ret = mbedtls_ecjpake_derive_k(ctx, &K, f_rng, p_rng);
|
||||
if( ret )
|
||||
goto cleanup;
|
||||
|
||||
ret = mbedtls_ecp_point_write_binary( &ctx->grp, &K, ctx->point_format,
|
||||
olen, buf, len );
|
||||
if( ret != 0 )
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
mbedtls_ecp_point_free( &K );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
@ -815,12 +857,7 @@ cleanup:
|
|||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
|
||||
!defined(MBEDTLS_SHA256_C)
|
||||
|
@ -958,6 +995,15 @@ static const unsigned char ecjpake_test_cli_two[] = {
|
|||
0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
|
||||
};
|
||||
|
||||
static const unsigned char ecjpake_test_shared_key[] = {
|
||||
0x04, 0x01, 0xab, 0xe9, 0xf2, 0xc7, 0x3a, 0x99, 0x14, 0xcb, 0x1f, 0x80,
|
||||
0xfb, 0x9d, 0xdb, 0x7e, 0x00, 0x12, 0xa8, 0x9c, 0x2f, 0x39, 0x27, 0x79,
|
||||
0xf9, 0x64, 0x40, 0x14, 0x75, 0xea, 0xc1, 0x31, 0x28, 0x43, 0x8f, 0xe1,
|
||||
0x12, 0x41, 0xd6, 0xc1, 0xe5, 0x5f, 0x7b, 0x80, 0x88, 0x94, 0xc9, 0xc0,
|
||||
0x27, 0xa3, 0x34, 0x41, 0xf5, 0xcb, 0xa1, 0xfe, 0x6c, 0xc7, 0xe6, 0x12,
|
||||
0x17, 0xc3, 0xde, 0x27, 0xb4,
|
||||
};
|
||||
|
||||
static const unsigned char ecjpake_test_pms[] = {
|
||||
0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
|
||||
0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
|
||||
|
@ -1144,6 +1190,13 @@ int mbedtls_ecjpake_self_test( int verbose )
|
|||
TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
|
||||
TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
|
||||
|
||||
/* Server derives K as unsigned binary data */
|
||||
TEST_ASSERT( mbedtls_ecjpake_write_shared_key( &srv,
|
||||
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
|
||||
|
||||
TEST_ASSERT( len == sizeof( ecjpake_test_shared_key ) );
|
||||
TEST_ASSERT( memcmp( buf, ecjpake_test_shared_key, len ) == 0 );
|
||||
|
||||
memset( buf, 0, len ); /* Avoid interferences with next step */
|
||||
|
||||
/* Client derives PMS */
|
||||
|
@ -1153,6 +1206,13 @@ int mbedtls_ecjpake_self_test( int verbose )
|
|||
TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
|
||||
TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
|
||||
|
||||
/* Client derives K as unsigned binary data */
|
||||
TEST_ASSERT( mbedtls_ecjpake_write_shared_key( &cli,
|
||||
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
|
||||
|
||||
TEST_ASSERT( len == sizeof( ecjpake_test_shared_key ) );
|
||||
TEST_ASSERT( memcmp( buf, ecjpake_test_shared_key, len ) == 0 );
|
||||
|
||||
if( verbose != 0 )
|
||||
mbedtls_printf( "passed\n" );
|
||||
#endif /* ! MBEDTLS_ECJPAKE_ALT */
|
||||
|
|
|
@ -84,15 +84,7 @@
|
|||
|
||||
#if !defined(MBEDTLS_ECP_ALT)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "ecp_internal_alt.h"
|
||||
|
||||
|
@ -2287,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 );
|
||||
|
@ -2467,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 );
|
||||
|
@ -2537,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 );
|
||||
|
@ -2666,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 );
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "mbedtls/error.h"
|
||||
|
||||
#include "bn_mul.h"
|
||||
#include "bignum_internal.h"
|
||||
#include "bignum_core.h"
|
||||
#include "ecp_invasive.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -4969,9 +4969,6 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
|
|||
#define ADD( j ) add32( &cur, A( j ), &c );
|
||||
#define SUB( j ) sub32( &cur, A( j ), &c );
|
||||
|
||||
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
|
||||
#define biL (ciL << 3) /* bits in limb */
|
||||
|
||||
/*
|
||||
* Helpers for the main 'loop'
|
||||
*/
|
||||
|
|
|
@ -32,18 +32,9 @@
|
|||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
#include "mbedtls/platform.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
|
||||
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
|
||||
|
|
|
@ -35,9 +35,7 @@
|
|||
#if defined(MBEDTLS_TIMING_C)
|
||||
#include "mbedtls/timing.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED) || !defined(HAVE_SYSCTL_ARND)
|
||||
#include "mbedtls/platform.h"
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#if defined(MBEDTLS_GCM_C)
|
||||
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
|
@ -41,29 +42,13 @@
|
|||
#include "aesni.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||
|
||||
#if !defined(MBEDTLS_GCM_ALT)
|
||||
|
||||
/* Parameter validation macros */
|
||||
#define GCM_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
|
||||
#define GCM_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/*
|
||||
* Initialize a context
|
||||
*/
|
||||
void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
|
||||
{
|
||||
GCM_VALIDATE( ctx != NULL );
|
||||
memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
|
||||
}
|
||||
|
||||
|
@ -143,9 +128,8 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const mbedtls_cipher_info_t *cipher_info;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( key != NULL );
|
||||
GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
|
||||
if( keybits != 128 && keybits != 192 && keybits != 256 )
|
||||
return MBEDTLS_ERR_GCM_BAD_INPUT;
|
||||
|
||||
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
|
||||
MBEDTLS_MODE_ECB );
|
||||
|
@ -256,9 +240,6 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
|
|||
size_t use_len, olen = 0;
|
||||
uint64_t iv_bits;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( iv != NULL );
|
||||
|
||||
/* IV is limited to 2^64 bits, so 2^61 bytes */
|
||||
/* IV is not allowed to be zero length */
|
||||
if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
|
||||
|
@ -334,8 +315,6 @@ int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
|
|||
const unsigned char *p;
|
||||
size_t use_len, i, offset;
|
||||
|
||||
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
|
||||
/* IV is limited to 2^64 bits, so 2^61 bytes */
|
||||
if( (uint64_t) add_len >> 61 != 0 )
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
|
@ -434,7 +413,6 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
|
|||
|
||||
if( output_size < input_length )
|
||||
return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
|
||||
GCM_VALIDATE_RET( output_length != NULL );
|
||||
*output_length = input_length;
|
||||
|
||||
/* Exit early if input_length==0 so that we don't do any pointer arithmetic
|
||||
|
@ -444,10 +422,6 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
|
|||
if( input_length == 0 )
|
||||
return( 0 );
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( input != NULL );
|
||||
GCM_VALIDATE_RET( output != NULL );
|
||||
|
||||
if( output > input && (size_t) ( output - input ) < input_length )
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
|
||||
|
@ -519,9 +493,6 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
|
|||
uint64_t orig_len;
|
||||
uint64_t orig_add_len;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( tag != NULL );
|
||||
|
||||
/* We never pass any output in finish(). The output parameter exists only
|
||||
* for the sake of alternative implementations. */
|
||||
(void) output;
|
||||
|
@ -580,13 +551,6 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t olen;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( iv != NULL );
|
||||
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
GCM_VALIDATE_RET( tag != NULL );
|
||||
|
||||
if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
|
@ -619,13 +583,6 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
|
|||
size_t i;
|
||||
int diff;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( iv != NULL );
|
||||
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
GCM_VALIDATE_RET( tag != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
|
||||
if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
|
||||
iv, iv_len, add, add_len,
|
||||
input, output, tag_len, check_tag ) ) != 0 )
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "hash_info.h"
|
||||
#include "legacy_or_psa.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -35,6 +35,20 @@
|
|||
#include "mbedtls/md.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
/** \def MBEDTLS_HASH_MAX_SIZE
|
||||
*
|
||||
* Maximum size of a hash based on configuration.
|
||||
*/
|
||||
#if defined(MBEDTLS_MD_C) && ( \
|
||||
!defined(MBEDTLS_PSA_CRYPTO_C) || \
|
||||
MBEDTLS_MD_MAX_SIZE >= PSA_HASH_MAX_SIZE )
|
||||
#define MBEDTLS_HASH_MAX_SIZE MBEDTLS_MD_MAX_SIZE
|
||||
#elif defined(MBEDTLS_PSA_CRYPTO_C) && ( \
|
||||
!defined(MBEDTLS_MD_C) || \
|
||||
PSA_HASH_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE )
|
||||
#define MBEDTLS_HASH_MAX_SIZE PSA_HASH_MAX_SIZE
|
||||
#endif
|
||||
|
||||
/** Get the output length of the given hash type from its MD type.
|
||||
*
|
||||
* \note To get the output length from the PSA alg, use \c PSA_HASH_LENGTH().
|
||||
|
|
|
@ -37,14 +37,7 @@
|
|||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
|
||||
/*
|
||||
* HMAC_DRBG context initialization
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
/**
|
||||
* Internal macros to express dependencies for code and tests
|
||||
* that may use either the legacy API or PSA in various builds.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These macros are for code that wants to use <crypto feature> and will do so
|
||||
* using <legacy API> or PSA depending on <condition>, where:
|
||||
* - <crypto feature> will generally be an algorithm (SHA-256, ECDH) but may
|
||||
* also be a key type (AES, RSA, EC) or domain parameters (elliptic curve);
|
||||
* - <legacy API> will be either:
|
||||
* - low-level module API (aes.h, sha256.h), or
|
||||
* - an abstraction layer (md.h, cipher.h);
|
||||
* - <condition> will be either:
|
||||
* - depending on what's available in the build:
|
||||
* legacy API used if available, PSA otherwise
|
||||
* (this is done to ensure backwards compatibility); or
|
||||
* - depending on whether MBEDTLS_USE_PSA_CRYPTO is defined.
|
||||
*
|
||||
* Examples:
|
||||
* - TLS 1.2 will compute hashes using either mbedtls_md_xxx() (and
|
||||
* mbedtls_sha256_xxx()) or psa_aead_xxx() depending on whether
|
||||
* MBEDTLS_USE_PSA_CRYPTO is defined;
|
||||
* - RSA PKCS#1 v2.1 will, in the near future*, compute hashes (for padding)
|
||||
* using either `mbedtls_md()` if it's available, or `psa_hash_compute()`
|
||||
* otherwise;
|
||||
* - PEM decoding of PEM-encrypted keys will, in the near future*, compute MD5
|
||||
* hashes using either `mbedtls_md5_xxx()` if it's available, or
|
||||
* `psa_hash_xxx()` otherwise.
|
||||
* *See docs/architecture/psa-migration/strategy.md, section "Supporting
|
||||
* builds with drivers without the software implementation", strategy for step
|
||||
* 1 (libmbedcrypto except the RNG subsystem).
|
||||
*
|
||||
* Note: the macros are essential to express test dependencies. Inside code,
|
||||
* we could instead just use the equivalent pre-processor condition, but
|
||||
* that's not possible in test dependencies where we need a single macro.
|
||||
* Hopefully, using these macros in code will also help with consistency.
|
||||
*
|
||||
* The naming scheme for these macros is:
|
||||
* MBEDTLS_HAS_feature_VIA_legacy_OR_PSA(_condition)
|
||||
* where:
|
||||
* - feature is expressed the same way as in PSA_WANT macros, for example:
|
||||
* KEY_TYPE_AES, ALG_SHA_256, ECC_SECP_R1_256;
|
||||
* - legacy is either LOWLEVEL or the name of the layer: MD, CIPHER;
|
||||
* - condition is omitted if it's based on availability, else it's
|
||||
* BASED_ON_USE_PSA.
|
||||
*
|
||||
* Coming back to the examples above:
|
||||
* - TLS 1.2 will determine if it can use SHA-256 using
|
||||
* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
|
||||
* for the purposes of negotiation, and in test dependencies;
|
||||
* - RSA PKCS#1 v2.1 tests that used SHA-256 will depend on
|
||||
* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA
|
||||
* - PEM decoding code and its associated tests will depend on
|
||||
* MBEDTLS_HAS_ALG_MD5_VIA_LOWLEVEL_OR_PSA
|
||||
*
|
||||
* Note: every time it's possible to use, say SHA-256, via the MD API, then
|
||||
* it's also possible to used it via the low-level API. So, code that wants to
|
||||
* use SHA-256 via both APIs only needs to depend on the MD macro. Also, it
|
||||
* just so happens that all the choosing which API to use based on
|
||||
* MBEDTLS_USE_PSA_CRYPTO (X.509, TLS 1.2/shared), always uses the abstraction
|
||||
* layer (sometimes in addition to the low-level API), so we don't need the
|
||||
* MBEDTLS_HAS_feature_VIA_LOWLEVEL_OR_PSA_BASED_ON_USE_PSA macros.
|
||||
* (PK, while obeying MBEDTLS_USE_PSA_CRYPTO, doesn't compute hashes itself,
|
||||
* even less makes use of ciphers.)
|
||||
*
|
||||
* Note: the macros MBEDTLS_HAS_feature_VIA_LOWLEVEL_OR_PSA are the minimal
|
||||
* condition for being able to use <feature> at all. As such, they should be
|
||||
* used for guarding data about <feature>, such as OIDs or size. For example,
|
||||
* OID values related to SHA-256 are only useful when SHA-256 can be used at
|
||||
* least in some way.
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_OR_PSA_HELPERS_H
|
||||
#define MBEDTLS_OR_PSA_HELPERS_H
|
||||
|
||||
#include "common.h"
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#include "psa/crypto.h"
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/*
|
||||
* Hashes
|
||||
*/
|
||||
|
||||
/* Hashes using low-level or PSA based on availability */
|
||||
#if defined(MBEDTLS_MD5_C) || \
|
||||
( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_MD5) )
|
||||
#define MBEDTLS_HAS_ALG_MD5_VIA_LOWLEVEL_OR_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_RIPEMD160_C) || \
|
||||
( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_RIPEMD160) )
|
||||
#define MBEDTLS_HAS_ALG_RIPEMD160_VIA_LOWLEVEL_OR_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA1_C) || \
|
||||
( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_1) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_1_VIA_LOWLEVEL_OR_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA224_C) || \
|
||||
( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_224) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_224_VIA_LOWLEVEL_OR_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA256_C) || \
|
||||
( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_256_VIA_LOWLEVEL_OR_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA384_C) || \
|
||||
( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_384) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_384_VIA_LOWLEVEL_OR_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA512_C) || \
|
||||
( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_512) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_512_VIA_LOWLEVEL_OR_PSA
|
||||
#endif
|
||||
|
||||
/* Hashes using MD or PSA based on availability */
|
||||
#if ( defined(MBEDTLS_MD_C) && defined(MBEDTLS_MD5_C) ) || \
|
||||
( !defined(MBEDTLS_MD_C) && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_MD5) )
|
||||
#define MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA
|
||||
#endif
|
||||
#if ( defined(MBEDTLS_MD_C) && defined(MBEDTLS_RIPEMD160_C) ) || \
|
||||
( !defined(MBEDTLS_MD_C) && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_RIPEMD160) )
|
||||
#define MBEDTLS_HAS_ALG_RIPEMD160_VIA_MD_OR_PSA
|
||||
#endif
|
||||
#if ( defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA1_C) ) || \
|
||||
( !defined(MBEDTLS_MD_C) && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_1) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA
|
||||
#endif
|
||||
#if ( defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA224_C) ) || \
|
||||
( !defined(MBEDTLS_MD_C) && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_224) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_224_VIA_MD_OR_PSA
|
||||
#endif
|
||||
#if ( defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C) ) || \
|
||||
( !defined(MBEDTLS_MD_C) && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA
|
||||
#endif
|
||||
#if ( defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA384_C) ) || \
|
||||
( !defined(MBEDTLS_MD_C) && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_384) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA
|
||||
#endif
|
||||
#if ( defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA512_C) ) || \
|
||||
( !defined(MBEDTLS_MD_C) && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_512) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA
|
||||
#endif
|
||||
|
||||
/* Hashes using MD or PSA based on MBEDTLS_USE_PSA_CRYPTO */
|
||||
#if ( !defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_MD_C) && defined(MBEDTLS_MD5_C) ) || \
|
||||
( defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_MD5) )
|
||||
#define MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
|
||||
#endif
|
||||
#if ( !defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_MD_C) && defined(MBEDTLS_RIPEMD160_C) ) || \
|
||||
( defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_RIPEMD160) )
|
||||
#define MBEDTLS_HAS_ALG_RIPEMD160_VIA_MD_OR_PSA_BASED_ON_USE_PSA
|
||||
#endif
|
||||
#if ( !defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA1_C) ) || \
|
||||
( defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_1) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA
|
||||
#endif
|
||||
#if ( !defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA224_C) ) || \
|
||||
( defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_224) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_224_VIA_MD_OR_PSA_BASED_ON_USE_PSA
|
||||
#endif
|
||||
#if ( !defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C) ) || \
|
||||
( defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_256) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
|
||||
#endif
|
||||
#if ( !defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA384_C) ) || \
|
||||
( defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_384) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA
|
||||
#endif
|
||||
#if ( !defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA512_C) ) || \
|
||||
( defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_512) )
|
||||
#define MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_OR_PSA_HELPERS_H */
|
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) */
|
|
@ -36,13 +36,7 @@
|
|||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
@ -32,14 +32,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_MD5_ALT)
|
||||
|
||||
|
|
|
@ -30,13 +30,7 @@
|
|||
#include "mps_common.h"
|
||||
#include "mps_trace.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_vsnprintf vsnprintf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
|
||||
#if defined(MBEDTLS_MPS_ENABLE_TRACE)
|
||||
|
||||
|
|
|
@ -37,11 +37,7 @@
|
|||
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in mbedtls_config.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "mbedtls/net_sockets.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
|
|
@ -39,14 +39,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||
|
||||
#if !defined(MBEDTLS_NIST_KW_ALT)
|
||||
|
||||
|
|
|
@ -27,16 +27,12 @@
|
|||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include "legacy_or_psa.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#define mbedtls_snprintf snprintf
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro to automatically add the size of #define'd OIDs
|
||||
|
|
|
@ -33,24 +33,20 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
|
||||
#include "legacy_or_psa.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
|
||||
#if defined(MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
|
||||
#if defined(MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \
|
||||
defined(MBEDTLS_CIPHER_MODE_CBC) && \
|
||||
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
|
||||
#define PEM_RFC1421
|
||||
#endif /* MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA && MBEDTLS_CIPHER_MODE_CBC &&
|
||||
#endif /* MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA &&
|
||||
MBEDTLS_CIPHER_MODE_CBC &&
|
||||
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
|
|
46
library/pk.c
46
library/pk.c
|
@ -46,19 +46,11 @@
|
|||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Parameter validation macros based on platform_util.h */
|
||||
#define PK_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
|
||||
#define PK_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/*
|
||||
* Initialise a mbedtls_pk_context
|
||||
*/
|
||||
void mbedtls_pk_init( mbedtls_pk_context *ctx )
|
||||
{
|
||||
PK_VALIDATE( ctx != NULL );
|
||||
|
||||
ctx->pk_info = NULL;
|
||||
ctx->pk_ctx = NULL;
|
||||
}
|
||||
|
@ -83,7 +75,6 @@ void mbedtls_pk_free( mbedtls_pk_context *ctx )
|
|||
*/
|
||||
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
|
||||
{
|
||||
PK_VALIDATE( ctx != NULL );
|
||||
ctx->pk_info = NULL;
|
||||
ctx->rs_ctx = NULL;
|
||||
}
|
||||
|
@ -137,7 +128,6 @@ const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
|
|||
*/
|
||||
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
|
||||
{
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
if( info == NULL || ctx->pk_info != NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -200,7 +190,6 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
|
|||
mbedtls_rsa_alt_context *rsa_alt;
|
||||
const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
|
||||
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
if( ctx->pk_info != NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -404,10 +393,8 @@ int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
|
|||
const unsigned char *sig, size_t sig_len,
|
||||
mbedtls_pk_restart_ctx *rs_ctx )
|
||||
{
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
|
||||
hash != NULL );
|
||||
PK_VALIDATE_RET( sig != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hash_len != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
||||
if( ctx->pk_info == NULL ||
|
||||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
|
||||
|
@ -462,10 +449,8 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
|
|||
const unsigned char *hash, size_t hash_len,
|
||||
const unsigned char *sig, size_t sig_len )
|
||||
{
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
|
||||
hash != NULL );
|
||||
PK_VALIDATE_RET( sig != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hash_len != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
||||
if( ctx->pk_info == NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
@ -588,13 +573,10 @@ int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
|
|||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
mbedtls_pk_restart_ctx *rs_ctx )
|
||||
{
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
|
||||
hash != NULL );
|
||||
PK_VALIDATE_RET( sig != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hash_len != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
||||
if( ctx->pk_info == NULL ||
|
||||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
|
||||
if( ctx->pk_info == NULL || pk_hashlen_helper( md_alg, &hash_len ) != 0 )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
|
@ -707,11 +689,6 @@ int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
|
|||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( input != NULL || ilen == 0 );
|
||||
PK_VALIDATE_RET( output != NULL || osize == 0 );
|
||||
PK_VALIDATE_RET( olen != NULL );
|
||||
|
||||
if( ctx->pk_info == NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -730,11 +707,6 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
|
|||
unsigned char *output, size_t *olen, size_t osize,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( input != NULL || ilen == 0 );
|
||||
PK_VALIDATE_RET( output != NULL || osize == 0 );
|
||||
PK_VALIDATE_RET( olen != NULL );
|
||||
|
||||
if( ctx->pk_info == NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -753,9 +725,6 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
|
|||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
PK_VALIDATE_RET( pub != NULL );
|
||||
PK_VALIDATE_RET( prv != NULL );
|
||||
|
||||
if( pub->pk_info == NULL ||
|
||||
prv->pk_info == NULL )
|
||||
{
|
||||
|
@ -800,7 +769,6 @@ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
|
|||
*/
|
||||
int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
|
||||
{
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
if( ctx->pk_info == NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
|
|
|
@ -55,13 +55,7 @@
|
|||
#include "hash_info.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
|
150
library/pkcs12.c
150
library/pkcs12.c
|
@ -39,6 +39,9 @@
|
|||
#include "mbedtls/des.h"
|
||||
#endif
|
||||
|
||||
#include "hash_info.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
|
||||
static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
|
||||
|
@ -209,6 +212,108 @@ static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int calculate_hashes( mbedtls_md_type_t md_type, int iterations,
|
||||
unsigned char *diversifier, unsigned char *salt_block,
|
||||
unsigned char *pwd_block, unsigned char *hash_output, int use_salt,
|
||||
int use_password, size_t hlen, size_t v )
|
||||
{
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
int ret = -1;
|
||||
size_t i;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_context_t md_ctx;
|
||||
md_info = mbedtls_md_info_from_type( md_type );
|
||||
if( md_info == NULL )
|
||||
return ( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
|
||||
|
||||
mbedtls_md_init( &md_ctx );
|
||||
|
||||
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
|
||||
return ( ret );
|
||||
// Calculate hash( diversifier || salt_block || pwd_block )
|
||||
if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
if( use_salt != 0 )
|
||||
{
|
||||
if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( use_password != 0 )
|
||||
{
|
||||
if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
// Perform remaining ( iterations - 1 ) recursive hash calculations
|
||||
for( i = 1; i < (size_t) iterations; i++ )
|
||||
{
|
||||
if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) )
|
||||
!= 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_md_free( &md_ctx );
|
||||
return ret;
|
||||
#else
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_algorithm_t alg = mbedtls_psa_translate_md( md_type );
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status_abort = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t i, out_len, out_size = PSA_HASH_LENGTH( alg );
|
||||
|
||||
if( alg == PSA_ALG_NONE )
|
||||
return ( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
|
||||
|
||||
if( ( status = psa_hash_setup( &op, alg ) ) != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
// Calculate hash( diversifier || salt_block || pwd_block )
|
||||
if( ( status = psa_hash_update( &op, diversifier, v ) ) != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
if( use_salt != 0 )
|
||||
{
|
||||
if( ( status = psa_hash_update( &op, salt_block, v ) ) != PSA_SUCCESS )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( use_password != 0 )
|
||||
{
|
||||
if( ( status = psa_hash_update( &op, pwd_block, v ) ) != PSA_SUCCESS )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( ( status = psa_hash_finish( &op, hash_output, out_size, &out_len ) )
|
||||
!= PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
// Perform remaining ( iterations - 1 ) recursive hash calculations
|
||||
for( i = 1; i < (size_t) iterations; i++ )
|
||||
{
|
||||
if( ( status = psa_hash_compute( alg, hash_output, hlen, hash_output,
|
||||
out_size, &out_len ) ) != PSA_SUCCESS )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
status_abort = psa_hash_abort( &op );
|
||||
if( status == PSA_SUCCESS )
|
||||
status = status_abort;
|
||||
return ( mbedtls_md_error_from_psa( status ) );
|
||||
#endif /* !MBEDTLS_MD_C */
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *salt, size_t saltlen,
|
||||
|
@ -219,7 +324,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
|
|||
|
||||
unsigned char diversifier[128];
|
||||
unsigned char salt_block[128], pwd_block[128], hash_block[128] = {0};
|
||||
unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
|
||||
unsigned char hash_output[MBEDTLS_HASH_MAX_SIZE];
|
||||
unsigned char *p;
|
||||
unsigned char c;
|
||||
int use_password = 0;
|
||||
|
@ -227,9 +332,6 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
|
|||
|
||||
size_t hlen, use_len, v, i;
|
||||
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_context_t md_ctx;
|
||||
|
||||
// This version only allows max of 64 bytes of password or salt
|
||||
if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
|
||||
return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
|
||||
|
@ -243,15 +345,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
|
|||
use_password = ( pwd && pwdlen != 0 );
|
||||
use_salt = ( salt && saltlen != 0 );
|
||||
|
||||
md_info = mbedtls_md_info_from_type( md_type );
|
||||
if( md_info == NULL )
|
||||
return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
|
||||
|
||||
mbedtls_md_init( &md_ctx );
|
||||
|
||||
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
|
||||
return( ret );
|
||||
hlen = mbedtls_md_get_size( md_info );
|
||||
hlen = mbedtls_hash_info_get_size( md_type );
|
||||
|
||||
if( hlen <= 32 )
|
||||
v = 64;
|
||||
|
@ -273,33 +367,11 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
|
|||
p = data;
|
||||
while( datalen > 0 )
|
||||
{
|
||||
// Calculate hash( diversifier || salt_block || pwd_block )
|
||||
if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
if( use_salt != 0 )
|
||||
if( calculate_hashes( md_type, iterations, diversifier, salt_block,
|
||||
pwd_block, hash_output, use_salt, use_password, hlen,
|
||||
v ) != 0 )
|
||||
{
|
||||
if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v )) != 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( use_password != 0)
|
||||
{
|
||||
if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v )) != 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
// Perform remaining ( iterations - 1 ) recursive hash calculations
|
||||
for( i = 1; i < (size_t) iterations; i++ )
|
||||
{
|
||||
if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
use_len = ( datalen > hlen ) ? hlen : datalen;
|
||||
|
@ -351,8 +423,6 @@ exit:
|
|||
mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) );
|
||||
mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) );
|
||||
|
||||
mbedtls_md_free( &md_ctx );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
|
200
library/pkcs5.c
200
library/pkcs5.c
|
@ -42,12 +42,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif
|
||||
|
||||
#include "hash_info.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
|
||||
|
@ -118,9 +116,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
|
|||
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
|
||||
unsigned char key[32], iv[32];
|
||||
size_t olen = 0;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
const mbedtls_cipher_info_t *cipher_info;
|
||||
mbedtls_md_context_t md_ctx;
|
||||
mbedtls_cipher_type_t cipher_alg;
|
||||
mbedtls_cipher_context_t cipher_ctx;
|
||||
|
||||
|
@ -153,10 +149,6 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
|
|||
return( ret );
|
||||
}
|
||||
|
||||
md_info = mbedtls_md_info_from_type( md_type );
|
||||
if( md_info == NULL )
|
||||
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
|
||||
&enc_scheme_params ) ) != 0 )
|
||||
{
|
||||
|
@ -182,16 +174,13 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
|
|||
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT );
|
||||
}
|
||||
|
||||
mbedtls_md_init( &md_ctx );
|
||||
mbedtls_cipher_init( &cipher_ctx );
|
||||
|
||||
memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
|
||||
|
||||
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
|
||||
iterations, keylen, key ) ) != 0 )
|
||||
if( ( ret = mbedtls_pkcs5_pbkdf2_hmac_ext( md_type, pwd, pwdlen, salt.p,
|
||||
salt.len, iterations, keylen,
|
||||
key ) ) != 0 )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
@ -208,18 +197,18 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
|
|||
ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
|
||||
|
||||
exit:
|
||||
mbedtls_md_free( &md_ctx );
|
||||
mbedtls_cipher_free( &cipher_ctx );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
|
||||
int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx,
|
||||
const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output )
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
static int pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx,
|
||||
const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int j;
|
||||
|
@ -297,9 +286,149 @@ cleanup:
|
|||
return( ret );
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx,
|
||||
const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output )
|
||||
{
|
||||
return( pkcs5_pbkdf2_hmac( ctx, password, plen, salt, slen, iteration_count,
|
||||
key_length, output ) );
|
||||
}
|
||||
#endif
|
||||
#endif /* MBEDTLS_MD_C */
|
||||
|
||||
int mbedtls_pkcs5_pbkdf2_hmac_ext( mbedtls_md_type_t md_alg,
|
||||
const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output )
|
||||
{
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
mbedtls_md_context_t md_ctx;
|
||||
const mbedtls_md_info_t *md_info = NULL;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
md_info = mbedtls_md_info_from_type( md_alg );
|
||||
if( md_info == NULL )
|
||||
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
|
||||
|
||||
mbedtls_md_init( &md_ctx );
|
||||
|
||||
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
|
||||
goto exit;
|
||||
ret = pkcs5_pbkdf2_hmac( &md_ctx, password, plen, salt, slen,
|
||||
iteration_count, key_length, output );
|
||||
exit:
|
||||
mbedtls_md_free( &md_ctx );
|
||||
return( ret );
|
||||
#else
|
||||
int j;
|
||||
unsigned int i;
|
||||
unsigned char md1[PSA_HASH_MAX_SIZE];
|
||||
unsigned char work[PSA_HASH_MAX_SIZE];
|
||||
const unsigned char md_size = mbedtls_hash_info_get_size( md_alg );
|
||||
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status_destruction = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t use_len, out_len;
|
||||
unsigned char *out_p = output;
|
||||
unsigned char counter[4];
|
||||
mbedtls_svc_key_id_t psa_hmac_key = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
const psa_algorithm_t alg = PSA_ALG_HMAC( mbedtls_hash_info_psa_from_md( md_alg ) );
|
||||
const size_t out_size = PSA_MAC_LENGTH( PSA_KEY_TYPE_HMAC, 0, alg );
|
||||
|
||||
memset( counter, 0, sizeof( counter ) );
|
||||
counter[3] = 1;
|
||||
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
|
||||
|
||||
if( key_length == 0 )
|
||||
return 0;
|
||||
if( ( status = psa_import_key( &attributes,
|
||||
password, plen,
|
||||
&psa_hmac_key ) ) != PSA_SUCCESS )
|
||||
{
|
||||
return MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
#if UINT_MAX > 0xFFFFFFFF
|
||||
if( iteration_count > 0xFFFFFFFF )
|
||||
return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
|
||||
#endif
|
||||
|
||||
while( key_length )
|
||||
{
|
||||
status = psa_mac_sign_setup( &operation, psa_hmac_key,
|
||||
PSA_ALG_HMAC( alg ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
// U1 ends up in work
|
||||
if( ( status = psa_mac_update( &operation, salt, slen ) ) != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
|
||||
if( ( status = psa_mac_update( &operation, counter, sizeof( counter ) ) ) != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
|
||||
if( ( status = psa_mac_sign_finish( &operation, work, out_size, &out_len ) )
|
||||
!= PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
|
||||
memcpy( md1, work, out_len );
|
||||
|
||||
for( i = 1; i < iteration_count; i++ )
|
||||
{
|
||||
// U2 ends up in md1
|
||||
//
|
||||
status = psa_mac_sign_setup( &operation, psa_hmac_key,
|
||||
PSA_ALG_HMAC( alg ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
if( ( status = psa_mac_update( &operation, md1, md_size ) ) != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
if( ( status = psa_mac_sign_finish( &operation, md1, out_size, &out_len ) ) != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
|
||||
// U1 xor U2
|
||||
//
|
||||
for( j = 0; j < md_size; j++ )
|
||||
work[j] ^= md1[j];
|
||||
}
|
||||
|
||||
use_len = ( key_length < md_size ) ? key_length : md_size;
|
||||
memcpy( out_p, work, use_len );
|
||||
|
||||
key_length -= (uint32_t) use_len;
|
||||
out_p += use_len;
|
||||
|
||||
for( i = 4; i > 0; i-- )
|
||||
if( ++counter[i - 1] != 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* Zeroise buffers to clear sensitive data from memory. */
|
||||
mbedtls_platform_zeroize( work, PSA_HASH_MAX_SIZE );
|
||||
mbedtls_platform_zeroize( md1, PSA_HASH_MAX_SIZE );
|
||||
status_destruction = psa_destroy_key( psa_hmac_key );
|
||||
if( status == PSA_SUCCESS && status_destruction != PSA_SUCCESS )
|
||||
status = status_destruction;
|
||||
status_destruction = psa_mac_abort( &operation );
|
||||
if( status == PSA_SUCCESS && status_destruction != PSA_SUCCESS )
|
||||
status = status_destruction;
|
||||
|
||||
return( mbedtls_md_error_from_psa( status ) );
|
||||
#endif /* !MBEDTLS_MD_C */
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
#if !defined(MBEDTLS_SHA1_C)
|
||||
#if !defined(MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA)
|
||||
int mbedtls_pkcs5_self_test( int verbose )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
|
@ -362,32 +491,15 @@ static const unsigned char result_key_test_data[MAX_TESTS][32] =
|
|||
|
||||
int mbedtls_pkcs5_self_test( int verbose )
|
||||
{
|
||||
mbedtls_md_context_t sha1_ctx;
|
||||
const mbedtls_md_info_t *info_sha1;
|
||||
int ret, i;
|
||||
unsigned char key[64];
|
||||
|
||||
mbedtls_md_init( &sha1_ctx );
|
||||
|
||||
info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
|
||||
if( info_sha1 == NULL )
|
||||
{
|
||||
ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 )
|
||||
{
|
||||
ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for( i = 0; i < MAX_TESTS; i++ )
|
||||
{
|
||||
if( verbose != 0 )
|
||||
mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i );
|
||||
|
||||
ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password_test_data[i],
|
||||
ret = mbedtls_pkcs5_pbkdf2_hmac_ext( MBEDTLS_MD_SHA1, password_test_data[i],
|
||||
plen_test_data[i], salt_test_data[i],
|
||||
slen_test_data[i], it_cnt_test_data[i],
|
||||
key_len_test_data[i], key );
|
||||
|
@ -409,11 +521,9 @@ int mbedtls_pkcs5_self_test( int verbose )
|
|||
mbedtls_printf( "\n" );
|
||||
|
||||
exit:
|
||||
mbedtls_md_free( &sha1_ctx );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_SHA1_C */
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA */
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
|
|
|
@ -48,19 +48,7 @@
|
|||
#include "mbedtls/pkcs12.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
/* Parameter validation macros based on platform_util.h */
|
||||
#define PK_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
|
||||
#define PK_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/*
|
||||
|
@ -75,10 +63,6 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
|
|||
FILE *f;
|
||||
long size;
|
||||
|
||||
PK_VALIDATE_RET( path != NULL );
|
||||
PK_VALIDATE_RET( buf != NULL );
|
||||
PK_VALIDATE_RET( n != NULL );
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
|
||||
|
||||
|
@ -133,9 +117,6 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
|
|||
size_t n;
|
||||
unsigned char *buf;
|
||||
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( path != NULL );
|
||||
|
||||
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
|
@ -160,9 +141,6 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
|
|||
size_t n;
|
||||
unsigned char *buf;
|
||||
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
PK_VALIDATE_RET( path != NULL );
|
||||
|
||||
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
|
@ -620,11 +598,6 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
|
|||
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
|
||||
PK_VALIDATE_RET( p != NULL );
|
||||
PK_VALIDATE_RET( *p != NULL );
|
||||
PK_VALIDATE_RET( end != NULL );
|
||||
PK_VALIDATE_RET( pk != NULL );
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
|
@ -1217,10 +1190,8 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
|||
mbedtls_pem_context pem;
|
||||
#endif
|
||||
|
||||
PK_VALIDATE_RET( pk != NULL );
|
||||
if( keylen == 0 )
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
|
||||
PK_VALIDATE_RET( key != NULL );
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pem_init( &pem );
|
||||
|
@ -1436,10 +1407,8 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
|
|||
mbedtls_pem_context pem;
|
||||
#endif
|
||||
|
||||
PK_VALIDATE_RET( ctx != NULL );
|
||||
if( keylen == 0 )
|
||||
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
|
||||
PK_VALIDATE_RET( key != NULL || keylen == 0 );
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
mbedtls_pem_init( &pem );
|
||||
|
|
|
@ -51,19 +51,7 @@
|
|||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
/* Parameter validation macros based on platform_util.h */
|
||||
#define PK_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
|
||||
#define PK_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
/*
|
||||
|
@ -182,11 +170,6 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
PK_VALIDATE_RET( p != NULL );
|
||||
PK_VALIDATE_RET( *p != NULL );
|
||||
PK_VALIDATE_RET( start != NULL );
|
||||
PK_VALIDATE_RET( key != NULL );
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
|
||||
MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
|
||||
|
@ -233,10 +216,8 @@ int mbedtls_pk_write_pubkey_der( const mbedtls_pk_context *key, unsigned char *b
|
|||
mbedtls_pk_type_t pk_type;
|
||||
const char *oid;
|
||||
|
||||
PK_VALIDATE_RET( key != NULL );
|
||||
if( size == 0 )
|
||||
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||
PK_VALIDATE_RET( buf != NULL );
|
||||
|
||||
c = buf + size;
|
||||
|
||||
|
@ -333,10 +314,8 @@ int mbedtls_pk_write_key_der( const mbedtls_pk_context *key, unsigned char *buf,
|
|||
unsigned char *c;
|
||||
size_t len = 0;
|
||||
|
||||
PK_VALIDATE_RET( key != NULL );
|
||||
if( size == 0 )
|
||||
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
|
||||
PK_VALIDATE_RET( buf != NULL );
|
||||
|
||||
c = buf + size;
|
||||
|
||||
|
@ -500,9 +479,6 @@ int mbedtls_pk_write_pubkey_pem( const mbedtls_pk_context *key, unsigned char *b
|
|||
unsigned char output_buf[PUB_DER_MAX_BYTES];
|
||||
size_t olen = 0;
|
||||
|
||||
PK_VALIDATE_RET( key != NULL );
|
||||
PK_VALIDATE_RET( buf != NULL || size == 0 );
|
||||
|
||||
if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
|
||||
sizeof(output_buf) ) ) < 0 )
|
||||
{
|
||||
|
@ -526,9 +502,6 @@ int mbedtls_pk_write_key_pem( const mbedtls_pk_context *key, unsigned char *buf,
|
|||
const char *begin, *end;
|
||||
size_t olen = 0;
|
||||
|
||||
PK_VALIDATE_RET( key != NULL );
|
||||
PK_VALIDATE_RET( buf != NULL || size == 0 );
|
||||
|
||||
if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
|
||||
return( ret );
|
||||
|
||||
|
|
|
@ -28,14 +28,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_POLY1305_ALT)
|
||||
|
||||
|
@ -44,12 +37,6 @@
|
|||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Parameter validation macros */
|
||||
#define POLY1305_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
|
||||
#define POLY1305_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
|
||||
|
||||
/*
|
||||
|
@ -258,8 +245,6 @@ static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
|
|||
|
||||
void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
|
||||
{
|
||||
POLY1305_VALIDATE( ctx != NULL );
|
||||
|
||||
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
|
||||
}
|
||||
|
||||
|
@ -274,9 +259,6 @@ void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
|
|||
int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
|
||||
const unsigned char key[32] )
|
||||
{
|
||||
POLY1305_VALIDATE_RET( ctx != NULL );
|
||||
POLY1305_VALIDATE_RET( key != NULL );
|
||||
|
||||
/* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
|
||||
ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 ) & 0x0FFFFFFFU;
|
||||
ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 ) & 0x0FFFFFFCU;
|
||||
|
@ -310,8 +292,6 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
|
|||
size_t remaining = ilen;
|
||||
size_t queue_free_len;
|
||||
size_t nblocks;
|
||||
POLY1305_VALIDATE_RET( ctx != NULL );
|
||||
POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
|
||||
{
|
||||
|
@ -369,9 +349,6 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
|
|||
int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
|
||||
unsigned char mac[16] )
|
||||
{
|
||||
POLY1305_VALIDATE_RET( ctx != NULL );
|
||||
POLY1305_VALIDATE_RET( mac != NULL );
|
||||
|
||||
/* Process any leftover data */
|
||||
if( ctx->queue_len > 0U )
|
||||
{
|
||||
|
@ -400,9 +377,6 @@ int mbedtls_poly1305_mac( const unsigned char key[32],
|
|||
{
|
||||
mbedtls_poly1305_context ctx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
POLY1305_VALIDATE_RET( key != NULL );
|
||||
POLY1305_VALIDATE_RET( mac != NULL );
|
||||
POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
mbedtls_poly1305_init( &ctx );
|
||||
|
||||
|
|
|
@ -52,10 +52,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
|
@ -445,6 +441,8 @@ psa_status_t psa_validate_unstructured_key_bit_size( psa_key_type_t type,
|
|||
case PSA_KEY_TYPE_RAW_DATA:
|
||||
case PSA_KEY_TYPE_HMAC:
|
||||
case PSA_KEY_TYPE_DERIVE:
|
||||
case PSA_KEY_TYPE_PASSWORD:
|
||||
case PSA_KEY_TYPE_PASSWORD_HASH:
|
||||
break;
|
||||
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||
case PSA_KEY_TYPE_AES:
|
||||
|
@ -3590,6 +3588,7 @@ static psa_status_t psa_aead_check_nonce_length( psa_algorithm_t alg,
|
|||
break;
|
||||
#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
|
||||
default:
|
||||
(void) nonce_length;
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
|
@ -3706,39 +3705,34 @@ exit:
|
|||
return( status );
|
||||
}
|
||||
|
||||
static psa_status_t psa_validate_tag_length( psa_aead_operation_t *operation,
|
||||
psa_algorithm_t alg ) {
|
||||
uint8_t tag_len = 0;
|
||||
if( psa_driver_get_tag_len( operation, &tag_len ) != PSA_SUCCESS )
|
||||
{
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
static psa_status_t psa_validate_tag_length( psa_algorithm_t alg ) {
|
||||
const uint8_t tag_len = PSA_ALG_AEAD_GET_TAG_LENGTH( alg );
|
||||
|
||||
switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) )
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
#if defined(PSA_WANT_ALG_CCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
|
||||
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.*/
|
||||
if( tag_len < 4 || tag_len > 16 || tag_len % 2 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#endif /* PSA_WANT_ALG_CCM */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
|
||||
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. */
|
||||
if( tag_len != 4 && tag_len != 8 && ( tag_len < 12 || tag_len > 16 ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
|
||||
/* We only support the default tag length. */
|
||||
if( tag_len != 16 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
|
||||
|
||||
default:
|
||||
(void) tag_len;
|
||||
|
@ -3789,6 +3783,9 @@ static psa_status_t psa_aead_setup( psa_aead_operation_t *operation,
|
|||
.core = slot->attr
|
||||
};
|
||||
|
||||
if( ( status = psa_validate_tag_length( alg ) ) != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
if( is_encrypt )
|
||||
status = psa_driver_wrapper_aead_encrypt_setup( operation,
|
||||
&attributes,
|
||||
|
@ -3804,9 +3801,6 @@ static psa_status_t psa_aead_setup( psa_aead_operation_t *operation,
|
|||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
if( ( status = psa_validate_tag_length( operation, alg ) ) != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
operation->key_type = psa_get_key_type( &attributes );
|
||||
|
||||
exit:
|
||||
|
@ -4243,7 +4237,8 @@ psa_status_t psa_aead_abort( psa_aead_operation_t *operation )
|
|||
|
||||
#if defined(BUILTIN_ALG_ANY_HKDF) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
#define AT_LEAST_ONE_BUILTIN_KDF
|
||||
#endif /* At least one builtin KDF */
|
||||
|
||||
|
@ -4350,6 +4345,14 @@ psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation
|
|||
else
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
if( kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS )
|
||||
{
|
||||
mbedtls_platform_zeroize( operation->ctx.tls12_ecjpake_to_pms.data,
|
||||
sizeof( operation->ctx.tls12_ecjpake_to_pms.data ) );
|
||||
}
|
||||
else
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) */
|
||||
{
|
||||
status = PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
@ -4631,6 +4634,31 @@ static psa_status_t psa_key_derivation_tls12_prf_read(
|
|||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
|
||||
* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
static psa_status_t psa_key_derivation_tls12_ecjpake_to_pms_read(
|
||||
psa_tls12_ecjpake_to_pms_t *ecjpake,
|
||||
uint8_t *output,
|
||||
size_t output_length )
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_size = 0;
|
||||
|
||||
if( output_length != 32 )
|
||||
return ( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
status = psa_hash_compute( PSA_ALG_SHA_256, ecjpake->data,
|
||||
PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE, output, output_length,
|
||||
&output_size );
|
||||
if( status != PSA_SUCCESS )
|
||||
return ( status );
|
||||
|
||||
if( output_size != output_length )
|
||||
return ( PSA_ERROR_GENERIC_ERROR );
|
||||
|
||||
return ( PSA_SUCCESS );
|
||||
}
|
||||
#endif
|
||||
|
||||
psa_status_t psa_key_derivation_output_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
uint8_t *output,
|
||||
|
@ -4685,6 +4713,15 @@ psa_status_t psa_key_derivation_output_bytes(
|
|||
else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
|
||||
* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
if( kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS )
|
||||
{
|
||||
status = psa_key_derivation_tls12_ecjpake_to_pms_read(
|
||||
&operation->ctx.tls12_ecjpake_to_pms, output, output_length );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
|
||||
|
||||
{
|
||||
(void) kdf_alg;
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
@ -5076,6 +5113,10 @@ static int is_kdf_alg_supported( psa_algorithm_t kdf_alg )
|
|||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
|
||||
if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
|
||||
return( 1 );
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
if( kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS )
|
||||
return( 1 );
|
||||
#endif
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -5100,19 +5141,26 @@ static psa_status_t psa_key_derivation_setup_kdf(
|
|||
if( ! is_kdf_alg_supported( kdf_alg ) )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
/* All currently supported key derivation algorithms are based on a
|
||||
* hash algorithm. */
|
||||
/* All currently supported key derivation algorithms (apart from
|
||||
* ecjpake to pms) are based on a hash algorithm. */
|
||||
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
|
||||
size_t hash_size = PSA_HASH_LENGTH( hash_alg );
|
||||
if( hash_size == 0 )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
if( kdf_alg != PSA_ALG_TLS12_ECJPAKE_TO_PMS )
|
||||
{
|
||||
if( hash_size == 0 )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
/* Make sure that hash_alg is a supported hash algorithm. Otherwise
|
||||
* we might fail later, which is somewhat unfriendly and potentially
|
||||
* risk-prone. */
|
||||
psa_status_t status = psa_hash_try_support( hash_alg );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
/* Make sure that hash_alg is a supported hash algorithm. Otherwise
|
||||
* we might fail later, which is somewhat unfriendly and potentially
|
||||
* risk-prone. */
|
||||
psa_status_t status = psa_hash_try_support( hash_alg );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_size = PSA_HASH_LENGTH( PSA_ALG_SHA_256 );
|
||||
}
|
||||
|
||||
if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
|
||||
PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
|
||||
|
@ -5120,11 +5168,14 @@ static psa_status_t psa_key_derivation_setup_kdf(
|
|||
{
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT)
|
||||
if( PSA_ALG_IS_HKDF_EXTRACT( kdf_alg ) )
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
if( PSA_ALG_IS_HKDF_EXTRACT( kdf_alg ) ||
|
||||
( kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS ) )
|
||||
operation->capacity = hash_size;
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT ||
|
||||
MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
|
||||
operation->capacity = 255 * hash_size;
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
@ -5513,6 +5564,29 @@ static psa_status_t psa_tls12_prf_psk_to_ms_input(
|
|||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
static psa_status_t psa_tls12_ecjpake_to_pms_input(
|
||||
psa_tls12_ecjpake_to_pms_t *ecjpake,
|
||||
psa_key_derivation_step_t step,
|
||||
const uint8_t *data,
|
||||
size_t data_length )
|
||||
{
|
||||
if( data_length != PSA_TLS12_ECJPAKE_TO_PMS_INPUT_SIZE ||
|
||||
step != PSA_KEY_DERIVATION_INPUT_SECRET )
|
||||
{
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
|
||||
/* Check if the passed point is in an uncompressed form */
|
||||
if( data[0] != 0x04 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
/* Only K.X has to be extracted - bytes 1 to 32 inclusive. */
|
||||
memcpy( ecjpake->data, data + 1, PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE );
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
|
||||
/** Check whether the given key type is acceptable for the given
|
||||
* input step of a key derivation.
|
||||
*
|
||||
|
@ -5591,6 +5665,14 @@ static psa_status_t psa_key_derivation_input_internal(
|
|||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
if( kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS )
|
||||
{
|
||||
status = psa_tls12_ecjpake_to_pms_input(
|
||||
&operation->ctx.tls12_ecjpake_to_pms, step, data, data_length );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
|
||||
{
|
||||
/* This can't happen unless the operation object was not initialized */
|
||||
(void) data;
|
||||
|
|
|
@ -24,13 +24,10 @@
|
|||
|
||||
#include "psa_crypto_aead.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "mbedtls/ccm.h"
|
||||
#include "mbedtls/chachapoly.h"
|
||||
|
@ -49,7 +46,6 @@ static psa_status_t psa_aead_setup(
|
|||
size_t key_bits;
|
||||
const mbedtls_cipher_info_t *cipher_info;
|
||||
mbedtls_cipher_id_t cipher_id;
|
||||
size_t full_tag_length = 0;
|
||||
|
||||
( void ) key_buffer_size;
|
||||
|
||||
|
@ -66,7 +62,6 @@ static psa_status_t psa_aead_setup(
|
|||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
|
||||
operation->alg = PSA_ALG_CCM;
|
||||
full_tag_length = 16;
|
||||
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
|
||||
* The call to mbedtls_ccm_encrypt_and_tag or
|
||||
* mbedtls_ccm_auth_decrypt will validate the tag length. */
|
||||
|
@ -85,7 +80,6 @@ static psa_status_t psa_aead_setup(
|
|||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
|
||||
operation->alg = PSA_ALG_GCM;
|
||||
full_tag_length = 16;
|
||||
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
|
||||
* The call to mbedtls_gcm_crypt_and_tag or
|
||||
* mbedtls_gcm_auth_decrypt will validate the tag length. */
|
||||
|
@ -104,7 +98,6 @@ static psa_status_t psa_aead_setup(
|
|||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
|
||||
operation->alg = PSA_ALG_CHACHA20_POLY1305;
|
||||
full_tag_length = 16;
|
||||
/* We only support the default tag length. */
|
||||
if( alg != PSA_ALG_CHACHA20_POLY1305 )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
@ -124,16 +117,9 @@ static psa_status_t psa_aead_setup(
|
|||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
if( PSA_AEAD_TAG_LENGTH( attributes->core.type,
|
||||
key_bits, alg )
|
||||
> full_tag_length )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
operation->key_type = psa_get_key_type( attributes );
|
||||
|
||||
operation->tag_length = PSA_AEAD_TAG_LENGTH( operation->key_type,
|
||||
key_bits,
|
||||
alg );
|
||||
operation->tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH( alg );
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PSA cipher driver entry points
|
||||
* PSA cipher driver entry points and associated auxiliary functions
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
void psa_reset_key_attributes( psa_key_attributes_t *attributes )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -226,10 +226,6 @@ psa_status_t psa_driver_wrapper_aead_decrypt(
|
|||
const uint8_t *ciphertext, size_t ciphertext_length,
|
||||
uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length );
|
||||
|
||||
psa_status_t psa_driver_get_tag_len(
|
||||
psa_aead_operation_t *operation,
|
||||
uint8_t *tag_len );
|
||||
|
||||
psa_status_t psa_driver_wrapper_aead_encrypt_setup(
|
||||
psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
|
|
|
@ -31,10 +31,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include <mbedtls/ecdsa.h>
|
||||
#include <mbedtls/ecp.h>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
861
library/psa_crypto_pake.c
Normal file
861
library/psa_crypto_pake.c
Normal file
|
@ -0,0 +1,861 @@
|
|||
/*
|
||||
* PSA PAKE layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
|
||||
#include <mbedtls/ecjpake.h>
|
||||
#include <mbedtls/psa_util.h>
|
||||
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* State sequence:
|
||||
*
|
||||
* psa_pake_setup()
|
||||
* |
|
||||
* |-- In any order:
|
||||
* | | psa_pake_set_password_key()
|
||||
* | | psa_pake_set_user()
|
||||
* | | psa_pake_set_peer()
|
||||
* | | psa_pake_set_role()
|
||||
* |
|
||||
* |--- In any order: (First round input before or after first round output)
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* |
|
||||
* |--- In any order: (Second round input before or after second round output)
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* |
|
||||
* psa_pake_get_implicit_key()
|
||||
* psa_pake_abort()
|
||||
*/
|
||||
|
||||
enum psa_pake_step
|
||||
{
|
||||
PSA_PAKE_STEP_INVALID = 0,
|
||||
PSA_PAKE_STEP_X1_X2 = 1,
|
||||
PSA_PAKE_STEP_X2S = 2,
|
||||
PSA_PAKE_STEP_DERIVE = 3,
|
||||
};
|
||||
|
||||
enum psa_pake_state
|
||||
{
|
||||
PSA_PAKE_STATE_INVALID = 0,
|
||||
PSA_PAKE_STATE_SETUP = 1,
|
||||
PSA_PAKE_STATE_READY = 2,
|
||||
PSA_PAKE_OUTPUT_X1_X2 = 3,
|
||||
PSA_PAKE_OUTPUT_X2S = 4,
|
||||
PSA_PAKE_INPUT_X1_X2 = 5,
|
||||
PSA_PAKE_INPUT_X4S = 6,
|
||||
};
|
||||
|
||||
/*
|
||||
* The first PAKE step shares the same sequences of the second PAKE step
|
||||
* but with a second set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs.
|
||||
* It's simpler to share the same sequences numbers of the first
|
||||
* set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs in both PAKE steps.
|
||||
*
|
||||
* State sequence with step, state & sequence enums:
|
||||
* => Input & Output Step = PSA_PAKE_STEP_INVALID
|
||||
* => state = PSA_PAKE_STATE_INVALID
|
||||
* psa_pake_setup()
|
||||
* => Input & Output Step = PSA_PAKE_STEP_X1_X2
|
||||
* => state = PSA_PAKE_STATE_SETUP
|
||||
* => sequence = PSA_PAKE_SEQ_INVALID
|
||||
* |
|
||||
* |--- In any order: (First round input before or after first round output)
|
||||
* | | First call of psa_pake_output() or psa_pake_input() sets
|
||||
* | | state = PSA_PAKE_STATE_READY
|
||||
* | |
|
||||
* | |------ In Order: => state = PSA_PAKE_OUTPUT_X1_X2
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF
|
||||
* | | | => state = PSA_PAKE_STATE_READY
|
||||
* | | | => sequence = PSA_PAKE_SEQ_INVALID
|
||||
* | | | => Output Step = PSA_PAKE_STEP_X2S
|
||||
* | |
|
||||
* | |------ In Order: => state = PSA_PAKE_INPUT_X1_X2
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF
|
||||
* | | | => state = PSA_PAKE_STATE_READY
|
||||
* | | | => sequence = PSA_PAKE_SEQ_INVALID
|
||||
* | | | => Output Step = PSA_PAKE_INPUT_X4S
|
||||
* |
|
||||
* |--- In any order: (Second round input before or after second round output)
|
||||
* | |
|
||||
* | |------ In Order: => state = PSA_PAKE_OUTPUT_X2S
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
|
||||
* | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
|
||||
* | | | => state = PSA_PAKE_STATE_READY
|
||||
* | | | => sequence = PSA_PAKE_SEQ_INVALID
|
||||
* | | | => Output Step = PSA_PAKE_STEP_DERIVE
|
||||
* | |
|
||||
* | |------ In Order: => state = PSA_PAKE_INPUT_X4S
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
|
||||
* | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
|
||||
* | | | => state = PSA_PAKE_STATE_READY
|
||||
* | | | => sequence = PSA_PAKE_SEQ_INVALID
|
||||
* | | | => Output Step = PSA_PAKE_STEP_DERIVE
|
||||
* |
|
||||
* psa_pake_get_implicit_key()
|
||||
* => Input & Output Step = PSA_PAKE_STEP_INVALID
|
||||
*/
|
||||
enum psa_pake_sequence
|
||||
{
|
||||
PSA_PAKE_SEQ_INVALID = 0,
|
||||
PSA_PAKE_X1_STEP_KEY_SHARE = 1, /* also X2S & X4S KEY_SHARE */
|
||||
PSA_PAKE_X1_STEP_ZK_PUBLIC = 2, /* also X2S & X4S ZK_PUBLIC */
|
||||
PSA_PAKE_X1_STEP_ZK_PROOF = 3, /* also X2S & X4S ZK_PROOF */
|
||||
PSA_PAKE_X2_STEP_KEY_SHARE = 4,
|
||||
PSA_PAKE_X2_STEP_ZK_PUBLIC = 5,
|
||||
PSA_PAKE_X2_STEP_ZK_PROOF = 6,
|
||||
PSA_PAKE_SEQ_END = 7,
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
static psa_status_t mbedtls_ecjpake_to_psa_error( int ret )
|
||||
{
|
||||
switch( ret )
|
||||
{
|
||||
case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_ECP_INVALID_KEY:
|
||||
case MBEDTLS_ERR_ECP_VERIFY_FAILED:
|
||||
return( PSA_ERROR_DATA_INVALID );
|
||||
case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
|
||||
case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
|
||||
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||
case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
|
||||
return( PSA_ERROR_CORRUPTION_DETECTED );
|
||||
default:
|
||||
return( PSA_ERROR_GENERIC_ERROR );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
|
||||
psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
|
||||
const psa_pake_cipher_suite_t *cipher_suite)
|
||||
{
|
||||
/* A context must be freshly initialized before it can be set up. */
|
||||
if( operation->alg != PSA_ALG_NONE )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
if( cipher_suite == NULL ||
|
||||
PSA_ALG_IS_PAKE(cipher_suite->algorithm ) == 0 ||
|
||||
( cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC &&
|
||||
cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_DH ) ||
|
||||
PSA_ALG_IS_HASH( cipher_suite->hash ) == 0 )
|
||||
{
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if( cipher_suite->algorithm == PSA_ALG_JPAKE )
|
||||
{
|
||||
if( cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC ||
|
||||
cipher_suite->family != PSA_ECC_FAMILY_SECP_R1 ||
|
||||
cipher_suite->bits != 256 ||
|
||||
cipher_suite->hash != PSA_ALG_SHA_256 )
|
||||
{
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
operation->alg = cipher_suite->algorithm;
|
||||
|
||||
mbedtls_ecjpake_init( &operation->ctx.ecjpake );
|
||||
|
||||
operation->state = PSA_PAKE_STATE_SETUP;
|
||||
operation->sequence = PSA_PAKE_SEQ_INVALID;
|
||||
operation->input_step = PSA_PAKE_STEP_X1_X2;
|
||||
operation->output_step = PSA_PAKE_STEP_X1_X2;
|
||||
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
|
||||
mbedtls_svc_key_id_t password )
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = psa_key_attributes_init();
|
||||
psa_key_type_t type;
|
||||
psa_key_usage_t usage;
|
||||
|
||||
if( operation->alg == PSA_ALG_NONE ||
|
||||
operation->state != PSA_PAKE_STATE_SETUP )
|
||||
{
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
status = psa_get_key_attributes( password, &attributes );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
type = psa_get_key_type( &attributes );
|
||||
usage = psa_get_key_usage_flags( &attributes );
|
||||
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
if( type != PSA_KEY_TYPE_PASSWORD &&
|
||||
type != PSA_KEY_TYPE_PASSWORD_HASH )
|
||||
{
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
|
||||
if( ( usage & PSA_KEY_USAGE_DERIVE ) == 0 )
|
||||
return( PSA_ERROR_NOT_PERMITTED );
|
||||
|
||||
operation->password = password;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_pake_set_user( psa_pake_operation_t *operation,
|
||||
const uint8_t *user_id,
|
||||
size_t user_id_len )
|
||||
{
|
||||
if( operation->alg == PSA_ALG_NONE ||
|
||||
operation->state != PSA_PAKE_STATE_SETUP )
|
||||
{
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
if( user_id_len == 0 || user_id == NULL )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation,
|
||||
const uint8_t *peer_id,
|
||||
size_t peer_id_len )
|
||||
{
|
||||
if( operation->alg == PSA_ALG_NONE ||
|
||||
operation->state != PSA_PAKE_STATE_SETUP )
|
||||
{
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
if( peer_id_len == 0 || peer_id == NULL )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
psa_status_t psa_pake_set_role( psa_pake_operation_t *operation,
|
||||
psa_pake_role_t role )
|
||||
{
|
||||
if( operation->alg == PSA_ALG_NONE ||
|
||||
operation->state != PSA_PAKE_STATE_SETUP )
|
||||
{
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
if( role != PSA_PAKE_ROLE_NONE &&
|
||||
role != PSA_PAKE_ROLE_FIRST &&
|
||||
role != PSA_PAKE_ROLE_SECOND &&
|
||||
role != PSA_PAKE_ROLE_CLIENT &&
|
||||
role != PSA_PAKE_ROLE_SERVER )
|
||||
{
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if( operation->alg == PSA_ALG_JPAKE )
|
||||
{
|
||||
if( role != PSA_PAKE_ROLE_CLIENT &&
|
||||
role != PSA_PAKE_ROLE_SERVER )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
operation->role = role;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecjpake_role role;
|
||||
psa_key_slot_t *slot = NULL;
|
||||
|
||||
if( operation->role == PSA_PAKE_ROLE_CLIENT )
|
||||
role = MBEDTLS_ECJPAKE_CLIENT;
|
||||
else if( operation->role == PSA_PAKE_ROLE_SERVER )
|
||||
role = MBEDTLS_ECJPAKE_SERVER;
|
||||
else
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
if( psa_is_valid_key_id( operation->password, 1 ) == 0 )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
status = psa_get_and_lock_key_slot( operation->password, &slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
|
||||
ret = mbedtls_ecjpake_setup( &operation->ctx.ecjpake,
|
||||
role,
|
||||
MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_ECP_DP_SECP256R1,
|
||||
slot->key.data, slot->key.bytes );
|
||||
|
||||
psa_unlock_key_slot( slot );
|
||||
slot = NULL;
|
||||
|
||||
if( ret != 0 )
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
|
||||
operation->state = PSA_PAKE_STATE_READY;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
#endif
|
||||
|
||||
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,
|
||||
size_t *output_length )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t length;
|
||||
|
||||
if( operation->alg == PSA_ALG_NONE ||
|
||||
operation->state == PSA_PAKE_STATE_INVALID )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
if( output == NULL || output_size == 0 || output_length == NULL )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
/*
|
||||
* The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different
|
||||
* handling of output sequencing.
|
||||
*
|
||||
* The MbedTLS JPAKE API outputs the whole X1+X2 and X2S steps data
|
||||
* at once, on the other side the PSA CRYPTO PAKE api requires
|
||||
* the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be
|
||||
* retrieved in sequence.
|
||||
*
|
||||
* In order to achieve API compatibility, the whole X1+X2 or X2S steps
|
||||
* data is stored in an intermediate buffer at first step output call,
|
||||
* and data is sliced down by parsing the ECPoint records in order
|
||||
* to return the right parts on each step.
|
||||
*/
|
||||
if( operation->alg == PSA_ALG_JPAKE )
|
||||
{
|
||||
if( step != PSA_PAKE_STEP_KEY_SHARE &&
|
||||
step != PSA_PAKE_STEP_ZK_PUBLIC &&
|
||||
step != PSA_PAKE_STEP_ZK_PROOF )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
if( operation->state == PSA_PAKE_STATE_SETUP ) {
|
||||
status = psa_pake_ecjpake_setup( operation );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
}
|
||||
|
||||
if( operation->state != PSA_PAKE_STATE_READY &&
|
||||
operation->state != PSA_PAKE_OUTPUT_X1_X2 &&
|
||||
operation->state != PSA_PAKE_OUTPUT_X2S )
|
||||
{
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
if( operation->state == PSA_PAKE_STATE_READY )
|
||||
{
|
||||
if( step != PSA_PAKE_STEP_KEY_SHARE )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
switch( operation->output_step )
|
||||
{
|
||||
case PSA_PAKE_STEP_X1_X2:
|
||||
operation->state = PSA_PAKE_OUTPUT_X1_X2;
|
||||
break;
|
||||
case PSA_PAKE_STEP_X2S:
|
||||
operation->state = PSA_PAKE_OUTPUT_X2S;
|
||||
break;
|
||||
default:
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
|
||||
}
|
||||
|
||||
/* Check if step matches current sequence */
|
||||
switch( operation->sequence )
|
||||
{
|
||||
case PSA_PAKE_X1_STEP_KEY_SHARE:
|
||||
case PSA_PAKE_X2_STEP_KEY_SHARE:
|
||||
if( step != PSA_PAKE_STEP_KEY_SHARE )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
break;
|
||||
|
||||
case PSA_PAKE_X1_STEP_ZK_PUBLIC:
|
||||
case PSA_PAKE_X2_STEP_ZK_PUBLIC:
|
||||
if( step != PSA_PAKE_STEP_ZK_PUBLIC )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
break;
|
||||
|
||||
case PSA_PAKE_X1_STEP_ZK_PROOF:
|
||||
case PSA_PAKE_X2_STEP_ZK_PROOF:
|
||||
if( step != PSA_PAKE_STEP_ZK_PROOF )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
break;
|
||||
|
||||
default:
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
/* Initialize & write round on KEY_SHARE sequences */
|
||||
if( operation->state == PSA_PAKE_OUTPUT_X1_X2 &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
|
||||
{
|
||||
ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake,
|
||||
operation->buffer,
|
||||
MBEDTLS_PSA_PAKE_BUFFER_SIZE,
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE );
|
||||
if( ret != 0 )
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
|
||||
operation->buffer_offset = 0;
|
||||
}
|
||||
else if( operation->state == PSA_PAKE_OUTPUT_X2S &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
|
||||
{
|
||||
ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake,
|
||||
operation->buffer,
|
||||
MBEDTLS_PSA_PAKE_BUFFER_SIZE,
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE );
|
||||
if( ret != 0 )
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
|
||||
operation->buffer_offset = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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->role == PSA_PAKE_ROLE_SERVER )
|
||||
{
|
||||
/* Skip ECParameters, with is 3 bytes (RFC 8422) */
|
||||
operation->buffer_offset += 3;
|
||||
}
|
||||
|
||||
/* 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 )
|
||||
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||
|
||||
memcpy( output,
|
||||
operation->buffer + operation->buffer_offset,
|
||||
length );
|
||||
*output_length = length;
|
||||
|
||||
operation->buffer_offset += length;
|
||||
|
||||
/* Reset buffer after ZK_PROOF sequence */
|
||||
if( ( operation->state == PSA_PAKE_OUTPUT_X1_X2 &&
|
||||
operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) ||
|
||||
( operation->state == PSA_PAKE_OUTPUT_X2S &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
|
||||
{
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
|
||||
operation->state = PSA_PAKE_STATE_READY;
|
||||
operation->output_step++;
|
||||
operation->sequence = PSA_PAKE_SEQ_INVALID;
|
||||
}
|
||||
else
|
||||
operation->sequence++;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if( operation->alg == PSA_ALG_NONE ||
|
||||
operation->state == PSA_PAKE_STATE_INVALID )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
if( input == NULL || input_length == 0 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
/*
|
||||
* The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different
|
||||
* handling of input sequencing.
|
||||
*
|
||||
* The MbedTLS JPAKE API takes the whole X1+X2 or X4S steps data
|
||||
* at once as input, on the other side the PSA CRYPTO PAKE api requires
|
||||
* the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X4S to be
|
||||
* given in sequence.
|
||||
*
|
||||
* In order to achieve API compatibility, each X1+X2 or X4S step data
|
||||
* is stored sequentially in an intermediate buffer and given to the
|
||||
* MbedTLS JPAKE API on the last step.
|
||||
*
|
||||
* This causes any input error to be only detected on the last step.
|
||||
*/
|
||||
if( operation->alg == PSA_ALG_JPAKE )
|
||||
{
|
||||
if( step != PSA_PAKE_STEP_KEY_SHARE &&
|
||||
step != PSA_PAKE_STEP_ZK_PUBLIC &&
|
||||
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 )
|
||||
return( status );
|
||||
}
|
||||
|
||||
if( operation->state != PSA_PAKE_STATE_READY &&
|
||||
operation->state != PSA_PAKE_INPUT_X1_X2 &&
|
||||
operation->state != PSA_PAKE_INPUT_X4S )
|
||||
{
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
if( operation->state == PSA_PAKE_STATE_READY )
|
||||
{
|
||||
if( step != PSA_PAKE_STEP_KEY_SHARE )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
switch( operation->input_step )
|
||||
{
|
||||
case PSA_PAKE_STEP_X1_X2:
|
||||
operation->state = PSA_PAKE_INPUT_X1_X2;
|
||||
break;
|
||||
case PSA_PAKE_STEP_X2S:
|
||||
operation->state = PSA_PAKE_INPUT_X4S;
|
||||
break;
|
||||
default:
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
|
||||
}
|
||||
|
||||
/* Check if step matches current sequence */
|
||||
switch( operation->sequence )
|
||||
{
|
||||
case PSA_PAKE_X1_STEP_KEY_SHARE:
|
||||
case PSA_PAKE_X2_STEP_KEY_SHARE:
|
||||
if( step != PSA_PAKE_STEP_KEY_SHARE )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
break;
|
||||
|
||||
case PSA_PAKE_X1_STEP_ZK_PUBLIC:
|
||||
case PSA_PAKE_X2_STEP_ZK_PUBLIC:
|
||||
if( step != PSA_PAKE_STEP_ZK_PUBLIC )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
break;
|
||||
|
||||
case PSA_PAKE_X1_STEP_ZK_PROOF:
|
||||
case PSA_PAKE_X2_STEP_ZK_PROOF:
|
||||
if( step != PSA_PAKE_STEP_ZK_PROOF )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
break;
|
||||
|
||||
default:
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/* Load buffer at each last round ZK_PROOF */
|
||||
if( operation->state == PSA_PAKE_INPUT_X1_X2 &&
|
||||
operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF )
|
||||
{
|
||||
ret = mbedtls_ecjpake_read_round_one( &operation->ctx.ecjpake,
|
||||
operation->buffer,
|
||||
operation->buffer_length );
|
||||
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
|
||||
if( ret != 0 )
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
}
|
||||
else if( operation->state == PSA_PAKE_INPUT_X4S &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF )
|
||||
{
|
||||
ret = mbedtls_ecjpake_read_round_two( &operation->ctx.ecjpake,
|
||||
operation->buffer,
|
||||
operation->buffer_length );
|
||||
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
|
||||
if( ret != 0 )
|
||||
return( mbedtls_ecjpake_to_psa_error( ret ) );
|
||||
}
|
||||
|
||||
if( ( operation->state == PSA_PAKE_INPUT_X1_X2 &&
|
||||
operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) ||
|
||||
( operation->state == PSA_PAKE_INPUT_X4S &&
|
||||
operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
|
||||
{
|
||||
operation->state = PSA_PAKE_STATE_READY;
|
||||
operation->input_step++;
|
||||
operation->sequence = PSA_PAKE_SEQ_INVALID;
|
||||
}
|
||||
else
|
||||
operation->sequence++;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( operation->alg == PSA_ALG_NONE ||
|
||||
operation->state != PSA_PAKE_STATE_READY ||
|
||||
operation->input_step != PSA_PAKE_STEP_DERIVE ||
|
||||
operation->output_step != PSA_PAKE_STEP_DERIVE )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if( operation->alg == PSA_ALG_JPAKE )
|
||||
{
|
||||
ret = mbedtls_ecjpake_write_shared_key( &operation->ctx.ecjpake,
|
||||
operation->buffer,
|
||||
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 ) );
|
||||
}
|
||||
|
||||
status = psa_key_derivation_input_bytes( output,
|
||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||
operation->buffer,
|
||||
operation->buffer_length );
|
||||
|
||||
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
|
||||
psa_pake_abort( operation );
|
||||
|
||||
return( status );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
|
||||
{
|
||||
if( operation->alg == PSA_ALG_NONE )
|
||||
{
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if( operation->alg == PSA_ALG_JPAKE )
|
||||
{
|
||||
operation->input_step = PSA_PAKE_STEP_INVALID;
|
||||
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, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
mbedtls_ecjpake_free( &operation->ctx.ecjpake );
|
||||
}
|
||||
#endif
|
||||
|
||||
operation->alg = PSA_ALG_NONE;
|
||||
operation->state = PSA_PAKE_STATE_INVALID;
|
||||
operation->sequence = PSA_PAKE_SEQ_INVALID;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_PAKE */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
|
@ -32,10 +32,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include <mbedtls/rsa.h>
|
||||
#include <mbedtls/error.h>
|
||||
|
|
|
@ -38,10 +38,6 @@
|
|||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -34,12 +34,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
|
||||
|
||||
|
|
|
@ -36,13 +36,7 @@
|
|||
#include "psa/internal_trusted_storage.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -22,11 +22,7 @@
|
|||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#define mbedtls_snprintf snprintf
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
|
|
|
@ -33,14 +33,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if !defined(MBEDTLS_RIPEMD160_ALT)
|
||||
|
||||
|
|
129
library/rsa.c
129
library/rsa.c
|
@ -57,39 +57,22 @@
|
|||
/* We use MD first if it's available (for compatibility reasons)
|
||||
* and "fall back" to PSA otherwise (which needs psa_crypto_init()). */
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
#define HASH_MAX_SIZE MBEDTLS_MD_MAX_SIZE
|
||||
#else /* MBEDTLS_MD_C */
|
||||
#if !defined(MBEDTLS_MD_C)
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
#define HASH_MAX_SIZE PSA_HASH_MAX_SIZE
|
||||
#endif /* MBEDTLS_MD_C */
|
||||
#endif /* MBEDTLS_PKCS1_V21 */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_RSA_ALT)
|
||||
|
||||
/* Parameter validation macros */
|
||||
#define RSA_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
|
||||
#define RSA_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
|
||||
const mbedtls_mpi *N,
|
||||
const mbedtls_mpi *P, const mbedtls_mpi *Q,
|
||||
const mbedtls_mpi *D, const mbedtls_mpi *E )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
|
||||
( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
|
||||
|
@ -114,7 +97,6 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
|
|||
unsigned char const *E, size_t E_len )
|
||||
{
|
||||
int ret = 0;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
if( N != NULL )
|
||||
{
|
||||
|
@ -244,8 +226,6 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
|
|||
#endif
|
||||
int n_missing, pq_missing, d_missing, is_pub, is_priv;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
|
||||
have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
|
||||
have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
|
||||
|
@ -348,7 +328,6 @@ int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
|
|||
{
|
||||
int ret = 0;
|
||||
int is_priv;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
/* Check if key is private or public */
|
||||
is_priv =
|
||||
|
@ -393,7 +372,6 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int is_priv;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
/* Check if key is private or public */
|
||||
is_priv =
|
||||
|
@ -437,7 +415,6 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int is_priv;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
/* Check if key is private or public */
|
||||
is_priv =
|
||||
|
@ -474,8 +451,6 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
|
|||
*/
|
||||
void mbedtls_rsa_init( mbedtls_rsa_context *ctx )
|
||||
{
|
||||
RSA_VALIDATE( ctx != NULL );
|
||||
|
||||
memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
|
||||
|
||||
ctx->padding = MBEDTLS_RSA_PKCS_V15;
|
||||
|
@ -552,8 +527,6 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi H, G, L;
|
||||
int prime_quality = 0;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( f_rng != NULL );
|
||||
|
||||
/*
|
||||
* If the modulus is 1024 bit long or shorter, then the security strength of
|
||||
|
@ -666,8 +639,6 @@ cleanup:
|
|||
*/
|
||||
int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
|
||||
{
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
|
||||
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
|
||||
|
||||
|
@ -691,8 +662,6 @@ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
|
|||
*/
|
||||
int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
|
||||
{
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
|
||||
rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
|
||||
{
|
||||
|
@ -722,9 +691,6 @@ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
|
|||
int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
|
||||
const mbedtls_rsa_context *prv )
|
||||
{
|
||||
RSA_VALIDATE_RET( pub != NULL );
|
||||
RSA_VALIDATE_RET( prv != NULL );
|
||||
|
||||
if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
|
||||
mbedtls_rsa_check_privkey( prv ) != 0 )
|
||||
{
|
||||
|
@ -750,9 +716,6 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t olen;
|
||||
mbedtls_mpi T;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( input != NULL );
|
||||
RSA_VALIDATE_RET( output != NULL );
|
||||
|
||||
if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
@ -920,10 +883,6 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
|
|||
* checked result; should be the same in the end. */
|
||||
mbedtls_mpi I, C;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( input != NULL );
|
||||
RSA_VALIDATE_RET( output != NULL );
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -1114,7 +1073,7 @@ static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
|
|||
unsigned char *p;
|
||||
unsigned int hlen;
|
||||
size_t i, use_len;
|
||||
unsigned char mask[HASH_MAX_SIZE];
|
||||
unsigned char mask[MBEDTLS_HASH_MAX_SIZE];
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
int ret = 0;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
|
@ -1311,11 +1270,6 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
|
|||
unsigned char *p = output;
|
||||
unsigned int hlen;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( output != NULL );
|
||||
RSA_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -1377,10 +1331,6 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *p = output;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( output != NULL );
|
||||
RSA_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
olen = ctx->len;
|
||||
|
||||
/* first comparison checks for overflow */
|
||||
|
@ -1429,10 +1379,6 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
|
|||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( output != NULL );
|
||||
RSA_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
#if defined(MBEDTLS_PKCS1_V15)
|
||||
|
@ -1469,15 +1415,9 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
|
|||
size_t ilen, i, pad_len;
|
||||
unsigned char *p, bad, pad_done;
|
||||
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
|
||||
unsigned char lhash[HASH_MAX_SIZE];
|
||||
unsigned char lhash[MBEDTLS_HASH_MAX_SIZE];
|
||||
unsigned int hlen;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
|
||||
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
|
||||
RSA_VALIDATE_RET( input != NULL );
|
||||
RSA_VALIDATE_RET( olen != NULL );
|
||||
|
||||
/*
|
||||
* Parameters sanity checks
|
||||
*/
|
||||
|
@ -1598,11 +1538,6 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
|
|||
size_t ilen;
|
||||
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
|
||||
RSA_VALIDATE_RET( input != NULL );
|
||||
RSA_VALIDATE_RET( olen != NULL );
|
||||
|
||||
ilen = ctx->len;
|
||||
|
||||
if( ctx->padding != MBEDTLS_RSA_PKCS_V15 )
|
||||
|
@ -1637,11 +1572,6 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
|
|||
unsigned char *output,
|
||||
size_t output_max_len)
|
||||
{
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
|
||||
RSA_VALIDATE_RET( input != NULL );
|
||||
RSA_VALIDATE_RET( olen != NULL );
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
#if defined(MBEDTLS_PKCS1_V15)
|
||||
|
@ -1679,11 +1609,8 @@ static int rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t msb;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
|
||||
hashlen == 0 ) ||
|
||||
hash != NULL );
|
||||
RSA_VALIDATE_RET( sig != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hashlen != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
if( ctx->padding != MBEDTLS_RSA_PKCS_V21 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
@ -1955,11 +1882,8 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *sig_try = NULL, *verif = NULL;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
|
||||
hashlen == 0 ) ||
|
||||
hash != NULL );
|
||||
RSA_VALIDATE_RET( sig != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hashlen != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
if( ctx->padding != MBEDTLS_RSA_PKCS_V15 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
@ -2023,11 +1947,8 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
|
|||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
|
||||
hashlen == 0 ) ||
|
||||
hash != NULL );
|
||||
RSA_VALIDATE_RET( sig != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hashlen != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
|
@ -2064,16 +1985,13 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
|
|||
size_t siglen;
|
||||
unsigned char *p;
|
||||
unsigned char *hash_start;
|
||||
unsigned char result[HASH_MAX_SIZE];
|
||||
unsigned char result[MBEDTLS_HASH_MAX_SIZE];
|
||||
unsigned int hlen;
|
||||
size_t observed_salt_len, msb;
|
||||
unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = {0};
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( sig != NULL );
|
||||
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
|
||||
hashlen == 0 ) ||
|
||||
hash != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hashlen != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
siglen = ctx->len;
|
||||
|
||||
|
@ -2168,11 +2086,8 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
|
|||
const unsigned char *sig )
|
||||
{
|
||||
mbedtls_md_type_t mgf1_hash_id;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( sig != NULL );
|
||||
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
|
||||
hashlen == 0 ) ||
|
||||
hash != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hashlen != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
|
||||
? (mbedtls_md_type_t) ctx->hash_id
|
||||
|
@ -2201,11 +2116,8 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
|
|||
size_t sig_len;
|
||||
unsigned char *encoded = NULL, *encoded_expected = NULL;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( sig != NULL );
|
||||
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
|
||||
hashlen == 0 ) ||
|
||||
hash != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hashlen != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
sig_len = ctx->len;
|
||||
|
||||
|
@ -2270,11 +2182,8 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
|
|||
const unsigned char *hash,
|
||||
const unsigned char *sig )
|
||||
{
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( sig != NULL );
|
||||
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
|
||||
hashlen == 0 ) ||
|
||||
hash != NULL );
|
||||
if( ( md_alg != MBEDTLS_MD_NONE || hashlen != 0 ) && hash == NULL )
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
|
@ -2301,8 +2210,6 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
|
|||
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
RSA_VALIDATE_RET( dst != NULL );
|
||||
RSA_VALIDATE_RET( src != NULL );
|
||||
|
||||
dst->len = src->len;
|
||||
|
||||
|
|
|
@ -32,26 +32,12 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#define SHA1_VALIDATE_RET(cond) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA )
|
||||
|
||||
#define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#if !defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
SHA1_VALIDATE( ctx != NULL );
|
||||
|
||||
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
|
||||
}
|
||||
|
||||
|
@ -66,9 +52,6 @@ void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
|
|||
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src )
|
||||
{
|
||||
SHA1_VALIDATE( dst != NULL );
|
||||
SHA1_VALIDATE( src != NULL );
|
||||
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
|
@ -77,8 +60,6 @@ void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
|
|||
*/
|
||||
int mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
SHA1_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
|
@ -100,9 +81,6 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
|
|||
uint32_t temp, W[16], A, B, C, D, E;
|
||||
} local;
|
||||
|
||||
SHA1_VALIDATE_RET( ctx != NULL );
|
||||
SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
|
||||
|
||||
local.W[ 0] = MBEDTLS_GET_UINT32_BE( data, 0 );
|
||||
local.W[ 1] = MBEDTLS_GET_UINT32_BE( data, 4 );
|
||||
local.W[ 2] = MBEDTLS_GET_UINT32_BE( data, 8 );
|
||||
|
@ -277,9 +255,6 @@ int mbedtls_sha1_update( mbedtls_sha1_context *ctx,
|
|||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
SHA1_VALIDATE_RET( ctx != NULL );
|
||||
SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
if( ilen == 0 )
|
||||
return( 0 );
|
||||
|
||||
|
@ -329,9 +304,6 @@ int mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
|
|||
uint32_t used;
|
||||
uint32_t high, low;
|
||||
|
||||
SHA1_VALIDATE_RET( ctx != NULL );
|
||||
SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
/*
|
||||
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
|
||||
*/
|
||||
|
@ -392,9 +364,6 @@ int mbedtls_sha1( const unsigned char *input,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_sha1_context ctx;
|
||||
|
||||
SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
mbedtls_sha1_init( &ctx );
|
||||
|
||||
if( ( ret = mbedtls_sha1_starts( &ctx ) ) != 0 )
|
||||
|
|
|
@ -32,17 +32,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if defined(__aarch64__)
|
||||
# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
|
||||
|
@ -149,18 +139,12 @@ static int mbedtls_a64_crypto_sha256_determine_support( void )
|
|||
|
||||
#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */
|
||||
|
||||
#define SHA256_VALIDATE_RET(cond) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
|
||||
#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#if !defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
#define SHA256_BLOCK_SIZE 64
|
||||
|
||||
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
SHA256_VALIDATE( ctx != NULL );
|
||||
|
||||
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
|
||||
}
|
||||
|
||||
|
@ -175,9 +159,6 @@ void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
|
|||
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src )
|
||||
{
|
||||
SHA256_VALIDATE( dst != NULL );
|
||||
SHA256_VALIDATE( src != NULL );
|
||||
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
|
@ -186,12 +167,12 @@ void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
|
|||
*/
|
||||
int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
|
||||
{
|
||||
SHA256_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
|
||||
if( is224 != 0 && is224 != 1 )
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
#else
|
||||
SHA256_VALIDATE_RET( is224 == 0 );
|
||||
if( is224 != 0 )
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
#endif
|
||||
|
||||
ctx->total[0] = 0;
|
||||
|
@ -427,9 +408,6 @@ int mbedtls_internal_sha256_process_c( mbedtls_sha256_context *ctx,
|
|||
|
||||
unsigned int i;
|
||||
|
||||
SHA256_VALIDATE_RET( ctx != NULL );
|
||||
SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
local.A[i] = ctx->state[i];
|
||||
|
||||
|
@ -579,9 +557,6 @@ int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
|
|||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
SHA256_VALIDATE_RET( ctx != NULL );
|
||||
SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
if( ilen == 0 )
|
||||
return( 0 );
|
||||
|
||||
|
@ -633,9 +608,6 @@ int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
|
|||
uint32_t used;
|
||||
uint32_t high, low;
|
||||
|
||||
SHA256_VALIDATE_RET( ctx != NULL );
|
||||
SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
/*
|
||||
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
|
||||
*/
|
||||
|
@ -683,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 );
|
||||
|
@ -705,14 +679,13 @@ int mbedtls_sha256( const unsigned char *input,
|
|||
mbedtls_sha256_context ctx;
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
|
||||
if( is224 != 0 && is224 != 1 )
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
#else
|
||||
SHA256_VALIDATE_RET( is224 == 0 );
|
||||
if( is224 != 0 )
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
#endif
|
||||
|
||||
SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
mbedtls_sha256_init( &ctx );
|
||||
|
||||
if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
|
||||
|
|
|
@ -38,17 +38,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#if defined(__aarch64__)
|
||||
# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \
|
||||
|
@ -164,10 +154,6 @@ static int mbedtls_a64_crypto_sha512_determine_support( void )
|
|||
|
||||
#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */
|
||||
|
||||
#define SHA512_VALIDATE_RET(cond) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
|
||||
#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
#if !defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#define SHA512_BLOCK_SIZE 128
|
||||
|
@ -183,8 +169,6 @@ static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
|
|||
|
||||
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
|
||||
{
|
||||
SHA512_VALIDATE( ctx != NULL );
|
||||
|
||||
memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
|
||||
}
|
||||
|
||||
|
@ -199,9 +183,6 @@ void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
|
|||
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
|
||||
const mbedtls_sha512_context *src )
|
||||
{
|
||||
SHA512_VALIDATE( dst != NULL );
|
||||
SHA512_VALIDATE( src != NULL );
|
||||
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
|
@ -210,11 +191,12 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
|
|||
*/
|
||||
int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
|
||||
{
|
||||
SHA512_VALIDATE_RET( ctx != NULL );
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
|
||||
if( is384 != 0 && is384 != 1 )
|
||||
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
#else
|
||||
SHA512_VALIDATE_RET( is384 == 0 );
|
||||
if( is384 != 0 )
|
||||
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
#endif
|
||||
|
||||
ctx->total[0] = 0;
|
||||
|
@ -569,9 +551,6 @@ int mbedtls_internal_sha512_process_c( mbedtls_sha512_context *ctx,
|
|||
uint64_t A[8];
|
||||
} local;
|
||||
|
||||
SHA512_VALIDATE_RET( ctx != NULL );
|
||||
SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
|
||||
|
||||
#define SHR(x,n) ((x) >> (n))
|
||||
#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
|
||||
|
||||
|
@ -735,9 +714,6 @@ int mbedtls_sha512_update( mbedtls_sha512_context *ctx,
|
|||
size_t fill;
|
||||
unsigned int left;
|
||||
|
||||
SHA512_VALIDATE_RET( ctx != NULL );
|
||||
SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
if( ilen == 0 )
|
||||
return( 0 );
|
||||
|
||||
|
@ -788,9 +764,6 @@ int mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
|
|||
unsigned used;
|
||||
uint64_t high, low;
|
||||
|
||||
SHA512_VALIDATE_RET( ctx != NULL );
|
||||
SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
/*
|
||||
* Add padding: 0x80 then 0x00 until 16 bytes remain for the length
|
||||
*/
|
||||
|
@ -837,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 );
|
||||
|
@ -862,12 +837,12 @@ int mbedtls_sha512( const unsigned char *input,
|
|||
mbedtls_sha512_context ctx;
|
||||
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
|
||||
if( is384 != 0 && is384 != 1 )
|
||||
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
#else
|
||||
SHA512_VALIDATE_RET( is384 == 0 );
|
||||
if( is384 != 0 )
|
||||
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
#endif
|
||||
SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
mbedtls_sha512_init( &ctx );
|
||||
|
||||
|
|
|
@ -25,13 +25,7 @@
|
|||
|
||||
#if defined(MBEDTLS_SSL_CACHE_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "mbedtls/ssl_cache.h"
|
||||
#include "ssl_misc.h"
|
||||
|
|
|
@ -23,17 +23,13 @@
|
|||
|
||||
#if defined(MBEDTLS_SSL_TLS_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#include "legacy_or_psa.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
@ -24,13 +24,7 @@
|
|||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -376,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 );
|
||||
|
@ -614,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 ) ) ||
|
||||
|
@ -629,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 )
|
||||
|
@ -643,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.
|
||||
*/
|
||||
|
@ -656,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;
|
||||
|
@ -719,6 +714,34 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
{
|
||||
int ret;
|
||||
size_t session_id_len;
|
||||
mbedtls_ssl_session *session_negotiate = ssl->session_negotiate;
|
||||
|
||||
if( session_negotiate == NULL )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_HAVE_TIME)
|
||||
|
||||
/* Check if a tls13 ticket has been configured. */
|
||||
if( ssl->handshake->resume != 0 &&
|
||||
session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
||||
session_negotiate->ticket != NULL )
|
||||
{
|
||||
mbedtls_time_t now = mbedtls_time( NULL );
|
||||
uint64_t age = (uint64_t)( now - session_negotiate->ticket_received );
|
||||
if( session_negotiate->ticket_received > now ||
|
||||
age > session_negotiate->ticket_lifetime )
|
||||
{
|
||||
/* Without valid ticket, disable session resumption.*/
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ( "Ticket expired, disable session resumption" ) );
|
||||
ssl->handshake->resume = 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
|
||||
MBEDTLS_SSL_SESSION_TICKETS &&
|
||||
MBEDTLS_HAVE_TIME */
|
||||
|
||||
if( ssl->conf->f_rng == NULL )
|
||||
{
|
||||
|
@ -737,7 +760,7 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
{
|
||||
if( ssl->handshake->resume )
|
||||
{
|
||||
ssl->tls_version = ssl->session_negotiate->tls_version;
|
||||
ssl->tls_version = session_negotiate->tls_version;
|
||||
ssl->handshake->min_tls_version = ssl->tls_version;
|
||||
}
|
||||
else
|
||||
|
@ -771,7 +794,7 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
* to zero, except in the case of a TLS 1.2 session renegotiation or
|
||||
* session resumption.
|
||||
*/
|
||||
session_id_len = ssl->session_negotiate->id_len;
|
||||
session_id_len = session_negotiate->id_len;
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 )
|
||||
|
@ -790,12 +813,15 @@ 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( ( ssl->session_negotiate->ticket != NULL ) &&
|
||||
( ssl->session_negotiate->ticket_len != 0 ) )
|
||||
if( ( session_negotiate->ticket != NULL ) &&
|
||||
( session_negotiate->ticket_len != 0 ) )
|
||||
{
|
||||
session_id_len = 32;
|
||||
}
|
||||
|
@ -827,13 +853,13 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
}
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
|
||||
|
||||
if( session_id_len != ssl->session_negotiate->id_len )
|
||||
if( session_id_len != session_negotiate->id_len )
|
||||
{
|
||||
ssl->session_negotiate->id_len = session_id_len;
|
||||
session_negotiate->id_len = session_id_len;
|
||||
if( session_id_len > 0 )
|
||||
{
|
||||
ret = ssl->conf->f_rng( ssl->conf->p_rng,
|
||||
ssl->session_negotiate->id,
|
||||
session_negotiate->id,
|
||||
session_id_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
|
@ -843,9 +869,39 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl )
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
||||
ssl->handshake->resume )
|
||||
{
|
||||
int hostname_mismatch = ssl->hostname != NULL ||
|
||||
session_negotiate->hostname != NULL;
|
||||
if( ssl->hostname != NULL && session_negotiate->hostname != NULL )
|
||||
{
|
||||
hostname_mismatch = strcmp(
|
||||
ssl->hostname, session_negotiate->hostname ) != 0;
|
||||
}
|
||||
|
||||
if( hostname_mismatch )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1, ( "Hostname mismatch the session ticket, "
|
||||
"disable session resumption." ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return mbedtls_ssl_session_set_hostname( session_negotiate,
|
||||
ssl->hostname );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
|
||||
MBEDTLS_SSL_SESSION_TICKETS &&
|
||||
MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write ClientHello handshake message.
|
||||
* Handler for MBEDTLS_SSL_CLIENT_HELLO
|
||||
|
@ -905,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(
|
||||
|
@ -915,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,
|
||||
|
|
|
@ -25,12 +25,7 @@
|
|||
|
||||
#if defined(MBEDTLS_SSL_COOKIE_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "mbedtls/ssl_cookie.h"
|
||||
#include "ssl_misc.h"
|
||||
|
@ -38,13 +33,13 @@
|
|||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/constant_time.h"
|
||||
|
||||
#include "legacy_or_psa.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
|
||||
#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
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "mbedtls/psa_util.h"
|
||||
#include "hash_info.h"
|
||||
#endif
|
||||
#include "legacy_or_psa.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
|
||||
#if defined(MBEDTLS_MD5_C)
|
||||
#include "mbedtls/md5.h"
|
||||
|
@ -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,14 +619,17 @@ 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)
|
||||
uint16_t new_session_tickets_count; /*!< number of session tickets */
|
||||
#endif
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
|
||||
#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
|
||||
|
||||
|
@ -674,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;
|
||||
|
@ -683,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 */
|
||||
|
@ -850,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
|
||||
|
@ -1362,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:
|
||||
|
@ -1419,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 );
|
||||
|
@ -1781,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.
|
||||
|
@ -1828,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.
|
||||
|
@ -1868,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
|
||||
*/
|
||||
|
@ -1881,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
|
||||
|
@ -1911,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
|
||||
*/
|
||||
|
@ -1919,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
|
||||
|
@ -2039,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 &&
|
||||
|
@ -2051,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 )
|
||||
{
|
||||
|
@ -2076,8 +2081,80 @@ 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_tls13_sig_alg_for_cert_verify_is_supported(
|
||||
const uint16_t sig_alg )
|
||||
{
|
||||
switch( sig_alg )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
#if defined(PSA_WANT_ALG_SHA_256) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
|
||||
break;
|
||||
#endif /* PSA_WANT_ALG_SHA_256 && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
|
||||
#if defined(PSA_WANT_ALG_SHA_384) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
|
||||
break;
|
||||
#endif /* PSA_WANT_ALG_SHA_384 && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
|
||||
#if defined(PSA_WANT_ALG_SHA_512) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
|
||||
break;
|
||||
#endif /* PSA_WANT_ALG_SHA_512 && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
|
||||
#endif /* MBEDTLS_ECDSA_C */
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
break;
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
break;
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#if defined(PSA_WANT_ALG_SHA_512)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
break;
|
||||
#endif /* PSA_WANT_ALG_SHA_512 */
|
||||
#endif /* MBEDTLS_PKCS1_V21 */
|
||||
default:
|
||||
return( 0 );
|
||||
}
|
||||
return( 1 );
|
||||
|
||||
}
|
||||
|
||||
static inline int mbedtls_ssl_tls13_sig_alg_is_supported(
|
||||
const uint16_t sig_alg )
|
||||
{
|
||||
switch( sig_alg )
|
||||
{
|
||||
#if defined(MBEDTLS_PKCS1_V15)
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
|
||||
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_PKCS1_SHA384:
|
||||
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_PKCS1_SHA512:
|
||||
break;
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
#endif /* MBEDTLS_PKCS1_V15 */
|
||||
default:
|
||||
return( mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported(
|
||||
sig_alg ) );
|
||||
}
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
|
@ -2130,76 +2207,6 @@ static inline int mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(
|
|||
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 )
|
||||
{
|
||||
switch( sig_alg )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
|
||||
#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA384_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
|
||||
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
|
||||
#endif /* MBEDTLS_ECDSA_C */
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA256_C */
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA384_C */
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA512_C */
|
||||
#endif /* MBEDTLS_PKCS1_V21 */
|
||||
default:
|
||||
return( 0 );
|
||||
}
|
||||
return( 1 );
|
||||
|
||||
}
|
||||
|
||||
static inline int mbedtls_ssl_tls13_sig_alg_is_supported(
|
||||
const uint16_t sig_alg )
|
||||
{
|
||||
switch( sig_alg )
|
||||
{
|
||||
#if defined(MBEDTLS_PKCS1_V15)
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA256_C */
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA384_C */
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
|
||||
break;
|
||||
#endif /* MBEDTLS_SHA512_C */
|
||||
#endif /* MBEDTLS_PKCS1_V15 */
|
||||
default:
|
||||
return( mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported(
|
||||
sig_alg ) );
|
||||
}
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
static inline int mbedtls_ssl_tls12_sig_alg_is_supported(
|
||||
const uint16_t sig_alg )
|
||||
|
@ -2276,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.
|
||||
|
@ -2456,17 +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)
|
||||
/* Check if we have any PSK to offer, returns 0 if PSK is available.
|
||||
* Assign the psk and ticket if pointers are present.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_get_psk_to_offer(
|
||||
const mbedtls_ssl_context *ssl,
|
||||
int *psk_type,
|
||||
const unsigned char **psk, size_t *psk_len,
|
||||
const unsigned char **psk_identity, size_t *psk_identity_len );
|
||||
|
||||
#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.
|
||||
|
@ -2499,6 +2487,15 @@ 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) && \
|
||||
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
|
||||
defined(MBEDTLS_SSL_CLI_C)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_session_set_hostname( mbedtls_ssl_session *session,
|
||||
const char *hostname );
|
||||
#endif
|
||||
|
||||
#endif /* ssl_misc.h */
|
||||
|
|
|
@ -26,13 +26,7 @@
|
|||
|
||||
#if defined(MBEDTLS_SSL_TLS_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "ssl_misc.h"
|
||||
|
@ -1124,7 +1118,9 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
|
|||
mbedtls_ssl_transform *transform,
|
||||
mbedtls_record *rec )
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) || defined(MBEDTLS_CIPHER_MODE_AEAD)
|
||||
size_t olen;
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC || MBEDTLS_CIPHER_MODE_AEAD */
|
||||
mbedtls_ssl_mode_t ssl_mode;
|
||||
int ret;
|
||||
|
||||
|
@ -1669,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;
|
||||
|
||||
|
@ -1801,8 +1797,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
|
|||
|
||||
if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
|
||||
"or mbedtls_ssl_set_bio()" ) );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
|
@ -2017,8 +2012,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
|
|||
|
||||
if( ssl->f_send == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
|
||||
"or mbedtls_ssl_set_bio()" ) );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
|
@ -3851,8 +3845,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. */
|
||||
|
@ -3860,11 +3854,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 )
|
||||
|
|
|
@ -21,13 +21,7 @@
|
|||
|
||||
#if defined(MBEDTLS_SSL_TICKET_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "ssl_misc.h"
|
||||
#include "mbedtls/ssl_ticket.h"
|
||||
|
|
|
@ -27,15 +27,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_printf printf
|
||||
#endif /* !MBEDTLS_PLATFORM_C */
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "ssl_client.h"
|
||||
|
@ -54,7 +46,7 @@
|
|||
#include "mbedtls/psa_util.h"
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
#include "legacy_or_psa.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
#include "mbedtls/oid.h"
|
||||
|
@ -243,10 +235,13 @@ int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
|
|||
{
|
||||
mbedtls_ssl_session_free( dst );
|
||||
memcpy( dst, src, sizeof( mbedtls_ssl_session ) );
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||
dst->ticket = NULL;
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
dst->hostname = NULL;
|
||||
#endif
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
|
||||
|
@ -295,6 +290,18 @@ int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
|
|||
|
||||
memcpy( dst->ticket, src->ticket, src->ticket_len );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
if( src->endpoint == MBEDTLS_SSL_IS_CLIENT )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
ret = mbedtls_ssl_session_set_hostname( dst, src->hostname );
|
||||
if( ret != 0 )
|
||||
return ( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
|
||||
MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
return( 0 );
|
||||
|
@ -597,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)
|
||||
|
@ -763,6 +776,13 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
|
|||
mbedtls_ssl_transform_init( ssl->transform_negotiate );
|
||||
ssl_handshake_params_init( ssl->handshake );
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SRV_C) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
ssl->handshake->new_session_tickets_count =
|
||||
ssl->conf->new_session_tickets_count ;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
||||
{
|
||||
|
@ -823,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
|
||||
|
@ -889,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 );
|
||||
}
|
||||
|
||||
|
@ -992,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 );
|
||||
|
@ -1204,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;
|
||||
|
@ -1366,6 +1412,23 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session
|
|||
if( ssl->handshake->resume == 1 )
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if( session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 )
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
mbedtls_ssl_ciphersuite_from_id( session->ciphersuite );
|
||||
|
||||
if( mbedtls_ssl_validate_ciphersuite(
|
||||
ssl, ciphersuite_info, MBEDTLS_SSL_VERSION_TLS1_3,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3 ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "%d is not a valid TLS 1.3 ciphersuite.",
|
||||
session->ciphersuite ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate,
|
||||
session ) ) != 0 )
|
||||
return( ret );
|
||||
|
@ -1388,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)
|
||||
|
@ -1562,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 );
|
||||
|
@ -1617,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 )
|
||||
{
|
||||
|
@ -1640,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 */
|
||||
|
@ -1758,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 */
|
||||
|
@ -1788,6 +1865,7 @@ int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
|
|||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
|
||||
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
|
||||
size_t),
|
||||
|
@ -1796,7 +1874,9 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
|
|||
conf->f_psk = f_psk;
|
||||
conf->p_psk = p_psk;
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static mbedtls_ssl_mode_t mbedtls_ssl_get_base_mode(
|
||||
|
@ -1907,6 +1987,7 @@ mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite(
|
|||
/* Serialization of TLS 1.3 sessions:
|
||||
*
|
||||
* struct {
|
||||
* opaque hostname<0..2^16-1>;
|
||||
* uint64 ticket_received;
|
||||
* uint32 ticket_lifetime;
|
||||
* opaque ticket<1..2^16-1>;
|
||||
|
@ -1933,6 +2014,11 @@ static int ssl_tls13_session_save( const mbedtls_ssl_session *session,
|
|||
size_t *olen )
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
#if defined(MBEDTLS_SSL_CLI_C) && \
|
||||
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
size_t hostname_len = ( session->hostname == NULL ) ?
|
||||
0 : strlen( session->hostname ) + 1;
|
||||
#endif
|
||||
size_t needed = 1 /* endpoint */
|
||||
+ 2 /* ciphersuite */
|
||||
+ 4 /* ticket_age_add */
|
||||
|
@ -1951,6 +2037,11 @@ static int ssl_tls13_session_save( const mbedtls_ssl_session *session,
|
|||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
if( session->endpoint == MBEDTLS_SSL_IS_CLIENT )
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
needed += 2 /* hostname_len */
|
||||
+ hostname_len; /* hostname */
|
||||
#endif
|
||||
|
||||
needed += 4 /* ticket_lifetime */
|
||||
+ 2; /* ticket_len */
|
||||
|
||||
|
@ -1988,6 +2079,17 @@ static int ssl_tls13_session_save( const mbedtls_ssl_session *session,
|
|||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
if( session->endpoint == MBEDTLS_SSL_IS_CLIENT )
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
MBEDTLS_PUT_UINT16_BE( hostname_len, p, 0 );
|
||||
p += 2;
|
||||
if( hostname_len > 0 )
|
||||
{
|
||||
/* save host name */
|
||||
memcpy( p, session->hostname, hostname_len );
|
||||
p += hostname_len;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
MBEDTLS_PUT_UINT64_BE( (uint64_t) session->ticket_received, p, 0 );
|
||||
p += 8;
|
||||
|
@ -2048,6 +2150,28 @@ static int ssl_tls13_session_load( mbedtls_ssl_session *session,
|
|||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
if( session->endpoint == MBEDTLS_SSL_IS_CLIENT )
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
size_t hostname_len;
|
||||
/* load host name */
|
||||
if( end - p < 2 )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
hostname_len = MBEDTLS_GET_UINT16_BE( p, 0 );
|
||||
p += 2;
|
||||
|
||||
if( end - p < ( long int )hostname_len )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
if( hostname_len > 0 )
|
||||
{
|
||||
session->hostname = mbedtls_calloc( 1, hostname_len );
|
||||
if( session->hostname == NULL )
|
||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
memcpy( session->hostname, p, hostname_len );
|
||||
p += hostname_len;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION &&
|
||||
MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
if( end - p < 8 )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
@ -2305,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
|
||||
|
@ -2326,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)
|
||||
|
@ -2611,6 +2735,15 @@ void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets
|
|||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
void mbedtls_ssl_conf_new_session_tickets( mbedtls_ssl_config *conf,
|
||||
uint16_t num_tickets )
|
||||
{
|
||||
conf->new_session_tickets_count = num_tickets;
|
||||
}
|
||||
#endif
|
||||
|
||||
void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
|
||||
mbedtls_ssl_ticket_write_t *f_ticket_write,
|
||||
mbedtls_ssl_ticket_parse_t *f_ticket_parse,
|
||||
|
@ -3243,6 +3376,10 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
|
|||
if( ret != 0 )
|
||||
goto cleanup;
|
||||
|
||||
/* If ssl->conf->endpoint is not one of MBEDTLS_SSL_IS_CLIENT or
|
||||
* MBEDTLS_SSL_IS_SERVER, this is the return code we give */
|
||||
ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
|
||||
{
|
||||
|
@ -3253,6 +3390,7 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
|
|||
{
|
||||
case MBEDTLS_SSL_HELLO_REQUEST:
|
||||
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_CLIENT_HELLO:
|
||||
|
@ -3488,7 +3626,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 );
|
||||
|
@ -3500,7 +3638,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 )
|
||||
|
@ -3546,7 +3684,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 ) )
|
||||
{
|
||||
|
@ -3566,7 +3704,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)
|
||||
|
@ -3640,6 +3778,10 @@ void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
|
|||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
mbedtls_free( session->hostname );
|
||||
#endif
|
||||
mbedtls_free( session->ticket );
|
||||
#endif
|
||||
|
||||
|
@ -3955,6 +4097,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.
|
||||
|
@ -4040,17 +4185,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,
|
||||
|
@ -4354,7 +4504,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
|
||||
|
@ -4499,7 +4649,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)
|
||||
|
@ -4511,7 +4661,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
|
||||
|
@ -4535,7 +4685,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
|
||||
|
@ -4547,7 +4697,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" );
|
||||
|
@ -4573,7 +4723,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 */
|
||||
|
@ -4644,6 +4794,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
|
|||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
mbedtls_ssl_conf_new_session_tickets(
|
||||
conf, MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS );
|
||||
#endif
|
||||
/*
|
||||
* Allow all TLS 1.3 key exchange modes by default.
|
||||
*/
|
||||
|
@ -4700,14 +4854,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;
|
||||
|
@ -4726,14 +4880,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;
|
||||
|
@ -4758,7 +4912,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 ) )
|
||||
{
|
||||
|
@ -4780,7 +4934,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 );
|
||||
|
@ -5062,6 +5216,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 */
|
||||
|
@ -5148,6 +5306,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 );
|
||||
|
@ -5155,7 +5320,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`
|
||||
|
@ -5263,7 +5428,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)
|
||||
|
||||
|
@ -5334,6 +5499,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,
|
||||
|
@ -5408,9 +5575,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,
|
||||
|
@ -5494,13 +5664,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)
|
||||
|
@ -5814,7 +5987,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 );
|
||||
}
|
||||
|
||||
|
@ -7335,16 +7511,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 */
|
||||
|
||||
|
@ -7581,11 +7766,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;
|
||||
|
@ -8455,7 +8645,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.
|
||||
*
|
||||
|
@ -8558,7 +8748,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)
|
||||
/*
|
||||
|
@ -8758,4 +8948,54 @@ int mbedtls_ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
|
|||
}
|
||||
#endif /* MBEDTLS_SSL_ALPN */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
|
||||
defined(MBEDTLS_SSL_CLI_C)
|
||||
int mbedtls_ssl_session_set_hostname( mbedtls_ssl_session *session,
|
||||
const char *hostname )
|
||||
{
|
||||
/* Initialize to suppress unnecessary compiler warning */
|
||||
size_t hostname_len = 0;
|
||||
|
||||
/* Check if new hostname is valid before
|
||||
* making any change to current one */
|
||||
if( hostname != NULL )
|
||||
{
|
||||
hostname_len = strlen( hostname );
|
||||
|
||||
if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
/* Now it's clear that we will overwrite the old hostname,
|
||||
* so we can free it safely */
|
||||
if( session->hostname != NULL )
|
||||
{
|
||||
mbedtls_platform_zeroize( session->hostname,
|
||||
strlen( session->hostname ) );
|
||||
mbedtls_free( session->hostname );
|
||||
}
|
||||
|
||||
/* Passing NULL as hostname shall clear the old one */
|
||||
if( hostname == NULL )
|
||||
{
|
||||
session->hostname = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
session->hostname = mbedtls_calloc( 1, hostname_len + 1 );
|
||||
if( session->hostname == NULL )
|
||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
|
||||
memcpy( session->hostname, hostname, hostname_len );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
|
||||
MBEDTLS_SSL_SESSION_TICKETS &&
|
||||
MBEDTLS_SSL_SERVER_NAME_INDICATION &&
|
||||
MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS_C */
|
||||
|
|
|
@ -21,13 +21,7 @@
|
|||
|
||||
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "ssl_client.h"
|
||||
|
@ -55,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,
|
||||
|
@ -1777,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,
|
||||
|
@ -1845,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 )
|
||||
{
|
||||
|
@ -1875,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,
|
||||
|
@ -1910,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,
|
||||
|
@ -2330,11 +2319,8 @@ start_processing:
|
|||
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
|
||||
{
|
||||
size_t sig_len, hashlen;
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
unsigned char hash[PSA_HASH_MAX_SIZE];
|
||||
#else
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
#endif
|
||||
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
|
||||
|
||||
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
|
||||
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
|
||||
unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
|
||||
|
@ -2474,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,
|
||||
|
@ -2692,7 +2680,6 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
|
|||
{
|
||||
unsigned char *p = dn + i + 2;
|
||||
mbedtls_x509_name name;
|
||||
mbedtls_x509_name *name_cur, *name_prv;
|
||||
size_t asn1_len;
|
||||
char s[MBEDTLS_X509_MAX_DN_NAME_SIZE];
|
||||
memset( &name, 0, sizeof( name ) );
|
||||
|
@ -2712,14 +2699,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
|
|||
MBEDTLS_SSL_DEBUG_MSG( 3,
|
||||
( "DN hint: %.*s",
|
||||
mbedtls_x509_dn_gets( s, sizeof(s), &name ), s ) );
|
||||
name_cur = name.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
|
||||
mbedtls_free( name_prv );
|
||||
}
|
||||
mbedtls_asn1_free_named_data_list_shallow( name.next );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -21,13 +21,7 @@
|
|||
|
||||
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "ssl_misc.h"
|
||||
|
@ -36,6 +30,7 @@
|
|||
#include "mbedtls/platform_util.h"
|
||||
#include "constant_time_internal.h"
|
||||
#include "mbedtls/constant_time.h"
|
||||
#include "hash_info.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -713,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" ) );
|
||||
|
@ -734,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;
|
||||
|
@ -922,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
|
||||
|
@ -930,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 )
|
||||
{
|
||||
|
@ -3059,11 +3063,8 @@ curve_matching_done:
|
|||
|
||||
size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
|
||||
size_t hashlen = 0;
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
unsigned char hash[PSA_HASH_MAX_SIZE];
|
||||
#else
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
#endif
|
||||
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
|
||||
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
@ -664,10 +672,194 @@ static int ssl_tls13_write_psk_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
|
|||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES;
|
||||
return ( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
static psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg( int ciphersuite )
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
|
||||
|
||||
if( ciphersuite_info != NULL )
|
||||
return( mbedtls_psa_translate_md( ciphersuite_info->mac ) );
|
||||
|
||||
return( PSA_ALG_NONE );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
static int ssl_tls13_has_configured_ticket( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
return( ssl->handshake->resume &&
|
||||
session != NULL && session->ticket != NULL );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_ticket_get_identity( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
const unsigned char **identity,
|
||||
size_t *identity_len )
|
||||
{
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
|
||||
if( !ssl_tls13_has_configured_ticket( ssl ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = ssl_tls13_get_ciphersuite_hash_alg( session->ciphersuite );
|
||||
*identity = session->ticket;
|
||||
*identity_len = session->ticket_len;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_ticket_get_psk( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
const unsigned char **psk,
|
||||
size_t *psk_len )
|
||||
{
|
||||
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
|
||||
if( !ssl_tls13_has_configured_ticket( ssl ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = ssl_tls13_get_ciphersuite_hash_alg( session->ciphersuite );
|
||||
*psk = session->resumption_key;
|
||||
*psk_len = session->resumption_key_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_psk_get_identity( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
const unsigned char **identity,
|
||||
size_t *identity_len )
|
||||
{
|
||||
|
||||
if( ! mbedtls_ssl_conf_has_static_psk( ssl->conf ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = PSA_ALG_SHA_256;
|
||||
*identity = ssl->conf->psk_identity;
|
||||
*identity_len = ssl->conf->psk_identity_len;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_psk_get_psk( mbedtls_ssl_context *ssl,
|
||||
psa_algorithm_t *hash_alg,
|
||||
const unsigned char **psk,
|
||||
size_t *psk_len )
|
||||
{
|
||||
|
||||
if( ! mbedtls_ssl_conf_has_static_psk( ssl->conf ) )
|
||||
return( -1 );
|
||||
|
||||
*hash_alg = PSA_ALG_SHA_256;
|
||||
*psk = ssl->conf->psk;
|
||||
*psk_len = ssl->conf->psk_len;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int ssl_tls13_get_configured_psk_count( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int configured_psk_count = 0;
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( ssl_tls13_has_configured_ticket( ssl ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Ticket is configured" ) );
|
||||
configured_psk_count++;
|
||||
}
|
||||
#endif
|
||||
if( mbedtls_ssl_conf_has_static_psk( ssl->conf ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK is configured" ) );
|
||||
configured_psk_count++;
|
||||
}
|
||||
return( configured_psk_count );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_write_identity( mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
unsigned char *end,
|
||||
const unsigned char *identity,
|
||||
size_t identity_len,
|
||||
uint32_t obfuscated_ticket_age,
|
||||
size_t *out_len )
|
||||
{
|
||||
((void) ssl);
|
||||
*out_len = 0;
|
||||
|
||||
/*
|
||||
* - identity_len (2 bytes)
|
||||
* - identity (psk_identity_len bytes)
|
||||
* - obfuscated_ticket_age (4 bytes)
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 6 + identity_len );
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE( identity_len, buf, 0 );
|
||||
memcpy( buf + 2, identity, identity_len );
|
||||
MBEDTLS_PUT_UINT32_BE( obfuscated_ticket_age, buf, 2 + identity_len );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "write identity", buf, 6 + identity_len );
|
||||
|
||||
*out_len = 6 + identity_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_write_binder( mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
unsigned char *end,
|
||||
int psk_type,
|
||||
psa_algorithm_t hash_alg,
|
||||
const unsigned char *psk,
|
||||
size_t psk_len,
|
||||
size_t *out_len )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char binder_len;
|
||||
unsigned char transcript[ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
|
||||
size_t transcript_len = 0;
|
||||
|
||||
*out_len = 0;
|
||||
|
||||
binder_len = PSA_HASH_LENGTH( hash_alg );
|
||||
|
||||
/*
|
||||
* - binder_len (1 bytes)
|
||||
* - binder (binder_len bytes)
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 1 + binder_len );
|
||||
|
||||
buf[0] = binder_len;
|
||||
|
||||
/* Get current state of handshake transcript. */
|
||||
ret = mbedtls_ssl_get_handshake_transcript(
|
||||
ssl, mbedtls_hash_info_md_from_psa( hash_alg ),
|
||||
transcript, sizeof( transcript ), &transcript_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_tls13_create_psk_binder( ssl, hash_alg,
|
||||
psk, psk_len, psk_type,
|
||||
transcript, buf + 1 );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_create_psk_binder", ret );
|
||||
return( ret );
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "write binder", buf, 1 + binder_len );
|
||||
|
||||
*out_len = 1 + binder_len;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* mbedtls_ssl_tls13_write_pre_shared_key_ext() structure:
|
||||
* mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext() structure:
|
||||
*
|
||||
* struct {
|
||||
* opaque identity<1..2^16-1>;
|
||||
|
@ -689,125 +881,105 @@ static int ssl_tls13_write_psk_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
|
|||
* } PreSharedKeyExtension;
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
|
||||
int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
|
||||
mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf, unsigned char *end,
|
||||
size_t *out_len, size_t *binders_len )
|
||||
mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end,
|
||||
size_t *out_len, size_t *binders_len )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int configured_psk_count = 0;
|
||||
unsigned char *p = buf;
|
||||
const unsigned char *psk;
|
||||
size_t psk_len;
|
||||
const unsigned char *psk_identity;
|
||||
size_t psk_identity_len;
|
||||
int psk_type;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
|
||||
const int *ciphersuites;
|
||||
psa_algorithm_t psa_hash_alg;
|
||||
int hash_len = 0;
|
||||
size_t identities_len, l_binders_len;
|
||||
uint32_t obfuscated_ticket_age = 0;
|
||||
psa_algorithm_t hash_alg;
|
||||
const unsigned char *identity;
|
||||
size_t identity_len;
|
||||
size_t l_binders_len = 0;
|
||||
size_t output_len;
|
||||
|
||||
*out_len = 0;
|
||||
*binders_len = 0;
|
||||
|
||||
/* Check if we have any PSKs to offer. If so, return the first.
|
||||
*
|
||||
* NOTE: Ultimately, we want to be able to offer multiple PSKs,
|
||||
* in which case we want to iterate over them here.
|
||||
*
|
||||
* As it stands, however, we only ever offer one, chosen
|
||||
* by the following heuristic:
|
||||
* - If a ticket has been configured, offer the corresponding PSK.
|
||||
* - If no ticket has been configured by an external PSK has been
|
||||
* configured, offer that.
|
||||
* - Otherwise, skip the PSK extension.
|
||||
*/
|
||||
|
||||
if( mbedtls_ssl_get_psk_to_offer( ssl, &psk_type, &psk, &psk_len,
|
||||
&psk_identity, &psk_identity_len ) != 0 )
|
||||
/* Check if we have any PSKs to offer. If no, skip pre_shared_key */
|
||||
configured_psk_count = ssl_tls13_get_configured_psk_count( ssl );
|
||||
if( configured_psk_count == 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip pre_shared_key extensions" ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( psk_type == MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL )
|
||||
{
|
||||
/*
|
||||
* Ciphersuite list
|
||||
*/
|
||||
ciphersuites = ssl->conf->ciphersuite_list;
|
||||
for( int i = 0; ciphersuites[i] != 0; i++ )
|
||||
{
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
|
||||
ciphersuites[i] );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "Pre-configured PSK number = %d",
|
||||
configured_psk_count ) );
|
||||
|
||||
if( mbedtls_ssl_validate_ciphersuite(
|
||||
ssl, ciphersuite_info,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3 ) != 0 )
|
||||
continue;
|
||||
|
||||
/* In this implementation we only add one pre-shared-key
|
||||
* extension.
|
||||
*/
|
||||
ssl->session_negotiate->ciphersuite = ciphersuites[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
|
||||
ssl->session_negotiate->ciphersuite );
|
||||
/* No suitable ciphersuite for the PSK */
|
||||
if( ciphersuite_info == NULL )
|
||||
return( 0 );
|
||||
|
||||
psa_hash_alg = mbedtls_psa_translate_md( ciphersuite_info->mac );
|
||||
hash_len = PSA_HASH_LENGTH( psa_hash_alg );
|
||||
if( hash_len == -1 )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
/* Check if we have space to write the extension, binder included.
|
||||
/* Check if we have space to write the extension, binders included.
|
||||
* - extension_type (2 bytes)
|
||||
* - extension_data_len (2 bytes)
|
||||
* - identities_len (2 bytes)
|
||||
* - identity_len (2 bytes)
|
||||
* - identity (psk_identity_len bytes)
|
||||
* - obfuscated_ticket_age (4 bytes)
|
||||
* - binders_len (2 bytes)
|
||||
* - binder_len (1 byte)
|
||||
* - binder (hash_len bytes)
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
|
||||
p += 6;
|
||||
|
||||
identities_len = 6 + psk_identity_len;
|
||||
l_binders_len = 1 + hash_len;
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( ssl_tls13_ticket_get_identity(
|
||||
ssl, &hash_alg, &identity, &identity_len ) == 0 )
|
||||
{
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t now = mbedtls_time( NULL );
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
uint32_t obfuscated_ticket_age =
|
||||
(uint32_t)( now - session->ticket_received );
|
||||
|
||||
obfuscated_ticket_age *= 1000;
|
||||
obfuscated_ticket_age += session->ticket_age_add;
|
||||
|
||||
ret = ssl_tls13_write_identity( ssl, p, end,
|
||||
identity, identity_len,
|
||||
obfuscated_ticket_age,
|
||||
&output_len );
|
||||
#else
|
||||
ret = ssl_tls13_write_identity( ssl, p, end, identity, identity_len,
|
||||
0, &output_len );
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
p += output_len;
|
||||
l_binders_len += 1 + PSA_HASH_LENGTH( hash_alg );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
if( ssl_tls13_psk_get_identity(
|
||||
ssl, &hash_alg, &identity, &identity_len ) == 0 )
|
||||
{
|
||||
|
||||
ret = ssl_tls13_write_identity( ssl, p, end, identity, identity_len, 0,
|
||||
&output_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
p += output_len;
|
||||
l_binders_len += 1 + PSA_HASH_LENGTH( hash_alg );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3,
|
||||
( "client hello, adding pre_shared_key extension, "
|
||||
"omitting PSK binder list" ) );
|
||||
|
||||
/* Extension header */
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 8 );
|
||||
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_PRE_SHARED_KEY, p, 0 );
|
||||
MBEDTLS_PUT_UINT16_BE( 2 + identities_len + 2 + l_binders_len , p, 2 );
|
||||
/* Take into account the two bytes for the length of the binders. */
|
||||
l_binders_len += 2;
|
||||
/* Check if there is enough space for binders */
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, l_binders_len );
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE( identities_len, p, 4 );
|
||||
MBEDTLS_PUT_UINT16_BE( psk_identity_len, p, 6 );
|
||||
p += 8;
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, psk_identity_len );
|
||||
memcpy( p, psk_identity, psk_identity_len );
|
||||
p += psk_identity_len;
|
||||
/*
|
||||
* - extension_type (2 bytes)
|
||||
* - extension_data_len (2 bytes)
|
||||
* - identities_len (2 bytes)
|
||||
*/
|
||||
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_PRE_SHARED_KEY, buf, 0 );
|
||||
MBEDTLS_PUT_UINT16_BE( p - buf - 4 + l_binders_len , buf, 2 );
|
||||
MBEDTLS_PUT_UINT16_BE( p - buf - 6 , buf, 4 );
|
||||
|
||||
/* add obfuscated ticket age */
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
|
||||
MBEDTLS_PUT_UINT32_BE( obfuscated_ticket_age, p, 0 );
|
||||
p += 4;
|
||||
*out_len = ( p - buf ) + l_binders_len;
|
||||
*binders_len = l_binders_len;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 + l_binders_len );
|
||||
*out_len = ( p - buf ) + l_binders_len + 2;
|
||||
*binders_len = l_binders_len + 2;
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key identities", buf, p - buf );
|
||||
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
|
||||
|
@ -815,68 +987,133 @@ int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
|
|||
}
|
||||
|
||||
int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
|
||||
mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf, unsigned char *end )
|
||||
mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *p = buf;
|
||||
const unsigned char *psk_identity;
|
||||
size_t psk_identity_len;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
|
||||
psa_algorithm_t psa_hash_alg;
|
||||
int hash_len = 0;
|
||||
const unsigned char *psk = NULL;
|
||||
size_t psk_len = 0;
|
||||
int psk_type;
|
||||
unsigned char transcript[MBEDTLS_MD_MAX_SIZE];
|
||||
size_t transcript_len;
|
||||
psa_algorithm_t hash_alg = PSA_ALG_NONE;
|
||||
const unsigned char *psk;
|
||||
size_t psk_len;
|
||||
size_t output_len;
|
||||
|
||||
if( mbedtls_ssl_get_psk_to_offer( ssl, &psk_type, &psk, &psk_len,
|
||||
&psk_identity, &psk_identity_len ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
|
||||
ssl->session_negotiate->ciphersuite );
|
||||
if( ciphersuite_info == NULL )
|
||||
return( 0 );
|
||||
|
||||
psa_hash_alg = mbedtls_psa_translate_md( ciphersuite_info->mac );
|
||||
hash_len = PSA_HASH_LENGTH( psa_hash_alg );
|
||||
if( ( hash_len == -1 ) || ( ( end - buf ) != 3 + hash_len ) )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding PSK binder list" ) );
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 3 + hash_len );
|
||||
/* 2 bytes length field for array of psk binders */
|
||||
MBEDTLS_PUT_UINT16_BE( hash_len + 1, p, 0 );
|
||||
/* Check if we have space to write binders_len.
|
||||
* - binders_len (2 bytes)
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
|
||||
p += 2;
|
||||
|
||||
/* 1 bytes length field for next psk binder */
|
||||
*p++ = MBEDTLS_BYTE_0( hash_len );
|
||||
|
||||
/* Get current state of handshake transcript. */
|
||||
ret = mbedtls_ssl_get_handshake_transcript( ssl, ciphersuite_info->mac,
|
||||
transcript, sizeof( transcript ),
|
||||
&transcript_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_tls13_create_psk_binder( ssl,
|
||||
mbedtls_psa_translate_md( ciphersuite_info->mac ),
|
||||
psk, psk_len, psk_type,
|
||||
transcript, p );
|
||||
if( ret != 0 )
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( ssl_tls13_ticket_get_psk( ssl, &hash_alg, &psk, &psk_len ) == 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_create_psk_binder", ret );
|
||||
return( ret );
|
||||
|
||||
ret = ssl_tls13_write_binder( ssl, p, end,
|
||||
MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION,
|
||||
hash_alg, psk, psk_len,
|
||||
&output_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
p += output_len;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
if( ssl_tls13_psk_get_psk( ssl, &hash_alg, &psk, &psk_len ) == 0 )
|
||||
{
|
||||
|
||||
ret = ssl_tls13_write_binder( ssl, p, end,
|
||||
MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL,
|
||||
hash_alg, psk, psk_len,
|
||||
&output_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
p += output_len;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding PSK binder list." ) );
|
||||
|
||||
/*
|
||||
* - binders_len (2 bytes)
|
||||
*/
|
||||
MBEDTLS_PUT_UINT16_BE( p - buf - 2, buf, 0 );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key binders", buf, p - buf );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
/*
|
||||
* struct {
|
||||
* opaque identity<1..2^16-1>;
|
||||
* uint32 obfuscated_ticket_age;
|
||||
* } PskIdentity;
|
||||
*
|
||||
* opaque PskBinderEntry<32..255>;
|
||||
*
|
||||
* struct {
|
||||
*
|
||||
* select (Handshake.msg_type) {
|
||||
* ...
|
||||
* case server_hello: uint16 selected_identity;
|
||||
* };
|
||||
*
|
||||
* } PreSharedKeyExtension;
|
||||
*
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_parse_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int selected_identity;
|
||||
const unsigned char *psk;
|
||||
size_t psk_len;
|
||||
psa_algorithm_t hash_alg;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( buf, end, 2 );
|
||||
selected_identity = MBEDTLS_GET_UINT16_BE( buf, 0 );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected_identity = %d", selected_identity ) );
|
||||
|
||||
if( selected_identity >= ssl_tls13_get_configured_psk_count( ssl ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Invalid PSK identity." ) );
|
||||
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
|
||||
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
|
||||
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( selected_identity == 0 && ssl_tls13_has_configured_ticket( ssl ) )
|
||||
{
|
||||
ret = ssl_tls13_ticket_get_psk( ssl, &hash_alg, &psk, &psk_len );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( mbedtls_ssl_conf_has_static_psk( ssl->conf ) )
|
||||
{
|
||||
ret = ssl_tls13_psk_get_psk( ssl, &hash_alg, &psk, &psk_len );
|
||||
}
|
||||
else
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_set_hs_psk( ssl, psk, psk_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_set_hs_psk", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#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,
|
||||
|
@ -906,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 );
|
||||
|
@ -913,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.
|
||||
*
|
||||
|
@ -928,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;
|
||||
|
||||
|
@ -1234,92 +1473,6 @@ static int ssl_tls13_check_server_hello_session_id_echo( mbedtls_ssl_context *ss
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
/*
|
||||
* struct {
|
||||
* opaque identity<1..2^16-1>;
|
||||
* uint32 obfuscated_ticket_age;
|
||||
* } PskIdentity;
|
||||
*
|
||||
* opaque PskBinderEntry<32..255>;
|
||||
*
|
||||
* struct {
|
||||
*
|
||||
* select (Handshake.msg_type) {
|
||||
* ...
|
||||
* case server_hello: uint16 selected_identity;
|
||||
* };
|
||||
*
|
||||
* } PreSharedKeyExtension;
|
||||
*
|
||||
*/
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_parse_server_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t selected_identity;
|
||||
|
||||
const unsigned char *psk;
|
||||
size_t psk_len;
|
||||
const unsigned char *psk_identity;
|
||||
size_t psk_identity_len;
|
||||
|
||||
|
||||
/* Check which PSK we've offered.
|
||||
*
|
||||
* NOTE: Ultimately, we want to offer multiple PSKs, and in this
|
||||
* case, we need to iterate over them here.
|
||||
*/
|
||||
if( mbedtls_ssl_get_psk_to_offer( ssl, NULL, &psk, &psk_len,
|
||||
&psk_identity, &psk_identity_len ) != 0 )
|
||||
{
|
||||
/* If we haven't offered a PSK, the server must not send
|
||||
* a PSK identity extension. */
|
||||
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 2 );
|
||||
selected_identity = MBEDTLS_GET_UINT16_BE( buf, 0 );
|
||||
|
||||
/* We have offered only one PSK, so the only valid choice
|
||||
* for the server is PSK index 0.
|
||||
*
|
||||
* This will change once we support multiple PSKs. */
|
||||
if( selected_identity > 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server's chosen PSK identity out of range" ) );
|
||||
|
||||
if( ( ret = mbedtls_ssl_send_alert_message( ssl,
|
||||
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
|
||||
}
|
||||
|
||||
/* Set the chosen PSK
|
||||
*
|
||||
* TODO: We don't have to do this in case we offered 0-RTT and the
|
||||
* server accepted it, because in this case we've already
|
||||
* set the handshake PSK. */
|
||||
ret = mbedtls_ssl_set_hs_psk( ssl, psk, psk_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_set_hs_psk", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Parse ServerHello message and configure context
|
||||
*
|
||||
* struct {
|
||||
|
@ -1530,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 )
|
||||
|
@ -1547,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" ) );
|
||||
|
@ -1602,6 +1755,23 @@ cleanup:
|
|||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
static const char *ssl_tls13_get_kex_mode_str(int mode)
|
||||
{
|
||||
switch( mode )
|
||||
{
|
||||
case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK:
|
||||
return "psk";
|
||||
case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL:
|
||||
return "ephemeral";
|
||||
case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL:
|
||||
return "psk_ephemeral";
|
||||
default:
|
||||
return "unknown mode";
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
|
@ -1641,6 +1811,19 @@ static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl )
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if( !mbedtls_ssl_conf_tls13_check_kex_modes( ssl, handshake->key_exchange_mode ) )
|
||||
{
|
||||
ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2,
|
||||
( "Key exchange mode(%s) is not supported.",
|
||||
ssl_tls13_get_kex_mode_str( handshake->key_exchange_mode ) ) );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3,
|
||||
( "Selected key exchange mode: %s",
|
||||
ssl_tls13_get_kex_mode_str( handshake->key_exchange_mode ) ) );
|
||||
|
||||
/* Start the TLS 1.3 key schedule: Set the PSK and derive early secret.
|
||||
*
|
||||
* TODO: We don't have to do this in case we offered 0-RTT and the
|
||||
|
@ -1819,7 +2002,12 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl,
|
|||
*/
|
||||
switch( extension_type )
|
||||
{
|
||||
case MBEDTLS_TLS_EXT_SERVERNAME:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found server_name extension" ) );
|
||||
|
||||
/* The server_name extension should be an empty extension */
|
||||
|
||||
break;
|
||||
case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extensions supported groups" ) );
|
||||
break;
|
||||
|
@ -1879,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
|
||||
|
@ -1896,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
|
||||
*
|
||||
|
@ -2133,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
|
||||
|
@ -2179,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 );
|
||||
|
@ -2209,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
|
||||
*/
|
||||
|
@ -2223,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
|
||||
|
@ -2237,11 +2425,11 @@ static int ssl_tls13_write_client_finished( mbedtls_ssl_context *ssl )
|
|||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_tls13_generate_resumption_master_secret( ssl );
|
||||
ret = mbedtls_ssl_tls13_compute_resumption_master_secret( ssl );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1,
|
||||
"mbedtls_ssl_tls13_generate_resumption_master_secret ", ret );
|
||||
"mbedtls_ssl_tls13_compute_resumption_master_secret ", ret );
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
|
@ -2405,6 +2593,9 @@ static int ssl_tls13_parse_new_session_ticket( mbedtls_ssl_context *ssl,
|
|||
return( ret );
|
||||
}
|
||||
|
||||
/* session has been updated, allow export */
|
||||
session->exported = 0;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -2533,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;
|
||||
|
@ -2545,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 );
|
||||
|
@ -2555,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),
|
||||
|
@ -906,12 +906,8 @@ int mbedtls_ssl_tls13_check_sig_alg_cert_key_match( uint16_t sig_alg,
|
|||
case MBEDTLS_SSL_SIG_RSA:
|
||||
switch( sig_alg )
|
||||
{
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
return( key_size <= 3072 );
|
||||
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
return( key_size <= 7680 );
|
||||
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: /* Intentional fallthrough */
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: /* Intentional fallthrough */
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
return( 1 );
|
||||
|
||||
|
@ -927,43 +923,13 @@ int mbedtls_ssl_tls13_check_sig_alg_cert_key_match( uint16_t sig_alg,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_select_sig_alg_for_certificate_verify(
|
||||
mbedtls_ssl_context *ssl,
|
||||
mbedtls_pk_context *own_key,
|
||||
uint16_t *algorithm )
|
||||
{
|
||||
uint16_t *sig_alg = ssl->handshake->received_sig_algs;
|
||||
|
||||
*algorithm = MBEDTLS_TLS1_3_SIG_NONE;
|
||||
for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE ; sig_alg++ )
|
||||
{
|
||||
if( mbedtls_ssl_sig_alg_is_offered( ssl, *sig_alg ) &&
|
||||
mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported( *sig_alg ) &&
|
||||
mbedtls_ssl_tls13_check_sig_alg_cert_key_match( *sig_alg, own_key ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3,
|
||||
( "select_sig_alg_for_certificate_verify:"
|
||||
"selected signature algorithm %s [%04x]",
|
||||
mbedtls_ssl_sig_alg_to_str( *sig_alg ),
|
||||
*sig_alg ) );
|
||||
*algorithm = *sig_alg;
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2,
|
||||
( "select_sig_alg_for_certificate_verify:"
|
||||
"no suitable signature algorithm found" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_write_certificate_verify_body( mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
unsigned char *end,
|
||||
size_t *out_len )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *p = buf;
|
||||
mbedtls_pk_context *own_key;
|
||||
|
||||
|
@ -971,14 +937,9 @@ static int ssl_tls13_write_certificate_verify_body( mbedtls_ssl_context *ssl,
|
|||
size_t handshake_hash_len;
|
||||
unsigned char verify_buffer[ SSL_VERIFY_STRUCT_MAX_SIZE ];
|
||||
size_t verify_buffer_len;
|
||||
mbedtls_pk_type_t pk_type = MBEDTLS_PK_NONE;
|
||||
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
|
||||
psa_algorithm_t psa_algorithm = PSA_ALG_NONE;
|
||||
uint16_t algorithm = MBEDTLS_TLS1_3_SIG_NONE;
|
||||
|
||||
uint16_t *sig_alg = ssl->handshake->received_sig_algs;
|
||||
size_t signature_len = 0;
|
||||
unsigned char verify_hash[ MBEDTLS_MD_MAX_SIZE ];
|
||||
size_t verify_hash_len;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
*out_len = 0;
|
||||
|
||||
|
@ -1011,64 +972,84 @@ static int ssl_tls13_write_certificate_verify_body( mbedtls_ssl_context *ssl,
|
|||
* opaque signature<0..2^16-1>;
|
||||
* } CertificateVerify;
|
||||
*/
|
||||
ret = ssl_tls13_select_sig_alg_for_certificate_verify( ssl, own_key,
|
||||
&algorithm );
|
||||
if( ret != 0 )
|
||||
/* Check there is space for the algorithm identifier (2 bytes) and the
|
||||
* signature length (2 bytes).
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
|
||||
|
||||
for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE ; sig_alg++ )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1,
|
||||
( "signature algorithm not in received or offered list." ) );
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_pk_type_t pk_type = MBEDTLS_PK_NONE;
|
||||
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
|
||||
psa_algorithm_t psa_algorithm = PSA_ALG_NONE;
|
||||
unsigned char verify_hash[PSA_HASH_MAX_SIZE];
|
||||
size_t verify_hash_len;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Signature algorithm is %s",
|
||||
mbedtls_ssl_sig_alg_to_str( algorithm ) ) );
|
||||
if( !mbedtls_ssl_sig_alg_is_offered( ssl, *sig_alg ) )
|
||||
continue;
|
||||
|
||||
if( !mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported( *sig_alg ) )
|
||||
continue;
|
||||
|
||||
if( !mbedtls_ssl_tls13_check_sig_alg_cert_key_match( *sig_alg, own_key ) )
|
||||
continue;
|
||||
|
||||
if( mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(
|
||||
*sig_alg, &pk_type, &md_alg ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
|
||||
/* Hash verify buffer with indicated hash function */
|
||||
psa_algorithm = mbedtls_hash_info_psa_from_md( md_alg );
|
||||
status = psa_hash_compute( psa_algorithm,
|
||||
verify_buffer,
|
||||
verify_buffer_len,
|
||||
verify_hash, sizeof( verify_hash ),
|
||||
&verify_hash_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( psa_ssl_status_to_mbedtls( status ) );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "verify hash", verify_hash, verify_hash_len );
|
||||
|
||||
if( ( ret = mbedtls_pk_sign_ext( pk_type, own_key,
|
||||
md_alg, verify_hash, verify_hash_len,
|
||||
p + 4, (size_t)( end - ( p + 4 ) ), &signature_len,
|
||||
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "CertificateVerify signature failed with %s",
|
||||
mbedtls_ssl_sig_alg_to_str( *sig_alg ) ) );
|
||||
MBEDTLS_SSL_DEBUG_RET( 2, "mbedtls_pk_sign_ext", ret );
|
||||
|
||||
/* The signature failed. This is possible if the private key
|
||||
* was not suitable for the signature operation as purposely we
|
||||
* did not check its suitability completely. Let's try with
|
||||
* another signature algorithm.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "CertificateVerify signature with %s",
|
||||
mbedtls_ssl_sig_alg_to_str( *sig_alg ) ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if( *sig_alg == MBEDTLS_TLS1_3_SIG_NONE )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no suitable signature algorithm" ) );
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "CertificateVerify with %s",
|
||||
mbedtls_ssl_sig_alg_to_str( algorithm )) );
|
||||
MBEDTLS_PUT_UINT16_BE( *sig_alg, p, 0 );
|
||||
MBEDTLS_PUT_UINT16_BE( signature_len, p, 2 );
|
||||
|
||||
if( mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(
|
||||
algorithm, &pk_type, &md_alg ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
*out_len = 4 + signature_len;
|
||||
|
||||
/* Check there is space for the algorithm identifier (2 bytes) and the
|
||||
* signature length (2 bytes).
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
|
||||
MBEDTLS_PUT_UINT16_BE( algorithm, p, 0 );
|
||||
p += 2;
|
||||
|
||||
/* Hash verify buffer with indicated hash function */
|
||||
psa_algorithm = mbedtls_hash_info_psa_from_md( md_alg );
|
||||
status = psa_hash_compute( psa_algorithm,
|
||||
verify_buffer,
|
||||
verify_buffer_len,
|
||||
verify_hash,sizeof( verify_hash ),
|
||||
&verify_hash_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( psa_ssl_status_to_mbedtls( status ) );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "verify hash", verify_hash, verify_hash_len );
|
||||
|
||||
if( ( ret = mbedtls_pk_sign_ext( pk_type, own_key,
|
||||
md_alg, verify_hash, verify_hash_len,
|
||||
p + 2, (size_t)( end - ( p + 2 ) ), &signature_len,
|
||||
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE( signature_len, p, 0 );
|
||||
p += 2 + signature_len;
|
||||
|
||||
*out_len = (size_t)( p - buf );
|
||||
|
||||
return( ret );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_ssl_tls13_write_certificate_verify( mbedtls_ssl_context *ssl )
|
||||
|
@ -1097,7 +1078,7 @@ cleanup:
|
|||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -1361,7 +1342,7 @@ cleanup:
|
|||
int mbedtls_ssl_reset_transcript_for_hrr( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char hash_transcript[ MBEDTLS_MD_MAX_SIZE + 4 ];
|
||||
unsigned char hash_transcript[PSA_HASH_MAX_SIZE + 4];
|
||||
size_t hash_len;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
uint16_t cipher_suite = ssl->session_negotiate->ciphersuite;
|
||||
|
@ -1371,7 +1352,7 @@ int mbedtls_ssl_reset_transcript_for_hrr( mbedtls_ssl_context *ssl )
|
|||
|
||||
ret = mbedtls_ssl_get_handshake_transcript( ssl, ciphersuite_info->mac,
|
||||
hash_transcript + 4,
|
||||
MBEDTLS_MD_MAX_SIZE,
|
||||
PSA_HASH_MAX_SIZE,
|
||||
&hash_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
|
@ -1386,9 +1367,9 @@ int mbedtls_ssl_reset_transcript_for_hrr( mbedtls_ssl_context *ssl )
|
|||
|
||||
hash_len += 4;
|
||||
|
||||
#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA)
|
||||
if( ciphersuite_info->mac == MBEDTLS_MD_SHA256 )
|
||||
{
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "Truncated SHA-256 handshake transcript",
|
||||
hash_transcript, hash_len );
|
||||
|
||||
|
@ -1398,11 +1379,11 @@ int mbedtls_ssl_reset_transcript_for_hrr( mbedtls_ssl_context *ssl )
|
|||
#else
|
||||
mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 );
|
||||
#endif
|
||||
#endif /* MBEDTLS_SHA256_C */
|
||||
}
|
||||
else if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
|
||||
#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)
|
||||
if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
|
||||
{
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "Truncated SHA-384 handshake transcript",
|
||||
hash_transcript, hash_len );
|
||||
|
||||
|
@ -1412,12 +1393,11 @@ int mbedtls_ssl_reset_transcript_for_hrr( mbedtls_ssl_context *ssl )
|
|||
#else
|
||||
mbedtls_sha512_starts( &ssl->handshake->fin_sha384, 1 );
|
||||
#endif
|
||||
#endif /* MBEDTLS_SHA384_C */
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA384_C)
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
#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)
|
||||
ssl->handshake->update_checksum( ssl, hash_transcript, hash_len );
|
||||
#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA384_C */
|
||||
#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA || MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
@ -1505,41 +1485,4 @@ int mbedtls_ssl_tls13_generate_and_write_ecdh_key_exchange(
|
|||
}
|
||||
#endif /* MBEDTLS_ECDH_C */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
/* Check if we have any PSK to offer, returns 0 if PSK is available.
|
||||
* Assign the psk and ticket if pointers are present.
|
||||
*/
|
||||
int mbedtls_ssl_get_psk_to_offer(
|
||||
const mbedtls_ssl_context *ssl,
|
||||
int *psk_type,
|
||||
const unsigned char **psk, size_t *psk_len,
|
||||
const unsigned char **psk_identity, size_t *psk_identity_len )
|
||||
{
|
||||
int ptrs_present = 0;
|
||||
|
||||
if( psk_type != NULL && psk != NULL && psk_len != NULL &&
|
||||
psk_identity != NULL && psk_identity_len != NULL )
|
||||
{
|
||||
ptrs_present = 1;
|
||||
}
|
||||
|
||||
/* Check if an external PSK has been configured. */
|
||||
if( ssl->conf->psk != NULL )
|
||||
{
|
||||
if( ptrs_present )
|
||||
{
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
|
||||
*psk = ssl->conf->psk;
|
||||
*psk_len = ssl->conf->psk_len;
|
||||
*psk_identity = ssl->conf->psk_identity;
|
||||
*psk_identity_len = ssl->conf->psk_identity_len;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
|
|
@ -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
|
||||
|
@ -1504,12 +1520,43 @@ cleanup:
|
|||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_ssl_tls13_generate_resumption_master_secret(
|
||||
mbedtls_ssl_context *ssl )
|
||||
int mbedtls_ssl_tls13_compute_resumption_master_secret( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_md_type_t md_type;
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
|
||||
size_t transcript_len;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2,
|
||||
( "=> mbedtls_ssl_tls13_compute_resumption_master_secret" ) );
|
||||
|
||||
md_type = handshake->ciphersuite_info->mac;
|
||||
|
||||
ret = mbedtls_ssl_get_handshake_transcript( ssl, md_type,
|
||||
transcript, sizeof( transcript ),
|
||||
&transcript_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_tls13_derive_resumption_master_secret(
|
||||
mbedtls_psa_translate_md( md_type ),
|
||||
handshake->tls13_master_secrets.app,
|
||||
transcript, transcript_len,
|
||||
&ssl->session_negotiate->app_secrets );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Erase master secrets */
|
||||
mbedtls_platform_zeroize( &ssl->handshake->tls13_master_secrets,
|
||||
sizeof( ssl->handshake->tls13_master_secrets ) );
|
||||
mbedtls_platform_zeroize( &handshake->tls13_master_secrets,
|
||||
sizeof( handshake->tls13_master_secrets ) );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "Resumption master secret",
|
||||
ssl->session_negotiate->app_secrets.resumption_master_secret,
|
||||
PSA_HASH_LENGTH( mbedtls_psa_translate_md( md_type ) ) ) ;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2,
|
||||
( "<= mbedtls_ssl_tls13_compute_resumption_master_secret" ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -1567,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 )
|
||||
|
@ -1608,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 */
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ extern const struct mbedtls_ssl_tls13_labels_struct mbedtls_ssl_tls13_labels;
|
|||
* Since contexts are always hashes of message transcripts, this can
|
||||
* be approximated from above by the maximum hash size. */
|
||||
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN \
|
||||
MBEDTLS_MD_MAX_SIZE
|
||||
PSA_HASH_MAX_SIZE
|
||||
|
||||
/* Maximum desired length for expanded key material generated
|
||||
* by HKDF-Expand-Label.
|
||||
|
@ -636,8 +636,7 @@ int mbedtls_ssl_tls13_generate_application_keys(
|
|||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_generate_resumption_master_secret(
|
||||
mbedtls_ssl_context *ssl );
|
||||
int mbedtls_ssl_tls13_compute_resumption_master_secret( mbedtls_ssl_context *ssl );
|
||||
|
||||
/**
|
||||
* \brief Calculate the verify_data value for the client or server TLS 1.3
|
||||
|
@ -692,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
|
||||
*
|
||||
|
@ -708,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 */
|
||||
|
||||
|
|
|
@ -34,13 +34,7 @@
|
|||
#include "mbedtls/ecp.h"
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
|
||||
#include "ssl_misc.h"
|
||||
#include "ssl_tls13_keys.h"
|
||||
|
@ -65,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;
|
||||
|
@ -121,14 +115,170 @@ static int ssl_tls13_parse_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
|
|||
|
||||
#define SSL_TLS1_3_OFFERED_PSK_NOT_MATCH 1
|
||||
#define SSL_TLS1_3_OFFERED_PSK_MATCH 0
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *identity,
|
||||
size_t identity_len,
|
||||
uint32_t obfuscated_ticket_age,
|
||||
mbedtls_ssl_session *session )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *ticket_buffer;
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t now;
|
||||
uint64_t age_in_s;
|
||||
int64_t age_diff_in_ms;
|
||||
#endif
|
||||
|
||||
((void) obfuscated_ticket_age);
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> check_identity_match_ticket" ) );
|
||||
|
||||
/* Ticket parser is not configured, Skip */
|
||||
if( ssl->conf->f_ticket_parse == NULL || identity_len == 0 )
|
||||
return( 0 );
|
||||
|
||||
/* We create a copy of the encrypted ticket since the ticket parsing
|
||||
* function is allowed to use its input buffer as an output buffer
|
||||
* (in-place decryption). We do, however, need the original buffer for
|
||||
* computing the PSK binder value.
|
||||
*/
|
||||
ticket_buffer = mbedtls_calloc( 1, identity_len );
|
||||
if( ticket_buffer == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
|
||||
return ( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
}
|
||||
memcpy( ticket_buffer, identity, identity_len );
|
||||
|
||||
if( ( ret = ssl->conf->f_ticket_parse( ssl->conf->p_ticket,
|
||||
session,
|
||||
ticket_buffer, identity_len ) ) != 0 )
|
||||
{
|
||||
if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is not authentic" ) );
|
||||
else if( ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED )
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is expired" ) );
|
||||
else
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "ticket_parse", ret );
|
||||
}
|
||||
|
||||
/* We delete the temporary buffer */
|
||||
mbedtls_free( ticket_buffer );
|
||||
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
now = mbedtls_time( NULL );
|
||||
|
||||
if( now < session->start )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ( "Invalid ticket start time ( now=%" MBEDTLS_PRINTF_LONGLONG
|
||||
", start=%" MBEDTLS_PRINTF_LONGLONG " )",
|
||||
(long long)now, (long long)session->start ) );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
age_in_s = (uint64_t)( now - session->start );
|
||||
|
||||
/* RFC 8446 section 4.6.1
|
||||
*
|
||||
* Servers MUST NOT use any value greater than 604800 seconds (7 days).
|
||||
*
|
||||
* RFC 8446 section 4.2.11.1
|
||||
*
|
||||
* Clients MUST NOT attempt to use tickets which have ages greater than
|
||||
* the "ticket_lifetime" value which was provided with the ticket.
|
||||
*
|
||||
* For time being, the age MUST be less than 604800 seconds (7 days).
|
||||
*/
|
||||
if( age_in_s > 604800 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ( "Ticket age exceeds limitation ticket_age=%lu",
|
||||
(long unsigned int)age_in_s ) );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* RFC 8446 section 4.2.10
|
||||
*
|
||||
* For PSKs provisioned via NewSessionTicket, a server MUST validate that
|
||||
* the ticket age for the selected PSK identity (computed by subtracting
|
||||
* ticket_age_add from PskIdentity.obfuscated_ticket_age modulo 2^32) is
|
||||
* within a small tolerance of the time since the ticket was issued.
|
||||
*
|
||||
* NOTE: When `now == session->start`, `age_diff_in_ms` may be negative
|
||||
* as the age units are different on the server (s) and in the
|
||||
* client (ms) side. Add a -1000 ms tolerance window to take this
|
||||
* into account.
|
||||
*/
|
||||
age_diff_in_ms = age_in_s * 1000;
|
||||
age_diff_in_ms -= ( obfuscated_ticket_age - session->ticket_age_add );
|
||||
if( age_diff_in_ms <= -1000 ||
|
||||
age_diff_in_ms > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ( "Ticket age outside tolerance window ( diff=%d )",
|
||||
(int)age_diff_in_ms ) );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
exit:
|
||||
if( ret != 0 )
|
||||
mbedtls_ssl_session_free( session );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= check_identity_match_ticket" ) );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_offered_psks_check_identity_match(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *identity,
|
||||
size_t identity_len,
|
||||
int *psk_type )
|
||||
uint32_t obfuscated_ticket_age,
|
||||
int *psk_type,
|
||||
mbedtls_ssl_session *session )
|
||||
{
|
||||
((void) session);
|
||||
((void) obfuscated_ticket_age);
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "identity", identity, identity_len );
|
||||
ssl->handshake->resume = 0;
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
ssl, identity, identity_len, obfuscated_ticket_age,
|
||||
session ) == SSL_TLS1_3_OFFERED_PSK_MATCH )
|
||||
{
|
||||
ssl->handshake->resume = 1;
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION;
|
||||
mbedtls_ssl_set_hs_psk( ssl,
|
||||
session->resumption_key,
|
||||
session->resumption_key_len );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "Ticket-resumed PSK:",
|
||||
session->resumption_key,
|
||||
session->resumption_key_len );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "ticket: obfuscated_ticket_age: %u",
|
||||
(unsigned)obfuscated_ticket_age ) );
|
||||
return( SSL_TLS1_3_OFFERED_PSK_MATCH );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
/* Check identity with external configured function */
|
||||
if( ssl->conf->f_psk != NULL )
|
||||
{
|
||||
|
@ -256,6 +406,7 @@ static int ssl_tls13_select_ciphersuite_for_psk(
|
|||
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_select_ciphersuite_for_resumption(
|
||||
mbedtls_ssl_context *ssl,
|
||||
|
@ -265,15 +416,46 @@ static int ssl_tls13_select_ciphersuite_for_resumption(
|
|||
uint16_t *selected_ciphersuite,
|
||||
const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info )
|
||||
{
|
||||
((void) ssl);
|
||||
((void) session);
|
||||
((void) cipher_suites);
|
||||
((void) cipher_suites_end);
|
||||
|
||||
*selected_ciphersuite = 0;
|
||||
*selected_ciphersuite_info = NULL;
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
for( const unsigned char *p = cipher_suites; p < cipher_suites_end; p += 2 )
|
||||
{
|
||||
uint16_t cipher_suite = MBEDTLS_GET_UINT16_BE( p, 0 );
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
if( cipher_suite != session->ciphersuite )
|
||||
continue;
|
||||
|
||||
ciphersuite_info = ssl_tls13_validate_peer_ciphersuite( ssl,
|
||||
cipher_suite );
|
||||
if( ciphersuite_info == NULL )
|
||||
continue;
|
||||
|
||||
*selected_ciphersuite = cipher_suite;
|
||||
*selected_ciphersuite_info = ciphersuite_info;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_session_copy_ticket( mbedtls_ssl_session *dst,
|
||||
const mbedtls_ssl_session *src )
|
||||
{
|
||||
dst->ticket_age_add = src->ticket_age_add;
|
||||
dst->ticket_flags = src->ticket_flags;
|
||||
dst->resumption_key_len = src->resumption_key_len;
|
||||
if( src->resumption_key_len == 0 )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
memcpy( dst->resumption_key, src->resumption_key, src->resumption_key_len );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
/* Parser for pre_shared_key extension in client hello
|
||||
* struct {
|
||||
* opaque identity<1..2^16-1>;
|
||||
|
@ -343,17 +525,23 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
{
|
||||
const unsigned char *identity;
|
||||
size_t identity_len;
|
||||
uint32_t obfuscated_ticket_age;
|
||||
const unsigned char *binder;
|
||||
size_t binder_len;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int psk_type;
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
mbedtls_ssl_session session;
|
||||
mbedtls_ssl_session_init( &session );
|
||||
#endif
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p_identity_len, identities_end, 2 + 1 + 4 );
|
||||
identity_len = MBEDTLS_GET_UINT16_BE( p_identity_len, 0 );
|
||||
identity = p_identity_len + 2;
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( identity, identities_end, identity_len + 4 );
|
||||
obfuscated_ticket_age = MBEDTLS_GET_UINT32_BE( identity , identity_len );
|
||||
p_identity_len += identity_len + 6;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p_binder_len, binders_end, 1 + 32 );
|
||||
|
@ -367,7 +555,8 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
continue;
|
||||
|
||||
ret = ssl_tls13_offered_psks_check_identity_match(
|
||||
ssl, identity, identity_len, &psk_type );
|
||||
ssl, identity, identity_len, obfuscated_ticket_age,
|
||||
&psk_type, &session );
|
||||
if( ret != SSL_TLS1_3_OFFERED_PSK_MATCH )
|
||||
continue;
|
||||
|
||||
|
@ -380,9 +569,15 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
&cipher_suite, &ciphersuite_info );
|
||||
break;
|
||||
case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION:
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
ret = ssl_tls13_select_ciphersuite_for_resumption(
|
||||
ssl, ciphersuites, ciphersuites_end, NULL,
|
||||
ssl, ciphersuites, ciphersuites_end, &session,
|
||||
&cipher_suite, &ciphersuite_info );
|
||||
if( ret != 0 )
|
||||
mbedtls_ssl_session_free( &session );
|
||||
#else
|
||||
ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
@ -406,6 +601,9 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
/* For security reasons, the handshake should be aborted when we
|
||||
* fail to validate a binder value. See RFC 8446 section 4.2.11.2
|
||||
* and appendix E.6. */
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
mbedtls_ssl_session_free( &session );
|
||||
#endif
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Invalid binder." ) );
|
||||
MBEDTLS_SSL_DEBUG_RET( 1,
|
||||
"ssl_tls13_offered_psks_check_binder_match" , ret );
|
||||
|
@ -418,11 +616,20 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
matched_identity = identity_id;
|
||||
|
||||
/* Update handshake parameters */
|
||||
ssl->session_negotiate->ciphersuite = cipher_suite;
|
||||
ssl->handshake->ciphersuite_info = ciphersuite_info;
|
||||
ssl->session_negotiate->ciphersuite = cipher_suite;
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "overwrite ciphersuite: %04x - %s",
|
||||
cipher_suite, ciphersuite_info->name ) );
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if( psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION )
|
||||
{
|
||||
ret = ssl_tls13_session_copy_ticket( ssl->session_negotiate,
|
||||
&session );
|
||||
mbedtls_ssl_session_free( &session );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
}
|
||||
|
||||
if( p_identity_len != identities_end || p_binder_len != binders_end )
|
||||
|
@ -467,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. */
|
||||
|
@ -494,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 {
|
||||
|
@ -786,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 )
|
||||
|
@ -808,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 )
|
||||
|
@ -820,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 ) );
|
||||
|
@ -833,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 ) );
|
||||
|
@ -897,7 +1106,37 @@ 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 )
|
||||
{
|
||||
switch( sig_alg )
|
||||
{
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
|
||||
return( PSA_ALG_ECDSA( PSA_ALG_SHA_256 ) );
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
|
||||
return( PSA_ALG_ECDSA( PSA_ALG_SHA_384 ) );
|
||||
case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
|
||||
return( PSA_ALG_ECDSA( PSA_ALG_SHA_512 ) );
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
return( PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ) );
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
return( PSA_ALG_RSA_PSS( PSA_ALG_SHA_384 ) );
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
return( PSA_ALG_RSA_PSS( PSA_ALG_SHA_512 ) );
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
|
||||
return( PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_256 ) );
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
|
||||
return( PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_384 ) );
|
||||
case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
|
||||
return( PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_512 ) );
|
||||
default:
|
||||
return( PSA_ALG_NONE );
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
/*
|
||||
* Pick best ( private key, certificate chain ) pair based on the signature
|
||||
* algorithms supported by the client.
|
||||
|
@ -923,9 +1162,19 @@ static int ssl_tls13_pick_key_cert( mbedtls_ssl_context *ssl )
|
|||
|
||||
for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
|
||||
{
|
||||
if( !mbedtls_ssl_sig_alg_is_offered( ssl, *sig_alg ) )
|
||||
continue;
|
||||
|
||||
if( !mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported( *sig_alg ) )
|
||||
continue;
|
||||
|
||||
for( key_cert = key_cert_list; key_cert != NULL;
|
||||
key_cert = key_cert->next )
|
||||
{
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_algorithm_t psa_alg = PSA_ALG_NONE;
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
MBEDTLS_SSL_DEBUG_CRT( 3, "certificate (chain) candidate",
|
||||
key_cert->cert );
|
||||
|
||||
|
@ -949,8 +1198,18 @@ static int ssl_tls13_pick_key_cert( mbedtls_ssl_context *ssl )
|
|||
"check signature algorithm %s [%04x]",
|
||||
mbedtls_ssl_sig_alg_to_str( *sig_alg ),
|
||||
*sig_alg ) );
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_alg = ssl_tls13_iana_sig_alg_to_psa_alg( *sig_alg );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if( mbedtls_ssl_tls13_check_sig_alg_cert_key_match(
|
||||
*sig_alg, &key_cert->cert->pk ) )
|
||||
*sig_alg, &key_cert->cert->pk )
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
&& psa_alg != PSA_ALG_NONE &&
|
||||
mbedtls_pk_can_do_ext( &key_cert->cert->pk, psa_alg,
|
||||
PSA_KEY_USAGE_SIGN_HASH ) == 1
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
)
|
||||
{
|
||||
ssl->handshake->key_cert = key_cert;
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3,
|
||||
|
@ -972,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 */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -1032,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;
|
||||
|
||||
|
@ -1143,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;
|
||||
|
@ -1324,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" ) );
|
||||
|
||||
|
@ -1339,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" ) );
|
||||
|
@ -1351,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;
|
||||
|
||||
|
@ -1377,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" ) );
|
||||
|
||||
|
@ -1392,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,
|
||||
|
@ -1412,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.
|
||||
|
@ -1441,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 );
|
||||
}
|
||||
|
@ -1674,6 +1933,10 @@ static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
|
|||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding key share extension" ) );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, write selected_group: %s (%04x)",
|
||||
mbedtls_ssl_named_group_to_str( group ),
|
||||
group ) );
|
||||
|
||||
/* Check if we have space for header and length fields:
|
||||
* - extension_type (2 bytes)
|
||||
* - extension_data_length (2 bytes)
|
||||
|
@ -1893,8 +2156,8 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
|
|||
p += output_len;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
if( mbedtls_ssl_tls13_key_exchange_mode_with_psk( ssl ) )
|
||||
#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 );
|
||||
if( ret != 0 )
|
||||
|
@ -1905,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 );
|
||||
|
||||
|
@ -2129,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
|
||||
|
@ -2144,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:
|
||||
|
@ -2168,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;
|
||||
|
||||
|
@ -2312,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
|
||||
|
@ -2362,11 +2628,11 @@ static int ssl_tls13_process_client_finished( mbedtls_ssl_context *ssl )
|
|||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_tls13_generate_resumption_master_secret( ssl );
|
||||
ret = mbedtls_ssl_tls13_compute_resumption_master_secret( ssl );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1,
|
||||
"mbedtls_ssl_tls13_generate_resumption_master_secret ", ret );
|
||||
"mbedtls_ssl_tls13_compute_resumption_master_secret", ret );
|
||||
}
|
||||
|
||||
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP );
|
||||
|
@ -2402,7 +2668,21 @@ static int ssl_tls13_write_new_session_ticket_coordinate( mbedtls_ssl_context *s
|
|||
/* Check whether the use of session tickets is enabled */
|
||||
if( ssl->conf->f_ticket_write == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "new session ticket is not enabled" ) );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "NewSessionTicket: disabled,"
|
||||
" callback is not set" ) );
|
||||
return( SSL_NEW_SESSION_TICKET_SKIP );
|
||||
}
|
||||
if( ssl->conf->new_session_tickets_count == 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "NewSessionTicket: disabled,"
|
||||
" configured count is zero" ) );
|
||||
return( SSL_NEW_SESSION_TICKET_SKIP );
|
||||
}
|
||||
|
||||
if( ssl->handshake->new_session_tickets_count == 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "NewSessionTicket: all tickets have "
|
||||
"been sent." ) );
|
||||
return( SSL_NEW_SESSION_TICKET_SKIP );
|
||||
}
|
||||
|
||||
|
@ -2567,7 +2847,8 @@ static int ssl_tls13_write_new_session_ticket_body( mbedtls_ssl_context *ssl,
|
|||
* MAY treat a ticket as valid for a shorter period of time than what
|
||||
* is stated in the ticket_lifetime.
|
||||
*/
|
||||
ticket_lifetime %= 604800;
|
||||
if( ticket_lifetime > 604800 )
|
||||
ticket_lifetime = 604800;
|
||||
MBEDTLS_PUT_UINT32_BE( ticket_lifetime, p, 0 );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket_lifetime: %u",
|
||||
( unsigned int )ticket_lifetime ) );
|
||||
|
@ -2635,6 +2916,15 @@ static int ssl_tls13_write_new_session_ticket( mbedtls_ssl_context *ssl )
|
|||
MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg(
|
||||
ssl, buf_len, msg_len ) );
|
||||
|
||||
/* Limit session tickets count to one when resumption connection.
|
||||
*
|
||||
* See document of mbedtls_ssl_conf_new_session_tickets.
|
||||
*/
|
||||
if( ssl->handshake->resume == 1 )
|
||||
ssl->handshake->new_session_tickets_count = 0;
|
||||
else
|
||||
ssl->handshake->new_session_tickets_count--;
|
||||
|
||||
mbedtls_ssl_handshake_set_state( ssl,
|
||||
MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH );
|
||||
}
|
||||
|
@ -2699,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;
|
||||
|
@ -2711,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
|
||||
|
@ -2742,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 )
|
||||
|
@ -2768,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:
|
||||
|
@ -2785,7 +3077,11 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
|
|||
* as part of ssl_prepare_handshake_step.
|
||||
*/
|
||||
ret = 0;
|
||||
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER );
|
||||
|
||||
if( ssl->handshake->new_session_tickets_count == 0 )
|
||||
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER );
|
||||
else
|
||||
mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_NEW_SESSION_TICKET );
|
||||
break;
|
||||
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
|
|
@ -43,16 +43,7 @@
|
|||
#include "mbedtls/pem.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_snprintf snprintf
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#include "mbedtls/platform_time.h"
|
||||
|
@ -62,7 +53,7 @@
|
|||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include "legacy_or_psa.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
|
||||
#define CHECK(code) if( ( ret = ( code ) ) != 0 ){ return( ret ); }
|
||||
#define CHECK_RANGE(min, max, val) \
|
||||
|
@ -468,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 )
|
||||
|
@ -475,6 +471,7 @@ 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;
|
||||
|
||||
/* don't use recursion, we'd risk stack overflow if not optimized */
|
||||
while( 1 )
|
||||
|
@ -484,14 +481,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;
|
||||
|
@ -502,7 +502,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;
|
||||
}
|
||||
|
@ -516,10 +519,20 @@ 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 */
|
||||
mbedtls_asn1_free_named_data_list_shallow( head->next );
|
||||
head->next = NULL;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static int x509_parse_int( unsigned char **p, size_t n, int *res )
|
||||
|
|
|
@ -42,15 +42,7 @@
|
|||
#include "mbedtls/pem.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_snprintf snprintf
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
||||
|
@ -713,28 +705,16 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
|
|||
{
|
||||
mbedtls_x509_crl *crl_cur = crl;
|
||||
mbedtls_x509_crl *crl_prv;
|
||||
mbedtls_x509_name *name_cur;
|
||||
mbedtls_x509_name *name_prv;
|
||||
mbedtls_x509_crl_entry *entry_cur;
|
||||
mbedtls_x509_crl_entry *entry_prv;
|
||||
|
||||
if( crl == NULL )
|
||||
return;
|
||||
|
||||
do
|
||||
while( crl_cur != NULL )
|
||||
{
|
||||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
||||
mbedtls_free( crl_cur->sig_opts );
|
||||
#endif
|
||||
|
||||
name_cur = crl_cur->issuer.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
|
||||
mbedtls_free( name_prv );
|
||||
}
|
||||
mbedtls_asn1_free_named_data_list_shallow( crl_cur->issuer.next );
|
||||
|
||||
entry_cur = crl_cur->entry.next;
|
||||
while( entry_cur != NULL )
|
||||
|
@ -752,13 +732,6 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
|
|||
mbedtls_free( crl_cur->raw.p );
|
||||
}
|
||||
|
||||
crl_cur = crl_cur->next;
|
||||
}
|
||||
while( crl_cur != NULL );
|
||||
|
||||
crl_cur = crl;
|
||||
do
|
||||
{
|
||||
crl_prv = crl_cur;
|
||||
crl_cur = crl_cur->next;
|
||||
|
||||
|
@ -766,7 +739,6 @@ void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
|
|||
if( crl_prv != crl )
|
||||
mbedtls_free( crl_prv );
|
||||
}
|
||||
while( crl_cur != NULL );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_X509_CRL_PARSE_C */
|
||||
|
|
|
@ -47,18 +47,10 @@
|
|||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
#include "hash_info.h"
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
#include "hash_info.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_snprintf snprintf
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
#include "mbedtls/threading.h"
|
||||
|
@ -693,16 +685,7 @@ static int x509_get_subject_alt_name( unsigned char **p,
|
|||
*/
|
||||
if( ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
|
||||
{
|
||||
mbedtls_x509_sequence *seq_cur = subject_alt_name->next;
|
||||
mbedtls_x509_sequence *seq_prv;
|
||||
while( seq_cur != NULL )
|
||||
{
|
||||
seq_prv = seq_cur;
|
||||
seq_cur = seq_cur->next;
|
||||
mbedtls_platform_zeroize( seq_prv,
|
||||
sizeof( mbedtls_x509_sequence ) );
|
||||
mbedtls_free( seq_prv );
|
||||
}
|
||||
mbedtls_asn1_sequence_free( subject_alt_name->next );
|
||||
subject_alt_name->next = NULL;
|
||||
return( ret );
|
||||
}
|
||||
|
@ -1854,6 +1837,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
|
|||
const char *prefix )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t i;
|
||||
size_t n = *size;
|
||||
char *p = *buf;
|
||||
const mbedtls_x509_sequence *cur = subject_alt_name;
|
||||
|
@ -1906,18 +1890,11 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
|
|||
ret = mbedtls_snprintf( p, n, "\n%s hardware serial number : ", prefix );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
if( other_name->value.hardware_module_name.val.len >= n )
|
||||
for( i = 0; i < other_name->value.hardware_module_name.val.len; i++ )
|
||||
{
|
||||
*p = '\0';
|
||||
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
|
||||
ret = mbedtls_snprintf( p, n, "%02X", other_name->value.hardware_module_name.val.p[i] );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
|
||||
memcpy( p, other_name->value.hardware_module_name.val.p,
|
||||
other_name->value.hardware_module_name.val.len );
|
||||
p += other_name->value.hardware_module_name.val.len;
|
||||
|
||||
n -= other_name->value.hardware_module_name.val.len;
|
||||
|
||||
}/* MBEDTLS_OID_ON_HW_MODULE_NAME */
|
||||
}
|
||||
break;
|
||||
|
@ -2354,11 +2331,10 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
|
|||
const mbedtls_x509_crt_profile *profile )
|
||||
{
|
||||
int flags = 0;
|
||||
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
unsigned char hash[PSA_HASH_MAX_SIZE];
|
||||
psa_algorithm_t psa_algorithm;
|
||||
#else
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
const mbedtls_md_info_t *md_info;
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
size_t hash_length;
|
||||
|
@ -2465,8 +2441,8 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child,
|
|||
mbedtls_x509_crt_restart_ctx *rs_ctx )
|
||||
{
|
||||
size_t hash_len;
|
||||
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
|
||||
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
const mbedtls_md_info_t *md_info;
|
||||
md_info = mbedtls_md_info_from_type( child->sig_md );
|
||||
hash_len = mbedtls_md_get_size( md_info );
|
||||
|
@ -2475,7 +2451,6 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child,
|
|||
if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 )
|
||||
return( -1 );
|
||||
#else
|
||||
unsigned char hash[PSA_HASH_MAX_SIZE];
|
||||
psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md( child->sig_md );
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
|
@ -3310,15 +3285,8 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
|
|||
{
|
||||
mbedtls_x509_crt *cert_cur = crt;
|
||||
mbedtls_x509_crt *cert_prv;
|
||||
mbedtls_x509_name *name_cur;
|
||||
mbedtls_x509_name *name_prv;
|
||||
mbedtls_x509_sequence *seq_cur;
|
||||
mbedtls_x509_sequence *seq_prv;
|
||||
|
||||
if( crt == NULL )
|
||||
return;
|
||||
|
||||
do
|
||||
while( cert_cur != NULL )
|
||||
{
|
||||
mbedtls_pk_free( &cert_cur->pk );
|
||||
|
||||
|
@ -3326,53 +3294,11 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
|
|||
mbedtls_free( cert_cur->sig_opts );
|
||||
#endif
|
||||
|
||||
name_cur = cert_cur->issuer.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
|
||||
mbedtls_free( name_prv );
|
||||
}
|
||||
|
||||
name_cur = cert_cur->subject.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
|
||||
mbedtls_free( name_prv );
|
||||
}
|
||||
|
||||
seq_cur = cert_cur->ext_key_usage.next;
|
||||
while( seq_cur != NULL )
|
||||
{
|
||||
seq_prv = seq_cur;
|
||||
seq_cur = seq_cur->next;
|
||||
mbedtls_platform_zeroize( seq_prv,
|
||||
sizeof( mbedtls_x509_sequence ) );
|
||||
mbedtls_free( seq_prv );
|
||||
}
|
||||
|
||||
seq_cur = cert_cur->subject_alt_names.next;
|
||||
while( seq_cur != NULL )
|
||||
{
|
||||
seq_prv = seq_cur;
|
||||
seq_cur = seq_cur->next;
|
||||
mbedtls_platform_zeroize( seq_prv,
|
||||
sizeof( mbedtls_x509_sequence ) );
|
||||
mbedtls_free( seq_prv );
|
||||
}
|
||||
|
||||
seq_cur = cert_cur->certificate_policies.next;
|
||||
while( seq_cur != NULL )
|
||||
{
|
||||
seq_prv = seq_cur;
|
||||
seq_cur = seq_cur->next;
|
||||
mbedtls_platform_zeroize( seq_prv,
|
||||
sizeof( mbedtls_x509_sequence ) );
|
||||
mbedtls_free( seq_prv );
|
||||
}
|
||||
mbedtls_asn1_free_named_data_list_shallow( cert_cur->issuer.next );
|
||||
mbedtls_asn1_free_named_data_list_shallow( cert_cur->subject.next );
|
||||
mbedtls_asn1_sequence_free( cert_cur->ext_key_usage.next );
|
||||
mbedtls_asn1_sequence_free( cert_cur->subject_alt_names.next );
|
||||
mbedtls_asn1_sequence_free( cert_cur->certificate_policies.next );
|
||||
|
||||
if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
|
||||
{
|
||||
|
@ -3380,13 +3306,6 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
|
|||
mbedtls_free( cert_cur->raw.p );
|
||||
}
|
||||
|
||||
cert_cur = cert_cur->next;
|
||||
}
|
||||
while( cert_cur != NULL );
|
||||
|
||||
cert_cur = crt;
|
||||
do
|
||||
{
|
||||
cert_prv = cert_cur;
|
||||
cert_cur = cert_cur->next;
|
||||
|
||||
|
@ -3394,7 +3313,6 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
|
|||
if( cert_prv != crt )
|
||||
mbedtls_free( cert_prv );
|
||||
}
|
||||
while( cert_cur != NULL );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
|
|
|
@ -42,15 +42,7 @@
|
|||
#include "mbedtls/pem.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_snprintf snprintf
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
|
||||
#include <stdio.h>
|
||||
|
@ -383,9 +375,6 @@ void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
|
|||
*/
|
||||
void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
|
||||
{
|
||||
mbedtls_x509_name *name_cur;
|
||||
mbedtls_x509_name *name_prv;
|
||||
|
||||
if( csr == NULL )
|
||||
return;
|
||||
|
||||
|
@ -395,14 +384,7 @@ void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
|
|||
mbedtls_free( csr->sig_opts );
|
||||
#endif
|
||||
|
||||
name_cur = csr->subject.next;
|
||||
while( name_cur != NULL )
|
||||
{
|
||||
name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
|
||||
mbedtls_free( name_prv );
|
||||
}
|
||||
mbedtls_asn1_free_named_data_list_shallow( csr->subject.next );
|
||||
|
||||
if( csr->raw.p != NULL )
|
||||
{
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
#include "hash_info.h"
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#include "legacy_or_psa.h"
|
||||
#include "hash_info.h"
|
||||
#include "mbedtls/legacy_or_psa.h"
|
||||
|
||||
void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -360,12 +397,10 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx,
|
|||
unsigned char *c, *c2;
|
||||
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
|
||||
size_t hash_length = 0;
|
||||
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_algorithm_t psa_algorithm;
|
||||
unsigned char hash[PSA_HASH_MAX_SIZE];
|
||||
#else
|
||||
unsigned char hash[64];
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
#include "hash_info.h"
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
#include "hash_info.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -45,13 +45,7 @@
|
|||
#include "mbedtls/pem.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
|
||||
{
|
||||
|
@ -145,7 +139,7 @@ static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
|
|||
const char *sig_oid;
|
||||
size_t sig_oid_len = 0;
|
||||
unsigned char *c, *c2;
|
||||
unsigned char hash[64];
|
||||
unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
|
||||
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
|
||||
size_t len = 0;
|
||||
mbedtls_pk_type_t pk_alg;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue