HMAC_DRBG: deprecate mbedtls_hmac_drbg_update because it ignores errors
Deprecate mbedtls_hmac_drbg_update (which returns void) in favor of a
new function mbedtls_hmac_drbg_update_ret which reports error.
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 3bc675e..146367b 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -195,10 +195,13 @@
* \param additional Additional data to update state with, or NULL
* \param add_len Length of additional data, or 0
*
+ * \return \c 0 on success, or an error from the underlying
+ * hash calculation.
+ *
* \note Additional data is optional, pass NULL and 0 as second
* third argument if no additional data is being used.
*/
-void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
+int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
/**
@@ -257,6 +260,31 @@
*/
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief HMAC_DRBG update state
+ *
+ * \deprecated Superseded by mbedtls_hmac_drbg_update_ret()
+ * in 2.16.0.
+ *
+ * \param ctx HMAC_DRBG context
+ * \param additional Additional data to update state with, or NULL
+ * \param add_len Length of additional data, or 0
+ *
+ * \note Additional data is optional, pass NULL and 0 as second
+ * third argument if no additional data is being used.
+ */
+MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
+ mbedtls_hmac_drbg_context *ctx,
+ const unsigned char *additional, size_t add_len );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
#if defined(MBEDTLS_FS_IO)
/**
* \brief Write a seed file
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 65c8dac..7f65354 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -66,33 +66,60 @@
/*
* HMAC_DRBG update, using optional additional data (10.1.2.2)
*/
-void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
- const unsigned char *additional, size_t add_len )
+int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t add_len )
{
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
unsigned char sep[1];
unsigned char K[MBEDTLS_MD_MAX_SIZE];
+ int ret;
for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
{
/* Step 1 or 4 */
- mbedtls_md_hmac_reset( &ctx->md_ctx );
- mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 );
+ if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ ctx->V, md_len ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ sep, 1 ) ) != 0 )
+ goto exit;
if( rounds == 2 )
- mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len );
- mbedtls_md_hmac_finish( &ctx->md_ctx, K );
+ {
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ additional, add_len ) ) != 0 )
+ goto exit;
+ }
+ if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
+ goto exit;
/* Step 2 or 5 */
- mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len );
- mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
+ if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+ ctx->V, md_len ) ) != 0 )
+ goto exit;
+ if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
+ goto exit;
}
+exit:
mbedtls_platform_zeroize( K, sizeof( K ) );
+ return( ret );
}
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t add_len )
+{
+ (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
/*
* Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
*/
@@ -113,7 +140,8 @@
mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) );
memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
- mbedtls_hmac_drbg_update( ctx, data, data_len );
+ if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
+ return( ret );
return( 0 );
}
@@ -126,6 +154,7 @@
{
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
size_t seedlen;
+ int ret;
/* III. Check input length */
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
@@ -150,14 +179,16 @@
}
/* 2. Update state */
- mbedtls_hmac_drbg_update( ctx, seed, seedlen );
+ if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
+ goto exit;
/* 3. Reset reseed_counter */
ctx->reseed_counter = 1;
+exit:
/* 4. Done */
mbedtls_platform_zeroize( seed, seedlen );
- return( 0 );
+ return( ret );
}
/*
@@ -276,7 +307,11 @@
/* 2. Use additional data if any */
if( additional != NULL && add_len != 0 )
- mbedtls_hmac_drbg_update( ctx, additional, add_len );
+ {
+ if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+ additional, add_len ) ) != 0 )
+ goto exit;
+ }
/* 3, 4, 5. Generate bytes */
while( left != 0 )
@@ -293,13 +328,16 @@
}
/* 6. Update */
- mbedtls_hmac_drbg_update( ctx, additional, add_len );
+ if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+ additional, add_len ) ) != 0 )
+ goto exit;
/* 7. Update reseed counter */
ctx->reseed_counter++;
+exit:
/* 8. Done */
- return( 0 );
+ return( ret );
}
/*
@@ -391,8 +429,7 @@
if( fread( buf, 1, n, f ) != n )
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
else
- mbedtls_hmac_drbg_update( ctx, buf, n );
-
+ ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
fclose( f );
mbedtls_platform_zeroize( buf, sizeof( buf ) );