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.
mbed-cloud-client/update-client-hub/modules/manifest-manager/source/arm_uc_mmInit.c@2:bf2124b482f9, 2018-07-02 (annotated)
- Committer:
- MACRUM
- Date:
- Mon Jul 02 08:06:37 2018 +0000
- Revision:
- 2:bf2124b482f9
- Parent:
- 0:276e7a263c35
Update library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MACRUM | 0:276e7a263c35 | 1 | // ---------------------------------------------------------------------------- |
MACRUM | 0:276e7a263c35 | 2 | // Copyright 2016-2017 ARM Ltd. |
MACRUM | 0:276e7a263c35 | 3 | // |
MACRUM | 0:276e7a263c35 | 4 | // SPDX-License-Identifier: Apache-2.0 |
MACRUM | 0:276e7a263c35 | 5 | // |
MACRUM | 0:276e7a263c35 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); |
MACRUM | 0:276e7a263c35 | 7 | // you may not use this file except in compliance with the License. |
MACRUM | 0:276e7a263c35 | 8 | // You may obtain a copy of the License at |
MACRUM | 0:276e7a263c35 | 9 | // |
MACRUM | 0:276e7a263c35 | 10 | // http://www.apache.org/licenses/LICENSE-2.0 |
MACRUM | 0:276e7a263c35 | 11 | // |
MACRUM | 0:276e7a263c35 | 12 | // Unless required by applicable law or agreed to in writing, software |
MACRUM | 0:276e7a263c35 | 13 | // distributed under the License is distributed on an "AS IS" BASIS, |
MACRUM | 0:276e7a263c35 | 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
MACRUM | 0:276e7a263c35 | 15 | // See the License for the specific language governing permissions and |
MACRUM | 0:276e7a263c35 | 16 | // limitations under the License. |
MACRUM | 0:276e7a263c35 | 17 | // ---------------------------------------------------------------------------- |
MACRUM | 0:276e7a263c35 | 18 | |
MACRUM | 0:276e7a263c35 | 19 | #include "arm_uc_mmInit.h" |
MACRUM | 0:276e7a263c35 | 20 | #include "arm_uc_mmCommon.h" |
MACRUM | 0:276e7a263c35 | 21 | #if !MANIFEST_MANAGER_NO_STORAGE |
MACRUM | 0:276e7a263c35 | 22 | #include "update-client-manifest-manager/update-client-manifest-manager-context.h" |
MACRUM | 0:276e7a263c35 | 23 | #include "arm_uc_mmGetLatestTimestamp.h" |
MACRUM | 0:276e7a263c35 | 24 | #include "arm_uc_mm_derparse.h" |
MACRUM | 0:276e7a263c35 | 25 | #include "cfstore-fsm.h" |
MACRUM | 0:276e7a263c35 | 26 | #include "crypto-fsm.h" |
MACRUM | 0:276e7a263c35 | 27 | #include "accessors.h" |
MACRUM | 0:276e7a263c35 | 28 | #include "update-client-common/arm_uc_types.h" |
MACRUM | 0:276e7a263c35 | 29 | #include "update-client-common/arm_uc_common.h" |
MACRUM | 0:276e7a263c35 | 30 | #include "update-client-common/arm_uc_error.h" |
MACRUM | 0:276e7a263c35 | 31 | #include "mbedtls/sha256.h" |
MACRUM | 0:276e7a263c35 | 32 | |
MACRUM | 0:276e7a263c35 | 33 | #include "arm_uc_mmFSMHelper.h" |
MACRUM | 0:276e7a263c35 | 34 | |
MACRUM | 0:276e7a263c35 | 35 | #ifndef min |
MACRUM | 0:276e7a263c35 | 36 | #define min(X,Y) ((X) < (Y) ? (X) : (Y)) |
MACRUM | 0:276e7a263c35 | 37 | #endif |
MACRUM | 0:276e7a263c35 | 38 | |
MACRUM | 0:276e7a263c35 | 39 | const char* ARM_UC_mmInitState2Str(uint32_t state) |
MACRUM | 0:276e7a263c35 | 40 | { |
MACRUM | 0:276e7a263c35 | 41 | switch (state) { |
MACRUM | 0:276e7a263c35 | 42 | #define ENUM_AUTO(name) case name: return #name; |
MACRUM | 0:276e7a263c35 | 43 | #define ENUM_FIXED(name, val) ENUM_AUTO(name) |
MACRUM | 0:276e7a263c35 | 44 | ARM_UC_MM_INIT_STATE_LIST |
MACRUM | 0:276e7a263c35 | 45 | #undef ENUM_FIXED |
MACRUM | 0:276e7a263c35 | 46 | #undef ENUM_AUTO |
MACRUM | 0:276e7a263c35 | 47 | default: |
MACRUM | 0:276e7a263c35 | 48 | return "Unknown State"; |
MACRUM | 0:276e7a263c35 | 49 | } |
MACRUM | 0:276e7a263c35 | 50 | } |
MACRUM | 0:276e7a263c35 | 51 | |
MACRUM | 0:276e7a263c35 | 52 | |
MACRUM | 0:276e7a263c35 | 53 | |
MACRUM | 0:276e7a263c35 | 54 | arm_uc_error_t arm_uc_mmInitFSM(uint32_t event) |
MACRUM | 0:276e7a263c35 | 55 | { |
MACRUM | 0:276e7a263c35 | 56 | if (arm_uc_mmPersistentContext.ctx == NULL || *arm_uc_mmPersistentContext.ctx == NULL) |
MACRUM | 0:276e7a263c35 | 57 | { |
MACRUM | 0:276e7a263c35 | 58 | return (arm_uc_error_t){MFST_ERR_NULL_PTR}; |
MACRUM | 0:276e7a263c35 | 59 | } |
MACRUM | 0:276e7a263c35 | 60 | struct arm_uc_mmInitContext_t* ctx = &(*arm_uc_mmPersistentContext.ctx)->init; |
MACRUM | 0:276e7a263c35 | 61 | arm_uc_error_t err = {MFST_ERR_PENDING}; |
MACRUM | 0:276e7a263c35 | 62 | |
MACRUM | 0:276e7a263c35 | 63 | ARM_UC_MM_FSM_HELPER_START(*ctx, ARM_UC_mmInitState2Str){ |
MACRUM | 0:276e7a263c35 | 64 | case ARM_UC_MM_INIT_BEGIN: |
MACRUM | 0:276e7a263c35 | 65 | // Find the latest manifest. |
MACRUM | 0:276e7a263c35 | 66 | ARM_UC_MM_SET_BUFFER(ctx->keyPath, ctx->pathBuffer); |
MACRUM | 0:276e7a263c35 | 67 | err = getLatestManifestTimestamp(&ctx->timestamp, &ctx->keyPath); |
MACRUM | 0:276e7a263c35 | 68 | ctx->state = ARM_UC_MM_INIT_LATEST_MFST; |
MACRUM | 0:276e7a263c35 | 69 | // clear the missing dep flag |
MACRUM | 0:276e7a263c35 | 70 | ctx->missingDep = 0; |
MACRUM | 0:276e7a263c35 | 71 | // Set the root manifest flag |
MACRUM | 0:276e7a263c35 | 72 | ctx->root = 1; |
MACRUM | 0:276e7a263c35 | 73 | |
MACRUM | 0:276e7a263c35 | 74 | event = ARM_UC_MM_EVENT_BEGIN; |
MACRUM | 0:276e7a263c35 | 75 | break; |
MACRUM | 0:276e7a263c35 | 76 | case ARM_UC_MM_INIT_LATEST_MFST: |
MACRUM | 0:276e7a263c35 | 77 | { |
MACRUM | 0:276e7a263c35 | 78 | err = getLatestManifestTimestampFSM(event); |
MACRUM | 0:276e7a263c35 | 79 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 80 | { |
MACRUM | 0:276e7a263c35 | 81 | break; |
MACRUM | 0:276e7a263c35 | 82 | } |
MACRUM | 0:276e7a263c35 | 83 | if (ctx->timestamp == 0) |
MACRUM | 0:276e7a263c35 | 84 | { |
MACRUM | 0:276e7a263c35 | 85 | err.code = MFST_ERR_NO_MANIFEST; |
MACRUM | 0:276e7a263c35 | 86 | break; |
MACRUM | 0:276e7a263c35 | 87 | } |
MACRUM | 0:276e7a263c35 | 88 | // Copy out the root manifest's base path |
MACRUM | 0:276e7a263c35 | 89 | strncpy((char*)ctx->rootManifestBasePath, (char*)ctx->keyPath.ptr, sizeof(ctx->rootManifestBasePath)-1); |
MACRUM | 0:276e7a263c35 | 90 | ctx->rootManifestBasePath[sizeof(ctx->rootManifestBasePath)-1] = 0; |
MACRUM | 0:276e7a263c35 | 91 | // Modify the key path. |
MACRUM | 0:276e7a263c35 | 92 | char* pos = (char*)ctx->keyPath.ptr + strlen((char*)ctx->keyPath.ptr) - strlen("ts"); |
MACRUM | 0:276e7a263c35 | 93 | *pos = 'm'; |
MACRUM | 0:276e7a263c35 | 94 | *(pos + 1) = 0; |
MACRUM | 0:276e7a263c35 | 95 | // Setup the manifest buffer |
MACRUM | 0:276e7a263c35 | 96 | ARM_UC_MM_SET_BUFFER(ctx->manifest, ctx->manifestBuffer); |
MACRUM | 0:276e7a263c35 | 97 | // Find the manifest |
MACRUM | 0:276e7a263c35 | 98 | err = ARM_UC_mmCfStoreFindKey(&ctx->keyPath); |
MACRUM | 0:276e7a263c35 | 99 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 100 | { |
MACRUM | 0:276e7a263c35 | 101 | break; |
MACRUM | 0:276e7a263c35 | 102 | } |
MACRUM | 0:276e7a263c35 | 103 | event = ARM_UC_MM_EVENT_CF_BEGIN; |
MACRUM | 0:276e7a263c35 | 104 | ctx->state = ARM_UC_MM_INIT_FINDING; |
MACRUM | 0:276e7a263c35 | 105 | // no break; |
MACRUM | 0:276e7a263c35 | 106 | } |
MACRUM | 0:276e7a263c35 | 107 | case ARM_UC_MM_INIT_FINDING: |
MACRUM | 0:276e7a263c35 | 108 | if (event == UCMM_EVENT_CF_FIND_FAILED) |
MACRUM | 0:276e7a263c35 | 109 | { |
MACRUM | 0:276e7a263c35 | 110 | if (ctx->root) |
MACRUM | 0:276e7a263c35 | 111 | { |
MACRUM | 0:276e7a263c35 | 112 | //TODO: assert! This should not be possible! |
MACRUM | 0:276e7a263c35 | 113 | err.code = MFST_ERR_INVALID_STATE; |
MACRUM | 0:276e7a263c35 | 114 | } else { |
MACRUM | 0:276e7a263c35 | 115 | // No more deps to find. |
MACRUM | 0:276e7a263c35 | 116 | err.code = MFST_ERR_NONE; |
MACRUM | 0:276e7a263c35 | 117 | } |
MACRUM | 0:276e7a263c35 | 118 | break; |
MACRUM | 0:276e7a263c35 | 119 | } |
MACRUM | 0:276e7a263c35 | 120 | err = ARM_UC_mmCfStoreFindKeyFSM(event); |
MACRUM | 0:276e7a263c35 | 121 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 122 | { |
MACRUM | 0:276e7a263c35 | 123 | break; |
MACRUM | 0:276e7a263c35 | 124 | } |
MACRUM | 0:276e7a263c35 | 125 | // Read the manifest |
MACRUM | 0:276e7a263c35 | 126 | err = ARM_UC_mmCfStoreReadLastKey(&ctx->manifest); |
MACRUM | 0:276e7a263c35 | 127 | if (err.code != MFST_ERR_NONE) { |
MACRUM | 0:276e7a263c35 | 128 | break; |
MACRUM | 0:276e7a263c35 | 129 | } |
MACRUM | 0:276e7a263c35 | 130 | event = ARM_UC_MM_EVENT_CF_BEGIN; |
MACRUM | 0:276e7a263c35 | 131 | ctx->state = ARM_UC_MM_INIT_READING; |
MACRUM | 0:276e7a263c35 | 132 | // no break; |
MACRUM | 0:276e7a263c35 | 133 | case ARM_UC_MM_INIT_READING: |
MACRUM | 0:276e7a263c35 | 134 | // Read the manifest into a buffer |
MACRUM | 0:276e7a263c35 | 135 | err = ARM_UC_mmCfStoreReadLastKeyFSM(event); |
MACRUM | 0:276e7a263c35 | 136 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 137 | { |
MACRUM | 0:276e7a263c35 | 138 | break; |
MACRUM | 0:276e7a263c35 | 139 | } |
MACRUM | 0:276e7a263c35 | 140 | ctx->state = ARM_UC_MM_INIT_STATE_HASH_VERIFY; |
MACRUM | 0:276e7a263c35 | 141 | // Preserve the manifest key |
MACRUM | 0:276e7a263c35 | 142 | ARM_UC_mmCfStorePreserveLastKey(); |
MACRUM | 0:276e7a263c35 | 143 | |
MACRUM | 0:276e7a263c35 | 144 | // no break; |
MACRUM | 0:276e7a263c35 | 145 | case ARM_UC_MM_INIT_STATE_HASH_VERIFY: |
MACRUM | 0:276e7a263c35 | 146 | // Verify the manifest hash |
MACRUM | 0:276e7a263c35 | 147 | err = ucmmValidateManifestHash(&ctx->manifest); |
MACRUM | 0:276e7a263c35 | 148 | if (err.code == MFST_ERR_NONE) { |
MACRUM | 0:276e7a263c35 | 149 | uint32_t val; |
MACRUM | 0:276e7a263c35 | 150 | err = ARM_UC_mmGetCryptoMode(&ctx->manifest, &val); |
MACRUM | 0:276e7a263c35 | 151 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 152 | { |
MACRUM | 0:276e7a263c35 | 153 | break; |
MACRUM | 0:276e7a263c35 | 154 | } |
MACRUM | 0:276e7a263c35 | 155 | ucmm_crypto_flags_t cryptoMode = ARM_UC_mmGetCryptoFlags(val); |
MACRUM | 0:276e7a263c35 | 156 | if(cryptoMode.ecc || cryptoMode.rsa) { |
MACRUM | 0:276e7a263c35 | 157 | ctx->state = ARM_UC_MM_INIT_STATE_PK_VERIFY; |
MACRUM | 0:276e7a263c35 | 158 | } else { |
MACRUM | 0:276e7a263c35 | 159 | ctx->state = ARM_UC_MM_INIT_STATE_ROOT_DEPS_VERIFY_BEGIN; |
MACRUM | 0:276e7a263c35 | 160 | } |
MACRUM | 0:276e7a263c35 | 161 | } |
MACRUM | 0:276e7a263c35 | 162 | break; |
MACRUM | 0:276e7a263c35 | 163 | case ARM_UC_MM_INIT_STATE_PK_VERIFY: |
MACRUM | 0:276e7a263c35 | 164 | // Verify the manifest signature |
MACRUM | 0:276e7a263c35 | 165 | err = ucmmValidateSignature(&ctx->manifest); |
MACRUM | 0:276e7a263c35 | 166 | if (err.code == MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 167 | { |
MACRUM | 0:276e7a263c35 | 168 | ctx->state = ARM_UC_MM_INIT_STATE_PK_VERIFYING; |
MACRUM | 0:276e7a263c35 | 169 | } |
MACRUM | 0:276e7a263c35 | 170 | break; |
MACRUM | 0:276e7a263c35 | 171 | case ARM_UC_MM_INIT_STATE_PK_VERIFYING: |
MACRUM | 0:276e7a263c35 | 172 | err = ucmmValidateSignatureFSM(event); |
MACRUM | 0:276e7a263c35 | 173 | if (err.code == MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 174 | { |
MACRUM | 0:276e7a263c35 | 175 | ctx->state = ARM_UC_MM_INIT_STATE_ROOT_DEPS_VERIFY_BEGIN; |
MACRUM | 0:276e7a263c35 | 176 | } |
MACRUM | 0:276e7a263c35 | 177 | break; |
MACRUM | 0:276e7a263c35 | 178 | case ARM_UC_MM_INIT_STATE_ROOT_DEPS_VERIFY_BEGIN: |
MACRUM | 0:276e7a263c35 | 179 | // ATTACKVECTOR: If an attacker can add a manifest to the dependency prefix in the config store, the manifest |
MACRUM | 0:276e7a263c35 | 180 | // manager has no way to know that it is not valid, due to the flat file heirarchy. |
MACRUM | 0:276e7a263c35 | 181 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_MANIFEST_BEGIN; |
MACRUM | 0:276e7a263c35 | 182 | // NO BREAK; |
MACRUM | 0:276e7a263c35 | 183 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_MANIFEST_BEGIN: |
MACRUM | 0:276e7a263c35 | 184 | // Loop: manifest |
MACRUM | 0:276e7a263c35 | 185 | // Set the depidx to 0 |
MACRUM | 0:276e7a263c35 | 186 | ctx->depidx = 0; |
MACRUM | 0:276e7a263c35 | 187 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_GET_HASH; |
MACRUM | 0:276e7a263c35 | 188 | // NO BREAK; |
MACRUM | 0:276e7a263c35 | 189 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_GET_HASH: |
MACRUM | 0:276e7a263c35 | 190 | { |
MACRUM | 0:276e7a263c35 | 191 | arm_uc_buffer_t dependency; |
MACRUM | 0:276e7a263c35 | 192 | arm_uc_buffer_t hash; |
MACRUM | 0:276e7a263c35 | 193 | // Read the dependency at depidx |
MACRUM | 0:276e7a263c35 | 194 | err = ARM_UC_mmGetManifestLinksElement(&ctx->manifest, ctx->depidx, &dependency); |
MACRUM | 0:276e7a263c35 | 195 | // If there isn't one |
MACRUM | 0:276e7a263c35 | 196 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 197 | { |
MACRUM | 0:276e7a263c35 | 198 | break; |
MACRUM | 0:276e7a263c35 | 199 | } |
MACRUM | 0:276e7a263c35 | 200 | if (dependency.ptr == NULL) |
MACRUM | 0:276e7a263c35 | 201 | { |
MACRUM | 0:276e7a263c35 | 202 | // Exit Loop: dependency |
MACRUM | 0:276e7a263c35 | 203 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_END; |
MACRUM | 0:276e7a263c35 | 204 | err.code = MFST_ERR_NONE; |
MACRUM | 0:276e7a263c35 | 205 | break; |
MACRUM | 0:276e7a263c35 | 206 | } |
MACRUM | 0:276e7a263c35 | 207 | // Get the dependency hash |
MACRUM | 0:276e7a263c35 | 208 | err = ARM_UC_mmGetManifestLinksHash(&dependency, &hash); |
MACRUM | 0:276e7a263c35 | 209 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 210 | { |
MACRUM | 0:276e7a263c35 | 211 | break; |
MACRUM | 0:276e7a263c35 | 212 | } |
MACRUM | 0:276e7a263c35 | 213 | // Store the dependency hash |
MACRUM | 0:276e7a263c35 | 214 | memcpy(ctx->currentHash, hash.ptr, min(hash.size, sizeof(ctx->currentHash))); |
MACRUM | 0:276e7a263c35 | 215 | // Format the dependency search key |
MACRUM | 0:276e7a263c35 | 216 | // The result of this operation is: |
MACRUM | 0:276e7a263c35 | 217 | // com.arm.mbed.update.mm.m.<root manifest hash>.deps.<dependency hash>.m |
MACRUM | 0:276e7a263c35 | 218 | // ASSUMES sizeof keypath > sizeof rootManifestBasePath |
MACRUM | 0:276e7a263c35 | 219 | strncpy((char*)ctx->keyPath.ptr, (char*)ctx->rootManifestBasePath, sizeof(ctx->keyPath.ptr)); |
MACRUM | 0:276e7a263c35 | 220 | ctx->keyPath.size = strlen(ctx->keyPath.ptr); |
MACRUM | 0:276e7a263c35 | 221 | // Back up one space to remove the 'm' |
MACRUM | 0:276e7a263c35 | 222 | strncpy((char*)ctx->keyPath.ptr + ctx->keyPath.size-1, "deps.", ctx->keyPath.size_max - ctx->keyPath.size); |
MACRUM | 0:276e7a263c35 | 223 | ctx->keyPath.size = strlen(ctx->keyPath.ptr); |
MACRUM | 0:276e7a263c35 | 224 | ARM_UC_Base64Enc(ctx->keyPath.ptr + ctx->keyPath.size, ctx->keyPath.size_max - ctx->keyPath.size, &hash); |
MACRUM | 0:276e7a263c35 | 225 | ctx->keyPath.size = strlen(ctx->keyPath.ptr); |
MACRUM | 0:276e7a263c35 | 226 | strncpy((char*)ctx->keyPath.ptr + ctx->keyPath.size, ".m", ctx->keyPath.size_max - ctx->keyPath.size); |
MACRUM | 0:276e7a263c35 | 227 | ctx->keyPath.size += 3; // add one for null terminator |
MACRUM | 0:276e7a263c35 | 228 | |
MACRUM | 0:276e7a263c35 | 229 | // Find the dependency in the config store |
MACRUM | 0:276e7a263c35 | 230 | err = ucmmCfstoreFindAndRead((char*)ctx->keyPath.ptr, &ctx->manifest); |
MACRUM | 0:276e7a263c35 | 231 | if (err.code == MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 232 | { |
MACRUM | 0:276e7a263c35 | 233 | event = ARM_UC_MM_EVENT_BEGIN; |
MACRUM | 0:276e7a263c35 | 234 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_READING_DEPENDENCY; |
MACRUM | 0:276e7a263c35 | 235 | } |
MACRUM | 0:276e7a263c35 | 236 | break; |
MACRUM | 0:276e7a263c35 | 237 | } |
MACRUM | 0:276e7a263c35 | 238 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_READING_DEPENDENCY: |
MACRUM | 0:276e7a263c35 | 239 | // If there is no matching dependency |
MACRUM | 0:276e7a263c35 | 240 | if (event == UCMM_EVENT_CF_FIND_FAILED) |
MACRUM | 0:276e7a263c35 | 241 | { |
MACRUM | 0:276e7a263c35 | 242 | // Set the missing dep flag |
MACRUM | 0:276e7a263c35 | 243 | ctx->missingDep = 1; |
MACRUM | 0:276e7a263c35 | 244 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_URI_CHECK; |
MACRUM | 0:276e7a263c35 | 245 | // Continue... |
MACRUM | 0:276e7a263c35 | 246 | err.code = MFST_ERR_NONE; |
MACRUM | 0:276e7a263c35 | 247 | break; |
MACRUM | 0:276e7a263c35 | 248 | } |
MACRUM | 0:276e7a263c35 | 249 | // Find/Read the dependency manifest |
MACRUM | 0:276e7a263c35 | 250 | err = ucmmCfstoreFindAndReadFSM(event); |
MACRUM | 0:276e7a263c35 | 251 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 252 | { |
MACRUM | 0:276e7a263c35 | 253 | break; |
MACRUM | 0:276e7a263c35 | 254 | } |
MACRUM | 0:276e7a263c35 | 255 | // There is a matching dependency |
MACRUM | 0:276e7a263c35 | 256 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_CHECK_HASH; |
MACRUM | 0:276e7a263c35 | 257 | // No break; |
MACRUM | 0:276e7a263c35 | 258 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_CHECK_HASH: |
MACRUM | 0:276e7a263c35 | 259 | { |
MACRUM | 0:276e7a263c35 | 260 | #if MAX_HASH_BYTES != 256/8 |
MACRUM | 0:276e7a263c35 | 261 | #error Hash size mismatch |
MACRUM | 0:276e7a263c35 | 262 | #endif |
MACRUM | 0:276e7a263c35 | 263 | uint8_t localhash[MAX_HASH_BYTES]; |
MACRUM | 0:276e7a263c35 | 264 | arm_uc_buffer_t local = { |
MACRUM | 0:276e7a263c35 | 265 | .size_max = MAX_HASH_BYTES, |
MACRUM | 0:276e7a263c35 | 266 | .size = 256/8, |
MACRUM | 0:276e7a263c35 | 267 | .ptr = localhash |
MACRUM | 0:276e7a263c35 | 268 | }; |
MACRUM | 0:276e7a263c35 | 269 | arm_uc_buffer_t resource; |
MACRUM | 0:276e7a263c35 | 270 | const int32_t valueID = ARM_UC_MM_DER_RESOURCE; |
MACRUM | 0:276e7a263c35 | 271 | int rc = ARM_UC_mmDERGetSignedResourceValues(&resource, 1, &valueID, &resource); |
MACRUM | 0:276e7a263c35 | 272 | if (rc) |
MACRUM | 0:276e7a263c35 | 273 | { |
MACRUM | 0:276e7a263c35 | 274 | err.code = MFST_ERR_DER_FORMAT; |
MACRUM | 0:276e7a263c35 | 275 | break; |
MACRUM | 0:276e7a263c35 | 276 | } |
MACRUM | 0:276e7a263c35 | 277 | { |
MACRUM | 0:276e7a263c35 | 278 | // Calculate the dependency hash |
MACRUM | 0:276e7a263c35 | 279 | mbedtls_sha256_context ctx; |
MACRUM | 0:276e7a263c35 | 280 | mbedtls_sha256_init(&ctx); |
MACRUM | 0:276e7a263c35 | 281 | mbedtls_sha256_starts(&ctx, 0); |
MACRUM | 0:276e7a263c35 | 282 | mbedtls_sha256_update(&ctx, resource.ptr, resource.size); |
MACRUM | 0:276e7a263c35 | 283 | mbedtls_sha256_finish(&ctx, local.ptr); |
MACRUM | 0:276e7a263c35 | 284 | } |
MACRUM | 0:276e7a263c35 | 285 | { |
MACRUM | 0:276e7a263c35 | 286 | arm_uc_buffer_t remote = { |
MACRUM | 0:276e7a263c35 | 287 | .size_max = MAX_HASH_BYTES, |
MACRUM | 0:276e7a263c35 | 288 | .size = 256/8, |
MACRUM | 0:276e7a263c35 | 289 | .ptr = ctx->currentHash |
MACRUM | 0:276e7a263c35 | 290 | }; |
MACRUM | 0:276e7a263c35 | 291 | // Validate the dependency hash |
MACRUM | 0:276e7a263c35 | 292 | if(ARM_UC_BinCompareCT(&local, &remote)) |
MACRUM | 0:276e7a263c35 | 293 | { |
MACRUM | 0:276e7a263c35 | 294 | // If invalid, Set the missing dep flag |
MACRUM | 0:276e7a263c35 | 295 | ctx->missingDep = 1; |
MACRUM | 0:276e7a263c35 | 296 | // Delete the manifest |
MACRUM | 0:276e7a263c35 | 297 | ARM_UC_mmCfStoreDeleteLastKey(); |
MACRUM | 0:276e7a263c35 | 298 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_DELETE; |
MACRUM | 0:276e7a263c35 | 299 | event = ARM_UC_MM_EVENT_CF_BEGIN; |
MACRUM | 0:276e7a263c35 | 300 | } |
MACRUM | 0:276e7a263c35 | 301 | else |
MACRUM | 0:276e7a263c35 | 302 | { |
MACRUM | 0:276e7a263c35 | 303 | // End Loop: dependency |
MACRUM | 0:276e7a263c35 | 304 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_READ; |
MACRUM | 0:276e7a263c35 | 305 | // Increment the depidx |
MACRUM | 0:276e7a263c35 | 306 | ctx->depidx++; |
MACRUM | 0:276e7a263c35 | 307 | } |
MACRUM | 0:276e7a263c35 | 308 | } |
MACRUM | 0:276e7a263c35 | 309 | break; |
MACRUM | 0:276e7a263c35 | 310 | } |
MACRUM | 0:276e7a263c35 | 311 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_DELETE: |
MACRUM | 0:276e7a263c35 | 312 | err = ARM_UC_mmCfStoreDeleteLastKeyFSM(event); |
MACRUM | 0:276e7a263c35 | 313 | if (err.code == MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 314 | { |
MACRUM | 0:276e7a263c35 | 315 | // Make sure a URI exists. |
MACRUM | 0:276e7a263c35 | 316 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_URI_CHECK; |
MACRUM | 0:276e7a263c35 | 317 | } |
MACRUM | 0:276e7a263c35 | 318 | break; |
MACRUM | 0:276e7a263c35 | 319 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_URI_CHECK: |
MACRUM | 0:276e7a263c35 | 320 | { |
MACRUM | 0:276e7a263c35 | 321 | // modify the search path |
MACRUM | 0:276e7a263c35 | 322 | char* pos = (char*)ctx->keyPath.ptr + ctx->keyPath.size - 2; // null terminator |
MACRUM | 0:276e7a263c35 | 323 | strncpy(pos, "uri", ctx->keyPath.size_max - (ctx->keyPath.size - 2)); // null terminator |
MACRUM | 0:276e7a263c35 | 324 | // Check if there is a URI entry |
MACRUM | 0:276e7a263c35 | 325 | // HACK: No API for find without ovewriting the existing stored key. Use find/read even though we don't need the |
MACRUM | 0:276e7a263c35 | 326 | // data. |
MACRUM | 0:276e7a263c35 | 327 | err = ucmmCfstoreFindAndRead((char*)ctx->keyPath.ptr, &ctx->manifest); |
MACRUM | 0:276e7a263c35 | 328 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 329 | { |
MACRUM | 0:276e7a263c35 | 330 | break; |
MACRUM | 0:276e7a263c35 | 331 | } |
MACRUM | 0:276e7a263c35 | 332 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_URI_CHECKING; |
MACRUM | 0:276e7a263c35 | 333 | event = ARM_UC_MM_EVENT_CF_BEGIN; |
MACRUM | 0:276e7a263c35 | 334 | // no break |
MACRUM | 0:276e7a263c35 | 335 | } |
MACRUM | 0:276e7a263c35 | 336 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_URI_CHECKING: |
MACRUM | 0:276e7a263c35 | 337 | if (event == UCMM_EVENT_CF_FIND_FAILED) |
MACRUM | 0:276e7a263c35 | 338 | { |
MACRUM | 0:276e7a263c35 | 339 | // TODO: Erase all deps and start over. |
MACRUM | 0:276e7a263c35 | 340 | err.code = MFST_ERR_INVALID_STATE; |
MACRUM | 0:276e7a263c35 | 341 | break; |
MACRUM | 0:276e7a263c35 | 342 | } |
MACRUM | 0:276e7a263c35 | 343 | err = ucmmCfstoreFindAndReadFSM(event); |
MACRUM | 0:276e7a263c35 | 344 | if (err.code == MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 345 | { |
MACRUM | 0:276e7a263c35 | 346 | // Increment the depidx |
MACRUM | 0:276e7a263c35 | 347 | ctx->depidx++; |
MACRUM | 0:276e7a263c35 | 348 | // End Loop: dependency |
MACRUM | 0:276e7a263c35 | 349 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_READ; |
MACRUM | 0:276e7a263c35 | 350 | } |
MACRUM | 0:276e7a263c35 | 351 | break; |
MACRUM | 0:276e7a263c35 | 352 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_READ: |
MACRUM | 0:276e7a263c35 | 353 | // Loop: dependency |
MACRUM | 0:276e7a263c35 | 354 | // Restore the manifest key |
MACRUM | 0:276e7a263c35 | 355 | ARM_UC_mmCfStoreRestoreLastKey(); |
MACRUM | 0:276e7a263c35 | 356 | // Seek the current key |
MACRUM | 0:276e7a263c35 | 357 | err = ARM_UC_mmCfStoreSeekLastKey(0); |
MACRUM | 0:276e7a263c35 | 358 | if (err.code == MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 359 | { |
MACRUM | 0:276e7a263c35 | 360 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_SEEKING; |
MACRUM | 0:276e7a263c35 | 361 | } |
MACRUM | 0:276e7a263c35 | 362 | break; |
MACRUM | 0:276e7a263c35 | 363 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_SEEKING: |
MACRUM | 0:276e7a263c35 | 364 | err = ARM_UC_mmCfStoreSeekLastKeyFSM(event); |
MACRUM | 0:276e7a263c35 | 365 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 366 | { |
MACRUM | 0:276e7a263c35 | 367 | break; |
MACRUM | 0:276e7a263c35 | 368 | } |
MACRUM | 0:276e7a263c35 | 369 | // Read the current key |
MACRUM | 0:276e7a263c35 | 370 | err = ARM_UC_mmCfStoreReadLastKey(&ctx->manifest); |
MACRUM | 0:276e7a263c35 | 371 | if (err.code != MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 372 | { |
MACRUM | 0:276e7a263c35 | 373 | break; |
MACRUM | 0:276e7a263c35 | 374 | } |
MACRUM | 0:276e7a263c35 | 375 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_READING; |
MACRUM | 0:276e7a263c35 | 376 | event = ARM_UC_MM_EVENT_CF_BEGIN; |
MACRUM | 0:276e7a263c35 | 377 | // no break |
MACRUM | 0:276e7a263c35 | 378 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_READING: |
MACRUM | 0:276e7a263c35 | 379 | err = ARM_UC_mmCfStoreReadLastKeyFSM(event); |
MACRUM | 0:276e7a263c35 | 380 | if (err.code == MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 381 | { |
MACRUM | 0:276e7a263c35 | 382 | ctx->state = ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_GET_HASH; |
MACRUM | 0:276e7a263c35 | 383 | // Preserve the manifest key |
MACRUM | 0:276e7a263c35 | 384 | ARM_UC_mmCfStorePreserveLastKey(); |
MACRUM | 0:276e7a263c35 | 385 | } |
MACRUM | 0:276e7a263c35 | 386 | break; |
MACRUM | 0:276e7a263c35 | 387 | case ARM_UC_MM_INIT_STATE_DEPS_LOOP_DEPENDENCY_END: |
MACRUM | 0:276e7a263c35 | 388 | // Format the dependency search key |
MACRUM | 0:276e7a263c35 | 389 | strncpy((char*)ctx->keyPath.ptr, (char*)ctx->rootManifestBasePath, sizeof(ctx->rootManifestBasePath)); |
MACRUM | 0:276e7a263c35 | 390 | ctx->keyPath.size = sizeof(ctx->rootManifestBasePath)-1; |
MACRUM | 0:276e7a263c35 | 391 | strncpy((char*)ctx->keyPath.ptr + ctx->keyPath.size, ".deps.*", ctx->keyPath.size_max - ctx->keyPath.size); |
MACRUM | 0:276e7a263c35 | 392 | ctx->keyPath.size += sizeof(".deps.*") - 1; |
MACRUM | 0:276e7a263c35 | 393 | // If the root flag is set |
MACRUM | 0:276e7a263c35 | 394 | if (ctx->root) |
MACRUM | 0:276e7a263c35 | 395 | { |
MACRUM | 0:276e7a263c35 | 396 | // Clear the root flag |
MACRUM | 0:276e7a263c35 | 397 | ctx->root = 0; |
MACRUM | 0:276e7a263c35 | 398 | // Start the dependency search |
MACRUM | 0:276e7a263c35 | 399 | err = ARM_UC_mmCfStoreFindKey(&ctx->keyPath); |
MACRUM | 0:276e7a263c35 | 400 | } |
MACRUM | 0:276e7a263c35 | 401 | else |
MACRUM | 0:276e7a263c35 | 402 | { |
MACRUM | 0:276e7a263c35 | 403 | // Continue the dependency search |
MACRUM | 0:276e7a263c35 | 404 | err = ARM_UC_mmCfStoreFindNextKey(); |
MACRUM | 0:276e7a263c35 | 405 | } |
MACRUM | 0:276e7a263c35 | 406 | if (err.code == MFST_ERR_NONE) |
MACRUM | 0:276e7a263c35 | 407 | { |
MACRUM | 0:276e7a263c35 | 408 | event = ARM_UC_MM_EVENT_CF_BEGIN; |
MACRUM | 0:276e7a263c35 | 409 | // End Loop: manifest |
MACRUM | 0:276e7a263c35 | 410 | ctx->state = ARM_UC_MM_INIT_FINDING; |
MACRUM | 0:276e7a263c35 | 411 | } |
MACRUM | 0:276e7a263c35 | 412 | break; |
MACRUM | 0:276e7a263c35 | 413 | default: |
MACRUM | 0:276e7a263c35 | 414 | err.code = MFST_ERR_INVALID_STATE; |
MACRUM | 0:276e7a263c35 | 415 | break; |
MACRUM | 0:276e7a263c35 | 416 | } ARM_UC_MM_FSM_HELPER_FINISH(*ctx); |
MACRUM | 0:276e7a263c35 | 417 | if (err.code == MFST_ERR_NONE && ctx->missingDep == 1) |
MACRUM | 0:276e7a263c35 | 418 | { |
MACRUM | 0:276e7a263c35 | 419 | // TODO: Configure & trigger insert FSM |
MACRUM | 0:276e7a263c35 | 420 | } |
MACRUM | 0:276e7a263c35 | 421 | return err; |
MACRUM | 0:276e7a263c35 | 422 | } |
MACRUM | 0:276e7a263c35 | 423 | |
MACRUM | 0:276e7a263c35 | 424 | #endif // !MANIFEST_MANAGER_NO_STORAGE |