diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 5217dac468..7866a36ec0 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -187,4 +187,5 @@ endif if BUILD_PSA src_libwolfssl_la_SOURCES += wolfcrypt/src/port/psa/psa.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/psa/psa_hash.c endif diff --git a/wolfcrypt/src/port/psa/psa_hash.c b/wolfcrypt/src/port/psa/psa_hash.c new file mode 100644 index 0000000000..38b27122a3 --- /dev/null +++ b/wolfcrypt/src/port/psa/psa_hash.c @@ -0,0 +1,276 @@ +/* psa_hash.c + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) + +#if !defined(NO_SHA) +#include +#endif + +#if !defined(NO_SHA256) +#include +#endif + +#include +#include + +#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA224) +static int wc_psa_hash_init_and_setup(psa_hash_operation_t *ctx, + psa_algorithm_t alg) +{ + psa_status_t s; + + if (ctx == NULL) + return BAD_FUNC_ARG; + + XMEMSET(ctx, 0, sizeof(*ctx)); + + s = psa_hash_setup(ctx, alg); + + if (s != PSA_SUCCESS) { + psa_hash_abort(ctx); + return WC_HW_E; + } + + return 0; +} + +static int wc_psa_hash_update(psa_hash_operation_t *ctx, const uint8_t *input, + size_t input_length) +{ + psa_status_t s; + + if (ctx == NULL || (input == NULL && input_length > 0)) + return BAD_FUNC_ARG; + + s = psa_hash_update(ctx, input, input_length); + + if (s != PSA_SUCCESS) { + psa_hash_abort(ctx); + return WC_HW_E; + } + + return 0; +} + +static int wc_psa_hash_finish_setup(psa_hash_operation_t *ctx, + uint8_t *output, psa_algorithm_t alg) +{ + size_t hash_length; + psa_status_t s; + + if (ctx == NULL || output == NULL) + return BAD_FUNC_ARG; + + s = psa_hash_finish(ctx, output, PSA_HASH_LENGTH(alg), &hash_length); + if (s != PSA_SUCCESS) { + psa_hash_abort(ctx); + return WC_HW_E; + } + + s = psa_hash_setup(ctx, alg); + if (s != PSA_SUCCESS) { + psa_hash_abort(ctx); + return WC_HW_E; + } + + return 0; +} + +static int wc_psa_hash_clone(const psa_hash_operation_t *src, + psa_hash_operation_t *dst) +{ + psa_status_t s; + + if (src == NULL || dst == NULL) + return BAD_FUNC_ARG; + + psa_hash_abort(dst); + + s = psa_hash_clone(src, dst); + if (s != PSA_SUCCESS) + return WC_HW_E; + + return 0; +} + +static int wc_psa_hash_abort(psa_hash_operation_t *ctx) +{ + psa_status_t s; + + if (ctx == NULL) + return BAD_FUNC_ARG; + + s = psa_hash_abort(ctx); + if (s != PSA_SUCCESS) + return WC_HW_E; + + return 0; +} + +static int wc_psa_get_hash(psa_hash_operation_t *ctx, + uint8_t *out, psa_algorithm_t alg) +{ + psa_hash_operation_t tmp; + size_t hash_length; + psa_status_t s; + + (void)hash_length; + + if (ctx == NULL || out == NULL) + return BAD_FUNC_ARG; + + XMEMSET(&tmp, 0, sizeof(tmp)); + s = psa_hash_clone(ctx, &tmp); + if (s != PSA_SUCCESS) { + psa_hash_abort(&tmp); + return WC_HW_E; + } + + s = psa_hash_finish(&tmp, out, PSA_HASH_LENGTH(alg), &hash_length); + if (s != PSA_SUCCESS) { + psa_hash_abort(&tmp); + return WC_HW_E; + } + + return 0; +} +#endif /* !defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA224)*/ + +#if !defined(NO_SHA) + +int wc_InitSha_ex(wc_Sha *sha, void *heap, int devId) +{ + (void)heap; + (void)devId; + + return wc_psa_hash_init_and_setup(&sha->psa_ctx, PSA_ALG_SHA_1); +} + +int wc_ShaUpdate(wc_Sha *sha, const byte *in, word32 size) +{ + return wc_psa_hash_update(&sha->psa_ctx, in, size); +} + +int wc_ShaFinal(wc_Sha *sha, byte *out) +{ + return wc_psa_hash_finish_setup(&sha->psa_ctx, out, PSA_ALG_SHA_1); +} + +int wc_ShaGetHash(wc_Sha *sha, byte *out) +{ + + return wc_psa_get_hash(&sha->psa_ctx, out, PSA_ALG_SHA_1); +} + +int wc_ShaCopy(wc_Sha *src, wc_Sha *dst) +{ + return wc_psa_hash_clone(&src->psa_ctx, &dst->psa_ctx); +} + +void wc_ShaFree(wc_Sha *sha) +{ + wc_psa_hash_abort(&sha->psa_ctx); +} +#endif /* !NO_SHA */ + +#if !defined(NO_SHA256) + +int wc_InitSha256_ex(wc_Sha256 *sha, void *heap, int devId) +{ + (void)heap; + (void)devId; + + return wc_psa_hash_init_and_setup(&sha->psa_ctx, PSA_ALG_SHA_256); +} + +int wc_Sha256Update(wc_Sha256 *sha, const byte *in, word32 size) +{ + return wc_psa_hash_update(&sha->psa_ctx, in, size); +} + +int wc_Sha256Final(wc_Sha256 *sha, byte *out) +{ + return wc_psa_hash_finish_setup(&sha->psa_ctx, out, PSA_ALG_SHA_256); +} + +int wc_Sha256GetHash(wc_Sha256 *sha, byte *out) +{ + return wc_psa_get_hash(&sha->psa_ctx, out, PSA_ALG_SHA_256); +} + +int wc_Sha256Copy(wc_Sha256 *src, wc_Sha256 *dst) +{ + return wc_psa_hash_clone(&src->psa_ctx, &dst->psa_ctx); +} + +void wc_Sha256Free(wc_Sha256 *sha) +{ + wc_psa_hash_abort(&sha->psa_ctx); +} + +#endif /* !NO_SHA256 */ + +#if defined(WOLFSSL_SHA224) + +int wc_InitSha224_ex(wc_Sha224 *sha, void *heap, int devId) +{ + (void)heap; + (void)devId; + + return wc_psa_hash_init_and_setup(&sha->psa_ctx, PSA_ALG_SHA_224); +} + +int wc_Sha224Update(wc_Sha224 *sha, const byte *in, word32 size) +{ + return wc_psa_hash_update(&sha->psa_ctx, in, size); +} + +int wc_Sha224Final(wc_Sha224 *sha, byte *out) +{ + return wc_psa_hash_finish_setup(&sha->psa_ctx, out, PSA_ALG_SHA_224); +} + +int wc_Sha224GetHash(wc_Sha224 *sha, byte *out) +{ + return wc_psa_get_hash(&sha->psa_ctx, out, PSA_ALG_SHA_224); +} + +int wc_Sha224Copy(wc_Sha224 *src, wc_Sha224 *dst) +{ + return wc_psa_hash_clone(&src->psa_ctx, &dst->psa_ctx); +} + +void wc_Sha224Free(wc_Sha224 *sha) +{ + wc_psa_hash_abort(&sha->psa_ctx); +} + +#endif /* WOLFSSL_SHA224 */ + +#endif /* WOLFSSL_HAVE_PSA && !WOLFSSL_PSA_NO_HASH */ diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 9df07ef147..bc38ae4f6f 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -370,6 +370,8 @@ return ret; } +#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) +/* implemented in wolfcrypt/src/port/psa/psa_hash.c */ #else /* Software implementation */ #define USE_SHA_SOFTWARE_IMPL @@ -832,6 +834,8 @@ int wc_InitSha(wc_Sha* sha) return wc_InitSha_ex(sha, NULL, INVALID_DEVID); } +#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) + void wc_ShaFree(wc_Sha* sha) { if (sha == NULL) @@ -859,6 +863,7 @@ void wc_ShaFree(wc_Sha* sha) #endif } +#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ #endif /* !WOLFSSL_TI_HASH */ #endif /* HAVE_FIPS */ @@ -866,6 +871,8 @@ void wc_ShaFree(wc_Sha* sha) #if !defined(WOLFSSL_RENESAS_TSIP_CRYPT) || \ defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) + +#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) int wc_ShaGetHash(wc_Sha* sha, byte* hash) { int ret; @@ -929,7 +936,7 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) } #endif /* defined(WOLFSSL_RENESAS_TSIP_CRYPT) ... */ #endif /* !WOLFSSL_TI_HASH && !WOLFSSL_IMXRT_DCP */ - +#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ #ifdef WOLFSSL_HASH_FLAGS int wc_ShaSetFlags(wc_Sha* sha, word32 flags) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 6f9ea61917..45dcb433f2 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -185,7 +185,8 @@ where 0 <= L < 2^64. (!defined(WOLFSSL_RENESAS_TSIP_CRYPT) || defined(NO_WOLFSSL_RENESAS_TSIP_HASH)) && \ !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050_HASH) && \ - (!defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(NO_WOLFSSL_RENESAS_SCEPROTECT_HASH)) + (!defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(NO_WOLFSSL_RENESAS_SCEPROTECT_HASH)) && \ + (!defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)) @@ -765,6 +766,9 @@ static int InitSha256(wc_Sha256* sha256) #elif defined(WOLFSSL_KCAPI_HASH) /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) + /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ + #else #define NEED_SOFT_SHA256 @@ -1459,6 +1463,9 @@ static int InitSha256(wc_Sha256* sha256) #elif defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224) /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) + /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ + #else #define NEED_SOFT_SHA224 @@ -1582,6 +1589,9 @@ static int InitSha256(wc_Sha256* sha256) return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID); } +#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) + /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ + void wc_Sha224Free(wc_Sha224* sha224) { if (sha224 == NULL) @@ -1606,6 +1616,7 @@ static int InitSha256(wc_Sha256* sha256) #endif } #endif /* WOLFSSL_SHA224 */ +#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ int wc_InitSha256(wc_Sha256* sha256) @@ -1613,6 +1624,9 @@ int wc_InitSha256(wc_Sha256* sha256) return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID); } +#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) + /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ + void wc_Sha256Free(wc_Sha256* sha256) { if (sha256 == NULL) @@ -1664,6 +1678,7 @@ void wc_Sha256Free(wc_Sha256* sha256) #endif } +#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ #endif /* !WOLFSSL_TI_HASH */ #endif /* HAVE_FIPS */ @@ -1673,6 +1688,8 @@ void wc_Sha256Free(wc_Sha256* sha256) #if defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224) /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) + /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ #else @@ -1762,6 +1779,9 @@ void wc_Sha256Free(wc_Sha256* sha256) #elif defined(WOLFSSL_KCAPI_HASH) /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */ +#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) + /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ + #else int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash) diff --git a/wolfssl/wolfcrypt/port/psa/psa.h b/wolfssl/wolfcrypt/port/psa/psa.h index d02fade920..aea8fe91e1 100644 --- a/wolfssl/wolfcrypt/port/psa/psa.h +++ b/wolfssl/wolfcrypt/port/psa/psa.h @@ -29,6 +29,7 @@ * * WOLFSSL_HAVE_PSA: Global switch to enable PSA * WOLFSSL_PSA_NO_RNG: disable PSA random generator support + * WOLFSSL_PSA_NO_HASH: disable PSA hashing support */ #ifndef WOLFSSL_PSA_H @@ -44,6 +45,7 @@ #include #include +#include int wc_psa_init(void); diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index 1f3de3b09c..ad93830cde 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -114,6 +114,12 @@ enum { #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" #endif +#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) +#include +#undef WOLFSSL_NO_HASH_RAW +#define WOLFSSL_NO_HASH_RAW +#endif + /* Sha digest */ struct wc_Sha { #ifdef FREESCALE_LTC_SHA @@ -127,6 +133,8 @@ struct wc_Sha { #elif defined(WOLFSSL_IMXRT_DCP) dcp_handle_t handle; dcp_hash_ctx_t ctx; +#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) + psa_hash_operation_t psa_ctx; #else word32 buffLen; /* in bytes */ word32 loLen; /* length in bytes */ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 1f50306047..56a9ae859d 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -105,6 +105,12 @@ #include "wolfssl/wolfcrypt/port/kcapi/kcapi_hash.h" #endif +#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) +#include +#undef WOLFSSL_NO_HASH_RAW +#define WOLFSSL_NO_HASH_RAW +#endif + #if defined(_MSC_VER) #define SHA256_NOINLINE __declspec(noinline) #elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) @@ -168,6 +174,8 @@ struct wc_Sha256 { cy_stc_crypto_sha_state_t hash_state; cy_en_crypto_sha_mode_t sha_mode; cy_stc_crypto_v2_sha256_buffers_t sha_buffers; +#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) + psa_hash_operation_t psa_ctx; #else /* alignment on digest and buffer speeds up ARMv8 crypto operations */ ALIGN16 word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)];