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 */ 6 7 #include <string.h> 8 #include "fido.h" 9 10 iso7816_apdu_t * 11 iso7816_new(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 18 if ((apdu = calloc(1, alloc_len)) == NULL) 19 return (NULL); 20 21 apdu->alloc_len = alloc_len; 22 apdu->payload_len = payload_len; 23 apdu->payload_ptr = apdu->payload; 24 apdu->header.ins = ins; 25 apdu->header.p1 = p1; 26 apdu->header.lc2 = (uint8_t)((payload_len >> 8) & 0xff); 27 apdu->header.lc3 = (uint8_t)(payload_len & 0xff); 28 29 return (apdu); 30 } 31 32 void 33 iso7816_free(iso7816_apdu_t **apdu_p) 34 { 35 iso7816_apdu_t *apdu; 36 37 if (apdu_p == NULL || (apdu = *apdu_p) == NULL) 38 return; 39 40 explicit_bzero(apdu, apdu->alloc_len); 41 free(apdu); 42 43 *apdu_p = NULL; 44 } 45 46 int 47 iso7816_add(iso7816_apdu_t *apdu, const void *buf, size_t cnt) 48 { 49 if (cnt > apdu->payload_len || cnt > UINT16_MAX) 50 return (-1); 51 52 memcpy(apdu->payload_ptr, buf, cnt); 53 apdu->payload_ptr += cnt; 54 apdu->payload_len = (uint16_t)(apdu->payload_len - cnt); 55 56 return (0); 57 } 58 59 const unsigned char * 60 iso7816_ptr(const iso7816_apdu_t *apdu) 61 { 62 return ((const unsigned char *)&apdu->header); 63 } 64 65 size_t 66 iso7816_len(const iso7816_apdu_t *apdu) 67 { 68 return (apdu->alloc_len - sizeof(apdu->alloc_len) - 69 sizeof(apdu->payload_len) - sizeof(apdu->payload_ptr)); 70 } 71