Toyomasa Watarai / simple-mbed-cloud-client

Dependents:  

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?

UserRevisionLine numberNew 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