From f88e786c04a4b408083eb52987dc65ed976276ed Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 13 Mar 2024 17:16:35 +0100 Subject: [PATCH] Changed ASN1 calls for easier calls. Signed-off-by: Pol Henarejos --- src/asn1.c | 55 ++++++++++++++++++++++++++++++++++++++------------- src/asn1.h | 19 ++++++++++++------ src/eac.c | 13 +++++++++--- src/fs/file.c | 30 +++++++++++++++++----------- 4 files changed, 82 insertions(+), 35 deletions(-) diff --git a/src/asn1.c b/src/asn1.c index b114d7b..a08c3d6 100644 --- a/src/asn1.c +++ b/src/asn1.c @@ -15,8 +15,40 @@ * along with this program. If not, see . */ +#include "pico_keys.h" #include "asn1.h" +int asn1_ctx_init(uint8_t *data, uint16_t len, asn1_ctx_t *ctx) { + if (!ctx) { + return CCID_ERR_NULL_PARAM; + } + ctx->data = data; + ctx->len = 0; + return CCID_OK; +} + +int asn1_ctx_clear(asn1_ctx_t *ctx) { + ctx->data = NULL; + ctx->len = 0; + return CCID_OK; +} + +uint16_t asn1_len(asn1_ctx_t *ctx) { + if (ctx->data && ctx->len > 0) { + return ctx->len; + } + return 0; +} + +uint32_t asn1_get_uint(asn1_ctx_t *ctx) { + uint32_t d = ctx->data[0]; + for (uint8_t lt = 1; lt < ctx->len; lt++) { + d <<= 8; + d |= ctx->data[lt]; + } + return d; +} + uint16_t asn1_len_tag(uint16_t tag, uint16_t len) { uint16_t ret = 1 + format_tlv_len(len, NULL) + len; if (tag > 0x00ff) { @@ -47,8 +79,7 @@ uint8_t format_tlv_len(uint16_t len, uint8_t *out) { return 3; } -int walk_tlv(const uint8_t *cdata, - uint16_t cdata_len, +int walk_tlv(const asn1_ctx_t *ctxi, uint8_t **p, uint16_t *tag, uint16_t *tag_len, @@ -57,9 +88,9 @@ int walk_tlv(const uint8_t *cdata, return 0; } if (!*p) { - *p = (uint8_t *) cdata; + *p = (uint8_t *) ctxi->data; } - if (*p - cdata >= cdata_len) { + if (*p - ctxi->data >= ctxi->len) { return 0; } uint16_t tg = 0x0; @@ -90,22 +121,18 @@ int walk_tlv(const uint8_t *cdata, return 1; } -bool asn1_find_tag(const uint8_t *data, - uint16_t data_len, +bool asn1_find_tag(const asn1_ctx_t *ctxi, uint16_t itag, - uint16_t *tag_len, - uint8_t **tag_data) { + asn1_ctx_t *ctxo) { uint16_t tag = 0x0; uint8_t *p = NULL; uint8_t *tdata = NULL; uint16_t tlen = 0; - while (walk_tlv(data, data_len, &p, &tag, &tlen, &tdata)) { + while (walk_tlv(ctxi, &p, &tag, &tlen, &tdata)) { if (itag == tag) { - if (tag_data != NULL) { - *tag_data = tdata; - } - if (tag_len != NULL) { - *tag_len = tlen; + if (ctxo != NULL) { + ctxo->data = tdata; + ctxo->len = tlen; } return true; } diff --git a/src/asn1.h b/src/asn1.h index 474cb6d..3d4c5e1 100644 --- a/src/asn1.h +++ b/src/asn1.h @@ -26,18 +26,25 @@ #include #endif -extern int walk_tlv(const uint8_t *cdata, - uint16_t cdata_len, +typedef struct asn1_ctx { + uint8_t *data; + uint16_t len; +} asn1_ctx_t; + +extern int asn1_ctx_init(uint8_t *, uint16_t, asn1_ctx_t *); +extern int asn1_ctx_clear(asn1_ctx_t *ctx); +extern uint16_t asn1_len(asn1_ctx_t *ctx); +extern uint32_t asn1_get_uint(asn1_ctx_t *ctx); + +extern int walk_tlv(const asn1_ctx_t *ctxi, uint8_t **p, uint16_t *tag, uint16_t *tag_len, uint8_t **data); extern uint8_t format_tlv_len(uint16_t len, uint8_t *out); -extern bool asn1_find_tag(const uint8_t *data, - uint16_t data_len, +extern bool asn1_find_tag(const asn1_ctx_t *ctxi, uint16_t itag, - uint16_t *tag_len, - uint8_t **tag_data); + asn1_ctx_t *ctxo); extern uint16_t asn1_len_tag(uint16_t tag, uint16_t len); #endif diff --git a/src/eac.c b/src/eac.c index 1d0ddf8..77181da 100644 --- a/src/eac.c +++ b/src/eac.c @@ -113,7 +113,10 @@ int sm_unwrap() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) + { if (tag == 0x87 || tag == 0x85) { body = tag_data; body_size = tag_len; @@ -209,7 +212,9 @@ uint16_t sm_get_le() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x97) { uint16_t le = 0; for (uint16_t t = 1; t <= tag_len; t++) { @@ -266,7 +271,9 @@ int sm_verify() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag & 0x1) { input[input_len++] = (uint8_t)tag; uint8_t tlen = format_tlv_len(tag_len, input + input_len); diff --git a/src/fs/file.c b/src/fs/file.c index 93be707..c6fad0c 100644 --- a/src/fs/file.c +++ b/src/fs/file.c @@ -358,9 +358,11 @@ uint16_t meta_find(uint16_t fid, uint8_t **out) { return 0; } uint16_t tag = 0x0; - uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef); - uint16_t tag_len = 0, data_len = file_get_size(ef); - while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) { + uint8_t *tag_data = NULL, *p = NULL; + uint16_t tag_len = 0; + asn1_ctx_t ctxi; + asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag_len < 2) { continue; } @@ -380,27 +382,29 @@ int meta_delete(uint16_t fid) { return CCID_ERR_FILE_NOT_FOUND; } uint16_t tag = 0x0; - uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef); - uint16_t tag_len = 0, data_len = file_get_size(ef); + uint8_t *tag_data = NULL, *p = NULL; + uint16_t tag_len = 0; uint8_t *fdata = NULL; - while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { uint8_t *tpos = p - tag_len - format_tlv_len(tag_len, NULL) - 1; if (tag_len < 2) { continue; } uint16_t cfid = (tag_data[0] << 8 | tag_data[1]); if (cfid == fid) { - uint16_t new_len = data_len - 1 - tag_len - format_tlv_len(tag_len, NULL); + uint16_t new_len = ctxi.len - 1 - tag_len - format_tlv_len(tag_len, NULL); if (new_len == 0) { flash_clear_file(ef); } else { fdata = (uint8_t *) calloc(1, new_len); - if (tpos > data) { - memcpy(fdata, data, tpos - data); + if (tpos > ctxi.data) { + memcpy(fdata, ctxi.data, tpos - ctxi.data); } - if (data + data_len > p) { - memcpy(fdata + (tpos - data), p, data + data_len - p); + if (ctxi.data + ctxi.len > p) { + memcpy(fdata + (tpos - ctxi.data), p, ctxi.data + ctxi.len - p); } int r = flash_write_data_to_file(ef, fdata, new_len); free(fdata); @@ -426,7 +430,9 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(fdata, ef_size, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(fdata, ef_size, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag_len < 2) { continue; }