Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_uc_metadata_header_v2.c Source File

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                 input_buf.size_max = sizeof(arm_uc_hash_t);
00150                 input_buf.size = sizeof(arm_uc_hash_t);
00151                 input_buf.ptr = (uint8_t *) &input[ARM_UC_EXTERNAL_HMAC_OFFSET_V2];
00152 
00153                 int diff = ARM_UC_BinCompareCT(&input_buf, &output_buf);
00154 
00155                 if (diff == 0)
00156                 {
00157                     details->version = arm_uc_parse_uint64(&input[ARM_UC_EXTERNAL_FIRMWARE_VERSION_OFFSET_V2]);
00158                     details->size = arm_uc_parse_uint64(&input[ARM_UC_EXTERNAL_FIRMWARE_SIZE_OFFSET_V2]);
00159 
00160                     memcpy(details->hash,
00161                            &input[ARM_UC_EXTERNAL_FIRMWARE_HASH_OFFSET_V2],
00162                            ARM_UC_SHA256_SIZE);
00163 
00164                     memcpy(details->campaign,
00165                            &input[ARM_UC_EXTERNAL_CAMPAIGN_OFFSET_V2],
00166                            ARM_UC_GUID_SIZE);
00167 
00168                     details->signatureSize = 0;
00169 
00170                     result.code = ERR_NONE;
00171                 }
00172             }
00173         }
00174     }
00175 
00176     return result;
00177 }
00178 
00179 arm_uc_error_t arm_uc_create_external_header_v2(const arm_uc_firmware_details_t* input,
00180                                                 arm_uc_buffer_t* output)
00181 {
00182     arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
00183 
00184     if (input &&
00185         output &&
00186         (output->size_max >= ARM_UC_EXTERNAL_HEADER_SIZE_V2))
00187     {
00188         /* zero buffer and reset size*/
00189         memset(output->ptr, 0, ARM_UC_EXTERNAL_HEADER_SIZE_V2);
00190         output->size = 0;
00191 
00192         /* MSB encode header magic and version */
00193         arm_uc_write_uint32(&output->ptr[0],
00194                             ARM_UC_EXTERNAL_HEADER_MAGIC_V2);
00195         arm_uc_write_uint32(&output->ptr[4],
00196                             ARM_UC_EXTERNAL_HEADER_VERSION_V2);
00197 
00198         /* MSB encode firmware version */
00199         arm_uc_write_uint64(&output->ptr[ARM_UC_EXTERNAL_FIRMWARE_VERSION_OFFSET_V2],
00200                             input->version);
00201 
00202         /* MSB encode firmware size to header */
00203         arm_uc_write_uint64(&output->ptr[ARM_UC_EXTERNAL_FIRMWARE_SIZE_OFFSET_V2],
00204                             input->size);
00205 
00206         /* raw copy firmware hash to header */
00207         memcpy(&output->ptr[ARM_UC_EXTERNAL_FIRMWARE_HASH_OFFSET_V2],
00208                input->hash,
00209                ARM_UC_SHA256_SIZE);
00210 
00211         /* MSB encode payload size to header */
00212         arm_uc_write_uint64(&output->ptr[ARM_UC_EXTERNAL_PAYLOAD_SIZE_OFFSET_V2],
00213                             input->size);
00214 
00215         /* raw copy payload hash to header */
00216         memcpy(&output->ptr[ARM_UC_EXTERNAL_PAYLOAD_HASH_OFFSET_V2],
00217                input->hash,
00218                ARM_UC_SHA256_SIZE);
00219 
00220         /* raw copy campaign ID to header */
00221         memcpy(&output->ptr[ARM_UC_EXTERNAL_CAMPAIGN_OFFSET_V2],
00222                input->campaign,
00223                ARM_UC_GUID_SIZE);
00224 
00225         /* read 256 bit device key */
00226         uint8_t key_buf[ARM_UC_DEVICE_KEY_SIZE] = { 0 };
00227         arm_uc_buffer_t key = {
00228             .size_max = ARM_UC_DEVICE_KEY_SIZE,
00229             .size = 0,
00230             .ptr = key_buf
00231         };
00232 
00233         arm_uc_error_t status = ARM_UC_getDeviceKey256Bit(&key);
00234 
00235         if (status.error == ERR_NONE)
00236         {
00237             arm_uc_buffer_t input_buf = {
00238                 .size_max = ARM_UC_EXTERNAL_HMAC_OFFSET_V2,
00239                 .size = ARM_UC_EXTERNAL_HMAC_OFFSET_V2,
00240                 .ptr = output->ptr
00241             };
00242             arm_uc_buffer_t output_buf = {
00243                 .size_max = sizeof(arm_uc_hash_t),
00244                 .size = sizeof(arm_uc_hash_t),
00245                 .ptr = &output->ptr[ARM_UC_EXTERNAL_HMAC_OFFSET_V2]
00246             };
00247 
00248             /* calculate header HMAC */
00249             result = ARM_UC_cryptoHMACSHA256(&key, &input_buf, &output_buf);
00250             if (result.error == ERR_NONE)
00251             {
00252                 /* set output size */
00253                 output->size = ARM_UC_EXTERNAL_HEADER_SIZE_V2;
00254             }
00255         }
00256     }
00257 
00258     return result;
00259 }