Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_uc_mmFetchFirmwareInfo.c Source File

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 }