diff --git a/include/polarssl/ecdsa.h b/include/polarssl/ecdsa.h index d61e82c2d..15b90e667 100644 --- a/include/polarssl/ecdsa.h +++ b/include/polarssl/ecdsa.h @@ -31,6 +31,8 @@ /** * \brief ECDSA context structure + * + * \note Purposefully begins with the same members as struct ecp_keypair. */ typedef struct { diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h index df3fc44de..2f7008514 100644 --- a/include/polarssl/pk.h +++ b/include/polarssl/pk.h @@ -33,6 +33,10 @@ #include "rsa.h" #endif +#if defined(POLARSSL_ECDSA_C) +#include "ecdsa.h" +#endif + #define POLARSSL_ERR_PK_MALLOC_FAILED -0x2F80 /**< Memory alloation failed. */ #define POLARSSL_ERR_PK_TYPE_MISMATCH -0x2F00 /**< Type mismatch, eg attempt to use a RSA key as EC, or to modify key type */ @@ -107,6 +111,33 @@ void pk_free( pk_context *ctx ); */ int pk_set_type( pk_context *ctx, pk_type_t type ); +#if defined(POLARSSL_ECDSA_C) +/** + * \brief Convert a generic EC key into an ECDSA context + * + * \param ctx Context to convert + * + * \return 0 on success, or + * POLARSSL_ERR_PK_MALLOC_FAILED or + * POLARSSL_ERR_PK_TYPE_MISMATCH. + */ +int pk_ec_to_ecdsa( pk_context *ctx ); + +/** + * \brief Tell if a PK context can be used for ECDSA + * + * \param ctx Context to check + * + * \return 0 if context cannot be used for ECDSA, + * 1 otherwise + */ +static inline int pk_can_ecdsa( pk_context ctx ) +{ + return( ctx.type == POLARSSL_PK_ECKEY || + ctx.type == POLARSSL_PK_ECDSA ); +} +#endif /* POLARSSL_ECDSA_C */ + #if defined(POLARSSL_RSA_C) /** * \brief Wrap a RSA context in a PK context diff --git a/library/pk.c b/library/pk.c index 3755fbcfe..c5583c363 100644 --- a/library/pk.c +++ b/library/pk.c @@ -132,6 +132,42 @@ int pk_set_type( pk_context *ctx, pk_type_t type ) return( 0 ); } +#if defined(POLARSSL_ECDSA_C) +/* + * Convert generic EC context to ECDSA + */ +int pk_ec_to_ecdsa( pk_context *ctx ) +{ + ecp_keypair *eckey; + ecdsa_context *ecdsa; + + if( ctx->type == POLARSSL_PK_ECDSA ) + return( 0 ); + + if( ctx->type != POLARSSL_PK_ECKEY ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + eckey = (ecp_keypair *) ctx->data; + + if( ( ecdsa = polarssl_malloc( sizeof( ecdsa_context ) ) ) == NULL ) + return( POLARSSL_ERR_PK_MALLOC_FAILED ); + + ecdsa_init( ecdsa ); + + /* struct ecdsa_context begins the same as struct ecp_keypair */ + memcpy( ecdsa, eckey, sizeof( ecp_keypair ) ); + + if( ! ctx->dont_free ) + polarssl_free( eckey ); + + ctx->dont_free = 0; + ctx->type = POLARSSL_PK_ECDSA; + ctx->data = ecdsa; + + return( 0 ); +} +#endif /* POLARSSL_ECDSA_C */ + #if defined(POLARSSL_RSA_C) /* * Wrap an RSA context in a PK context