Implement ECDH
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 6f25d8b..c18c8f0 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -62,6 +62,7 @@
#include "mbedtls/cmac.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/des.h"
+#include "mbedtls/ecdh.h"
#include "mbedtls/ecp.h"
#include "mbedtls/entropy.h"
#include "mbedtls/error.h"
@@ -3593,6 +3594,48 @@
/* Key agreement */
/****************************************************************/
+static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
+ size_t peer_key_length,
+ const mbedtls_ecp_keypair *our_key,
+ uint8_t *shared_secret,
+ size_t shared_secret_size,
+ size_t *shared_secret_length )
+{
+ mbedtls_pk_context pk;
+ mbedtls_ecp_keypair *their_key = NULL;
+ mbedtls_ecdh_context ecdh;
+ int ret;
+ mbedtls_ecdh_init( &ecdh );
+ mbedtls_pk_init( &pk );
+
+ ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
+ if( ret != 0 )
+ goto exit;
+ if( mbedtls_pk_get_type( &pk ) != MBEDTLS_PK_ECKEY )
+ {
+ ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+ goto exit;
+ }
+ their_key = mbedtls_pk_ec( pk );
+ ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
+ if( ret != 0 )
+ goto exit;
+ ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
+ if( ret != 0 )
+ goto exit;
+
+ ret = mbedtls_ecdh_calc_secret( &ecdh,
+ shared_secret_length,
+ shared_secret, shared_secret_size,
+ mbedtls_ctr_drbg_random,
+ &global_data.ctr_drbg );
+
+exit:
+ mbedtls_pk_free( &pk );
+ mbedtls_ecdh_free( &ecdh );
+ return( mbedtls_to_psa_error( ret ) );
+}
+
#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
@@ -3609,6 +3652,17 @@
* secret. */
switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
{
+#if defined(MBEDTLS_ECDH_C)
+ case PSA_ALG_ECDH_BASE:
+ if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
+ return( PSA_ERROR_INVALID_ARGUMENT );
+ status = psa_key_agreement_ecdh( peer_key, peer_key_length,
+ private_key->data.ecp,
+ shared_secret,
+ sizeof( shared_secret ),
+ &shared_secret_length );
+ break;
+#endif /* MBEDTLS_ECDH_C */
default:
return( PSA_ERROR_NOT_SUPPORTED );
}