Skip to content

Commit

Permalink
Add CRC32 support to dynamic network management
Browse files Browse the repository at this point in the history
  • Loading branch information
cedelavergne-ledger committed Sep 23, 2024
1 parent 90439e3 commit 4b91143
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/network_dynamic.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#endif

#define WITH_TAG_SIGNATURE
// #define WITH_TAG_CRC32

#define MAX_STATIC_BUFFER_SIZE 32 // TODO: Adjust with max signature size
#define NETWORK_TLV_VERSION 0x01
Expand All @@ -26,6 +27,7 @@ enum {
TAG_NETWORK_TICKER = 0x13,
TAG_NETWORK_ICON = 0x14,
TAG_SIGNATURE = 0x21,
TAG_CRC32 = 0x22,
};

typedef struct network_payload_s {
Expand All @@ -45,6 +47,12 @@ typedef struct {
cx_sha256_t hash_ctx;
} s_sig_ctx;
#endif
#ifdef WITH_TAG_CRC32
typedef struct {
uint32_t calculated;
uint32_t received;
} crc32_ctx_t;
#endif

// Global structure to temporary store the network payload APDU
static network_payload_t g_network_payload = {0};
Expand Down Expand Up @@ -273,6 +281,36 @@ static bool verify_signature(s_sig_ctx *sig_ctx) {
}
#endif

#ifdef WITH_TAG_CRC32
/**
* Parse the CRC32 value.
*
* @param[in] field_len Length of the field value
* @param[in] offset Offset in the received buffer
* @param[out] crc32_received CRC32 value received
* @return APDU Response code
*/
static uint32_t parse_crc32(uint32_t field_len, uint32_t offset, uint32_t *crc32_received) {
if (field_len != 4) {
PRINTF("TAG_CRC32 Size mismatch!\n");
return APDU_RESPONSE_INSUFFICIENT_MEMORY;
}
*crc32_received = U4BE(g_network_payload.buf, offset);
return APDU_RESPONSE_OK;
}
/**
* Verify the CRC32
*
* Verify payload integrity
*
* @param[in] crc32_ctx CRC32 context
* @return whether it was successful
*/
static bool verify_crc32(crc32_ctx_t *crc32_ctx) {
return crc32_ctx->calculated == crc32_ctx->received;
}
#endif

/**
* Parse the TLV payload containing the Network configuration.
*
Expand All @@ -290,6 +328,9 @@ static uint32_t parse_tlv(void) {
#ifdef WITH_TAG_SIGNATURE
s_sig_ctx sig_ctx = {0};
#endif
#ifdef WITH_TAG_CRC32
crc32_ctx_t crc32_ctx = {0};
#endif

#ifdef WITH_TAG_SIGNATURE
// Initialize the hash context
Expand Down Expand Up @@ -325,6 +366,11 @@ static uint32_t parse_tlv(void) {
sw = parse_signature(field_len, offset, &sig_ctx);
#endif
break;
#ifdef WITH_TAG_CRC32
case TAG_CRC32:
sw = parse_crc32(field_len, offset, &crc32_ctx.received);
break;
#endif
default:
PRINTF("Unknown tag: %d\n", field_tag);
sw = APDU_RESPONSE_INVALID_DATA;
Expand All @@ -340,6 +386,13 @@ static uint32_t parse_tlv(void) {
(offset - tag_start_off),
(cx_hash_t *) &sig_ctx.hash_ctx);
}
#endif
#ifdef WITH_TAG_CRC32
if (field_tag != TAG_CRC32) { // crc32 wasn't computed on itself
crc32_ctx.calculated = cx_crc32_update(crc32_ctx.calculated,
g_network_payload.buf + tag_start_off,
(offset - tag_start_off));
}
#endif
}
if (sw == APDU_RESPONSE_OK) {
Expand All @@ -348,6 +401,12 @@ static uint32_t parse_tlv(void) {
PRINTF("Signature verification failed!\n");
sw = APDU_RESPONSE_INVALID_DATA;
}
#endif
#ifdef WITH_TAG_CRC32
if (verify_crc32(&crc32_ctx) == false) {
PRINTF("CRC32 verification failed\n");
sw = APDU_RESPONSE_INVALID_DATA;
}
#endif
}
if (sw == APDU_RESPONSE_OK) {
Expand Down

0 comments on commit 4b91143

Please sign in to comment.