Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
arm_uc_mmFetchFirmwareInfo.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 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 #include "arm_uc_mmCryptoUtils.h" 00020 #include "arm_uc_mmCommon.h" 00021 #include "arm_uc_mmConfig.h" 00022 #include "arm_uc_mmDerManifestAccessors.h" 00023 #include "arm_uc_mmDerManifestParser.h" 00024 #include "arm_uc_mmFSMHelper.h" 00025 #include "update-client-common/arm_uc_scheduler.h" 00026 00027 #include "update-client-manifest-manager/update-client-manifest-manager.h" 00028 #include "update-client-manifest-manager/update-client-manifest-types.h" 00029 00030 #include "pal.h" 00031 00032 #include <stdint.h> 00033 #include <stdio.h> 00034 #include <stddef.h> 00035 #include <string.h> 00036 00037 #define htobe PAL_HTONL 00038 #ifndef htobe 00039 static inline uint32_t htobe(uint32_t x) 00040 { 00041 #if BYTE_ORDER == LITTLE_ENDIAN 00042 return __builtin_bswap32(x); 00043 #else 00044 return x; 00045 #endif 00046 } 00047 #endif 00048 00049 #undef ARRAY_SIZE 00050 #define ARRAY_SIZE(ENUM_AUTO)\ 00051 (sizeof(ENUM_AUTO)/sizeof((ENUM_AUTO)[0])) 00052 00053 00054 #define ARM_UC_MM_MFST_IMAGE_REF_FIELDS \ 00055 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_FMT_ENUM)\ 00056 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_STRG_ID)\ 00057 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_HASH)\ 00058 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_URL)\ 00059 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_SIZE)\ 00060 00061 static const int32_t imageRefFields [] = { 00062 #define ENUM_AUTO(ENUM_AUTO) ENUM_AUTO, 00063 ARM_UC_MM_MFST_IMAGE_REF_FIELDS 00064 #undef ENUM_AUTO 00065 }; 00066 enum imageRefFieldIdxs { 00067 #define ENUM_AUTO(ENUM_AUTO) IRF_ ## ENUM_AUTO ## _IDX, 00068 ARM_UC_MM_MFST_IMAGE_REF_FIELDS 00069 #undef ENUM_AUTO 00070 }; 00071 00072 #if ARM_UC_MANIFEST_MANAGER_TRACE_ENABLE 00073 static const char* ARM_UC_mmFwState2Str(uint32_t state) 00074 { 00075 switch (state) { 00076 #define ENUM_AUTO(name) case name: return #name; 00077 #define ENUM_FIXED(name, val) ENUM_AUTO(name) 00078 ARM_UC_MM_FW_STATE_LIST 00079 #undef ENUM_AUTO 00080 #undef ENUM_FIXED 00081 default: 00082 return "Unknown State"; 00083 } 00084 } 00085 #endif 00086 00087 int ARM_UC_mmGetImageRef(manifest_firmware_info_t* info, arm_uc_buffer_t* mfst_fwref) 00088 { 00089 arm_uc_buffer_t buffers[ARRAY_SIZE(imageRefFields)]; 00090 int rc = ARM_UC_mmDERParseTree(arm_uc_mmManifestFirmwareDescription, 00091 mfst_fwref, 00092 ARRAY_SIZE(imageRefFields), 00093 imageRefFields, 00094 buffers); 00095 if (rc == 0) 00096 { 00097 // Found local key ID and encrypted key 00098 info->cipherMode = ARM_UC_MM_CIPHERMODE_NONE; 00099 // TODO: Handle non-enum format 00100 uint32_t format = ARM_UC_mmDerBuf2Uint(&buffers[IRF_ARM_UC_MM_DER_MFST_FW_FMT_ENUM_IDX]); 00101 memset(&info->format, 0, sizeof(info->format)); 00102 info->format.words[RFC_4122_WORDS-1] = htobe(format); 00103 00104 ARM_UC_buffer_shallow_copy(&info->strgId, &buffers[IRF_ARM_UC_MM_DER_MFST_FW_STRG_ID_IDX]); 00105 ARM_UC_buffer_shallow_copy(&info->hash, &buffers[IRF_ARM_UC_MM_DER_MFST_FW_RSRC_REF_HASH_IDX]); 00106 ARM_UC_buffer_shallow_copy(&info->uri, &buffers[IRF_ARM_UC_MM_DER_MFST_FW_RSRC_REF_URL_IDX]); 00107 info->size = ARM_UC_mmDerBuf2Uint(&buffers[IRF_ARM_UC_MM_DER_MFST_FW_RSRC_REF_SIZE_IDX]); 00108 } 00109 return rc; 00110 } 00111 00112 #define ARM_UC_MM_MFST_CRYPT_LOCAL_ID_FIELDS \ 00113 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_FMT_ENUM)\ 00114 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_IV)\ 00115 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_ID_LOCAL)\ 00116 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_KEY_CIPHERKEY)\ 00117 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_STRG_ID)\ 00118 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_HASH)\ 00119 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_URL)\ 00120 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_SIZE)\ 00121 00122 static const int32_t localEncKeyFields [] = { 00123 #define ENUM_AUTO(ENUM_AUTO) ENUM_AUTO, 00124 ARM_UC_MM_MFST_CRYPT_LOCAL_ID_FIELDS 00125 #undef ENUM_AUTO 00126 }; 00127 enum localEncKeyFieldIdxs { 00128 #define ENUM_AUTO(ENUM_AUTO) LEK_ ## ENUM_AUTO ## _IDX, 00129 ARM_UC_MM_MFST_CRYPT_LOCAL_ID_FIELDS 00130 #undef ENUM_AUTO 00131 }; 00132 00133 int ARM_UC_mmGetLocalIDAndKey(manifest_firmware_info_t* info, arm_uc_buffer_t* mfst_fwref) 00134 { 00135 arm_uc_buffer_t buffers[ARRAY_SIZE(localEncKeyFields)]; 00136 int rc = ARM_UC_mmDERParseTree(arm_uc_mmManifestFirmwareDescription, 00137 mfst_fwref, 00138 ARRAY_SIZE(localEncKeyFields), 00139 localEncKeyFields, 00140 buffers); 00141 if (rc == 0) 00142 { 00143 // Found local key ID and encrypted key 00144 info->cipherMode = ARM_UC_MM_CIPHERMODE_PSK; 00145 // TODO: Handle non-enum format 00146 uint32_t format = ARM_UC_mmDerBuf2Uint(&buffers[LEK_ARM_UC_MM_DER_MFST_FW_FMT_ENUM_IDX]); 00147 memset(&info->format, 0, sizeof(info->format)); 00148 info->format.words[RFC_4122_WORDS-1] = htobe(format); 00149 ARM_UC_buffer_shallow_copy(&info->initVector, &buffers[LEK_ARM_UC_MM_DER_MFST_FW_CRYPT_IV_IDX]); 00150 ARM_UC_buffer_shallow_copy(&info->psk.keyID, &buffers[LEK_ARM_UC_MM_DER_MFST_FW_FMT_ENUM_IDX]); 00151 ARM_UC_buffer_shallow_copy(&info->psk.cipherKey, &buffers[LEK_ARM_UC_MM_DER_MFST_FW_CRYPT_KEY_CIPHERKEY_IDX]); 00152 00153 ARM_UC_buffer_shallow_copy(&info->strgId, &buffers[LEK_ARM_UC_MM_DER_MFST_FW_STRG_ID_IDX]); 00154 ARM_UC_buffer_shallow_copy(&info->hash, &buffers[LEK_ARM_UC_MM_DER_MFST_FW_RSRC_REF_HASH_IDX]); 00155 ARM_UC_buffer_shallow_copy(&info->uri, &buffers[LEK_ARM_UC_MM_DER_MFST_FW_RSRC_REF_URL_IDX]); 00156 info->size = ARM_UC_mmDerBuf2Uint(&buffers[LEK_ARM_UC_MM_DER_MFST_FW_RSRC_REF_SIZE_IDX]); 00157 } 00158 return rc; 00159 } 00160 00161 00162 #define ARM_UC_MM_MFST_CRYPT_CERT_KEY_FIELDS \ 00163 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_FMT_ENUM)\ 00164 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_IV)\ 00165 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_ID_CERT_FINGERPRINT)\ 00166 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_ID_CERT_URL)\ 00167 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_KEY_CIPHERKEY)\ 00168 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_STRG_ID)\ 00169 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_HASH)\ 00170 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_URL)\ 00171 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_SIZE)\ 00172 00173 static const int32_t certEncKeyFields [] = { 00174 #define ENUM_AUTO(ENUM_AUTO) ENUM_AUTO, 00175 ARM_UC_MM_MFST_CRYPT_CERT_KEY_FIELDS 00176 #undef ENUM_AUTO 00177 }; 00178 00179 enum certEncKeyFieldIdxs { 00180 #define ENUM_AUTO(ENUM_AUTO) CEK_ ## ENUM_AUTO ## _IDX, 00181 ARM_UC_MM_MFST_CRYPT_CERT_KEY_FIELDS 00182 #undef ENUM_AUTO 00183 }; 00184 00185 int ARM_UC_mmGetCertAndKey(manifest_firmware_info_t* info, arm_uc_buffer_t* mfst_fwref) 00186 { 00187 arm_uc_buffer_t buffers[ARRAY_SIZE(certEncKeyFields)]; 00188 int rc = ARM_UC_mmDERParseTree(arm_uc_mmManifestFirmwareDescription, 00189 mfst_fwref, 00190 ARRAY_SIZE(certEncKeyFields), 00191 certEncKeyFields, 00192 buffers); 00193 if (rc == 0) 00194 { 00195 info->cipherMode = ARM_UC_MM_CIPHERMODE_CERT_CIPHERKEY; 00196 // TODO: Handle non-enum format 00197 uint32_t format = ARM_UC_mmDerBuf2Uint(&buffers[CEK_ARM_UC_MM_DER_MFST_FW_FMT_ENUM_IDX]); 00198 memset(&info->format, 0, sizeof(info->format)); 00199 info->format.words[RFC_4122_WORDS-1] = htobe(format); 00200 ARM_UC_buffer_shallow_copy(&info->initVector, &buffers[CEK_ARM_UC_MM_DER_MFST_FW_CRYPT_IV_IDX]); 00201 00202 ARM_UC_buffer_shallow_copy(&info->certCK.certFingerPrint, &buffers[CEK_ARM_UC_MM_DER_MFST_FW_CRYPT_ID_CERT_FINGERPRINT_IDX]); 00203 ARM_UC_buffer_shallow_copy(&info->certCK.certURL, &buffers[CEK_ARM_UC_MM_DER_MFST_FW_CRYPT_ID_CERT_URL_IDX]); 00204 ARM_UC_buffer_shallow_copy(&info->certCK.cipherKey, &buffers[CEK_ARM_UC_MM_DER_MFST_FW_CRYPT_KEY_CIPHERKEY_IDX]); 00205 00206 ARM_UC_buffer_shallow_copy(&info->strgId, &buffers[CEK_ARM_UC_MM_DER_MFST_FW_STRG_ID_IDX]); 00207 ARM_UC_buffer_shallow_copy(&info->hash, &buffers[CEK_ARM_UC_MM_DER_MFST_FW_RSRC_REF_HASH_IDX]); 00208 ARM_UC_buffer_shallow_copy(&info->uri, &buffers[CEK_ARM_UC_MM_DER_MFST_FW_RSRC_REF_URL_IDX]); 00209 info->size = ARM_UC_mmDerBuf2Uint(&buffers[CEK_ARM_UC_MM_DER_MFST_FW_RSRC_REF_SIZE_IDX]); 00210 } 00211 return rc; 00212 } 00213 00214 00215 #define ARM_UC_MM_MFST_CRYPT_CERT_KEYTABLE_FIELDS \ 00216 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_FMT_ENUM)\ 00217 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_IV)\ 00218 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_ID_CERT_FINGERPRINT)\ 00219 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_ID_CERT_URL)\ 00220 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_CRYPT_KEY_KEYTABLE_REF)\ 00221 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_STRG_ID)\ 00222 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_HASH)\ 00223 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_URL)\ 00224 ENUM_AUTO(ARM_UC_MM_DER_MFST_FW_RSRC_REF_SIZE)\ 00225 00226 static const int32_t certKeyTableFields [] = { 00227 #define ENUM_AUTO(ENUM_AUTO) ENUM_AUTO, 00228 ARM_UC_MM_MFST_CRYPT_CERT_KEYTABLE_FIELDS 00229 #undef ENUM_AUTO 00230 }; 00231 00232 enum certKeyTableFieldIdxs { 00233 #define ENUM_AUTO(ENUM_AUTO) CKT_ ## ENUM_AUTO ## _IDX, 00234 ARM_UC_MM_MFST_CRYPT_CERT_KEYTABLE_FIELDS 00235 #undef ENUM_AUTO 00236 }; 00237 00238 int ARM_UC_mmGetCertAndKeyTable(manifest_firmware_info_t* info, arm_uc_buffer_t* mfst_fwref) 00239 { 00240 arm_uc_buffer_t buffers[ARRAY_SIZE(certKeyTableFields)]; 00241 int rc = ARM_UC_mmDERParseTree(arm_uc_mmManifestFirmwareDescription, 00242 mfst_fwref, 00243 ARRAY_SIZE(certKeyTableFields), 00244 certKeyTableFields, 00245 buffers); 00246 if (rc == 0) 00247 { 00248 info->cipherMode = ARM_UC_MM_CIPHERMODE_CERT_KEYTABLE; 00249 // TODO: Handle non-enum format 00250 uint32_t format = ARM_UC_mmDerBuf2Uint(&buffers[CKT_ARM_UC_MM_DER_MFST_FW_FMT_ENUM_IDX]); 00251 memset(&info->format, 0, sizeof(info->format)); 00252 info->format.words[RFC_4122_WORDS-1] = htobe(format); 00253 ARM_UC_buffer_shallow_copy(&info->initVector, &buffers[CKT_ARM_UC_MM_DER_MFST_FW_CRYPT_IV_IDX]); 00254 00255 ARM_UC_buffer_shallow_copy(&info->certKT.certFingerPrint, &buffers[CKT_ARM_UC_MM_DER_MFST_FW_CRYPT_ID_CERT_FINGERPRINT_IDX]); 00256 ARM_UC_buffer_shallow_copy(&info->certKT.certURL, &buffers[CKT_ARM_UC_MM_DER_MFST_FW_CRYPT_ID_CERT_URL_IDX]); 00257 ARM_UC_buffer_shallow_copy(&info->certKT.keyTableURL, &buffers[CKT_ARM_UC_MM_DER_MFST_FW_CRYPT_KEY_KEYTABLE_REF_IDX]); 00258 00259 ARM_UC_buffer_shallow_copy(&info->strgId, &buffers[CKT_ARM_UC_MM_DER_MFST_FW_STRG_ID_IDX]); 00260 ARM_UC_buffer_shallow_copy(&info->hash, &buffers[CKT_ARM_UC_MM_DER_MFST_FW_RSRC_REF_HASH_IDX]); 00261 ARM_UC_buffer_shallow_copy(&info->uri, &buffers[CKT_ARM_UC_MM_DER_MFST_FW_RSRC_REF_URL_IDX]); 00262 info->size = ARM_UC_mmDerBuf2Uint(&buffers[CKT_ARM_UC_MM_DER_MFST_FW_RSRC_REF_SIZE_IDX]); 00263 } 00264 return rc; 00265 } 00266 00267 arm_uc_error_t ARM_UC_mmFetchFirmwareInfoFSM(uint32_t event) 00268 { 00269 arm_uc_error_t err = {MFST_ERR_NONE}; 00270 if (arm_uc_mmPersistentContext.ctx == NULL || *arm_uc_mmPersistentContext.ctx == NULL) 00271 { 00272 return (arm_uc_error_t){MFST_ERR_NULL_PTR}; 00273 } 00274 struct arm_uc_mm_fw_context_t* ctx = &(*arm_uc_mmPersistentContext.ctx)->getFw; 00275 if (ctx->info == NULL) 00276 { 00277 return (arm_uc_error_t){MFST_ERR_NULL_PTR}; 00278 } 00279 ARM_UC_MM_FSM_HELPER_START(*ctx, ARM_UC_mmFwState2Str) { 00280 case ARM_UC_MM_FW_STATE_IDLE: 00281 err = (arm_uc_error_t){MFST_ERR_NONE}; 00282 break; 00283 case ARM_UC_MM_FW_STATE_BEGIN: 00284 { 00285 // If there is no manifest storage, assume it is still present in the input buffer 00286 ctx->state = ARM_UC_MM_FW_STATE_READ_URI; 00287 ARM_UC_MM_SET_BUFFER(ctx->current_data, ctx->info->manifestBuffer); 00288 ctx->current_data.size = ctx->info->manifestSize; 00289 break; 00290 } 00291 case ARM_UC_MM_FW_STATE_READ_URI: 00292 { 00293 // Get the encryption mode and the firmware info block. 00294 const int32_t fieldIDs [] = {ARM_UC_MM_DER_MFST_ENC_ENUM, ARM_UC_MM_DER_MFST_FIRMWARE}; 00295 arm_uc_buffer_t buffers [sizeof(fieldIDs)/sizeof(fieldIDs[0])]; 00296 int rc = ARM_UC_mmDERGetSignedResourceValues( 00297 &ctx->current_data, 00298 sizeof(fieldIDs)/sizeof(fieldIDs[0]), 00299 fieldIDs, 00300 buffers); 00301 if (rc < 0) 00302 { 00303 err.code = MFST_ERR_DER_FORMAT; 00304 break; 00305 } 00306 else if (rc > 0) 00307 { 00308 // in storage mode, firmware must be supplied. 00309 err.code = MFST_ERR_EMPTY_FIELD; 00310 break; 00311 } 00312 arm_uc_buffer_t fwBuf; 00313 ARM_UC_buffer_shallow_copy(&fwBuf, &buffers[1]); 00314 00315 // Store timestamp 00316 ARM_UC_MM_SET_BUFFER(ctx->current_data, ctx->info->manifestBuffer); 00317 ctx->current_data.size = ctx->info->manifestSize; 00318 err = ARM_UC_mmGetTimestamp(&ctx->current_data, &ctx->info->timestamp); 00319 if (err.error != 0) 00320 { 00321 break; 00322 } 00323 00324 ctx->info->cipherMode = ARM_UC_MM_CIPHERMODE_NONE; 00325 // Found an encryption mode and firmware! 00326 uint32_t cryptoMode = ARM_UC_mmDerBuf2Uint(&buffers[0]); 00327 if (!ARM_UC_mmGetCryptoFlags(cryptoMode).aes) 00328 { 00329 // Encryption not in use. Skip key, ID, and IV extraction. 00330 rc = ARM_UC_mmGetImageRef(ctx->info, &fwBuf); 00331 if (rc == 0) 00332 { 00333 ctx->state = ARM_UC_MM_FW_STATE_NOTIFY; 00334 err.code = MFST_ERR_NONE; 00335 } 00336 else 00337 { 00338 err.code = MFST_ERR_DER_FORMAT; 00339 } 00340 break; 00341 } 00342 // There are three possible combinations of encryption info: 00343 // local key ID & encrypted key 00344 rc = ARM_UC_mmGetLocalIDAndKey(ctx->info, &fwBuf); 00345 if (!rc) { 00346 ctx->state = ARM_UC_MM_FW_STATE_NOTIFY; 00347 err.code = MFST_ERR_NONE; 00348 break; 00349 } 00350 // Certificate and encrypted key 00351 rc = ARM_UC_mmGetCertAndKey(ctx->info, &fwBuf); 00352 if (!rc) { 00353 ctx->state = ARM_UC_MM_FW_STATE_NOTIFY; 00354 err.code = MFST_ERR_NONE; 00355 break; 00356 } 00357 // Certificate and key table reference 00358 rc = ARM_UC_mmGetCertAndKeyTable(ctx->info, &fwBuf); 00359 if (!rc) { 00360 ctx->state = ARM_UC_MM_FW_STATE_NOTIFY; 00361 err.code = MFST_ERR_NONE; 00362 break; 00363 } 00364 00365 break; 00366 } 00367 case ARM_UC_MM_FW_STATE_GET_FW_REF: 00368 00369 // TODO: Ref only 00370 case ARM_UC_MM_FW_STATE_NOTIFY: 00371 ctx->state = ARM_UC_MM_FW_STATE_ROOT_NOTIFY_WAIT; 00372 err.code = MFST_ERR_PENDING; 00373 ARM_UC_PostCallback(&ctx->callbackStorage, arm_uc_mmPersistentContext.applicationEventHandler, ARM_UC_MM_RC_NEED_FW); 00374 break; 00375 00376 case ARM_UC_MM_FW_STATE_ROOT_NOTIFY_WAIT: 00377 if (event == ARM_UC_MM_EVENT_BEGIN) 00378 { 00379 err.code = MFST_ERR_NONE; 00380 ctx->state = ARM_UC_MM_FW_STATE_DONE; 00381 } 00382 break; 00383 case ARM_UC_MM_FW_STATE_DONE: 00384 // NOTE: The outer FSM will send the "done" message. 00385 ctx->state = ARM_UC_MM_FW_STATE_IDLE; 00386 break; 00387 case ARM_UC_MM_FW_STATE_INVALID: 00388 default: 00389 err = (arm_uc_error_t){MFST_ERR_INVALID_STATE}; 00390 break; 00391 } ARM_UC_MM_FSM_HELPER_FINISH(*ctx); 00392 return err; 00393 }
Generated on Tue Jul 12 2022 19:12:11 by 1.7.2