mirror of https://github.com/ARMmbed/mbed-os.git
M467: Support Crypto SHA/ECC H/W
1. Prepare crypto common code 2. Support list - SHA - ECC NOTE: AES/RSA are to support in other works NOTE: Compared to M487, M467's SHA supports context save & restore (DMA Cascade mode) and so no software fallback is needed. NOTE: M467's ECC, following M487, goes partial-module replacement and it can just improve primitives e.g. point addition/doubling by 2X, and cannot improve high level point multiplication because MbedTLS doesn’t open it. To improve performance best, full-module replacement is needed. NOTE: Continuing above, add support for Montgomery curvepull/15337/head
parent
ec2c15533e
commit
24b0feb17f
|
@ -1,7 +1,9 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if("M480" IN_LIST MBED_TARGET_LABELS)
|
||||
if("M460" IN_LIST MBED_TARGET_LABELS)
|
||||
add_subdirectory(TARGET_M460)
|
||||
elseif("M480" IN_LIST MBED_TARGET_LABELS)
|
||||
add_subdirectory(TARGET_M480)
|
||||
elseif("NUC472" IN_LIST MBED_TARGET_LABELS)
|
||||
add_subdirectory(TARGET_NUC472)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
target_include_directories(mbed-mbedtls
|
||||
INTERFACE
|
||||
.
|
||||
./aes
|
||||
./ecp
|
||||
./rsa
|
||||
./sha
|
||||
)
|
||||
|
||||
target_sources(mbed-mbedtls
|
||||
INTERFACE
|
||||
aes/aes_alt.c
|
||||
ecp/ecp_internal_alt.c
|
||||
rsa/rsa_alt.c
|
||||
sha/sha1_alt.c
|
||||
sha/sha256_alt.c
|
||||
sha/sha512_alt.c
|
||||
sha/sha_alt_hw.c
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
/* TODO */
|
|
@ -0,0 +1 @@
|
|||
/* TODO */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 MBEDTLS_DEVICE_H
|
||||
#define MBEDTLS_DEVICE_H
|
||||
|
||||
#define MBEDTLS_SHA1_ALT
|
||||
#define MBEDTLS_SHA256_ALT
|
||||
#define MBEDTLS_SHA512_ALT
|
||||
|
||||
//#define MBEDTLS_AES_ALT
|
||||
|
||||
#define MBEDTLS_ECP_INTERNAL_ALT
|
||||
/* Support for Weierstrass curves with Jacobi representation */
|
||||
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
|
||||
#define MBEDTLS_ECP_ADD_MIXED_ALT
|
||||
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
|
||||
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
|
||||
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
|
||||
/* Support for curves with Montgomery arithmetic */
|
||||
//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT
|
||||
#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT
|
||||
#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
|
||||
|
||||
//#define MBEDTLS_RSA_ALT
|
||||
|
||||
#endif /* MBEDTLS_DEVICE_H */
|
|
@ -0,0 +1 @@
|
|||
/* TODO */
|
|
@ -0,0 +1 @@
|
|||
/* TODO */
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 "mbedtls/sha1.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA1_C)
|
||||
#if defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
#include "crypto-misc.h"
|
||||
#include "nu_bitutil.h"
|
||||
#include "string.h"
|
||||
|
||||
void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
|
||||
{
|
||||
crypto_sha_init(&ctx->hw_ctx, SHA_MODE_SHA1);
|
||||
}
|
||||
|
||||
void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
crypto_sha_free(&ctx->hw_ctx);
|
||||
}
|
||||
|
||||
void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src)
|
||||
{
|
||||
// Corner case: Destination/source contexts are the same
|
||||
if (dst == src) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dst, src, sizeof(mbedtls_sha1_context));
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return MBEDTLS_ERR_SHA1_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_starts(&ctx->hw_ctx, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 process buffer
|
||||
*/
|
||||
int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
|
||||
{
|
||||
if (ctx == NULL || (input == NULL && ilen == 0)) {
|
||||
return MBEDTLS_ERR_SHA1_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_update(&ctx->hw_ctx, input, ilen);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
|
||||
{
|
||||
if (ctx == NULL || output == NULL) {
|
||||
return MBEDTLS_ERR_SHA1_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_finish(&ctx->hw_ctx, output, 20);
|
||||
}
|
||||
|
||||
int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
|
||||
{
|
||||
if (ctx == NULL || data == NULL) {
|
||||
return MBEDTLS_ERR_SHA1_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_update(&ctx->hw_ctx, data, 64);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT */
|
||||
#endif /* MBEDTLS_SHA1_C */
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 MBEDTLS_SHA1_ALT_H
|
||||
#define MBEDTLS_SHA1_ALT_H
|
||||
|
||||
#include "mbedtls/sha1.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
#include "sha_alt_hw.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct mbedtls_sha1_context_s;
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct mbedtls_sha1_context_s {
|
||||
crypto_sha_context hw_ctx;
|
||||
}
|
||||
mbedtls_sha1_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-1 context
|
||||
*
|
||||
* \param ctx SHA-1 context to be initialized
|
||||
*/
|
||||
void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-1 context
|
||||
*
|
||||
* \param ctx SHA-1 context to be cleared
|
||||
*/
|
||||
void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-1 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 process buffer
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 final digest
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param output SHA-1 checksum result
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] );
|
||||
|
||||
/* Internal use */
|
||||
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define MBEDTLS_DEPRECATED
|
||||
#endif
|
||||
/**
|
||||
* \brief SHA-1 context setup
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0
|
||||
*
|
||||
* \param ctx The SHA-1 context to be initialized.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 process buffer
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0
|
||||
*
|
||||
* \param ctx The SHA-1 context.
|
||||
* \param input The buffer holding the input data.
|
||||
* \param ilen The length of the input data.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 final digest
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0
|
||||
*
|
||||
* \param ctx The SHA-1 context.
|
||||
* \param output The SHA-1 checksum result.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
|
||||
unsigned char output[20] );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 process data block (internal use only)
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0
|
||||
*
|
||||
* \param ctx The SHA-1 context.
|
||||
* \param data The data block being processed.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
|
||||
const unsigned char data[64] );
|
||||
|
||||
#undef MBEDTLS_DEPRECATED
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT */
|
||||
|
||||
#endif /* sha1_alt.h */
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 "mbedtls/sha256.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
#if defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
#include "crypto-misc.h"
|
||||
#include "nu_bitutil.h"
|
||||
#include "string.h"
|
||||
|
||||
void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
|
||||
{
|
||||
crypto_sha_init(&ctx->hw_ctx, SHA_MODE_SHA256);
|
||||
}
|
||||
|
||||
void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
crypto_sha_free(&ctx->hw_ctx);
|
||||
}
|
||||
|
||||
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src)
|
||||
{
|
||||
// Corner case: Destination/source contexts are the same
|
||||
if (dst == src) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dst, src, sizeof(mbedtls_sha256_context));
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 context setup
|
||||
*/
|
||||
int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_starts(&ctx->hw_ctx, is224);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 process buffer
|
||||
*/
|
||||
int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
|
||||
{
|
||||
if (ctx == NULL || (input == NULL && ilen == 0)) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_update(&ctx->hw_ctx, input, ilen);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 final digest
|
||||
*/
|
||||
int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
|
||||
{
|
||||
if (ctx == NULL || output == NULL) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_finish(&ctx->hw_ctx, output, ctx->hw_ctx.is224_384 ? 28 : 32);
|
||||
}
|
||||
|
||||
int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
|
||||
{
|
||||
if (ctx == NULL || data == NULL) {
|
||||
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_update(&ctx->hw_ctx, data, 64);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA256_ALT */
|
||||
#endif /* MBEDTLS_SHA256_C */
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 MBEDTLS_SHA256_ALT_H
|
||||
#define MBEDTLS_SHA256_ALT_H
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
#include "sha_alt_hw.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct mbedtls_sha256_context_s;
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*/
|
||||
typedef struct mbedtls_sha256_context_s {
|
||||
crypto_sha_context hw_ctx;
|
||||
}
|
||||
mbedtls_sha256_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-256 context
|
||||
*
|
||||
* \param ctx SHA-256 context to be initialized
|
||||
*/
|
||||
void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-256 context
|
||||
*
|
||||
* \param ctx SHA-256 context to be cleared
|
||||
*/
|
||||
void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-256 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 process buffer
|
||||
*
|
||||
* \param ctx SHA-256 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input,
|
||||
size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 final digest
|
||||
*
|
||||
* \param ctx SHA-256 context
|
||||
* \param output SHA-224/256 checksum result
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] );
|
||||
|
||||
/* Internal use */
|
||||
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define MBEDTLS_DEPRECATED
|
||||
#endif
|
||||
/**
|
||||
* \brief This function starts a SHA-256 checksum calculation.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha256_starts_ret() in 2.7.0.
|
||||
*
|
||||
* \param ctx The SHA-256 context to initialize.
|
||||
* \param is224 Determines which function to use.
|
||||
* <ul><li>0: Use SHA-256.</li>
|
||||
* <li>1: Use SHA-224.</li></ul>
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
|
||||
int is224 );
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing
|
||||
* SHA-256 checksum calculation.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha256_update_ret() in 2.7.0.
|
||||
*
|
||||
* \param ctx The SHA-256 context to initialize.
|
||||
* \param input The buffer holding the data.
|
||||
* \param ilen The length of the input data.
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief This function finishes the SHA-256 operation, and writes
|
||||
* the result to the output buffer.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha256_finish_ret() in 2.7.0.
|
||||
*
|
||||
* \param ctx The SHA-256 context.
|
||||
* \param output The SHA-224or SHA-256 checksum result.
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
|
||||
unsigned char output[32] );
|
||||
|
||||
/**
|
||||
* \brief This function processes a single data block within
|
||||
* the ongoing SHA-256 computation. This function is for
|
||||
* internal use only.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_internal_sha256_process() in 2.7.0.
|
||||
*
|
||||
* \param ctx The SHA-256 context.
|
||||
* \param data The buffer holding one block of data.
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
|
||||
const unsigned char data[64] );
|
||||
|
||||
#undef MBEDTLS_DEPRECATED
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA256_ALT */
|
||||
|
||||
#endif /* sha256_alt.h */
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 "mbedtls/sha512.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
#if defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#include "crypto-misc.h"
|
||||
#include "nu_bitutil.h"
|
||||
#include "string.h"
|
||||
|
||||
void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
|
||||
{
|
||||
crypto_sha_init(&ctx->hw_ctx, SHA_MODE_SHA512);
|
||||
}
|
||||
|
||||
void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
crypto_sha_free(&ctx->hw_ctx);
|
||||
}
|
||||
|
||||
void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
|
||||
const mbedtls_sha512_context *src)
|
||||
{
|
||||
// Corner case: Destination/source contexts are the same
|
||||
if (dst == src) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dst, src, sizeof(mbedtls_sha512_context));
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 context setup
|
||||
*/
|
||||
int mbedtls_sha512_starts_ret(mbedtls_sha512_context *ctx, int is384)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_starts(&ctx->hw_ctx, is384);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 process buffer
|
||||
*/
|
||||
int mbedtls_sha512_update_ret(mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen)
|
||||
{
|
||||
if (ctx == NULL || (input == NULL && ilen == 0)) {
|
||||
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_update(&ctx->hw_ctx, input, ilen);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 final digest
|
||||
*/
|
||||
int mbedtls_sha512_finish_ret(mbedtls_sha512_context *ctx, unsigned char output[64])
|
||||
{
|
||||
if (ctx == NULL || output == NULL) {
|
||||
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_finish(&ctx->hw_ctx, output, ctx->hw_ctx.is224_384 ? 48 : 64);
|
||||
}
|
||||
|
||||
int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx, const unsigned char data[128])
|
||||
{
|
||||
if (ctx == NULL || data == NULL) {
|
||||
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return crypto_sha_update(&ctx->hw_ctx, data, 128);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA512_ALT */
|
||||
#endif /* MBEDTLS_SHA512_C */
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 MBEDTLS_SHA512_ALT_H
|
||||
#define MBEDTLS_SHA512_ALT_H
|
||||
|
||||
#include "mbedtls/sha512.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#include "sha_alt_hw.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct mbedtls_sha512_context_s;
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
typedef struct mbedtls_sha512_context_s {
|
||||
crypto_sha_context hw_ctx;
|
||||
}
|
||||
mbedtls_sha512_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-512 context
|
||||
*
|
||||
* \param ctx SHA-512 context to be initialized
|
||||
*/
|
||||
void mbedtls_sha512_init( mbedtls_sha512_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-512 context
|
||||
*
|
||||
* \param ctx SHA-512 context to be cleared
|
||||
*/
|
||||
void mbedtls_sha512_free( mbedtls_sha512_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-512 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
|
||||
const mbedtls_sha512_context *src );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 process buffer
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input,
|
||||
size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 final digest
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param output SHA-384/512 checksum result
|
||||
*
|
||||
* \returns error code
|
||||
*/
|
||||
int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] );
|
||||
|
||||
/* Internal use */
|
||||
int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define MBEDTLS_DEPRECATED
|
||||
#endif
|
||||
/**
|
||||
* \brief This function starts a SHA-384 or SHA-512 checksum
|
||||
* calculation.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha512_starts_ret() in 2.7.0
|
||||
*
|
||||
* \param ctx The SHA-512 context to initialize.
|
||||
* \param is384 Determines which function to use.
|
||||
* <ul><li>0: Use SHA-512.</li>
|
||||
* <li>1: Use SHA-384.</li></ul>
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
|
||||
int is384 );
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing
|
||||
* SHA-512 checksum calculation.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0
|
||||
*
|
||||
* \param ctx The SHA-512 context.
|
||||
* \param input The buffer holding the data.
|
||||
* \param ilen The length of the input data.
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief This function finishes the SHA-512 operation, and writes
|
||||
* the result to the output buffer.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0
|
||||
*
|
||||
* \param ctx The SHA-512 context.
|
||||
* \param output The SHA-384 or SHA-512 checksum result.
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
|
||||
unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief This function processes a single data block within
|
||||
* the ongoing SHA-512 computation. This function is for
|
||||
* internal use only.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0
|
||||
*
|
||||
* \param ctx The SHA-512 context.
|
||||
* \param data The buffer holding one block of data.
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
|
||||
const unsigned char data[128] );
|
||||
|
||||
#undef MBEDTLS_DEPRECATED
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA512_ALT */
|
||||
|
||||
#endif /* sha512_alt.h */
|
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA1_C) || defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C)
|
||||
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#include "nu_bitutil.h"
|
||||
#include "nu_timer.h"
|
||||
#include "mbed_assert.h"
|
||||
#include "mbed_error.h"
|
||||
#include "crypto-misc.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* SHA context for DMA */
|
||||
static struct {
|
||||
MBED_ALIGN(4)
|
||||
uint8_t block_imd[NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES]; // Intermediate data block in DMA mode
|
||||
uint32_t fbinfo_imd[NU_CRYPTO_SHA_MAXSIZE_FBINFO_WORDS]; // Intermediate feedback information in DMA cascade mode
|
||||
|
||||
const uint8_t *block_act; // Actual of above
|
||||
uint32_t *fbinfo_act; // Actual of above
|
||||
} dma_ctx_inst;
|
||||
|
||||
/* Manage SHA H/W
|
||||
*
|
||||
* We follow the rules below to manage SHA H/W to share among contexts:
|
||||
* 1. Go DMA cascade mode to support context save & restore.
|
||||
* 2. Initialize/un-initialize crypto H/W at first context init/last context free.
|
||||
* 3. All code involving SHA H/W are in between crypto_sha_acquire()/crypto_sha_release().
|
||||
* 4. Interrupt is enabled (SHA_ENABLE_INT()/SHA_DISABLE_INT()) only during real SHA H/W operation.
|
||||
*/
|
||||
|
||||
void crypto_sha_init(crypto_sha_context *ctx, uint32_t type)
|
||||
{
|
||||
MBED_ASSERT(type == SHA_MODE_SHA1 ||
|
||||
type == SHA_MODE_SHA256 ||
|
||||
type == SHA_MODE_SHA512);
|
||||
|
||||
/* Clean SHA context */
|
||||
crypto_zeroize(ctx, sizeof(*ctx));
|
||||
|
||||
/* SHA operation mode */
|
||||
ctx->type = type;
|
||||
ctx->opmode = type;
|
||||
|
||||
/* Mbed TLS error code for the SHA type */
|
||||
switch (type) {
|
||||
case SHA_MODE_SHA1:
|
||||
ctx->digestsize = 20;
|
||||
ctx->err_hw_accel = MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED;
|
||||
ctx->err_bad_input = MBEDTLS_ERR_SHA1_BAD_INPUT_DATA;
|
||||
break;
|
||||
|
||||
case SHA_MODE_SHA256:
|
||||
ctx->digestsize = 32;
|
||||
ctx->err_hw_accel = MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
|
||||
ctx->err_bad_input = MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
|
||||
break;
|
||||
|
||||
case SHA_MODE_SHA512:
|
||||
ctx->digestsize = 64;
|
||||
ctx->err_hw_accel = MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED;
|
||||
ctx->err_bad_input = MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
MBED_ASSERT(0);
|
||||
}
|
||||
|
||||
/* Acquire ownership of SHA H/W */
|
||||
crypto_sha_acquire();
|
||||
|
||||
/* SHA H/W DMA buffer has the following requirements:
|
||||
* (1) Word-aligned buffer base address
|
||||
* (2) Word-aligned buffer size
|
||||
* (3) Located in 0x20000000-0x2FFFFFFF region */
|
||||
if ((! crypto_dma_buff_compat(dma_ctx_inst.block_imd, sizeof(dma_ctx_inst.block_imd), 4)) ||
|
||||
(! crypto_dma_buff_compat(dma_ctx_inst.fbinfo_imd, sizeof(dma_ctx_inst.fbinfo_imd), 4))) {
|
||||
error("Buffer for SHA H/W DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
|
||||
}
|
||||
|
||||
/* Initialize crypto module */
|
||||
crypto_init();
|
||||
|
||||
/* Release ownership of SHA H/W */
|
||||
crypto_sha_release();
|
||||
}
|
||||
|
||||
void crypto_sha_free(crypto_sha_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Acquire ownership of SHA H/W */
|
||||
crypto_sha_acquire();
|
||||
|
||||
/* Un-initialize crypto module */
|
||||
crypto_uninit();
|
||||
|
||||
/* Release ownership of SHA H/W */
|
||||
crypto_sha_release();
|
||||
|
||||
/* Clean SHA context */
|
||||
crypto_zeroize(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
int crypto_sha_starts(crypto_sha_context *ctx, int is224_384)
|
||||
{
|
||||
MBED_ASSERT(ctx != NULL);
|
||||
|
||||
/* NOTE: mbedtls may call mbedtls_shaXXX_starts multiple times and then call the ending mbedtls_shaXXX_finish. Guard from it. */
|
||||
/* NOTE: In DMA cascade mode, re-configure SHA H/W instead of at start */
|
||||
|
||||
ctx->total = 0;
|
||||
ctx->buffer_left = 0;
|
||||
|
||||
switch (ctx->type) {
|
||||
case SHA_MODE_SHA1:
|
||||
ctx->blocksize = 64;
|
||||
ctx->blocksize_mask = 0x3F;
|
||||
break;
|
||||
|
||||
case SHA_MODE_SHA256:
|
||||
ctx->blocksize = 64;
|
||||
ctx->blocksize_mask = 0x3F;
|
||||
ctx->opmode = is224_384 ? SHA_MODE_SHA224 : SHA_MODE_SHA256;
|
||||
ctx->digestsize = is224_384 ? 28 : 32;
|
||||
break;
|
||||
|
||||
case SHA_MODE_SHA512:
|
||||
ctx->blocksize = 128;
|
||||
ctx->blocksize_mask = 0x7F;
|
||||
ctx->opmode = is224_384 ? SHA_MODE_SHA384 : SHA_MODE_SHA512;
|
||||
ctx->digestsize = is224_384 ? 48 : 64;
|
||||
break;
|
||||
|
||||
default:
|
||||
MBED_ASSERT(0);
|
||||
}
|
||||
|
||||
ctx->is224_384 = is224_384;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen)
|
||||
{
|
||||
MBED_ASSERT(ctx != NULL);
|
||||
|
||||
if (ilen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MBED_ASSERT(input != NULL);
|
||||
|
||||
int rc = 0;
|
||||
|
||||
/* One complete block = above left + new input */
|
||||
size_t fill = ctx->blocksize - ctx->buffer_left;
|
||||
if (ctx->buffer_left && ilen >= fill) {
|
||||
memcpy((void *) (ctx->buffer + ctx->buffer_left), input, fill);
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
ctx->buffer_left += fill;
|
||||
MBED_ASSERT(ctx->buffer_left == ctx->blocksize);
|
||||
rc = crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, (ctx->total == 0), 0);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
ctx->total += ctx->buffer_left;
|
||||
ctx->buffer_left = 0;
|
||||
}
|
||||
|
||||
/* Complete blocks in block runs */
|
||||
while (ilen >= NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES) {
|
||||
rc = crypto_sha_update_nobuf(ctx, input, NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES, (ctx->total == 0), 0);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
ctx->total += NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES;
|
||||
input += NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES;
|
||||
ilen -= NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES;
|
||||
}
|
||||
|
||||
/* Complete blocks modulus block run */
|
||||
fill = ilen - (ilen % ctx->blocksize);
|
||||
MBED_ASSERT((fill % ctx->blocksize) == 0);
|
||||
if (fill) {
|
||||
rc = crypto_sha_update_nobuf(ctx, input, fill, (ctx->total == 0), 0);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
ctx->total += fill;
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
}
|
||||
|
||||
/* Left incomplete block */
|
||||
if (ilen > 0) {
|
||||
MBED_ASSERT(ilen < ctx->blocksize);
|
||||
fill = ilen;
|
||||
memcpy((void *) (ctx->buffer + ctx->buffer_left), input, fill);
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
ctx->buffer_left += fill;
|
||||
}
|
||||
|
||||
MBED_ASSERT(ilen == 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int isfirst, int islast)
|
||||
{
|
||||
MBED_ASSERT(ctx != NULL);
|
||||
|
||||
/* Accept only:
|
||||
* 1. Last block which may be incomplete
|
||||
* 2. Non-last block(s) which must be complete */
|
||||
MBED_ASSERT(islast || (ilen % ctx->blocksize) == 0);
|
||||
|
||||
int rc = 0;
|
||||
|
||||
/* Acquire ownership of SHA H/W */
|
||||
crypto_sha_acquire();
|
||||
|
||||
/* Enable SHA interrupt */
|
||||
SHA_ENABLE_INT(CRPT);
|
||||
|
||||
/* Use intermediate buffer when incompatible with SHA H/W DMA buffer */
|
||||
if (!crypto_dma_buff_compat(input, ilen, 1)) {
|
||||
memcpy(dma_ctx_inst.block_imd, input, ilen);
|
||||
dma_ctx_inst.block_act = dma_ctx_inst.block_imd;
|
||||
} else {
|
||||
dma_ctx_inst.block_act = input;
|
||||
}
|
||||
if (!crypto_dma_buff_compat(ctx->fbinfo, sizeof(ctx->fbinfo), 4)) {
|
||||
memcpy(dma_ctx_inst.fbinfo_imd, ctx->fbinfo, sizeof(ctx->fbinfo));
|
||||
dma_ctx_inst.fbinfo_act = dma_ctx_inst.fbinfo_imd;
|
||||
} else {
|
||||
dma_ctx_inst.fbinfo_act = ctx->fbinfo;
|
||||
}
|
||||
|
||||
SHA_Open(CRPT, ctx->opmode, SHA_IN_SWAP, 0);
|
||||
SHA_SetDMATransfer(CRPT, (uint32_t) dma_ctx_inst.block_act, ilen);
|
||||
|
||||
/* Address of feedback information input/output */
|
||||
CRPT->HMAC_FBADDR = (uint32_t) dma_ctx_inst.fbinfo_act;
|
||||
|
||||
/* Continue above and re-configure further */
|
||||
uint32_t hmac_ctl = CRPT->HMAC_CTL |
|
||||
CRPT_HMAC_CTL_START_Msk | // Start SHA/HMAC engine
|
||||
(isfirst ? CRPT_HMAC_CTL_DMAFIRST_Msk : 0) | // SHA/HMAC first block in cascade function
|
||||
(islast ? CRPT_HMAC_CTL_DMALAST_Msk : 0) | // SHA/HMAC last block
|
||||
CRPT_HMAC_CTL_DMACSCAD_Msk | // Enable SHA/HMAC engine DMA with cascade mode
|
||||
CRPT_HMAC_CTL_DMAEN_Msk | // Enable SHA/HMAC engine DMA
|
||||
(isfirst ? 0 : CRPT_HMAC_CTL_FBIN_Msk) | // Feedback input to SHA/HMAC via DMA automatically
|
||||
// FBIN doesn't make sense for the first block, on which
|
||||
// SHA H/W isn't fool-proof. Enable FBIN for the first block
|
||||
// will crash SHA H/W.
|
||||
(islast ? 0 : CRPT_HMAC_CTL_FBOUT_Msk) | // Feedback output from SHA/HMAC via DMA automatically
|
||||
// FBOUT is unnecessary for the last block.
|
||||
0;
|
||||
|
||||
crypto_sha_prestart();
|
||||
CRPT->HMAC_CTL = hmac_ctl;
|
||||
rc = crypto_sha_wait() ? 0 : ctx->err_hw_accel;
|
||||
|
||||
/* On using intermediate buffer, restore output feedback information */
|
||||
if (rc == 0 &&
|
||||
(uint32_t) ctx->fbinfo != (uint32_t) dma_ctx_inst.fbinfo_act) {
|
||||
memcpy(ctx->fbinfo, dma_ctx_inst.fbinfo_act, sizeof(ctx->fbinfo));
|
||||
}
|
||||
|
||||
/* Disable SHA interrupt */
|
||||
SHA_DISABLE_INT(CRPT);
|
||||
|
||||
/* Release ownership of SHA H/W */
|
||||
crypto_sha_release();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int crypto_sha_finish(crypto_sha_context *ctx, unsigned char output[], size_t olen)
|
||||
{
|
||||
MBED_ASSERT(ctx != NULL);
|
||||
MBED_ASSERT(output != NULL);
|
||||
MBED_ASSERT(olen != 0 && olen == ctx->digestsize);
|
||||
|
||||
int rc = 0;
|
||||
|
||||
/* NOTE: Per real test, SHA H/W can support zero data, so we needn't
|
||||
* special handling for it. */
|
||||
rc = crypto_sha_update_nobuf(ctx, ctx->buffer, ctx->buffer_left, (ctx->total == 0), 1);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
ctx->total += ctx->buffer_left;
|
||||
ctx->buffer_left = 0;
|
||||
rc = crypto_sha_getdigest(output, ctx->digestsize);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int crypto_sha_getdigest(unsigned char output[], size_t olen)
|
||||
{
|
||||
MBED_ASSERT(output != NULL);
|
||||
MBED_ASSERT(olen != 0 && (olen % 4) == 0);
|
||||
|
||||
uint32_t *in_pos = (uint32_t *) &CRPT->HMAC_DGST[0];
|
||||
unsigned char *out_pos = output;
|
||||
uint32_t rmn = olen;
|
||||
|
||||
while (rmn) {
|
||||
uint32_t val = *in_pos ++;
|
||||
nu_set32_be(out_pos, val);
|
||||
out_pos += 4;
|
||||
rmn -= 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
|
||||
#endif /* MBEDTLS_SHA1_C || MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 MBEDTLS_SHA_ALT_HW_H
|
||||
#define MBEDTLS_SHA_ALT_HW_H
|
||||
|
||||
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Max size of SHA block in bytes
|
||||
*
|
||||
* SHA-160/224/256: 64 bytes
|
||||
* SHA-384/512: 128 bytes
|
||||
*
|
||||
* \note Support SHA1/2 only, no SHA3
|
||||
*/
|
||||
#define NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES 128
|
||||
|
||||
/**
|
||||
* \brief Max size of SHA DMA block run in bytes
|
||||
*
|
||||
* \note DMA cascade mode requires block-aligned except for the last block.
|
||||
* \note This also defines DMA intermediary buffer size.
|
||||
*/
|
||||
#define NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES \
|
||||
(NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES * 4)
|
||||
|
||||
/**
|
||||
* \brief Max size of SHA feedback information in words, used in DMA cascade mode
|
||||
*
|
||||
* SHA1/2: 54 words
|
||||
* SHA3: 88 words
|
||||
*
|
||||
* \note Support SHA1/2 only, no SHA3
|
||||
* \note According to spec, reserve 54 words for SHA1/2. But per real
|
||||
* test, SHA H/W will overwrite beyond 54 words. Workaround by
|
||||
* reserving 88 words anyway.
|
||||
*/
|
||||
#define NU_CRYPTO_SHA_MAXSIZE_FBINFO_WORDS 88
|
||||
|
||||
/**
|
||||
* \brief SHA context structure
|
||||
*
|
||||
* \note SHA type/opmode
|
||||
* 1. For type, borrow from opmode defines and can only be SHA_MODE_SHA1/SHA256/SHA512.
|
||||
* 2. Initialize opmode/digestsize dependent on type
|
||||
* 3. For SHA_MODE_SHA256/512, opmode will change to SHA_MODE_SHA224/384
|
||||
* when is224_384 is non-zero in the call to crypto_sha_starts().
|
||||
* 4. Following above, for opmode being SHA_MODE_SHA224/384, change digestsize to 28/48
|
||||
*/
|
||||
typedef struct {
|
||||
/* These fields will initialize at crypto_sha_init() */
|
||||
uint32_t type; /*!< SHA type */
|
||||
uint32_t opmode; /*!< SHA operation mode */
|
||||
uint32_t digestsize; /*!< SHA digest size */
|
||||
int err_hw_accel; /*!< Mbed TLS error code for the SHA type */
|
||||
int err_bad_input; /*!< Mbed TLS error code for the SHA type */
|
||||
|
||||
/* These fields will initialize at crypto_sha_starts() */
|
||||
uint32_t total; /*!< number of bytes processed */
|
||||
union {
|
||||
uint8_t buffer[NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES]; /*!< data block being processed. Max of SHA-1/SHA-256/SHA-512 */
|
||||
uint32_t buffer_u32[NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES/4]; /*!< make buffer word aligned */
|
||||
};
|
||||
uint16_t buffer_left;
|
||||
uint16_t blocksize; /*!< block size */
|
||||
uint32_t blocksize_mask; /*!< block size mask */
|
||||
int is224_384; /*!< 0 => SHA-256/SHA-512, else SHA-224/384 */
|
||||
uint32_t fbinfo[NU_CRYPTO_SHA_MAXSIZE_FBINFO_WORDS]; /*!< feedback information in DMA cascade mode */
|
||||
}
|
||||
crypto_sha_context;
|
||||
|
||||
void crypto_sha_init(crypto_sha_context *ctx, uint32_t type);
|
||||
void crypto_sha_free(crypto_sha_context *ctx);
|
||||
int crypto_sha_starts(crypto_sha_context *ctx, int is224_384);
|
||||
int crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen);
|
||||
int crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int isfirst, int islast);
|
||||
int crypto_sha_finish(crypto_sha_context *ctx, unsigned char output[], size_t olen);
|
||||
int crypto_sha_getdigest(unsigned char output[], size_t olen);
|
||||
|
||||
#if defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
void mbedtls_sha1_hw_init( crypto_sha_context *ctx );
|
||||
void mbedtls_sha1_hw_free( crypto_sha_context *ctx );
|
||||
int mbedtls_sha1_hw_starts( crypto_sha_context *ctx );
|
||||
int mbedtls_sha1_hw_update( crypto_sha_context *ctx, const unsigned char *input, size_t ilen );
|
||||
int mbedtls_sha1_hw_finish( crypto_sha_context *ctx, unsigned char output[20] );
|
||||
int mbedtls_sha1_hw_process( crypto_sha_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT */
|
||||
|
||||
#if defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
void mbedtls_sha256_hw_init( crypto_sha_context *ctx );
|
||||
void mbedtls_sha256_hw_free( crypto_sha_context *ctx );
|
||||
int mbedtls_sha256_hw_starts( crypto_sha_context *ctx, int is224 );
|
||||
int mbedtls_sha256_hw_update( crypto_sha_context *ctx, const unsigned char *input,
|
||||
size_t ilen );
|
||||
int mbedtls_sha256_hw_finish( crypto_sha_context *ctx, unsigned char output[32] );
|
||||
int mbedtls_sha256_hw_process( crypto_sha_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#endif /* MBEDTLS_SHA256_ALT */
|
||||
|
||||
#if defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
void mbedtls_sha512_hw_init( crypto_sha_context *ctx );
|
||||
void mbedtls_sha512_hw_free( crypto_sha_context *ctx );
|
||||
int mbedtls_sha512_hw_starts( crypto_sha_context *ctx, int is384 );
|
||||
int mbedtls_sha512_hw_update( crypto_sha_context *ctx, const unsigned char *input,
|
||||
size_t ilen );
|
||||
int mbedtls_sha512_hw_finish( crypto_sha_context *ctx, unsigned char output[64] );
|
||||
int mbedtls_sha512_hw_process( crypto_sha_context *ctx, const unsigned char data[128] );
|
||||
|
||||
#endif /* MBEDTLS_SHA512_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */
|
||||
|
||||
#endif /* sha_alt.h */
|
|
@ -14,6 +14,8 @@ target_sources(mbed-m460
|
|||
analogin_api.c
|
||||
analogout_api.c
|
||||
|
||||
crypto/crypto-misc.cpp
|
||||
|
||||
device/startup_M460.c
|
||||
device/system_M460.c
|
||||
device/StdDriver/src/m460_acmp.c
|
||||
|
@ -83,6 +85,7 @@ target_sources(mbed-m460
|
|||
target_include_directories(mbed-m460
|
||||
INTERFACE
|
||||
.
|
||||
crypto
|
||||
device
|
||||
device/Reg
|
||||
device/StdDriver/inc
|
||||
|
|
|
@ -0,0 +1,399 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 "cmsis.h"
|
||||
#include "mbed_assert.h"
|
||||
#include "mbed_atomic.h"
|
||||
#include "mbed_critical.h"
|
||||
#include "mbed_error.h"
|
||||
#include <limits.h>
|
||||
#include "nu_modutil.h"
|
||||
#include "nu_bitutil.h"
|
||||
#include "crypto-misc.h"
|
||||
#include "platform/SingletonPtr.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
|
||||
/* Consideration for choosing proper synchronization mechanism
|
||||
*
|
||||
* We choose mutex to synchronize access to crypto ACC. We can guarantee:
|
||||
* (1) No deadlock
|
||||
* We just lock mutex for a short sequence of operations rather than the whole lifetime
|
||||
* of crypto context.
|
||||
* (2) No priority inversion
|
||||
* Mutex supports priority inheritance and it is enabled.
|
||||
*/
|
||||
|
||||
/* Mutex for crypto PRNG ACC management */
|
||||
static SingletonPtr<PlatformMutex> crypto_prng_mutex;
|
||||
|
||||
/* Mutex for crypto AES ACC management */
|
||||
static SingletonPtr<PlatformMutex> crypto_aes_mutex;
|
||||
|
||||
/* Mutex for crypto SHA ACC management */
|
||||
static SingletonPtr<PlatformMutex> crypto_sha_mutex;
|
||||
|
||||
/* Mutex for crypto ECC ACC management */
|
||||
static SingletonPtr<PlatformMutex> crypto_ecc_mutex;
|
||||
|
||||
/* Mutex for crypto RSA ACC management */
|
||||
static SingletonPtr<PlatformMutex> crypto_rsa_mutex;
|
||||
|
||||
/* Crypto init counter. Crypto keeps active as it is non-zero. */
|
||||
static uint16_t crypto_init_counter = 0U;
|
||||
|
||||
/* Crypto done flags */
|
||||
#define NU_CRYPTO_DONE_OK BIT0 // Done with OK
|
||||
#define NU_CRYPTO_DONE_ERR BIT1 // Done with error
|
||||
|
||||
/* Track if PRNG H/W operation is done */
|
||||
static volatile uint16_t crypto_prng_done;
|
||||
/* Track if AES H/W operation is done */
|
||||
static volatile uint16_t crypto_aes_done;
|
||||
/* Track if SHA H/W operation is done */
|
||||
static volatile uint16_t crypto_sha_done;
|
||||
/* Track if ECC H/W operation is done */
|
||||
static volatile uint16_t crypto_ecc_done;
|
||||
/* Track if RSA H/W operation is done */
|
||||
static volatile uint16_t crypto_rsa_done;
|
||||
|
||||
static void crypto_submodule_prestart(volatile uint16_t *submodule_done);
|
||||
static bool crypto_submodule_wait(volatile uint16_t *submodule_done);
|
||||
|
||||
/* As crypto init counter changes from 0 to 1:
|
||||
*
|
||||
* 1. Enable crypto clock
|
||||
* 2. Enable crypto interrupt
|
||||
*/
|
||||
void crypto_init(void)
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
if (crypto_init_counter == USHRT_MAX) {
|
||||
core_util_critical_section_exit();
|
||||
error("Crypto clock enable counter would overflow (> USHRT_MAX)");
|
||||
}
|
||||
core_util_atomic_incr_u16(&crypto_init_counter, 1);
|
||||
if (crypto_init_counter == 1) {
|
||||
SYS_UnlockReg(); // Unlock protected register
|
||||
CLK_EnableModuleClock(CRPT_MODULE);
|
||||
SYS_ResetModule(CRPT_RST);
|
||||
SYS_LockReg(); // Lock protected register
|
||||
|
||||
NVIC_EnableIRQ(CRPT_IRQn);
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/* As crypto init counter changes from 1 to 0:
|
||||
*
|
||||
* 1. Disable crypto interrupt
|
||||
* 2. Disable crypto clock
|
||||
*/
|
||||
void crypto_uninit(void)
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
if (crypto_init_counter == 0) {
|
||||
core_util_critical_section_exit();
|
||||
error("Crypto clock enable counter would underflow (< 0)");
|
||||
}
|
||||
core_util_atomic_decr_u16(&crypto_init_counter, 1);
|
||||
if (crypto_init_counter == 0) {
|
||||
NVIC_DisableIRQ(CRPT_IRQn);
|
||||
|
||||
SYS_UnlockReg(); // Unlock protected register
|
||||
CLK_DisableModuleClock(CRPT_MODULE);
|
||||
SYS_LockReg(); // Lock protected register
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
void crypto_zeroize(void *v, size_t n)
|
||||
{
|
||||
volatile unsigned char *p = (volatile unsigned char*) v;
|
||||
while (n--) {
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
void crypto_zeroize32(uint32_t *v, size_t n)
|
||||
{
|
||||
volatile uint32_t *p = (volatile uint32_t*) v;
|
||||
while (n--) {
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void crypto_prng_acquire(void)
|
||||
{
|
||||
/* Don't check return code of Mutex::lock(void)
|
||||
*
|
||||
* This function treats RTOS errors as fatal system errors, so it can only return osOK.
|
||||
* Use of the return value is deprecated, as the return is expected to become void in
|
||||
* the future.
|
||||
*/
|
||||
crypto_prng_mutex->lock();
|
||||
}
|
||||
|
||||
void crypto_prng_release(void)
|
||||
{
|
||||
crypto_prng_mutex->unlock();
|
||||
}
|
||||
|
||||
void crypto_aes_acquire(void)
|
||||
{
|
||||
/* Don't check return code of Mutex::lock(void) */
|
||||
crypto_aes_mutex->lock();
|
||||
}
|
||||
|
||||
void crypto_aes_release(void)
|
||||
{
|
||||
crypto_aes_mutex->unlock();
|
||||
}
|
||||
|
||||
void crypto_sha_acquire(void)
|
||||
{
|
||||
/* Don't check return code of Mutex::lock(void) */
|
||||
crypto_sha_mutex->lock();
|
||||
}
|
||||
|
||||
void crypto_sha_release(void)
|
||||
{
|
||||
crypto_sha_mutex->unlock();
|
||||
}
|
||||
|
||||
void crypto_ecc_acquire(void)
|
||||
{
|
||||
/* Don't check return code of Mutex::lock(void) */
|
||||
crypto_ecc_mutex->lock();
|
||||
}
|
||||
|
||||
void crypto_ecc_release(void)
|
||||
{
|
||||
crypto_ecc_mutex->unlock();
|
||||
}
|
||||
|
||||
void crypto_rsa_acquire(void)
|
||||
{
|
||||
/* Don't check return code of Mutex::lock(void) */
|
||||
crypto_rsa_mutex->lock();
|
||||
}
|
||||
|
||||
void crypto_rsa_release(void)
|
||||
{
|
||||
crypto_rsa_mutex->unlock();
|
||||
}
|
||||
|
||||
void crypto_prng_prestart(void)
|
||||
{
|
||||
crypto_submodule_prestart(&crypto_prng_done);
|
||||
}
|
||||
|
||||
bool crypto_prng_wait(void)
|
||||
{
|
||||
return crypto_submodule_wait(&crypto_prng_done);
|
||||
}
|
||||
|
||||
void crypto_aes_prestart(void)
|
||||
{
|
||||
crypto_submodule_prestart(&crypto_aes_done);
|
||||
}
|
||||
|
||||
bool crypto_aes_wait(void)
|
||||
{
|
||||
return crypto_submodule_wait(&crypto_aes_done);
|
||||
}
|
||||
|
||||
void crypto_sha_prestart(void)
|
||||
{
|
||||
crypto_submodule_prestart(&crypto_sha_done);
|
||||
}
|
||||
|
||||
bool crypto_sha_wait(void)
|
||||
{
|
||||
return crypto_submodule_wait(&crypto_sha_done);
|
||||
}
|
||||
|
||||
void crypto_ecc_prestart(void)
|
||||
{
|
||||
crypto_submodule_prestart(&crypto_ecc_done);
|
||||
}
|
||||
|
||||
bool crypto_ecc_wait(void)
|
||||
{
|
||||
return crypto_submodule_wait(&crypto_ecc_done);
|
||||
}
|
||||
|
||||
void crypto_rsa_prestart(void)
|
||||
{
|
||||
crypto_submodule_prestart(&crypto_rsa_done);
|
||||
}
|
||||
|
||||
bool crypto_rsa_wait(void)
|
||||
{
|
||||
return crypto_submodule_wait(&crypto_rsa_done);
|
||||
}
|
||||
|
||||
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
|
||||
{
|
||||
uint32_t buff_ = (uint32_t) buff;
|
||||
|
||||
return (((buff_ & 0x03) == 0) && /* Word-aligned buffer base address */
|
||||
((buff_size & (size_aligned_to - 1)) == 0) && /* Crypto submodule dependent buffer size alignment */
|
||||
(((buff_ >> 28) == 0x2) && (buff_size <= (0x30000000 - buff_)))); /* 0x20000000-0x2FFFFFFF */
|
||||
}
|
||||
|
||||
/* Overlap cases
|
||||
*
|
||||
* 1. in_buff in front of out_buff:
|
||||
*
|
||||
* in in_end
|
||||
* | |
|
||||
* ||||||||||||||||
|
||||
* ||||||||||||||||
|
||||
* | |
|
||||
* out out_end
|
||||
*
|
||||
* 2. out_buff in front of in_buff:
|
||||
*
|
||||
* in in_end
|
||||
* | |
|
||||
* ||||||||||||||||
|
||||
* ||||||||||||||||
|
||||
* | |
|
||||
* out out_end
|
||||
*/
|
||||
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size)
|
||||
{
|
||||
uint32_t in = (uint32_t) in_buff;
|
||||
uint32_t in_end = in + in_buff_size;
|
||||
uint32_t out = (uint32_t) out_buff;
|
||||
uint32_t out_end = out + out_buff_size;
|
||||
|
||||
bool overlap = (in <= out && out < in_end) || (out <= in && in < out_end);
|
||||
|
||||
return overlap;
|
||||
}
|
||||
|
||||
static void crypto_submodule_prestart(volatile uint16_t *submodule_done)
|
||||
{
|
||||
*submodule_done = 0;
|
||||
|
||||
/* Ensure memory accesses above are completed before DMA is started
|
||||
*
|
||||
* Replacing __DSB() with __DMB() is also OK in this case.
|
||||
*
|
||||
* Refer to "multi-master systems" section with DMA in:
|
||||
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
|
||||
*/
|
||||
__DSB();
|
||||
}
|
||||
|
||||
static bool crypto_submodule_wait(volatile uint16_t *submodule_done)
|
||||
{
|
||||
while (! *submodule_done);
|
||||
|
||||
/* Ensure while loop above and subsequent code are not reordered */
|
||||
__DSB();
|
||||
|
||||
if ((*submodule_done & NU_CRYPTO_DONE_OK)) {
|
||||
/* Done with OK */
|
||||
return true;
|
||||
} else if ((*submodule_done & NU_CRYPTO_DONE_ERR)) {
|
||||
/* Done with error */
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Crypto interrupt handler */
|
||||
extern "C" void CRPT_IRQHandler()
|
||||
{
|
||||
uint32_t intsts;
|
||||
|
||||
/* PRNG */
|
||||
if ((intsts = PRNG_GET_INT_FLAG(CRPT)) != 0) {
|
||||
/* Check interrupt flags */
|
||||
if (intsts & CRPT_INTSTS_PRNGIF_Msk) {
|
||||
/* Done with OK */
|
||||
crypto_prng_done |= NU_CRYPTO_DONE_OK;
|
||||
} else if (intsts & CRPT_INTSTS_PRNGEIF_Msk) {
|
||||
/* Done with error */
|
||||
crypto_prng_done |= NU_CRYPTO_DONE_ERR;
|
||||
}
|
||||
/* Clear interrupt flag */
|
||||
PRNG_CLR_INT_FLAG(CRPT);
|
||||
}
|
||||
|
||||
/* AES */
|
||||
if ((intsts = AES_GET_INT_FLAG(CRPT)) != 0) {
|
||||
/* Check interrupt flags */
|
||||
if (intsts & CRPT_INTSTS_AESIF_Msk) {
|
||||
/* Done with OK */
|
||||
crypto_aes_done |= NU_CRYPTO_DONE_OK;
|
||||
} else if (intsts & CRPT_INTSTS_AESEIF_Msk) {
|
||||
/* Done with error */
|
||||
crypto_aes_done |= NU_CRYPTO_DONE_ERR;
|
||||
}
|
||||
/* Clear interrupt flag */
|
||||
AES_CLR_INT_FLAG(CRPT);
|
||||
}
|
||||
|
||||
/* SHA */
|
||||
if ((intsts = SHA_GET_INT_FLAG(CRPT)) != 0) {
|
||||
/* Check interrupt flags */
|
||||
if (intsts & CRPT_INTSTS_HMACIF_Msk) {
|
||||
/* Done with OK */
|
||||
crypto_sha_done |= NU_CRYPTO_DONE_OK;
|
||||
} else if (intsts & CRPT_INTSTS_HMACEIF_Msk) {
|
||||
/* Done with error */
|
||||
crypto_sha_done |= NU_CRYPTO_DONE_ERR;
|
||||
}
|
||||
/* Clear interrupt flag */
|
||||
SHA_CLR_INT_FLAG(CRPT);
|
||||
}
|
||||
|
||||
/* ECC */
|
||||
if ((intsts = ECC_GET_INT_FLAG(CRPT)) != 0) {
|
||||
/* Check interrupt flags */
|
||||
if (intsts & CRPT_INTSTS_ECCIF_Msk) {
|
||||
/* Done with OK */
|
||||
crypto_ecc_done |= NU_CRYPTO_DONE_OK;
|
||||
} else if (intsts & CRPT_INTSTS_ECCEIF_Msk) {
|
||||
/* Done with error */
|
||||
crypto_ecc_done |= NU_CRYPTO_DONE_ERR;
|
||||
}
|
||||
/* Clear interrupt flag */
|
||||
ECC_CLR_INT_FLAG(CRPT);
|
||||
}
|
||||
|
||||
/* RSA */
|
||||
if ((intsts = RSA_GET_INT_FLAG(CRPT)) != 0) {
|
||||
/* Check interrupt flags */
|
||||
if (intsts & CRPT_INTSTS_RSAIF_Msk) {
|
||||
/* Done with OK */
|
||||
crypto_rsa_done |= NU_CRYPTO_DONE_OK;
|
||||
} else if (intsts & CRPT_INTSTS_RSAEIF_Msk) {
|
||||
/* Done with error */
|
||||
crypto_rsa_done |= NU_CRYPTO_DONE_ERR;
|
||||
}
|
||||
/* Clear interrupt flag */
|
||||
RSA_CLR_INT_FLAG(CRPT);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Nuvoton Technology Corporation
|
||||
*
|
||||
* 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 MBED_CRYPTO_MISC_H
|
||||
#define MBED_CRYPTO_MISC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Init/Uninit crypto module */
|
||||
void crypto_init(void);
|
||||
void crypto_uninit(void);
|
||||
|
||||
/* Clear buffer to zero
|
||||
* Implementation that should never be optimized out by the compiler */
|
||||
void crypto_zeroize(void *v, size_t n);
|
||||
void crypto_zeroize32(uint32_t *v, size_t n);
|
||||
|
||||
/* Acquire/release ownership of crypto sub-module
|
||||
*
|
||||
* \note "acquire" is blocking until ownership is acquired
|
||||
*
|
||||
* \note "acquire"/"release" must be paired.
|
||||
*
|
||||
* \note Recursive "acquire" is allowed because the underlying synchronization
|
||||
* primitive mutex supports it.
|
||||
*/
|
||||
void crypto_prng_acquire(void);
|
||||
void crypto_prng_release(void);
|
||||
void crypto_aes_acquire(void);
|
||||
void crypto_aes_release(void);
|
||||
void crypto_sha_acquire(void);
|
||||
void crypto_sha_release(void);
|
||||
void crypto_ecc_acquire(void);
|
||||
void crypto_ecc_release(void);
|
||||
void crypto_rsa_acquire(void);
|
||||
void crypto_rsa_release(void);
|
||||
|
||||
/* Flow control between crypto/xxx start and crypto/xxx ISR
|
||||
*
|
||||
* crypto_xxx_prestart/crypto_xxx_wait encapsulate control flow between crypto/xxx start and crypto/xxx ISR.
|
||||
*
|
||||
* crypto_xxx_prestart will also address synchronization issue with memory barrier instruction.
|
||||
*
|
||||
* On finish, return of crypto_xxx_wait indicates success or not:
|
||||
* true if successful
|
||||
* false if failed
|
||||
*
|
||||
* Example: Start AES H/W and wait for its finish
|
||||
* crypto_aes_prestart();
|
||||
* AES_Start();
|
||||
* crypto_aes_wait();
|
||||
*/
|
||||
void crypto_prng_prestart(void);
|
||||
bool crypto_prng_wait(void);
|
||||
void crypto_aes_prestart(void);
|
||||
bool crypto_aes_wait(void);
|
||||
void crypto_sha_prestart(void);
|
||||
bool crypto_sha_wait(void);
|
||||
void crypto_ecc_prestart(void);
|
||||
bool crypto_ecc_wait(void);
|
||||
void crypto_rsa_prestart(void);
|
||||
bool crypto_rsa_wait(void);
|
||||
|
||||
|
||||
/* Check if buffer can be used for crypto DMA. It has the following requirements:
|
||||
* (1) Word-aligned buffer base address
|
||||
* (2) Crypto submodule (AES, SHA, etc.) dependent buffer size alignment. Must be 2 power.
|
||||
* (3) Located in 0x20000000-0x2FFFFFFF region
|
||||
*/
|
||||
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to);
|
||||
|
||||
/* Check if input/output buffers are overlapped */
|
||||
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -7503,6 +7503,9 @@
|
|||
"inherits": [
|
||||
"MCU_M460"
|
||||
],
|
||||
"macros_add": [
|
||||
"MBEDTLS_CONFIG_HW_SUPPORT"
|
||||
],
|
||||
"supported_form_factors": [
|
||||
"ARDUINO_UNO"
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue