summaryrefslogtreecommitdiff
path: root/thirdparty/mbedtls/library/pk.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/mbedtls/library/pk.c')
-rw-r--r--thirdparty/mbedtls/library/pk.c209
1 files changed, 188 insertions, 21 deletions
diff --git a/thirdparty/mbedtls/library/pk.c b/thirdparty/mbedtls/library/pk.c
index f05b139e3f..bac685dc19 100644
--- a/thirdparty/mbedtls/library/pk.c
+++ b/thirdparty/mbedtls/library/pk.c
@@ -44,13 +44,18 @@
#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 )
{
- if( ctx == NULL )
- return;
+ PK_VALIDATE( ctx != NULL );
ctx->pk_info = NULL;
ctx->pk_ctx = NULL;
@@ -61,14 +66,44 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx )
*/
void mbedtls_pk_free( mbedtls_pk_context *ctx )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ if( ctx == NULL )
return;
- ctx->pk_info->ctx_free_func( ctx->pk_ctx );
+ if ( ctx->pk_info != NULL )
+ ctx->pk_info->ctx_free_func( ctx->pk_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
}
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/*
+ * Initialize a restart context
+ */
+void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
+{
+ PK_VALIDATE( ctx != NULL );
+ ctx->pk_info = NULL;
+ ctx->rs_ctx = NULL;
+}
+
+/*
+ * Free the components of a restart context
+ */
+void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
+{
+ if( ctx == NULL || ctx->pk_info == NULL ||
+ ctx->pk_info->rs_free_func == NULL )
+ {
+ return;
+ }
+
+ ctx->pk_info->rs_free_func( ctx->rs_ctx );
+
+ ctx->pk_info = NULL;
+ ctx->rs_ctx = NULL;
+}
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
/*
* Get pk_info structure from type
*/
@@ -100,7 +135,8 @@ 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 )
{
- if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ if( info == NULL || ctx->pk_info != NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
@@ -123,7 +159,8 @@ 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;
- if( ctx == NULL || ctx->pk_info != NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ if( ctx->pk_info != NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
@@ -147,7 +184,9 @@ int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
*/
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
{
- /* null or NONE context can't do anything */
+ /* A context with null pk_info is not set up yet and can't do anything.
+ * For backward compatibility, also accept NULL instead of a context
+ * pointer. */
if( ctx == NULL || ctx->pk_info == NULL )
return( 0 );
@@ -171,17 +210,71 @@ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len
return( 0 );
}
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/*
- * Verify a signature
+ * Helper to set up a restart context if needed
*/
-int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
+ const mbedtls_pk_info_t *info )
+{
+ /* Don't do anything if already set up or invalid */
+ if( ctx == NULL || ctx->pk_info != NULL )
+ return( 0 );
+
+ /* Should never happen when we're called */
+ if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
+ return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+ ctx->pk_info = info;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+/*
+ * Verify a signature (restartable)
+ */
+int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
+ mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
- const unsigned char *sig, size_t sig_len )
+ const unsigned char *sig, size_t sig_len,
+ mbedtls_pk_restart_ctx *rs_ctx )
{
- if( ctx == NULL || ctx->pk_info == NULL ||
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+ hash != NULL );
+ PK_VALIDATE_RET( sig != NULL );
+
+ 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)
+ /* optimization: use non-restartable version if restart disabled */
+ if( rs_ctx != NULL &&
+ mbedtls_ecp_restart_is_enabled() &&
+ ctx->pk_info->verify_rs_func != NULL )
+ {
+ int ret;
+
+ if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
+ return( ret );
+
+ ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
+ md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
+
+ if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
+ mbedtls_pk_restart_free( rs_ctx );
+
+ return( ret );
+ }
+#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+ (void) rs_ctx;
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
if( ctx->pk_info->verify_func == NULL )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
@@ -190,6 +283,17 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
}
/*
+ * Verify a signature
+ */
+int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
+ sig, sig_len, NULL ) );
+}
+
+/*
* Verify a signature with options
*/
int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
@@ -197,7 +301,12 @@ 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 )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+ hash != NULL );
+ PK_VALIDATE_RET( sig != NULL );
+
+ if( ctx->pk_info == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ! mbedtls_pk_can_do( ctx, type ) )
@@ -248,17 +357,47 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
}
/*
- * Make a signature
+ * Make a signature (restartable)
*/
-int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
+ mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+ mbedtls_pk_restart_ctx *rs_ctx )
{
- if( ctx == NULL || ctx->pk_info == NULL ||
+ PK_VALIDATE_RET( ctx != NULL );
+ PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+ hash != NULL );
+ PK_VALIDATE_RET( sig != NULL );
+
+ 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)
+ /* optimization: use non-restartable version if restart disabled */
+ if( rs_ctx != NULL &&
+ mbedtls_ecp_restart_is_enabled() &&
+ ctx->pk_info->sign_rs_func != NULL )
+ {
+ int ret;
+
+ if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
+ return( ret );
+
+ ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
+ hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
+
+ if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
+ mbedtls_pk_restart_free( rs_ctx );
+
+ return( ret );
+ }
+#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+ (void) rs_ctx;
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
if( ctx->pk_info->sign_func == NULL )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
@@ -267,6 +406,18 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
}
/*
+ * Make a signature
+ */
+int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ unsigned char *sig, size_t *sig_len,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+ return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
+ sig, sig_len, f_rng, p_rng, NULL ) );
+}
+
+/*
* Decrypt message
*/
int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
@@ -274,7 +425,12 @@ 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 )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ 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 );
if( ctx->pk_info->decrypt_func == NULL )
@@ -292,7 +448,12 @@ 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 )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ 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 );
if( ctx->pk_info->encrypt_func == NULL )
@@ -307,8 +468,11 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
*/
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
{
- if( pub == NULL || pub->pk_info == NULL ||
- prv == NULL || prv->pk_info == NULL ||
+ PK_VALIDATE_RET( pub != NULL );
+ PK_VALIDATE_RET( prv != NULL );
+
+ if( pub->pk_info == NULL ||
+ prv->pk_info == NULL ||
prv->pk_info->check_pair_func == NULL )
{
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
@@ -333,6 +497,8 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte
*/
size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
{
+ /* For backward compatibility, accept NULL or a context that
+ * isn't set up yet, and return a fake value that should be safe. */
if( ctx == NULL || ctx->pk_info == NULL )
return( 0 );
@@ -344,7 +510,8 @@ 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 )
{
- if( ctx == NULL || ctx->pk_info == NULL )
+ PK_VALIDATE_RET( ctx != NULL );
+ if( ctx->pk_info == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->debug_func == NULL )