3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2019 Nest Labs, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * Provides implementations for the Chip entropy sourcing functions
22 * on the Silcon Labs EFR32 platforms.
24 /* this file behaves like a config.h, comes first */
25 #include <platform/internal/CHIPDeviceLayerInternal.h>
27 #include <support/crypto/CHIPRNG.h>
29 #include <mbedtls/entropy_poll.h>
31 #include <em_device.h>
33 #if defined(_SILICON_LABS_32B_SERIES_1)
34 #include <openthread/platform/entropy.h>
35 #elif defined(_SILICON_LABS_32B_SERIES_2)
36 extern "C" int mbedtls_hardware_poll(void * data, unsigned char * output, size_t len, size_t * olen);
37 #else // !defined(_SILICON_LABS_32B_SERIES_1) && !defined(_SILICON_LABS_32B_SERIES_2)
38 #error "Unsupported EFR32 series"
41 using namespace ::chip;
43 #if !CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG
44 #error "CHIP DRBG implementation must be enabled on EFR32 platforms"
45 #endif // !CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG
48 namespace DeviceLayer {
52 * Retrieve entropy from the underlying RNG source.
54 * This function is called by the CHIP DRBG to acquire entropy.
56 int GetEntropy_EFR32(uint8_t * buf, size_t count)
60 VerifyOrDie(count <= UINT16_MAX);
62 #if defined(_SILICON_LABS_32B_SERIES_1)
63 #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
64 if (ThreadStackManagerImpl::IsInitialized())
66 ThreadStackMgr().LockThreadStack();
68 #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
70 #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
71 if (ThreadStackManagerImpl::IsInitialized())
73 ThreadStackMgr().LockThreadStack();
75 #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
77 otError otErr = otPlatEntropyGet(buf, (uint16_t) count);
78 if (otErr != OT_ERROR_NONE)
80 res = CHIP_ERROR_DRBG_ENTROPY_SOURCE_FAILED;
83 #elif defined(_SILICON_LABS_32B_SERIES_2)
84 size_t entropy_len = 0;
87 while (entropy_len < count)
89 res = mbedtls_hardware_poll(NULL, buf + entropy_len, count - entropy_len, &olen);
92 res = CHIP_ERROR_DRBG_ENTROPY_SOURCE_FAILED;
98 #else // !defined(_SILICON_LABS_32B_SERIES_1) && !defined(_SILICON_LABS_32B_SERIES_2)
99 #error "Unsupported EFR32 series"
105 CHIP_ERROR InitEntropy()
109 // Initialize the CHIP DRBG.
110 err = Platform::Security::InitSecureRandomDataSource(GetEntropy_EFR32, 64, NULL, 0);
113 // Seed the standard rand() pseudo-random generator with data from the secure random source.
116 err = Platform::Security::GetSecureRandomData((uint8_t *) &seed, sizeof(seed));
122 if (err != CHIP_NO_ERROR)
124 ChipLogError(Crypto, "InitEntropy() failed: 0x%08" PRIX32, err);
129 } // namespace Internal
130 } // namespace DeviceLayer