NuMaker Pelion Device Management example
Fork of mbed-os-example-pelion by
provision.cpp
00001 /* 00002 * Copyright (c) 2019 Nuvoton Technology Corporation 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 #include "mbed.h" 00020 #include "mbedtls/config.h" 00021 #include "entropy_poll.h" 00022 #include "kvstore_global_api.h" 00023 #include "KVStore.h" 00024 #include "TDBStore.h" 00025 #include "KVMap.h" 00026 #include "kv_config.h" 00027 #if MBED_MAJOR_VERSION >= 6 00028 #include "DeviceKey.h" 00029 #endif 00030 00031 #ifndef __STDC_FORMAT_MACROS 00032 #define __STDC_FORMAT_MACROS 00033 #endif 00034 #include <inttypes.h> 00035 00036 /* Simulate provision process for development 00037 * 00038 * 1. Reset kvstore 00039 * 2. Inject entropy seed (if no entropy source) 00040 * 3. Initialize user filesystem (if enabled) 00041 * 4. Mark the device as provisioned 00042 * 00043 * WARNING: For mass production, remove this file and run real provision process. 00044 */ 00045 00046 /* Check weak reference/definition at the link: 00047 * http://www.keil.com/support/man/docs/ARMLINK/armlink_pge1362065917715.htm */ 00048 00049 extern "C" { 00050 MBED_USED void provision(void); 00051 } 00052 00053 /* Stringize */ 00054 #define STR_EXPAND(tok) #tok 00055 #define STR(tok) STR_EXPAND(tok) 00056 00057 #define _GET_FILESYSTEM_concat(dev, ...) _get_filesystem_##dev(__VA_ARGS__) 00058 #define GET_FILESYSTEM(dev, ...) _GET_FILESYSTEM_concat(dev, __VA_ARGS__) 00059 00060 /* Key for the device provisioned */ 00061 #define KV_KEY_PROVISION "provision" 00062 00063 void provision(void) 00064 { 00065 int kv_reset(const char *kvstore_path); 00066 00067 /* Initialize kvstore */ 00068 int kv_status = kv_init_storage_config(); 00069 if (kv_status != MBED_SUCCESS) { 00070 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Initialize kvstore failed", kv_status); 00071 } 00072 00073 /* Get kvstore internal storage */ 00074 KVMap &kv_map = KVMap::get_instance(); 00075 KVStore *inner_store = kv_map.get_internal_kv_instance(NULL); 00076 if (inner_store == NULL) { 00077 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "kvstore internal storage failed"); 00078 } 00079 00080 /* Check if the device has provisioned */ 00081 KVStore::info_t kv_info; 00082 kv_status = inner_store->get_info(KV_KEY_PROVISION, &kv_info); 00083 if (kv_status == MBED_SUCCESS) { 00084 do { 00085 /* Get KV_KEY_PROVISION key */ 00086 char buffer[4]; 00087 size_t actual_size = 0; 00088 int kv_status = inner_store->get(KV_KEY_PROVISION, buffer, sizeof(buffer), &actual_size); 00089 if (kv_status != MBED_SUCCESS) { 00090 printf("Get \'%s\' failed: %d\r\n", KV_KEY_PROVISION, kv_status); 00091 break; 00092 } 00093 /* Check KV_KEY_PROVISION key's value */ 00094 if (actual_size != 1 || buffer[0] != '1') { 00095 printf("\"%s\" not equal \"%s\"\r\n", KV_KEY_PROVISION, "1"); 00096 break; 00097 } 00098 00099 printf("The device has provisioned. Skip provision process\r\n"); 00100 return; 00101 } while (0); 00102 } else if (kv_status == MBED_ERROR_ITEM_NOT_FOUND) { 00103 /* Not provisioned yet */ 00104 printf("The device has not provisioned yet. Try to provision it...\r\n"); 00105 } else { 00106 printf("Get \'%s\' key failed: %d\r\n", KV_KEY_PROVISION, kv_status); 00107 } 00108 00109 /* Provision from here */ 00110 printf("Provision for development...\r\n"); 00111 00112 printf("Reset kvstore...\r\n"); 00113 00114 /* Reset kvstore for clean kvstore */ 00115 kv_status = kv_reset("/" STR(MBED_CONF_STORAGE_DEFAULT_KV) "/"); 00116 if (kv_status != MBED_SUCCESS) { 00117 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "kv_reset() failed", kv_status); 00118 } 00119 00120 printf("\rReset kvstore...OK\r\n"); 00121 00122 #if !DEVICE_TRNG && !TARGET_PSA 00123 #if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT) 00124 /* Inject trivial seed for development */ 00125 00126 printf("Inject NV seed...\r\n"); 00127 00128 psa_status_t psa_status; 00129 uint8_t seed[SEED_SIZE] = { 0 }; 00130 00131 /* First inject seed, expect OK or seed has injected by some provision process */ 00132 psa_status = mbedtls_psa_inject_entropy(seed, sizeof(seed)); 00133 if (psa_status != PSA_SUCCESS && psa_status != PSA_ERROR_NOT_PERMITTED) { 00134 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Inject entropy failed", psa_status); 00135 } 00136 00137 /* Second inject seed, expect seed has injected above or by some provision process */ 00138 psa_status = mbedtls_psa_inject_entropy(seed, sizeof(seed)); 00139 if (psa_status != PSA_ERROR_NOT_PERMITTED) { 00140 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Re-jnject entropy expects PSA_ERROR_NOT_PERMITTED", psa_status); 00141 } 00142 00143 printf("\rInject NV seed...OK\r\n"); 00144 #endif /* !defined(MBEDTLS_ENTROPY_HARDWARE_ALT) */ 00145 #endif /* #if !DEVICE_TRNG && !TARGET_PSA */ 00146 00147 #if MBED_MAJOR_VERSION >= 6 00148 /* Since Mbedd OS 6.0, device key is not installed automatically and silently, possibly via generate_derived_key(...). Install it manually. */ 00149 printf("Install device key...\r\n"); 00150 00151 /* DeviceKey is a singleton */ 00152 DeviceKey &devkey = DeviceKey::get_instance(); 00153 00154 /* To be compatible with mbed-bootloader, install 16-byte version. */ 00155 int device_key_status = devkey.generate_root_of_trust(DEVICE_KEY_16BYTE); 00156 switch (device_key_status) { 00157 case DEVICEKEY_SUCCESS: 00158 printf("\rInstall device key...OK\r\n"); 00159 break; 00160 00161 case DEVICEKEY_ALREADY_EXIST: 00162 printf("\rInstall device key...Already existed\r\n"); 00163 break; 00164 00165 case DEVICEKEY_GENERATE_RANDOM_ERROR: 00166 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "No entropy sources and cannot generate device key"); 00167 MBED_FALLTHROUGH; 00168 00169 default: 00170 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Install device key failed", device_key_status); 00171 } 00172 #endif 00173 00174 /* Mark the device as provisioned */ 00175 kv_status = inner_store->set(KV_KEY_PROVISION, "1", 1, KVStore::WRITE_ONCE_FLAG); 00176 if (kv_status != MBED_SUCCESS) { 00177 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Mark the device as provisioned failed", kv_status); 00178 } 00179 00180 printf("Provision for development...OK\r\n"); 00181 }
Generated on Tue Jul 12 2022 16:37:29 by 1.7.2