CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
apdu.cpp
Go to the documentation of this file.
1
6
8#include <string.h>
9
17bool apdu_parse(const uint8_t *raw, size_t raw_len, apdu_t *apdu) {
18 if (!raw || !apdu || raw_len < 4) {
19 return false;
20 }
21
22 memset(apdu, 0, sizeof(apdu_t));
23
24 apdu->cla = raw[0];
25 apdu->ins = raw[1];
26 apdu->p1 = raw[2];
27 apdu->p2 = raw[3];
28
29 // Case 1: No Lc, no Le (just CLA INS P1 P2)
30 if (raw_len == 4) {
31 apdu->lc = 0;
32 apdu->le = 0;
33 apdu->data = nullptr;
34 return true;
35 }
36
37 size_t pos = 4;
38
39 // Check for extended APDU (first length byte is 0x00)
40 if (raw[pos] == 0x00 && raw_len > 7) {
41 apdu->extended = true;
42
43 // Extended Lc (3 bytes: 0x00 + 2 bytes)
44 if (pos + 3 <= raw_len) {
45 apdu->lc = static_cast<uint16_t>((raw[pos + 1] << 8) | raw[pos + 2]);
46 pos += 3;
47 }
48 } else {
49 apdu->extended = false;
50
51 // Short Lc (1 byte) or Le
52 if (raw_len == 5) {
53 // Case 2: Le only
54 apdu->lc = 0;
55 apdu->le = raw[pos] == 0 ? 256 : raw[pos];
56 apdu->data = nullptr;
57 return true;
58 }
59
60 apdu->lc = raw[pos];
61 pos++;
62 }
63
64 // Command data
65 if (apdu->lc > 0) {
66 if (pos + apdu->lc > raw_len) {
67 return false; // Not enough data
68 }
69 apdu->data = raw + pos;
70 pos += apdu->lc;
71 }
72
73 // Le field (optional)
74 if (pos < raw_len) {
75 if (apdu->extended) {
76 // Extended Le (2 bytes)
77 if (pos + 2 <= raw_len) {
78 uint16_t le_val = static_cast<uint16_t>((raw[pos] << 8) | raw[pos + 1]);
79 apdu->le = (le_val == 0) ? 65536 : le_val;
80 }
81 } else {
82 // Short Le (1 byte)
83 apdu->le = (raw[pos] == 0) ? 256 : raw[pos];
84 }
85 }
86
87 return true;
88}
89
99size_t apdu_build_response(uint8_t *buf, size_t buf_max,
100 const uint8_t *data, size_t data_len,
101 uint16_t sw) {
102 if (!buf || buf_max < 2) {
103 return 0;
104 }
105
106 size_t total = data_len + 2;
107 if (total > buf_max) {
108 // Truncate data if necessary
109 data_len = buf_max - 2;
110 total = buf_max;
111 }
112
113 if (data && data_len > 0) {
114 memcpy(buf, data, data_len);
115 }
116
117 buf[data_len] = (sw >> 8) & 0xFF;
118 buf[data_len + 1] = sw & 0xFF;
119
120 return total;
121}
bool apdu_parse(const uint8_t *raw, size_t raw_len, apdu_t *apdu)
ISO 7816 APDU parsing/building helpers for CDC Badge OpenPGP stack.
Definition apdu.cpp:17
size_t apdu_build_response(uint8_t *buf, size_t buf_max, const uint8_t *data, size_t data_len, uint16_t sw)
Builds APDU response payload with status word trailer.
Definition apdu.cpp:99