diff --git a/docs/architecture/psa-migration/md-cipher-dispatch.md b/docs/architecture/psa-migration/md-cipher-dispatch.md index eee59c4d80..355f5618dd 100644 --- a/docs/architecture/psa-migration/md-cipher-dispatch.md +++ b/docs/architecture/psa-migration/md-cipher-dispatch.md @@ -312,13 +312,16 @@ Note that some algorithms have different spellings in legacy and PSA. Since MD i ``` #if defined(MBEDTLS_MD_LIGHT) #if defined(MBEDTLS_SHA256_C) || \ - ((defined(MBEDTLS_PSA_CRYPTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)) && \ - PSA_WANT_ALG_SHA_256) + (defined(MBEDTLS_PSA_CRYPTO_C) && PSA_WANT_ALG_SHA_256) #define MBEDTLS_MD_CAN_SHA256 #endif #endif ``` +Note: in the future, we may want to replace `defined(MBEDTLS_PSA_CRYPTO_C)` +with `defined(MBEDTLS_PSA_CRYTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)` but +for now this is out of scope. + #### MD light internal support macros * If at least one hash has a PSA driver, define `MBEDTLS_MD_SOME_PSA`. @@ -337,16 +340,11 @@ enum { } mbedtls_md_engine_t; // private type typedef struct mbedtls_md_context_t { - const mbedtls_md_type_t type; - const mbedtls_md_engine_t engine; - union { -#if defined(MBEDTLS_MD_SOME_LEGACY) - void *legacy; // used if engine == LEGACY -#endif + mbedtls_md_type_t type; #if defined(MBEDTLS_MD_SOME_PSA) - psa_hash_operation_t *psa; // used if engine == PSA + mbedtls_md_engine_t engine; #endif - } digest; + void *md_ctx; // mbedtls_xxx_context or psa_hash_operation #if defined(MBEDTLS_MD_C) void *hmac_ctx; #endif diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h index 3341d1cc02..7bad24dc9b 100644 --- a/include/mbedtls/md.h +++ b/include/mbedtls/md.h @@ -32,6 +32,93 @@ #include "mbedtls/build_info.h" #include "mbedtls/platform_util.h" +#if defined(MBEDTLS_MD_LIGHT) + +/* + * - MBEDTLS_MD_CAN_xxx is defined if the md module can perform xxx. + * - MBEDTLS_MD_xxx_VIA_PSA is defined if the md module may perform xxx via PSA + * (see below). + * - MBEDTLS_MD_SOME_PSA is defined if at least one algorithm may be performed + * via PSA (see below). + * - MBEDTLS_MD_SOME_LEGACY is defined if at least one algorithm may be performed + * via a direct legacy call (see below). + * + * The md module performs an algorithm via PSA if there is a PSA hash + * accelerator and the PSA driver subsytem is initialized at the time the + * operation is started, and makes a direct legacy call otherwise. + */ + +/* PSA accelerated implementations */ +#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5) +#define MBEDTLS_MD_CAN_MD5 +#define MBEDTLS_MD_MD5_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) +#define MBEDTLS_MD_CAN_SHA1 +#define MBEDTLS_MD_SHA1_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) +#define MBEDTLS_MD_CAN_SHA224 +#define MBEDTLS_MD_SHA224_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) +#define MBEDTLS_MD_CAN_SHA256 +#define MBEDTLS_MD_SHA256_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) +#define MBEDTLS_MD_CAN_SHA384 +#define MBEDTLS_MD_SHA384_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) +#define MBEDTLS_MD_CAN_SHA512 +#define MBEDTLS_MD_SHA512_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) +#define MBEDTLS_MD_CAN_RIPEMD160 +#define MBEDTLS_MD_RIPEMD160_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#endif /* MBEDTLS_PSA_CRYPTO_C */ + +/* Built-in implementations */ +#if defined(MBEDTLS_MD5_C) +#define MBEDTLS_MD_CAN_MD5 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA1_C) +#define MBEDTLS_MD_CAN_SHA1 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA224_C) +#define MBEDTLS_MD_CAN_SHA224 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA256_C) +#define MBEDTLS_MD_CAN_SHA256 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA384_C) +#define MBEDTLS_MD_CAN_SHA384 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA512_C) +#define MBEDTLS_MD_CAN_SHA512 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_RIPEMD160_C) +#define MBEDTLS_MD_CAN_RIPEMD160 +#define MBEDTLS_MD_SOME_LEGACY +#endif + +#endif /* MBEDTLS_MD_LIGHT */ + /** The selected feature is not available. */ #define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /** Bad input parameters to function. */ @@ -64,19 +151,20 @@ typedef enum { MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */ } mbedtls_md_type_t; -#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_MD_CAN_SHA512) #define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ -#elif defined(MBEDTLS_SHA384_C) +#elif defined(MBEDTLS_MD_CAN_SHA384) #define MBEDTLS_MD_MAX_SIZE 48 /* longest known is SHA384 */ -#elif defined(MBEDTLS_SHA256_C) +#elif defined(MBEDTLS_MD_CAN_SHA256) #define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 */ -#elif defined(MBEDTLS_SHA224_C) +#elif defined(MBEDTLS_MD_CAN_SHA224) #define MBEDTLS_MD_MAX_SIZE 28 /* longest known is SHA224 */ #else -#define MBEDTLS_MD_MAX_SIZE 20 /* longest known is SHA1 or RIPE MD-160 */ +#define MBEDTLS_MD_MAX_SIZE 20 /* longest known is SHA1 or RIPE MD-160 + or smaller (MD5 and earlier) */ #endif -#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_MD_CAN_SHA512) #define MBEDTLS_MD_MAX_BLOCK_SIZE 128 #else #define MBEDTLS_MD_MAX_BLOCK_SIZE 64 @@ -94,6 +182,16 @@ typedef enum { /* Defined internally in library/md_wrap.h. */ typedef struct mbedtls_md_info_t mbedtls_md_info_t; +/** + * Used internally to indicate whether a context uses legacy or PSA. + * + * Internal use only. + */ +typedef enum { + MBEDTLS_MD_ENGINE_LEGACY = 0, + MBEDTLS_MD_ENGINE_PSA, +} mbedtls_md_engine_t; + /** * The generic message-digest context. */ @@ -101,11 +199,18 @@ typedef struct mbedtls_md_context_t { /** Information about the associated message digest. */ const mbedtls_md_info_t *MBEDTLS_PRIVATE(md_info); - /** The digest-specific context. */ +#if defined(MBEDTLS_MD_SOME_PSA) + /** Are hash operations dispatched to PSA or legacy? */ + mbedtls_md_engine_t MBEDTLS_PRIVATE(engine); +#endif + + /** The digest-specific context (legacy) or the PSA operation. */ void *MBEDTLS_PRIVATE(md_ctx); +#if defined(MBEDTLS_MD_C) /** The HMAC part of the context. */ void *MBEDTLS_PRIVATE(hmac_ctx); +#endif } mbedtls_md_context_t; /** @@ -185,6 +290,10 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info * * \return \c 0 on success. * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure. + * \return #MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE if both contexts are + * not using the same engine. This can be avoided by moving + * the call to psa_crypto_init() before the first call to + * mbedtls_md_setup(). */ MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_clone(mbedtls_md_context_t *dst, diff --git a/library/md.c b/library/md.c index 6681f9aa0c..bebe3580bd 100644 --- a/library/md.c +++ b/library/md.c @@ -52,6 +52,11 @@ #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" +#if defined(MBEDTLS_MD_SOME_PSA) +#include +#include "psa_crypto_core.h" +#endif + #include "mbedtls/platform.h" #include @@ -60,7 +65,7 @@ #include #endif -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_MD_CAN_MD5) const mbedtls_md_info_t mbedtls_md5_info = { "MD5", MBEDTLS_MD_MD5, @@ -69,7 +74,7 @@ const mbedtls_md_info_t mbedtls_md5_info = { }; #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_MD_CAN_RIPEMD160) const mbedtls_md_info_t mbedtls_ripemd160_info = { "RIPEMD160", MBEDTLS_MD_RIPEMD160, @@ -78,7 +83,7 @@ const mbedtls_md_info_t mbedtls_ripemd160_info = { }; #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_MD_CAN_SHA1) const mbedtls_md_info_t mbedtls_sha1_info = { "SHA1", MBEDTLS_MD_SHA1, @@ -87,7 +92,7 @@ const mbedtls_md_info_t mbedtls_sha1_info = { }; #endif -#if defined(MBEDTLS_SHA224_C) +#if defined(MBEDTLS_MD_CAN_SHA224) const mbedtls_md_info_t mbedtls_sha224_info = { "SHA224", MBEDTLS_MD_SHA224, @@ -96,7 +101,7 @@ const mbedtls_md_info_t mbedtls_sha224_info = { }; #endif -#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_MD_CAN_SHA256) const mbedtls_md_info_t mbedtls_sha256_info = { "SHA256", MBEDTLS_MD_SHA256, @@ -105,7 +110,7 @@ const mbedtls_md_info_t mbedtls_sha256_info = { }; #endif -#if defined(MBEDTLS_SHA384_C) +#if defined(MBEDTLS_MD_CAN_SHA384) const mbedtls_md_info_t mbedtls_sha384_info = { "SHA384", MBEDTLS_MD_SHA384, @@ -114,7 +119,7 @@ const mbedtls_md_info_t mbedtls_sha384_info = { }; #endif -#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_MD_CAN_SHA512) const mbedtls_md_info_t mbedtls_sha512_info = { "SHA512", MBEDTLS_MD_SHA512, @@ -126,31 +131,31 @@ const mbedtls_md_info_t mbedtls_sha512_info = { const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) { switch (md_type) { -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_MD_CAN_MD5) case MBEDTLS_MD_MD5: return &mbedtls_md5_info; #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_MD_CAN_RIPEMD160) case MBEDTLS_MD_RIPEMD160: return &mbedtls_ripemd160_info; #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_MD_CAN_SHA1) case MBEDTLS_MD_SHA1: return &mbedtls_sha1_info; #endif -#if defined(MBEDTLS_SHA224_C) +#if defined(MBEDTLS_MD_CAN_SHA224) case MBEDTLS_MD_SHA224: return &mbedtls_sha224_info; #endif -#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_MD_CAN_SHA256) case MBEDTLS_MD_SHA256: return &mbedtls_sha256_info; #endif -#if defined(MBEDTLS_SHA384_C) +#if defined(MBEDTLS_MD_CAN_SHA384) case MBEDTLS_MD_SHA384: return &mbedtls_sha384_info; #endif -#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_MD_CAN_SHA512) case MBEDTLS_MD_SHA512: return &mbedtls_sha512_info; #endif @@ -159,8 +164,71 @@ const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) } } +#if defined(MBEDTLS_MD_SOME_PSA) +static psa_algorithm_t psa_alg_of_md(const mbedtls_md_info_t *info) +{ + switch (info->type) { +#if defined(MBEDTLS_MD_MD5_VIA_PSA) + case MBEDTLS_MD_MD5: + return PSA_ALG_MD5; +#endif +#if defined(MBEDTLS_MD_RIPEMD160_VIA_PSA) + case MBEDTLS_MD_RIPEMD160: + return PSA_ALG_RIPEMD160; +#endif +#if defined(MBEDTLS_MD_SHA1_VIA_PSA) + case MBEDTLS_MD_SHA1: + return PSA_ALG_SHA_1; +#endif +#if defined(MBEDTLS_MD_SHA224_VIA_PSA) + case MBEDTLS_MD_SHA224: + return PSA_ALG_SHA_224; +#endif +#if defined(MBEDTLS_MD_SHA256_VIA_PSA) + case MBEDTLS_MD_SHA256: + return PSA_ALG_SHA_256; +#endif +#if defined(MBEDTLS_MD_SHA384_VIA_PSA) + case MBEDTLS_MD_SHA384: + return PSA_ALG_SHA_384; +#endif +#if defined(MBEDTLS_MD_SHA512_VIA_PSA) + case MBEDTLS_MD_SHA512: + return PSA_ALG_SHA_512; +#endif + default: + return PSA_ALG_NONE; + } +} + +static int md_can_use_psa(const mbedtls_md_info_t *info) +{ + psa_algorithm_t alg = psa_alg_of_md(info); + if (alg == PSA_ALG_NONE) { + return 0; + } + + return psa_can_do_hash(alg); +} + +static int mbedtls_md_error_from_psa(psa_status_t status) +{ + switch (status) { + case PSA_SUCCESS: + return 0; + case PSA_ERROR_NOT_SUPPORTED: + return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; + case PSA_ERROR_INSUFFICIENT_MEMORY: + return MBEDTLS_ERR_MD_ALLOC_FAILED; + default: + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } +} +#endif /* MBEDTLS_MD_SOME_PSA */ + void mbedtls_md_init(mbedtls_md_context_t *ctx) { + /* Note: this sets engine (if present) to MBEDTLS_MD_ENGINE_LEGACY */ memset(ctx, 0, sizeof(mbedtls_md_context_t)); } @@ -171,6 +239,11 @@ void mbedtls_md_free(mbedtls_md_context_t *ctx) } if (ctx->md_ctx != NULL) { +#if defined(MBEDTLS_MD_SOME_PSA) + if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { + psa_hash_abort(ctx->md_ctx); + } else +#endif switch (ctx->md_info->type) { #if defined(MBEDTLS_MD5_C) case MBEDTLS_MD_MD5: @@ -214,11 +287,13 @@ void mbedtls_md_free(mbedtls_md_context_t *ctx) mbedtls_free(ctx->md_ctx); } +#if defined(MBEDTLS_MD_C) if (ctx->hmac_ctx != NULL) { mbedtls_platform_zeroize(ctx->hmac_ctx, 2 * ctx->md_info->block_size); mbedtls_free(ctx->hmac_ctx); } +#endif mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md_context_t)); } @@ -232,6 +307,21 @@ int mbedtls_md_clone(mbedtls_md_context_t *dst, return MBEDTLS_ERR_MD_BAD_INPUT_DATA; } +#if defined(MBEDTLS_MD_SOME_PSA) + if (src->engine != dst->engine) { + /* This can happen with src set to legacy because PSA wasn't ready + * yet, and dst to PSA because it became ready in the meantime. + * We currently don't support that case (we'd need to re-allocate + * md_ctx to the size of the appropriate MD context). */ + return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; + } + + if (src->engine == MBEDTLS_MD_ENGINE_PSA) { + psa_status_t status = psa_hash_clone(src->md_ctx, dst->md_ctx); + return mbedtls_md_error_from_psa(status); + } +#endif + switch (src->md_info->type) { #if defined(MBEDTLS_MD5_C) case MBEDTLS_MD_MD5: @@ -292,8 +382,23 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ctx->md_info = md_info; ctx->md_ctx = NULL; +#if defined(MBEDTLS_MD_C) ctx->hmac_ctx = NULL; +#else + if (hmac != 0) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +#endif +#if defined(MBEDTLS_MD_SOME_PSA) + if (md_can_use_psa(ctx->md_info)) { + ctx->md_ctx = mbedtls_calloc(1, sizeof(psa_hash_operation_t)); + if (ctx->md_ctx == NULL) { + return MBEDTLS_ERR_MD_ALLOC_FAILED; + } + ctx->engine = MBEDTLS_MD_ENGINE_PSA; + } else +#endif switch (md_info->type) { #if defined(MBEDTLS_MD5_C) case MBEDTLS_MD_MD5: @@ -334,6 +439,7 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info return MBEDTLS_ERR_MD_BAD_INPUT_DATA; } +#if defined(MBEDTLS_MD_C) if (hmac != 0) { ctx->hmac_ctx = mbedtls_calloc(2, md_info->block_size); if (ctx->hmac_ctx == NULL) { @@ -341,6 +447,7 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info return MBEDTLS_ERR_MD_ALLOC_FAILED; } } +#endif return 0; } @@ -352,6 +459,15 @@ int mbedtls_md_starts(mbedtls_md_context_t *ctx) return MBEDTLS_ERR_MD_BAD_INPUT_DATA; } +#if defined(MBEDTLS_MD_SOME_PSA) + if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { + psa_algorithm_t alg = psa_alg_of_md(ctx->md_info); + psa_hash_abort(ctx->md_ctx); + psa_status_t status = psa_hash_setup(ctx->md_ctx, alg); + return mbedtls_md_error_from_psa(status); + } +#endif + switch (ctx->md_info->type) { #if defined(MBEDTLS_MD5_C) case MBEDTLS_MD_MD5: @@ -392,6 +508,13 @@ int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, siz return MBEDTLS_ERR_MD_BAD_INPUT_DATA; } +#if defined(MBEDTLS_MD_SOME_PSA) + if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { + psa_status_t status = psa_hash_update(ctx->md_ctx, input, ilen); + return mbedtls_md_error_from_psa(status); + } +#endif + switch (ctx->md_info->type) { #if defined(MBEDTLS_MD5_C) case MBEDTLS_MD_MD5: @@ -432,6 +555,15 @@ int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output) return MBEDTLS_ERR_MD_BAD_INPUT_DATA; } +#if defined(MBEDTLS_MD_SOME_PSA) + if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { + size_t size = ctx->md_info->size; + psa_status_t status = psa_hash_finish(ctx->md_ctx, + output, size, &size); + return mbedtls_md_error_from_psa(status); + } +#endif + switch (ctx->md_info->type) { #if defined(MBEDTLS_MD5_C) case MBEDTLS_MD_MD5: @@ -473,6 +605,16 @@ int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, siz return MBEDTLS_ERR_MD_BAD_INPUT_DATA; } +#if defined(MBEDTLS_MD_SOME_PSA) + if (md_can_use_psa(md_info)) { + size_t size = md_info->size; + psa_status_t status = psa_hash_compute(psa_alg_of_md(md_info), + input, ilen, + output, size, &size); + return mbedtls_md_error_from_psa(status); + } +#endif + switch (md_info->type) { #if defined(MBEDTLS_MD5_C) case MBEDTLS_MD_MD5: @@ -536,30 +678,30 @@ mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info) */ static const int supported_digests[] = { -#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_MD_CAN_SHA512) MBEDTLS_MD_SHA512, #endif -#if defined(MBEDTLS_SHA384_C) +#if defined(MBEDTLS_MD_CAN_SHA384) MBEDTLS_MD_SHA384, #endif -#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_MD_CAN_SHA256) MBEDTLS_MD_SHA256, #endif -#if defined(MBEDTLS_SHA224_C) +#if defined(MBEDTLS_MD_CAN_SHA224) MBEDTLS_MD_SHA224, #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_MD_CAN_SHA1) MBEDTLS_MD_SHA1, #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_MD_CAN_RIPEMD160) MBEDTLS_MD_RIPEMD160, #endif -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_MD_CAN_MD5) MBEDTLS_MD_MD5, #endif @@ -578,37 +720,37 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name) } /* Get the appropriate digest information */ -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_MD_CAN_MD5) if (!strcmp("MD5", md_name)) { return mbedtls_md_info_from_type(MBEDTLS_MD_MD5); } #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_MD_CAN_RIPEMD160) if (!strcmp("RIPEMD160", md_name)) { return mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160); } #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_MD_CAN_SHA1) if (!strcmp("SHA1", md_name) || !strcmp("SHA", md_name)) { return mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); } #endif -#if defined(MBEDTLS_SHA224_C) +#if defined(MBEDTLS_MD_CAN_SHA224) if (!strcmp("SHA224", md_name)) { return mbedtls_md_info_from_type(MBEDTLS_MD_SHA224); } #endif -#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_MD_CAN_SHA256) if (!strcmp("SHA256", md_name)) { return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); } #endif -#if defined(MBEDTLS_SHA384_C) +#if defined(MBEDTLS_MD_CAN_SHA384) if (!strcmp("SHA384", md_name)) { return mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); } #endif -#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_MD_CAN_SHA512) if (!strcmp("SHA512", md_name)) { return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); } diff --git a/library/psa_crypto.c b/library/psa_crypto.c index ba204f7ef2..46938eadbf 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -111,6 +111,7 @@ static int key_type_is_raw_bytes(psa_key_type_t type) typedef struct { unsigned initialized : 1; unsigned rng_state : 2; + unsigned drivers_initialized : 1; mbedtls_psa_random_context_t rng; } psa_global_data_t; @@ -125,6 +126,12 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = if (global_data.initialized == 0) \ return PSA_ERROR_BAD_STATE; +int psa_can_do_hash(psa_algorithm_t hash_alg) +{ + (void) hash_alg; + return global_data.drivers_initialized; +} + psa_status_t mbedtls_to_psa_error(int ret) { /* Mbed TLS error codes can combine a high-level error code and a @@ -7124,6 +7131,13 @@ psa_status_t psa_crypto_init(void) return PSA_SUCCESS; } + /* Init drivers */ + status = psa_driver_wrapper_init(); + if (status != PSA_SUCCESS) { + goto exit; + } + global_data.drivers_initialized = 1; + /* Initialize and seed the random generator. */ mbedtls_psa_random_init(&global_data.rng); global_data.rng_state = RNG_INITIALIZED; @@ -7138,12 +7152,6 @@ psa_status_t psa_crypto_init(void) goto exit; } - /* Init drivers */ - status = psa_driver_wrapper_init(); - if (status != PSA_SUCCESS) { - goto exit; - } - #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) status = psa_crypto_load_transaction(); if (status == PSA_SUCCESS) { diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index d3d0188a6e..8bc1b647c0 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -26,6 +26,18 @@ #include "psa/crypto.h" #include "psa/crypto_se_driver.h" +/** + * Tell if PSA is ready for this hash. + * + * \note For now, only checks the state of the driver subsystem, + * not the algorithm. Might do more in the future. + * + * \param hash_alg The hash algorithm (ignored for now). + * + * \return 1 if the driver subsytem is ready, 0 otherwise. + */ +int psa_can_do_hash(psa_algorithm_t hash_alg); + /** Constant-time buffer comparison * * \param[in] a Left-hand buffer for comparison. diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index ac6eb2083a..38a60b4f15 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -24,15 +24,43 @@ #include "test/helpers.h" #if defined(MBEDTLS_PSA_CRYPTO_C) - #include "test/psa_helpers.h" - #include +#endif #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/psa_util.h" #endif +#if defined(MBEDTLS_PSA_CRYPTO_C) +/** Initialize the PSA Crypto subsystem. */ +#define PSA_INIT() PSA_ASSERT(psa_crypto_init()) + +/** Shut down the PSA Crypto subsystem and destroy persistent keys. + * Expect a clean shutdown, with no slots in use. + * + * If some key slots are still in use, record the test case as failed, + * but continue executing. This macro is suitable (and primarily intended) + * for use in the cleanup section of test functions. + * + * \note Persistent keys must be recorded with #TEST_USES_KEY_ID before + * creating them. + */ +#define PSA_DONE() \ + do \ + { \ + mbedtls_test_fail_if_psa_leaking(__LINE__, __FILE__); \ + mbedtls_test_psa_purge_key_storage(); \ + mbedtls_psa_crypto_free(); \ + } \ + while (0) +#else /*MBEDTLS_PSA_CRYPTO_C */ +#define PSA_INIT() ((void) 0) +#define PSA_DONE() ((void) 0) +#endif /* MBEDTLS_PSA_CRYPTO_C */ + +#if defined(MBEDTLS_PSA_CRYPTO_C) + #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) /* Internal function for #TEST_USES_KEY_ID. Return 1 on success, 0 on failure. */ @@ -86,8 +114,6 @@ void mbedtls_test_psa_purge_key_cache(void); #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ -#define PSA_INIT() PSA_ASSERT(psa_crypto_init()) - /** Check for things that have not been cleaned up properly in the * PSA subsystem. * @@ -112,25 +138,6 @@ const char *mbedtls_test_helper_is_psa_leaking(void); } \ while (0) -/** Shut down the PSA Crypto subsystem and destroy persistent keys. - * Expect a clean shutdown, with no slots in use. - * - * If some key slots are still in use, record the test case as failed, - * but continue executing. This macro is suitable (and primarily intended) - * for use in the cleanup section of test functions. - * - * \note Persistent keys must be recorded with #TEST_USES_KEY_ID before - * creating them. - */ -#define PSA_DONE() \ - do \ - { \ - mbedtls_test_fail_if_psa_leaking(__LINE__, __FILE__); \ - mbedtls_test_psa_purge_key_storage(); \ - mbedtls_psa_crypto_free(); \ - } \ - while (0) - /** Shut down the PSA Crypto subsystem, allowing persistent keys to survive. * Expect a clean shutdown, with no slots in use. * @@ -295,6 +302,7 @@ int mbedtls_test_fail_if_psa_leaking(int line_no, const char *filename); #define PSA_INIT_IF_NO_MD() ((void) 0) #define PSA_DONE_IF_NO_MD() ((void) 0) #endif + /** \def USE_PSA_INIT * * Call this macro to initialize the PSA subsystem if #MBEDTLS_USE_PSA_CRYPTO diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index b76ba579ff..d444cbaf68 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2062,12 +2062,12 @@ component_test_psa_crypto_config_accel_ecdsa () { scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING - # These hashes are needed for some ECDSA signature tests. - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA224_C - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA384_C - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA512_C - loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' ) + # These hashes are needed for some ECDSA signature tests. + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_224" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_256" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_384" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_512" make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS" # Configure and build the main libraries @@ -2135,14 +2135,13 @@ component_test_psa_crypto_config_accel_ecdsa_use_psa () { scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING - # SHA-1 and all variants of SHA-2 are needed for ECDSA and X.509 tests, - # but only SHA-256 is enabled by default, so enable the others. - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA1_C - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA224_C - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA384_C - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA512_C - loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' ) + # SHA-1 and all variants of SHA-2 are needed for ECDSA and X.509 tests + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_1" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_224" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_256" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_384" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_512" make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS" # Configure and build the main libraries with drivers enabled @@ -2364,14 +2363,10 @@ component_test_psa_crypto_config_accel_rsa_signature () { # PSA_ALG_ANY_HASH as algorithm to test with the key, the chosen hash # algorithm based on the hashes supported by the library is also # supported by the test library. + # Disabled unwanted hashes here, we'll enable hashes we want in loc_accel_flags. scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_MD5 scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_RIPEMD160_C - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA1_C - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA224_C - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_SHA512_C - # We need to define either MD_C or all of the PSA_WANT_ALG_SHAxxx. - scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_MD_C # We need PEM parsing in the test library as well to support the import # of PEM encoded RSA keys. scripts/config.py -f tests/include/test/drivers/config_test_driver.h set MBEDTLS_PEM_PARSE_C @@ -2379,6 +2374,12 @@ component_test_psa_crypto_config_accel_rsa_signature () { loc_accel_list="ALG_RSA_PKCS1V15_SIGN ALG_RSA_PSS KEY_TYPE_RSA_KEY_PAIR KEY_TYPE_RSA_PUBLIC_KEY" loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' ) + # These hashes are needed for some RSA-PSS signature tests. + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_1" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_224" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_256" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_384" + loc_accel_flags="$loc_accel_flags -DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_ALG_SHA_512" make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS" # Mbed TLS library build @@ -2442,6 +2443,29 @@ component_test_psa_crypto_config_accel_hash () { make test } +component_test_psa_crypto_config_accel_hash_keep_builtins () { + msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated+builtin hash" + # This component ensures that all the test cases for + # md_psa_dynamic_dispatch with legacy+driver in test_suite_md are run. + + # Disable ALG_STREAM_CIPHER and ALG_ECB_NO_PADDING to avoid having + # partial support for cipher operations in the driver test library. + scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER + scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING + + loc_accel_list="ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512" + loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' ) + make -C tests libtestdriver1.a CFLAGS="$ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS" + + scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS + scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG + loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )" + make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" + + msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated+builtin hash" + make test +} + # Auxiliary function to build config for hashes with and without drivers config_psa_crypto_hash_use_psa () { DRIVER_ONLY="$1" diff --git a/tests/suites/test_suite_md.data b/tests/suites/test_suite_md.data index 79b837619b..24dd39bf9b 100644 --- a/tests/suites/test_suite_md.data +++ b/tests/suites/test_suite_md.data @@ -1016,3 +1016,87 @@ mbedtls_md_file:MBEDTLS_MD_SHA512:"data_files/hash_file_3":"7ccc9b2da71ffde9966c generic SHA-512 Hash file #4 depends_on:MBEDTLS_SHA512_C mbedtls_md_file:MBEDTLS_MD_SHA512:"data_files/hash_file_4":"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + +PSA dispatch MD5 legacy only +depends_on:MBEDTLS_MD5_C:!MBEDTLS_MD_MD5_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_MD5:0:MBEDTLS_MD_ENGINE_LEGACY + +PSA dispatch MD5 driver only +depends_on:!MBEDTLS_MD5_C:MBEDTLS_MD_MD5_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_MD5:MBEDTLS_ERR_MD_BAD_INPUT_DATA:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch MD5 legacy+driver +depends_on:MBEDTLS_MD5_C:MBEDTLS_MD_MD5_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_MD5:0:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch RIPEMD160 legacy only +depends_on:MBEDTLS_RIPEMD160_C:!MBEDTLS_MD_RIPEMD160_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_RIPEMD160:0:MBEDTLS_MD_ENGINE_LEGACY + +PSA dispatch RIPEMD160 driver only +depends_on:!MBEDTLS_RIPEMD160_C:MBEDTLS_MD_RIPEMD160_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_RIPEMD160:MBEDTLS_ERR_MD_BAD_INPUT_DATA:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch RIPEMD160 legacy+driver +depends_on:MBEDTLS_RIPEMD160_C:MBEDTLS_MD_RIPEMD160_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_RIPEMD160:0:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA1 legacy only +depends_on:MBEDTLS_SHA1_C:!MBEDTLS_MD_SHA1_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA1:0:MBEDTLS_MD_ENGINE_LEGACY + +PSA dispatch SHA1 driver only +depends_on:!MBEDTLS_SHA1_C:MBEDTLS_MD_SHA1_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA1:MBEDTLS_ERR_MD_BAD_INPUT_DATA:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA1 legacy+driver +depends_on:MBEDTLS_SHA1_C:MBEDTLS_MD_SHA1_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA1:0:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA224 legacy only +depends_on:MBEDTLS_SHA224_C:!MBEDTLS_MD_SHA224_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA224:0:MBEDTLS_MD_ENGINE_LEGACY + +PSA dispatch SHA224 driver only +depends_on:!MBEDTLS_SHA224_C:MBEDTLS_MD_SHA224_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA224:MBEDTLS_ERR_MD_BAD_INPUT_DATA:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA224 legacy+driver +depends_on:MBEDTLS_SHA224_C:MBEDTLS_MD_SHA224_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA224:0:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA256 legacy only +depends_on:MBEDTLS_SHA256_C:!MBEDTLS_MD_SHA256_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA256:0:MBEDTLS_MD_ENGINE_LEGACY + +PSA dispatch SHA256 driver only +depends_on:!MBEDTLS_SHA256_C:MBEDTLS_MD_SHA256_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA256:MBEDTLS_ERR_MD_BAD_INPUT_DATA:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA256 legacy+driver +depends_on:MBEDTLS_SHA256_C:MBEDTLS_MD_SHA256_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA256:0:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA384 legacy only +depends_on:MBEDTLS_SHA384_C:!MBEDTLS_MD_SHA384_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA384:0:MBEDTLS_MD_ENGINE_LEGACY + +PSA dispatch SHA384 driver only +depends_on:!MBEDTLS_SHA384_C:MBEDTLS_MD_SHA384_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA384:MBEDTLS_ERR_MD_BAD_INPUT_DATA:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA384 legacy+driver +depends_on:MBEDTLS_SHA384_C:MBEDTLS_MD_SHA384_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA384:0:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA512 legacy only +depends_on:MBEDTLS_SHA512_C:!MBEDTLS_MD_SHA512_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA512:0:MBEDTLS_MD_ENGINE_LEGACY + +PSA dispatch SHA512 driver only +depends_on:!MBEDTLS_SHA512_C:MBEDTLS_MD_SHA512_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA512:MBEDTLS_ERR_MD_BAD_INPUT_DATA:MBEDTLS_MD_ENGINE_PSA + +PSA dispatch SHA512 legacy+driver +depends_on:MBEDTLS_SHA512_C:MBEDTLS_MD_SHA512_VIA_PSA +md_psa_dynamic_dispatch:MBEDTLS_MD_SHA512:0:MBEDTLS_MD_ENGINE_PSA diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function index 1e8622be0f..64a417147e 100644 --- a/tests/suites/test_suite_md.function +++ b/tests/suites/test_suite_md.function @@ -1,5 +1,13 @@ /* BEGIN_HEADER */ #include "mbedtls/md.h" + +#if defined(MBEDTLS_MD_SOME_PSA) +#define MD_PSA_INIT() PSA_INIT() +#define MD_PSA_DONE() PSA_DONE() +#else /* MBEDTLS_MD_SOME_PSA */ +#define MD_PSA_INIT() ((void) 0) +#define MD_PSA_DONE() ((void) 0) +#endif /* MBEDTLS_MD_SOME_PSA */ /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -15,6 +23,7 @@ void mbedtls_md_list() mbedtls_md_context_t ctx; unsigned char out[MBEDTLS_MD_MAX_SIZE] = { 0 }; + MD_PSA_INIT(); mbedtls_md_init(&ctx); /* @@ -31,6 +40,7 @@ void mbedtls_md_list() exit: mbedtls_md_free(&ctx); + MD_PSA_DONE(); } /* END_CASE */ @@ -43,6 +53,7 @@ void md_null_args() #endif unsigned char buf[1] = { 0 }; + MD_PSA_INIT(); mbedtls_md_init(&ctx); TEST_EQUAL(0, mbedtls_md_get_size(NULL)); @@ -101,6 +112,9 @@ void md_null_args() #if defined(MBEDTLS_MD_C) TEST_ASSERT(mbedtls_md_info_from_string("no such md") == NULL); #endif + +exit: + MD_PSA_DONE(); } /* END_CASE */ @@ -114,6 +128,8 @@ void md_info(int md_type, char *md_name, int md_size) (void) md_name; #endif + /* Note: PSA Crypto init not needed to info functions */ + md_info = mbedtls_md_info_from_type(md_type); TEST_ASSERT(md_info != NULL); #if defined(MBEDTLS_MD_C) @@ -144,12 +160,17 @@ void md_text(int md_type, char *text_src_string, data_t *hash) unsigned char output[MBEDTLS_MD_MAX_SIZE] = { 0 }; const mbedtls_md_info_t *md_info = NULL; + MD_PSA_INIT(); + md_info = mbedtls_md_info_from_type(md_type); TEST_ASSERT(md_info != NULL); TEST_EQUAL(0, mbedtls_md(md_info, src, src_len, output)); ASSERT_COMPARE(output, mbedtls_md_get_size(md_info), hash->x, hash->len); + +exit: + MD_PSA_DONE(); } /* END_CASE */ @@ -159,6 +180,8 @@ void md_hex(int md_type, data_t *src_str, data_t *hash) unsigned char output[MBEDTLS_MD_MAX_SIZE] = { 0 }; const mbedtls_md_info_t *md_info = NULL; + MD_PSA_INIT(); + md_info = mbedtls_md_info_from_type(md_type); TEST_ASSERT(md_info != NULL); @@ -166,6 +189,9 @@ void md_hex(int md_type, data_t *src_str, data_t *hash) ASSERT_COMPARE(output, mbedtls_md_get_size(md_info), hash->x, hash->len); + +exit: + MD_PSA_DONE(); } /* END_CASE */ @@ -181,6 +207,8 @@ void md_text_multi(int md_type, char *text_src_string, const mbedtls_md_info_t *md_info = NULL; mbedtls_md_context_t ctx, ctx_copy; + MD_PSA_INIT(); + mbedtls_md_init(&ctx); mbedtls_md_init(&ctx_copy); @@ -214,6 +242,7 @@ void md_text_multi(int md_type, char *text_src_string, exit: mbedtls_md_free(&ctx); mbedtls_md_free(&ctx_copy); + MD_PSA_DONE(); } /* END_CASE */ @@ -225,6 +254,8 @@ void md_hex_multi(int md_type, data_t *src_str, data_t *hash) mbedtls_md_context_t ctx, ctx_copy; int halfway; + MD_PSA_INIT(); + mbedtls_md_init(&ctx); mbedtls_md_init(&ctx_copy); @@ -258,6 +289,7 @@ void md_hex_multi(int md_type, data_t *src_str, data_t *hash) exit: mbedtls_md_free(&ctx); mbedtls_md_free(&ctx_copy); + MD_PSA_DONE(); } /* END_CASE */ @@ -269,6 +301,8 @@ void mbedtls_md_hmac(int md_type, int trunc_size, unsigned char output[MBEDTLS_MD_MAX_SIZE] = { 0 }; const mbedtls_md_info_t *md_info = NULL; + MD_PSA_INIT(); + md_info = mbedtls_md_info_from_type(md_type); TEST_ASSERT(md_info != NULL); @@ -277,6 +311,9 @@ void mbedtls_md_hmac(int md_type, int trunc_size, src_str->x, src_str->len, output)); ASSERT_COMPARE(output, trunc_size, hash->x, hash->len); + +exit: + MD_PSA_DONE(); } /* END_CASE */ @@ -289,6 +326,8 @@ void md_hmac_multi(int md_type, int trunc_size, data_t *key_str, mbedtls_md_context_t ctx; int halfway; + MD_PSA_INIT(); + mbedtls_md_init(&ctx); md_info = mbedtls_md_info_from_type(md_type); @@ -320,6 +359,7 @@ void md_hmac_multi(int md_type, int trunc_size, data_t *key_str, exit: mbedtls_md_free(&ctx); + MD_PSA_DONE(); } /* END_CASE */ @@ -330,11 +370,65 @@ void mbedtls_md_file(int md_type, char *filename, unsigned char output[MBEDTLS_MD_MAX_SIZE] = { 0 }; const mbedtls_md_info_t *md_info = NULL; + MD_PSA_INIT(); + md_info = mbedtls_md_info_from_type(md_type); TEST_ASSERT(md_info != NULL); TEST_EQUAL(0, mbedtls_md_file(md_info, filename, output)); ASSERT_COMPARE(output, mbedtls_md_get_size(md_info), hash->x, hash->len); + +exit: + MD_PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void md_psa_dynamic_dispatch(int md_type, int pre_psa_ret, int post_psa_engine) +{ + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); + TEST_ASSERT(md_info != NULL); + mbedtls_md_context_t ctx1, ctx2; + + /* Intentionally no PSA init here! (Will be done later.) */ + + mbedtls_md_init(&ctx1); + mbedtls_md_init(&ctx2); + + /* Before PSA crypto init */ + TEST_EQUAL(pre_psa_ret, mbedtls_md_setup(&ctx1, md_info, 0)); + TEST_EQUAL(pre_psa_ret, mbedtls_md_setup(&ctx2, md_info, 0)); + +#if defined(MBEDTLS_MD_SOME_PSA) + TEST_EQUAL(ctx1.engine, MBEDTLS_MD_ENGINE_LEGACY); + TEST_EQUAL(ctx2.engine, MBEDTLS_MD_ENGINE_LEGACY); +#endif + + /* Reset ctx1 but keep ctx2 for the cloning test */ + mbedtls_md_free(&ctx1); + mbedtls_md_init(&ctx1); + + /* Now initilize PSA Crypto */ + MD_PSA_INIT(); + + /* After PSA Crypto init */ + TEST_EQUAL(0, mbedtls_md_setup(&ctx1, md_info, 0)); +#if defined(MBEDTLS_MD_SOME_PSA) + TEST_EQUAL(ctx1.engine, post_psa_engine); +#endif + + /* Cloning test */ + if (pre_psa_ret == 0) { + int exp_clone_ret = post_psa_engine == MBEDTLS_MD_ENGINE_PSA + ? MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE + : 0; + TEST_EQUAL(exp_clone_ret, mbedtls_md_clone(&ctx2, &ctx1)); + } + +exit: + mbedtls_md_free(&ctx1); + mbedtls_md_free(&ctx2); + MD_PSA_DONE(); } /* END_CASE */ diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index eddac7fc16..86b2f667db 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1,3 +1,6 @@ +PSA can_do_hash +psa_can_do_hash: + PSA compile-time sanity checks static_checks: diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 231b47fca4..41a3237b3e 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -13,6 +13,9 @@ #include "psa/crypto.h" #include "psa_crypto_slot_management.h" +/* For psa_can_do_hash() */ +#include "psa_crypto_core.h" + #include "test/asn1_helpers.h" #include "test/psa_crypto_helpers.h" #include "test/psa_exercise_key.h" @@ -1255,6 +1258,18 @@ static void interruptible_signverify_get_minmax_completes(uint32_t max_ops, * END_DEPENDENCIES */ +/* BEGIN_CASE */ +void psa_can_do_hash() +{ + /* We can't test that this is specific to drivers until partial init has + * been implemented, but we can at least test before/after full init. */ + TEST_EQUAL(0, psa_can_do_hash(PSA_ALG_NONE)); + PSA_INIT(); + TEST_EQUAL(1, psa_can_do_hash(PSA_ALG_NONE)); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE */ void static_checks() {