3 #include "reader-common.h"
7 static const uint8_t dgcrypt_atr
[8] = { 0x3B, 0xE9, 0x00, 0x00, 0x81, 0x31, 0xC3, 0x45 };
8 static const uint8_t cmd_CWKEY
[5] = { 0x81, 0xD0, 0x00, 0x01, 0x08 };
9 //static const uint8_t cmd_CAID[5] = { 0x81, 0xC0, 0x00, 0x01, 0x0A };
10 static const uint8_t cmd_SERIAL
[5] = { 0x81, 0xD1, 0x00, 0x01, 0x10 };
11 static const uint8_t cmd_LABEL
[5] = { 0x81, 0xD2, 0x00, 0x01, 0x10 };
12 //static const uint8_t cmd_SUBSYS[5] = { 0x81, 0xDD, 0x00, 0x10, 0x04 };
13 static const uint8_t cmd_ECM
[3] = { 0x80, 0xEA, 0x80 };
17 uint8_t session_key
[16];
20 static int32_t dgcrypt_cmd(struct s_reader
*rdr
, const uint8_t *buf
, const int32_t buflen
, uint8_t *response
, uint16_t *response_length
, uint16_t min_response_len
)
28 rdr_log(rdr
, "SEND -> %s(%d)", cs_hexdump(1, buf
, buflen
, tmp
, sizeof(tmp
)), buflen
);
30 int32_t ret
= reader_cmd2icc(rdr
, buf
, buflen
, response
, response_length
);
35 rdr_log(rdr
, "RECV <- %s(%d) ret=%d", cs_hexdump(1, response
, *response_length
, tmp
, sizeof(tmp
)), *response_length
, ret
);
37 // reader_cmd2icc retuns ERROR=1, OK=0 - the opposite of OK and ERROR defines in reader-common.h
41 rdr_log(rdr
, "ERROR: reader_cmd2icc() ret=%d", ret
);
45 if(*response_length
< 2 || *response_length
< min_response_len
)
47 rdr_log(rdr
, "ERROR: response_length=%d < min_response_length=%d", *response_length
, min_response_len
);
48 return ERROR
; // Response is two short
51 if(response
[*response_length
- 2] != 0x90 || response
[*response_length
- 1] != 0x00)
53 rdr_log(rdr
, "ERROR: response[-2] != 0x90 its 0x%02X", response
[*response_length
- 2]);
54 rdr_log(rdr
, "ERROR: response[-1] != 0x00 its 0x%02X", response
[*response_length
- 1]);
55 return ERROR
; // The reader responded with "command not OK"
60 static int32_t dgcrypt_card_init(struct s_reader
*rdr
, ATR
*newatr
)
65 if(atr_size
< sizeof(dgcrypt_atr
))
68 // Full ATR: 3B E9 00 00 81 31 C3 45 99 63 74 69 19 99 12 56 10 EC
69 if(memcmp(atr
, dgcrypt_atr
, sizeof(dgcrypt_atr
)) != 0)
72 if(!cs_malloc(&rdr
->csystem_data
, sizeof(struct dgcrypt_data
)))
75 struct dgcrypt_data
*csystem_data
= rdr
->csystem_data
;
77 rdr_log(rdr
, "[dgcrypt-reader] card detected.");
79 memset(rdr
->sa
, 0, sizeof(rdr
->sa
));
80 memset(rdr
->prid
, 0, sizeof(rdr
->prid
));
81 memset(rdr
->hexserial
, 0, sizeof(rdr
->hexserial
));
87 // Send: 81 D0 00 01 08
88 // Recv: 32 86 17 D5 2C 66 61 14 90 00
89 if(!dgcrypt_cmd(rdr
, cmd_CWKEY
, sizeof(cmd_CWKEY
), cta_res
, &cta_lr
, 8))
91 memcpy(csystem_data
->session_key
+ 0, cta_res
, 8);
92 memcpy(csystem_data
->session_key
+ 8, cta_res
, 8);
95 // Send: 81 C0 00 01 0A
97 // if (!dgcrypt_cmd(rdr, cmd_CAID, sizeof(cmd_CAID), cta_res, &cta_lr, 2))
99 // rdr->caid = (cta_res[0] << 8) | cta_res[1];
102 // Send: 81 D1 00 01 10
103 // Recv: 00 0D DB 08 71 0D D5 0C 30 30 30 30 30 30 30 30 90 00
104 if(!dgcrypt_cmd(rdr
, cmd_SERIAL
, sizeof(cmd_SERIAL
), cta_res
, &cta_lr
, 8))
106 memcpy(rdr
->hexserial
, cta_res
+ 1, 7);
109 // Send: 81 D2 00 01 10
110 // Recv: 50 61 79 5F 54 56 5F 43 61 72 64 00 00 00 00 00 90 00
111 // Txt: P a y _ T V _ C a r d
112 if(!dgcrypt_cmd(rdr
, cmd_LABEL
, sizeof(cmd_LABEL
), cta_res
, &cta_lr
, 16))
115 memset(label
, 0, sizeof(label
));
116 memcpy(label
, cta_res
, 16);
118 // Get subsystem - !FIXME! We are not using the answer of this command!
119 // Send: 81 DD 00 10 04
120 // Recv: 00 55 00 55 90 00
121 if(!dgcrypt_cmd(rdr
, cmd_LABEL
, sizeof(cmd_LABEL
), cta_res
, &cta_lr
, 4))
124 rdr_log_sensitive(rdr
, "CAID: 0x%04X, Serial: {%"PRIu64
"} HexSerial: {%02X %02X %02X %02X %02X %02X %02X} Label: {%s}",
126 b2ll(7, rdr
->hexserial
),
127 rdr
->hexserial
[0], rdr
->hexserial
[1], rdr
->hexserial
[2],
128 rdr
->hexserial
[3], rdr
->hexserial
[4], rdr
->hexserial
[5], rdr
->hexserial
[6],
134 static int32_t dgcrypt_do_ecm(struct s_reader
*rdr
, const ECM_REQUEST
*er
, struct s_ecm_answer
*ea
)
137 uint8_t cmd_buffer
[256];
138 struct dgcrypt_data
*csystem_data
= rdr
->csystem_data
;
140 memcpy(cmd_buffer
, er
->ecm
, er
->ecm
[2] + 3);
141 // Replace The first 3 bytes of the ECM with the command
142 memcpy(cmd_buffer
, cmd_ECM
, sizeof(cmd_ECM
));
145 // Send: 80 EA 80 00 55 00 00 3F 90 03 00 00 18 5D 82 4E 01 C4 2D 60 12 ED 34 37 ED 72 .. .. ..
146 // Recv: 72 25 8D A1 0D 0D D2 44 EE ED 51 2F 3B 5D 19 63 E6 90 00
147 if(!dgcrypt_cmd(rdr
, cmd_buffer
, er
->ecm
[2] + 3, cta_res
, &cta_lr
, 17))
150 if(cta_res
[0] != 0x72) // CW response MUST start with 0x72
154 for(i
= 0; i
< 16; i
++)
156 ea
->cw
[i
] = cta_res
[1 + i
] ^ csystem_data
->session_key
[i
];
161 static int32_t dgcrypt_get_emm_filter(struct s_reader
*rdr
__attribute__((unused
)), struct s_csystem_emm_filter
**emm_filters
__attribute__((unused
)), unsigned int *filter_count
)
167 const struct s_cardsystem reader_dgcrypt
=
170 .caids
= (uint16_t[]){ 0x4ABF, 0 },
171 // DGCrypt system does not send EMMs
172 .card_init
= dgcrypt_card_init
,
173 .do_ecm
= dgcrypt_do_ecm
,
174 .get_emm_filter
= dgcrypt_get_emm_filter
,