Remove TRNG support

Reasons to remove TRNG support:
1.  M252 just has 32KiB SRAM and cannot afford mbedtls application.
2.  Implementing TRNG HAL with PRNG H/W has security concern.
pull/11696/head
Chun-Chieh Li 2019-09-27 17:50:48 +08:00 committed by adbridge
parent 7f921bc292
commit 03affe94d8
5 changed files with 0 additions and 473 deletions

View File

@ -1,274 +0,0 @@
/*
* Copyright (c) 2019, 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"
#if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT)
/* Consideration for choosing proper synchronization mechanism
*
* 1. We choose mutex to synchronize access to crypto non-SHA AC. 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.
* 2. We choose atomic flag to synchronize access to crypto SHA AC. We can guarantee:
* (1) No deadlock
* With SHA AC not supporting context save & restore, we provide SHA S/W fallback when
* SHA AC is not available.
* (2) No biting CPU
* Same reason as above.
*/
/* Mutex for crypto AES AC management */
static SingletonPtr<PlatformMutex> crypto_aes_mutex;
/* Atomic flag for crypto SHA AC management */
static core_util_atomic_flag crypto_sha_atomic_flag = CORE_UTIL_ATOMIC_FLAG_INIT;
/* Crypto (AES, DES, SHA, etc.) init counter. Crypto's keeps active as it is non-zero. */
static uint16_t crypto_init_counter = 0U;
/* Crypto done flags */
#define CRYPTO_DONE_OK BIT0 /* Done with OK */
#define 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;
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) {
CLK_EnableModuleClock(CRPT_MODULE);
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);
CLK_DisableModuleClock(CRPT_MODULE);
}
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_aes_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_aes_mutex->lock();
}
void crypto_aes_release(void)
{
crypto_aes_mutex->unlock();
}
bool crypto_sha_try_acquire(void)
{
return !core_util_atomic_flag_test_and_set(&crypto_sha_atomic_flag);
}
void crypto_sha_release(void)
{
core_util_atomic_flag_clear(&crypto_sha_atomic_flag);
}
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);
}
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 & CRYPTO_DONE_OK)) {
/* Done with OK */
return true;
} else if ((*submodule_done & CRYPTO_DONE_ERR)) {
/* Done with error */
return false;
}
return false;
}
/* Crypto interrupt handler
*
* There's inconsistency in cryptography related naming, Crpt or Crypto. For example,
* cryptography IRQ handler could be CRPT_IRQHandler or CRYPTO_IRQHandler. To override
* default cryptography IRQ handler, see device/startup_{CHIP}.c for its correct name
* or call NVIC_SetVector() in crypto_init() regardless of its name. */
extern "C" void CRPT_IRQHandler()
{
uint32_t intsts;
if ((intsts = PRNG_GET_INT_FLAG(CRYPTO_MODBASE())) != 0) {
/* Done with OK */
crypto_prng_done |= CRYPTO_DONE_OK;
/* Clear interrupt flag */
PRNG_CLR_INT_FLAG(CRYPTO_MODBASE());
} else if ((intsts = AES_GET_INT_FLAG(CRYPTO_MODBASE())) != 0) {
/* Done with OK */
crypto_aes_done |= CRYPTO_DONE_OK;
/* Clear interrupt flag */
AES_CLR_INT_FLAG(CRYPTO_MODBASE());
}
}
#endif /* #if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT) */

View File

@ -1,104 +0,0 @@
/*
* Copyright (c) 2019, 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>
#if DEVICE_TRNG || defined(MBEDTLS_CONFIG_HW_SUPPORT)
#ifdef __cplusplus
extern "C" {
#endif
/* Get Crypto module base */
__STATIC_INLINE CRPT_T *CRYPTO_MODBASE(void)
{
return CRPT;
}
/* 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_aes_acquire(void);
void crypto_aes_release(void);
/* Acquire/release ownership of crypto sub-module
*
* \return false if crytpo sub-module is held by another thread or
* another mbedtls context.
* true if successful
*
* \note Successful "try_acquire" and "release" must be paired.
*/
bool crypto_sha_try_acquire(void);
void crypto_sha_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);
/* Check if buffer can be used for crypto DMA. It has the following requirements:
* (1) Word-aligned buffer base address
* (2) Crypto submodule (AES, DES, 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
#endif

View File

@ -126,10 +126,6 @@ struct sleep_s {
int powerdown;
};
struct trng_s {
uint8_t dummy;
};
#ifdef __cplusplus
}
#endif

View File

@ -1,90 +0,0 @@
/*
* Copyright (c) 2019, 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.
*/
#if DEVICE_TRNG
#include <stdlib.h>
#include <string.h>
#include "cmsis.h"
#include "us_ticker_api.h"
#include "trng_api.h"
#include "crypto-misc.h"
/*
* Get Random number generator.
*/
#define PRNG_KEY_SIZE (0x20UL)
static void trng_get(unsigned char *pConversionData)
{
uint32_t *p32ConversionData;
p32ConversionData = (uint32_t *)pConversionData;
PRNG_Open(CRYPTO_MODBASE(), PRNG_KEY_SIZE_256, 1, us_ticker_read());
crypto_prng_prestart();
PRNG_Start(CRYPTO_MODBASE());
crypto_prng_wait();
PRNG_Read(CRYPTO_MODBASE(), p32ConversionData);
}
void trng_init(trng_t *obj)
{
(void)obj;
/* Init crypto module */
crypto_init();
PRNG_ENABLE_INT(CRYPTO_MODBASE());
}
void trng_free(trng_t *obj)
{
(void)obj;
PRNG_DISABLE_INT(CRYPTO_MODBASE());
/* Uninit crypto module */
crypto_uninit();
}
int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length)
{
(void)obj;
unsigned char tmpBuff[PRNG_KEY_SIZE];
size_t cur_length = 0;
while (length >= sizeof(tmpBuff)) {
trng_get(output);
output += sizeof(tmpBuff);
cur_length += sizeof(tmpBuff);
length -= sizeof(tmpBuff);
}
if (length > 0) {
trng_get(tmpBuff);
memcpy(output, tmpBuff, length);
cur_length += length;
crypto_zeroize(tmpBuff, sizeof(tmpBuff));
}
*output_length = cur_length;
return 0;
}
#endif

View File

@ -8895,7 +8895,6 @@
"SPI",
"SPISLAVE",
"SPI_ASYNCH",
"TRNG",
"FLASH",
"MPU"
],