diff options
Diffstat (limited to 'core/tee/se/iso7816.c')
-rw-r--r-- | core/tee/se/iso7816.c | 242 |
1 files changed, 3 insertions, 239 deletions
diff --git a/core/tee/se/iso7816.c b/core/tee/se/iso7816.c index 7c1eb9a..c007f10 100644 --- a/core/tee/se/iso7816.c +++ b/core/tee/se/iso7816.c @@ -41,245 +41,9 @@ #include <stdlib.h> #include <string.h> -enum { - /* command APDU */ - CLA = 0, - INS = 1, - P1 = 2, - P2 = 3, - LC = 4, - CDATA = 5, - OFF_LE = 0, - - /* response APDU */ - RDATA = 0, - OFF_SW1 = 0, - OFF_SW2 = 1, -}; - -struct apdu_base { - uint8_t *data_buf; - size_t length; - int refcnt; -}; - -struct cmd_apdu { - struct apdu_base base; -}; - -struct resp_apdu { - struct apdu_base base; - uint8_t sw1; - uint8_t sw2; - uint8_t *resp_data; - size_t resp_data_len; -}; - -struct tee_se_aid { - uint8_t aid[MAX_AID_LENGTH]; - size_t length; - int refcnt; -}; - -/* - * APDU format, [..] means optional fields - * - * CMD_APDU: CLA, INS, P1, P2, [LC, DATA, LE] - * RESP_APDU: [DATA], SW1, SW2 - * - */ -#define CMD_APDU_SIZE(lc) ((lc) + 4) -#define RESP_APDU_SIZE(le) ((le) + 2) - -struct cmd_apdu *alloc_cmd_apdu(uint8_t cla, uint8_t ins, uint8_t p1, - uint8_t p2, uint8_t lc, uint8_t le, uint8_t *data) -{ - size_t apdu_length = CMD_APDU_SIZE(lc); - size_t total_length; - struct cmd_apdu *apdu; - uint8_t *buf; - - /* - * check if we need to reserve space for LC/LE - * (both fields are optional) - */ - if (lc) - apdu_length++; - if (le) - apdu_length++; - - total_length = sizeof(struct cmd_apdu) + apdu_length; - apdu = malloc(total_length); - - if (!apdu) - return NULL; - - apdu->base.length = apdu_length; - apdu->base.data_buf = (uint8_t *)(apdu + 1); - apdu->base.refcnt = 1; - - buf = apdu->base.data_buf; - buf[CLA] = cla; - buf[INS] = ins; - buf[P1] = p1; - buf[P2] = p2; - if (lc) - buf[LC] = lc; - if (data != NULL) - memmove(&buf[CDATA], data, lc); - if (le) - buf[CDATA + lc + OFF_LE] = le; - - return apdu; -} - -struct cmd_apdu *alloc_cmd_apdu_from_buf(uint8_t *buf, size_t length) -{ - struct cmd_apdu *apdu = malloc(sizeof(struct cmd_apdu)); - - if (!apdu) - return NULL; - apdu->base.length = length; - apdu->base.data_buf = buf; - apdu->base.refcnt = 1; - return apdu; -} - -struct resp_apdu *alloc_resp_apdu(uint8_t le) -{ - size_t total_length = sizeof(struct resp_apdu) + RESP_APDU_SIZE(le); - struct resp_apdu *apdu; - - apdu = malloc(total_length); - - if (!apdu) - return NULL; - - apdu->base.length = RESP_APDU_SIZE(le); - apdu->base.data_buf = (uint8_t *)(apdu + 1); - apdu->base.refcnt = 1; - - return apdu; -} - -uint8_t *resp_apdu_get_data(struct resp_apdu *apdu) -{ - TEE_ASSERT(apdu != NULL); - return apdu->resp_data; -} - -size_t resp_apdu_get_data_len(struct resp_apdu *apdu) -{ - TEE_ASSERT(apdu != NULL); - return apdu->resp_data_len; -} - -uint8_t resp_apdu_get_sw1(struct resp_apdu *apdu) -{ - TEE_ASSERT(apdu != NULL); - return apdu->sw1; -} - -uint8_t resp_apdu_get_sw2(struct resp_apdu *apdu) -{ - TEE_ASSERT(apdu != NULL); - return apdu->sw2; -} - -uint8_t *apdu_get_data(struct apdu_base *apdu) -{ - TEE_ASSERT(apdu != NULL); - return apdu->data_buf; -} -size_t apdu_get_length(struct apdu_base *apdu) -{ - TEE_ASSERT(apdu != NULL); - return apdu->length; -} -int apdu_get_refcnt(struct apdu_base *apdu) -{ - TEE_ASSERT(apdu != NULL); - return apdu->refcnt; -} -void apdu_acquire(struct apdu_base *apdu) -{ - TEE_ASSERT(apdu != NULL); - apdu->refcnt++; -} -void apdu_release(struct apdu_base *apdu) -{ - TEE_ASSERT(apdu != NULL); - apdu->refcnt--; - if (apdu->refcnt == 0) - free(apdu); -} - - - -TEE_Result tee_se_aid_create(const char *name, struct tee_se_aid **aid) -{ - size_t str_length = strlen(name); - size_t aid_length = str_length / 2; - - TEE_ASSERT(aid != NULL && *aid == NULL); - if (str_length < MIN_AID_LENGTH || str_length > MAX_AID_LENGTH) - return TEE_ERROR_BAD_PARAMETERS; - - *aid = malloc(sizeof(struct tee_se_aid)); - if (!(*aid)) - return TEE_ERROR_OUT_OF_MEMORY; - - hex_decode(name, str_length, (*aid)->aid); - (*aid)->length = aid_length; - (*aid)->refcnt = 1; - return TEE_SUCCESS; -} - -TEE_Result tee_se_aid_create_from_buffer(uint8_t *id, size_t length, - struct tee_se_aid **aid) -{ - *aid = malloc(sizeof(struct tee_se_aid)); - if (!(*aid)) - return TEE_ERROR_OUT_OF_MEMORY; - - memcpy((*aid)->aid, id, length); - (*aid)->length = length; - (*aid)->refcnt = 1; - return TEE_SUCCESS; -} - -void tee_se_aid_acquire(struct tee_se_aid *aid) -{ - TEE_ASSERT(aid != NULL); - aid->refcnt++; -} - -int tee_se_aid_get_refcnt(struct tee_se_aid *aid) -{ - TEE_ASSERT(aid != NULL); - return aid->refcnt; -} - -void tee_se_aid_release(struct tee_se_aid *aid) -{ - TEE_ASSERT(aid != NULL && aid->refcnt > 0); - aid->refcnt--; - if (aid->refcnt == 0) - free(aid); -} - -static void parse_resp_apdu(struct resp_apdu *apdu) -{ - uint8_t *buf = apdu->base.data_buf; - /* resp data length = resp buf length - SW1 - SW2 */ - apdu->resp_data_len = apdu->base.length - 2; - if (apdu->resp_data_len > 0) - apdu->resp_data = &buf[RDATA]; - else - apdu->resp_data = NULL; - apdu->sw1 = buf[RDATA + apdu->resp_data_len + OFF_SW1]; - apdu->sw2 = buf[RDATA + apdu->resp_data_len + OFF_SW2]; -} +#include "session_priv.h" +#include "aid_priv.h" +#include "apdu_priv.h" TEE_Result iso7816_exchange_apdu(struct tee_se_reader_proxy *proxy, struct cmd_apdu *cmd, struct resp_apdu *resp) |