Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
pal_plat_drbg_w_entropy_sources.c
00001 00002 // ---------------------------------------------------------------------------- 00003 // Copyright 2019 ARM Ltd. 00004 // 00005 // SPDX-License-Identifier: Apache-2.0 00006 // 00007 // Licensed under the Apache License, Version 2.0 (the "License"); 00008 // you may not use this file except in compliance with the License. 00009 // You may obtain a copy of the License at 00010 // 00011 // http://www.apache.org/licenses/LICENSE-2.0 00012 // 00013 // Unless required by applicable law or agreed to in writing, software 00014 // distributed under the License is distributed on an "AS IS" BASIS, 00015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 // See the License for the specific language governing permissions and 00017 // limitations under the License. 00018 // ---------------------------------------------------------------------------- 00019 00020 // This file is compiled if we wish to use mbedtls entropy sources for collecting entropy and updating the non-volatile entropy 00021 // There is currently an open issue https://jira.arm.com/browse/IOTCRYPT-180 (ability to accumulate sufficiently large entropy) 00022 // So, meanwhile use this module only with PSA build since we must use the mbedtls entropy sourcing method. 00023 // When this issue is resolved - SOTP builds may also use this module, which will deprecate pal_plat_drbg_sotp.c 00024 00025 // This file implements pal_plat_drbg.h for mbedtls properly 00026 00027 #if defined(MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT) 00028 #include "pal.h" 00029 #include "pal_plat_drbg.h" 00030 #include "sotp.h" 00031 #include "mbedtls/x509_crt.h" 00032 #include "mbedtls/ctr_drbg.h" 00033 #include "mbedtls/entropy.h" 00034 #include "config.h" 00035 #include "pal_plat_Crypto.h" 00036 #if PAL_USE_HW_TRNG 00037 #include "pal_plat_drbg_noise.h" 00038 #endif 00039 #include "mbed_trace.h" 00040 #include <stdlib.h> 00041 00042 #define TRACE_GROUP "PAL" 00043 00044 // Forward declaration to use non-public function from pal_plat_Crypto.c 00045 palStatus_t pal_plat_CtrDRBGSeedFromEntropySources(palCtrDrbgCtxHandle_t ctx, int (*f_entropy)(void *, unsigned char *, size_t), const void* additionalData, size_t additionalDataLen); 00046 00047 PAL_PRIVATE palCtrDrbgCtxHandle_t g_palCtrDrbgCtx = NULLPTR; 00048 00049 // Forward declaration 00050 palStatus_t pal_plat_DRBGSeed(void); 00051 00052 00053 /** 00054 * 1. init CTR DRBG context (entropy and DRBG mbedtls contexts) and noise 00055 * 2. If not expecting entropy (MBEDTLS_ENTROPY_NV_SEED not defined): 00056 * 2.a Seed the DRBG 00057 * 3. If expecting entropy (MBEDTLS_ENTROPY_NV_SEED defined): 00058 * Do nothing (DRBG will be initialized by pal_plat_osEntropyInject() 00059 */ 00060 palStatus_t pal_plat_DRBGInit(void) 00061 { 00062 palStatus_t status = PAL_SUCCESS; 00063 if (g_palCtrDrbgCtx) { 00064 return status; 00065 } 00066 00067 #if PAL_USE_HW_TRNG 00068 status = pal_plat_noiseInit(); 00069 if (status != PAL_SUCCESS) 00070 { 00071 goto Exit; 00072 } 00073 #endif 00074 00075 // Notice that pal_plat_CtrDRBGInit is used and NOT pal_CtrDRBGInit, because the latter also tries to seed the DRBG 00076 status = pal_plat_CtrDRBGInit(&g_palCtrDrbgCtx); 00077 if (status != PAL_SUCCESS) 00078 { 00079 goto Exit; 00080 } 00081 00082 /* 00083 * Seed the DRBG only if we do not expect a non-volatile entropy to be injected. 00084 * If we expect an NV seed, mbedtls_ctr_drbg_seed will fail trying to read the seed 00085 * since the entropy was not injected yet. 00086 */ 00087 00088 #ifndef MBEDTLS_ENTROPY_NV_SEED 00089 status = pal_plat_DRBGSeed(); 00090 if (status != PAL_SUCCESS) { 00091 goto Exit; 00092 } 00093 #else 00094 00095 #if PAL_USE_HW_TRNG 00096 status = pal_plat_noiseCreateThread(); 00097 if (status != PAL_SUCCESS) 00098 { 00099 PAL_LOG_ERR("Error creating noise thread\n"); 00100 goto Exit; 00101 } 00102 #endif // PAL_USE_HW_TRNG 00103 #endif // MBEDTLS_ENTROPY_NV_SEED 00104 00105 /* 00106 * At this point the DRBG has the following state: 00107 * * If defined(MBEDTLS_ENTROPY_NV_SEED): initialized but not seeded - will be seeded when pal_plat_osEntropyInject() is called. pal_plat_osRandomBuffer_blocking() 00108 * will fail until entropy is injected. 00109 * * If not defined(MBEDTLS_ENTROPY_NV_SEED): initialized and seeded. pal_plat_osRandomBuffer_blocking() call should succeed. 00110 */ 00111 00112 Exit: 00113 if (status != PAL_SUCCESS && g_palCtrDrbgCtx != NULLPTR) { 00114 (void)pal_CtrDRBGFree(&g_palCtrDrbgCtx); 00115 // No need to set g_palCtrDrbgCtx = NULLPTR, the pal_plat_CtrDRBGFree function already does so 00116 } 00117 return status; 00118 } 00119 00120 palStatus_t pal_plat_DRBGDestroy(void) 00121 { 00122 palStatus_t status = PAL_SUCCESS; 00123 if (!g_palCtrDrbgCtx) { 00124 return PAL_ERR_NOT_INITIALIZED ; 00125 } else { 00126 (void)pal_CtrDRBGFree(&g_palCtrDrbgCtx); 00127 status = pal_plat_noiseDestroy(); 00128 //g_palDRBGIsSeeded = false; 00129 } 00130 return status; 00131 } 00132 00133 //! This function must not be static as it is also called from pal_plat_osEntropyInject() which declares it explicitly 00134 // FIXME: move to pal_plat_Crypto (mbedtls) ? then pal_plat_CtrDRBGSeedFromEntropySources is a static function within 00135 // This function seeds the DRBG based on internal sources (i.e entropy that is already injected, trng, etc.) 00136 // Should be pal_plat_DRBGSeed(palCtrDrbgCtxHandle_t handle) and we can move 00137 palStatus_t pal_plat_DRBGSeed() 00138 { 00139 palStatus_t status = PAL_SUCCESS; 00140 00141 if (!g_palCtrDrbgCtx) 00142 { 00143 return PAL_ERR_NOT_INITIALIZED ; 00144 } 00145 00146 // Seed the DRBG if not seeded. If it is - reseed it. 00147 status = pal_plat_CtrDRBGSeedFromEntropySources(g_palCtrDrbgCtx, mbedtls_entropy_func, NULL, 0); 00148 00149 return status; 00150 } 00151 00152 palStatus_t pal_plat_osRandomBuffer_blocking(uint8_t *randomBuf, size_t bufSizeBytes) 00153 { 00154 palStatus_t status = PAL_SUCCESS; 00155 00156 if (!g_palCtrDrbgCtx) 00157 { 00158 return PAL_ERR_NOT_INITIALIZED ; 00159 } 00160 /* 00161 * If the DRBG is not yet seeded, try to seed it. 00162 * This check is important for the production flow where NV entropy is expected (MBEDTLS_ENTROPY_NV_SEED defined): 00163 * First run factory app: 00164 * - Entropy is injected and DRBG is seeded 00165 * Then run Pelion client app (entropy exists in storage): 00166 * - call pal_plat_osRandomBuffer_blocking(). DRBG is not seeded during pal_plat_DRBGInit() and pal_plat_osEntropyInject() 00167 * will not be called so we should seed the DRBG with the entropy already in storage. 00168 */ 00169 if (pal_CtrDRBGIsSeeded(g_palCtrDrbgCtx) == PAL_ERR_CTR_DRBG_NOT_SEEDED) 00170 { 00171 status = pal_plat_DRBGSeed(); 00172 // If seeding failed with source error, we assume that the NV source did not exist, and return a PAL_ERR_CTR_DRBG_NOT_SEEDED error 00173 if (status == PAL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) 00174 { 00175 return PAL_ERR_CTR_DRBG_NOT_SEEDED; 00176 } else if (status != PAL_SUCCESS) { 00177 return status; 00178 } 00179 } 00180 00181 #if PAL_USE_HW_TRNG 00182 return pal_plat_generateDrbgWithNoiseAttempt(g_palCtrDrbgCtx, randomBuf, false, bufSizeBytes); 00183 #else 00184 // Note that calling pal_plat_generateDrbgWithNoiseAttempt here will also work 00185 // but that will add some unnecessary code to the image. Besides, it is more clear 00186 // this way. 00187 return pal_CtrDRBGGenerate(g_palCtrDrbgCtx, randomBuf, bufSizeBytes); 00188 #endif 00189 } 00190 00191 #endif // MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
Generated on Tue Jul 12 2022 20:21:01 by
