yh Tang
/
NuMaker-mbed-AWS-IoT-example
NuMaker connection with AWS IoT thru MQTT/HTTPS
targets/TARGET_NUVOTON/platform_entropy.cpp@29:e890b0fdce53, 2019-10-29 (annotated)
- Committer:
- ccli8
- Date:
- Tue Oct 29 10:59:34 2019 +0800
- Revision:
- 29:e890b0fdce53
- Child:
- 33:c3a985807206
Update to mbed-os 5.14.2 and related modifications
1. Provide custom entropy source on targets without real TRNG
The targets below don't have real TRNG and cannot annouce TRNG support. A custom entropy source with EADC seeded PRNG is given to remedy it:
- NUMAKER_PFM_NUC47
- NUMAKER_PFM_M487
- NUMAKER_IOT_M487
2. Override mbed_main() for:
(1) Simulating provision process
(2) Handling host command via event queue
3. Remove memory statistics printing at end of main(). Printed via host command instead.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ccli8 |
29:e890b0fdce53 | 1 | /* |
ccli8 |
29:e890b0fdce53 | 2 | * Copyright (c) 2019 Nuvoton Technology Corporation |
ccli8 |
29:e890b0fdce53 | 3 | * |
ccli8 |
29:e890b0fdce53 | 4 | * SPDX-License-Identifier: Apache-2.0 |
ccli8 |
29:e890b0fdce53 | 5 | * |
ccli8 |
29:e890b0fdce53 | 6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
ccli8 |
29:e890b0fdce53 | 7 | * you may not use this file except in compliance with the License. |
ccli8 |
29:e890b0fdce53 | 8 | * You may obtain a copy of the License at |
ccli8 |
29:e890b0fdce53 | 9 | * |
ccli8 |
29:e890b0fdce53 | 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
ccli8 |
29:e890b0fdce53 | 11 | * |
ccli8 |
29:e890b0fdce53 | 12 | * Unless required by applicable law or agreed to in writing, software |
ccli8 |
29:e890b0fdce53 | 13 | * distributed under the License is distributed on an "AS IS" BASIS, |
ccli8 |
29:e890b0fdce53 | 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
ccli8 |
29:e890b0fdce53 | 15 | * See the License for the specific language governing permissions and |
ccli8 |
29:e890b0fdce53 | 16 | * limitations under the License. |
ccli8 |
29:e890b0fdce53 | 17 | */ |
ccli8 |
29:e890b0fdce53 | 18 | |
ccli8 |
29:e890b0fdce53 | 19 | #if !DEVICE_TRNG && !TARGET_PSA |
ccli8 |
29:e890b0fdce53 | 20 | |
ccli8 |
29:e890b0fdce53 | 21 | #include "mbed.h" |
ccli8 |
29:e890b0fdce53 | 22 | #include "mbedtls/config.h" |
ccli8 |
29:e890b0fdce53 | 23 | |
ccli8 |
29:e890b0fdce53 | 24 | #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) |
ccli8 |
29:e890b0fdce53 | 25 | |
ccli8 |
29:e890b0fdce53 | 26 | /* Support entropy source with EADC seeded PRNG on non-PSA targets without TRNG |
ccli8 |
29:e890b0fdce53 | 27 | * |
ccli8 |
29:e890b0fdce53 | 28 | * Follow the steps below to replace TRNG with EADC seeded PRNG: |
ccli8 |
29:e890b0fdce53 | 29 | * |
ccli8 |
29:e890b0fdce53 | 30 | * 1. Seed PRNG with EADC band gap |
ccli8 |
29:e890b0fdce53 | 31 | * 2. Define MBEDTLS_ENTROPY_HARDWARE_ALT and provide custom mbedtls_hardware_poll(...) |
ccli8 |
29:e890b0fdce53 | 32 | * |
ccli8 |
29:e890b0fdce53 | 33 | * Reference configuration in mbed_app.json: |
ccli8 |
29:e890b0fdce53 | 34 | * |
ccli8 |
29:e890b0fdce53 | 35 | * For Pelion/mbedtls: |
ccli8 |
29:e890b0fdce53 | 36 | * |
ccli8 |
29:e890b0fdce53 | 37 | * "target.macros_add": [ |
ccli8 |
29:e890b0fdce53 | 38 | * "MBEDTLS_USER_CONFIG_FILE=\"mbedTLSConfig_mbedOS.h\"", |
ccli8 |
29:e890b0fdce53 | 39 | * "MBEDTLS_ENTROPY_HARDWARE_ALT" |
ccli8 |
29:e890b0fdce53 | 40 | * ], |
ccli8 |
29:e890b0fdce53 | 41 | * |
ccli8 |
29:e890b0fdce53 | 42 | * For non-Pelion/mbedtls: |
ccli8 |
29:e890b0fdce53 | 43 | * |
ccli8 |
29:e890b0fdce53 | 44 | * "target.macros_add": [ |
ccli8 |
29:e890b0fdce53 | 45 | * "MBEDTLS_ENTROPY_HARDWARE_ALT" |
ccli8 |
29:e890b0fdce53 | 46 | * ], |
ccli8 |
29:e890b0fdce53 | 47 | * |
ccli8 |
29:e890b0fdce53 | 48 | * For both Pelion/non-Pelion (skip when done in targets.json): |
ccli8 |
29:e890b0fdce53 | 49 | * |
ccli8 |
29:e890b0fdce53 | 50 | * "target.device_has_remove": ["TRNG"], |
ccli8 |
29:e890b0fdce53 | 51 | * |
ccli8 |
29:e890b0fdce53 | 52 | * WARNING: If the security level of EADC seeded PRNG cannot meet requirements, replace it with another entropy source. |
ccli8 |
29:e890b0fdce53 | 53 | */ |
ccli8 |
29:e890b0fdce53 | 54 | |
ccli8 |
29:e890b0fdce53 | 55 | #include "crypto-misc.h" |
ccli8 |
29:e890b0fdce53 | 56 | |
ccli8 |
29:e890b0fdce53 | 57 | extern "C" { |
ccli8 |
29:e890b0fdce53 | 58 | int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen); |
ccli8 |
29:e890b0fdce53 | 59 | } |
ccli8 |
29:e890b0fdce53 | 60 | |
ccli8 |
29:e890b0fdce53 | 61 | /* Support EADC band gap |
ccli8 |
29:e890b0fdce53 | 62 | * |
ccli8 |
29:e890b0fdce53 | 63 | * Mbed OS defines analog-in HAL for normal purposes, but EADC band gap is not defined. |
ccli8 |
29:e890b0fdce53 | 64 | * To avoid EADC code conflict and fit into existent analog-in HAL, we: |
ccli8 |
29:e890b0fdce53 | 65 | * |
ccli8 |
29:e890b0fdce53 | 66 | * 1. Hijack AnalogIn driver to involve analog-in HAL protection and EADC initialization. |
ccli8 |
29:e890b0fdce53 | 67 | * This needs one dedicated EADC pin EADC_AUX_PINNAME. |
ccli8 |
29:e890b0fdce53 | 68 | * 2. Run EADC band gap conversion, with EADC module already initialized via above. This needs |
ccli8 |
29:e890b0fdce53 | 69 | * one dedicated sample module and one dedicated channel. |
ccli8 |
29:e890b0fdce53 | 70 | */ |
ccli8 |
29:e890b0fdce53 | 71 | |
ccli8 |
29:e890b0fdce53 | 72 | #if TARGET_NUC472 |
ccli8 |
29:e890b0fdce53 | 73 | #define EADC_AUX_PINNAME A0 |
ccli8 |
29:e890b0fdce53 | 74 | #define EADC_BANDGAP_SMPLMOD 7 |
ccli8 |
29:e890b0fdce53 | 75 | #define EADC_BANDGAP_CHN 8 |
ccli8 |
29:e890b0fdce53 | 76 | #define PRNG_KEYSIZE_ID PRNG_KEY_SIZE_128 |
ccli8 |
29:e890b0fdce53 | 77 | #define PRNG_KEYSIZE 16 |
ccli8 |
29:e890b0fdce53 | 78 | #elif TARGET_M480 |
ccli8 |
29:e890b0fdce53 | 79 | #define EADC_AUX_PINNAME A0 |
ccli8 |
29:e890b0fdce53 | 80 | #define EADC_BANDGAP_SMPLMOD 16 |
ccli8 |
29:e890b0fdce53 | 81 | #define EADC_BANDGAP_CHN 16 |
ccli8 |
29:e890b0fdce53 | 82 | #define PRNG_KEYSIZE_ID PRNG_KEY_SIZE_128 |
ccli8 |
29:e890b0fdce53 | 83 | #define PRNG_KEYSIZE 16 |
ccli8 |
29:e890b0fdce53 | 84 | #else |
ccli8 |
29:e890b0fdce53 | 85 | #error("Target not support") |
ccli8 |
29:e890b0fdce53 | 86 | #endif |
ccli8 |
29:e890b0fdce53 | 87 | |
ccli8 |
29:e890b0fdce53 | 88 | class NuBandGap : public mbed::AnalogIn { |
ccli8 |
29:e890b0fdce53 | 89 | public: |
ccli8 |
29:e890b0fdce53 | 90 | NuBandGap(); |
ccli8 |
29:e890b0fdce53 | 91 | ~NuBandGap(); |
ccli8 |
29:e890b0fdce53 | 92 | |
ccli8 |
29:e890b0fdce53 | 93 | /* Generate bitstream based on EADC band gap |
ccli8 |
29:e890b0fdce53 | 94 | * |
ccli8 |
29:e890b0fdce53 | 95 | * @returns 1/0 bitstream |
ccli8 |
29:e890b0fdce53 | 96 | */ |
ccli8 |
29:e890b0fdce53 | 97 | uint16_t read_bitstream(); |
ccli8 |
29:e890b0fdce53 | 98 | }; |
ccli8 |
29:e890b0fdce53 | 99 | |
ccli8 |
29:e890b0fdce53 | 100 | class NuEADCSeedPRNG : private mbed::NonCopyable<NuEADCSeedPRNG> |
ccli8 |
29:e890b0fdce53 | 101 | { |
ccli8 |
29:e890b0fdce53 | 102 | public: |
ccli8 |
29:e890b0fdce53 | 103 | NuEADCSeedPRNG(); |
ccli8 |
29:e890b0fdce53 | 104 | ~NuEADCSeedPRNG(); |
ccli8 |
29:e890b0fdce53 | 105 | |
ccli8 |
29:e890b0fdce53 | 106 | /* Get random data |
ccli8 |
29:e890b0fdce53 | 107 | * |
ccli8 |
29:e890b0fdce53 | 108 | * @param output The pointer to an output array |
ccli8 |
29:e890b0fdce53 | 109 | * @param len The size of output data, to avoid buffer overwrite |
ccli8 |
29:e890b0fdce53 | 110 | * @param olen The length of generated data |
ccli8 |
29:e890b0fdce53 | 111 | */ |
ccli8 |
29:e890b0fdce53 | 112 | int get_bytes(unsigned char *output, size_t len, size_t *olen); |
ccli8 |
29:e890b0fdce53 | 113 | |
ccli8 |
29:e890b0fdce53 | 114 | private: |
ccli8 |
29:e890b0fdce53 | 115 | NuBandGap band_gap; |
ccli8 |
29:e890b0fdce53 | 116 | }; |
ccli8 |
29:e890b0fdce53 | 117 | |
ccli8 |
29:e890b0fdce53 | 118 | int mbedtls_hardware_poll(MBED_UNUSED void *data, unsigned char *output, size_t len, size_t *olen) |
ccli8 |
29:e890b0fdce53 | 119 | { |
ccli8 |
29:e890b0fdce53 | 120 | static NuEADCSeedPRNG eadc_seed_prng; |
ccli8 |
29:e890b0fdce53 | 121 | |
ccli8 |
29:e890b0fdce53 | 122 | return eadc_seed_prng.get_bytes(output, len, olen); |
ccli8 |
29:e890b0fdce53 | 123 | } |
ccli8 |
29:e890b0fdce53 | 124 | |
ccli8 |
29:e890b0fdce53 | 125 | NuBandGap::NuBandGap() : mbed::AnalogIn(EADC_AUX_PINNAME) |
ccli8 |
29:e890b0fdce53 | 126 | { |
ccli8 |
29:e890b0fdce53 | 127 | EADC_T *eadc_base = (EADC_T *) EADC_BASE; |
ccli8 |
29:e890b0fdce53 | 128 | |
ccli8 |
29:e890b0fdce53 | 129 | EADC_ConfigSampleModule(eadc_base, EADC_BANDGAP_SMPLMOD, EADC_SOFTWARE_TRIGGER, EADC_BANDGAP_CHN); |
ccli8 |
29:e890b0fdce53 | 130 | } |
ccli8 |
29:e890b0fdce53 | 131 | |
ccli8 |
29:e890b0fdce53 | 132 | NuBandGap::~NuBandGap() |
ccli8 |
29:e890b0fdce53 | 133 | { |
ccli8 |
29:e890b0fdce53 | 134 | } |
ccli8 |
29:e890b0fdce53 | 135 | |
ccli8 |
29:e890b0fdce53 | 136 | uint16_t NuBandGap::read_bitstream() |
ccli8 |
29:e890b0fdce53 | 137 | { |
ccli8 |
29:e890b0fdce53 | 138 | uint16_t one_or_zero; |
ccli8 |
29:e890b0fdce53 | 139 | |
ccli8 |
29:e890b0fdce53 | 140 | lock(); |
ccli8 |
29:e890b0fdce53 | 141 | |
ccli8 |
29:e890b0fdce53 | 142 | EADC_T *eadc_base = (EADC_T *) EADC_BASE; |
ccli8 |
29:e890b0fdce53 | 143 | |
ccli8 |
29:e890b0fdce53 | 144 | EADC_START_CONV(eadc_base, 1 << EADC_BANDGAP_SMPLMOD); |
ccli8 |
29:e890b0fdce53 | 145 | while (EADC_GET_DATA_VALID_FLAG(eadc_base, 1 << EADC_BANDGAP_SMPLMOD) != (1 << EADC_BANDGAP_SMPLMOD)); |
ccli8 |
29:e890b0fdce53 | 146 | uint16_t conv_res_12 = EADC_GET_CONV_DATA(eadc_base, EADC_BANDGAP_SMPLMOD); |
ccli8 |
29:e890b0fdce53 | 147 | |
ccli8 |
29:e890b0fdce53 | 148 | /* 1 as number of 'one' is odd; 0 otherwise */ |
ccli8 |
29:e890b0fdce53 | 149 | unsigned i; |
ccli8 |
29:e890b0fdce53 | 150 | uint16_t count_one = 0; |
ccli8 |
29:e890b0fdce53 | 151 | for (i = 0; i < 12; i ++) { |
ccli8 |
29:e890b0fdce53 | 152 | if (conv_res_12 & 1) { |
ccli8 |
29:e890b0fdce53 | 153 | count_one ++; |
ccli8 |
29:e890b0fdce53 | 154 | } |
ccli8 |
29:e890b0fdce53 | 155 | conv_res_12 >>= 1; |
ccli8 |
29:e890b0fdce53 | 156 | } |
ccli8 |
29:e890b0fdce53 | 157 | one_or_zero = count_one & 1; |
ccli8 |
29:e890b0fdce53 | 158 | |
ccli8 |
29:e890b0fdce53 | 159 | unlock(); |
ccli8 |
29:e890b0fdce53 | 160 | |
ccli8 |
29:e890b0fdce53 | 161 | return one_or_zero; |
ccli8 |
29:e890b0fdce53 | 162 | } |
ccli8 |
29:e890b0fdce53 | 163 | |
ccli8 |
29:e890b0fdce53 | 164 | NuEADCSeedPRNG::NuEADCSeedPRNG() |
ccli8 |
29:e890b0fdce53 | 165 | { |
ccli8 |
29:e890b0fdce53 | 166 | crypto_init(); |
ccli8 |
29:e890b0fdce53 | 167 | PRNG_ENABLE_INT(); |
ccli8 |
29:e890b0fdce53 | 168 | |
ccli8 |
29:e890b0fdce53 | 169 | uint32_t seed = 0; |
ccli8 |
29:e890b0fdce53 | 170 | unsigned i = 32; |
ccli8 |
29:e890b0fdce53 | 171 | |
ccli8 |
29:e890b0fdce53 | 172 | /* Get seed from EADC band gap */ |
ccli8 |
29:e890b0fdce53 | 173 | while (i --) { |
ccli8 |
29:e890b0fdce53 | 174 | seed <<= 1; |
ccli8 |
29:e890b0fdce53 | 175 | seed |= band_gap.read_bitstream(); |
ccli8 |
29:e890b0fdce53 | 176 | } |
ccli8 |
29:e890b0fdce53 | 177 | |
ccli8 |
29:e890b0fdce53 | 178 | /* PRNG reload seed */ |
ccli8 |
29:e890b0fdce53 | 179 | PRNG_Open(PRNG_KEYSIZE_ID, 1, seed); |
ccli8 |
29:e890b0fdce53 | 180 | } |
ccli8 |
29:e890b0fdce53 | 181 | |
ccli8 |
29:e890b0fdce53 | 182 | NuEADCSeedPRNG::~NuEADCSeedPRNG() |
ccli8 |
29:e890b0fdce53 | 183 | { |
ccli8 |
29:e890b0fdce53 | 184 | PRNG_DISABLE_INT(); |
ccli8 |
29:e890b0fdce53 | 185 | crypto_uninit(); |
ccli8 |
29:e890b0fdce53 | 186 | } |
ccli8 |
29:e890b0fdce53 | 187 | |
ccli8 |
29:e890b0fdce53 | 188 | int NuEADCSeedPRNG::get_bytes(unsigned char *output, size_t len, size_t *olen) |
ccli8 |
29:e890b0fdce53 | 189 | { |
ccli8 |
29:e890b0fdce53 | 190 | /* Check argument validity */ |
ccli8 |
29:e890b0fdce53 | 191 | if (!output && len) { |
ccli8 |
29:e890b0fdce53 | 192 | return -1; |
ccli8 |
29:e890b0fdce53 | 193 | } |
ccli8 |
29:e890b0fdce53 | 194 | |
ccli8 |
29:e890b0fdce53 | 195 | unsigned char *output_ind = output; |
ccli8 |
29:e890b0fdce53 | 196 | size_t rmn = len; |
ccli8 |
29:e890b0fdce53 | 197 | uint32_t rand_data[PRNG_KEYSIZE / sizeof(uint32_t)]; |
ccli8 |
29:e890b0fdce53 | 198 | while (rmn) { |
ccli8 |
29:e890b0fdce53 | 199 | crypto_prng_prestart(); |
ccli8 |
29:e890b0fdce53 | 200 | PRNG_Start(); |
ccli8 |
29:e890b0fdce53 | 201 | crypto_prng_wait(); |
ccli8 |
29:e890b0fdce53 | 202 | |
ccli8 |
29:e890b0fdce53 | 203 | PRNG_Read(rand_data); |
ccli8 |
29:e890b0fdce53 | 204 | |
ccli8 |
29:e890b0fdce53 | 205 | size_t n = (rmn >= PRNG_KEYSIZE) ? PRNG_KEYSIZE : rmn; |
ccli8 |
29:e890b0fdce53 | 206 | memcpy(output_ind, rand_data, n); |
ccli8 |
29:e890b0fdce53 | 207 | |
ccli8 |
29:e890b0fdce53 | 208 | output_ind += n; |
ccli8 |
29:e890b0fdce53 | 209 | rmn -= n; |
ccli8 |
29:e890b0fdce53 | 210 | } |
ccli8 |
29:e890b0fdce53 | 211 | |
ccli8 |
29:e890b0fdce53 | 212 | if (olen) { |
ccli8 |
29:e890b0fdce53 | 213 | *olen = len; |
ccli8 |
29:e890b0fdce53 | 214 | } |
ccli8 |
29:e890b0fdce53 | 215 | |
ccli8 |
29:e890b0fdce53 | 216 | return 0; |
ccli8 |
29:e890b0fdce53 | 217 | } |
ccli8 |
29:e890b0fdce53 | 218 | |
ccli8 |
29:e890b0fdce53 | 219 | #else |
ccli8 |
29:e890b0fdce53 | 220 | |
ccli8 |
29:e890b0fdce53 | 221 | /* Support entropy source with mbedtls NV seed on non-PSA targets without TRNG |
ccli8 |
29:e890b0fdce53 | 222 | * |
ccli8 |
29:e890b0fdce53 | 223 | * Follow the steps below to replace TRNG with mbedtls NV seed: |
ccli8 |
29:e890b0fdce53 | 224 | * |
ccli8 |
29:e890b0fdce53 | 225 | * 1. Define MBEDTLS_ENTROPY_NV_SEED |
ccli8 |
29:e890b0fdce53 | 226 | * 2. Define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO/MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and provide custom mbedtls_nv_seed_read(...)/mbedtls_nv_seed_write(...). |
ccli8 |
29:e890b0fdce53 | 227 | * 3. Don't define MBEDTLS_PSA_INJECT_ENTROPY. Meet mbedtls_psa_inject_entropy(...) undefined and then provide custom one, which must be compatible with mbedtls_nv_seed_read(...)/mbedtls_nv_seed_write(...) above. |
ccli8 |
29:e890b0fdce53 | 228 | * 4. For development, simulating partial provision process, inject entropy seed via mbedtls_psa_inject_entropy(...) pre-main. |
ccli8 |
29:e890b0fdce53 | 229 | * |
ccli8 |
29:e890b0fdce53 | 230 | * Reference configuration in mbed_app.json: |
ccli8 |
29:e890b0fdce53 | 231 | * |
ccli8 |
29:e890b0fdce53 | 232 | * For Pelion/mbedtls, don't define MBEDTLS_ENTROPY_NV_SEED because it has defined in: |
ccli8 |
29:e890b0fdce53 | 233 | * https://github.com/ARMmbed/mbed-cloud-client/blob/master/mbed-client-pal/Configs/mbedTLS/mbedTLSConfig_mbedOS_SW_TRNG.h |
ccli8 |
29:e890b0fdce53 | 234 | * |
ccli8 |
29:e890b0fdce53 | 235 | * "target.macros_add": [ |
ccli8 |
29:e890b0fdce53 | 236 | * "MBEDTLS_USER_CONFIG_FILE=\"mbedTLSConfig_mbedOS_SW_TRNG.h\"", |
ccli8 |
29:e890b0fdce53 | 237 | * "PAL_USE_HW_TRNG=0", |
ccli8 |
29:e890b0fdce53 | 238 | * "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO=mbedtls_platform_seed_read", |
ccli8 |
29:e890b0fdce53 | 239 | * "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO=mbedtls_platform_seed_write" |
ccli8 |
29:e890b0fdce53 | 240 | * ], |
ccli8 |
29:e890b0fdce53 | 241 | * |
ccli8 |
29:e890b0fdce53 | 242 | * For non-Pelion/mbedtls: |
ccli8 |
29:e890b0fdce53 | 243 | * |
ccli8 |
29:e890b0fdce53 | 244 | * "target.macros_add": [ |
ccli8 |
29:e890b0fdce53 | 245 | * "MBEDTLS_ENTROPY_NV_SEED", |
ccli8 |
29:e890b0fdce53 | 246 | * "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO=mbedtls_platform_seed_read", |
ccli8 |
29:e890b0fdce53 | 247 | * "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO=mbedtls_platform_seed_write" |
ccli8 |
29:e890b0fdce53 | 248 | * ], |
ccli8 |
29:e890b0fdce53 | 249 | * |
ccli8 |
29:e890b0fdce53 | 250 | * For both Pelion/non-Pelion (skip when done in targets.json): |
ccli8 |
29:e890b0fdce53 | 251 | * |
ccli8 |
29:e890b0fdce53 | 252 | * "target.device_has_remove": ["TRNG"], |
ccli8 |
29:e890b0fdce53 | 253 | * |
ccli8 |
29:e890b0fdce53 | 254 | * WARNING: The injection of mbedtls NV seed pre-main is only for development. Run provision process for mass production. |
ccli8 |
29:e890b0fdce53 | 255 | */ |
ccli8 |
29:e890b0fdce53 | 256 | |
ccli8 |
29:e890b0fdce53 | 257 | #include "entropy_poll.h" |
ccli8 |
29:e890b0fdce53 | 258 | #include "psa/crypto.h" |
ccli8 |
29:e890b0fdce53 | 259 | #include "KVStore.h" |
ccli8 |
29:e890b0fdce53 | 260 | #include "TDBStore.h" |
ccli8 |
29:e890b0fdce53 | 261 | #include "KVMap.h" |
ccli8 |
29:e890b0fdce53 | 262 | #include "kv_config.h" |
ccli8 |
29:e890b0fdce53 | 263 | |
ccli8 |
29:e890b0fdce53 | 264 | extern "C" { |
ccli8 |
29:e890b0fdce53 | 265 | psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, size_t seed_size); |
ccli8 |
29:e890b0fdce53 | 266 | int mbedtls_platform_seed_read(unsigned char *buf, size_t buf_len); |
ccli8 |
29:e890b0fdce53 | 267 | int mbedtls_platform_seed_write(unsigned char *buf, size_t buf_len); |
ccli8 |
29:e890b0fdce53 | 268 | } |
ccli8 |
29:e890b0fdce53 | 269 | |
ccli8 |
29:e890b0fdce53 | 270 | /* Requirement of seed size |
ccli8 |
29:e890b0fdce53 | 271 | * |
ccli8 |
29:e890b0fdce53 | 272 | * 1. >= MBEDTLS_ENTROPY_MIN_PLATFORM |
ccli8 |
29:e890b0fdce53 | 273 | * 2. >= MBEDTLS_ENTROPY_BLOCK_SIZE |
ccli8 |
29:e890b0fdce53 | 274 | * 3. <= MBEDTLS_ENTROPY_MAX_SEED_SIZE |
ccli8 |
29:e890b0fdce53 | 275 | */ |
ccli8 |
29:e890b0fdce53 | 276 | #define SEED_SIZE 64 |
ccli8 |
29:e890b0fdce53 | 277 | MBED_STATIC_ASSERT(SEED_SIZE >= MBEDTLS_ENTROPY_MIN_PLATFORM, "Seed size must be larger than or equal to MBEDTLS_ENTROPY_MIN_PLATFORM"); |
ccli8 |
29:e890b0fdce53 | 278 | MBED_STATIC_ASSERT(SEED_SIZE >= MBEDTLS_ENTROPY_BLOCK_SIZE, "Seed size must be larger than or equal to MBEDTLS_ENTROPY_BLOCK_SIZE"); |
ccli8 |
29:e890b0fdce53 | 279 | MBED_STATIC_ASSERT(SEED_SIZE <= MBEDTLS_ENTROPY_MAX_SEED_SIZE, "Seed size must be smaller than or equal to MBEDTLS_ENTROPY_MAX_SEED_SIZE"); |
ccli8 |
29:e890b0fdce53 | 280 | |
ccli8 |
29:e890b0fdce53 | 281 | /* Seed key name in kvstore */ |
ccli8 |
29:e890b0fdce53 | 282 | #define KV_KEY_SEED "seed" |
ccli8 |
29:e890b0fdce53 | 283 | |
ccli8 |
29:e890b0fdce53 | 284 | /* Inject an initial entropy seed for the random generator into secure storage |
ccli8 |
29:e890b0fdce53 | 285 | * |
ccli8 |
29:e890b0fdce53 | 286 | * See reference below for its prototype: |
ccli8 |
29:e890b0fdce53 | 287 | * https://github.com/ARMmbed/mbed-os/blob/master/features/mbedtls/mbed-crypto/inc/psa/crypto_extra.h |
ccli8 |
29:e890b0fdce53 | 288 | */ |
ccli8 |
29:e890b0fdce53 | 289 | psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, size_t seed_size) |
ccli8 |
29:e890b0fdce53 | 290 | { |
ccli8 |
29:e890b0fdce53 | 291 | /* Check seed size requirement */ |
ccli8 |
29:e890b0fdce53 | 292 | if ((( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM) || (seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE)) || |
ccli8 |
29:e890b0fdce53 | 293 | (seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE)) { |
ccli8 |
29:e890b0fdce53 | 294 | return PSA_ERROR_INVALID_ARGUMENT; |
ccli8 |
29:e890b0fdce53 | 295 | } |
ccli8 |
29:e890b0fdce53 | 296 | |
ccli8 |
29:e890b0fdce53 | 297 | /* Get kvstore internal storage where seed is injected */ |
ccli8 |
29:e890b0fdce53 | 298 | KVMap &kv_map = KVMap::get_instance(); |
ccli8 |
29:e890b0fdce53 | 299 | KVStore *inner_store = kv_map.get_internal_kv_instance(NULL); |
ccli8 |
29:e890b0fdce53 | 300 | if (inner_store == NULL) { |
ccli8 |
29:e890b0fdce53 | 301 | return PSA_ERROR_STORAGE_FAILURE; |
ccli8 |
29:e890b0fdce53 | 302 | } |
ccli8 |
29:e890b0fdce53 | 303 | |
ccli8 |
29:e890b0fdce53 | 304 | /* Check if seed has injected */ |
ccli8 |
29:e890b0fdce53 | 305 | KVStore::info_t kv_info; |
ccli8 |
29:e890b0fdce53 | 306 | int kv_status = inner_store->get_info(KV_KEY_SEED, &kv_info); |
ccli8 |
29:e890b0fdce53 | 307 | if (kv_status == MBED_SUCCESS) { |
ccli8 |
29:e890b0fdce53 | 308 | return PSA_ERROR_NOT_PERMITTED; |
ccli8 |
29:e890b0fdce53 | 309 | } else if (kv_status == MBED_ERROR_ITEM_NOT_FOUND) { |
ccli8 |
29:e890b0fdce53 | 310 | /* No seed injected, inject it below */ |
ccli8 |
29:e890b0fdce53 | 311 | } else { |
ccli8 |
29:e890b0fdce53 | 312 | return PSA_ERROR_STORAGE_FAILURE; |
ccli8 |
29:e890b0fdce53 | 313 | } |
ccli8 |
29:e890b0fdce53 | 314 | |
ccli8 |
29:e890b0fdce53 | 315 | /* Inject seed into kvstore internal storage */ |
ccli8 |
29:e890b0fdce53 | 316 | kv_status = inner_store->set(KV_KEY_SEED, seed, seed_size, 0); |
ccli8 |
29:e890b0fdce53 | 317 | if (kv_status == MBED_SUCCESS) { |
ccli8 |
29:e890b0fdce53 | 318 | return PSA_SUCCESS; |
ccli8 |
29:e890b0fdce53 | 319 | } else { |
ccli8 |
29:e890b0fdce53 | 320 | return PSA_ERROR_STORAGE_FAILURE; |
ccli8 |
29:e890b0fdce53 | 321 | } |
ccli8 |
29:e890b0fdce53 | 322 | } |
ccli8 |
29:e890b0fdce53 | 323 | |
ccli8 |
29:e890b0fdce53 | 324 | int mbedtls_platform_seed_read(unsigned char *buf, size_t buf_len) |
ccli8 |
29:e890b0fdce53 | 325 | { |
ccli8 |
29:e890b0fdce53 | 326 | /* Get kvstore internal storage where seed is injected */ |
ccli8 |
29:e890b0fdce53 | 327 | KVMap &kv_map = KVMap::get_instance(); |
ccli8 |
29:e890b0fdce53 | 328 | KVStore *inner_store = kv_map.get_internal_kv_instance(NULL); |
ccli8 |
29:e890b0fdce53 | 329 | if (inner_store == NULL) { |
ccli8 |
29:e890b0fdce53 | 330 | return -1; |
ccli8 |
29:e890b0fdce53 | 331 | } |
ccli8 |
29:e890b0fdce53 | 332 | |
ccli8 |
29:e890b0fdce53 | 333 | /* Read seed from kvstore internal storage */ |
ccli8 |
29:e890b0fdce53 | 334 | size_t actual_size = 0; |
ccli8 |
29:e890b0fdce53 | 335 | int kv_status = inner_store->get(KV_KEY_SEED, buf, buf_len, &actual_size, 0); |
ccli8 |
29:e890b0fdce53 | 336 | if (kv_status != MBED_SUCCESS || actual_size != buf_len) { |
ccli8 |
29:e890b0fdce53 | 337 | return -1; |
ccli8 |
29:e890b0fdce53 | 338 | } else { |
ccli8 |
29:e890b0fdce53 | 339 | return buf_len; |
ccli8 |
29:e890b0fdce53 | 340 | } |
ccli8 |
29:e890b0fdce53 | 341 | } |
ccli8 |
29:e890b0fdce53 | 342 | |
ccli8 |
29:e890b0fdce53 | 343 | int mbedtls_platform_seed_write(unsigned char *buf, size_t buf_len) |
ccli8 |
29:e890b0fdce53 | 344 | { |
ccli8 |
29:e890b0fdce53 | 345 | /* Get kvstore internal storage where seed is injected */ |
ccli8 |
29:e890b0fdce53 | 346 | KVMap &kv_map = KVMap::get_instance(); |
ccli8 |
29:e890b0fdce53 | 347 | KVStore *inner_store = kv_map.get_internal_kv_instance(NULL); |
ccli8 |
29:e890b0fdce53 | 348 | if (inner_store == NULL) { |
ccli8 |
29:e890b0fdce53 | 349 | return -1; |
ccli8 |
29:e890b0fdce53 | 350 | } |
ccli8 |
29:e890b0fdce53 | 351 | |
ccli8 |
29:e890b0fdce53 | 352 | /* Write seed into kvstore internal storage */ |
ccli8 |
29:e890b0fdce53 | 353 | int kv_status = inner_store->set(KV_KEY_SEED, buf, buf_len, 0); |
ccli8 |
29:e890b0fdce53 | 354 | if (kv_status != MBED_SUCCESS) { |
ccli8 |
29:e890b0fdce53 | 355 | return -1; |
ccli8 |
29:e890b0fdce53 | 356 | } else { |
ccli8 |
29:e890b0fdce53 | 357 | return buf_len; |
ccli8 |
29:e890b0fdce53 | 358 | } |
ccli8 |
29:e890b0fdce53 | 359 | } |
ccli8 |
29:e890b0fdce53 | 360 | |
ccli8 |
29:e890b0fdce53 | 361 | #endif /* #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) */ |
ccli8 |
29:e890b0fdce53 | 362 | |
ccli8 |
29:e890b0fdce53 | 363 | #endif /* !DEVICE_TRNG && !TARGET_PSA */ |