summaryrefslogtreecommitdiff
path: root/src/iso7816.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/iso7816.c')
-rw-r--r--src/iso7816.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/iso7816.c b/src/iso7816.c
new file mode 100644
index 0000000..e2ea281
--- /dev/null
+++ b/src/iso7816.c
@@ -0,0 +1,70 @@
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
10iso7816_apdu_t *
11iso7816_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;
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 = (payload_len >> 8) & 0xff;
27 apdu->header.lc3 = payload_len & 0xff;
28
29 return (apdu);
30}
31
32void
33iso7816_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
46int
47iso7816_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)cnt;
55
56 return (0);
57}
58
59const unsigned char *
60iso7816_ptr(const iso7816_apdu_t *apdu)
61{
62 return ((const unsigned char *)&apdu->header);
63}
64
65size_t
66iso7816_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}