Marco Zecchini / Mbed OS Example_RTOS
Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /*
marcozecchini 0:9fca2b23d0ba 2 * Hardware entropy collector for the K64F, using Freescale's RNGA
marcozecchini 0:9fca2b23d0ba 3 *
marcozecchini 0:9fca2b23d0ba 4 * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
marcozecchini 0:9fca2b23d0ba 5 * SPDX-License-Identifier: Apache-2.0
marcozecchini 0:9fca2b23d0ba 6 *
marcozecchini 0:9fca2b23d0ba 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
marcozecchini 0:9fca2b23d0ba 8 * not use this file except in compliance with the License.
marcozecchini 0:9fca2b23d0ba 9 * You may obtain a copy of the License at
marcozecchini 0:9fca2b23d0ba 10 *
marcozecchini 0:9fca2b23d0ba 11 * http://www.apache.org/licenses/LICENSE-2.0
marcozecchini 0:9fca2b23d0ba 12 *
marcozecchini 0:9fca2b23d0ba 13 * Unless required by applicable law or agreed to in writing, software
marcozecchini 0:9fca2b23d0ba 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
marcozecchini 0:9fca2b23d0ba 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
marcozecchini 0:9fca2b23d0ba 16 * See the License for the specific language governing permissions and
marcozecchini 0:9fca2b23d0ba 17 * limitations under the License.
marcozecchini 0:9fca2b23d0ba 18 *
marcozecchini 0:9fca2b23d0ba 19 */
marcozecchini 0:9fca2b23d0ba 20
marcozecchini 0:9fca2b23d0ba 21 /*
marcozecchini 0:9fca2b23d0ba 22 * Reference: "K64 Sub-Family Reference Manual, Rev. 2", chapter 34
marcozecchini 0:9fca2b23d0ba 23 */
marcozecchini 0:9fca2b23d0ba 24
marcozecchini 0:9fca2b23d0ba 25 #if defined(DEVICE_TRNG)
marcozecchini 0:9fca2b23d0ba 26
marcozecchini 0:9fca2b23d0ba 27 #include <stdlib.h>
marcozecchini 0:9fca2b23d0ba 28 #include "cmsis.h"
marcozecchini 0:9fca2b23d0ba 29 #include "fsl_common.h"
marcozecchini 0:9fca2b23d0ba 30 #include "fsl_clock.h"
marcozecchini 0:9fca2b23d0ba 31 #include "trng_api.h"
marcozecchini 0:9fca2b23d0ba 32
marcozecchini 0:9fca2b23d0ba 33 void trng_init(trng_t *obj)
marcozecchini 0:9fca2b23d0ba 34 {
marcozecchini 0:9fca2b23d0ba 35 (void)obj;
marcozecchini 0:9fca2b23d0ba 36 CLOCK_EnableClock(kCLOCK_Rnga0);
marcozecchini 0:9fca2b23d0ba 37 CLOCK_DisableClock(kCLOCK_Rnga0);
marcozecchini 0:9fca2b23d0ba 38 CLOCK_EnableClock(kCLOCK_Rnga0);
marcozecchini 0:9fca2b23d0ba 39 }
marcozecchini 0:9fca2b23d0ba 40
marcozecchini 0:9fca2b23d0ba 41 void trng_free(trng_t *obj)
marcozecchini 0:9fca2b23d0ba 42 {
marcozecchini 0:9fca2b23d0ba 43 (void)obj;
marcozecchini 0:9fca2b23d0ba 44 CLOCK_DisableClock(kCLOCK_Rnga0);
marcozecchini 0:9fca2b23d0ba 45 }
marcozecchini 0:9fca2b23d0ba 46
marcozecchini 0:9fca2b23d0ba 47 /*
marcozecchini 0:9fca2b23d0ba 48 * Get one byte of entropy from the RNG, assuming it is up and running.
marcozecchini 0:9fca2b23d0ba 49 * As recommended (34.1.1), get only one bit of each output.
marcozecchini 0:9fca2b23d0ba 50 */
marcozecchini 0:9fca2b23d0ba 51 static void trng_get_byte(unsigned char *byte)
marcozecchini 0:9fca2b23d0ba 52 {
marcozecchini 0:9fca2b23d0ba 53 size_t bit;
marcozecchini 0:9fca2b23d0ba 54
marcozecchini 0:9fca2b23d0ba 55 /* 34.5 Steps 3-4-5: poll SR and read from OR when ready */
marcozecchini 0:9fca2b23d0ba 56 for( bit = 0; bit < 8; bit++ )
marcozecchini 0:9fca2b23d0ba 57 {
marcozecchini 0:9fca2b23d0ba 58 while((RNG->SR & RNG_SR_OREG_LVL_MASK) == 0 );
marcozecchini 0:9fca2b23d0ba 59 *byte |= (RNG->OR & 1) << bit;
marcozecchini 0:9fca2b23d0ba 60 }
marcozecchini 0:9fca2b23d0ba 61 }
marcozecchini 0:9fca2b23d0ba 62
marcozecchini 0:9fca2b23d0ba 63 int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length)
marcozecchini 0:9fca2b23d0ba 64 {
marcozecchini 0:9fca2b23d0ba 65 (void)obj;
marcozecchini 0:9fca2b23d0ba 66 size_t i;
marcozecchini 0:9fca2b23d0ba 67
marcozecchini 0:9fca2b23d0ba 68 /* Set "Interrupt Mask", "High Assurance" and "Go",
marcozecchini 0:9fca2b23d0ba 69 * unset "Clear interrupt" and "Sleep" */
marcozecchini 0:9fca2b23d0ba 70 RNG->CR = RNG_CR_INTM_MASK | RNG_CR_HA_MASK | RNG_CR_GO_MASK;
marcozecchini 0:9fca2b23d0ba 71
marcozecchini 0:9fca2b23d0ba 72 for (i = 0; i < length; i++) {
marcozecchini 0:9fca2b23d0ba 73 trng_get_byte(output + i);
marcozecchini 0:9fca2b23d0ba 74 }
marcozecchini 0:9fca2b23d0ba 75
marcozecchini 0:9fca2b23d0ba 76 /* Just be extra sure that we didn't do it wrong */
marcozecchini 0:9fca2b23d0ba 77 if ((RNG->SR & RNG_SR_SECV_MASK) != 0) {
marcozecchini 0:9fca2b23d0ba 78 return -1;
marcozecchini 0:9fca2b23d0ba 79 }
marcozecchini 0:9fca2b23d0ba 80
marcozecchini 0:9fca2b23d0ba 81 *output_length = length;
marcozecchini 0:9fca2b23d0ba 82
marcozecchini 0:9fca2b23d0ba 83 return 0;
marcozecchini 0:9fca2b23d0ba 84 }
marcozecchini 0:9fca2b23d0ba 85
marcozecchini 0:9fca2b23d0ba 86 #endif