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