-
Notifications
You must be signed in to change notification settings - Fork 8
/
atr_test.c
94 lines (89 loc) · 2.88 KB
/
atr_test.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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "atr.h"
#include <check.h>
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#define NO_UPDATE (0xFFFF)
static const struct sample {
unsigned char data[32];
unsigned len;
unsigned first_protocol;
unsigned speed;
} samples[] = {
{ // T0 only and 2 historical bytes.
.data = {0x3B, 0x02, 0x36, 0x02}, .len = 4
},
{ // No historical bytes, and no checksum.
.data = {0x3B, 0x10, 0x16}, .len = 3,
},
{ // No historical bytes. Checksum included since T=1 signaled.
.data = {0x3B, 0x90, 0x16, 0x01, 0x87}, .len = 5,
.first_protocol = 1,
},
{ // T=0 and T=1 signaled, some historical data and checksum.
.data = {0x3B, 0x84, 0x80, 0x01, 0x00, 0x81, 0x87, 0x00, 0x03},
.len = 9,
},
{ // With TD(2) and TA(3).
.data = {0x3B, 0xF6, 0x18, 0x00, 0xFF, 0x81, 0x31, 0xFE,
0x45, 0x4A, 0x43, 0x4F, 0x50, 0x33, 0x30, 0x0F},
.len = 16, .first_protocol = 1,
},
{ // T=0 and T=15 signaled.
.data = {0x3B, 0x93, 0x95, 0x80, 0x1F, 0xC7, 0x80, 0x31, 0x80, 0x6F},
.len = 10,
},
{ // TA(1) with speed, TA(2) with bit 5 cleared, new speed in use.
.data = {0x3B, 0xD2, 0x13, 0xFF, 0x10, 0x80, 0x07, 0x14},
.len = 8, .speed = 0x13,
},
{ // TA(1) with speed, TA(2) with bit 5 set, no speed change.
.data = {0x3B, 0xD2, 0x13, 0xFF, 0x10, 0x90, 0x07, 0x14},
.len = 8,
},
{ // TD(1) present but as last byte.
.data = {0x3B, 0x80, 0x00}, .len = 3,
},
{ // Minimal ATR.
.data = {0x3B, 0x00}, .len = 2,
},
{ // Inverse convention (converted at session layer).
.data = {0x3F, 0x65, 0x25, 0x08, 0x33, 0x04, 0x20, 0x90, 0x00},
.len = 9,
}
};
START_TEST(parse_sample)
{
struct atr atr;
const struct sample *s = &samples[_i];
int pos;
unsigned new_proto = 0;
unsigned new_speed = NO_UPDATE;
atr_init(&atr);
for (pos = 0; pos < s->len; pos++) {
unsigned complete = 0;
enum result res = atr_analyze(&atr, s->data[pos], &complete);
if (pos + 1 == s->len) {
// Last byte, should signal packet from card, and completed.
ck_assert_uint_eq(res, ANSWER_TO_RESET);
ck_assert_uint_ne(complete, 0);
} else {
// Mid-packet, keep going.
ck_assert_uint_eq(res, CONTINUE);
ck_assert_uint_eq(complete, 0);
}
}
atr_result(&atr, &new_proto, &new_speed);
ck_assert_uint_eq(new_proto, s->first_protocol);
if (s->speed) {
ck_assert_uint_eq(new_speed, s->speed);
} else {
ck_assert_uint_eq(new_speed, NO_UPDATE);
}
}
END_TEST
Suite* atr_tests(void) {
Suite* suite = suite_create("atr");
TCase* test = tcase_create("atr");
tcase_add_loop_test(test, parse_sample, 0, ARRAY_SIZE(samples));
suite_add_tcase(suite, test);
return suite;
}