Pfp Cybersecurity (Aka Power Fingerprinting, Inc.) / Mbed OS pfp-emon-nxp

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_entropy_mbed.c Source File

pal_plat_entropy_mbed.c

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2019 ARM Ltd.
00003 //
00004 // SPDX-License-Identifier: Apache-2.0
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the "License");
00007 // you may not use this file except in compliance with the License.
00008 // You may obtain a copy of the License at
00009 //
00010 //     http://www.apache.org/licenses/LICENSE-2.0
00011 //
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 // ----------------------------------------------------------------------------
00018 
00019 // MBEDTLS_PSA_HAS_ITS_IO is defined by default in mbed_lib.json of mbedcrypto (part of mbed-os)
00020 // and therefore is visible througout the entire code
00021 #if defined(MBEDTLS_PSA_HAS_ITS_IO) && defined(MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT)
00022 
00023 #include "pal.h"
00024 #include "pal_plat_entropy.h"
00025 #include "crypto.h"
00026 #include "config.h" // Include mbedtls config file explicitly for MBEDTLS_ENTROPY_NV_SEED flag
00027 
00028 /*
00029  * Declaration of the function that seeds the DRBG. It is implemented in pal_plat_drbg_w_entropy_sources.c
00030  * This is not part of the pal_plat_drbg.h interface and therefore we declare it here manually
00031  */
00032 
00033 palStatus_t pal_plat_DRBGSeed();
00034 
00035 //Error Translation from PSA module to PAL
00036 PAL_PRIVATE palStatus_t pal_osPsaErrorTranslation(psa_status_t err)
00037 {
00038     palStatus_t ret;
00039     switch (err) {
00040         case PSA_SUCCESS:
00041             ret = PAL_SUCCESS;
00042             break;
00043         case PSA_ERROR_NOT_PERMITTED:
00044             ret = PAL_ERR_ENTROPY_EXISTS;
00045             break;
00046         default:
00047             ret = PAL_ERR_GENERIC_FAILURE ;
00048             break;
00049     }
00050     return ret;
00051 }
00052 
00053 /*
00054  * If entropy not in storage - store the entropy and seed the DRBG for future use
00055  * If entropy already in storage - do nothing return FCC_STATUS_ENTROPY_ERROR
00056  * If entropy not in storage, but DRBG is already seeded - store the entropy and reseed the DRBG
00057  */
00058 
00059 /**
00060  * Inject entropy to non-volatile memory via mbedtls PSA API
00061  * 
00062  * * If bufSizeBytes larger than 32, hash (SHA256) and inject the message digest (32 bytes)
00063  * * If it is exactly 32 inject the buffer
00064  * * If it is less than 32, return an error
00065  * 
00066  * After injecting, this API will seed the DRBG instance in pal_plat_drbg.
00067  * FIXME: When https://jira.arm.com/browse/IOTCRYPT-180 is resolved - no need to hash, just inject 48 bytes
00068  *
00069  * @param entropyBuf - pointer to buffer containing the entropy
00070  * @param bufSizeBytes - size of entropyBuf in bytes
00071  * 
00072  * @return PAL_SUCCESS - if operation is successful
00073  *         PAL_ERR_NOT_SUPPORTED - if code compiled in a way that does not expect an entropy to be injected (TRNG must be available)
00074  *         PAL_ERR_INVALID_ARGUMENT - bufSizeBytes too small
00075  *         PAL_ERR_ENTROPY_EXISTS - Entropy already injected
00076  *         PAL_ERR_GENERIC_FAILURE - any other case
00077  */
00078 palStatus_t pal_plat_osEntropyInject(const uint8_t *entropyBuf, size_t bufSizeBytes)
00079 {
00080 #ifdef MBEDTLS_ENTROPY_NV_SEED
00081     palStatus_t status = PAL_SUCCESS;
00082     bool entropyExists = false;
00083     uint8_t buf[PAL_SHA256_SIZE];
00084 
00085     if (bufSizeBytes < PAL_SHA256_SIZE) {
00086         return PAL_ERR_INVALID_ARGUMENT ;
00087     } else if (bufSizeBytes > PAL_SHA256_SIZE) { 
00088         if (pal_sha256(entropyBuf, bufSizeBytes, buf) != PAL_SUCCESS) {
00089             return PAL_ERR_GENERIC_FAILURE ;
00090         }
00091         // Point to the message digest instead of the actual message
00092         entropyBuf = buf;
00093         bufSizeBytes = PAL_SHA256_SIZE;
00094     }
00095 
00096     
00097     // Inject the entropy
00098     status = pal_osPsaErrorTranslation(mbedtls_psa_inject_entropy(entropyBuf, bufSizeBytes));
00099     if (status != PAL_SUCCESS && status != PAL_ERR_ENTROPY_EXISTS) {
00100         goto Exit;
00101     }
00102     // If entropy in storage - do nothing
00103     if (status == PAL_ERR_ENTROPY_EXISTS) {
00104         entropyExists = true;
00105     }
00106 
00107     /*
00108      * If status == PAL_ERR_ENTROPY_EXISTS, entropy is somehow already injected, yet the DRBG may not be seeded
00109      * This may happen if an injected device runs a new factory flow. We will return a PAL_ERR_ENTROPY_EXISTS
00110      * but we would still like for the DRBG to be initialized. Caller will still catch the error but will be able
00111      * to call pal_plat_osRandomBuffer_blocking() successfully.
00112      */
00113 
00114     // Only now that the entropy is injected, we may seed the DRBG, and make calls to pal_plat_osRandomBuffer_blocking()
00115     // FIXME: When the DRBG module moves to the client, it will provide a seeding API and fcc_entropy_set() will call 
00116     // the DRBG seeding function. Then pal_plat_osEntropyInject will not have to do so. Note that we seed the DRBG even
00117     // though pal_plat_osRandomBuffer_blocking() tries to seed it because we would like to know of failures as soon as
00118     // possible (already in the factory, were this API is invoked, as pal_plat_osRandomBuffer_blocking() may not be invoked
00119     // in the factory)
00120     status = pal_plat_DRBGSeed();
00121 Exit:
00122     if (entropyExists) {
00123         return PAL_ERR_ENTROPY_EXISTS;
00124     }
00125     return status;
00126 #else
00127     return PAL_ERR_NOT_SUPPORTED ;
00128 #endif
00129 }
00130 #endif