• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

canokeys / canokey-core / 13902598535

17 Mar 2025 02:55PM UTC coverage: 93.55% (+0.2%) from 93.361%
13902598535

push

github

web-flow
Merge pull request #124 from canokeys/feature/openpgp-algo-infou

refactor TAG_ALGORITHM_INFORMATION of openpgp

0 of 14 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

6483 of 6930 relevant lines covered (93.55%)

307645.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.12
/applets/openpgp/openpgp.c
1
// SPDX-License-Identifier: Apache-2.0
2
#include "algo.h"
3
#include "key.h"
4
#include <common.h>
5
#include <device.h>
6
#include <ecc.h>
7
#include <key.h>
8
#include <memzero.h>
9
#include <openpgp.h>
10
#include <pin.h>
11
#include <rand.h>
12
#include <rsa.h>
13

14
#define DATA_PATH "pgp-data" // Content: URL
15
#define SIG_KEY_PATH "pgp-sigk"
16
#define DEC_KEY_PATH "pgp-deck"
17
#define AUT_KEY_PATH "pgp-autk"
18
#define SIG_CERT_PATH "pgp-sigc"
19
#define DEC_CERT_PATH "pgp-decc"
20
#define AUT_CERT_PATH "pgp-autc"
21

22
#define MAX_LOGIN_LENGTH 63
23
#define MAX_URL_LENGTH 255
24
#define MAX_NAME_LENGTH 39
25
#define MAX_LANG_LENGTH 8
26
#define MAX_SEX_LENGTH 1
27
#define MAX_PIN_LENGTH 64
28
#define MAX_CERT_LENGTH 0x480
29
#define MAX_DO_LENGTH 0xFF
30
#define MAX_KEY_TEMPLATE_LENGTH 0x16
31
#define DIGITAL_SIG_COUNTER_LENGTH 3
32
#define PW_STATUS_LENGTH 7
33

34
#define ATTR_CA1_FP 0xFF
35
#define ATTR_CA2_FP 0xFE
36
#define ATTR_CA3_FP 0xFD
37
#define ATTR_TERMINATED 0xFC
38
#define ATTR_TOUCH_CACHE_TIME 0xFB
39

40
#define STATE_NORMAL 0x00
41
#define STATE_SELECT_DATA 0x01
42
#define STATE_GET_CERT_DATA 0x02
43

44
// Algorithm ID
45
#define ALGO_ID_RSA 0x01
46
#define ALGO_ID_ECDH 0x12
47
#define ALGO_ID_ECDSA 0x13
48
#define ALGO_ID_ED25519 0x16 // https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-rfc4880bis-08#section-9.1
49

50
static const uint8_t algo_attr[][12] = {
51
    [SECP256R1] = {9, 0x00, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07},
52
    [SECP256K1] = {6, 0x00, 0x2B, 0x81, 0x04, 0x00, 0x0A},
53
    [SECP384R1] = {6, 0x00, 0x2B, 0x81, 0x04, 0x00, 0x22},
54
    [SECP521R1] = {6, 0x00, 0x2B, 0x81, 0x04, 0x00, 0x23},
55
    [SM2] = {11, 0x00, 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D},
56
    [ED25519] = {10, ALGO_ID_ED25519, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01},
57
    [X25519] = {11, ALGO_ID_ECDH, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01},
58
    [RSA2048] = {6, ALGO_ID_RSA, 0x08, 0x00, 0x00, 0x20, 0x02},
59
    [RSA3072] = {6, ALGO_ID_RSA, 0x0C, 0x00, 0x00, 0x20, 0x02},
60
    [RSA4096] = {6, ALGO_ID_RSA, 0x10, 0x00, 0x00, 0x20, 0x02},
61
};
62

63
// clang-format off
64
static const uint8_t aid[] = {0xD2, 0x76, 0x00, 0x01, 0x24, 0x01, // aid
65
                              0x03, 0x04,                         // version
66
                              0xf1, 0xd0,                         // manufacturer
67
                              0x00, 0x00, 0x00, 0x00,             // serial number
68
                              0x00, 0x00};
69

70
static const uint8_t historical_bytes[] = {0x00,
71
                                           0x31, // card services
72
                                           0xC5, // Section 6.2
73
                                           0x73, // card capabilities
74
                                           0xC0, // full/partial
75
                                           0x01, // data coding byte
76
                                           0x40, // extended apdu (Section 6.1)
77
                                           0x05, 0x90, 0x00};
78

79
static const uint8_t extended_length_info[] = {0x02, 0x02, HI(APDU_BUFFER_SIZE), LO(APDU_BUFFER_SIZE),
80
                                               0x02, 0x02, HI(APDU_BUFFER_SIZE), LO(APDU_BUFFER_SIZE)};
81

82
static const uint8_t extended_capabilities[] = {
83
    0x74, // Support get challenge, key import, pw1 status change, and algorithm attributes changes
84
    0x00, // No SM algorithm
85
    HI(APDU_BUFFER_SIZE),
86
    LO(APDU_BUFFER_SIZE), // Challenge size
87
    HI(MAX_CERT_LENGTH),
88
    LO(MAX_CERT_LENGTH), // Cert length
89
    HI(MAX_DO_LENGTH),
90
    LO(MAX_DO_LENGTH), // Other DO length
91
    0x00,              // No PIN block 2 format
92
    0x00,              // No MSE
93
};
94

95
// clang-format on
96
static uint8_t pw1_mode, current_occurrence, state;
97
static pin_t pw1 = {.min_length = 6, .max_length = MAX_PIN_LENGTH, .is_validated = 0, .path = "pgp-pw1"};
98
static pin_t pw3 = {.min_length = 8, .max_length = MAX_PIN_LENGTH, .is_validated = 0, .path = "pgp-pw3"};
99
static pin_t rc = {.min_length = 8, .max_length = MAX_PIN_LENGTH, .is_validated = 0, .path = "pgp-rc"};
100
static uint8_t touch_cache_time;
101
static uint32_t last_touch = UINT32_MAX;
102

103
#define PW1_MODE81_ON() pw1_mode |= 1u
104
#define PW1_MODE81_OFF() pw1_mode &= 0XFEu
105
#define PW1_MODE81() (pw1_mode & 1u)
106
#define PW1_MODE82_ON() pw1_mode |= 2u
107
#define PW1_MODE82_OFF() pw1_mode &= 0XFDu
108
#define PW1_MODE82() (pw1_mode & 2u)
109
#define PW_RETRY_COUNTER_DEFAULT 3
110

111
#define ASSERT_ADMIN()                                                                                                 \
112
  do {                                                                                                                 \
113
    if (pw3.is_validated == 0) {                                                                                       \
114
      EXCEPT(SW_SECURITY_STATUS_NOT_SATISFIED);                                                                        \
115
    }                                                                                                                  \
116
  } while (0)
117

118
#define UIF_DISABLED 0
119
#define UIF_ENABLED 1
120
#define UIF_PERMANENTLY 2
121

122
#define OPENPGP_TOUCH()                                                                                                \
123
  do {                                                                                                                 \
124
    if (is_nfc()) break;                                                                                               \
125
    uint32_t current_tick = device_get_tick();                                                                         \
126
    if (current_tick > last_touch && current_tick - last_touch < touch_cache_time * 1000) break;                       \
127
    switch (wait_for_user_presence(WAIT_ENTRY_CCID)) {                                                                 \
128
    case USER_PRESENCE_CANCEL:                                                                                         \
129
    case USER_PRESENCE_TIMEOUT:                                                                                        \
130
      EXCEPT(SW_ERROR_WHILE_RECEIVING);                                                                                \
131
    }                                                                                                                  \
132
    last_touch = device_get_tick();                                                                                    \
133
  } while (0)
134

135
static const char *get_key_path(uint8_t tag) {
1,302✔
136
  switch (tag) {
1,302✔
137
  case 0xB6:
428✔
138
    return SIG_KEY_PATH;
428✔
139
  case 0xB8:
396✔
140
    return DEC_KEY_PATH;
396✔
141
  case 0xA4:
477✔
142
    return AUT_KEY_PATH;
477✔
143
  default:
1✔
144
    return NULL;
1✔
145
  }
146
}
147

148
static int reset_sig_counter(void) {
34✔
149
  uint8_t buf[3] = {0};
34✔
150
  if (write_attr(DATA_PATH, TAG_DIGITAL_SIG_COUNTER, buf, DIGITAL_SIG_COUNTER_LENGTH) < 0) return -1;
34✔
151
  return 0;
34✔
152
}
153

154
static inline int fill_attr(const key_meta_t *meta, uint8_t *buf) {
441✔
155
  const uint8_t *attr = algo_attr[meta->type];
441✔
156
  memcpy(buf, attr, attr[0] + 1);
441✔
157
  if (IS_SHORT_WEIERSTRASS(meta->type)) {
441✔
158
    if (meta->usage == SIGN)
163✔
159
      buf[1] = ALGO_ID_ECDSA;
103✔
160
    else if (meta->usage == ENCRYPT)
60✔
161
      buf[1] = ALGO_ID_ECDH;
60✔
162
    else
163
      return -1;
×
164
  }
165
  return attr[0] + 1;
441✔
166
}
167

168
static inline int get_touch_policy(uint8_t touch_policy) {
453✔
169
  switch (touch_policy) {
453✔
170
  case TOUCH_POLICY_DEFAULT:
417✔
171
    return UIF_DISABLED;
417✔
172
  case TOUCH_POLICY_CACHED:
18✔
173
    return UIF_ENABLED;
18✔
174
  case TOUCH_POLICY_PERMANENT:
18✔
175
    return UIF_PERMANENTLY;
18✔
176
  default:
×
177
    return -1;
×
178
  }
179
}
180

181
static int UIF_TO_TOUCH_POLICY[3] = {[UIF_DISABLED] = TOUCH_POLICY_DEFAULT,
182
                                     [UIF_ENABLED] = TOUCH_POLICY_CACHED,
183
                                     [UIF_PERMANENTLY] = TOUCH_POLICY_PERMANENT};
184

185
// Algorithm information structure to reduce code size
186
typedef struct {
187
  uint8_t tag;
188
  int algo_index; // Algorithm index in algo_attr array
189
  uint8_t id;
190
} algo_info_t;
191

192
// Add a single algorithm information to the buffer
NEW
193
static uint16_t add_algo_info(uint8_t *buffer, uint16_t offset, uint8_t tag, int algo_index, uint8_t id) {
×
NEW
194
  buffer[offset++] = tag;
×
NEW
195
  const uint8_t *attr = algo_attr[algo_index];
×
NEW
196
  memcpy(buffer + offset, attr, attr[0] + 1);
×
NEW
197
  buffer[offset + 1] = id;
×
NEW
198
  return offset + attr[0] + 1;
×
199
}
200

201
// Add all supported algorithm information to the buffer
NEW
202
static uint16_t add_all_algorithm_info(uint8_t *buffer) {
×
NEW
203
  uint16_t offset = 0;
×
204

205
  // Define a static array of all algorithm information to avoid duplicate code
206
  static const algo_info_t all_algo_infos[] = {
207
      // SIG algorithms
208
      {TAG_ALGORITHM_ATTRIBUTES_SIG, RSA2048, ALGO_ID_RSA},
209
      {TAG_ALGORITHM_ATTRIBUTES_SIG, RSA3072, ALGO_ID_RSA},
210
      {TAG_ALGORITHM_ATTRIBUTES_SIG, RSA4096, ALGO_ID_RSA},
211
      {TAG_ALGORITHM_ATTRIBUTES_SIG, SECP256R1, ALGO_ID_ECDSA},
212
      {TAG_ALGORITHM_ATTRIBUTES_SIG, SECP256K1, ALGO_ID_ECDSA},
213
      {TAG_ALGORITHM_ATTRIBUTES_SIG, SECP384R1, ALGO_ID_ECDSA},
214
      {TAG_ALGORITHM_ATTRIBUTES_SIG, SECP521R1, ALGO_ID_ECDSA},
215
      {TAG_ALGORITHM_ATTRIBUTES_SIG, ED25519, ALGO_ID_ED25519},
216
      {TAG_ALGORITHM_ATTRIBUTES_SIG, SM2, ALGO_ID_ECDSA},
217
      // DEC algorithms
218
      {TAG_ALGORITHM_ATTRIBUTES_DEC, RSA2048, ALGO_ID_RSA},
219
      {TAG_ALGORITHM_ATTRIBUTES_DEC, RSA3072, ALGO_ID_RSA},
220
      {TAG_ALGORITHM_ATTRIBUTES_DEC, RSA4096, ALGO_ID_RSA},
221
      {TAG_ALGORITHM_ATTRIBUTES_DEC, SECP256R1, ALGO_ID_ECDH},
222
      {TAG_ALGORITHM_ATTRIBUTES_DEC, SECP256K1, ALGO_ID_ECDH},
223
      {TAG_ALGORITHM_ATTRIBUTES_DEC, SECP384R1, ALGO_ID_ECDH},
224
      {TAG_ALGORITHM_ATTRIBUTES_DEC, SECP521R1, ALGO_ID_ECDH},
225
      {TAG_ALGORITHM_ATTRIBUTES_DEC, X25519, ALGO_ID_ECDH},
226
      {TAG_ALGORITHM_ATTRIBUTES_DEC, SM2, ALGO_ID_ECDH},
227
      // AUT algorithms
228
      {TAG_ALGORITHM_ATTRIBUTES_AUT, RSA2048, ALGO_ID_RSA},
229
      {TAG_ALGORITHM_ATTRIBUTES_AUT, RSA3072, ALGO_ID_RSA},
230
      {TAG_ALGORITHM_ATTRIBUTES_AUT, RSA4096, ALGO_ID_RSA},
231
      {TAG_ALGORITHM_ATTRIBUTES_AUT, SECP256R1, ALGO_ID_ECDSA},
232
      {TAG_ALGORITHM_ATTRIBUTES_AUT, SECP256K1, ALGO_ID_ECDSA},
233
      {TAG_ALGORITHM_ATTRIBUTES_AUT, SECP384R1, ALGO_ID_ECDSA},
234
      {TAG_ALGORITHM_ATTRIBUTES_AUT, SECP521R1, ALGO_ID_ECDSA},
235
      {TAG_ALGORITHM_ATTRIBUTES_AUT, ED25519, ALGO_ID_ED25519},
236
      {TAG_ALGORITHM_ATTRIBUTES_AUT, SM2, ALGO_ID_ECDSA},
237
  };
238

239
  // Use a loop to iterate through all algorithm information instead of repeated code blocks
NEW
240
  for (size_t i = 0; i < sizeof(all_algo_infos) / sizeof(algo_info_t); i++) {
×
NEW
241
    offset = add_algo_info(buffer, offset, all_algo_infos[i].tag, all_algo_infos[i].algo_index, all_algo_infos[i].id);
×
242
  }
243

NEW
244
  return offset;
×
245
}
246

247
void openpgp_poweroff(void) {
248
  pw1_mode = 0;
62✔
249
  pw1.is_validated = 0;
62✔
250
  pw3.is_validated = 0;
62✔
251
  state = STATE_NORMAL;
62✔
252
}
62✔
253

254
int openpgp_install(uint8_t reset) {
255
  openpgp_poweroff();
18✔
256
  if (!reset && get_file_size(DATA_PATH) >= 0) return 0;
18✔
257

258
  // Cardholder Data
259
  if (write_file(DATA_PATH, NULL, 0, 0, 1) < 0) return -1;
18✔
260
  uint8_t terminated = 0x01; // Terminated: yes
18✔
261
  if (write_attr(DATA_PATH, ATTR_TERMINATED, &terminated, 1) < 0) return -1;
18✔
262
  if (write_attr(DATA_PATH, TAG_LOGIN, NULL, 0) < 0) return -1;
18✔
263
  if (write_attr(DATA_PATH, TAG_NAME, NULL, 0)) return -1;
18✔
264
  // default lang = NULL
265
  if (write_attr(DATA_PATH, LO(TAG_LANG), NULL, 0) < 0) return -1;
18✔
266
  uint8_t default_sex = 0x39; // default sex
18✔
267
  if (write_attr(DATA_PATH, LO(TAG_SEX), &default_sex, 1) < 0) return -1;
18✔
268
  uint8_t default_pin_strategy = 0x00; // verify PIN every time
18✔
269
  if (write_attr(DATA_PATH, TAG_PW_STATUS, &default_pin_strategy, 1) < 0) return -1;
18✔
270

271
  // Key data, default to RSA2048
272
  uint8_t buf[20];
18✔
273
  memzero(buf, sizeof(buf));
18✔
274
  ck_key_t key = {.meta.origin = KEY_ORIGIN_NOT_PRESENT, .meta.type = RSA2048};
18✔
275

276
  key.meta.usage = SIGN;
18✔
277
  if (ck_write_key(SIG_KEY_PATH, &key) < 0) return -1;
18✔
278
  if (openpgp_key_set_fingerprint(SIG_KEY_PATH, buf) < 0) return -1;
18✔
279
  if (openpgp_key_set_datetime(SIG_KEY_PATH, buf) < 0) return -1;
18✔
280

281
  key.meta.usage = ENCRYPT;
18✔
282
  if (ck_write_key(DEC_KEY_PATH, &key) < 0) return -1;
18✔
283
  if (openpgp_key_set_fingerprint(DEC_KEY_PATH, buf) < 0) return -1;
18✔
284
  if (openpgp_key_set_datetime(DEC_KEY_PATH, buf) < 0) return -1;
18✔
285

286
  key.meta.usage = SIGN;
18✔
287
  if (ck_write_key(AUT_KEY_PATH, &key) < 0) return -1;
18✔
288
  if (openpgp_key_set_fingerprint(AUT_KEY_PATH, buf) < 0) return -1;
18✔
289
  if (openpgp_key_set_datetime(AUT_KEY_PATH, buf) < 0) return -1;
18✔
290

291
  if (write_attr(DATA_PATH, ATTR_CA1_FP, buf, KEY_FINGERPRINT_LENGTH) < 0) return -1;
18✔
292
  if (write_attr(DATA_PATH, ATTR_CA2_FP, buf, KEY_FINGERPRINT_LENGTH) < 0) return -1;
18✔
293
  if (write_attr(DATA_PATH, ATTR_CA3_FP, buf, KEY_FINGERPRINT_LENGTH) < 0) return -1;
18✔
294

295
  // Touch policy
296
  touch_cache_time = 0;
18✔
297
  if (write_attr(DATA_PATH, ATTR_TOUCH_CACHE_TIME, &touch_cache_time, sizeof(touch_cache_time)) < 0) return -1;
18✔
298

299
  // Digital Sig Counter
300
  if (reset_sig_counter() < 0) return -1;
18✔
301

302
  // Certs
303
  if (write_file(SIG_CERT_PATH, NULL, 0, 0, 1) < 0) return -1;
18✔
304
  if (write_file(DEC_CERT_PATH, NULL, 0, 0, 1) < 0) return -1;
18✔
305
  if (write_file(AUT_CERT_PATH, NULL, 0, 0, 1) < 0) return -1;
18✔
306

307
  // PIN data
308
  if (pin_create(&pw1, "123456", 6, PW_RETRY_COUNTER_DEFAULT) < 0) return -1;
18✔
309
  if (pin_create(&pw3, "12345678", 8, PW_RETRY_COUNTER_DEFAULT) < 0) return -1;
18✔
310
  if (pin_create(&rc, NULL, 0, PW_RETRY_COUNTER_DEFAULT) < 0) return -1;
18✔
311

312
  terminated = 0x00; // Terminated: no
18✔
313
  if (write_attr(DATA_PATH, ATTR_TERMINATED, &terminated, 1) < 0) return -1;
18✔
314

315
  return 0;
18✔
316
}
317

318
static int openpgp_select(const CAPDU *capdu, RAPDU *rapdu) {
46✔
319
  if (P1 != 0x04 || P2 != 0x00) EXCEPT(SW_WRONG_P1P2);
46✔
320
  if (LC != 6 || memcmp(DATA, aid, LC) != 0) EXCEPT(SW_FILE_NOT_FOUND);
31✔
321
  if (read_attr(DATA_PATH, ATTR_TOUCH_CACHE_TIME, &touch_cache_time, sizeof(touch_cache_time)) < 0) return -1;
31✔
322
  return 0;
31✔
323
}
324

325
static int openpgp_get_data(const CAPDU *capdu, RAPDU *rapdu) {
673✔
326
  if (LC != 0) EXCEPT(SW_WRONG_LENGTH);
673✔
327

328
  uint16_t tag = (uint16_t)(P1 << 8u) | P2;
673✔
329
  uint16_t off = 0;
673✔
330
  int len, retries;
331
  key_meta_t sig_meta, dec_meta, aut_meta;
673✔
332
  if (ck_read_key_metadata(SIG_KEY_PATH, &sig_meta) < 0) return -1;
673✔
333
  if (ck_read_key_metadata(DEC_KEY_PATH, &dec_meta) < 0) return -1;
673✔
334
  if (ck_read_key_metadata(AUT_KEY_PATH, &aut_meta) < 0) return -1;
673✔
335

336
  switch (tag) {
673✔
337
  case TAG_AID:
15✔
338
    memcpy(RDATA, aid, sizeof(aid));
15✔
339
    fill_sn(RDATA + 10);
15✔
340
    LL = sizeof(aid);
15✔
341
    break;
15✔
342

343
  case TAG_LOGIN:
38✔
344
    len = read_attr(DATA_PATH, TAG_LOGIN, RDATA, MAX_LOGIN_LENGTH);
38✔
345
    if (len < 0) return -1;
38✔
346
    LL = len;
38✔
347
    break;
38✔
348

349
  case TAG_URL:
36✔
350
    len = read_file(DATA_PATH, RDATA, 0, MAX_URL_LENGTH);
36✔
351
    if (len < 0) return -1;
36✔
352
    LL = len;
36✔
353
    break;
36✔
354

355
  case TAG_HISTORICAL_BYTES:
15✔
356
    memcpy(RDATA, historical_bytes, sizeof(historical_bytes));
15✔
357
    LL = sizeof(historical_bytes);
15✔
358
    break;
15✔
359

360
  case TAG_CARDHOLDER_RELATED_DATA:
64✔
361
    RDATA[off++] = TAG_CARDHOLDER_RELATED_DATA;
64✔
362
    RDATA[off++] = 0; // to be filled later
64✔
363
    RDATA[off++] = TAG_NAME;
64✔
364
    len = read_attr(DATA_PATH, TAG_NAME, RDATA + off + 1, MAX_NAME_LENGTH);
64✔
365
    if (len < 0) return -1;
64✔
366
    RDATA[off++] = len;
64✔
367
    off += len;
64✔
368

369
    RDATA[off++] = HI(TAG_LANG);
64✔
370
    RDATA[off++] = LO(TAG_LANG);
64✔
371
    len = read_attr(DATA_PATH, LO(TAG_LANG), RDATA + off + 1, MAX_LANG_LENGTH);
64✔
372
    if (len < 0) return -1;
64✔
373
    RDATA[off++] = len;
64✔
374
    off += len;
64✔
375

376
    RDATA[off++] = HI(TAG_SEX);
64✔
377
    RDATA[off++] = LO(TAG_SEX);
64✔
378
    len = read_attr(DATA_PATH, LO(TAG_SEX), RDATA + off + 1, MAX_SEX_LENGTH);
64✔
379
    if (len < 0) return -1;
64✔
380
    RDATA[off++] = len;
64✔
381
    off += len;
64✔
382
    RDATA[1] = off - 2;
64✔
383
    LL = off;
64✔
384
    break;
64✔
385

386
  case TAG_APPLICATION_RELATED_DATA:
147✔
387
    RDATA[off++] = TAG_APPLICATION_RELATED_DATA;
147✔
388
    RDATA[off++] = 0x82; // extended length
147✔
389
    RDATA[off++] = 0;    // to be filled later
147✔
390
    RDATA[off++] = 0;    // to be filled later
147✔
391
    RDATA[off++] = TAG_AID;
147✔
392
    RDATA[off++] = sizeof(aid);
147✔
393
    memcpy(RDATA + off, aid, sizeof(aid));
147✔
394
    fill_sn(RDATA + off + 10);
147✔
395
    off += sizeof(aid);
147✔
396

397
    RDATA[off++] = HI(TAG_HISTORICAL_BYTES);
147✔
398
    RDATA[off++] = LO(TAG_HISTORICAL_BYTES);
147✔
399
    RDATA[off++] = sizeof(historical_bytes);
147✔
400
    memcpy(RDATA + off, historical_bytes, sizeof(historical_bytes));
147✔
401
    off += sizeof(historical_bytes);
147✔
402

403
    RDATA[off++] = HI(TAG_EXTENDED_LENGTH_INFO);
147✔
404
    RDATA[off++] = LO(TAG_EXTENDED_LENGTH_INFO);
147✔
405
    RDATA[off++] = sizeof(extended_length_info);
147✔
406
    memcpy(RDATA + off, extended_length_info, sizeof(extended_length_info));
147✔
407
    off += sizeof(extended_length_info);
147✔
408

409
    RDATA[off++] = HI(TAG_GENERAL_FEATURE_MANAGEMENT);
147✔
410
    RDATA[off++] = LO(TAG_GENERAL_FEATURE_MANAGEMENT);
147✔
411
    RDATA[off++] = 0x03;
147✔
412
    RDATA[off++] = 0x81;
147✔
413
    RDATA[off++] = 0x01;
147✔
414
    RDATA[off++] = 0x20; // announces a button
147✔
415

416
    RDATA[off++] = TAG_DISCRETIONARY_DATA_OBJECTS;
147✔
417
    RDATA[off++] = 0x82;
147✔
418
    uint16_t length_pos = off;
147✔
419
    RDATA[off++] = 0; // these two bytes are for length
147✔
420
    RDATA[off++] = 0;
147✔
421

422
    RDATA[off++] = TAG_EXTENDED_CAPABILITIES;
147✔
423
    RDATA[off++] = sizeof(extended_capabilities);
147✔
424
    memcpy(RDATA + off, extended_capabilities, sizeof(extended_capabilities));
147✔
425
    off += sizeof(extended_capabilities);
147✔
426

427
    RDATA[off++] = TAG_ALGORITHM_ATTRIBUTES_SIG;
147✔
428
    len = fill_attr(&sig_meta, RDATA + off);
147✔
429
    if (len < 0) return -1;
147✔
430
    off += len;
147✔
431

432
    RDATA[off++] = TAG_ALGORITHM_ATTRIBUTES_DEC;
147✔
433
    len = fill_attr(&dec_meta, RDATA + off);
147✔
434
    if (len < 0) return -1;
147✔
435
    off += len;
147✔
436

437
    RDATA[off++] = TAG_ALGORITHM_ATTRIBUTES_AUT;
147✔
438
    len = fill_attr(&aut_meta, RDATA + off);
147✔
439
    if (len < 0) return -1;
147✔
440
    off += len;
147✔
441

442
    RDATA[off++] = TAG_PW_STATUS;
147✔
443
    RDATA[off++] = PW_STATUS_LENGTH;
147✔
444
    if (read_attr(DATA_PATH, TAG_PW_STATUS, RDATA + off++, 1) < 0) return -1;
147✔
445
    RDATA[off++] = MAX_PIN_LENGTH;
147✔
446
    RDATA[off++] = MAX_PIN_LENGTH;
147✔
447
    RDATA[off++] = MAX_PIN_LENGTH;
147✔
448
    retries = pin_get_retries(&pw1);
147✔
449
    if (retries < 0) return -1;
147✔
450
    RDATA[off++] = retries;
147✔
451
    retries = pin_get_retries(&rc);
147✔
452
    if (retries < 0) return -1;
147✔
453
    RDATA[off++] = retries;
147✔
454
    retries = pin_get_retries(&pw3);
147✔
455
    if (retries < 0) return -1;
147✔
456
    RDATA[off++] = retries;
147✔
457

458
    RDATA[off++] = TAG_KEY_FINGERPRINTS;
147✔
459
    RDATA[off++] = KEY_FINGERPRINT_LENGTH * 3;
147✔
460
    len = openpgp_key_get_fingerprint(SIG_KEY_PATH, RDATA + off);
147✔
461
    if (len < 0) return -1;
147✔
462
    off += len;
147✔
463
    len = openpgp_key_get_fingerprint(DEC_KEY_PATH, RDATA + off);
147✔
464
    if (len < 0) return -1;
147✔
465
    off += len;
147✔
466
    len = openpgp_key_get_fingerprint(AUT_KEY_PATH, RDATA + off);
147✔
467
    if (len < 0) return -1;
147✔
468
    off += len;
147✔
469

470
    RDATA[off++] = TAG_CA_FINGERPRINTS;
147✔
471
    RDATA[off++] = KEY_FINGERPRINT_LENGTH * 3;
147✔
472
    len = read_attr(DATA_PATH, ATTR_CA1_FP, RDATA + off, KEY_FINGERPRINT_LENGTH);
147✔
473
    if (len < 0) return -1;
147✔
474
    off += len;
147✔
475
    len = read_attr(DATA_PATH, ATTR_CA2_FP, RDATA + off, KEY_FINGERPRINT_LENGTH);
147✔
476
    if (len < 0) return -1;
147✔
477
    off += len;
147✔
478
    len = read_attr(DATA_PATH, ATTR_CA3_FP, RDATA + off, KEY_FINGERPRINT_LENGTH);
147✔
479
    if (len < 0) return -1;
147✔
480
    off += len;
147✔
481

482
    RDATA[off++] = TAG_KEY_GENERATION_DATES;
147✔
483
    RDATA[off++] = KEY_DATETIME_LENGTH * 3;
147✔
484
    len = openpgp_key_get_datetime(SIG_KEY_PATH, RDATA + off);
147✔
485
    if (len < 0) return -1;
147✔
486
    off += len;
147✔
487
    len = openpgp_key_get_datetime(DEC_KEY_PATH, RDATA + off);
147✔
488
    if (len < 0) return -1;
147✔
489
    off += len;
147✔
490
    len = openpgp_key_get_datetime(AUT_KEY_PATH, RDATA + off);
147✔
491
    if (len < 0) return -1;
147✔
492
    off += len;
147✔
493

494
    RDATA[off++] = TAG_KEY_INFO;
147✔
495
    RDATA[off++] = 6;
147✔
496
    RDATA[off++] = 0x01; // Key-ref: sig
147✔
497
    RDATA[off++] = sig_meta.origin;
147✔
498
    RDATA[off++] = 0x02; // Key-ref: dec
147✔
499
    RDATA[off++] = dec_meta.origin;
147✔
500
    RDATA[off++] = 0x03; // Key-ref: aut
147✔
501
    RDATA[off++] = aut_meta.origin;
147✔
502

503
    RDATA[off++] = TAG_UIF_SIG;
147✔
504
    RDATA[off++] = 2;
147✔
505
    RDATA[off++] = get_touch_policy(sig_meta.touch_policy);
147✔
506
    RDATA[off++] = 0x20; // button
147✔
507

508
    RDATA[off++] = TAG_UIF_DEC;
147✔
509
    RDATA[off++] = 2;
147✔
510
    RDATA[off++] = get_touch_policy(dec_meta.touch_policy);
147✔
511
    RDATA[off++] = 0x20; // button
147✔
512

513
    RDATA[off++] = TAG_UIF_AUT;
147✔
514
    RDATA[off++] = 2;
147✔
515
    RDATA[off++] = get_touch_policy(aut_meta.touch_policy);
147✔
516
    RDATA[off++] = 0x20; // button
147✔
517

518
    uint16_t ddo_length = off - length_pos - 2;
147✔
519
    RDATA[length_pos] = HI(ddo_length);
147✔
520
    RDATA[length_pos + 1] = LO(ddo_length);
147✔
521

522
    ddo_length = off - 4;
147✔
523
    RDATA[2] = HI(ddo_length);
147✔
524
    RDATA[3] = LO(ddo_length);
147✔
525
    LL = off;
147✔
526
    break;
147✔
527

528
  case TAG_SECURITY_SUPPORT_TEMPLATE:
113✔
529
    RDATA[0] = TAG_SECURITY_SUPPORT_TEMPLATE;
113✔
530
    RDATA[1] = DIGITAL_SIG_COUNTER_LENGTH + 2;
113✔
531
    RDATA[2] = TAG_DIGITAL_SIG_COUNTER;
113✔
532
    RDATA[3] = DIGITAL_SIG_COUNTER_LENGTH;
113✔
533
    len = read_attr(DATA_PATH, TAG_DIGITAL_SIG_COUNTER, RDATA + 4, DIGITAL_SIG_COUNTER_LENGTH);
113✔
534
    if (len < 0) return -1;
113✔
535
    LL = 4 + DIGITAL_SIG_COUNTER_LENGTH;
113✔
536
    break;
113✔
537

538
  case TAG_CARDHOLDER_CERTIFICATE:
10✔
539
    if (current_occurrence == 0)
10✔
540
      len = read_file(SIG_CERT_PATH, RDATA, 0, MAX_CERT_LENGTH);
6✔
541
    else if (current_occurrence == 1)
4✔
542
      len = read_file(DEC_CERT_PATH, RDATA, 0, MAX_CERT_LENGTH);
2✔
543
    else if (current_occurrence == 2)
2✔
544
      len = read_file(AUT_CERT_PATH, RDATA, 0, MAX_CERT_LENGTH);
2✔
545
    else
546
      EXCEPT(SW_REFERENCE_DATA_NOT_FOUND);
×
547
    if (len < 0) return -1;
10✔
548
    LL = len;
10✔
549
    break;
10✔
550

551
  case TAG_EXTENDED_LENGTH_INFO:
1✔
552
    memcpy(RDATA, extended_length_info, sizeof(extended_length_info));
1✔
553
    LL = sizeof(extended_length_info);
1✔
554
    break;
1✔
555

556
  case TAG_GENERAL_FEATURE_MANAGEMENT:
1✔
557
    RDATA[0] = 0x81;
1✔
558
    RDATA[1] = 0x01;
1✔
559
    RDATA[2] = 0x20;
1✔
560
    LL = 3;
1✔
561
    break;
1✔
562

563
  case TAG_PW_STATUS:
229✔
564
    if (read_attr(DATA_PATH, TAG_PW_STATUS, RDATA, 1) < 0) return -1;
229✔
565
    RDATA[1] = MAX_PIN_LENGTH;
229✔
566
    RDATA[2] = MAX_PIN_LENGTH;
229✔
567
    RDATA[3] = MAX_PIN_LENGTH;
229✔
568
    retries = pin_get_retries(&pw1);
229✔
569
    if (retries < 0) return -1;
229✔
570
    RDATA[4] = retries;
229✔
571
    retries = pin_get_retries(&rc);
229✔
572
    if (retries < 0) return -1;
229✔
573
    RDATA[5] = retries;
229✔
574
    retries = pin_get_retries(&pw3);
229✔
575
    if (retries < 0) return -1;
229✔
576
    RDATA[6] = retries;
229✔
577
    LL = PW_STATUS_LENGTH;
229✔
578
    break;
229✔
579

580
  case TAG_KEY_INFO:
2✔
581
    RDATA[0] = 0x01; // Key-ref: sig
2✔
582
    RDATA[1] = sig_meta.origin;
2✔
583
    RDATA[2] = 0x02; // Key-ref: dec
2✔
584
    RDATA[3] = dec_meta.origin;
2✔
585
    RDATA[4] = 0x03; // Key-ref: aut
2✔
586
    RDATA[5] = aut_meta.origin;
2✔
587
    LL = 6;
2✔
588
    break;
2✔
589

590
  case TAG_ALGORITHM_INFORMATION:
×
NEW
591
    RDATA[0] = TAG_ALGORITHM_INFORMATION;
×
NEW
592
    RDATA[1] = add_all_algorithm_info(RDATA + 2);
×
NEW
593
    LL = RDATA[1] + 2;
×
UNCOV
594
    break;
×
595

596
  case TAG_UIF_CACHE_TIME:
1✔
597
    RDATA[0] = touch_cache_time;
1✔
598
    LL = 1;
1✔
599
    break;
1✔
600

601
  default:
1✔
602
    EXCEPT(SW_REFERENCE_DATA_NOT_FOUND);
1✔
603
  }
604

605
  return 0;
672✔
606
}
607

608
static int openpgp_verify(const CAPDU *capdu, RAPDU *rapdu) {
188✔
609
  if (P1 != 0x00 && P1 != 0xFF) EXCEPT(SW_WRONG_P1P2);
188✔
610

611
  pin_t *pw;
612
  if (P2 == 0x81) {
188✔
613
    pw = &pw1;
78✔
614
    PW1_MODE81_OFF();
78✔
615
  } else if (P2 == 0x82) {
110✔
616
    pw = &pw1;
12✔
617
    PW1_MODE82_OFF();
12✔
618
  } else if (P2 == 0x83) {
98✔
619
    pw = &pw3;
97✔
620
  } else {
621
    EXCEPT(SW_WRONG_P1P2);
1✔
622
  }
623

624
  if (P1 == 0xFF) {
187✔
625
    pw->is_validated = 0;
2✔
626
    return 0;
2✔
627
  }
628

629
  if (LC == 0) {
185✔
630
    if (pw->is_validated) return 0;
3✔
631
    int retries = pin_get_retries(pw);
2✔
632
    if (retries < 0) return -1;
2✔
633
    EXCEPT(SW_PIN_RETRIES + retries);
2✔
634
  }
635

636
  uint8_t ctr;
182✔
637
  int err = pin_verify(pw, DATA, LC, &ctr);
182✔
638
  if (err == PIN_IO_FAIL) return -1;
182✔
639
  if (err == PIN_LENGTH_INVALID) EXCEPT(SW_WRONG_LENGTH);
182✔
640
  if (ctr == 0) EXCEPT(SW_AUTHENTICATION_BLOCKED);
181✔
641
  if (err == PIN_AUTH_FAIL) EXCEPT(SW_SECURITY_STATUS_NOT_SATISFIED);
139✔
642
  if (P2 == 0x81) {
95✔
643
    PW1_MODE81_ON();
34✔
644
  } else if (P2 == 0x82) {
61✔
645
    PW1_MODE82_ON();
12✔
646
  }
647

648
  return 0;
95✔
649
}
650

651
static int openpgp_change_reference_data(const CAPDU *capdu, RAPDU *rapdu) {
7✔
652
  if (P1 != 0x00) EXCEPT(SW_WRONG_P1P2);
7✔
653

654
  pin_t *pw;
655
  if (P2 == 0x81) {
6✔
656
    pw = &pw1;
4✔
657
    pw1_mode = 0;
4✔
658
  } else if (P2 == 0x83) {
2✔
659
    pw = &pw3;
1✔
660
  } else {
661
    EXCEPT(SW_WRONG_P1P2);
1✔
662
  }
663

664
  uint8_t ctr;
5✔
665
  int pw_length = pin_get_size(pw);
5✔
666
  int err = pin_verify(pw, DATA, (LC < pw_length ? LC : pw_length), &ctr);
5✔
667
  if (err == PIN_IO_FAIL) return -1;
5✔
668
  if (ctr == 0) EXCEPT(SW_AUTHENTICATION_BLOCKED);
5✔
669
  if (err == PIN_AUTH_FAIL) EXCEPT(SW_SECURITY_STATUS_NOT_SATISFIED);
5✔
670
  if (LC < pw_length) EXCEPT(SW_WRONG_LENGTH);
4✔
671
  err = pin_update(pw, DATA + pw_length, LC - pw_length);
4✔
672
  if (err == PIN_IO_FAIL) return -1;
4✔
673
  if (err == PIN_LENGTH_INVALID) EXCEPT(SW_WRONG_LENGTH);
4✔
674

675
  return 0;
3✔
676
}
677

678
static int openpgp_reset_retry_counter(const CAPDU *capdu, RAPDU *rapdu) {
3✔
679
  if ((P1 != 0x00 && P1 != 0x02) || P2 != 0x81) EXCEPT(SW_WRONG_P1P2);
3✔
680

681
  int offset, err;
682
  if (P1 == 0x00) {
3✔
683
    offset = pin_get_size(&rc);
1✔
684
    if (offset == 0) EXCEPT(SW_SECURITY_STATUS_NOT_SATISFIED);
1✔
685
    uint8_t ctr;
1✔
686
    err = pin_verify(&rc, DATA, (LC < offset ? LC : offset), &ctr);
1✔
687
    if (err == PIN_IO_FAIL) return -1;
1✔
688
    if (ctr == 0) EXCEPT(SW_AUTHENTICATION_BLOCKED);
1✔
689
    if (err == PIN_AUTH_FAIL) EXCEPT(SW_SECURITY_STATUS_NOT_SATISFIED);
1✔
690
  } else {
691
#ifndef FUZZ
692
    ASSERT_ADMIN();
2✔
693
#endif
694
    offset = 0;
1✔
695
  }
696
  if (LC < offset) EXCEPT(SW_WRONG_LENGTH);
2✔
697

698
  err = pin_update(&pw1, DATA + offset, LC - offset);
2✔
699
  if (err == PIN_IO_FAIL) return -1;
2✔
700
  if (err == PIN_LENGTH_INVALID) EXCEPT(SW_WRONG_LENGTH);
2✔
701

702
  return 0;
2✔
703
}
704

705
static int openpgp_generate_asymmetric_key_pair(const CAPDU *capdu, RAPDU *rapdu) {
1,288✔
706
  if (P2 != 0x00) EXCEPT(SW_WRONG_P1P2);
1,288✔
707
  if (LC != 0x02 && LC != 0x05) EXCEPT(SW_WRONG_LENGTH);
1,288✔
708

709
  const char *key_path = get_key_path(DATA[0]);
1,288✔
710
  if (key_path == NULL) EXCEPT(SW_WRONG_DATA);
1,288✔
711

712
  ck_key_t key;
1,287✔
713
  if (ck_read_key(key_path, &key) < 0) return -1;
1,287✔
714

715
  if (P1 == 0x80) {
1,287✔
716
    start_quick_blinking(0);
27✔
717
    if (ck_generate_key(&key) < 0) {
27✔
718
      ERR_MSG("Generate key %s failed\n", key_path);
×
719
      return -1;
×
720
    }
721
    if (ck_write_key(key_path, &key) < 0) {
27✔
722
      ERR_MSG("Write key %s failed\n", key_path);
×
723
      return -1;
×
724
    }
725
    DBG_MSG("Generate key %s successful\n", key_path);
27✔
726
    DBG_KEY_META(&key.meta);
27✔
727
  } else if (P1 == 0x81) {
1,260✔
728
    if (key.meta.origin == KEY_ORIGIN_NOT_PRESENT) {
1,259✔
729
      DBG_MSG("Generate key %s not set\n", key_path);
1,215✔
730
      memzero(&key, sizeof(key));
1,215✔
731
      EXCEPT(SW_REFERENCE_DATA_NOT_FOUND);
1,215✔
732
    }
733
  } else {
734
    memzero(&key, sizeof(key));
1✔
735
    EXCEPT(SW_WRONG_P1P2);
1✔
736
  }
737

738
  RDATA[0] = 0x7F;
71✔
739
  RDATA[1] = 0x49;
71✔
740
  int len = ck_encode_public_key(&key, &RDATA[2], true);
71✔
741
  memzero(&key, sizeof(key));
71✔
742
  if (len < 0) return -1;
71✔
743
  LL = len + 2;
71✔
744
  if (P1 == 0x80 && strcmp(key_path, SIG_KEY_PATH) == 0) return reset_sig_counter();
71✔
745

746
  return 0;
61✔
747
}
748

749
static int openpgp_sign_or_auth(const CAPDU *capdu, RAPDU *rapdu, bool is_sign) {
44✔
750
#ifndef FUZZ
751
  if (is_sign) {
44✔
752
    if (PW1_MODE81() == 0) EXCEPT(SW_SECURITY_STATUS_NOT_SATISFIED);
24✔
753
  } else {
754
    if (PW1_MODE82() == 0) EXCEPT(SW_SECURITY_STATUS_NOT_SATISFIED);
20✔
755
  }
756
#endif
757

758
  if (is_sign) {
44✔
759
    uint8_t pw1_status;
24✔
760
    if (read_attr(DATA_PATH, TAG_PW_STATUS, &pw1_status, 1) < 0) return -1;
24✔
761
    if (pw1_status == 0x00) PW1_MODE81_OFF();
24✔
762
  }
763

764
  const char *key_path = is_sign ? SIG_KEY_PATH : AUT_KEY_PATH;
44✔
765

766
  ck_key_t key;
44✔
767
  if (ck_read_key_metadata(key_path, &key.meta) < 0) {
44✔
768
    ERR_MSG("Read metadata failed\n");
×
769
    return -1;
×
770
  }
771

772
  if (key.meta.touch_policy == TOUCH_POLICY_CACHED || key.meta.touch_policy == TOUCH_POLICY_PERMANENT) OPENPGP_TOUCH();
44✔
773
  if (key.meta.origin == KEY_ORIGIN_NOT_PRESENT) EXCEPT(SW_REFERENCE_DATA_NOT_FOUND);
44✔
774
  if ((key.meta.usage & SIGN) == 0) EXCEPT(SW_CONDITIONS_NOT_SATISFIED);
40✔
775
  start_quick_blinking(0);
40✔
776

777
  size_t input_size = LC;
40✔
778
  if (IS_RSA(key.meta.type)) {
40✔
779
    if (LC > PUBLIC_KEY_LENGTH[key.meta.type] * 2 / 5) {
11✔
780
      DBG_MSG("DigestInfo should be not longer than 40%% of the length of the modulus\n");
2✔
781
      EXCEPT(SW_WRONG_LENGTH);
2✔
782
    }
783
  } else if (IS_SHORT_WEIERSTRASS(key.meta.type)) {
29✔
784
    if (LC > PRIVATE_KEY_LENGTH[key.meta.type]) {
20✔
785
      DBG_MSG("digest should has the same length as the private key\n");
2✔
786
      EXCEPT(SW_WRONG_LENGTH);
2✔
787
    }
788
    // prepend zeros
789
    memmove(DATA + (PRIVATE_KEY_LENGTH[key.meta.type] - LC), DATA, LC);
18✔
790
    memzero(DATA, PRIVATE_KEY_LENGTH[key.meta.type] - LC);
18✔
791
    input_size = PRIVATE_KEY_LENGTH[key.meta.type];
18✔
792
  }
793

794
  if (ck_read_key(key_path, &key) < 0) {
36✔
795
    ERR_MSG("Read key failed\n");
×
796
    return -1;
×
797
  }
798

799
  DBG_KEY_META(&key.meta);
36✔
800

801
  const int sig_len = ck_sign(&key, DATA, input_size, RDATA);
36✔
802
  if (sig_len < 0) {
36✔
803
    ERR_MSG("Sign failed\n");
×
804
    return -1;
×
805
  }
806

807
  memzero(&key, sizeof(key));
36✔
808
  LL = sig_len;
36✔
809

810
  if (is_sign) {
36✔
811
    uint8_t ctr[3];
20✔
812
    if (read_attr(DATA_PATH, TAG_DIGITAL_SIG_COUNTER, ctr, DIGITAL_SIG_COUNTER_LENGTH) < 0) {
20✔
813
      ERR_MSG("Read sig counter failed\n");
×
814
      return -1;
×
815
    }
816
    for (int i = 3; i > 0; --i)
20✔
817
      if (++ctr[i - 1] != 0) break;
20✔
818
    if (write_attr(DATA_PATH, TAG_DIGITAL_SIG_COUNTER, ctr, DIGITAL_SIG_COUNTER_LENGTH) < 0) {
20✔
819
      ERR_MSG("Write sig counter failed\n");
×
820
      return -1;
×
821
    }
822
  }
823

824
  return 0;
36✔
825
}
826

827
// Parse and validate the specific TLV structure for ECC key
828
static int parse_ecc_key_tlv(const uint8_t *data, size_t data_len, key_type_t key_type, int *public_key_offset) {
14✔
829
  const uint8_t *p = data;
14✔
830
  size_t remaining = data_len;
14✔
831
  int fail;
14✔
832
  size_t length_size;
14✔
833
  uint16_t length;
834

835
  // 1. Check Cipher DO (A6)
836
  if (remaining < 1 || *p != 0xA6) {
14✔
837
    DBG_MSG("Invalid Cipher DO tag\n");
×
838
    return -1;
×
839
  }
840
  p++;
14✔
841
  remaining--;
14✔
842

843
  // Get Cipher DO length
844
  length = tlv_get_length_safe(p, remaining, &fail, &length_size);
14✔
845
  if (fail || length != remaining - length_size) {
14✔
846
    DBG_MSG("Invalid Cipher DO length\n");
4✔
847
    return -1;
4✔
848
  }
849
  p += length_size;
10✔
850
  remaining -= length_size;
10✔
851

852
  // 2. Check Public Key DO (7F49)
853
  if (remaining < 2 || *p != 0x7F || *(p + 1) != 0x49) {
10✔
854
    DBG_MSG("Invalid Public Key DO\n");
×
855
    return -1;
×
856
  }
857
  p += 2; // Skip 7F49 tag
10✔
858
  remaining -= 2;
10✔
859

860
  // Get Public Key DO length
861
  length = tlv_get_length_safe(p, remaining, &fail, &length_size);
10✔
862
  if (fail || length != remaining - length_size) {
10✔
863
    DBG_MSG("Invalid Public Key DO length\n");
×
864
    return -1;
×
865
  }
866
  p += length_size;
10✔
867
  remaining -= length_size;
10✔
868

869
  // 3. Check External Public Key (86)
870
  if (remaining < 1 || *p != 0x86) {
10✔
871
    DBG_MSG("Invalid External Public Key\n");
×
872
    return -1;
×
873
  }
874
  p++;
10✔
875
  remaining--;
10✔
876

877
  // Get External Public Key length
878
  length = tlv_get_length_safe(p, remaining, &fail, &length_size);
10✔
879
  if (fail || length != remaining - length_size) {
10✔
880
    DBG_MSG("Invalid External Public Key length\n");
×
881
    return -1;
×
882
  }
883
  p += length_size;
10✔
884
  remaining -= length_size;
10✔
885

886
  // 4. Validate key data based on key type
887
  uint16_t expected_pubkey_len = PUBLIC_KEY_LENGTH[key_type];
10✔
888

889
  // For Short Weierstrass curves (SECP*, BP*), we need the 0x04 prefix
890
  if (IS_SHORT_WEIERSTRASS(key_type)) {
10✔
891
    if (length != expected_pubkey_len + 1 || *p != 0x04) {
8✔
892
      DBG_MSG("Invalid public key format for Short Weierstrass curve\n");
×
893
      return -1;
×
894
    }
895
    *public_key_offset = (p - data) + 1; // Skip 0x04 prefix
8✔
896
  } else {                               // For X25519
897
    if (length != expected_pubkey_len) {
2✔
898
      DBG_MSG("Invalid public key length for X25519\n");
×
899
      return -1;
×
900
    }
901
    *public_key_offset = p - data;
2✔
902
  }
903

904
  return 0;
10✔
905
}
906

907
static int openpgp_decipher(const CAPDU *capdu, RAPDU *rapdu) {
20✔
908
#ifndef FUZZ
909
  if (PW1_MODE82() == 0) EXCEPT(SW_SECURITY_STATUS_NOT_SATISFIED);
20✔
910
#endif
911

912
  ck_key_t key;
20✔
913
  if (ck_read_key_metadata(DEC_KEY_PATH, &key.meta) < 0) return -1;
20✔
914

915
  if (key.meta.touch_policy == TOUCH_POLICY_CACHED || key.meta.touch_policy == TOUCH_POLICY_PERMANENT) OPENPGP_TOUCH();
20✔
916
  if (key.meta.origin == KEY_ORIGIN_NOT_PRESENT) EXCEPT(SW_REFERENCE_DATA_NOT_FOUND);
20✔
917
  if ((key.meta.usage & ENCRYPT) == 0) EXCEPT(SW_CONDITIONS_NOT_SATISFIED);
18✔
918
  start_quick_blinking(0);
18✔
919

920
  if (ck_read_key(DEC_KEY_PATH, &key) < 0) {
18✔
921
    ERR_MSG("Read DEC key failed\n");
×
922
    return -1;
×
923
  }
924

925
  DBG_KEY_META(&key.meta);
18✔
926

927
  if (IS_RSA(key.meta.type)) {
21✔
928
    DBG_MSG("Using RSA key: %d\n", key.meta.type);
4✔
929

930
    size_t olen;
4✔
931
    uint8_t invalid_padding;
4✔
932

933
    if (LC < PUBLIC_KEY_LENGTH[key.meta.type] + 1) {
4✔
934
      DBG_MSG("Incorrect LC\n");
1✔
935
      memzero(&key, sizeof(key));
1✔
936
      EXCEPT(SW_WRONG_LENGTH);
1✔
937
    }
938
    if (DATA[0] != 0x00) { // Padding indicator byte (00) for RSA
3✔
939
      DBG_MSG("Incorrect padding indicator\n");
×
940
      memzero(&key, sizeof(key));
×
941
      EXCEPT(SW_WRONG_DATA);
×
942
    }
943

944
    if (rsa_decrypt_pkcs_v15(&key.rsa, DATA + 1, &olen, RDATA, &invalid_padding) < 0) {
3✔
945
      ERR_MSG("Decrypt failed\n");
×
946
      memzero(&key, sizeof(key));
×
947
      if (invalid_padding) EXCEPT(SW_WRONG_DATA);
×
948
      return -1;
×
949
    }
950

951
    memzero(&key, sizeof(key));
3✔
952
    LL = olen;
3✔
953
  } else if (IS_ECC(key.meta.type)) {
24✔
954
    DBG_MSG("Using ECC key: %d\n", key.meta.type);
14✔
955

956
    // check data and length first
957
    // A6 xx Cipher DO
958
    //       7F49 xx Public Key DO
959
    //               86 xx // External Public Key (04 || x || y, for short Weierstrass; x for X25519)
960
    if (LC < 8) {
14✔
961
      DBG_MSG("Incorrect LC\n");
×
962
      memzero(&key, sizeof(key));
×
963
      EXCEPT(SW_WRONG_LENGTH);
×
964
    }
965

966
    int public_key_offset;
14✔
967

968
    // Use our new TLV parsing function to process the data
969
    if (parse_ecc_key_tlv(DATA, LC, key.meta.type, &public_key_offset) < 0) {
14✔
970
      DBG_MSG("Incorrect TLV data structure\n");
4✔
971
      memzero(&key, sizeof(key));
4✔
972
      EXCEPT(SW_WRONG_DATA);
4✔
973
    }
974

975
    if (ecdh(key.meta.type, key.ecc.pri, DATA + public_key_offset, RDATA) < 0) {
10✔
976
      ERR_MSG("ECDH failed\n");
×
977
      memzero(&key, sizeof(key));
×
978
      return -1;
×
979
    }
980

981
    LL = PRIVATE_KEY_LENGTH[key.meta.type];
10✔
982
    memzero(&key, sizeof(key));
10✔
983
  } else {
984
    return -1;
×
985
  }
986

987
  return 0;
13✔
988
}
989

990
static int openpgp_put_data(const CAPDU *capdu, RAPDU *rapdu) {
176✔
991
#ifndef FUZZ
992
  ASSERT_ADMIN();
176✔
993
#endif
994
  int err;
995
  uint16_t tag = (uint16_t)(P1 << 8u) | P2;
176✔
996
  key_meta_t meta;
176✔
997

998
  switch (tag) {
176✔
999
  case TAG_NAME:
1✔
1000
    if (LC > MAX_NAME_LENGTH) EXCEPT(SW_WRONG_LENGTH);
1✔
1001
    if (write_attr(DATA_PATH, TAG_NAME, DATA, LC) < 0) return -1;
1✔
1002
    break;
1✔
1003

1004
  case TAG_LOGIN:
1✔
1005
    if (LC > MAX_LOGIN_LENGTH) EXCEPT(SW_WRONG_LENGTH);
1✔
1006
    if (write_attr(DATA_PATH, TAG_LOGIN, DATA, LC) < 0) return -1;
1✔
1007
    break;
1✔
1008

1009
  case TAG_LANG:
1✔
1010
    if (LC > MAX_LANG_LENGTH) EXCEPT(SW_WRONG_LENGTH);
1✔
1011
    if (write_attr(DATA_PATH, LO(TAG_LANG), DATA, LC) < 0) return -1;
1✔
1012
    break;
1✔
1013

1014
  case TAG_SEX:
1✔
1015
    if (LC > MAX_SEX_LENGTH) EXCEPT(SW_WRONG_LENGTH);
1✔
1016
    if (write_attr(DATA_PATH, LO(TAG_SEX), DATA, LC) < 0) return -1;
1✔
1017
    break;
1✔
1018

1019
  case TAG_URL:
1✔
1020
    if (LC > MAX_URL_LENGTH) EXCEPT(SW_WRONG_LENGTH);
1✔
1021
    if (write_file(DATA_PATH, DATA, 0, LC, 1) < 0) return -1;
1✔
1022
    break;
1✔
1023

1024
  case TAG_CARDHOLDER_CERTIFICATE:
12✔
1025
    if (LC > MAX_CERT_LENGTH) EXCEPT(SW_WRONG_LENGTH);
12✔
1026
    if (current_occurrence == 0)
12✔
1027
      err = write_file(SIG_CERT_PATH, DATA, 0, LC, 1);
6✔
1028
    else if (current_occurrence == 1)
6✔
1029
      err = write_file(DEC_CERT_PATH, DATA, 0, LC, 1);
2✔
1030
    else if (current_occurrence == 2)
4✔
1031
      err = write_file(AUT_CERT_PATH, DATA, 0, LC, 1);
4✔
1032
    else
1033
      EXCEPT(SW_REFERENCE_DATA_NOT_FOUND);
×
1034
    if (err < 0) return -1;
12✔
1035
    current_occurrence = 0;
12✔
1036
    break;
12✔
1037

1038
  case TAG_ALGORITHM_ATTRIBUTES_SIG:
41✔
1039
  case TAG_ALGORITHM_ATTRIBUTES_DEC:
1040
  case TAG_ALGORITHM_ATTRIBUTES_AUT:
1041
    if (LC < 1 || LC > MAX_ATTR_LENGTH) EXCEPT(SW_WRONG_LENGTH);
41✔
1042

1043
    key_type_t type;
1044
    for (type = SECP256R1 /* i.e., 0 */; type < KEY_TYPE_PKC_END; ++type) {
167✔
1045
      const uint8_t *attr = algo_attr[type];
165✔
1046
      if (LC == attr[0]) {
165✔
1047
        if (DATA[0] == ALGO_ID_RSA) { // For RSA, we only care the nbits
70✔
1048
          if (DATA[2] != 0) {
8✔
1049
            DBG_MSG("Invalid attr type\n");
×
1050
            EXCEPT(SW_WRONG_DATA);
×
1051
          }
1052
          if (DATA[1] == 0x08) {
8✔
1053
            type = RSA2048;
5✔
1054
            break;
5✔
1055
          } else if (DATA[1] == 0x0C) {
3✔
1056
            type = RSA3072;
×
1057
            break;
×
1058
          } else if (DATA[1] == 0x10) {
3✔
1059
            type = RSA4096;
3✔
1060
            break;
3✔
1061
          } else {
1062
            DBG_MSG("Invalid attr type\n");
×
1063
            EXCEPT(SW_WRONG_DATA);
×
1064
          }
1065
        } else if (memcmp(&attr[2], &DATA[1], LC - 1) == 0) { // OID
62✔
1066
          break;
31✔
1067
        }
1068
      }
1069
    }
1070
    if (type == KEY_TYPE_PKC_END) {
41✔
1071
      DBG_MSG("Invalid attr type\n");
2✔
1072
      EXCEPT(SW_WRONG_DATA);
2✔
1073
    }
1074
    DBG_MSG("New attr type: %d\n", type);
39✔
1075

1076
    const char *key_path = NULL;
39✔
1077
    if (tag == TAG_ALGORITHM_ATTRIBUTES_SIG) {
39✔
1078
      key_path = SIG_KEY_PATH;
14✔
1079
    } else if (tag == TAG_ALGORITHM_ATTRIBUTES_DEC) {
25✔
1080
      key_path = DEC_KEY_PATH;
13✔
1081
    } else {
1082
      key_path = AUT_KEY_PATH;
12✔
1083
    }
1084

1085
    if (ck_read_key_metadata(key_path, &meta) < 0) return -1;
39✔
1086
    if (type == meta.type) { // Key algorithm attribute unchanged
39✔
1087
      DBG_MSG("Attr unchanged\n");
1✔
1088
      break;
1✔
1089
    }
1090
    if (tag == TAG_ALGORITHM_ATTRIBUTES_DEC) {
38✔
1091
      if (type == ED25519) {
12✔
1092
        DBG_MSG("DEC key disallows ed25519\n");
×
1093
        EXCEPT(SW_WRONG_DATA);
×
1094
      }
1095
    } else { // TAG_ALGORITHM_ATTRIBUTES_SIG or TAG_ALGORITHM_ATTRIBUTES_AUT
1096
      if (type == X25519) {
26✔
1097
        DBG_MSG("SIG/AUT key disallows x25519\n");
×
1098
        EXCEPT(SW_WRONG_DATA);
×
1099
      }
1100
    }
1101
    meta.type = type;
38✔
1102
    meta.origin = KEY_ORIGIN_NOT_PRESENT;
38✔
1103
    if (ck_write_key_metadata(key_path, &meta) < 0) return -1;
38✔
1104
    break;
38✔
1105

1106
  case TAG_PW_STATUS:
38✔
1107
    if (LC != 1) EXCEPT(SW_WRONG_LENGTH);
38✔
1108
    if (DATA[0] != 0x00 && DATA[0] != 0x01) EXCEPT(SW_WRONG_DATA);
38✔
1109
    if (write_attr(DATA_PATH, TAG_PW_STATUS, DATA, LC) < 0) return -1;
38✔
1110
    break;
38✔
1111

1112
  case TAG_KEY_SIG_FINGERPRINT:
10✔
1113
    if (LC != KEY_FINGERPRINT_LENGTH) EXCEPT(SW_WRONG_LENGTH);
10✔
1114
    if (openpgp_key_set_fingerprint(SIG_KEY_PATH, DATA) < 0) return -1;
10✔
1115
    break;
10✔
1116

1117
  case TAG_KEY_DEC_FINGERPRINT:
10✔
1118
    if (LC != KEY_FINGERPRINT_LENGTH) EXCEPT(SW_WRONG_LENGTH);
10✔
1119
    if (openpgp_key_set_fingerprint(DEC_KEY_PATH, DATA) < 0) return -1;
10✔
1120
    break;
10✔
1121

1122
  case TAG_KEY_AUT_FINGERPRINT:
10✔
1123
    if (LC != KEY_FINGERPRINT_LENGTH) EXCEPT(SW_WRONG_LENGTH);
10✔
1124
    if (openpgp_key_set_fingerprint(AUT_KEY_PATH, DATA) < 0) return -1;
10✔
1125
    break;
10✔
1126

1127
  case TAG_KEY_CA1_FINGERPRINT:
1✔
1128
    if (LC != KEY_FINGERPRINT_LENGTH) EXCEPT(SW_WRONG_LENGTH);
1✔
1129
    if (write_attr(DATA_PATH, ATTR_CA1_FP, DATA, KEY_FINGERPRINT_LENGTH) < 0) return -1;
1✔
1130
    break;
1✔
1131

1132
  case TAG_KEY_CA2_FINGERPRINT:
1✔
1133
    if (LC != KEY_FINGERPRINT_LENGTH) EXCEPT(SW_WRONG_LENGTH);
1✔
1134
    if (write_attr(DATA_PATH, ATTR_CA2_FP, DATA, KEY_FINGERPRINT_LENGTH) < 0) return -1;
1✔
1135
    break;
1✔
1136

1137
  case TAG_KEY_CA3_FINGERPRINT:
1✔
1138
    if (LC != KEY_FINGERPRINT_LENGTH) EXCEPT(SW_WRONG_LENGTH);
1✔
1139
    if (write_attr(DATA_PATH, ATTR_CA3_FP, DATA, KEY_FINGERPRINT_LENGTH) < 0) return -1;
1✔
1140
    break;
1✔
1141

1142
  case TAG_KEY_SIG_GENERATION_DATES:
10✔
1143
    if (LC != KEY_DATETIME_LENGTH) EXCEPT(SW_WRONG_LENGTH);
10✔
1144
    if (openpgp_key_set_datetime(SIG_KEY_PATH, DATA) < 0) return -1;
10✔
1145
    break;
10✔
1146

1147
  case TAG_KEY_DEC_GENERATION_DATES:
10✔
1148
    if (LC != KEY_DATETIME_LENGTH) EXCEPT(SW_WRONG_LENGTH);
10✔
1149
    if (openpgp_key_set_datetime(DEC_KEY_PATH, DATA) < 0) return -1;
10✔
1150
    break;
10✔
1151

1152
  case TAG_KEY_AUT_GENERATION_DATES:
10✔
1153
    if (LC != KEY_DATETIME_LENGTH) EXCEPT(SW_WRONG_LENGTH);
10✔
1154
    if (openpgp_key_set_datetime(AUT_KEY_PATH, DATA) < 0) return -1;
10✔
1155
    break;
10✔
1156

1157
  case TAG_RESETTING_CODE:
3✔
1158
    if ((LC > 0 && LC < rc.min_length) || LC > rc.max_length) EXCEPT(SW_WRONG_LENGTH);
3✔
1159
    if (LC == 0) {
3✔
1160
      if (pin_clear(&rc) < 0) return -1;
1✔
1161
      return 0;
1✔
1162
    } else {
1163
      err = pin_update(&rc, DATA, LC);
2✔
1164
      if (err == PIN_IO_FAIL) return -1;
2✔
1165
      if (err == PIN_LENGTH_INVALID) EXCEPT(SW_WRONG_LENGTH);
2✔
1166
      return 0;
2✔
1167
    }
1168

1169
  case TAG_UIF_SIG:
4✔
1170
    if (LC != 2) EXCEPT(SW_WRONG_LENGTH);
4✔
1171
    if (ck_read_key_metadata(SIG_KEY_PATH, &meta) < 0) return -1;
4✔
1172
    if (get_touch_policy(meta.touch_policy) == UIF_PERMANENTLY) EXCEPT(SW_CONDITIONS_NOT_SATISFIED);
4✔
1173
    if (DATA[0] > UIF_PERMANENTLY) EXCEPT(SW_WRONG_DATA);
3✔
1174
    meta.touch_policy = UIF_TO_TOUCH_POLICY[DATA[0]];
3✔
1175
    if (ck_write_key_metadata(SIG_KEY_PATH, &meta) < 0) return -1;
3✔
1176
    break;
3✔
1177

1178
  case TAG_UIF_DEC:
4✔
1179
    if (LC != 2) EXCEPT(SW_WRONG_LENGTH);
4✔
1180
    if (ck_read_key_metadata(DEC_KEY_PATH, &meta) < 0) return -1;
4✔
1181
    if (get_touch_policy(meta.touch_policy) == UIF_PERMANENTLY) EXCEPT(SW_CONDITIONS_NOT_SATISFIED);
4✔
1182
    if (DATA[0] > UIF_PERMANENTLY) EXCEPT(SW_WRONG_DATA);
3✔
1183
    meta.touch_policy = UIF_TO_TOUCH_POLICY[DATA[0]];
3✔
1184
    if (ck_write_key_metadata(DEC_KEY_PATH, &meta) < 0) return -1;
3✔
1185
    break;
3✔
1186

1187
  case TAG_UIF_AUT:
4✔
1188
    if (ck_read_key_metadata(AUT_KEY_PATH, &meta) < 0) return -1;
4✔
1189
    if (get_touch_policy(meta.touch_policy) == UIF_PERMANENTLY) EXCEPT(SW_CONDITIONS_NOT_SATISFIED);
4✔
1190
    if (DATA[0] > UIF_PERMANENTLY) EXCEPT(SW_WRONG_DATA);
3✔
1191
    meta.touch_policy = UIF_TO_TOUCH_POLICY[DATA[0]];
3✔
1192
    if (ck_write_key_metadata(AUT_KEY_PATH, &meta) < 0) return -1;
3✔
1193
    break;
3✔
1194

1195
  case TAG_UIF_CACHE_TIME:
1✔
1196
    if (LC != 1) EXCEPT(SW_WRONG_LENGTH);
1✔
1197
    touch_cache_time = DATA[0];
1✔
1198
    if (write_attr(DATA_PATH, ATTR_TOUCH_CACHE_TIME, &touch_cache_time, sizeof(touch_cache_time)) < 0) return -1;
1✔
1199
    break;
1✔
1200

1201
  default:
1✔
1202
    EXCEPT(SW_WRONG_P1P2);
1✔
1203
  }
1204
  return 0;
167✔
1205
}
1206

1207
static int openpgp_import_key(const CAPDU *capdu, RAPDU *rapdu) {
14✔
1208
#ifndef FUZZ
1209
  ASSERT_ADMIN();
14✔
1210
#endif
1211
  if (P1 != 0x3F || P2 != 0xFF) EXCEPT(SW_WRONG_P1P2);
14✔
1212

1213
  // 4D xx Extended Header list
1214
  //       B6/B8/A4 00/03 Control Reference Template
1215
  //       Below are processed by ck_parse_openpgp
1216
  //       7F48 ...
1217
  //       5F48 ...
1218

1219
  const uint8_t *p = DATA;
14✔
1220
  int fail, len;
14✔
1221
  size_t length_size;
14✔
1222

1223
  // Extended Header list
1224
  if (LC < 2) EXCEPT(SW_WRONG_LENGTH);
14✔
1225
  if (*p++ != 0x4D) EXCEPT(SW_WRONG_DATA);
14✔
1226

1227
  len = tlv_get_length_safe(p, LC - 1, &fail, &length_size);
14✔
1228
  if (fail || len < 2) EXCEPT(SW_WRONG_DATA);
14✔
1229

1230
  if (len + length_size + 1 != LC) EXCEPT(SW_WRONG_LENGTH);
14✔
1231
  p += length_size;
14✔
1232

1233
  // Control Reference Template to indicate the private key: B6, B8 or A4
1234
  uint8_t key_ref = *p;
14✔
1235
  const char *key_path = get_key_path(key_ref);
14✔
1236
  if (key_path == NULL) EXCEPT(SW_WRONG_DATA);
14✔
1237

1238
  // XX 00 or XX 03 84 01 01, XX = B6 / B8 / A4
1239
  ++p;
14✔
1240
  if (*p != 0x00 && *p != 0x03) EXCEPT(SW_WRONG_DATA);
14✔
1241
  p += *p + 1;
14✔
1242

1243
  ck_key_t key;
14✔
1244
  if (ck_read_key_metadata(key_path, &key.meta) < 0) return -1;
14✔
1245
  int err = ck_parse_openpgp(&key, p, LC - (p - DATA));
14✔
1246
  if (err == KEY_ERR_LENGTH)
14✔
1247
    EXCEPT(SW_WRONG_LENGTH);
×
1248
  else if (err == KEY_ERR_DATA)
14✔
1249
    EXCEPT(SW_WRONG_DATA);
×
1250
  else if (err < 0)
14✔
1251
    EXCEPT(SW_UNABLE_TO_PROCESS);
×
1252
  if (ck_write_key(key_path, &key) < 0) {
14✔
1253
    memzero(&key, sizeof(key));
×
1254
    return -1;
×
1255
  }
1256
  memzero(&key, sizeof(key));
14✔
1257

1258
  if (key_ref == 0xB6) return reset_sig_counter();
14✔
1259
  return 0;
8✔
1260
}
1261

1262
static int openpgp_select_data(const CAPDU *capdu, RAPDU *rapdu) {
16✔
1263
  current_occurrence = 0;
16✔
1264
  if (P1 > 2 || P2 != 0x04) EXCEPT(SW_WRONG_P1P2);
16✔
1265
  if (LC != 0x06) EXCEPT(SW_WRONG_LENGTH);
14✔
1266
  if (DATA[0] != 0x60 || DATA[1] != 0x04 || DATA[2] != 0x5C || DATA[3] != 0x02 || DATA[4] != 0x7F || DATA[5] != 0x21)
14✔
1267
    EXCEPT(SW_WRONG_DATA);
2✔
1268
  current_occurrence = P1;
12✔
1269
  return 0;
12✔
1270
}
1271

1272
static int openpgp_get_next_data(const CAPDU *capdu, RAPDU *rapdu) {
6✔
1273
  if (P1 != 0x7F || P2 != 0x21) EXCEPT(SW_WRONG_P1P2);
6✔
1274
  if (LC > 0) EXCEPT(SW_WRONG_LENGTH);
6✔
1275
  int len;
1276
  ++current_occurrence;
6✔
1277
  if (current_occurrence == 1) {
6✔
1278
    len = read_file(DEC_CERT_PATH, RDATA, 0, MAX_CERT_LENGTH);
2✔
1279
  } else if (current_occurrence == 2) {
4✔
1280
    len = read_file(AUT_CERT_PATH, RDATA, 0, MAX_CERT_LENGTH);
2✔
1281
  } else {
1282
    EXCEPT(SW_REFERENCE_DATA_NOT_FOUND);
2✔
1283
  }
1284
  if (len < 0) return -1;
4✔
1285
  LL = len;
4✔
1286
  return 0;
4✔
1287
}
1288

1289
static int openpgp_terminate(const CAPDU *capdu, RAPDU *rapdu) {
11✔
1290
  if (P1 != 0x00 || P2 != 0x00) EXCEPT(SW_WRONG_P1P2);
11✔
1291
  int retries = pin_get_retries(&pw3);
11✔
1292
  if (retries < 0) return -1;
11✔
1293
  if (retries > 0) ASSERT_ADMIN();
11✔
1294
  uint8_t terminated = 1;
11✔
1295
  if (write_attr(DATA_PATH, ATTR_TERMINATED, &terminated, 1) < 0) return -1;
11✔
1296
  return 0;
11✔
1297
}
1298

1299
static int openpgp_activate(const CAPDU *capdu, RAPDU *rapdu) {
11✔
1300
  if (P1 != 0x00 || P2 != 0x00) EXCEPT(SW_WRONG_P1P2);
11✔
1301
  return openpgp_install(1);
11✔
1302
}
1303

1304
static int openpgp_get_challenge(const CAPDU *capdu, RAPDU *rapdu) {
1✔
1305
  if (P1 != 0x00 || P2 != 0x00) EXCEPT(SW_WRONG_P1P2);
1✔
1306
  if (LE > APDU_BUFFER_SIZE) EXCEPT(SW_WRONG_LENGTH);
1✔
1307
  random_buffer(RDATA, LE);
1✔
1308
  LL = LE;
1✔
1309
  return 0;
1✔
1310
}
1311

1312
int openpgp_process_apdu(const CAPDU *capdu, RAPDU *rapdu) {
1313
  LL = 0;
2,508✔
1314
  SW = SW_NO_ERROR;
2,508✔
1315
  if (CLA != 0x00) EXCEPT(SW_CLA_NOT_SUPPORTED);
2,508✔
1316

1317
  if (INS == OPENPGP_INS_SELECT_DATA) {
2,508✔
1318
    state = STATE_SELECT_DATA;
16✔
1319
  } else if (state == STATE_NORMAL) {
2,492✔
1320
    if (INS == OPENPGP_INS_GET_NEXT_DATA) EXCEPT(SW_CONDITIONS_NOT_SATISFIED);
2,469✔
1321
    if (INS == OPENPGP_INS_GET_DATA && P1 == 0x7F && P2 == 0x21) {
2,469✔
1322
      state = STATE_GET_CERT_DATA;
6✔
1323
    }
1324
  } else if (state == STATE_SELECT_DATA) {
23✔
1325
    if (INS == OPENPGP_INS_GET_NEXT_DATA) EXCEPT(SW_CONDITIONS_NOT_SATISFIED);
13✔
1326
    if (INS == OPENPGP_INS_GET_DATA && P1 == 0x7F && P2 == 0x21) {
13✔
1327
      state = STATE_GET_CERT_DATA;
4✔
1328
    } else {
1329
      if (INS != OPENPGP_INS_PUT_DATA || P1 != 0x7F || P2 != 0x21) current_occurrence = 0;
9✔
1330
      state = STATE_NORMAL;
9✔
1331
    }
1332
  } else {
1333
    if (INS != OPENPGP_INS_GET_NEXT_DATA) {
10✔
1334
      current_occurrence = 0;
4✔
1335
      state = STATE_NORMAL;
4✔
1336
    }
1337
  }
1338

1339
  uint8_t terminated;
2,508✔
1340
  if (read_attr(DATA_PATH, ATTR_TERMINATED, &terminated, 1) < 0) EXCEPT(SW_UNABLE_TO_PROCESS);
2,508✔
1341
#ifndef FUZZ
1342
  if (terminated == 1 && INS != OPENPGP_INS_ACTIVATE && INS != OPENPGP_INS_SELECT) EXCEPT(SW_TERMINATED);
2,508✔
1343
#endif
1344

1345
  int ret;
1346
  switch (INS) {
2,507✔
1347
  case OPENPGP_INS_SELECT:
46✔
1348
    ret = openpgp_select(capdu, rapdu);
46✔
1349
    break;
46✔
1350
  case OPENPGP_INS_ACTIVATE:
12✔
1351
    if (terminated == 0) EXCEPT(SW_CONDITIONS_NOT_SATISFIED);
12✔
1352
    ret = openpgp_activate(capdu, rapdu);
11✔
1353
    break;
11✔
1354
  case OPENPGP_INS_GET_DATA:
673✔
1355
    ret = openpgp_get_data(capdu, rapdu);
673✔
1356
    break;
673✔
1357
  case OPENPGP_INS_SELECT_DATA:
16✔
1358
    ret = openpgp_select_data(capdu, rapdu);
16✔
1359
    break;
16✔
1360
  case OPENPGP_INS_GET_NEXT_DATA:
6✔
1361
    ret = openpgp_get_next_data(capdu, rapdu);
6✔
1362
    break;
6✔
1363
  case OPENPGP_INS_VERIFY:
188✔
1364
    ret = openpgp_verify(capdu, rapdu);
188✔
1365
    break;
188✔
1366
  case OPENPGP_INS_CHANGE_REFERENCE_DATA:
7✔
1367
    ret = openpgp_change_reference_data(capdu, rapdu);
7✔
1368
    break;
7✔
1369
  case OPENPGP_INS_RESET_RETRY_COUNTER:
3✔
1370
    ret = openpgp_reset_retry_counter(capdu, rapdu);
3✔
1371
    break;
3✔
1372
  case OPENPGP_INS_PUT_DATA:
176✔
1373
    ret = openpgp_put_data(capdu, rapdu);
176✔
1374
    break;
176✔
1375
  case OPENPGP_INS_IMPORT_KEY:
14✔
1376
    ret = openpgp_import_key(capdu, rapdu);
14✔
1377
    break;
14✔
1378
  case OPENPGP_INS_GENERATE_ASYMMETRIC_KEY_PAIR:
1,288✔
1379
    ret = openpgp_generate_asymmetric_key_pair(capdu, rapdu);
1,288✔
1380
    stop_blinking();
1,288✔
1381
    break;
1,288✔
1382
  case OPENPGP_INS_PSO:
45✔
1383
    if (P1 == 0x9E && P2 == 0x9A) {
45✔
1384
      ret = openpgp_sign_or_auth(capdu, rapdu, true);
24✔
1385
      stop_blinking();
24✔
1386
      break;
24✔
1387
    }
1388
    if (P1 == 0x80 && P2 == 0x86) {
21✔
1389
      ret = openpgp_decipher(capdu, rapdu);
20✔
1390
      stop_blinking();
20✔
1391
      break;
20✔
1392
    }
1393
    EXCEPT(SW_WRONG_P1P2);
1✔
1394
  case OPENPGP_INS_INTERNAL_AUTHENTICATE:
20✔
1395
    ret = openpgp_sign_or_auth(capdu, rapdu, false);
20✔
1396
    stop_blinking();
20✔
1397
    break;
20✔
1398
  case OPENPGP_INS_GET_CHALLENGE:
1✔
1399
    ret = openpgp_get_challenge(capdu, rapdu);
1✔
1400
    break;
1✔
1401
  case OPENPGP_INS_TERMINATE:
11✔
1402
    ret = openpgp_terminate(capdu, rapdu);
11✔
1403
    break;
11✔
1404
  default:
1✔
1405
    EXCEPT(SW_INS_NOT_SUPPORTED);
1✔
1406
  }
1407

1408
  if (ret < 0) EXCEPT(SW_UNABLE_TO_PROCESS);
2,504✔
1409
  return 0;
2,504✔
1410
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc