Merge pull request #4157 from stevew817/dispatch_hash_operations

Dispatch hash operations through the driver wrapper layer
This commit is contained in:
Gilles Peskine 2021-03-17 21:50:00 +01:00 committed by GitHub
commit d08e538fa5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 1433 additions and 484 deletions

View file

@ -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 */

View file

@ -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. */

View file

@ -68,14 +68,9 @@ extern "C" {
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#include "mbedtls/cmac.h" #include "mbedtls/cmac.h"
#include "mbedtls/gcm.h" #include "mbedtls/gcm.h"
#include "mbedtls/md.h"
#include "mbedtls/md2.h" /* Include the context definition for the compiled-in drivers */
#include "mbedtls/md4.h" #include "psa/crypto_driver_contexts.h"
#include "mbedtls/md5.h"
#include "mbedtls/ripemd160.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
typedef struct { typedef struct {
/** Unique ID indicating which driver got assigned to do the /** Unique ID indicating which driver got assigned to do the
@ -89,32 +84,14 @@ typedef struct {
struct psa_hash_operation_s struct psa_hash_operation_s
{ {
psa_algorithm_t alg; /** Unique ID indicating which driver got assigned to do the
union * operation. Since driver contexts are driver-specific, swapping
{ * drivers halfway through the operation is not supported.
unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ * ID values are auto-generated in psa_driver_wrappers.h
#if defined(MBEDTLS_MD2_C) * ID value zero means the context is not valid or not assigned to
mbedtls_md2_context md2; * any driver (i.e. none of the driver contexts are active). */
#endif unsigned int id;
#if defined(MBEDTLS_MD4_C) psa_driver_hash_context_t ctx;
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;
}; };
#define PSA_HASH_OPERATION_INIT {0, {0}} #define PSA_HASH_OPERATION_INIT {0, {0}}
@ -127,6 +104,8 @@ static inline struct psa_hash_operation_s psa_hash_operation_init( void )
#if defined(MBEDTLS_MD_C) #if defined(MBEDTLS_MD_C)
typedef struct typedef struct
{ {
/** The HMAC algorithm in use */
psa_algorithm_t alg;
/** The hash context. */ /** The hash context. */
struct psa_hash_operation_s hash_ctx; struct psa_hash_operation_s hash_ctx;
/** The HMAC part of the context. */ /** The HMAC part of the context. */

View file

@ -64,6 +64,7 @@ set(src_crypto
psa_crypto_client.c psa_crypto_client.c
psa_crypto_driver_wrappers.c psa_crypto_driver_wrappers.c
psa_crypto_ecp.c psa_crypto_ecp.c
psa_crypto_hash.c
psa_crypto_rsa.c psa_crypto_rsa.c
psa_crypto_se.c psa_crypto_se.c
psa_crypto_slot_management.c psa_crypto_slot_management.c

View file

@ -121,6 +121,7 @@ OBJS_CRYPTO= \
psa_crypto_client.o \ psa_crypto_client.o \
psa_crypto_driver_wrappers.o \ psa_crypto_driver_wrappers.o \
psa_crypto_ecp.o \ psa_crypto_ecp.o \
psa_crypto_hash.o \
psa_crypto_rsa.o \ psa_crypto_rsa.o \
psa_crypto_se.o \ psa_crypto_se.o \
psa_crypto_slot_management.o \ psa_crypto_slot_management.o \

View file

@ -33,6 +33,7 @@
#include "psa_crypto_invasive.h" #include "psa_crypto_invasive.h"
#include "psa_crypto_driver_wrappers.h" #include "psa_crypto_driver_wrappers.h"
#include "psa_crypto_ecp.h" #include "psa_crypto_ecp.h"
#include "psa_crypto_hash.h"
#include "psa_crypto_rsa.h" #include "psa_crypto_rsa.h"
#include "psa_crypto_ecp.h" #include "psa_crypto_ecp.h"
#if defined(MBEDTLS_PSA_CRYPTO_SE_C) #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@ -2141,274 +2142,53 @@ exit:
/* Message digests */ /* 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 ) psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
{ {
switch( operation->alg ) /* Aborting a non-active operation is allowed */
{ if( operation->id == 0 )
case 0: return( PSA_SUCCESS );
/* 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 psa_status_t status = psa_driver_wrapper_hash_abort( operation );
* nothing to do. */ operation->id = 0;
break;
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) return( status );
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 );
} }
psa_status_t psa_hash_setup( psa_hash_operation_t *operation, psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
psa_algorithm_t alg ) psa_algorithm_t alg )
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* A context must be freshly initialized before it can be set up. */ /* 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 ); return( PSA_ERROR_BAD_STATE );
}
switch( alg ) if( !PSA_ALG_IS_HASH( alg ) )
{ return( PSA_ERROR_INVALID_ARGUMENT );
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2)
case PSA_ALG_MD2: /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
mbedtls_md2_init( &operation->ctx.md2 ); * directly zeroes the int-sized dummy member of the context union. */
ret = mbedtls_md2_starts_ret( &operation->ctx.md2 ); memset( &operation->ctx, 0, sizeof( operation->ctx ) );
break;
#endif return( psa_driver_wrapper_hash_setup( operation, alg ) );
#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 ) );
} }
psa_status_t psa_hash_update( psa_hash_operation_t *operation, psa_status_t psa_hash_update( psa_hash_operation_t *operation,
const uint8_t *input, const uint8_t *input,
size_t input_length ) 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 /* Don't require hash implementations to behave correctly on a
* zero-length input, which may have an invalid pointer. */ * zero-length input, which may have an invalid pointer. */
if( input_length == 0 ) if( input_length == 0 )
return( PSA_SUCCESS ); return( PSA_SUCCESS );
switch( operation->alg ) psa_status_t status = psa_driver_wrapper_hash_update( operation,
{ input, input_length );
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) if( status != PSA_SUCCESS )
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_hash_abort( operation ); psa_hash_abort( operation );
return( mbedtls_to_psa_error( ret ) );
return( status );
} }
psa_status_t psa_hash_finish( psa_hash_operation_t *operation, psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
@ -2416,88 +2196,14 @@ psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
size_t hash_size, size_t hash_size,
size_t *hash_length ) size_t *hash_length )
{ {
psa_status_t status; *hash_length = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; if( operation->id == 0 )
size_t actual_hash_length = PSA_HASH_LENGTH( operation->alg ); return( PSA_ERROR_BAD_STATE );
/* Fill the output buffer with something that isn't a valid hash psa_status_t status = psa_driver_wrapper_hash_finish(
* (barring an attack on the hash and deliberately-crafted input), operation, hash, hash_size, hash_length );
* in case the caller doesn't check the return status properly. */ psa_hash_abort( operation );
*hash_length = hash_size; return( status );
/* 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 psa_hash_verify( psa_hash_operation_t *operation, psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
@ -2506,9 +2212,10 @@ psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
{ {
uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE]; uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
size_t actual_hash_length; size_t actual_hash_length;
psa_status_t status = psa_hash_finish( operation, psa_status_t status = psa_hash_finish(
actual_hash, sizeof( actual_hash ), operation,
&actual_hash_length ); actual_hash, sizeof( actual_hash ),
&actual_hash_length );
if( status != PSA_SUCCESS ) if( status != PSA_SUCCESS )
return( status ); return( status );
if( actual_hash_length != hash_length ) if( actual_hash_length != hash_length )
@ -2523,123 +2230,52 @@ psa_status_t psa_hash_compute( psa_algorithm_t alg,
uint8_t *hash, size_t hash_size, uint8_t *hash, size_t hash_size,
size_t *hash_length ) size_t *hash_length )
{ {
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; *hash_length = 0;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; if( !PSA_ALG_IS_HASH( alg ) )
return( PSA_ERROR_INVALID_ARGUMENT );
*hash_length = hash_size; return( psa_driver_wrapper_hash_compute( alg, input, input_length,
status = psa_hash_setup( &operation, alg ); hash, hash_size, hash_length ) );
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 );
} }
psa_status_t psa_hash_compare( psa_algorithm_t alg, psa_status_t psa_hash_compare( psa_algorithm_t alg,
const uint8_t *input, size_t input_length, const uint8_t *input, size_t input_length,
const uint8_t *hash, size_t hash_length ) const uint8_t *hash, size_t hash_length )
{ {
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t actual_hash_length;
status = psa_hash_setup( &operation, alg ); if( !PSA_ALG_IS_HASH( alg ) )
if( status != PSA_SUCCESS ) return( PSA_ERROR_INVALID_ARGUMENT );
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;
exit: psa_status_t status = psa_driver_wrapper_hash_compute(
if( status == PSA_SUCCESS ) alg, input, input_length,
status = psa_hash_abort( &operation ); actual_hash, sizeof(actual_hash),
else &actual_hash_length );
psa_hash_abort( &operation ); if( status != PSA_SUCCESS )
return( status ); 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_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation ) psa_hash_operation_t *target_operation )
{ {
if( target_operation->alg != 0 ) if( source_operation->id == 0 ||
return( PSA_ERROR_BAD_STATE ); target_operation->id != 0 )
switch( source_operation->alg )
{ {
case 0: return( PSA_ERROR_BAD_STATE );
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 );
} }
target_operation->alg = source_operation->alg; psa_status_t status = psa_driver_wrapper_hash_clone( source_operation,
return( PSA_SUCCESS ); target_operation );
if( status != PSA_SUCCESS )
psa_hash_abort( target_operation );
return( status );
} }
@ -2795,7 +2431,7 @@ static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
if( PSA_ALG_IS_HMAC( operation->alg ) ) if( PSA_ALG_IS_HMAC( operation->alg ) )
{ {
/* We'll set up the hash operation later in psa_hmac_setup_internal. */ /* 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; status = PSA_SUCCESS;
} }
else else
@ -2902,6 +2538,8 @@ static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
size_t block_size = psa_get_hash_block_size( hash_alg ); size_t block_size = psa_get_hash_block_size( hash_alg );
psa_status_t status; psa_status_t status;
hmac->alg = hash_alg;
/* Sanity checks on block_size, to guarantee that there won't be a buffer /* Sanity checks on block_size, to guarantee that there won't be a buffer
* overflow below. This should never trigger if the hash algorithm * overflow below. This should never trigger if the hash algorithm
* is implemented correctly. */ * is implemented correctly. */
@ -3119,7 +2757,7 @@ static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
size_t mac_size ) size_t mac_size )
{ {
uint8_t tmp[MBEDTLS_MD_MAX_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 hash_size = 0;
size_t block_size = psa_get_hash_block_size( hash_alg ); size_t block_size = psa_get_hash_block_size( hash_alg );
psa_status_t status; psa_status_t status;

View file

@ -30,8 +30,6 @@
#include "psa/crypto.h" #include "psa/crypto.h"
#include "psa/crypto_se_driver.h" #include "psa/crypto_se_driver.h"
#include <mbedtls/md_internal.h>
/** The data structure representing a key slot, containing key material /** The data structure representing a key slot, containing key material
* and metadata for one key. * and metadata for one key.
*/ */
@ -214,15 +212,6 @@ psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
*/ */
psa_status_t mbedtls_to_psa_error( int ret ); 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. /** Import a key in binary format.
* *
* \note The signature of this function is that of a PSA driver * \note The signature of this function is that of a PSA driver

View file

@ -21,6 +21,8 @@
#include "psa_crypto_core.h" #include "psa_crypto_core.h"
#include "psa_crypto_driver_wrappers.h" #include "psa_crypto_driver_wrappers.h"
#include "psa_crypto_hash.h"
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) #if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
@ -37,15 +39,18 @@
#endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_DRIVER_TEST */
/* Repeat above block for each JSON-declared driver during autogeneration */ /* 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 */ #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 */ /* Support the 'old' SE interface when asked to */
#if defined(MBEDTLS_PSA_CRYPTO_SE_C) #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style /* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style
@ -1066,4 +1071,172 @@ psa_status_t psa_driver_wrapper_cipher_abort(
#endif /* PSA_CRYPTO_DRIVER_PRESENT */ #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. */ /* End of automatically generated file. */

View file

@ -127,6 +127,39 @@ psa_status_t psa_driver_wrapper_cipher_finish(
psa_status_t psa_driver_wrapper_cipher_abort( psa_status_t psa_driver_wrapper_cipher_abort(
psa_operation_driver_context_t *operation ); 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 */ #endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */
/* End of automatically generated file. */ /* End of automatically generated file. */

View file

@ -26,6 +26,7 @@
#include "psa_crypto_core.h" #include "psa_crypto_core.h"
#include "psa_crypto_ecp.h" #include "psa_crypto_ecp.h"
#include "psa_crypto_random_impl.h" #include "psa_crypto_random_impl.h"
#include "psa_crypto_hash.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

697
library/psa_crypto_hash.c Normal file
View file

@ -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 */

273
library/psa_crypto_hash.h Normal file
View file

@ -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 */

View file

@ -26,6 +26,7 @@
#include "psa_crypto_core.h" #include "psa_crypto_core.h"
#include "psa_crypto_random_impl.h" #include "psa_crypto_random_impl.h"
#include "psa_crypto_rsa.h" #include "psa_crypto_rsa.h"
#include "psa_crypto_hash.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View file

@ -1457,6 +1457,15 @@ component_test_psa_crypto_config_basic() {
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS" 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_ECDSA"
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_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" loc_cflags="${loc_cflags} -I../tests/include -O2"
make CC=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS" make CC=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS"
@ -2226,6 +2235,7 @@ component_test_se_default () {
component_test_psa_crypto_drivers () { component_test_psa_crypto_drivers () {
msg "build: MBEDTLS_PSA_CRYPTO_DRIVERS w/ driver hooks" msg "build: MBEDTLS_PSA_CRYPTO_DRIVERS w/ driver hooks"
scripts/config.py full
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS 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 # 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" loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST"
@ -2235,12 +2245,21 @@ component_test_psa_crypto_drivers () {
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS" 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_ECDSA"
loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_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" loc_cflags="${loc_cflags} -I../tests/include -O2"
make CC=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS" make CC=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS"
unset loc_cflags unset loc_cflags
msg "test: MBEDTLS_PSA_CRYPTO_DRIVERS, signature" msg "test: full + MBEDTLS_PSA_CRYPTO_DRIVERS"
make test make test
} }

View file

@ -222,9 +222,11 @@
<ClInclude Include="..\..\include\mbedtls\x509_csr.h" /> <ClInclude Include="..\..\include\mbedtls\x509_csr.h" />
<ClInclude Include="..\..\include\mbedtls\xtea.h" /> <ClInclude Include="..\..\include\mbedtls\xtea.h" />
<ClInclude Include="..\..\include\psa\crypto.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_compat.h" />
<ClInclude Include="..\..\include\psa\crypto_config.h" /> <ClInclude Include="..\..\include\psa\crypto_config.h" />
<ClInclude Include="..\..\include\psa\crypto_driver_common.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_extra.h" />
<ClInclude Include="..\..\include\psa\crypto_platform.h" /> <ClInclude Include="..\..\include\psa\crypto_platform.h" />
<ClInclude Include="..\..\include\psa\crypto_se_driver.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_core.h" />
<ClInclude Include="..\..\library\psa_crypto_driver_wrappers.h" /> <ClInclude Include="..\..\library\psa_crypto_driver_wrappers.h" />
<ClInclude Include="..\..\library\psa_crypto_ecp.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_invasive.h" />
<ClInclude Include="..\..\library\psa_crypto_its.h" /> <ClInclude Include="..\..\library\psa_crypto_its.h" />
<ClInclude Include="..\..\library\psa_crypto_random_impl.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_client.c" />
<ClCompile Include="..\..\library\psa_crypto_driver_wrappers.c" /> <ClCompile Include="..\..\library\psa_crypto_driver_wrappers.c" />
<ClCompile Include="..\..\library\psa_crypto_ecp.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_rsa.c" />
<ClCompile Include="..\..\library\psa_crypto_se.c" /> <ClCompile Include="..\..\library\psa_crypto_se.c" />
<ClCompile Include="..\..\library\psa_crypto_slot_management.c" /> <ClCompile Include="..\..\library\psa_crypto_slot_management.c" />