blob: a904c5c8d2871251eeeeaeffbe8e8d8829e37bb2 [file] [log] [blame]
Jonathan Huia0bf1142016-06-15 13:56:37 -07001/*
Jonathan Hui44350172016-09-13 15:57:11 -07002 * Copyright (c) 2016, The OpenThread Authors.
Jonathan Huia0bf1142016-06-15 13:56:37 -07003 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @file
Lu Wangc05c6322016-09-07 12:57:08 +080031 * This file implements a random number generator.
Jonathan Huia0bf1142016-06-15 13:56:37 -070032 *
Jonathan Huia0bf1142016-06-15 13:56:37 -070033 */
34
Lu Wang3d043442016-08-26 14:41:40 +080035#include <openthread-types.h>
36
37#include <common/code_utils.hpp>
Lu Wangc05c6322016-09-07 12:57:08 +080038#include <platform/radio.h>
Jonathan Huia0bf1142016-06-15 13:56:37 -070039#include <platform/random.h>
Jonathan Huidb436d92016-06-27 17:19:37 -070040#include "platform-cc2538.h"
Jonathan Huia0bf1142016-06-15 13:56:37 -070041
Lu Wangc05c6322016-09-07 12:57:08 +080042static void generateRandom(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength)
43{
44 HWREG(SOC_ADC_ADCCON1) &= ~(SOC_ADC_ADCCON1_RCTRL1 | SOC_ADC_ADCCON1_RCTRL0);
45 HWREG(SYS_CTRL_RCGCRFC) = SYS_CTRL_RCGCRFC_RFC0;
46
47 while (HWREG(SYS_CTRL_RCGCRFC) != SYS_CTRL_RCGCRFC_RFC0);
48
49 HWREG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_INFINITY_RX;
50 HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_RXON;
51
52 while (!HWREG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID);
53
54 for (uint16_t index = 0; index < aInputLength; index++)
55 {
56 aOutput[index] = 0;
57
58 for (uint8_t offset = 0; offset < 8 * sizeof(uint8_t); offset++)
59 {
60 aOutput[index] <<= 1;
61 aOutput[index] |= (HWREG(RFCORE_XREG_RFRND) & RFCORE_XREG_RFRND_IRND);
62 }
63 }
64
65 HWREG(RFCORE_SFR_RFST) = RFCORE_SFR_RFST_INSTR_RFOFF;
66
67 if (aOutputLength)
68 {
69 *aOutputLength = aInputLength;
70 }
71}
Jonathan Huia0bf1142016-06-15 13:56:37 -070072
Jonathan Huidc8e7de2016-06-30 09:49:45 -070073void cc2538RandomInit(void)
Jonathan Huia0bf1142016-06-15 13:56:37 -070074{
Lu Wangc05c6322016-09-07 12:57:08 +080075 uint16_t seed = 0;
76
77 while (seed == 0x0000 || seed == 0x8003)
78 {
79 generateRandom(sizeof(seed), (uint8_t *)&seed, 0);
80 }
81
82 HWREG(SOC_ADC_RNDL) = (seed >> 8) & 0xff;
83 HWREG(SOC_ADC_RNDL) = seed & 0xff;
Jonathan Huia0bf1142016-06-15 13:56:37 -070084}
85
86uint32_t otPlatRandomGet(void)
87{
Lu Wangc05c6322016-09-07 12:57:08 +080088 uint32_t random = 0;
Jonathan Huia0bf1142016-06-15 13:56:37 -070089
Lu Wangc05c6322016-09-07 12:57:08 +080090 HWREG(SOC_ADC_ADCCON1) |= SOC_ADC_ADCCON1_RCTRL0;
91 random = HWREG(SOC_ADC_RNDL) | (HWREG(SOC_ADC_RNDH) << 8);
Jonathan Huia0bf1142016-06-15 13:56:37 -070092
Lu Wangc05c6322016-09-07 12:57:08 +080093 HWREG(SOC_ADC_ADCCON1) |= SOC_ADC_ADCCON1_RCTRL0;
94 random |= ((HWREG(SOC_ADC_RNDL) | (HWREG(SOC_ADC_RNDH) << 8)) << 16);
Jonathan Huia0bf1142016-06-15 13:56:37 -070095
Lu Wangc05c6322016-09-07 12:57:08 +080096 return random;
Jonathan Huia0bf1142016-06-15 13:56:37 -070097}
Lu Wang3d043442016-08-26 14:41:40 +080098
Lu Wangc05c6322016-09-07 12:57:08 +080099ThreadError otPlatRandomSecureGet(uint16_t aInputLength, uint8_t *aOutput, uint16_t *aOutputLength)
Lu Wang3d043442016-08-26 14:41:40 +0800100{
101 ThreadError error = kThreadError_None;
Lu Wangc05c6322016-09-07 12:57:08 +0800102 uint8_t channel = 0;
Lu Wang3d043442016-08-26 14:41:40 +0800103
104 VerifyOrExit(aOutput && aOutputLength, error = kThreadError_InvalidArgs);
105
Nick Banksffbe65c2016-09-12 14:29:43 -0700106 if (otPlatRadioIsEnabled(sInstance))
Lu Wang3d043442016-08-26 14:41:40 +0800107 {
Lu Wangc05c6322016-09-07 12:57:08 +0800108 channel = 11 + (HWREG(RFCORE_XREG_FREQCTRL) - 11) / 5;
Nick Banksffbe65c2016-09-12 14:29:43 -0700109 otPlatRadioSleep(sInstance);
110 otPlatRadioDisable(sInstance);
Lu Wang3d043442016-08-26 14:41:40 +0800111 }
112
Lu Wangc05c6322016-09-07 12:57:08 +0800113 generateRandom(aInputLength, aOutput, aOutputLength);
114
115 if (channel)
116 {
117 cc2538RadioInit();
Nick Banksffbe65c2016-09-12 14:29:43 -0700118 otPlatRadioEnable(sInstance);
119 otPlatRadioReceive(sInstance, channel);
Lu Wangc05c6322016-09-07 12:57:08 +0800120 }
Lu Wang3d043442016-08-26 14:41:40 +0800121
122exit:
123 return error;
124}