#include "set_firmware.h" #include size_t setp_fw_begin_encode(const setp_fw_begin_t *value, uint8_t *out, size_t capacity) { size_t total; if ((value == NULL) || (out == NULL) || (value->block_size == 0U) || (value->block_size > SETP_MAX_PAYLOAD - SETP_FW_DATA_HEADER_SIZE) || ((value->signature_length != 0U) && (value->signature == NULL))) { return 0U; } total = (size_t)SETP_FW_BEGIN_FIXED_SIZE + value->signature_length; if ((total > SETP_MAX_PAYLOAD) || (capacity < total) || (((value->flags & SETP_FW_FLAG_SIGNED) != 0U) && (value->signature_length == 0U))) { return 0U; } setp_put_u32(&out[0], value->image_size); setp_put_u32(&out[4], value->image_crc32); setp_put_u32(&out[8], value->image_version); setp_put_u32(&out[12], value->base_address); out[16] = value->slot; out[17] = value->flags; setp_put_u16(&out[18], value->block_size); (void)memcpy(&out[20], value->sha256, SETP_SHA256_SIZE); setp_put_u32(&out[52], value->signing_key_id); setp_put_u16(&out[56], value->signature_length); if (value->signature_length != 0U) { (void)memcpy(&out[SETP_FW_BEGIN_FIXED_SIZE], value->signature, value->signature_length); } return total; } bool setp_fw_begin_decode(const uint8_t *payload, uint16_t length, setp_fw_begin_t *out) { uint16_t signature_length; if ((payload == NULL) || (out == NULL) || (length < SETP_FW_BEGIN_FIXED_SIZE)) { return false; } out->image_size = setp_get_u32(&payload[0]); out->image_crc32 = setp_get_u32(&payload[4]); out->image_version = setp_get_u32(&payload[8]); out->base_address = setp_get_u32(&payload[12]); out->slot = payload[16]; out->flags = payload[17]; out->block_size = setp_get_u16(&payload[18]); (void)memcpy(out->sha256, &payload[20], SETP_SHA256_SIZE); out->signing_key_id = setp_get_u32(&payload[52]); signature_length = setp_get_u16(&payload[56]); if (length != SETP_FW_BEGIN_FIXED_SIZE + signature_length) { return false; } out->signature_length = signature_length; out->signature = signature_length != 0U ? &payload[SETP_FW_BEGIN_FIXED_SIZE] : NULL; return (out->block_size != 0U) && (out->block_size <= SETP_MAX_PAYLOAD - SETP_FW_DATA_HEADER_SIZE) && (((out->flags & SETP_FW_FLAG_SIGNED) == 0U) || (signature_length != 0U)); } size_t setp_fw_data_encode(uint32_t offset, uint16_t flags, const uint8_t *data, uint16_t data_length, uint8_t *out, size_t capacity) { size_t total = (size_t)SETP_FW_DATA_HEADER_SIZE + data_length; if ((data == NULL) || (out == NULL) || (data_length == 0U) || (total > SETP_MAX_PAYLOAD) || (capacity < total)) { return 0U; } setp_put_u32(&out[0], offset); setp_put_u16(&out[4], data_length); setp_put_u16(&out[6], flags); setp_put_u32(&out[8], setp_crc32(data, data_length)); (void)memcpy(&out[SETP_FW_DATA_HEADER_SIZE], data, data_length); return total; } bool setp_fw_data_decode(const uint8_t *payload, uint16_t length, setp_fw_data_t *out) { uint16_t data_length; if ((payload == NULL) || (out == NULL) || (length < SETP_FW_DATA_HEADER_SIZE)) { return false; } data_length = setp_get_u16(&payload[4]); if ((data_length == 0U) || (length != SETP_FW_DATA_HEADER_SIZE + data_length)) { return false; } out->offset = setp_get_u32(&payload[0]); out->data_length = data_length; out->flags = setp_get_u16(&payload[6]); out->data_crc32 = setp_get_u32(&payload[8]); out->data = &payload[SETP_FW_DATA_HEADER_SIZE]; return setp_crc32(out->data, out->data_length) == out->data_crc32; } size_t setp_fw_end_encode(const setp_fw_end_t *value, uint8_t *out, size_t capacity) { if ((value == NULL) || (out == NULL) || (capacity < SETP_FW_END_SIZE)) { return 0U; } setp_put_u32(&out[0], value->image_size); setp_put_u32(&out[4], value->image_crc32); (void)memcpy(&out[8], value->sha256, SETP_SHA256_SIZE); return SETP_FW_END_SIZE; } bool setp_fw_end_decode(const uint8_t *payload, uint16_t length, setp_fw_end_t *out) { if ((payload == NULL) || (out == NULL) || (length != SETP_FW_END_SIZE)) { return false; } out->image_size = setp_get_u32(&payload[0]); out->image_crc32 = setp_get_u32(&payload[4]); (void)memcpy(out->sha256, &payload[8], SETP_SHA256_SIZE); return true; } size_t setp_fw_status_encode(const setp_fw_status_t *value, uint8_t *out, size_t capacity) { if ((value == NULL) || (out == NULL) || (capacity < SETP_FW_STATUS_SIZE)) { return 0U; } out[0] = value->state; out[1] = value->active_slot; setp_put_u16(&out[2], value->max_block_size); setp_put_u32(&out[4], value->next_offset); setp_put_u32(&out[8], value->image_size); setp_put_u16(&out[12], value->last_error); setp_put_u16(&out[14], value->flags); return SETP_FW_STATUS_SIZE; } bool setp_fw_status_decode(const uint8_t *payload, uint16_t length, setp_fw_status_t *out) { if ((payload == NULL) || (out == NULL) || (length != SETP_FW_STATUS_SIZE)) { return false; } out->state = payload[0]; out->active_slot = payload[1]; out->max_block_size = setp_get_u16(&payload[2]); out->next_offset = setp_get_u32(&payload[4]); out->image_size = setp_get_u32(&payload[8]); out->last_error = setp_get_u16(&payload[12]); out->flags = setp_get_u16(&payload[14]); return true; } size_t setp_fw_manifest_encode(const setp_fw_begin_t *value, uint8_t *out, size_t capacity) { static const uint8_t prefix[8] = { 'S', 'E', 'T', 'P', 'F', 'W', '2', 0U }; if ((value == NULL) || (out == NULL) || (capacity < SETP_FW_MANIFEST_SIZE)) { return 0U; } (void)memcpy(out, prefix, sizeof(prefix)); setp_put_u32(&out[8], value->image_size); setp_put_u32(&out[12], value->image_crc32); setp_put_u32(&out[16], value->image_version); setp_put_u32(&out[20], value->base_address); out[24] = value->slot; (void)memcpy(&out[25], value->sha256, SETP_SHA256_SIZE); return SETP_FW_MANIFEST_SIZE; }