]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libfido2/src/iso7816.c
Merge llvm-project main llvmorg-14-init-18294-gdb01b123d012
[FreeBSD/FreeBSD.git] / contrib / libfido2 / src / iso7816.c
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 *
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
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
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 *
54 iso7816_ptr(const iso7816_apdu_t *apdu)
55 {
56         return (const unsigned char *)&apdu->header;
57 }
58
59 size_t
60 iso7816_len(const iso7816_apdu_t *apdu)
61 {
62         return apdu->alloc_len - offsetof(iso7816_apdu_t, header) -
63             (sizeof(iso7816_apdu_t) - offsetof(iso7816_apdu_t, payload));
64 }