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