1 /* 2 * Copyright (c) 2018 Yubico AB. All rights reserved. 3 * Use of this source code is governed by a BSD-style 4 * license that can be found in the LICENSE file. 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8 #include "fido.h" 9 10 iso7816_apdu_t * 11 iso7816_new(uint8_t cla, uint8_t ins, uint8_t p1, uint16_t payload_len) 12 { 13 iso7816_apdu_t *apdu; 14 size_t alloc_len; 15 16 alloc_len = sizeof(iso7816_apdu_t) + payload_len + 2; /* le1 le2 */ 17 if ((apdu = calloc(1, alloc_len)) == NULL) 18 return NULL; 19 apdu->alloc_len = alloc_len; 20 apdu->payload_len = payload_len; 21 apdu->payload_ptr = apdu->payload; 22 apdu->header.cla = cla; 23 apdu->header.ins = ins; 24 apdu->header.p1 = p1; 25 apdu->header.lc2 = (uint8_t)((payload_len >> 8) & 0xff); 26 apdu->header.lc3 = (uint8_t)(payload_len & 0xff); 27 28 return apdu; 29 } 30 31 void 32 iso7816_free(iso7816_apdu_t **apdu_p) 33 { 34 iso7816_apdu_t *apdu; 35 36 if (apdu_p == NULL || (apdu = *apdu_p) == NULL) 37 return; 38 freezero(apdu, apdu->alloc_len); 39 *apdu_p = NULL; 40 } 41 42 int 43 iso7816_add(iso7816_apdu_t *apdu, const void *buf, size_t cnt) 44 { 45 if (cnt > apdu->payload_len || cnt > UINT16_MAX) 46 return -1; 47 memcpy(apdu->payload_ptr, buf, cnt); 48 apdu->payload_ptr += cnt; 49 apdu->payload_len = (uint16_t)(apdu->payload_len - cnt); 50 51 return 0; 52 } 53 54 const unsigned char * 55 iso7816_ptr(const iso7816_apdu_t *apdu) 56 { 57 return (const unsigned char *)&apdu->header; 58 } 59 60 size_t 61 iso7816_len(const iso7816_apdu_t *apdu) 62 { 63 return apdu->alloc_len - offsetof(iso7816_apdu_t, header) - 64 (sizeof(iso7816_apdu_t) - offsetof(iso7816_apdu_t, payload)); 65 } 66