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