Skip to content

Commit

Permalink
Give each packet type its own identifier
Browse files Browse the repository at this point in the history
With embedded direction data.
  • Loading branch information
yarrick committed Aug 15, 2024
1 parent 0c9b161 commit 53c6c47
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 98 deletions.
4 changes: 2 additions & 2 deletions atr.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static int handle_t_bits(struct atr *atr, unsigned char data, unsigned *complete
// No more T bytes or historical bytes
atr->state = ATR_DONE;
if (complete) *complete = 1;
return PACKET_FROM_CARD;
return ANSWER_TO_RESET;
}
return CONTINUE;
}
Expand Down Expand Up @@ -91,7 +91,7 @@ enum result atr_analyze(struct atr *atr, unsigned char data, unsigned *complete)
case WAIT_END:
atr->state = ATR_DONE;
if (complete) *complete = 1;
return PACKET_FROM_CARD;
return ANSWER_TO_RESET;
default:
return STATE_ERROR;
}
Expand Down
2 changes: 1 addition & 1 deletion atr_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ START_TEST(parse_sample)
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, PACKET_FROM_CARD);
ck_assert_uint_eq(res, ANSWER_TO_RESET);
ck_assert_uint_ne(complete, 0);
} else {
// Mid-packet, keep going.
Expand Down
26 changes: 13 additions & 13 deletions data.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static enum result t0_transfer_direction(struct data_t0 *data) {
case 0xE0: // CREATE FILE
case 0xE2: // APPEND RECORD
case 0xE4: // DELETE FILE
return PACKET_TO_CARD;
return T0_DATA_CMD_BODY;

// First data transfer (if any) will be from the card.
case 0x70: // MANAGE CHANNEL
Expand All @@ -46,7 +46,7 @@ static enum result t0_transfer_direction(struct data_t0 *data) {
case 0xB2: // READ RECORD
case 0xC0: // GET RESPONSE
case 0xCA: // GET DATA
return PACKET_FROM_CARD;
return T0_DATA_RESP_BODY;

case 0xA4: // SELECT
// ISO 7816-4 Table 39: P1 meaning for SELECT command.
Expand All @@ -57,14 +57,14 @@ static enum result t0_transfer_direction(struct data_t0 *data) {
case 0x08: // Select from the MF (data = Path without MF id)
case 0x09: // Select from the current DF
// (data = path without the current DF identifier)
return PACKET_TO_CARD;
return T0_DATA_CMD_BODY;

case 0x03: // Select parent DF of the current DF (data absent)
return PACKET_FROM_CARD;
return T0_DATA_RESP_BODY;
}
break;
}
return PACKET_UNKNOWN;
return T0_DATA_UNK_BODY;
}

enum result data_t0_analyze(struct data *data, unsigned char byte) {
Expand All @@ -78,17 +78,17 @@ enum result data_t0_analyze(struct data *data, unsigned char byte) {
t0->p1 = byte;
} else if (t0->command_bytes_seen == 5) {
t0->p3_len = byte;
if (t0_transfer_direction(t0) == PACKET_FROM_CARD) {
if (PACKET_DIR(t0_transfer_direction(t0)) == DIR_FROM_CARD) {
// This is response length so 0 means 256.
// Note that this direction check has false negatives.
if (byte == 0x00) t0->p3_len = 256;
}
t0->state = PROCEDURE_BYTE;
return PACKET_TO_CARD;
return T0_DATA_CMD_HEADER;
}
break;
case PROCEDURE_BYTE:
if (byte == 0x60) return PACKET_FROM_CARD;
if (byte == 0x60) return T0_DATA_NULL;
if ((byte & 0xF0) == 0x60 || (byte & 0xF0) == 0x90) {
t0->state = SW2;
}
Expand All @@ -97,22 +97,22 @@ enum result data_t0_analyze(struct data *data, unsigned char byte) {
if (t0->transfer_bytes_seen < t0->p3_len) {
t0->state = TRANSFER_ALL;
}
return PACKET_FROM_CARD;
return T0_DATA_ACK;
}
if ((byte ^ 0xFF) == t0->ins) {
// Expect a single byte if not all sent already
if (t0->transfer_bytes_seen < t0->p3_len) {
t0->state = TRANSFER_ONE;
}
return PACKET_FROM_CARD;
return T0_DATA_ACK;
}
break;
case SW2:
// Completion of whole exchange.
t0->state = COMMAND;
t0->command_bytes_seen = 0;
t0->transfer_bytes_seen = 0;
return PACKET_FROM_CARD;
return T0_DATA_RESP_SW;
case TRANSFER_ALL:
t0->transfer_bytes_seen++;
if (t0->p3_len == t0->transfer_bytes_seen) {
Expand All @@ -139,8 +139,8 @@ enum result data_t1_analyze(struct data *data, unsigned char byte) {
}
if (t1->msg_length && t1->bytes_seen == t1->msg_length) {
// End of block, reset counters for next block
enum result res = PACKET_TO_CARD;
if (t1->direction_from_card) res = PACKET_FROM_CARD;
enum result res = T1_DATA_CMD;
if (t1->direction_from_card) res = T1_DATA_RESP;
t1->bytes_seen = 0;
t1->msg_length = 0;
// Flip direction for next packet
Expand Down
82 changes: 41 additions & 41 deletions data_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ START_TEST(t0_empty_ack)
T0_BYTE(&data, 0xCA, CONTINUE);
T0_BYTE(&data, 0x01, CONTINUE);
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0x04, PACKET_TO_CARD);
T0_BYTE(&data, 0x04, T0_DATA_CMD_HEADER);
// ACK
T0_BYTE(&data, 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0xCA, T0_DATA_ACK);
// Remaining bytes
T0_BYTE(&data, 0x01, CONTINUE);
T0_BYTE(&data, 0x02, CONTINUE);
T0_BYTE(&data, 0x03, CONTINUE);
T0_BYTE(&data, 0x04, PACKET_FROM_CARD);
T0_BYTE(&data, 0x04, T0_DATA_RESP_BODY);
// Extra ACKs, no data remaining
T0_BYTE(&data, 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0xCA, T0_DATA_ACK);
T0_BYTE(&data, 0xCA, T0_DATA_ACK);
T0_BYTE(&data, 0xCA, T0_DATA_ACK);
// Status bytes
T0_BYTE(&data, 0x90, CONTINUE);
T0_BYTE(&data, 0x00, PACKET_FROM_CARD);
T0_BYTE(&data, 0x00, T0_DATA_RESP_SW);
}
END_TEST

Expand All @@ -41,25 +41,25 @@ START_TEST(t0_null_procedure_byte)
T0_BYTE(&data, 0xCA, CONTINUE);
T0_BYTE(&data, 0x01, CONTINUE);
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0x04, PACKET_TO_CARD);
T0_BYTE(&data, 0x04, T0_DATA_CMD_HEADER);
// NULL procedure byte
T0_BYTE(&data, 0x60, PACKET_FROM_CARD);
T0_BYTE(&data, 0x60, PACKET_FROM_CARD);
T0_BYTE(&data, 0x60, PACKET_FROM_CARD);
T0_BYTE(&data, 0x60, PACKET_FROM_CARD);
T0_BYTE(&data, 0x60, T0_DATA_NULL);
T0_BYTE(&data, 0x60, T0_DATA_NULL);
T0_BYTE(&data, 0x60, T0_DATA_NULL);
T0_BYTE(&data, 0x60, T0_DATA_NULL);
// ACK
T0_BYTE(&data, 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0xCA, T0_DATA_ACK);
// Remaining bytes
T0_BYTE(&data, 0x01, CONTINUE);
T0_BYTE(&data, 0x02, CONTINUE);
T0_BYTE(&data, 0x03, CONTINUE);
T0_BYTE(&data, 0x04, PACKET_FROM_CARD);
T0_BYTE(&data, 0x04, T0_DATA_RESP_BODY);
// NULL procedure byte
T0_BYTE(&data, 0x60, PACKET_FROM_CARD);
T0_BYTE(&data, 0x60, PACKET_FROM_CARD);
T0_BYTE(&data, 0x60, T0_DATA_NULL);
T0_BYTE(&data, 0x60, T0_DATA_NULL);
// Status bytes
T0_BYTE(&data, 0x90, CONTINUE);
T0_BYTE(&data, 0x00, PACKET_FROM_CARD);
T0_BYTE(&data, 0x00, T0_DATA_RESP_SW);
}
END_TEST

Expand All @@ -72,25 +72,25 @@ START_TEST(t0_single_byte_transfer)
T0_BYTE(&data, 0xCA, CONTINUE);
T0_BYTE(&data, 0x01, CONTINUE);
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0x04, PACKET_TO_CARD);
T0_BYTE(&data, 0x04, T0_DATA_CMD_HEADER);

// Single-byte ACK
T0_BYTE(&data, 0xFF ^ 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0xFF ^ 0xCA, T0_DATA_ACK);
// One byte
T0_BYTE(&data, 0x01, PACKET_FROM_CARD);
T0_BYTE(&data, 0x01, T0_DATA_RESP_BODY);
// Repeat
T0_BYTE(&data, 0xFF ^ 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0x02, PACKET_FROM_CARD);
T0_BYTE(&data, 0xFF ^ 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0x03, PACKET_FROM_CARD);
T0_BYTE(&data, 0xFF ^ 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0x04, PACKET_FROM_CARD);
T0_BYTE(&data, 0xFF ^ 0xCA, T0_DATA_ACK);
T0_BYTE(&data, 0x02, T0_DATA_RESP_BODY);
T0_BYTE(&data, 0xFF ^ 0xCA, T0_DATA_ACK);
T0_BYTE(&data, 0x03, T0_DATA_RESP_BODY);
T0_BYTE(&data, 0xFF ^ 0xCA, T0_DATA_ACK);
T0_BYTE(&data, 0x04, T0_DATA_RESP_BODY);
// Extra single-byte acks with no data
T0_BYTE(&data, 0xFF ^ 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0xFF ^ 0xCA, PACKET_FROM_CARD);
T0_BYTE(&data, 0xFF ^ 0xCA, T0_DATA_ACK);
T0_BYTE(&data, 0xFF ^ 0xCA, T0_DATA_ACK);
// Status bytes
T0_BYTE(&data, 0x90, CONTINUE);
T0_BYTE(&data, 0x00, PACKET_FROM_CARD);
T0_BYTE(&data, 0x00, T0_DATA_RESP_SW);
}
END_TEST

Expand All @@ -103,33 +103,33 @@ START_TEST(t0_get_response)
T0_BYTE(&data, 0xA4, CONTINUE);
T0_BYTE(&data, 0x04, CONTINUE);
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0x04, PACKET_TO_CARD);
T0_BYTE(&data, 0x04, T0_DATA_CMD_HEADER);
// ACK
T0_BYTE(&data, 0xA4, PACKET_FROM_CARD);
T0_BYTE(&data, 0xA4, T0_DATA_ACK);
// DF name
T0_BYTE(&data, 'T', CONTINUE);
T0_BYTE(&data, 'e', CONTINUE);
T0_BYTE(&data, 's', CONTINUE);
T0_BYTE(&data, 't', PACKET_TO_CARD);
T0_BYTE(&data, 't', T0_DATA_CMD_BODY);
// Status bytes
T0_BYTE(&data, 0x61, CONTINUE);
T0_BYTE(&data, 0x03, PACKET_FROM_CARD);
T0_BYTE(&data, 0x03, T0_DATA_RESP_SW);

// Get response
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0xC0, CONTINUE);
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0x03, PACKET_TO_CARD);
T0_BYTE(&data, 0x03, T0_DATA_CMD_HEADER);
// ACK
T0_BYTE(&data, 0xC0, PACKET_FROM_CARD);
T0_BYTE(&data, 0xC0, T0_DATA_ACK);
// Response bytes
T0_BYTE(&data, 'Y', CONTINUE);
T0_BYTE(&data, 'a', CONTINUE);
T0_BYTE(&data, 'y', PACKET_FROM_CARD);
T0_BYTE(&data, 'y', T0_DATA_RESP_BODY);
// Status bytes
T0_BYTE(&data, 0x90, CONTINUE);
T0_BYTE(&data, 0x00, PACKET_FROM_CARD);
T0_BYTE(&data, 0x00, T0_DATA_RESP_SW);
}
END_TEST

Expand All @@ -142,17 +142,17 @@ START_TEST(t0_unknown_direction)
T0_BYTE(&data, 0x23, CONTINUE);
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0x00, CONTINUE);
T0_BYTE(&data, 0x04, PACKET_TO_CARD);
T0_BYTE(&data, 0x04, T0_DATA_CMD_HEADER);
// ACK
T0_BYTE(&data, 0x23, PACKET_FROM_CARD);
T0_BYTE(&data, 0x23, T0_DATA_ACK);
// Payload bytes
T0_BYTE(&data, 0x01, CONTINUE);
T0_BYTE(&data, 0x02, CONTINUE);
T0_BYTE(&data, 0x03, CONTINUE);
T0_BYTE(&data, 0x04, PACKET_UNKNOWN);
T0_BYTE(&data, 0x04, T0_DATA_UNK_BODY);
// Status bytes
T0_BYTE(&data, 0x90, CONTINUE);
T0_BYTE(&data, 0x00, PACKET_FROM_CARD);
T0_BYTE(&data, 0x00, T0_DATA_RESP_SW);
}
END_TEST

Expand Down
32 changes: 26 additions & 6 deletions packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,33 @@

#include <sys/time.h>

enum packet_dir {
DIR_UNKNOWN = 0x00,
DIR_FROM_CARD = 0x01,
DIR_TO_CARD = 0x02,
INVALID_ERROR = 0x0E,
INVALID_NOISE = 0x0F,
};

#define PACKET_DIR(res) ((res) & 0x0F)

enum result {
CONTINUE = 0, // Need more bytes
PACKET_TO_CARD, // End of packet, to card
PACKET_FROM_CARD, // End of packet, from card
PACKET_UNKNOWN, // End of packet, unclear direction
STATE_ERROR = 99, // Should not get more bytes
NOISE = 100, // Suspected noise, ignored
CONTINUE = 0x00, // Need more bytes
// Packet direction encoded in lower nibble.
ANSWER_TO_RESET = 0x100 | DIR_FROM_CARD,
PPS_REQ = 0x200 | DIR_TO_CARD,
PPS_RESP = 0x210 | DIR_FROM_CARD,
T0_DATA_CMD_HEADER = 0x300 | DIR_TO_CARD,
T0_DATA_ACK = 0x310 | DIR_FROM_CARD,
T0_DATA_NULL = 0x320 | DIR_FROM_CARD,
T0_DATA_CMD_BODY = 0x330 | DIR_TO_CARD,
T0_DATA_RESP_BODY = 0x340 | DIR_FROM_CARD,
T0_DATA_UNK_BODY = 0x350 | DIR_UNKNOWN,
T0_DATA_RESP_SW = 0x360 | DIR_FROM_CARD,
T1_DATA_CMD = 0x400 | DIR_TO_CARD,
T1_DATA_RESP = 0x410 | DIR_FROM_CARD,
STATE_ERROR = 0x1FF0 | INVALID_ERROR, // Should not get more bytes
NOISE = 0x2FF0 | INVALID_NOISE, // Suspected noise, ignored
};

struct packet {
Expand Down
10 changes: 5 additions & 5 deletions pps.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static int pps_msg_len(unsigned char pps0) {
}

static int pps_parse(struct pps_msg *msg, unsigned char data,
enum result packet_direction) {
enum result packet_res) {
msg->bytes_seen++;
if (msg->bytes_seen == 2) {
// PPS0
Expand All @@ -25,20 +25,20 @@ static int pps_parse(struct pps_msg *msg, unsigned char data,
// PPS1
msg->pps1 = data;
}
if (msg->bytes_seen == msg->msg_length) return packet_direction;
if (msg->bytes_seen == msg->msg_length) return packet_res;
return CONTINUE;
}

enum result pps_analyze(struct pps *pps, unsigned char data,
unsigned *complete) {
if (pps->proposal.bytes_seen < 2 ||
pps->proposal.bytes_seen < pps->proposal.msg_length) {
return pps_parse(&pps->proposal, data, PACKET_TO_CARD);
return pps_parse(&pps->proposal, data, PPS_REQ);
}
if (pps->reply.bytes_seen < 2 ||
pps->reply.bytes_seen < pps->reply.msg_length) {
int result = pps_parse(&pps->reply, data, PACKET_FROM_CARD);
if (result == PACKET_FROM_CARD && complete) {
int result = pps_parse(&pps->reply, data, PPS_RESP);
if (result == PPS_RESP && complete) {
*complete = 1;
}
return result;
Expand Down
12 changes: 6 additions & 6 deletions scsniff.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ static void handle_packet(struct packet *packet) {
unsigned i;
timersub(&packet->time, &reset_time, &diff);
printf("+%ld.%06lds | ", diff.tv_sec, diff.tv_usec);
switch (packet->result) {
case NOISE: printf("NOISE??"); break;
case PACKET_TO_CARD: printf("CARD<<<"); break;
case PACKET_FROM_CARD: printf("CARD>>>"); break;
case PACKET_UNKNOWN: printf("CARD<?>"); break;
default: printf("ERROR!!"); break;
switch (PACKET_DIR(packet->result)) {
case INVALID_NOISE: printf("NOISE??"); break;
case DIR_TO_CARD: printf("CARD<<<"); break;
case DIR_FROM_CARD: printf("CARD>>>"); break;
case DIR_UNKNOWN: printf("CARD<?>"); break;
default: printf("ERROR!!"); break;
}
printf(" |");
for (i = 0; i < packet->data_length; i++) {
Expand Down
Loading

0 comments on commit 53c6c47

Please sign in to comment.