1 //-----------------------------------------------------------------------------
2 // Iceman, February 2020
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // Support functions for smart card
9 //-----------------------------------------------------------------------------
10 #include "cardhelper.h"
13 #include "cmdparser.h"
14 #include "cmdsmartcard.h"
18 #define CARD_INS_DECRYPT 0x01
19 #define CARD_INS_ENCRYPT 0x02
20 #define CARD_INS_VEIRFY_RRG 0x05
21 #define CARD_INS_DECODE 0x06
22 #define CARD_INS_NUMBLOCKS 0x07
23 #define CARD_INS_PINSIZE 0x08
24 #define CARD_INS_CC 0x81
25 #define CARD_INS_CC_DESC 0x82
27 // look for CardHelper
28 bool IsCardHelperPresent(bool verbose
) {
30 if (IfPm3Smartcard()) {
32 uint8_t version
[] = {0x96, 0x69, 0x00, 0x00, 0x00};
33 uint8_t resp
[30] = {0};
34 ExchangeAPDUSC(verbose
, version
, sizeof(version
), true, true, resp
, sizeof(resp
), &resp_len
);
40 if (strstr("CryptoHelper", (char *)resp
) == 0) {
42 PrintAndLogEx(INFO
, "Found smart card helper");
50 static bool executeCrypto(uint8_t ins
, uint8_t *src
, uint8_t *dest
) {
51 uint8_t cmd
[] = {0x96, ins
, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
52 memcpy(cmd
+ 5, src
, 8);
55 uint8_t dec
[11] = {0};
56 ExchangeAPDUSC(false, cmd
, sizeof(cmd
), false, true, dec
, sizeof(dec
), &resp_len
);
64 bool Decrypt(uint8_t *src
, uint8_t *dest
) {
65 return executeCrypto(CARD_INS_DECRYPT
, src
, dest
);
68 bool Encrypt(uint8_t *src
, uint8_t *dest
) {
69 return executeCrypto(CARD_INS_ENCRYPT
, src
, dest
);
73 void DecodeBlock6(uint8_t *src
) {
75 uint8_t resp
[254] = {0};
77 uint8_t c
[] = {0x96, CARD_INS_DECODE
, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
78 memcpy(c
+ 6, src
, 8);
81 ExchangeAPDUSC(false, c
, sizeof(c
), false, true, resp
, sizeof(resp
), &resp_len
);
88 PrintAndLogEx(SUCCESS
, "%.*s", resp_len
- 11, resp
+ 9);
92 ExchangeAPDUSC(false, c
, sizeof(c
), false, false, resp
, sizeof(resp
), &resp_len
);
98 PrintAndLogEx(SUCCESS
, "%.*s", resp_len
- 11, resp
+ 9);
102 uint8_t GetNumberBlocksForUserId(uint8_t *src
) {
104 uint8_t resp
[254] = {0};
105 uint8_t c
[] = {0x96, CARD_INS_NUMBLOCKS
, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
106 memcpy(c
+ 5, src
, 8);
107 ExchangeAPDUSC(false, c
, sizeof(c
), false, false, resp
, sizeof(resp
), &resp_len
);
118 uint8_t GetPinSize(uint8_t *src
) {
120 uint8_t resp
[254] = {0};
121 uint8_t c
[] = {0x96, CARD_INS_PINSIZE
, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
122 memcpy(c
+ 5, src
, 8);
123 ExchangeAPDUSC(false, c
, sizeof(c
), false, false, resp
, sizeof(resp
), &resp_len
);
128 if (resp
[resp_len
- 2] == 0x90 && resp
[resp_len
- 1] == 0x00) {
134 int GetConfigCardByIdx(uint8_t typ
, uint8_t *blocks
) {
139 uint8_t resp
[254] = {0};
140 uint8_t c
[] = {0x96, CARD_INS_CC
, 0x00, 0x00, 17, typ
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
141 ExchangeAPDUSC(false, c
, sizeof(c
), false, true, resp
, sizeof(resp
), &resp_len
);
147 if (resp
[resp_len
- 2] == 0x90 && resp
[resp_len
- 1] == 0x00) {
148 memcpy(blocks
, resp
+ 1, 16);
154 int GetConfigCardStrByIdx(uint8_t typ
, uint8_t *out
) {
159 uint8_t resp
[254] = {0};
160 uint8_t c
[] = {0x96, CARD_INS_CC_DESC
, 0x00, 0x00, 1, typ
};
161 ExchangeAPDUSC(false, c
, sizeof(c
), false, true, resp
, sizeof(resp
), &resp_len
);
167 if (resp
[resp_len
- 2] == 0x90 && resp
[resp_len
- 1] == 0x00) {
168 memcpy(out
, resp
+ 1, resp_len
- 2 - 1);
174 int VerifyRdv4Signature(uint8_t *memid
, uint8_t *signature
) {
175 if (memid
== NULL
|| signature
== NULL
)
179 uint8_t resp
[254] = {0};
180 uint8_t c
[5 + 8 + 128] = {0x96, CARD_INS_VEIRFY_RRG
, 0x00, 0x00, 8 + 128};
182 memcpy(c
+ 5, memid
, 8);
183 memcpy(c
+ 5 + 8, signature
, 128);
185 ExchangeAPDUSC(false, c
, sizeof(c
), true, false, resp
, sizeof(resp
), &resp_len
);
190 if (memcmp(resp
+ resp_len
- 4, "\x6f\x6b\x90\x00", 4) == 0) {