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