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