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_metadata_header_v2.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 "update-client-metadata-header/arm_uc_metadata_header_v2.h" 00020 #include "update-client-metadata-header/arm_uc_buffer_utilities.h" 00021 #include <string.h> 00022 00023 extern arm_uc_error_t ARM_UC_cryptoHMACSHA256(arm_uc_buffer_t *key, arm_uc_buffer_t *input, arm_uc_buffer_t *output); 00024 00025 arm_uc_error_t ARM_UC_getDeviceKey256Bit(arm_uc_buffer_t *output) 00026 { 00027 arm_uc_error_t result = (arm_uc_error_t) { ARM_UC_CU_ERR_INVALID_PARAMETER }; 00028 00029 if (output->size_max >= ARM_UC_DEVICE_KEY_SIZE) { 00030 int8_t rv = mbed_cloud_client_get_rot_128bit(output->ptr, output->size_max); 00031 if (rv == 0) { 00032 arm_uc_buffer_t input = { 00033 .size_max = ARM_UC_DEVICE_HMAC_KEY_SIZE, 00034 .size = ARM_UC_DEVICE_HMAC_KEY_SIZE, 00035 .ptr = (uint8_t *) &ARM_UC_DEVICE_HMAC_KEY 00036 }; 00037 output->size = ARM_UC_ROT_SIZE; 00038 #if defined(PAL_DEVICE_KEY_DERIVATION_BACKWARD_COMPATIBILITY_CALC) && \ 00039 (PAL_DEVICE_KEY_DERIVATION_BACKWARD_COMPATIBILITY_CALC == 1) 00040 result = ARM_UC_cryptoHMACSHA256(&input, output, output); 00041 #else 00042 result = ARM_UC_cryptoHMACSHA256(output, &input, output); 00043 #endif 00044 } 00045 } 00046 00047 if (result.code != ERR_NONE) { 00048 /* clear buffer on failure so we don't leak the rot */ 00049 memset(output->ptr, 0, output->size_max); 00050 } 00051 00052 return result; 00053 } 00054 00055 arm_uc_error_t arm_uc_parse_internal_header_v2(const uint8_t *input, 00056 arm_uc_firmware_details_t *details) 00057 { 00058 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00059 00060 if (input && details) { 00061 /* calculate CRC */ 00062 uint32_t calculatedChecksum = arm_uc_crc32(input, ARM_UC_INTERNAL_HEADER_CRC_OFFSET_V2); 00063 00064 /* read out CRC */ 00065 uint32_t temp32 = arm_uc_parse_uint32(&input[ARM_UC_INTERNAL_HEADER_CRC_OFFSET_V2]); 00066 00067 if (temp32 == calculatedChecksum) { 00068 /* parse content */ 00069 details->version = arm_uc_parse_uint64(&input[ARM_UC_INTERNAL_FIRMWARE_VERSION_OFFSET_V2]); 00070 details->size = arm_uc_parse_uint64(&input[ARM_UC_INTERNAL_FIRMWARE_SIZE_OFFSET_V2]); 00071 00072 memcpy(details->hash, 00073 &input[ARM_UC_INTERNAL_FIRMWARE_HASH_OFFSET_V2], 00074 ARM_UC_SHA256_SIZE); 00075 00076 memcpy(details->campaign, 00077 &input[ARM_UC_INTERNAL_CAMPAIGN_OFFSET_V2], 00078 ARM_UC_GUID_SIZE); 00079 00080 /* set result */ 00081 result.code = ERR_NONE; 00082 } 00083 } 00084 00085 return result; 00086 } 00087 00088 arm_uc_error_t arm_uc_create_internal_header_v2(const arm_uc_firmware_details_t *input, 00089 arm_uc_buffer_t *output) 00090 { 00091 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00092 00093 if (input && 00094 output && 00095 (output->size_max >= ARM_UC_INTERNAL_HEADER_SIZE_V2)) { 00096 /* zero buffer */ 00097 memset(output->ptr, 0, ARM_UC_INTERNAL_HEADER_SIZE_V2); 00098 00099 /* MSB encode header magic and version */ 00100 arm_uc_write_uint32(&output->ptr[0], 00101 ARM_UC_INTERNAL_HEADER_MAGIC_V2); 00102 arm_uc_write_uint32(&output->ptr[4], 00103 ARM_UC_INTERNAL_HEADER_VERSION_V2); 00104 00105 /* MSB encode firmware version */ 00106 arm_uc_write_uint64(&output->ptr[ARM_UC_INTERNAL_FIRMWARE_VERSION_OFFSET_V2], 00107 input->version); 00108 00109 /* MSB encode firmware size to header */ 00110 arm_uc_write_uint64(&output->ptr[ARM_UC_INTERNAL_FIRMWARE_SIZE_OFFSET_V2], 00111 input->size); 00112 00113 /* raw copy firmware hash to header */ 00114 memcpy(&output->ptr[ARM_UC_INTERNAL_FIRMWARE_HASH_OFFSET_V2], 00115 input->hash, 00116 ARM_UC_SHA256_SIZE); 00117 00118 /* raw copy campaign ID to header */ 00119 memcpy(&output->ptr[ARM_UC_INTERNAL_CAMPAIGN_OFFSET_V2], 00120 input->campaign, 00121 ARM_UC_GUID_SIZE); 00122 00123 /* calculate CRC */ 00124 uint32_t checksum = arm_uc_crc32(output->ptr, 00125 ARM_UC_INTERNAL_HEADER_CRC_OFFSET_V2); 00126 00127 /* MSB encode checksum to header */ 00128 arm_uc_write_uint32(&output->ptr[ARM_UC_INTERNAL_HEADER_CRC_OFFSET_V2], 00129 checksum); 00130 00131 /* set output size */ 00132 output->size = ARM_UC_INTERNAL_HEADER_SIZE_V2; 00133 00134 /* set error code */ 00135 result.code = ERR_NONE; 00136 } 00137 00138 return result; 00139 } 00140 00141 arm_uc_error_t arm_uc_parse_external_header_v2(const uint8_t *input, 00142 arm_uc_firmware_details_t *details) 00143 { 00144 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00145 00146 if (input && details) { 00147 00148 /* read 128 bit root-of-trust */ 00149 uint8_t key_buf[ARM_UC_DEVICE_KEY_SIZE] = { 0 }; 00150 arm_uc_buffer_t key = { 00151 .size_max = ARM_UC_DEVICE_KEY_SIZE, 00152 .size = 0, 00153 .ptr = key_buf 00154 }; 00155 arm_uc_error_t status = ARM_UC_getDeviceKey256Bit(&key); 00156 00157 if (status.error == ERR_NONE) { 00158 arm_uc_buffer_t input_buf = { 00159 .size_max = ARM_UC_EXTERNAL_HMAC_OFFSET_V2, 00160 .size = ARM_UC_EXTERNAL_HMAC_OFFSET_V2, 00161 .ptr = (uint8_t *) input 00162 }; 00163 arm_uc_hash_t hmac = { 0 }; 00164 arm_uc_buffer_t output_buf = { 00165 .size_max = sizeof(arm_uc_hash_t), 00166 .size = sizeof(arm_uc_hash_t), 00167 .ptr = (uint8_t *) &hmac 00168 }; 00169 00170 /* calculate header HMAC */ 00171 status = ARM_UC_cryptoHMACSHA256(&key, &input_buf, &output_buf); 00172 00173 if (status.error == ERR_NONE) { 00174 input_buf.size_max = sizeof(arm_uc_hash_t); 00175 input_buf.size = sizeof(arm_uc_hash_t); 00176 input_buf.ptr = (uint8_t *) &input[ARM_UC_EXTERNAL_HMAC_OFFSET_V2]; 00177 00178 int diff = ARM_UC_BinCompareCT(&input_buf, &output_buf); 00179 00180 if (diff == 0) { 00181 details->version = arm_uc_parse_uint64(&input[ARM_UC_EXTERNAL_FIRMWARE_VERSION_OFFSET_V2]); 00182 details->size = arm_uc_parse_uint64(&input[ARM_UC_EXTERNAL_FIRMWARE_SIZE_OFFSET_V2]); 00183 00184 memcpy(details->hash, 00185 &input[ARM_UC_EXTERNAL_FIRMWARE_HASH_OFFSET_V2], 00186 ARM_UC_SHA256_SIZE); 00187 00188 memcpy(details->campaign, 00189 &input[ARM_UC_EXTERNAL_CAMPAIGN_OFFSET_V2], 00190 ARM_UC_GUID_SIZE); 00191 00192 details->signatureSize = 0; 00193 00194 result.code = ERR_NONE; 00195 } 00196 } 00197 } 00198 } 00199 00200 return result; 00201 } 00202 00203 arm_uc_error_t arm_uc_create_external_header_v2(const arm_uc_firmware_details_t *input, 00204 arm_uc_buffer_t *output) 00205 { 00206 arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER }; 00207 00208 if (input && 00209 output && 00210 (output->size_max >= ARM_UC_EXTERNAL_HEADER_SIZE_V2)) { 00211 /* zero buffer and reset size*/ 00212 memset(output->ptr, 0, ARM_UC_EXTERNAL_HEADER_SIZE_V2); 00213 output->size = 0; 00214 00215 /* MSB encode header magic and version */ 00216 arm_uc_write_uint32(&output->ptr[0], 00217 ARM_UC_EXTERNAL_HEADER_MAGIC_V2); 00218 arm_uc_write_uint32(&output->ptr[4], 00219 ARM_UC_EXTERNAL_HEADER_VERSION_V2); 00220 00221 /* MSB encode firmware version */ 00222 arm_uc_write_uint64(&output->ptr[ARM_UC_EXTERNAL_FIRMWARE_VERSION_OFFSET_V2], 00223 input->version); 00224 00225 /* MSB encode firmware size to header */ 00226 arm_uc_write_uint64(&output->ptr[ARM_UC_EXTERNAL_FIRMWARE_SIZE_OFFSET_V2], 00227 input->size); 00228 00229 /* raw copy firmware hash to header */ 00230 memcpy(&output->ptr[ARM_UC_EXTERNAL_FIRMWARE_HASH_OFFSET_V2], 00231 input->hash, 00232 ARM_UC_SHA256_SIZE); 00233 00234 /* MSB encode payload size to header */ 00235 arm_uc_write_uint64(&output->ptr[ARM_UC_EXTERNAL_PAYLOAD_SIZE_OFFSET_V2], 00236 input->size); 00237 00238 /* raw copy payload hash to header */ 00239 memcpy(&output->ptr[ARM_UC_EXTERNAL_PAYLOAD_HASH_OFFSET_V2], 00240 input->hash, 00241 ARM_UC_SHA256_SIZE); 00242 00243 /* raw copy campaign ID to header */ 00244 memcpy(&output->ptr[ARM_UC_EXTERNAL_CAMPAIGN_OFFSET_V2], 00245 input->campaign, 00246 ARM_UC_GUID_SIZE); 00247 00248 /* read 256 bit device key */ 00249 uint8_t key_buf[ARM_UC_DEVICE_KEY_SIZE] = { 0 }; 00250 arm_uc_buffer_t key = { 00251 .size_max = ARM_UC_DEVICE_KEY_SIZE, 00252 .size = 0, 00253 .ptr = key_buf 00254 }; 00255 00256 arm_uc_error_t status = ARM_UC_getDeviceKey256Bit(&key); 00257 00258 if (status.error == ERR_NONE) { 00259 arm_uc_buffer_t input_buf = { 00260 .size_max = ARM_UC_EXTERNAL_HMAC_OFFSET_V2, 00261 .size = ARM_UC_EXTERNAL_HMAC_OFFSET_V2, 00262 .ptr = output->ptr 00263 }; 00264 arm_uc_buffer_t output_buf = { 00265 .size_max = sizeof(arm_uc_hash_t), 00266 .size = sizeof(arm_uc_hash_t), 00267 .ptr = &output->ptr[ARM_UC_EXTERNAL_HMAC_OFFSET_V2] 00268 }; 00269 00270 /* calculate header HMAC */ 00271 result = ARM_UC_cryptoHMACSHA256(&key, &input_buf, &output_buf); 00272 if (result.error == ERR_NONE) { 00273 /* set output size */ 00274 output->size = ARM_UC_EXTERNAL_HEADER_SIZE_V2; 00275 } 00276 } 00277 } 00278 00279 return result; 00280 }
Generated on Tue Jul 12 2022 20:20:57 by
