mbed-os
Fork of mbed-os by
Diff: targets/TARGET_NUVOTON/TARGET_NUC472/trng_api.c
- Revision:
- 0:f269e3021894
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/trng_api.c Sun Oct 23 15:10:02 2016 +0000 @@ -0,0 +1,100 @@ +/* + * Hardware entropy collector for NUC472's RNGA + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 "NUC472_442.h" +#include "us_ticker_api.h" +#include "trng_api.h" + +/* + * Get Random number generator. + */ +static volatile int g_PRNG_done; + +void CRYPTO_IRQHandler() +{ + if (PRNG_GET_INT_FLAG()) { + g_PRNG_done = 1; + PRNG_CLR_INT_FLAG(); + } +} + +static void trng_get(unsigned char *pConversionData) +{ + uint32_t *p32ConversionData; + + p32ConversionData = (uint32_t *)pConversionData; + + PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read()); + PRNG_Start(); + while (!g_PRNG_done); + + PRNG_Read(p32ConversionData); +} + +void trng_init(trng_t *obj) +{ + (void)obj; + /* Unlock protected registers */ + SYS_UnlockReg(); + /* Enable IP clock */ + CLK_EnableModuleClock(CRPT_MODULE); + + /* Lock protected registers */ + SYS_LockReg(); + + NVIC_EnableIRQ(CRPT_IRQn); + PRNG_ENABLE_INT(); +} + +void trng_free(trng_t *obj) +{ + (void)obj; + PRNG_DISABLE_INT(); + NVIC_DisableIRQ(CRPT_IRQn); +} + +int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length) +{ + (void)obj; + + *output_length = 0; + if (length < 32) { + unsigned char tmpBuff[32]; + trng_get(tmpBuff); + memcpy(output, &tmpBuff, length); + *output_length = length; + } else { + for (int i = 0; i < (length/32); i++) { + trng_get(output); + *output_length += 32; + output += 32; + } + } + + return 0; +} + +#endif +