Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
arm_uc_mmCryptoUtils.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_mmDerManifestParser.h" 00023 #include "update-client-common/arm_uc_crypto.h" 00024 00025 #include "update-client-control-center/arm_uc_certificate.h" 00026 00027 #include "arm_uc_mmDerManifestAccessors.h" 00028 #include "update-client-manifest-manager/update-client-manifest-manager.h" 00029 00030 #include <string.h> 00031 00032 void ARM_UC_mmVerifySignatureEntry(uint32_t event); 00033 /** 00034 * @file Cryptographic utilities 00035 * This file provides two primary APIs: 00036 * * Verifying manifest hashes 00037 * * Verifying manifest signatures 00038 * 00039 * Some utility functions used by other files in this module are also provided. 00040 * 00041 * Algorithm support: 00042 * ECC is currently supported, but RSA is not. 00043 * Currently, only ECC secp256r1 (prime256v1) is supported. 00044 * Currently, only SHA256 is supported. 00045 * HMAC is not yet supported. 00046 */ 00047 00048 /** 00049 * @brief Returns the sizes of the cryptographic primitives used by the supplied manifest. 00050 * @details Extracts the cryptomode field from a manifest and returns a struct that describes the size of cryptographic 00051 * primitives used in the manifest. The supplied manifest must have been validated. No validation is performed 00052 * by this function. 00053 * 00054 * @param[in] buffer A buffer that contains a validated manifest. 00055 * @return A struct cryptsize, which contains the AES primitive sizes and SHA primitive size, both in bytes. 00056 * An invalid cryptographic mode specifier will cause primitive sizes of `0` to be returned. 00057 */ 00058 struct cryptsize getCryptInfo(arm_uc_buffer_t* buffer) 00059 { 00060 struct cryptsize cs = {0}; 00061 uint32_t cryptoMode = 1U; // default SHA256 and ECC 00062 ARM_UC_mmGetCryptoMode(buffer, &cryptoMode); 00063 00064 switch(cryptoMode) 00065 { 00066 case MFST_CRYPT_SHA256_ECC_AES128_PSK: 00067 // case MFST_CRYPT_SHA256_HMAC_AES128_PSK: 00068 cs.aeslen = 128/CHAR_BIT; 00069 // case MFST_CRYPT_SHA256_HMAC: 00070 case MFST_CRYPT_SHA256: 00071 cs.hashlen = 256/CHAR_BIT; 00072 break; 00073 case MFST_CRYPT_SHA256_ECC: 00074 cs.hashlen = 256/CHAR_BIT; 00075 default: 00076 break; 00077 } 00078 return cs; 00079 } 00080 00081 /** 00082 * @brief Converts a cryptographic mode enum to a structure with mode identifiers 00083 * @details In order to simplify many tests, the cryptographic mode identifier is converted into a structure of mode 00084 * identifiers, one for each cryptographic primitive. This allows other parts of the code to examine the mode 00085 * of one particular primitive without testing against many enums. This function performs no validation. The 00086 * calling function should have performed validation in advance. If the cryptoMode is unrecognized, then a 00087 * return will be populated with 0 for every flag. 00088 * 00089 * HMAC modes are not currently supported. 00090 * TODO: Convert flags to enums 00091 * @param[in] cryptoMode The cryptographic mode enum that specifies the settings for each primitive 00092 * @return A structure of flags that indicate the mode of: 00093 * * Hash algorithm 00094 * * MAC 00095 * * Symmetric Encryption 00096 * * Pre-shared keys 00097 * * Public Key modes 00098 */ 00099 arm_uc_mm_crypto_flags_t ARM_UC_mmGetCryptoFlags(uint32_t cryptoMode) 00100 { 00101 00102 switch(cryptoMode) { 00103 case MFST_CRYPT_SHA256: 00104 return (arm_uc_mm_crypto_flags_t) {.hash = 1U}; 00105 // case MFST_CRYPT_SHA256_HMAC: 00106 // return (arm_uc_mm_crypto_flags_t) {.hash = 1, .hmac = 1}; 00107 // case MFST_CRYPT_SHA256_HMAC_AES128_PSK: 00108 // return (arm_uc_mm_crypto_flags_t) {.hash = 1, .hmac = 1, .aes = 1, .psk = 1}; 00109 case MFST_CRYPT_SHA256_ECC: 00110 return (arm_uc_mm_crypto_flags_t) {.hash = 1U, .ecc = 1U}; 00111 case MFST_CRYPT_SHA256_ECC_AES128_PSK: 00112 return (arm_uc_mm_crypto_flags_t) {.hash = 1U, .ecc = 1U, .aes = 1U, .psk = 1U}; 00113 } 00114 return (arm_uc_mm_crypto_flags_t) {.hash = 0}; 00115 00116 } 00117 00118 /** 00119 * @brief Extracts the hash of a manifest from the manifest wrapper. 00120 * @details This is a utility function that is used to extract the hash of the manifest for signature validation. 00121 * This function does not perform validation of the hash buffer, so the hash buffer is expected to be populated 00122 * with a known-good hash buffer. Typically, this buffer will be stack-allocated. 00123 * @param[in] buffer The manifest to parse 00124 * @param[out] hash Output buffer object to fill with the hash 00125 * @return MFST_ERR_NONE on success, or a parser error code otherwise 00126 */ 00127 arm_uc_error_t ARM_UC_mmGetManifestHashFromBin(arm_uc_buffer_t* buffer, arm_uc_buffer_t* hash) 00128 { 00129 const uint32_t fieldID = ARM_UC_MM_DER_SIG_HASH; 00130 int rc = ARM_UC_mmDERGetSignedResourceValues(buffer, 1U, &fieldID, hash); 00131 if (rc) return (arm_uc_error_t){MFST_ERR_DER_FORMAT}; 00132 return (arm_uc_error_t){MFST_ERR_NONE}; 00133 } 00134 00135 /** 00136 * Utility function for printing the hex value of a buffer. Used only for debugging. 00137 * @param buf [description] 00138 */ 00139 #if 0 00140 static void hexprint_buffer(arm_uc_buffer_t* buf) 00141 { 00142 for (size_t i = 0; i < buf->size; i++) 00143 { 00144 printf("%02x", buf->ptr[i]); 00145 } 00146 } 00147 #endif 00148 00149 /** 00150 * @brief ARM_UC_mmValidateManifestHash processes a manifest in order to validate its hash 00151 * @details The manifest parser extracts the manifest hash, calculates the hash of the manifest, then compares it to the 00152 * hash included in the manifest. 00153 * 00154 * The outer wrapper of the manifest is called a SignedResource. It contains a Resource object and a 00155 * ResourceSignature object. The Resource object contains a Resource Type identifier, an optional URL, and 00156 * either a manifest or binary data. 00157 * 00158 * This function extracts the Resource object and the ResourceSignature object so that the Resource can be 00159 * hashed and verified against the hash in the ResourceSignature. 00160 * 00161 * TODO: The dependency on the cryptoMode contained within the manifest will be removed with the change to CMS 00162 * First, the Resource object is extracted. Next, the cryptoMode is extracted from the Resource object. This 00163 * requires that the Resource object be a Manifest. 00164 * 00165 * @param[in] buffer The buffer that contains the manifest to validate 00166 * @retval MFST_ERR_NONE on success 00167 * @retval MFST_ERR_CRYPTO_MODE if there is a cryptographic mode error 00168 * @retval Otherwise, a DER Parser error can be expected 00169 */ 00170 arm_uc_error_t ARM_UC_mmValidateManifestHash(arm_uc_buffer_t* buffer) 00171 { 00172 uint8_t localhash[MAX_HASH_BYTES]; ///< An array to store the locally calculated hash 00173 arm_uc_buffer_t local = { ///< A buffer structure to use for the locally calculated hash 00174 .size_max = MAX_HASH_BYTES, 00175 .size = 0, 00176 .ptr = localhash 00177 }; 00178 arm_uc_buffer_t remote = { ///< A buffer for the hash provided in the manifest 00179 .size_max = MAX_HASH_BYTES, 00180 .size = 0, 00181 .ptr = NULL 00182 }; 00183 arm_uc_buffer_t resource = { ///< A buffer for the resource (the manifest) that is wrapped by a signature 00184 .size_max = MAX_HASH_BYTES, 00185 .size = 0, 00186 .ptr = NULL 00187 }; 00188 arm_uc_mdHandle_t hDigest = {0}; ///< This handle is for the digest algorithm 00189 arm_uc_error_t err = {MFST_ERR_NONE}; ///< The return code variable 00190 uint32_t cryptoMode = 0; ///< A temporary local copy of the crytpoMode 00191 arm_uc_mdType_t mdType = 0; ///< A type designator for the type of hash in use 00192 00193 // Extract the "resource" contained in the Signed Resource object 00194 err = ARM_UC_mmDERSignedResourceGetSingleValue(buffer, ARM_UC_MM_DER_RESOURCE, &resource); 00195 if (!err.error) 00196 { 00197 // Extract the hash from the manifest 00198 err = ARM_UC_mmGetManifestHash(buffer, &remote); 00199 } 00200 if (!err.error) 00201 { 00202 // Extract the cryptographic mode from the manifest 00203 err = ARM_UC_mmGetCryptoMode(buffer, &cryptoMode); 00204 } 00205 if (!err.error) 00206 { 00207 // Set the hash type identifier 00208 switch(cryptoMode) 00209 { 00210 case MFST_CRYPT_SHA256_ECC_AES128_PSK: 00211 case MFST_CRYPT_SHA256: 00212 case MFST_CRYPT_SHA256_ECC: 00213 mdType = ARM_UC_CU_SHA256; 00214 break; 00215 default: 00216 err.code = MFST_ERR_CRYPTO_MODE; 00217 break; 00218 } 00219 } 00220 if (!err.error) 00221 { 00222 // Initialize the message digest API 00223 err = ARM_UC_cryptoHashSetup(&hDigest, mdType); 00224 } 00225 if (!err.error) 00226 { 00227 // NOTE: If a hash accelerator is present on-chip, this could be converted from a blocking call to an 00228 // asynchronous one. 00229 // Hash the resource 00230 // Keep Coverity quiet - it can't resolve some semantic conditions here. 00231 if ( resource.ptr == NULL ) { 00232 ARM_UC_SET_ERROR(err, MFST_ERR_NULL_PTR); 00233 } else { 00234 err = ARM_UC_cryptoHashUpdate(&hDigest, &resource); 00235 } 00236 } 00237 if (!err.error) 00238 { 00239 // Extract the locally calculated hash from the hash API 00240 err = ARM_UC_cryptoHashFinish(&hDigest, &local); 00241 } 00242 if (!err.error) 00243 { 00244 // Check that the hashes match 00245 // Keep Coverity quiet - it can't resolve some semantic conditions here. 00246 if ( remote.ptr == NULL ) { 00247 ARM_UC_SET_ERROR(err, MFST_ERR_NULL_PTR); 00248 } else if(ARM_UC_BinCompareCT(&local, &remote)) { 00249 ARM_UC_SET_ERROR(err, MFST_ERR_HASH); 00250 } 00251 } 00252 // Explicitly set the manifest manager's no-error code, rather than another module's, which may be present here. 00253 if (!err.error) 00254 { 00255 ARM_UC_SET_ERROR(err, MFST_ERR_NONE); 00256 } 00257 return err; 00258 } 00259 00260 enum arm_uc_mmCertificateFetchEvents { 00261 ARM_UC_MM_CERTIFICATE_FETCH_UNINIT, 00262 ARM_UC_MM_CERTIFICATE_FETCH_SUCCESS, 00263 ARM_UC_MM_CERTIFICATE_FETCH_MISMATCH, 00264 ARM_UC_MM_CERTIFICATE_FETCH_ERROR, 00265 }; 00266 00267 /** 00268 * @brief Validates one signature of a manifest, once the signing certificate has been found. 00269 * @param buffer Holding buffer for the manifest to validate. 00270 * @param ca Buffer holding the certificate to use in verification 00271 * @param sigIndex Index of the manifest signature to verify with this certificate 00272 * @retval MFST_ERR_DER_FORMAT on parse error 00273 * @retval MFST_ERR_CERT_INVALID if the certificate is not valid 00274 * @retval MFST_ERR_INVALID_SIGNATURE if the signature is invalid 00275 * @retval MFST_ERR_NONE for a valid signature 00276 */ 00277 static arm_uc_error_t ARM_UC_mmValidateSignatureCert(arm_uc_buffer_t* buffer, arm_uc_buffer_t* ca, uint32_t sigIndex) 00278 { 00279 const uint32_t fieldIDs[] = {ARM_UC_MM_DER_SIG_HASH, ARM_UC_MM_DER_SIG_SIGNATURES}; 00280 arm_uc_buffer_t fields[ARRAY_SIZE(fieldIDs)]; 00281 00282 // Get the signature list 00283 int rc = ARM_UC_mmDERGetSignedResourceValues(buffer, ARRAY_SIZE(fieldIDs), fieldIDs, fields); 00284 if (rc) return (arm_uc_error_t){MFST_ERR_DER_FORMAT}; 00285 00286 // Get the specified signature block 00287 arm_uc_buffer_t sigblock; 00288 rc = ARM_UC_mmDERGetSequenceElement(&fields[1], sigIndex, &sigblock); 00289 if (rc) return (arm_uc_error_t){MFST_ERR_DER_FORMAT}; 00290 00291 // Load the specified signature out of the signature block 00292 arm_uc_buffer_t sig; 00293 const uint32_t sigID = ARM_UC_MM_DER_SIG_SIGNATURE; 00294 rc = ARM_UC_mmDERParseTree(&arm_uc_mmSignatures[0], &sigblock, 1U, &sigID, &sig); 00295 if (rc) return (arm_uc_error_t){MFST_ERR_DER_FORMAT}; 00296 00297 // Validate the signature 00298 return ARM_UC_verifyPkSignature(ca, &fields[0], &sig); 00299 } 00300 00301 struct { 00302 arm_uc_mm_validate_signature_context_t* ctx; 00303 arm_uc_callback_t callbackStorage; 00304 } arm_uc_mmSignatureVerificationContext; 00305 00306 00307 /** 00308 * @brief Callback function to continue signature verification once the certificate has been found 00309 * @details This function should be called by the certificate lookup function, which is provided by the application. 00310 * The certificate lookup function should call this callback regardless of success or failure so that errors 00311 * can be reported correctly. 00312 * 00313 * Caveats: 00314 * The certificate supplied here MUST be the same buffer as was provided to the certificate fetch function. 00315 * The fingerprint supplied here MUST be the same buffer as was provided to the certificate fetch function. 00316 * 00317 * These requirements are in place to ensure that only one signature verification may be carried out at a time. 00318 * 00319 * Once the basic checks are performed in the callback, it schedules the manifest manager to execute later. 00320 * 00321 * @param status Error code provided by the certificat lookup function 00322 * @param certificate Buffer containing the certificate 00323 * @param fingerprint Buffer containing the certificate fingerprint 00324 */ 00325 void ARM_UC_mmCertificateCallback(arm_uc_error_t status, const arm_uc_buffer_t* certificate, const arm_uc_buffer_t* fingerprint) 00326 { 00327 uint32_t event = ARM_UC_MM_CERTIFICATE_FETCH_UNINIT; 00328 UC_MMGR_TRACE("%s (%u)\n", __PRETTY_FUNCTION__, (unsigned)event); 00329 if (status.error == ERR_NONE) 00330 { 00331 // Verify that this is the same buffer as was provided to the certificate fetch function. 00332 if (fingerprint != &arm_uc_mmSignatureVerificationContext.ctx->fingerprint || 00333 certificate != &arm_uc_mmSignatureVerificationContext.ctx->cert) 00334 { 00335 event = ARM_UC_MM_CERTIFICATE_FETCH_MISMATCH; 00336 } 00337 else 00338 { 00339 event = ARM_UC_MM_CERTIFICATE_FETCH_SUCCESS; 00340 } 00341 } 00342 else 00343 { 00344 // Store the error for later reporting 00345 arm_uc_mmSignatureVerificationContext.ctx->storedError = status; 00346 event = ARM_UC_MM_CERTIFICATE_FETCH_ERROR; 00347 } 00348 // Post the Manifest Manager state machine entry point to the Update Client event queue 00349 UC_MMGR_TRACE("%s Posting ARM_UC_mmVerifySignatureEntry(%lu)\n", __PRETTY_FUNCTION__, event); 00350 ARM_UC_PostCallback(&arm_uc_mmSignatureVerificationContext.callbackStorage, ARM_UC_mmVerifySignatureEntry, event); 00351 } 00352 00353 /** 00354 * @brief State machine that controls the verification of signatures. 00355 * @details First, the state machine attempts to fetch the certificate. When the certificate has been fetched, 00356 * the state machine validates the signature, then alerts the calling application with the result. 00357 * 00358 * 00359 * @param[in] ctx Context pointer for the state machine 00360 * @param[in] event Event to move the state machine forward 00361 * @retval MFST_ERR_NONE on success 00362 * @retval MFST_ERR_PENDING when the validation has not completed and is waiting for external input 00363 * (e.g. certificate fetching) 00364 * @retval Another error code otherwise. 00365 */ 00366 static arm_uc_error_t ARM_UC_mmValidateSignatureFSM(arm_uc_mm_validate_signature_context_t* ctx, uint32_t event) 00367 { 00368 arm_uc_error_t err = {MFST_ERR_NONE}; 00369 enum arm_uc_mm_pk_sig_state oldState; 00370 UC_MMGR_TRACE("%s (%lu)\n", __PRETTY_FUNCTION__, event); 00371 do 00372 { 00373 oldState = ctx->state; 00374 UC_MMGR_TRACE("%s state:%u\n", __PRETTY_FUNCTION__, oldState); 00375 switch(ctx->state) 00376 { 00377 case UCMM_PKSIG_STATE_FIND_CA: 00378 // Start the search for a certificate 00379 // This state transitions automatically to UCMM_PKSIG_STATE_FINDING_CA unless there is an error 00380 err = ARM_UC_certificateFetch(&ctx->cert, 00381 &ctx->fingerprint, 00382 &ctx->certList, 00383 ARM_UC_mmCertificateCallback); 00384 if (err.error == ERR_NONE || err.code == MFST_ERR_PENDING) 00385 { 00386 ctx->state = UCMM_PKSIG_STATE_FINDING_CA; 00387 err.code = MFST_ERR_PENDING; 00388 } 00389 break; 00390 case UCMM_PKSIG_STATE_FINDING_CA: 00391 // Wait the Certificate fetch to complete. On completion, this state decides what to do with the result. 00392 switch(event) 00393 { 00394 // If the certificate was fetched successfully, proceed to signature verification 00395 case ARM_UC_MM_CERTIFICATE_FETCH_SUCCESS: 00396 err.code = MFST_ERR_NONE; 00397 ctx->state = UCMM_PKSIG_STATE_CHECK; 00398 break; 00399 // If an error occured, extract the error. 00400 case ARM_UC_MM_CERTIFICATE_FETCH_ERROR: 00401 err = ctx->storedError; 00402 break; 00403 // Otherwise, report a bad event. 00404 case ARM_UC_MM_CERTIFICATE_FETCH_UNINIT: 00405 case ARM_UC_MM_CERTIFICATE_FETCH_MISMATCH: 00406 default: 00407 err.code = MFST_ERR_BAD_EVENT; 00408 break; 00409 } 00410 break; 00411 // Validate the signature 00412 case UCMM_PKSIG_STATE_CHECK: 00413 err = ARM_UC_mmValidateSignatureCert(ctx->manifest, 00414 &ctx->cert, ctx->sigIndex); 00415 if (err.code == MFST_ERR_NONE) 00416 { 00417 ctx->state = UCMM_PKSIG_STATE_IDLE; 00418 } 00419 break; 00420 case UCMM_PKSIG_STATE_IDLE: 00421 err.code = MFST_ERR_NONE; 00422 // The Entry function will report success after this state exits. 00423 break; 00424 default: 00425 err = (arm_uc_error_t){MFST_ERR_INVALID_STATE}; 00426 break; 00427 } 00428 00429 } while (err.code == MFST_ERR_NONE && ctx->state != oldState); 00430 UC_MMGR_TRACE("%s() return code: %c%c:%hu (%s)\n", 00431 __PRETTY_FUNCTION__, err.modulecc[0], err.modulecc[1], err.error, ARM_UC_err2Str(err)); 00432 return err; 00433 } 00434 /** 00435 * @brief Start signature verification. 00436 * @details This API initiates a signature verification. The actual signature verification is carried out by 00437 * 00438 * 00439 * @param[in] ctx Signature validation context. This contains all the state used by the signature validator. 00440 * @param[in] buffer A buffer containing the manifest to verify 00441 * @param[in] certBuffer A temporary storage buffer for certificate fetching 00442 * @param[in] sigIndex Index of the signature to verify. 00443 * @retval MFST_ERR_NONE on success 00444 * @retval MFST_ERR_PENDING when the validation has not completed and is waiting for external input 00445 * (e.g. certificate fetching) 00446 * @retval Another error code otherwise. 00447 */ 00448 arm_uc_error_t ARM_UC_mmValidateSignature(arm_uc_mm_validate_signature_context_t* ctx, 00449 void (*applicationEventHandler)(uint32_t), 00450 arm_uc_buffer_t* buffer, 00451 arm_uc_buffer_t* certBuffer, 00452 uint32_t sigIndex) 00453 { 00454 UC_MMGR_TRACE("%s (%u)\n", __PRETTY_FUNCTION__, (unsigned)sigIndex); 00455 arm_uc_error_t err = {MFST_ERR_NONE}; 00456 if (ctx == NULL) 00457 { 00458 ARM_UC_SET_ERROR(err, MFST_ERR_NULL_PTR); 00459 } 00460 if (err.error == ERR_NONE) 00461 { 00462 #ifdef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK 00463 arm_uc_mmSignatureVerificationContext.callbackStorage.lock = 0; 00464 #endif 00465 arm_uc_mmSignatureVerificationContext.ctx = ctx; 00466 // Extract the certificate identifier from the manifest 00467 err = ARM_UC_mmGetCertificateId(buffer, sigIndex, &arm_uc_mmSignatureVerificationContext.ctx->fingerprint); 00468 UC_MMGR_TRACE("%s %c%c:%hu (%s)\n", "Get Certificate ID return code:", err.modulecc[0], err.modulecc[1], err.error, ARM_UC_err2Str(err)); 00469 } 00470 if(err.error == 0 && ctx) 00471 { 00472 // Copy all the relevant inputs into the state variable 00473 err.code = MFST_ERR_NONE; 00474 arm_uc_mmSignatureVerificationContext.ctx->manifest = buffer; 00475 arm_uc_mmSignatureVerificationContext.ctx->applicationEventHandler = applicationEventHandler; 00476 arm_uc_mmSignatureVerificationContext.ctx->state = UCMM_PKSIG_STATE_FIND_CA; 00477 arm_uc_mmSignatureVerificationContext.ctx->sigIndex = sigIndex; 00478 ARM_UC_buffer_shallow_copy(&arm_uc_mmSignatureVerificationContext.ctx->cert, certBuffer); 00479 UC_MMGR_TRACE("%s Posting ARM_UC_mmVerifySignatureEntry(%lu)\n", __PRETTY_FUNCTION__, ARM_UC_MM_EVENT_BEGIN); 00480 ARM_UC_PostCallback(&arm_uc_mmSignatureVerificationContext.callbackStorage, ARM_UC_mmVerifySignatureEntry, ARM_UC_MM_EVENT_BEGIN); 00481 } 00482 UC_MMGR_TRACE("%s %c%c:%hu (%s)\n", __PRETTY_FUNCTION__, err.modulecc[0], err.modulecc[1], err.error, ARM_UC_err2Str(err)); 00483 return err; 00484 } 00485 00486 /** 00487 * @brief Main entry point for callbacks to enter the state machine. 00488 * @details Calls the signature verification state machine. If the result is not Pending, calls the application event 00489 * handler with a result code. 00490 * Application event handler is invoked directly, not queued because this function should have minimal stack 00491 * and it should be called directly from the event queue. 00492 * @param[in] event Event to forward to the state machine 00493 */ 00494 void ARM_UC_mmVerifySignatureEntry(uint32_t event) 00495 { 00496 UC_MMGR_TRACE("%s (%u)\n", __PRETTY_FUNCTION__, (unsigned)event); 00497 arm_uc_error_t err = ARM_UC_mmValidateSignatureFSM(arm_uc_mmSignatureVerificationContext.ctx , event); 00498 if (err.code != MFST_ERR_NONE && err.code != MFST_ERR_PENDING) 00499 { 00500 arm_uc_mmSignatureVerificationContext.ctx->storedError = err; 00501 arm_uc_mmSignatureVerificationContext.ctx->applicationEventHandler(ARM_UC_MM_RC_ERROR); 00502 } 00503 if (err.code == MFST_ERR_NONE && arm_uc_mmSignatureVerificationContext.ctx->state == UCMM_PKSIG_STATE_IDLE) 00504 { 00505 // A callback is not posted since this runs inside 00506 arm_uc_mmSignatureVerificationContext.ctx->applicationEventHandler(ARM_UC_MM_RC_DONE); 00507 } 00508 UC_MMGR_TRACE("%s %c%c:%hu (%s)\n", __PRETTY_FUNCTION__, err.modulecc[0], err.modulecc[1], err.error, ARM_UC_err2Str(err)); 00509 }
Generated on Tue Jul 12 2022 19:01:32 by 1.7.2