From 199095c204e8c80bc69719f7225e2c0d2e509c30 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 1 Jun 2022 09:45:27 +0200 Subject: [PATCH] Moving some ASN1 procedures to a separate file. --- CMakeLists.txt | 1 + src/ccid/asn1.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ src/ccid/asn1.h | 29 +++++++++++++++ src/ccid/ccid2040.c | 73 ------------------------------------ src/ccid/ccid2040.h | 5 --- src/ccid/eac.c | 1 + src/fs/file.c | 1 + 7 files changed, 123 insertions(+), 78 deletions(-) create mode 100644 src/ccid/asn1.c create mode 100644 src/ccid/asn1.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d564061..a9582d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ target_sources(pico_ccid PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/rng/neug.c ${CMAKE_CURRENT_LIST_DIR}/src/ccid/eac.c ${CMAKE_CURRENT_LIST_DIR}/src/ccid/crypto_utils.c + ${CMAKE_CURRENT_LIST_DIR}/src/ccid/asn1.c ) target_include_directories(pico_ccid PUBLIC diff --git a/src/ccid/asn1.c b/src/ccid/asn1.c new file mode 100644 index 0000000..d0b5f7f --- /dev/null +++ b/src/ccid/asn1.c @@ -0,0 +1,91 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * Copyright (c) 2022 Pol Henarejos. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "asn1.h" + +size_t asn1_len_tag(uint16_t tag, size_t len) { + size_t ret = 1+format_tlv_len(len, NULL)+len; + if (tag > 0x00ff) + return ret+1; + return ret; +} + +int format_tlv_len(size_t len, uint8_t *out) { + if (len < 128) { + if (out) + *out = len; + return 1; + } + else if (len < 256) { + if (out) { + *out++ = 0x81; + *out++ = len; + } + return 2; + } + else { + if (out) { + *out++ = 0x82; + *out++ = (len >> 8) & 0xff; + *out++ = len & 0xff; + } + return 3; + } + return 0; +} + +int walk_tlv(const uint8_t *cdata, size_t cdata_len, uint8_t **p, uint16_t *tag, size_t *tag_len, uint8_t **data) { + if (!p) + return 0; + if (!*p) + *p = (uint8_t *)cdata; + if (*p-cdata >= cdata_len) + return 0; + uint16_t tg = 0x0; + size_t tgl = 0; + tg = *(*p)++; + if ((tg & 0x1f) == 0x1f) { + tg <<= 8; + tg |= *(*p)++; + } + tgl = *(*p)++; + if (tgl == 0x82) { + tgl = *(*p)++ << 8; + tgl |= *(*p)++; + } + else if (tgl == 0x81) { + tgl = *(*p)++; + } + if (tag) + *tag = tg; + if (tag_len) + *tag_len = tgl; + if (data) + *data = *p; + *p = *p+tgl; + return 1; +} + +bool asn1_find_tag(const uint8_t *data, size_t data_len, uint16_t itag, size_t *tag_len, uint8_t **tag_data) { + uint16_t tag = 0x0; + uint8_t *p = NULL; + while (walk_tlv(data, data_len, &p, &tag, tag_len, tag_data)) { + if (itag == tag) + return true; + } + return false; +} diff --git a/src/ccid/asn1.h b/src/ccid/asn1.h new file mode 100644 index 0000000..f22d754 --- /dev/null +++ b/src/ccid/asn1.h @@ -0,0 +1,29 @@ +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * Copyright (c) 2022 Pol Henarejos. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _ASN1_H_ +#define _ASN1_H_ + +#include +#include "pico/stdlib.h" + +extern int walk_tlv(const uint8_t *cdata, size_t cdata_len, uint8_t **p, uint16_t *tag, size_t *tag_len, uint8_t **data); +extern int format_tlv_len(size_t len, uint8_t *out); +extern bool asn1_find_tag(const uint8_t *data, size_t data_len, uint16_t itag, size_t *tag_len, uint8_t **tag_data); +extern size_t asn1_len_tag(uint16_t tag, size_t len); + +#endif diff --git a/src/ccid/ccid2040.c b/src/ccid/ccid2040.c index 45d5e44..3ffe1e6 100644 --- a/src/ccid/ccid2040.c +++ b/src/ccid/ccid2040.c @@ -529,79 +529,6 @@ void led_off_all() { #endif } -size_t asn1_len_tag(uint16_t tag, size_t len) { - size_t ret = 1+format_tlv_len(len, NULL)+len; - if (tag > 0x00ff) - return ret+1; - return ret; -} - -int format_tlv_len(size_t len, uint8_t *out) { - if (len < 128) { - if (out) - *out = len; - return 1; - } - else if (len < 256) { - if (out) { - *out++ = 0x81; - *out++ = len; - } - return 2; - } - else { - if (out) { - *out++ = 0x82; - *out++ = (len >> 8) & 0xff; - *out++ = len & 0xff; - } - return 3; - } - return 0; -} - -int walk_tlv(const uint8_t *cdata, size_t cdata_len, uint8_t **p, uint16_t *tag, size_t *tag_len, uint8_t **data) { - if (!p) - return 0; - if (!*p) - *p = (uint8_t *)cdata; - if (*p-cdata >= cdata_len) - return 0; - uint16_t tg = 0x0; - size_t tgl = 0; - tg = *(*p)++; - if ((tg & 0x1f) == 0x1f) { - tg <<= 8; - tg |= *(*p)++; - } - tgl = *(*p)++; - if (tgl == 0x82) { - tgl = *(*p)++ << 8; - tgl |= *(*p)++; - } - else if (tgl == 0x81) { - tgl = *(*p)++; - } - if (tag) - *tag = tg; - if (tag_len) - *tag_len = tgl; - if (data) - *data = *p; - *p = *p+tgl; - return 1; -} - -bool asn1_find_tag(const uint8_t *data, size_t data_len, uint16_t itag, size_t *tag_len, uint8_t **tag_data) { - uint16_t tag = 0x0; - uint8_t *p = NULL; - while (walk_tlv(data, data_len, &p, &tag, tag_len, tag_data)) { - if (itag == tag) - return true; - } - return false; -} - void init_rtc() { rtc_init(); diff --git a/src/ccid/ccid2040.h b/src/ccid/ccid2040.h index 4fb3509..5fc6d56 100644 --- a/src/ccid/ccid2040.h +++ b/src/ccid/ccid2040.h @@ -244,9 +244,4 @@ extern void led_set_blink(uint32_t mode); #define CCID_WRONG_PADDING -1011 #define CCID_VERIFICATION_FAILED -1012 -extern int walk_tlv(const uint8_t *cdata, size_t cdata_len, uint8_t **p, uint16_t *tag, size_t *tag_len, uint8_t **data); -extern int format_tlv_len(size_t len, uint8_t *out); -extern bool asn1_find_tag(const uint8_t *data, size_t data_len, uint16_t itag, size_t *tag_len, uint8_t **tag_data); -extern size_t asn1_len_tag(uint16_t tag, size_t len); - #endif \ No newline at end of file diff --git a/src/ccid/eac.c b/src/ccid/eac.c index 09a8ccf..f1115f7 100644 --- a/src/ccid/eac.c +++ b/src/ccid/eac.c @@ -19,6 +19,7 @@ #include "crypto_utils.h" #include "random.h" #include "mbedtls/cmac.h" +#include "asn1.h" static uint8_t nonce[8]; static uint8_t sm_kmac[16]; diff --git a/src/fs/file.c b/src/fs/file.c index 96c81a1..e586be2 100644 --- a/src/fs/file.c +++ b/src/fs/file.c @@ -19,6 +19,7 @@ #include "ccid2040.h" #include #include +#include "asn1.h" extern const uintptr_t end_data_pool; extern const uintptr_t start_data_pool;