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