Merge pull request #4157 from stevew817/dispatch_hash_operations
Dispatch hash operations through the driver wrapper layer
diff --git a/include/psa/crypto_builtin_hash.h b/include/psa/crypto_builtin_hash.h
new file mode 100644
index 0000000..64323bf
--- /dev/null
+++ b/include/psa/crypto_builtin_hash.h
@@ -0,0 +1,89 @@
+/*
+ * Context structure declaration of the software-based driver which performs
+ * hashing through the PSA Crypto driver dispatch layer.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PSA_CRYPTO_BUILTIN_HASH_H
+#define PSA_CRYPTO_BUILTIN_HASH_H
+
+#include <psa/crypto_driver_common.h>
+#include "mbedtls/md2.h"
+#include "mbedtls/md4.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/ripemd160.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
+#define MBEDTLS_PSA_BUILTIN_HASH
+#endif
+
+typedef struct
+{
+ psa_algorithm_t alg;
+ union
+ {
+ unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
+#if defined(MBEDTLS_MD2_C)
+ mbedtls_md2_context md2;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ mbedtls_md4_context md4;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ mbedtls_md5_context md5;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ mbedtls_ripemd160_context ripemd160;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ mbedtls_sha1_context sha1;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ mbedtls_sha256_context sha256;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ mbedtls_sha512_context sha512;
+#endif
+ } ctx;
+} mbedtls_psa_hash_operation_t;
+
+#define MBEDTLS_PSA_HASH_OPERATION_INIT {0, {0}}
+
+/*
+ * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY.
+ */
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+
+typedef mbedtls_psa_hash_operation_t mbedtls_transparent_test_driver_hash_operation_t;
+
+#define MBEDTLS_TRANSPARENT_TEST_DRIVER_HASH_OPERATION_INIT MBEDTLS_PSA_HASH_OPERATION_INIT
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+
+#endif /* PSA_CRYPTO_BUILTIN_HASH_H */
diff --git a/include/psa/crypto_driver_contexts.h b/include/psa/crypto_driver_contexts.h
new file mode 100644
index 0000000..fdf178f
--- /dev/null
+++ b/include/psa/crypto_driver_contexts.h
@@ -0,0 +1,51 @@
+/*
+ * Declaration of context structures for use with the PSA driver wrapper
+ * interface.
+ *
+ * Warning: This file will be auto-generated in the future.
+ */
+/* Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PSA_CRYPTO_DRIVER_CONTEXTS_H
+#define PSA_CRYPTO_DRIVER_CONTEXTS_H
+
+#include "psa/crypto.h"
+#include "psa/crypto_driver_common.h"
+
+/* Include the context structure definitions for those drivers that were
+ * declared during the autogeneration process. */
+
+/* Include the context structure definitions for the Mbed TLS software drivers */
+#include "psa/crypto_builtin_hash.h"
+
+/* Define the context to be used for an operation that is executed through the
+ * PSA Driver wrapper layer as the union of all possible driver's contexts.
+ *
+ * The union members are the driver's context structures, and the member names
+ * are formatted as `'drivername'_ctx`. This allows for procedural generation
+ * of both this file and the content of psa_crypto_driver_wrappers.c */
+
+typedef union {
+ unsigned dummy; /* Make sure this structure is always non-empty */
+ mbedtls_psa_hash_operation_t mbedtls_ctx;
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+ mbedtls_transparent_test_driver_hash_operation_t test_driver_ctx;
+#endif
+} psa_driver_hash_context_t;
+
+#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_H */
+/* End of automatically generated file. */
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 04ece6d..87eefb9 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -68,14 +68,9 @@
#include "mbedtls/cipher.h"
#include "mbedtls/cmac.h"
#include "mbedtls/gcm.h"
-#include "mbedtls/md.h"
-#include "mbedtls/md2.h"
-#include "mbedtls/md4.h"
-#include "mbedtls/md5.h"
-#include "mbedtls/ripemd160.h"
-#include "mbedtls/sha1.h"
-#include "mbedtls/sha256.h"
-#include "mbedtls/sha512.h"
+
+/* Include the context definition for the compiled-in drivers */
+#include "psa/crypto_driver_contexts.h"
typedef struct {
/** Unique ID indicating which driver got assigned to do the
@@ -89,32 +84,14 @@
struct psa_hash_operation_s
{
- psa_algorithm_t alg;
- union
- {
- unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
-#if defined(MBEDTLS_MD2_C)
- mbedtls_md2_context md2;
-#endif
-#if defined(MBEDTLS_MD4_C)
- mbedtls_md4_context md4;
-#endif
-#if defined(MBEDTLS_MD5_C)
- mbedtls_md5_context md5;
-#endif
-#if defined(MBEDTLS_RIPEMD160_C)
- mbedtls_ripemd160_context ripemd160;
-#endif
-#if defined(MBEDTLS_SHA1_C)
- mbedtls_sha1_context sha1;
-#endif
-#if defined(MBEDTLS_SHA256_C)
- mbedtls_sha256_context sha256;
-#endif
-#if defined(MBEDTLS_SHA512_C)
- mbedtls_sha512_context sha512;
-#endif
- } ctx;
+ /** Unique ID indicating which driver got assigned to do the
+ * operation. Since driver contexts are driver-specific, swapping
+ * drivers halfway through the operation is not supported.
+ * ID values are auto-generated in psa_driver_wrappers.h
+ * ID value zero means the context is not valid or not assigned to
+ * any driver (i.e. none of the driver contexts are active). */
+ unsigned int id;
+ psa_driver_hash_context_t ctx;
};
#define PSA_HASH_OPERATION_INIT {0, {0}}
@@ -127,6 +104,8 @@
#if defined(MBEDTLS_MD_C)
typedef struct
{
+ /** The HMAC algorithm in use */
+ psa_algorithm_t alg;
/** The hash context. */
struct psa_hash_operation_s hash_ctx;
/** The HMAC part of the context. */
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index c7542b5..2b2672e 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -64,6 +64,7 @@
psa_crypto_client.c
psa_crypto_driver_wrappers.c
psa_crypto_ecp.c
+ psa_crypto_hash.c
psa_crypto_rsa.c
psa_crypto_se.c
psa_crypto_slot_management.c
diff --git a/library/Makefile b/library/Makefile
index 6bb9c17..e9829cc 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -121,6 +121,7 @@
psa_crypto_client.o \
psa_crypto_driver_wrappers.o \
psa_crypto_ecp.o \
+ psa_crypto_hash.o \
psa_crypto_rsa.o \
psa_crypto_se.o \
psa_crypto_slot_management.o \
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 6225272..8c61cb9 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -33,6 +33,7 @@
#include "psa_crypto_invasive.h"
#include "psa_crypto_driver_wrappers.h"
#include "psa_crypto_ecp.h"
+#include "psa_crypto_hash.h"
#include "psa_crypto_rsa.h"
#include "psa_crypto_ecp.h"
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@@ -2141,274 +2142,53 @@
/* Message digests */
/****************************************************************/
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
- defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
- defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
- defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
-const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
-{
- switch( alg )
- {
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
- case PSA_ALG_MD2:
- return( &mbedtls_md2_info );
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
- case PSA_ALG_MD4:
- return( &mbedtls_md4_info );
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
- case PSA_ALG_MD5:
- return( &mbedtls_md5_info );
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
- case PSA_ALG_RIPEMD160:
- return( &mbedtls_ripemd160_info );
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
- case PSA_ALG_SHA_1:
- return( &mbedtls_sha1_info );
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
- case PSA_ALG_SHA_224:
- return( &mbedtls_sha224_info );
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
- case PSA_ALG_SHA_256:
- return( &mbedtls_sha256_info );
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
- case PSA_ALG_SHA_384:
- return( &mbedtls_sha384_info );
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
- case PSA_ALG_SHA_512:
- return( &mbedtls_sha512_info );
-#endif
- default:
- return( NULL );
- }
-}
-#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
- * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
- * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
- * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
-
psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
{
- switch( operation->alg )
- {
- case 0:
- /* The object has (apparently) been initialized but it is not
- * in use. It's ok to call abort on such an object, and there's
- * nothing to do. */
- break;
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
- case PSA_ALG_MD2:
- mbedtls_md2_free( &operation->ctx.md2 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
- case PSA_ALG_MD4:
- mbedtls_md4_free( &operation->ctx.md4 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
- case PSA_ALG_MD5:
- mbedtls_md5_free( &operation->ctx.md5 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
- case PSA_ALG_RIPEMD160:
- mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
- case PSA_ALG_SHA_1:
- mbedtls_sha1_free( &operation->ctx.sha1 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
- case PSA_ALG_SHA_224:
- mbedtls_sha256_free( &operation->ctx.sha256 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
- case PSA_ALG_SHA_256:
- mbedtls_sha256_free( &operation->ctx.sha256 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
- case PSA_ALG_SHA_384:
- mbedtls_sha512_free( &operation->ctx.sha512 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
- case PSA_ALG_SHA_512:
- mbedtls_sha512_free( &operation->ctx.sha512 );
- break;
-#endif
- default:
- return( PSA_ERROR_BAD_STATE );
- }
- operation->alg = 0;
- return( PSA_SUCCESS );
+ /* Aborting a non-active operation is allowed */
+ if( operation->id == 0 )
+ return( PSA_SUCCESS );
+
+ psa_status_t status = psa_driver_wrapper_hash_abort( operation );
+ operation->id = 0;
+
+ return( status );
}
psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
psa_algorithm_t alg )
{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
/* A context must be freshly initialized before it can be set up. */
- if( operation->alg != 0 )
- {
+ if( operation->id != 0 )
return( PSA_ERROR_BAD_STATE );
- }
- switch( alg )
- {
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
- case PSA_ALG_MD2:
- mbedtls_md2_init( &operation->ctx.md2 );
- ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
- case PSA_ALG_MD4:
- mbedtls_md4_init( &operation->ctx.md4 );
- ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
- case PSA_ALG_MD5:
- mbedtls_md5_init( &operation->ctx.md5 );
- ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
- case PSA_ALG_RIPEMD160:
- mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
- ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
- case PSA_ALG_SHA_1:
- mbedtls_sha1_init( &operation->ctx.sha1 );
- ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
- case PSA_ALG_SHA_224:
- mbedtls_sha256_init( &operation->ctx.sha256 );
- ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
- case PSA_ALG_SHA_256:
- mbedtls_sha256_init( &operation->ctx.sha256 );
- ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
- case PSA_ALG_SHA_384:
- mbedtls_sha512_init( &operation->ctx.sha512 );
- ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
- case PSA_ALG_SHA_512:
- mbedtls_sha512_init( &operation->ctx.sha512 );
- ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
- break;
-#endif
- default:
- return( PSA_ALG_IS_HASH( alg ) ?
- PSA_ERROR_NOT_SUPPORTED :
- PSA_ERROR_INVALID_ARGUMENT );
- }
- if( ret == 0 )
- operation->alg = alg;
- else
- psa_hash_abort( operation );
- return( mbedtls_to_psa_error( ret ) );
+ if( !PSA_ALG_IS_HASH( alg ) )
+ return( PSA_ERROR_INVALID_ARGUMENT );
+
+ /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
+ * directly zeroes the int-sized dummy member of the context union. */
+ memset( &operation->ctx, 0, sizeof( operation->ctx ) );
+
+ return( psa_driver_wrapper_hash_setup( operation, alg ) );
}
psa_status_t psa_hash_update( psa_hash_operation_t *operation,
const uint8_t *input,
size_t input_length )
{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ if( operation->id == 0 )
+ return( PSA_ERROR_BAD_STATE );
/* Don't require hash implementations to behave correctly on a
* zero-length input, which may have an invalid pointer. */
if( input_length == 0 )
return( PSA_SUCCESS );
- switch( operation->alg )
- {
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
- case PSA_ALG_MD2:
- ret = mbedtls_md2_update_ret( &operation->ctx.md2,
- input, input_length );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
- case PSA_ALG_MD4:
- ret = mbedtls_md4_update_ret( &operation->ctx.md4,
- input, input_length );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
- case PSA_ALG_MD5:
- ret = mbedtls_md5_update_ret( &operation->ctx.md5,
- input, input_length );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
- case PSA_ALG_RIPEMD160:
- ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
- input, input_length );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
- case PSA_ALG_SHA_1:
- ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
- input, input_length );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
- case PSA_ALG_SHA_224:
- ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
- input, input_length );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
- case PSA_ALG_SHA_256:
- ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
- input, input_length );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
- case PSA_ALG_SHA_384:
- ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
- input, input_length );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
- case PSA_ALG_SHA_512:
- ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
- input, input_length );
- break;
-#endif
- default:
- (void)input;
- return( PSA_ERROR_BAD_STATE );
- }
-
- if( ret != 0 )
+ psa_status_t status = psa_driver_wrapper_hash_update( operation,
+ input, input_length );
+ if( status != PSA_SUCCESS )
psa_hash_abort( operation );
- return( mbedtls_to_psa_error( ret ) );
+
+ return( status );
}
psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
@@ -2416,88 +2196,14 @@
size_t hash_size,
size_t *hash_length )
{
- psa_status_t status;
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t actual_hash_length = PSA_HASH_LENGTH( operation->alg );
+ *hash_length = 0;
+ if( operation->id == 0 )
+ return( PSA_ERROR_BAD_STATE );
- /* Fill the output buffer with something that isn't a valid hash
- * (barring an attack on the hash and deliberately-crafted input),
- * in case the caller doesn't check the return status properly. */
- *hash_length = hash_size;
- /* If hash_size is 0 then hash may be NULL and then the
- * call to memset would have undefined behavior. */
- if( hash_size != 0 )
- memset( hash, '!', hash_size );
-
- if( hash_size < actual_hash_length )
- {
- status = PSA_ERROR_BUFFER_TOO_SMALL;
- goto exit;
- }
-
- switch( operation->alg )
- {
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
- case PSA_ALG_MD2:
- ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
- case PSA_ALG_MD4:
- ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
- case PSA_ALG_MD5:
- ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
- case PSA_ALG_RIPEMD160:
- ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
- case PSA_ALG_SHA_1:
- ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
- case PSA_ALG_SHA_224:
- ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
- case PSA_ALG_SHA_256:
- ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
- case PSA_ALG_SHA_384:
- ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
- case PSA_ALG_SHA_512:
- ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
- break;
-#endif
- default:
- return( PSA_ERROR_BAD_STATE );
- }
- status = mbedtls_to_psa_error( ret );
-
-exit:
- if( status == PSA_SUCCESS )
- {
- *hash_length = actual_hash_length;
- return( psa_hash_abort( operation ) );
- }
- else
- {
- psa_hash_abort( operation );
- return( status );
- }
+ psa_status_t status = psa_driver_wrapper_hash_finish(
+ operation, hash, hash_size, hash_length );
+ psa_hash_abort( operation );
+ return( status );
}
psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
@@ -2506,9 +2212,10 @@
{
uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
size_t actual_hash_length;
- psa_status_t status = psa_hash_finish( operation,
- actual_hash, sizeof( actual_hash ),
- &actual_hash_length );
+ psa_status_t status = psa_hash_finish(
+ operation,
+ actual_hash, sizeof( actual_hash ),
+ &actual_hash_length );
if( status != PSA_SUCCESS )
return( status );
if( actual_hash_length != hash_length )
@@ -2523,123 +2230,52 @@
uint8_t *hash, size_t hash_size,
size_t *hash_length )
{
- psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
- psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ *hash_length = 0;
+ if( !PSA_ALG_IS_HASH( alg ) )
+ return( PSA_ERROR_INVALID_ARGUMENT );
- *hash_length = hash_size;
- status = psa_hash_setup( &operation, alg );
- if( status != PSA_SUCCESS )
- goto exit;
- status = psa_hash_update( &operation, input, input_length );
- if( status != PSA_SUCCESS )
- goto exit;
- status = psa_hash_finish( &operation, hash, hash_size, hash_length );
- if( status != PSA_SUCCESS )
- goto exit;
-
-exit:
- if( status == PSA_SUCCESS )
- status = psa_hash_abort( &operation );
- else
- psa_hash_abort( &operation );
- return( status );
+ return( psa_driver_wrapper_hash_compute( alg, input, input_length,
+ hash, hash_size, hash_length ) );
}
psa_status_t psa_hash_compare( psa_algorithm_t alg,
const uint8_t *input, size_t input_length,
const uint8_t *hash, size_t hash_length )
{
- psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
- psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
+ size_t actual_hash_length;
- status = psa_hash_setup( &operation, alg );
- if( status != PSA_SUCCESS )
- goto exit;
- status = psa_hash_update( &operation, input, input_length );
- if( status != PSA_SUCCESS )
- goto exit;
- status = psa_hash_verify( &operation, hash, hash_length );
- if( status != PSA_SUCCESS )
- goto exit;
+ if( !PSA_ALG_IS_HASH( alg ) )
+ return( PSA_ERROR_INVALID_ARGUMENT );
-exit:
- if( status == PSA_SUCCESS )
- status = psa_hash_abort( &operation );
- else
- psa_hash_abort( &operation );
- return( status );
+ psa_status_t status = psa_driver_wrapper_hash_compute(
+ alg, input, input_length,
+ actual_hash, sizeof(actual_hash),
+ &actual_hash_length );
+ if( status != PSA_SUCCESS )
+ return( status );
+ if( actual_hash_length != hash_length )
+ return( PSA_ERROR_INVALID_SIGNATURE );
+ if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
+ return( PSA_ERROR_INVALID_SIGNATURE );
+ return( PSA_SUCCESS );
}
psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation )
{
- if( target_operation->alg != 0 )
- return( PSA_ERROR_BAD_STATE );
-
- switch( source_operation->alg )
+ if( source_operation->id == 0 ||
+ target_operation->id != 0 )
{
- case 0:
- return( PSA_ERROR_BAD_STATE );
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
- case PSA_ALG_MD2:
- mbedtls_md2_clone( &target_operation->ctx.md2,
- &source_operation->ctx.md2 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4)
- case PSA_ALG_MD4:
- mbedtls_md4_clone( &target_operation->ctx.md4,
- &source_operation->ctx.md4 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
- case PSA_ALG_MD5:
- mbedtls_md5_clone( &target_operation->ctx.md5,
- &source_operation->ctx.md5 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
- case PSA_ALG_RIPEMD160:
- mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
- &source_operation->ctx.ripemd160 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
- case PSA_ALG_SHA_1:
- mbedtls_sha1_clone( &target_operation->ctx.sha1,
- &source_operation->ctx.sha1 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
- case PSA_ALG_SHA_224:
- mbedtls_sha256_clone( &target_operation->ctx.sha256,
- &source_operation->ctx.sha256 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
- case PSA_ALG_SHA_256:
- mbedtls_sha256_clone( &target_operation->ctx.sha256,
- &source_operation->ctx.sha256 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
- case PSA_ALG_SHA_384:
- mbedtls_sha512_clone( &target_operation->ctx.sha512,
- &source_operation->ctx.sha512 );
- break;
-#endif
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
- case PSA_ALG_SHA_512:
- mbedtls_sha512_clone( &target_operation->ctx.sha512,
- &source_operation->ctx.sha512 );
- break;
-#endif
- default:
- return( PSA_ERROR_NOT_SUPPORTED );
+ return( PSA_ERROR_BAD_STATE );
}
- target_operation->alg = source_operation->alg;
- return( PSA_SUCCESS );
+ psa_status_t status = psa_driver_wrapper_hash_clone( source_operation,
+ target_operation );
+ if( status != PSA_SUCCESS )
+ psa_hash_abort( target_operation );
+
+ return( status );
}
@@ -2795,7 +2431,7 @@
if( PSA_ALG_IS_HMAC( operation->alg ) )
{
/* We'll set up the hash operation later in psa_hmac_setup_internal. */
- operation->ctx.hmac.hash_ctx.alg = 0;
+ operation->ctx.hmac.alg = 0;
status = PSA_SUCCESS;
}
else
@@ -2902,6 +2538,8 @@
size_t block_size = psa_get_hash_block_size( hash_alg );
psa_status_t status;
+ hmac->alg = hash_alg;
+
/* Sanity checks on block_size, to guarantee that there won't be a buffer
* overflow below. This should never trigger if the hash algorithm
* is implemented correctly. */
@@ -3119,7 +2757,7 @@
size_t mac_size )
{
uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
- psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
+ psa_algorithm_t hash_alg = hmac->alg;
size_t hash_size = 0;
size_t block_size = psa_get_hash_block_size( hash_alg );
psa_status_t status;
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index da69044..ec7ac80 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -30,8 +30,6 @@
#include "psa/crypto.h"
#include "psa/crypto_se_driver.h"
-#include <mbedtls/md_internal.h>
-
/** The data structure representing a key slot, containing key material
* and metadata for one key.
*/
@@ -214,15 +212,6 @@
*/
psa_status_t mbedtls_to_psa_error( int ret );
-/** Get Mbed TLS MD information of a hash algorithm given its PSA identifier
- *
- * \param[in] alg PSA hash algorithm identifier
- *
- * \return The Mbed TLS MD information of the hash algorithm. \c NULL if the
- * PSA hash algorithm is not supported.
- */
-const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg );
-
/** Import a key in binary format.
*
* \note The signature of this function is that of a PSA driver
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 6cf23ce..6c94472 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -21,6 +21,8 @@
#include "psa_crypto_core.h"
#include "psa_crypto_driver_wrappers.h"
+#include "psa_crypto_hash.h"
+
#include "mbedtls/platform.h"
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
@@ -37,15 +39,18 @@
#endif /* PSA_CRYPTO_DRIVER_TEST */
/* Repeat above block for each JSON-declared driver during autogeneration */
-
-/* Auto-generated values depending on which drivers are registered. ID 0 is
- * reserved for unallocated operations. */
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-#define PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID (1)
-#define PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID (2)
-#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
+/* Auto-generated values depending on which drivers are registered.
+ * ID 0 is reserved for unallocated operations.
+ * ID 1 is reserved for the Mbed TLS software driver. */
+#define PSA_CRYPTO_MBED_TLS_DRIVER_ID (1)
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#define PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID (2)
+#define PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID (3)
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+
/* Support the 'old' SE interface when asked to */
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style
@@ -1066,4 +1071,172 @@
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
}
+/*
+ * Hashing functions
+ */
+psa_status_t psa_driver_wrapper_hash_compute(
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ /* Try accelerators first */
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+ status = mbedtls_transparent_test_driver_hash_compute(
+ alg, input, input_length, hash, hash_size, hash_length );
+ if( status != PSA_ERROR_NOT_SUPPORTED )
+ return( status );
+#endif
+
+ /* If software fallback is compiled in, try fallback */
+#if defined(MBEDTLS_PSA_BUILTIN_HASH)
+ status = mbedtls_psa_hash_compute( alg, input, input_length,
+ hash, hash_size, hash_length );
+ if( status != PSA_ERROR_NOT_SUPPORTED )
+ return( status );
+#endif
+ (void) status;
+ (void) alg;
+ (void) input;
+ (void) input_length;
+ (void) hash;
+ (void) hash_size;
+ (void) hash_length;
+
+ return( PSA_ERROR_NOT_SUPPORTED );
+}
+
+psa_status_t psa_driver_wrapper_hash_setup(
+ psa_hash_operation_t *operation,
+ psa_algorithm_t alg )
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ /* Try setup on accelerators first */
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+ status = mbedtls_transparent_test_driver_hash_setup(
+ &operation->ctx.test_driver_ctx, alg );
+ if( status == PSA_SUCCESS )
+ operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+
+ if( status != PSA_ERROR_NOT_SUPPORTED )
+ return( status );
+#endif
+
+ /* If software fallback is compiled in, try fallback */
+#if defined(MBEDTLS_PSA_BUILTIN_HASH)
+ status = mbedtls_psa_hash_setup( &operation->ctx.mbedtls_ctx, alg );
+ if( status == PSA_SUCCESS )
+ operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
+
+ if( status != PSA_ERROR_NOT_SUPPORTED )
+ return( status );
+#endif
+ /* Nothing left to try if we fall through here */
+ (void) status;
+ (void) operation;
+ (void) alg;
+ return( PSA_ERROR_NOT_SUPPORTED );
+}
+
+psa_status_t psa_driver_wrapper_hash_clone(
+ const psa_hash_operation_t *source_operation,
+ psa_hash_operation_t *target_operation )
+{
+ switch( source_operation->id )
+ {
+#if defined(MBEDTLS_PSA_BUILTIN_HASH)
+ case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+ target_operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
+ return( mbedtls_psa_hash_clone( &source_operation->ctx.mbedtls_ctx,
+ &target_operation->ctx.mbedtls_ctx ) );
+#endif
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+ case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+ target_operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+ return( mbedtls_transparent_test_driver_hash_clone(
+ &source_operation->ctx.test_driver_ctx,
+ &target_operation->ctx.test_driver_ctx ) );
+#endif
+ default:
+ (void) target_operation;
+ return( PSA_ERROR_BAD_STATE );
+ }
+}
+
+psa_status_t psa_driver_wrapper_hash_update(
+ psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length )
+{
+ switch( operation->id )
+ {
+#if defined(MBEDTLS_PSA_BUILTIN_HASH)
+ case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+ return( mbedtls_psa_hash_update( &operation->ctx.mbedtls_ctx,
+ input, input_length ) );
+#endif
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+ case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+ return( mbedtls_transparent_test_driver_hash_update(
+ &operation->ctx.test_driver_ctx,
+ input, input_length ) );
+#endif
+ default:
+ (void) input;
+ (void) input_length;
+ return( PSA_ERROR_BAD_STATE );
+ }
+}
+
+psa_status_t psa_driver_wrapper_hash_finish(
+ psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length )
+{
+ switch( operation->id )
+ {
+#if defined(MBEDTLS_PSA_BUILTIN_HASH)
+ case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+ return( mbedtls_psa_hash_finish( &operation->ctx.mbedtls_ctx,
+ hash, hash_size, hash_length ) );
+#endif
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+ case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+ return( mbedtls_transparent_test_driver_hash_finish(
+ &operation->ctx.test_driver_ctx,
+ hash, hash_size, hash_length ) );
+#endif
+ default:
+ (void) hash;
+ (void) hash_size;
+ (void) hash_length;
+ return( PSA_ERROR_BAD_STATE );
+ }
+}
+
+psa_status_t psa_driver_wrapper_hash_abort(
+ psa_hash_operation_t *operation )
+{
+ switch( operation->id )
+ {
+#if defined(MBEDTLS_PSA_BUILTIN_HASH)
+ case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
+ return( mbedtls_psa_hash_abort( &operation->ctx.mbedtls_ctx ) );
+#endif
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+ case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+ return( mbedtls_transparent_test_driver_hash_abort(
+ &operation->ctx.test_driver_ctx ) );
+#endif
+ default:
+ return( PSA_ERROR_BAD_STATE );
+ }
+}
+
/* End of automatically generated file. */
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index 22d22d6..dd7c6c7 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -127,6 +127,39 @@
psa_status_t psa_driver_wrapper_cipher_abort(
psa_operation_driver_context_t *operation );
+/*
+ * Hashing functions
+ */
+psa_status_t psa_driver_wrapper_hash_compute(
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length);
+
+psa_status_t psa_driver_wrapper_hash_setup(
+ psa_hash_operation_t *operation,
+ psa_algorithm_t alg );
+
+psa_status_t psa_driver_wrapper_hash_clone(
+ const psa_hash_operation_t *source_operation,
+ psa_hash_operation_t *target_operation );
+
+psa_status_t psa_driver_wrapper_hash_update(
+ psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length );
+
+psa_status_t psa_driver_wrapper_hash_finish(
+ psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length );
+
+psa_status_t psa_driver_wrapper_hash_abort(
+ psa_hash_operation_t *operation );
+
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */
/* End of automatically generated file. */
diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c
index 75ab169..3ce232c 100644
--- a/library/psa_crypto_ecp.c
+++ b/library/psa_crypto_ecp.c
@@ -26,6 +26,7 @@
#include "psa_crypto_core.h"
#include "psa_crypto_ecp.h"
#include "psa_crypto_random_impl.h"
+#include "psa_crypto_hash.h"
#include <stdlib.h>
#include <string.h>
diff --git a/library/psa_crypto_hash.c b/library/psa_crypto_hash.c
new file mode 100644
index 0000000..7552100
--- /dev/null
+++ b/library/psa_crypto_hash.c
@@ -0,0 +1,697 @@
+/*
+ * PSA hashing layer on top of Mbed TLS software crypto
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+
+#include <psa/crypto.h>
+#include "psa_crypto_core.h"
+#include "psa_crypto_hash.h"
+
+#include <mbedtls/error.h>
+#include <string.h>
+
+/* Use builtin defines specific to this compilation unit, since the test driver
+ * relies on the software driver. */
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_MD2) ) )
+#define BUILTIN_ALG_MD2 1
+#endif
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_MD4) ) )
+#define BUILTIN_ALG_MD4 1
+#endif
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_MD5) ) )
+#define BUILTIN_ALG_MD5 1
+#endif
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) ) )
+#define BUILTIN_ALG_RIPEMD160 1
+#endif
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) ) )
+#define BUILTIN_ALG_SHA_1 1
+#endif
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) ) )
+#define BUILTIN_ALG_SHA_224 1
+#endif
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) ) )
+#define BUILTIN_ALG_SHA_256 1
+#endif
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) ) )
+#define BUILTIN_ALG_SHA_384 1
+#endif
+#if( defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) || \
+ ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) ) )
+#define BUILTIN_ALG_SHA_512 1
+#endif
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
+const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
+{
+ switch( alg )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case PSA_ALG_MD2:
+ return( &mbedtls_md2_info );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case PSA_ALG_MD4:
+ return( &mbedtls_md4_info );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case PSA_ALG_MD5:
+ return( &mbedtls_md5_info );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case PSA_ALG_RIPEMD160:
+ return( &mbedtls_ripemd160_info );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case PSA_ALG_SHA_1:
+ return( &mbedtls_sha1_info );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case PSA_ALG_SHA_224:
+ return( &mbedtls_sha224_info );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case PSA_ALG_SHA_256:
+ return( &mbedtls_sha256_info );
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ case PSA_ALG_SHA_384:
+ return( &mbedtls_sha384_info );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case PSA_ALG_SHA_512:
+ return( &mbedtls_sha512_info );
+#endif
+ default:
+ return( NULL );
+ }
+}
+#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
+ * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
+ * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
+ * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
+
+/* Implement the PSA driver hash interface on top of mbed TLS if either the
+ * software driver or the test driver requires it. */
+#if defined(MBEDTLS_PSA_BUILTIN_HASH) || defined(PSA_CRYPTO_DRIVER_TEST)
+static psa_status_t hash_abort(
+ mbedtls_psa_hash_operation_t *operation )
+{
+ switch( operation->alg )
+ {
+ case 0:
+ /* The object has (apparently) been initialized but it is not
+ * in use. It's ok to call abort on such an object, and there's
+ * nothing to do. */
+ break;
+#if defined(BUILTIN_ALG_MD2)
+ case PSA_ALG_MD2:
+ mbedtls_md2_free( &operation->ctx.md2 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD4)
+ case PSA_ALG_MD4:
+ mbedtls_md4_free( &operation->ctx.md4 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD5)
+ case PSA_ALG_MD5:
+ mbedtls_md5_free( &operation->ctx.md5 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_RIPEMD160)
+ case PSA_ALG_RIPEMD160:
+ mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_1)
+ case PSA_ALG_SHA_1:
+ mbedtls_sha1_free( &operation->ctx.sha1 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_224)
+ case PSA_ALG_SHA_224:
+ mbedtls_sha256_free( &operation->ctx.sha256 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_256)
+ case PSA_ALG_SHA_256:
+ mbedtls_sha256_free( &operation->ctx.sha256 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_384)
+ case PSA_ALG_SHA_384:
+ mbedtls_sha512_free( &operation->ctx.sha512 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_512)
+ case PSA_ALG_SHA_512:
+ mbedtls_sha512_free( &operation->ctx.sha512 );
+ break;
+#endif
+ default:
+ return( PSA_ERROR_BAD_STATE );
+ }
+ operation->alg = 0;
+ return( PSA_SUCCESS );
+}
+
+static psa_status_t hash_setup(
+ mbedtls_psa_hash_operation_t *operation,
+ psa_algorithm_t alg )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* A context must be freshly initialized before it can be set up. */
+ if( operation->alg != 0 )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ switch( alg )
+ {
+#if defined(BUILTIN_ALG_MD2)
+ case PSA_ALG_MD2:
+ mbedtls_md2_init( &operation->ctx.md2 );
+ ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD4)
+ case PSA_ALG_MD4:
+ mbedtls_md4_init( &operation->ctx.md4 );
+ ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD5)
+ case PSA_ALG_MD5:
+ mbedtls_md5_init( &operation->ctx.md5 );
+ ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_RIPEMD160)
+ case PSA_ALG_RIPEMD160:
+ mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
+ ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_1)
+ case PSA_ALG_SHA_1:
+ mbedtls_sha1_init( &operation->ctx.sha1 );
+ ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_224)
+ case PSA_ALG_SHA_224:
+ mbedtls_sha256_init( &operation->ctx.sha256 );
+ ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_256)
+ case PSA_ALG_SHA_256:
+ mbedtls_sha256_init( &operation->ctx.sha256 );
+ ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_384)
+ case PSA_ALG_SHA_384:
+ mbedtls_sha512_init( &operation->ctx.sha512 );
+ ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_512)
+ case PSA_ALG_SHA_512:
+ mbedtls_sha512_init( &operation->ctx.sha512 );
+ ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
+ break;
+#endif
+ default:
+ return( PSA_ALG_IS_HASH( alg ) ?
+ PSA_ERROR_NOT_SUPPORTED :
+ PSA_ERROR_INVALID_ARGUMENT );
+ }
+ if( ret == 0 )
+ operation->alg = alg;
+ else
+ hash_abort( operation );
+ return( mbedtls_to_psa_error( ret ) );
+}
+
+static psa_status_t hash_clone(
+ const mbedtls_psa_hash_operation_t *source_operation,
+ mbedtls_psa_hash_operation_t *target_operation )
+{
+ switch( source_operation->alg )
+ {
+ case 0:
+ return( PSA_ERROR_BAD_STATE );
+#if defined(BUILTIN_ALG_MD2)
+ case PSA_ALG_MD2:
+ mbedtls_md2_clone( &target_operation->ctx.md2,
+ &source_operation->ctx.md2 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD4)
+ case PSA_ALG_MD4:
+ mbedtls_md4_clone( &target_operation->ctx.md4,
+ &source_operation->ctx.md4 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD5)
+ case PSA_ALG_MD5:
+ mbedtls_md5_clone( &target_operation->ctx.md5,
+ &source_operation->ctx.md5 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_RIPEMD160)
+ case PSA_ALG_RIPEMD160:
+ mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
+ &source_operation->ctx.ripemd160 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_1)
+ case PSA_ALG_SHA_1:
+ mbedtls_sha1_clone( &target_operation->ctx.sha1,
+ &source_operation->ctx.sha1 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_224)
+ case PSA_ALG_SHA_224:
+ mbedtls_sha256_clone( &target_operation->ctx.sha256,
+ &source_operation->ctx.sha256 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_256)
+ case PSA_ALG_SHA_256:
+ mbedtls_sha256_clone( &target_operation->ctx.sha256,
+ &source_operation->ctx.sha256 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_384)
+ case PSA_ALG_SHA_384:
+ mbedtls_sha512_clone( &target_operation->ctx.sha512,
+ &source_operation->ctx.sha512 );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_512)
+ case PSA_ALG_SHA_512:
+ mbedtls_sha512_clone( &target_operation->ctx.sha512,
+ &source_operation->ctx.sha512 );
+ break;
+#endif
+ default:
+ (void) source_operation;
+ (void) target_operation;
+ return( PSA_ERROR_NOT_SUPPORTED );
+ }
+
+ target_operation->alg = source_operation->alg;
+ return( PSA_SUCCESS );
+}
+
+static psa_status_t hash_update(
+ mbedtls_psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ switch( operation->alg )
+ {
+#if defined(BUILTIN_ALG_MD2)
+ case PSA_ALG_MD2:
+ ret = mbedtls_md2_update_ret( &operation->ctx.md2,
+ input, input_length );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD4)
+ case PSA_ALG_MD4:
+ ret = mbedtls_md4_update_ret( &operation->ctx.md4,
+ input, input_length );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD5)
+ case PSA_ALG_MD5:
+ ret = mbedtls_md5_update_ret( &operation->ctx.md5,
+ input, input_length );
+ break;
+#endif
+#if defined(BUILTIN_ALG_RIPEMD160)
+ case PSA_ALG_RIPEMD160:
+ ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
+ input, input_length );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_1)
+ case PSA_ALG_SHA_1:
+ ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
+ input, input_length );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_224)
+ case PSA_ALG_SHA_224:
+ ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
+ input, input_length );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_256)
+ case PSA_ALG_SHA_256:
+ ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
+ input, input_length );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_384)
+ case PSA_ALG_SHA_384:
+ ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
+ input, input_length );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_512)
+ case PSA_ALG_SHA_512:
+ ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
+ input, input_length );
+ break;
+#endif
+ default:
+ (void) input;
+ (void) input_length;
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ return( mbedtls_to_psa_error( ret ) );
+}
+
+static psa_status_t hash_finish(
+ mbedtls_psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length )
+{
+ psa_status_t status;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t actual_hash_length = PSA_HASH_LENGTH( operation->alg );
+
+ /* Fill the output buffer with something that isn't a valid hash
+ * (barring an attack on the hash and deliberately-crafted input),
+ * in case the caller doesn't check the return status properly. */
+ *hash_length = hash_size;
+ /* If hash_size is 0 then hash may be NULL and then the
+ * call to memset would have undefined behavior. */
+ if( hash_size != 0 )
+ memset( hash, '!', hash_size );
+
+ if( hash_size < actual_hash_length )
+ {
+ status = PSA_ERROR_BUFFER_TOO_SMALL;
+ goto exit;
+ }
+
+ switch( operation->alg )
+ {
+#if defined(BUILTIN_ALG_MD2)
+ case PSA_ALG_MD2:
+ ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD4)
+ case PSA_ALG_MD4:
+ ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
+ break;
+#endif
+#if defined(BUILTIN_ALG_MD5)
+ case PSA_ALG_MD5:
+ ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
+ break;
+#endif
+#if defined(BUILTIN_ALG_RIPEMD160)
+ case PSA_ALG_RIPEMD160:
+ ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_1)
+ case PSA_ALG_SHA_1:
+ ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_224)
+ case PSA_ALG_SHA_224:
+ ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_256)
+ case PSA_ALG_SHA_256:
+ ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_384)
+ case PSA_ALG_SHA_384:
+ ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
+ break;
+#endif
+#if defined(BUILTIN_ALG_SHA_512)
+ case PSA_ALG_SHA_512:
+ ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
+ break;
+#endif
+ default:
+ (void) hash;
+ return( PSA_ERROR_BAD_STATE );
+ }
+ status = mbedtls_to_psa_error( ret );
+
+exit:
+ if( status == PSA_SUCCESS )
+ *hash_length = actual_hash_length;
+ return( status );
+}
+
+static psa_status_t hash_compute(
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
+{
+ mbedtls_psa_hash_operation_t operation = MBEDTLS_PSA_HASH_OPERATION_INIT;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ *hash_length = hash_size;
+ status = hash_setup( &operation, alg );
+ if( status != PSA_SUCCESS )
+ goto exit;
+ status = hash_update( &operation, input, input_length );
+ if( status != PSA_SUCCESS )
+ goto exit;
+ status = hash_finish( &operation, hash, hash_size, hash_length );
+ if( status != PSA_SUCCESS )
+ goto exit;
+
+exit:
+ abort_status = hash_abort( &operation );
+ if( status == PSA_SUCCESS )
+ return( abort_status );
+ else
+ return( status );
+
+}
+#endif /* MBEDTLS_PSA_BUILTIN_HASH || PSA_CRYPTO_DRIVER_TEST */
+
+#if defined(MBEDTLS_PSA_BUILTIN_HASH)
+psa_status_t mbedtls_psa_hash_compute(
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
+{
+ return( hash_compute( alg, input, input_length,
+ hash, hash_size, hash_length ) );
+}
+
+psa_status_t mbedtls_psa_hash_setup(
+ mbedtls_psa_hash_operation_t *operation,
+ psa_algorithm_t alg )
+{
+ return( hash_setup( operation, alg ) );
+}
+
+psa_status_t mbedtls_psa_hash_clone(
+ const mbedtls_psa_hash_operation_t *source_operation,
+ mbedtls_psa_hash_operation_t *target_operation )
+{
+ return( hash_clone( source_operation, target_operation ) );
+}
+
+psa_status_t mbedtls_psa_hash_update(
+ mbedtls_psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length )
+{
+ return( hash_update( operation, input, input_length ) );
+}
+
+psa_status_t mbedtls_psa_hash_finish(
+ mbedtls_psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length )
+{
+ return( hash_finish( operation, hash, hash_size, hash_length ) );
+}
+
+psa_status_t mbedtls_psa_hash_abort(
+ mbedtls_psa_hash_operation_t *operation )
+{
+ return( hash_abort( operation ) );
+}
+#endif /* MBEDTLS_PSA_BUILTIN_HASH */
+
+ /*
+ * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
+ */
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+
+psa_status_t is_hash_accelerated( psa_algorithm_t alg )
+{
+ switch( alg )
+ {
+#if defined(MBEDTLS_PSA_ACCEL_ALG_MD2)
+ case PSA_ALG_MD2:
+ return( PSA_SUCCESS );
+#endif
+#if defined(MBEDTLS_PSA_ACCEL_ALG_MD4)
+ case PSA_ALG_MD4:
+ return( PSA_SUCCESS );
+#endif
+#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
+ case PSA_ALG_MD5:
+ return( PSA_SUCCESS );
+#endif
+#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
+ case PSA_ALG_RIPEMD160:
+ return( PSA_SUCCESS );
+#endif
+#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
+ case PSA_ALG_SHA_1:
+ return( PSA_SUCCESS );
+#endif
+#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
+ case PSA_ALG_SHA_224:
+ return( PSA_SUCCESS );
+#endif
+#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
+ case PSA_ALG_SHA_256:
+ return( PSA_SUCCESS );
+#endif
+#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
+ case PSA_ALG_SHA_384:
+ return( PSA_SUCCESS );
+#endif
+#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
+ case PSA_ALG_SHA_512:
+ return( PSA_SUCCESS );
+#endif
+ default:
+ return( PSA_ERROR_NOT_SUPPORTED );
+ }
+}
+
+psa_status_t mbedtls_transparent_test_driver_hash_compute(
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
+{
+ if( is_hash_accelerated( alg ) == PSA_SUCCESS )
+ return( hash_compute( alg, input, input_length,
+ hash, hash_size, hash_length ) );
+ else
+ return( PSA_ERROR_NOT_SUPPORTED );
+}
+
+psa_status_t mbedtls_transparent_test_driver_hash_setup(
+ mbedtls_transparent_test_driver_hash_operation_t *operation,
+ psa_algorithm_t alg )
+{
+ if( is_hash_accelerated( alg ) == PSA_SUCCESS )
+ return( hash_setup( operation, alg ) );
+ else
+ return( PSA_ERROR_NOT_SUPPORTED );
+}
+
+psa_status_t mbedtls_transparent_test_driver_hash_clone(
+ const mbedtls_transparent_test_driver_hash_operation_t *source_operation,
+ mbedtls_transparent_test_driver_hash_operation_t *target_operation )
+{
+ if( is_hash_accelerated( source_operation->alg ) == PSA_SUCCESS )
+ return( hash_clone( source_operation, target_operation ) );
+ else
+ return( PSA_ERROR_BAD_STATE );
+}
+
+psa_status_t mbedtls_transparent_test_driver_hash_update(
+ mbedtls_transparent_test_driver_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length )
+{
+ if( is_hash_accelerated( operation->alg ) == PSA_SUCCESS )
+ return( hash_update( operation, input, input_length ) );
+ else
+ return( PSA_ERROR_BAD_STATE );
+}
+
+psa_status_t mbedtls_transparent_test_driver_hash_finish(
+ mbedtls_transparent_test_driver_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length )
+{
+ if( is_hash_accelerated( operation->alg ) == PSA_SUCCESS )
+ return( hash_finish( operation, hash, hash_size, hash_length ) );
+ else
+ return( PSA_ERROR_BAD_STATE );
+}
+
+psa_status_t mbedtls_transparent_test_driver_hash_abort(
+ mbedtls_transparent_test_driver_hash_operation_t *operation )
+{
+ return( hash_abort( operation ) );
+}
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+
+#endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_hash.h b/library/psa_crypto_hash.h
new file mode 100644
index 0000000..af47c8b
--- /dev/null
+++ b/library/psa_crypto_hash.h
@@ -0,0 +1,273 @@
+/*
+ * PSA hashing layer on top of Mbed TLS software crypto
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PSA_CRYPTO_HASH_H
+#define PSA_CRYPTO_HASH_H
+
+#include <psa/crypto.h>
+#include <psa/crypto_builtin_hash.h>
+
+#include <mbedtls/md_internal.h>
+
+/** Get Mbed TLS MD information of a hash algorithm given its PSA identifier
+ *
+ * \param[in] alg PSA hash algorithm identifier
+ *
+ * \return The Mbed TLS MD information of the hash algorithm. \c NULL if the
+ * PSA hash algorithm is not supported.
+ */
+const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg );
+
+/** Calculate the hash (digest) of a message using Mbed TLS routines.
+ *
+ * \note The signature of this function is that of a PSA driver hash_compute
+ * entry point. This function behaves as a hash_compute entry point as
+ * defined in the PSA driver interface specification for transparent
+ * drivers.
+ *
+ * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_HASH(\p alg) is true).
+ * \param[in] input Buffer containing the message to hash.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the number of bytes
+ * that make up the hash value. This is always
+ * #PSA_HASH_LENGTH(\p alg).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p hash_size is too small
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_hash_compute(
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length);
+
+/** Set up a multipart hash operation using Mbed TLS routines.
+ *
+ * \note The signature of this function is that of a PSA driver hash_setup
+ * entry point. This function behaves as a hash_setup entry point as
+ * defined in the PSA driver interface specification for transparent
+ * drivers.
+ *
+ * If an error occurs at any step after a call to mbedtls_psa_hash_setup(), the
+ * operation will need to be reset by a call to mbedtls_psa_hash_abort(). The
+ * core may call mbedtls_psa_hash_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to mbedtls_psa_hash_setup(), the core must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A successful call to mbedtls_psa_hash_finish() or mbedtls_psa_hash_verify().
+ * - A call to mbedtls_psa_hash_abort().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized to all-zero and not yet be in use.
+ * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_HASH(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_hash_setup(
+ mbedtls_psa_hash_operation_t *operation,
+ psa_algorithm_t alg );
+
+/** Clone an Mbed TLS hash operation.
+ *
+ * \note The signature of this function is that of a PSA driver hash_clone
+ * entry point. This function behaves as a hash_clone entry point as
+ * defined in the PSA driver interface specification for transparent
+ * drivers.
+ *
+ * This function copies the state of an ongoing hash operation to
+ * a new operation object. In other words, this function is equivalent
+ * to calling mbedtls_psa_hash_setup() on \p target_operation with the same
+ * algorithm that \p source_operation was set up for, then
+ * mbedtls_psa_hash_update() on \p target_operation with the same input that
+ * that was passed to \p source_operation. After this function returns, the
+ * two objects are independent, i.e. subsequent calls involving one of
+ * the objects do not affect the other object.
+ *
+ * \param[in] source_operation The active hash operation to clone.
+ * \param[in,out] target_operation The operation object to set up.
+ * It must be initialized but not active.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_BAD_STATE
+ * The \p source_operation state is not valid (it must be active).
+ * \retval #PSA_ERROR_BAD_STATE
+ * The \p target_operation state is not valid (it must be inactive).
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ */
+psa_status_t mbedtls_psa_hash_clone(
+ const mbedtls_psa_hash_operation_t *source_operation,
+ mbedtls_psa_hash_operation_t *target_operation );
+
+/** Add a message fragment to a multipart Mbed TLS hash operation.
+ *
+ * \note The signature of this function is that of a PSA driver hash_update
+ * entry point. This function behaves as a hash_update entry point as
+ * defined in the PSA driver interface specification for transparent
+ * drivers.
+ *
+ * The application must call mbedtls_psa_hash_setup() before calling this function.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling mbedtls_psa_hash_abort().
+ *
+ * \param[in,out] operation Active hash operation.
+ * \param[in] input Buffer containing the message fragment to hash.
+ * \param input_length Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_hash_update(
+ mbedtls_psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length );
+
+/** Finish the calculation of the Mbed TLS-calculated hash of a message.
+ *
+ * \note The signature of this function is that of a PSA driver hash_finish
+ * entry point. This function behaves as a hash_finish entry point as
+ * defined in the PSA driver interface specification for transparent
+ * drivers.
+ *
+ * The application must call mbedtls_psa_hash_setup() before calling this function.
+ * This function calculates the hash of the message formed by concatenating
+ * the inputs passed to preceding calls to mbedtls_psa_hash_update().
+ *
+ * When this function returns successfuly, the operation becomes inactive.
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling mbedtls_psa_hash_abort().
+ *
+ * \param[in,out] operation Active hash operation.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the number of bytes
+ * that make up the hash value. This is always
+ * #PSA_HASH_LENGTH(\c alg) where \c alg is the
+ * hash algorithm that is calculated.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active).
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p hash buffer is too small. You can determine a
+ * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg)
+ * where \c alg is the hash algorithm that is calculated.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_hash_finish(
+ mbedtls_psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length );
+
+/** Abort an Mbed TLS hash operation.
+ *
+ * \note The signature of this function is that of a PSA driver hash_abort
+ * entry point. This function behaves as a hash_abort entry point as
+ * defined in the PSA driver interface specification for transparent
+ * drivers.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by calling
+ * mbedtls_psa_hash_setup() again.
+ *
+ * You may call this function any time after the operation object has
+ * been initialized by one of the methods described in #psa_hash_operation_t.
+ *
+ * In particular, calling mbedtls_psa_hash_abort() after the operation has been
+ * terminated by a call to mbedtls_psa_hash_abort(), mbedtls_psa_hash_finish() or
+ * mbedtls_psa_hash_verify() is safe and has no effect.
+ *
+ * \param[in,out] operation Initialized hash operation.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_hash_abort(
+ mbedtls_psa_hash_operation_t *operation );
+
+/*
+ * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
+ */
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+
+psa_status_t mbedtls_transparent_test_driver_hash_compute(
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length);
+
+psa_status_t mbedtls_transparent_test_driver_hash_setup(
+ mbedtls_transparent_test_driver_hash_operation_t *operation,
+ psa_algorithm_t alg );
+
+psa_status_t mbedtls_transparent_test_driver_hash_clone(
+ const mbedtls_transparent_test_driver_hash_operation_t *source_operation,
+ mbedtls_transparent_test_driver_hash_operation_t *target_operation );
+
+psa_status_t mbedtls_transparent_test_driver_hash_update(
+ mbedtls_transparent_test_driver_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length );
+
+psa_status_t mbedtls_transparent_test_driver_hash_finish(
+ mbedtls_transparent_test_driver_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length );
+
+psa_status_t mbedtls_transparent_test_driver_hash_abort(
+ mbedtls_transparent_test_driver_hash_operation_t *operation );
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+
+#endif /* PSA_CRYPTO_HASH_H */
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index 3e95d3a..1ab1e94 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -26,6 +26,7 @@
#include "psa_crypto_core.h"
#include "psa_crypto_random_impl.h"
#include "psa_crypto_rsa.h"
+#include "psa_crypto_hash.h"
#include <stdlib.h>
#include <string.h>
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 0e81d74..00e18dd 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1457,6 +1457,15 @@
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS"
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA"
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD2"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD4"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512"
loc_cflags="${loc_cflags} -I../tests/include -O2"
make CC=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS"
@@ -2226,6 +2235,7 @@
component_test_psa_crypto_drivers () {
msg "build: MBEDTLS_PSA_CRYPTO_DRIVERS w/ driver hooks"
+ scripts/config.py full
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
# Need to define the correct symbol and include the test driver header path in order to build with the test driver
loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST"
@@ -2235,12 +2245,21 @@
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS"
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA"
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD2"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD4"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384"
+ loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512"
loc_cflags="${loc_cflags} -I../tests/include -O2"
make CC=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS"
unset loc_cflags
- msg "test: MBEDTLS_PSA_CRYPTO_DRIVERS, signature"
+ msg "test: full + MBEDTLS_PSA_CRYPTO_DRIVERS"
make test
}
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index c2051e6..7a01344 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -222,9 +222,11 @@
<ClInclude Include="..\..\include\mbedtls\x509_csr.h" />
<ClInclude Include="..\..\include\mbedtls\xtea.h" />
<ClInclude Include="..\..\include\psa\crypto.h" />
+ <ClInclude Include="..\..\include\psa\crypto_builtin_hash.h" />
<ClInclude Include="..\..\include\psa\crypto_compat.h" />
<ClInclude Include="..\..\include\psa\crypto_config.h" />
<ClInclude Include="..\..\include\psa\crypto_driver_common.h" />
+ <ClInclude Include="..\..\include\psa\crypto_driver_contexts.h" />
<ClInclude Include="..\..\include\psa\crypto_extra.h" />
<ClInclude Include="..\..\include\psa\crypto_platform.h" />
<ClInclude Include="..\..\include\psa\crypto_se_driver.h" />
@@ -251,6 +253,7 @@
<ClInclude Include="..\..\library\psa_crypto_core.h" />
<ClInclude Include="..\..\library\psa_crypto_driver_wrappers.h" />
<ClInclude Include="..\..\library\psa_crypto_ecp.h" />
+ <ClInclude Include="..\..\library\psa_crypto_hash.h" />
<ClInclude Include="..\..\library\psa_crypto_invasive.h" />
<ClInclude Include="..\..\library\psa_crypto_its.h" />
<ClInclude Include="..\..\library\psa_crypto_random_impl.h" />
@@ -324,6 +327,7 @@
<ClCompile Include="..\..\library\psa_crypto_client.c" />
<ClCompile Include="..\..\library\psa_crypto_driver_wrappers.c" />
<ClCompile Include="..\..\library\psa_crypto_ecp.c" />
+ <ClCompile Include="..\..\library\psa_crypto_hash.c" />
<ClCompile Include="..\..\library\psa_crypto_rsa.c" />
<ClCompile Include="..\..\library\psa_crypto_se.c" />
<ClCompile Include="..\..\library\psa_crypto_slot_management.c" />