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.
Dependencies: FXAS21002 FXOS8700Q
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 #include "update-client-common/arm_uc_config.h" 00025 #include "update-client-metadata-header/arm_uc_buffer_utilities.h" 00026 #include "update-client-control-center/arm_uc_certificate.h" 00027 #include "update-client-control-center/arm_uc_pre_shared_key.h" 00028 00029 #include "arm_uc_mmDerManifestAccessors.h" 00030 #include "update-client-manifest-manager/update-client-manifest-manager.h" 00031 00032 #if defined(ARM_UC_FEATURE_MANIFEST_PSK) && (ARM_UC_FEATURE_MANIFEST_PSK == 1) 00033 #include "mbedtls/ccm.h" 00034 #endif /* ARM_UC_FEATURE_MANIFEST_PSK */ 00035 00036 #include <string.h> 00037 00038 extern int ARM_UC_MM_ASN1_get_tag(unsigned char **p, 00039 const unsigned char *end, 00040 size_t *len, int tag); 00041 00042 void ARM_UC_mmVerifySignatureEntry(uintptr_t event); 00043 /** 00044 * @file Cryptographic utilities 00045 * This file provides two primary APIs: 00046 * * Verifying manifest hashes 00047 * * Verifying manifest signatures 00048 * 00049 * Some utility functions used by other files in this module are also provided. 00050 * 00051 * Algorithm support: 00052 * ECC is currently supported, but RSA is not. 00053 * Currently, only ECC secp256r1 (prime256v1) is supported. 00054 * Currently, only SHA256 is supported. 00055 * HMAC is not yet supported. 00056 */ 00057 00058 /** 00059 * @brief Returns the sizes of the cryptographic primitives used by the supplied manifest. 00060 * @details Extracts the cryptomode field from a manifest and returns a struct that describes the size of cryptographic 00061 * primitives used in the manifest. The supplied manifest must have been validated. No validation is performed 00062 * by this function. 00063 * 00064 * @param[in] buffer A buffer that contains a validated manifest. 00065 * @return A struct cryptsize, which contains the AES primitive sizes and SHA primitive size, both in bytes. 00066 * An invalid cryptographic mode specifier will cause primitive sizes of `0` to be returned. 00067 */ 00068 struct cryptsize getCryptInfo(arm_uc_buffer_t *buffer) 00069 { 00070 struct cryptsize cs = {0}; 00071 uint32_t cryptoMode = 1U; // default SHA256 and ECC 00072 ARM_UC_mmGetCryptoMode(buffer, &cryptoMode); 00073 00074 switch (cryptoMode) { 00075 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00076 case MFST_CRYPT_SHA256_ECC_AES128_PSK: 00077 cs.aeslen = 128 / CHAR_BIT; 00078 // fall through 00079 __attribute__((fallthrough)); // prevent fallthrough warning 00080 // case MFST_CRYPT_SHA256_HMAC: 00081 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00082 case MFST_CRYPT_SHA256: 00083 cs.hashlen = 256 / CHAR_BIT; 00084 break; 00085 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00086 case MFST_CRYPT_SHA256_ECC: 00087 cs.hashlen = 256 / CHAR_BIT; 00088 break; 00089 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00090 #if defined(ARM_UC_FEATURE_MANIFEST_PSK) && (ARM_UC_FEATURE_MANIFEST_PSK == 1) 00091 case MFST_CRYPT_PSK_AES128CCM_SHA256: 00092 case MFST_CRYPT_NONE_PSK_AES128CCM_SHA256: 00093 cs.aeslen = 128 / CHAR_BIT; 00094 cs.hashlen = 256 / CHAR_BIT; 00095 break; 00096 #endif /* ARM_UC_FEATURE_MANIFEST_PSK */ 00097 default: 00098 break; 00099 } 00100 return cs; 00101 } 00102 00103 /** 00104 * @brief Converts a cryptographic mode enum to a structure with mode identifiers 00105 * @details In order to simplify many tests, the cryptographic mode identifier is converted into a structure of mode 00106 * identifiers, one for each cryptographic primitive. This allows other parts of the code to examine the mode 00107 * of one particular primitive without testing against many enums. This function performs no validation. The 00108 * calling function should have performed validation in advance. If the cryptoMode is unrecognized, then a 00109 * return will be populated with 0 for every flag. 00110 * 00111 * HMAC modes are not currently supported. 00112 * TODO: Convert flags to enums 00113 * @param[in] cryptoMode The cryptographic mode enum that specifies the settings for each primitive 00114 * @return A structure of flags that indicate the mode of: 00115 * * Hash algorithm 00116 * * MAC 00117 * * Symmetric Encryption 00118 * * Pre-shared keys 00119 * * Public Key modes 00120 */ 00121 arm_uc_mm_crypto_flags_t ARM_UC_mmGetCryptoFlags(uint32_t cryptoMode) 00122 { 00123 00124 switch (cryptoMode) { 00125 case MFST_CRYPT_SHA256: 00126 return (arm_uc_mm_crypto_flags_t) {.hash = 1U}; 00127 // case MFST_CRYPT_SHA256_HMAC: 00128 // return (arm_uc_mm_crypto_flags_t) {.hash = 1, .hmac = 1}; 00129 // case MFST_CRYPT_SHA256_HMAC_AES128_PSK: 00130 // return (arm_uc_mm_crypto_flags_t) {.hash = 1, .hmac = 1, .aes = 1, .psk = 1}; 00131 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00132 case MFST_CRYPT_SHA256_ECC: 00133 return (arm_uc_mm_crypto_flags_t) {.hash = 1U, .ecc = 1U}; 00134 case MFST_CRYPT_SHA256_ECC_AES128_PSK: 00135 return (arm_uc_mm_crypto_flags_t) {.hash = 1U, .ecc = 1U, .aes = 1U, .psk = 1U}; 00136 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00137 #if defined(ARM_UC_FEATURE_MANIFEST_PSK) && (ARM_UC_FEATURE_MANIFEST_PSK == 1) 00138 case MFST_CRYPT_PSK_AES128CCM_SHA256: 00139 return (arm_uc_mm_crypto_flags_t) {.hash = 1U, .aes = 1U, .psk = 1U}; 00140 case MFST_CRYPT_NONE_PSK_AES128CCM_SHA256: 00141 return (arm_uc_mm_crypto_flags_t) {.hash = 1U, .psk = 1U}; 00142 #endif /* ARM_UC_FEATURE_MANIFEST_PSK */ 00143 } 00144 return (arm_uc_mm_crypto_flags_t) {.hash = 0}; 00145 00146 } 00147 00148 /** 00149 * @brief Extracts the hash of a manifest from the manifest wrapper. 00150 * @details This is a utility function that is used to extract the hash of the manifest for signature validation. 00151 * This function does not perform validation of the hash buffer, so the hash buffer is expected to be populated 00152 * with a known-good hash buffer. Typically, this buffer will be stack-allocated. 00153 * @param[in] buffer The manifest to parse 00154 * @param[out] hash Output buffer object to fill with the hash 00155 * @return ERR_NONE on success, or a parser error code otherwise 00156 */ 00157 arm_uc_error_t ARM_UC_mmGetManifestHashFromBin(arm_uc_buffer_t *buffer, arm_uc_buffer_t *hash) 00158 { 00159 const int32_t fieldID = ARM_UC_MM_DER_SIG_HASH; 00160 int rc = ARM_UC_mmDERGetSignedResourceValues(buffer, 1U, &fieldID, hash); 00161 if (rc) return (arm_uc_error_t) {MFST_ERR_DER_FORMAT}; 00162 return (arm_uc_error_t) {ERR_NONE}; 00163 } 00164 00165 /** 00166 * Utility function for printing the hex value of a buffer. Used only for debugging. 00167 * @param buf [description] 00168 */ 00169 #if 0 00170 static void hexprint_buffer(arm_uc_buffer_t *buf) 00171 { 00172 for (size_t i = 0; i < buf->size; i++) { 00173 printf("%02x", buf->ptr[i]); 00174 } 00175 } 00176 #endif 00177 00178 /** 00179 * @brief ARM_UC_mmValidateManifestHash processes a manifest in order to validate its hash 00180 * @details The manifest parser extracts the manifest hash, calculates the hash of the manifest, then compares it to the 00181 * hash included in the manifest. 00182 * 00183 * The outer wrapper of the manifest is called a SignedResource. It contains a Resource object and a 00184 * ResourceSignature object. The Resource object contains a Resource Type identifier, an optional URL, and 00185 * either a manifest or binary data. 00186 * 00187 * This function extracts the Resource object and the ResourceSignature object so that the Resource can be 00188 * hashed and verified against the hash in the ResourceSignature. 00189 * 00190 * TODO: The dependency on the cryptoMode contained within the manifest will be removed with the change to CMS 00191 * First, the Resource object is extracted. Next, the cryptoMode is extracted from the Resource object. This 00192 * requires that the Resource object be a Manifest. 00193 * 00194 * @param[in] buffer The buffer that contains the manifest to validate 00195 * @retval ERR_NONE on success 00196 * @retval MFST_ERR_CRYPTO_MODE if there is a cryptographic mode error 00197 * @retval Otherwise, a DER Parser error can be expected 00198 */ 00199 arm_uc_error_t ARM_UC_mmValidateManifestHash(arm_uc_buffer_t *buffer) 00200 { 00201 uint8_t localhash[MAX_HASH_BYTES]; ///< An array to store the locally calculated hash 00202 arm_uc_buffer_t local = { ///< A buffer structure to use for the locally calculated hash 00203 .size_max = MAX_HASH_BYTES, 00204 .size = 0, 00205 .ptr = localhash 00206 }; 00207 arm_uc_buffer_t remote = { ///< A buffer for the hash provided in the manifest 00208 .size_max = MAX_HASH_BYTES, 00209 .size = 0, 00210 .ptr = NULL 00211 }; 00212 arm_uc_buffer_t resource = { ///< A buffer for the resource (the manifest) that is wrapped by a signature 00213 .size_max = MAX_HASH_BYTES, 00214 .size = 0, 00215 .ptr = NULL 00216 }; 00217 arm_uc_mdHandle_t hDigest = {0}; ///< This handle is for the digest algorithm 00218 arm_uc_error_t err = {ERR_NONE}; ///< The return code variable 00219 uint32_t cryptoMode = 0; ///< A temporary local copy of the crytpoMode 00220 arm_uc_mdType_t mdType = 0; ///< A type designator for the type of hash in use 00221 00222 // Extract the "resource" contained in the Signed Resource object 00223 err = ARM_UC_mmDERSignedResourceGetSingleValue(buffer, ARM_UC_MM_DER_RESOURCE, &resource); 00224 if (!err.error) { 00225 // Extract the hash from the manifest 00226 err = ARM_UC_mmGetManifestHash(buffer, &remote); 00227 } 00228 if (!err.error) { 00229 // Extract the cryptographic mode from the manifest 00230 err = ARM_UC_mmGetCryptoMode(buffer, &cryptoMode); 00231 } 00232 if (!err.error) { 00233 // Set the hash type identifier 00234 switch (cryptoMode) { 00235 case MFST_CRYPT_SHA256_ECC_AES128_PSK: 00236 case MFST_CRYPT_SHA256: 00237 case MFST_CRYPT_SHA256_ECC: 00238 case MFST_CRYPT_NONE_PSK_AES128CCM_SHA256: 00239 case MFST_CRYPT_PSK_AES128CCM_SHA256: 00240 mdType = ARM_UC_CU_SHA256; 00241 break; 00242 default: 00243 err.code = MFST_ERR_CRYPTO_MODE; 00244 break; 00245 } 00246 } 00247 if (!err.error) { 00248 // Initialize the message digest API 00249 err = ARM_UC_cryptoHashSetup(&hDigest, mdType); 00250 } 00251 if (!err.error) { 00252 // NOTE: If a hash accelerator is present on-chip, this could be converted from a blocking call to an 00253 // asynchronous one. 00254 // Hash the resource 00255 // Keep Coverity quiet - it can't resolve some semantic conditions here. 00256 if (resource.ptr == NULL) { 00257 ARM_UC_SET_ERROR(err, MFST_ERR_NULL_PTR); 00258 } else { 00259 err = ARM_UC_cryptoHashUpdate(&hDigest, &resource); 00260 } 00261 } 00262 if (!err.error) { 00263 // Extract the locally calculated hash from the hash API 00264 err = ARM_UC_cryptoHashFinish(&hDigest, &local); 00265 } 00266 if (!err.error) { 00267 // Check that the hashes match 00268 // Keep Coverity quiet - it can't resolve some semantic conditions here. 00269 if (remote.ptr == NULL) { 00270 ARM_UC_SET_ERROR(err, MFST_ERR_NULL_PTR); 00271 } else if (ARM_UC_BinCompareCT(&local, &remote)) { 00272 ARM_UC_SET_ERROR(err, MFST_ERR_HASH); 00273 } 00274 } 00275 // Explicitly set the manifest manager's no-error code, rather than another module's, which may be present here. 00276 if (!err.error) { 00277 ARM_UC_SET_ERROR(err, ERR_NONE); 00278 } 00279 return err; 00280 } 00281 00282 enum arm_uc_mmCertificateFetchEvents { 00283 ARM_UC_MM_CERTIFICATE_FETCH_UNINIT, 00284 ARM_UC_MM_CERTIFICATE_FETCH_SUCCESS, 00285 ARM_UC_MM_CERTIFICATE_FETCH_MISMATCH, 00286 ARM_UC_MM_CERTIFICATE_FETCH_ERROR, 00287 }; 00288 00289 /** 00290 * @brief Validates one signature of a manifest, once the signing certificate has been found. 00291 * @param buffer Holding buffer for the manifest to validate. 00292 * @param ca Buffer holding the certificate to use in verification 00293 * @param sigIndex Index of the manifest signature to verify with this certificate 00294 * @retval MFST_ERR_DER_FORMAT on parse error 00295 * @retval MFST_ERR_CERT_INVALID if the certificate is not valid 00296 * @retval MFST_ERR_INVALID_SIGNATURE if the signature is invalid 00297 * @retval ERR_NONE for a valid signature 00298 */ 00299 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00300 00301 #if defined(ARM_UC_FEATURE_CRYPTO_MBEDTLS) && (ARM_UC_FEATURE_CRYPTO_MBEDTLS == 1) 00302 /** 00303 * @brief Verify a public key signature 00304 * @details This function loads a certificate out of `ca`, and validates `hash` using the certificate and `sig`. If the 00305 * certificate used by this function requires a certificate chain validation (i.e. it is not the root of trust, 00306 * or it has not been previously validated), certificate chain validation should be done prior to calling this 00307 * function. 00308 * 00309 * WARNING: this function is to be used only inside a function where its arguments have been error checked. 00310 * WARNING: This is an internal utility function and is not accessible outside of the manifest manager. 00311 * 00312 * @param[in] ca A pointer to a buffer that contains the signing certificate. 00313 * @param[in] hash A pointer to a buffer containing the hash to verify. 00314 * @param[in] sig A pointer to a buffer containing a signature by `ca` 00315 * @retval MFST_ERR_CERT_INVALID when the certificate fails to load 00316 * @retval MFST_ERR_INVALID_SIGNATURE when signature verification fails 00317 * @retval ERR_OUT_OF_MEMORY when run out of memory 00318 * @retval ERR_NONE for a valid signature 00319 */ 00320 static arm_uc_error_t ARM_UC_verifyPkSignature(const arm_uc_buffer_t *ca, const arm_uc_buffer_t *hash, 00321 const arm_uc_buffer_t *sig) 00322 { 00323 arm_uc_error_t err = {ERR_NONE}; 00324 mbedtls_x509_crt crt; 00325 mbedtls_x509_crt_init(&crt); 00326 int rc = mbedtls_x509_crt_parse_der(&crt, ca->ptr, ca->size); 00327 if (rc == MBEDTLS_ERR_X509_ALLOC_FAILED) { 00328 err.code = ERR_OUT_OF_MEMORY; 00329 } else if (rc < 0) { 00330 UC_MMGR_ERR_MSG("mbedtls_x509_crt_parse_der returned error "PRIu32, rc); 00331 err.code = MFST_ERR_CERT_INVALID; 00332 } else { 00333 rc = mbedtls_pk_verify(&crt.pk, MBEDTLS_MD_SHA256, hash->ptr, hash->size, sig->ptr, sig->size); 00334 if (rc < 0) { 00335 UC_MMGR_ERR_MSG("mbedtls_pk_verify returned error "PRIu32, rc); 00336 err.code = MFST_ERR_INVALID_SIGNATURE; 00337 } 00338 } 00339 return err; 00340 } 00341 #elif defined(ARM_UC_FEATURE_CRYPTO_PAL) && (ARM_UC_FEATURE_CRYPTO_PAL == 1) 00342 00343 arm_uc_error_t ARM_UC_verifyPkSignature(const arm_uc_buffer_t *ca, const arm_uc_buffer_t *hash, 00344 const arm_uc_buffer_t *sig) 00345 { 00346 arm_uc_error_t err = {MFST_ERR_CERT_INVALID}; 00347 palX509Handle_t x509Cert; 00348 palStatus_t status = pal_x509Initiate(&x509Cert); 00349 if (PAL_SUCCESS == status) { 00350 err.code = MFST_ERR_CERT_INVALID; 00351 if (PAL_SUCCESS == pal_x509CertParse(x509Cert, ca->ptr, ca->size)) { 00352 // if (PAL_SUCCESS == pal_x509CertVerify(x509Cert, palX509Handle_t x509CertChain)) 00353 // { 00354 err.code = MFST_ERR_INVALID_SIGNATURE; 00355 status = pal_verifySignature(x509Cert, PAL_SHA256, hash->ptr, hash->size, sig->ptr, sig->size); 00356 if (PAL_SUCCESS == status) { 00357 err.code = ERR_NONE; 00358 } else if (PAL_ERR_CRYPTO_ALLOC_FAILED == status) { 00359 err.code = ERR_OUT_OF_MEMORY; 00360 } else { 00361 UC_MMGR_ERR_MSG("pal_verifySignature returned error "PRIu32, status); 00362 } 00363 // } 00364 } 00365 pal_x509Free(&x509Cert); 00366 } else if (PAL_ERR_CREATION_FAILED == status) { 00367 err.code = ERR_OUT_OF_MEMORY; 00368 } 00369 return err; 00370 } 00371 #endif 00372 00373 static arm_uc_error_t ARM_UC_mmValidateSignatureCert(arm_uc_buffer_t *buffer, arm_uc_buffer_t *ca, uint32_t sigIndex) 00374 { 00375 const int32_t fieldIDs[] = {ARM_UC_MM_DER_SIG_HASH, ARM_UC_MM_DER_SIG_SIGNATURES}; 00376 arm_uc_buffer_t fields[ARRAY_SIZE(fieldIDs)]; 00377 00378 // Get the signature list 00379 int rc = ARM_UC_mmDERGetSignedResourceValues(buffer, ARRAY_SIZE(fieldIDs), fieldIDs, fields); 00380 if (rc) return (arm_uc_error_t) {MFST_ERR_DER_FORMAT}; 00381 00382 // Get the specified signature block 00383 arm_uc_buffer_t sigblock; 00384 rc = ARM_UC_mmDERGetSequenceElement(&fields[1], sigIndex, &sigblock); 00385 if (rc) return (arm_uc_error_t) {MFST_ERR_DER_FORMAT}; 00386 00387 // Load the specified signature out of the signature block 00388 arm_uc_buffer_t sig; 00389 const int32_t sigID = ARM_UC_MM_DER_SIG_SIGNATURE; 00390 rc = ARM_UC_mmDERParseTree(&arm_uc_mmSignatures[0], &sigblock, 1U, &sigID, &sig); 00391 if (rc) return (arm_uc_error_t) {MFST_ERR_DER_FORMAT}; 00392 00393 // Validate the signature 00394 return ARM_UC_verifyPkSignature(ca, &fields[0], &sig); 00395 } 00396 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00397 struct { 00398 arm_uc_mm_validate_signature_context_t *ctx; 00399 arm_uc_callback_t callbackStorage; 00400 } arm_uc_mmSignatureVerificationContext; 00401 00402 00403 /** 00404 * @brief Callback function to continue signature verification once the certificate has been found 00405 * @details This function should be called by the certificate lookup function, which is provided by the application. 00406 * The certificate lookup function should call this callback regardless of success or failure so that errors 00407 * can be reported correctly. 00408 * 00409 * Caveats: 00410 * The certificate supplied here MUST be the same buffer as was provided to the certificate fetch function. 00411 * The fingerprint supplied here MUST be the same buffer as was provided to the certificate fetch function. 00412 * 00413 * These requirements are in place to ensure that only one signature verification may be carried out at a time. 00414 * 00415 * Once the basic checks are performed in the callback, it schedules the manifest manager to execute later. 00416 * 00417 * @param status Error code provided by the certificat lookup function 00418 * @param certificate Buffer containing the certificate 00419 * @param fingerprint Buffer containing the certificate fingerprint 00420 */ 00421 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00422 void ARM_UC_mmCertificateCallback(arm_uc_error_t status, const arm_uc_buffer_t *certificate, 00423 const arm_uc_buffer_t *fingerprint) 00424 { 00425 uint32_t event = ARM_UC_MM_CERTIFICATE_FETCH_UNINIT; 00426 UC_MMGR_TRACE("%s (%u)\n", __PRETTY_FUNCTION__, (unsigned)event); 00427 if (status.error == ERR_NONE) { 00428 // Verify that this is the same buffer as was provided to the certificate fetch function. 00429 if (fingerprint != &arm_uc_mmSignatureVerificationContext.ctx->fingerprint || 00430 certificate != &arm_uc_mmSignatureVerificationContext.ctx->cert) { 00431 event = ARM_UC_MM_CERTIFICATE_FETCH_MISMATCH; 00432 } else { 00433 event = ARM_UC_MM_CERTIFICATE_FETCH_SUCCESS; 00434 } 00435 } else { 00436 // Store the error for later reporting 00437 arm_uc_mmSignatureVerificationContext.ctx->storedError = status; 00438 event = ARM_UC_MM_CERTIFICATE_FETCH_ERROR; 00439 } 00440 // Post the Manifest Manager state machine entry point to the Update Client event queue 00441 UC_MMGR_TRACE("%s Posting ARM_UC_mmVerifySignatureEntry(%" PRIu32 ")\n", __PRETTY_FUNCTION__, event); 00442 ARM_UC_PostCallback(&arm_uc_mmSignatureVerificationContext.callbackStorage, ARM_UC_mmVerifySignatureEntry, event); 00443 } 00444 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00445 /** 00446 * @brief State machine that controls the verification of signatures. 00447 * @details First, the state machine attempts to fetch the certificate. When the certificate has been fetched, 00448 * the state machine validates the signature, then alerts the calling application with the result. 00449 * 00450 * 00451 * @param[in] ctx Context pointer for the state machine 00452 * @param[in] event Event to move the state machine forward 00453 * @retval ERR_NONE on success 00454 * @retval MFST_ERR_PENDING when the validation has not completed and is waiting for external input 00455 * (e.g. certificate fetching) 00456 * @retval Another error code otherwise. 00457 */ 00458 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00459 static arm_uc_error_t ARM_UC_mmValidateSignatureFSM(arm_uc_mm_validate_signature_context_t *ctx, uint32_t event) 00460 { 00461 arm_uc_error_t err = {ERR_NONE}; 00462 enum arm_uc_mm_pk_sig_state oldState; 00463 UC_MMGR_TRACE("%s (%" PRIu32 ")\n", __PRETTY_FUNCTION__, event); 00464 do { 00465 oldState = ctx->pk_state; 00466 UC_MMGR_TRACE("%s state:%u\n", __PRETTY_FUNCTION__, oldState); 00467 switch (ctx->pk_state) { 00468 case UCMM_PKSIG_STATE_FIND_CA: 00469 // Start the search for a certificate 00470 // This state transitions automatically to UCMM_PKSIG_STATE_FINDING_CA unless there is an error 00471 err = ARM_UC_certificateFetch(&ctx->cert, 00472 &ctx->fingerprint, 00473 &ctx->certList, 00474 ARM_UC_mmCertificateCallback); 00475 if (err.error == ERR_NONE || err.code == MFST_ERR_PENDING) { 00476 ctx->pk_state = UCMM_PKSIG_STATE_FINDING_CA; 00477 err.code = MFST_ERR_PENDING; 00478 } 00479 break; 00480 case UCMM_PKSIG_STATE_FINDING_CA: 00481 // Wait the Certificate fetch to complete. On completion, this state decides what to do with the result. 00482 switch (event) { 00483 // If the certificate was fetched successfully, proceed to signature verification 00484 case ARM_UC_MM_CERTIFICATE_FETCH_SUCCESS: 00485 err.code = ERR_NONE; 00486 ctx->pk_state = UCMM_PKSIG_STATE_CHECK; 00487 break; 00488 // If an error occured, extract the error. 00489 case ARM_UC_MM_CERTIFICATE_FETCH_ERROR: 00490 err = ctx->storedError; 00491 break; 00492 // Otherwise, report a bad event. 00493 case ARM_UC_MM_CERTIFICATE_FETCH_UNINIT: 00494 case ARM_UC_MM_CERTIFICATE_FETCH_MISMATCH: 00495 default: 00496 err.code = MFST_ERR_BAD_EVENT; 00497 break; 00498 } 00499 break; 00500 // Validate the signature 00501 case UCMM_PKSIG_STATE_CHECK: 00502 err = ARM_UC_mmValidateSignatureCert(ctx->manifest, 00503 &ctx->cert, ctx->sigIndex); 00504 if (err.code == ERR_NONE) { 00505 ctx->pk_state = UCMM_PKSIG_STATE_IDLE; 00506 } 00507 break; 00508 case UCMM_PKSIG_STATE_IDLE: 00509 err.code = ERR_NONE; 00510 // The Entry function will report success after this state exits. 00511 break; 00512 default: 00513 err = (arm_uc_error_t) {MFST_ERR_INVALID_STATE}; 00514 break; 00515 } 00516 00517 } while (err.code == ERR_NONE && ctx->pk_state != oldState); 00518 UC_MMGR_TRACE("%s() return code: %c%c:%hu (%s)\n", 00519 __PRETTY_FUNCTION__, CC_ASCII(err.modulecc[0]), CC_ASCII(err.modulecc[1]), 00520 err.error, ARM_UC_err2Str(err)); 00521 return err; 00522 } 00523 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00524 00525 #if defined(ARM_UC_FEATURE_MANIFEST_PSK) && (ARM_UC_FEATURE_MANIFEST_PSK == 1) 00526 static arm_uc_error_t ARM_UC_mmValidateSignaturePSKFSM(arm_uc_mm_validate_signature_context_t *ctx, uint32_t event) 00527 { 00528 arm_uc_error_t err = {ERR_NONE}; 00529 enum arm_uc_mm_psk_sig_state oldState; 00530 UC_MMGR_TRACE("%s (%" PRIu32 ")\n", __PRETTY_FUNCTION__, event); 00531 do { 00532 oldState = ctx->psk_state; 00533 UC_MMGR_TRACE("%s state:%u\n", __PRETTY_FUNCTION__, oldState); 00534 switch (ctx->psk_state) { 00535 case ARM_UC_MM_PSKSIG_STATE_FIND_PSK: 00536 // Start the search for a PSK 00537 // This state transitions automatically to UCMM_PKSIG_STATE_FINDING_CA unless there is an error 00538 err = ARM_UC_PreSharedKey_GetSecret((const uint8_t **)&ctx->PSK.ptr, 128); 00539 if (err.error == ERR_NONE) { 00540 ctx->PSK.size = 128 / 8; 00541 ctx->PSK.size_max = 128 / 8; 00542 ctx->psk_state = ARM_UC_MM_PSKSIG_STATE_FIND_SIG_START; 00543 } 00544 break; 00545 // TODO: Currently, PSK ID is unused. 00546 case ARM_UC_MM_PSKSIG_STATE_FIND_SIG_START: { 00547 // Right now, only "thismessage://" URIs are supported. 00548 const char refPrefix[] = "thismessage://"; 00549 // The following line deliberately excludes a ' - 1' because the URI needs to have 00550 // exactly one character following the "thismessage://" 00551 err.code = ERR_NONE; 00552 int sizeOK = ctx->keyTableRef.size == sizeof(refPrefix); 00553 int matchOK = 0; 00554 if (sizeOK) { 00555 matchOK = 1; 00556 // NOTE: There seems to be a problem with the evaluation of strncmp and/or memcmp on these values. 00557 // Byte-by-byte comparison *does* work. This should be investigated. 00558 for (size_t i = 0; i < sizeof(refPrefix) - 1; i++) { 00559 if (ctx->keyTableRef.ptr[i] != refPrefix[i]) { 00560 matchOK = 0; 00561 break; 00562 } 00563 } 00564 } else { 00565 UC_MMGR_TRACE("keytable reference length: expected=%" PRIu16 " actual=%" PRIu32 "\n", (uint16_t)sizeof(refPrefix), 00566 ctx->keyTableRef.size); 00567 } 00568 if (!matchOK) { 00569 UC_MMGR_TRACE("KeyTable Error - not matched."); 00570 ARM_UC_SET_ERROR(err, MFST_ERR_BAD_KEYTABLE); 00571 } 00572 // Only position 1 is supported for now. Position 0 is the manifest 00573 // Check the signature location 00574 if (err.error == ERR_NONE && ctx->keyTableRef.ptr[sizeof(refPrefix) - 1] != '1') { 00575 ARM_UC_SET_ERROR(err, MFST_ERR_MISSING_KEYTABLE); 00576 } 00577 00578 uint8_t *p = ctx->manifest->ptr; 00579 uint8_t *end = p + ctx->manifest->size; 00580 size_t len = 0; 00581 // Get the signature 00582 if (err.error == ERR_NONE) { 00583 // To get the signature, we have to find out how big the manifest is. 00584 int rc = ARM_UC_MM_ASN1_get_tag(&p, end, &len, ARM_UC_MM_ASN1_SEQUENCE | ARM_UC_MM_ASN1_CONSTRUCTED); 00585 if (rc) { 00586 UC_MMGR_TRACE("KeyTable Error - get-tag failed, manifest length == %" PRIu32, len); 00587 ARM_UC_SET_ERROR(err, MFST_ERR_MISSING_KEYTABLE); 00588 } 00589 } 00590 if (err.error == ERR_NONE) { 00591 p += len; 00592 len = 0; 00593 // Now, read the content. Currently, a single binary string is expected. 00594 int rc = ARM_UC_MM_ASN1_get_tag(&p, end, &len, ARM_UC_MM_ASN1_OCTET_STRING); 00595 if (rc || (len == 0)) { 00596 UC_MMGR_TRACE("KeyTable Error - get-content failed, keytable length == %" PRIu32, len); 00597 ARM_UC_SET_ERROR(err, len == 0 ? MFST_ERR_MISSING_KEYTABLE : MFST_ERR_BAD_KEYTABLE); 00598 } 00599 } 00600 if (err.error == ERR_NONE) { 00601 UC_MMGR_TRACE("KeyTable Found"); 00602 ctx->cipherText.ptr = p; 00603 ctx->cipherText.size = len; 00604 ctx->cipherText.size_max = len; 00605 ctx->psk_state = ARM_UC_MM_PSKSIG_STATE_VERIFY; 00606 } 00607 break; 00608 } 00609 case ARM_UC_MM_PSKSIG_STATE_FIND_SIG: 00610 // Wait for the find-sig to end 00611 // This is currently disabled. 00612 break; 00613 // Validate the signature 00614 case ARM_UC_MM_PSKSIG_STATE_VERIFY: { 00615 err.code = ERR_NONE; 00616 UC_MMGR_TRACE("Beginning PSK signature verification"); 00617 mbedtls_ccm_context ccm_ctx; 00618 mbedtls_ccm_init(&ccm_ctx); 00619 int rc = mbedtls_ccm_setkey(&ccm_ctx, MBEDTLS_CIPHER_ID_AES, ctx->PSK.ptr, 8 * ctx->PSK.size); 00620 if (rc) { 00621 UC_MMGR_TRACE("mbedtls_ccm_setkey failed with %d", rc); 00622 ARM_UC_SET_ERROR(err, (TWO_CC('M', 'T') << 16) + ((-rc) & 0xFFFF)); 00623 } 00624 00625 size_t tagSize = 0; 00626 switch (ctx->encryptionMode) { 00627 case MFST_CRYPT_NONE_PSK_AES128CCM_SHA256: 00628 case MFST_CRYPT_PSK_AES128CCM_SHA256: 00629 tagSize = 128 / 8; 00630 break; 00631 } 00632 00633 00634 uint8_t plaintextBuffer[ARM_UC_SHA512_SIZE + ARM_UC_AES256_KEY_SIZE + 6]; 00635 // Decrypt the key payload 00636 if (err.error == ERR_NONE) { 00637 size_t cipherTextSize = ctx->cipherText.size - tagSize; 00638 uint8_t *tagPtr = ctx->cipherText.ptr + cipherTextSize; 00639 00640 UC_MMGR_TRACE("Attempting authenticated decryption of manifest hash"); 00641 rc = mbedtls_ccm_auth_decrypt( 00642 &ccm_ctx, // Cipher context 00643 cipherTextSize, // Input size (without tag) 00644 ctx->keyTableIV.ptr, // Init vector 00645 ctx->keyTableIV.size, // Size of the init vector 00646 NULL, // Authenticated Associated Data 00647 0, // AAD length 00648 ctx->cipherText.ptr, 00649 plaintextBuffer, 00650 tagPtr, 00651 tagSize); // 00652 00653 if (rc == MBEDTLS_ERR_CCM_AUTH_FAILED) { 00654 ARM_UC_SET_ERROR(err, MFST_ERR_INVALID_SIGNATURE); 00655 } else if (rc) { 00656 UC_MMGR_TRACE("mbedtls_ccm_auth_decrypt failed with %d", rc); 00657 ARM_UC_SET_ERROR(err, (TWO_CC('M', 'T') << 16) + ((-rc) & 0xFFFF)); 00658 } 00659 } 00660 arm_uc_buffer_t fields[2]; 00661 if (err.error == ERR_NONE) { 00662 arm_uc_buffer_t buf = { 00663 .size_max = sizeof(plaintextBuffer), 00664 .size = ctx->cipherText.size - tagSize, 00665 .ptr = plaintextBuffer 00666 }; 00667 const int32_t fieldIDs[] = { 00668 ARM_UC_MM_KT_HASH, 00669 ARM_UC_MM_KT_PAYLOAD_KEY, 00670 }; 00671 const size_t nfields = sizeof(fieldIDs) / sizeof(fieldIDs[0]); 00672 UC_MMGR_TRACE("Extracting manifest hash and payload key"); 00673 // Extract the manifest hash and payload key 00674 rc = ARM_UC_mmDERParseTree( 00675 arm_uc_mmKeyTableEntry, 00676 &buf, nfields, fieldIDs, fields 00677 ); 00678 if (rc == 1 && ctx->encryptionMode == MFST_CRYPT_NONE_PSK_AES128CCM_SHA256) { 00679 rc = 0; 00680 } 00681 if (rc) { 00682 UC_MMGR_TRACE("ARM_UC_mmDERParseTree failed with %d", rc); 00683 ARM_UC_SET_ERROR(err, MFST_ERR_DER_FORMAT); 00684 } 00685 } 00686 arm_uc_buffer_t remoteDigest; 00687 if (err.error == ERR_NONE) { 00688 UC_MMGR_TRACE("Load manifest hash from manifest signature"); 00689 err = ARM_UC_mmGetManifestHash(ctx->manifest, &remoteDigest); 00690 } 00691 if (err.error == ERR_NONE) { 00692 UC_MMGR_TRACE("Comparing manifest hash and authenticated hash"); 00693 rc = ARM_UC_BinCompareCT(&fields[0], &remoteDigest); 00694 if (rc) { 00695 UC_MMGR_TRACE("Manifest hash does not match authenticated hash"); 00696 ARM_UC_SET_ERROR(err, MFST_ERR_INVALID_SIGNATURE); 00697 } 00698 } 00699 if (err.error == ERR_NONE) { 00700 ARM_UC_SET_ERROR(err, ERR_NONE); 00701 ctx->psk_state = ARM_UC_MM_PSKSIG_STATE_IDLE; 00702 } 00703 break; 00704 } 00705 case ARM_UC_MM_PSKSIG_STATE_IDLE: 00706 ARM_UC_SET_ERROR(err, ERR_NONE); 00707 // The Entry function will report success after this state exits. 00708 break; 00709 default: 00710 err = (arm_uc_error_t) {MFST_ERR_INVALID_STATE}; 00711 break; 00712 } 00713 } while (err.error == ERR_NONE && ctx->psk_state != oldState); 00714 UC_MMGR_TRACE("%s() return code: %c%c:%hu (%s)\n", 00715 __PRETTY_FUNCTION__, CC_ASCII(err.modulecc[0]), CC_ASCII(err.modulecc[1]), 00716 err.error, ARM_UC_err2Str(err)); 00717 return err; 00718 } 00719 #endif /* ARM_UC_FEATURE_MANIFEST_PSK */ 00720 /** 00721 * @brief Start signature verification. 00722 * @details This API initiates a signature verification. The actual signature verification is carried out by 00723 * 00724 * 00725 * @param[in] ctx Signature validation context. This contains all the state used by the signature validator. 00726 * @param[in] buffer A buffer containing the manifest to verify 00727 * @param[in] certBuffer A temporary storage buffer for certificate fetching 00728 * @param[in] sigIndex Index of the signature to verify. 00729 * @retval ERR_NONE on success 00730 * @retval MFST_ERR_PENDING when the validation has not completed and is waiting for external input 00731 * (e.g. certificate fetching) 00732 * @retval Another error code otherwise. 00733 */ 00734 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00735 arm_uc_error_t ARM_UC_mmValidateSignature(arm_uc_mm_validate_signature_context_t *ctx, 00736 void (*applicationEventHandler)(uintptr_t), 00737 arm_uc_buffer_t *buffer, 00738 arm_uc_buffer_t *certBuffer, 00739 uint32_t sigIndex) 00740 { 00741 UC_MMGR_TRACE("%s (%u)\n", __PRETTY_FUNCTION__, (unsigned)sigIndex); 00742 arm_uc_error_t err = {ERR_NONE}; 00743 if (ctx == NULL) { 00744 ARM_UC_SET_ERROR(err, MFST_ERR_NULL_PTR); 00745 } 00746 if (err.error == ERR_NONE) { 00747 err = ARM_UC_mmGetCryptoMode(buffer, &ctx->encryptionMode); 00748 } 00749 if (err.error == ERR_NONE) { 00750 #ifdef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK 00751 arm_uc_mmSignatureVerificationContext.callbackStorage.lock = 0; 00752 #endif 00753 arm_uc_mmSignatureVerificationContext.ctx = ctx; 00754 // Extract the certificate identifier from the manifest 00755 err = ARM_UC_mmGetCertificateId(buffer, sigIndex, &arm_uc_mmSignatureVerificationContext.ctx->fingerprint); 00756 UC_MMGR_TRACE("%s %c%c:%hu (%s)\n", "Get Certificate ID return code:", 00757 CC_ASCII(err.modulecc[0]), CC_ASCII(err.modulecc[1]), 00758 err.error, ARM_UC_err2Str(err)); 00759 } 00760 if (err.error == 0 && ctx) { 00761 // Copy all the relevant inputs into the state variable 00762 err.code = ERR_NONE; 00763 arm_uc_mmSignatureVerificationContext.ctx->manifest = buffer; 00764 arm_uc_mmSignatureVerificationContext.ctx->applicationEventHandler = applicationEventHandler; 00765 arm_uc_mmSignatureVerificationContext.ctx->pk_state = UCMM_PKSIG_STATE_FIND_CA; 00766 arm_uc_mmSignatureVerificationContext.ctx->sigIndex = sigIndex; 00767 ARM_UC_buffer_shallow_copy(&arm_uc_mmSignatureVerificationContext.ctx->cert, certBuffer); 00768 UC_MMGR_TRACE("%s Posting ARM_UC_mmVerifySignatureEntry(%" PRIi16 ")\n", __PRETTY_FUNCTION__, ARM_UC_MM_EVENT_BEGIN); 00769 ARM_UC_PostCallback(&arm_uc_mmSignatureVerificationContext.callbackStorage, ARM_UC_mmVerifySignatureEntry, 00770 ARM_UC_MM_EVENT_BEGIN); 00771 } 00772 UC_MMGR_TRACE("%s %c%c:%hu (%s)\n", __PRETTY_FUNCTION__, 00773 CC_ASCII(err.modulecc[0]), CC_ASCII(err.modulecc[1]), err.error, ARM_UC_err2Str(err)); 00774 return err; 00775 } 00776 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00777 /** 00778 * @brief Main entry point for callbacks to enter the state machine. 00779 * @details Calls the signature verification state machine. If the result is not Pending, calls the application event 00780 * handler with a result code. 00781 * Application event handler is invoked directly, not queued because this function should have minimal stack 00782 * and it should be called directly from the event queue. 00783 * @param[in] event Event to forward to the state machine 00784 */ 00785 void ARM_UC_mmVerifySignatureEntry(uintptr_t event) 00786 { 00787 UC_MMGR_TRACE("%s (%u)\n", __PRETTY_FUNCTION__, (unsigned)event); 00788 arm_uc_error_t err = {MFST_ERR_CRYPTO_MODE}; 00789 switch (arm_uc_mmSignatureVerificationContext.ctx->encryptionMode) { 00790 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00791 case MFST_CRYPT_SHA256_ECC_AES128_PSK: 00792 case MFST_CRYPT_SHA256_ECC: 00793 err = ARM_UC_mmValidateSignatureFSM(arm_uc_mmSignatureVerificationContext.ctx, event); 00794 break; 00795 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00796 #if defined(ARM_UC_FEATURE_MANIFEST_PSK) && (ARM_UC_FEATURE_MANIFEST_PSK == 1) 00797 case MFST_CRYPT_PSK_AES128CCM_SHA256: 00798 case MFST_CRYPT_NONE_PSK_AES128CCM_SHA256: 00799 err = ARM_UC_mmValidateSignaturePSKFSM(arm_uc_mmSignatureVerificationContext.ctx, event); 00800 break; 00801 #endif /* ARM_UC_FEATURE_MANIFEST_PSK */ 00802 } 00803 00804 if (err.code != ERR_NONE && err.code != MFST_ERR_PENDING) { 00805 arm_uc_mmSignatureVerificationContext.ctx->storedError = err; 00806 arm_uc_mmSignatureVerificationContext.ctx->applicationEventHandler(ARM_UC_MM_RC_ERROR); 00807 } 00808 if (err.code == ERR_NONE && arm_uc_mmSignatureVerificationContext.ctx->pk_state == UCMM_PKSIG_STATE_IDLE) { 00809 // A callback is not posted since this runs inside the scheduler 00810 arm_uc_mmSignatureVerificationContext.ctx->applicationEventHandler(ARM_UC_MM_RC_DONE); 00811 } 00812 UC_MMGR_TRACE("%s %c%c:%hu (%s)\n", __PRETTY_FUNCTION__, 00813 CC_ASCII(err.modulecc[0]), CC_ASCII(err.modulecc[1]), err.error, ARM_UC_err2Str(err)); 00814 } 00815 00816 #if defined(ARM_UC_FEATURE_MANIFEST_PSK) && (ARM_UC_FEATURE_MANIFEST_PSK == 1) 00817 arm_uc_error_t ARM_UC_mmVerifySignaturePSK(arm_uc_mm_validate_signature_context_t *ctx, 00818 void (*applicationEventHandler)(uintptr_t), 00819 arm_uc_buffer_t *buffer, 00820 uint32_t sigIndex) 00821 { 00822 UC_MMGR_TRACE("%s (%u)\n", __PRETTY_FUNCTION__, (unsigned)sigIndex); 00823 arm_uc_error_t err = {ERR_NONE}; 00824 // Parse the manifest for the hash, the signature (PSK IV) and the certificate list 00825 arm_uc_buffer_t mac; 00826 arm_uc_buffer_t fields[3] = {0}; 00827 const int32_t ResourceSignatureIDs[] = { 00828 ARM_UC_MM_DER_MFST_ENC_ENUM, 00829 ARM_UC_MM_DER_SIG_MACS, 00830 }; 00831 const int32_t MacBlockIDs[] = { 00832 ARM_UC_MM_DER_SIG_MAC_PSKID, 00833 ARM_UC_MM_DER_SIG_MAC_KEYTABLE_IV, 00834 ARM_UC_MM_DER_SIG_MAC_KEYTABLE_REF, 00835 }; 00836 // ctx validity check 00837 if (ctx == NULL) { 00838 ARM_UC_SET_ERROR(err, MFST_ERR_NULL_PTR); 00839 } else { 00840 arm_uc_mmSignatureVerificationContext.ctx = ctx; 00841 } 00842 if (err.error == ERR_NONE) { 00843 // Get the content of the ResourceSignature. 00844 int rc = ARM_UC_mmDERGetSignedResourceValues(buffer, 00845 sizeof(ResourceSignatureIDs) / sizeof(ResourceSignatureIDs[0]), 00846 ResourceSignatureIDs, 00847 fields); 00848 if (rc) { 00849 ARM_UC_SET_ERROR(err, MFST_ERR_DER_FORMAT); 00850 } 00851 } 00852 if (err.error == ERR_NONE) { 00853 ctx->encryptionMode = ARM_UC_mmDerBuf2Uint(&fields[0]); 00854 int rc = ARM_UC_mmDERGetSequenceElement(&fields[1], sigIndex, &mac); 00855 if (rc) { 00856 ARM_UC_SET_ERROR(err, MFST_ERR_DER_FORMAT); 00857 } 00858 if (mac.ptr == NULL) { 00859 ARM_UC_SET_ERROR(err, ARM_UC_DP_ERR_NO_MORE_ELEMENTS); 00860 } 00861 } 00862 if (err.error == ERR_NONE) { 00863 // Extract the MAC parameters 00864 int rc = ARM_UC_mmDERParseTree(&arm_uc_mmMacs[0], 00865 &mac, 00866 sizeof(MacBlockIDs) / sizeof(MacBlockIDs[0]), 00867 MacBlockIDs, 00868 fields); 00869 if (rc) { 00870 ARM_UC_SET_ERROR(err, MFST_ERR_DER_FORMAT); 00871 } 00872 } 00873 if (err.error == ERR_NONE) { 00874 ARM_UC_buffer_shallow_copy(&ctx->PSKid, &fields[0]); 00875 ARM_UC_buffer_shallow_copy(&ctx->keyTableIV, &fields[1]); 00876 ARM_UC_buffer_shallow_copy(&ctx->keyTableRef, &fields[2]); 00877 if (ctx->keyTableRef.size == 0) { 00878 ARM_UC_SET_ERROR(err, MFST_ERR_MISSING_KEYTABLE); 00879 } else if (ctx->keyTableIV.size < 7 || ctx->keyTableIV.size > 13) { 00880 ARM_UC_SET_ERROR(err, MFST_ERR_CTR_IV_SIZE); 00881 } 00882 } 00883 if (err.error == ERR_NONE && ctx) { 00884 // Copy all the relevant inputs into the state variable 00885 err.code = ERR_NONE; 00886 ctx->manifest = buffer; 00887 ctx->applicationEventHandler = applicationEventHandler; 00888 ctx->psk_state = ARM_UC_MM_PSKSIG_STATE_FIND_PSK; 00889 ctx->sigIndex = sigIndex; 00890 UC_MMGR_TRACE("%s Posting ARM_UC_mmVerifySignatureEntry(%d)\n", __PRETTY_FUNCTION__, ARM_UC_MM_EVENT_BEGIN); 00891 int rc = ARM_UC_PostCallback(&arm_uc_mmSignatureVerificationContext.callbackStorage, ARM_UC_mmVerifySignatureEntry, 00892 ARM_UC_MM_EVENT_BEGIN); 00893 if (!rc) { 00894 ARM_UC_SET_ERROR(err, MFST_ERR_NOT_READY); 00895 } 00896 } 00897 UC_MMGR_TRACE("< %s %c%c:%hu (%s)\n", __PRETTY_FUNCTION__, 00898 CC_ASCII(err.modulecc[0]), CC_ASCII(err.modulecc[1]), err.error, ARM_UC_err2Str(err)); 00899 return err; 00900 } 00901 #endif /* ARM_UC_FEATURE_MANIFEST_PSK */
Generated on Tue Jul 12 2022 20:20:57 by
