proxmark3/common/cardhelper.c

109 lines
3.3 KiB
C
Raw Normal View History

2020-02-27 23:35:17 +08:00
//-----------------------------------------------------------------------------
// Iceman, February 2020
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Support functions for smart card
//-----------------------------------------------------------------------------
#include "cardhelper.h"
#include <string.h>
#include <stdio.h>
#include "cmdparser.h"
#include "cmdsmartcard.h"
#include "ui.h"
#include "util.h"
2020-03-12 04:00:19 +08:00
#define CARD_INS_DECRYPT 0x01
#define CARD_INS_ENCRYPT 0x02
#define CARD_INS_DECODE 0x06
#define CARD_INS_NUMBLOCKS 0x07
2020-07-20 02:45:47 +08:00
#define CARD_INS_PINSIZE 0x08
2020-02-27 23:35:17 +08:00
static uint8_t cmd[] = {0x96, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// look for CryptoHelper
2020-07-14 02:58:24 +08:00
bool IsCryptoHelperPresent(bool verbose) {
2020-02-27 23:35:17 +08:00
if (IfPm3Smartcard()) {
int resp_len = 0;
uint8_t version[] = {0x96, 0x69, 0x00, 0x00, 0x00};
uint8_t resp[20] = {0};
ExchangeAPDUSC(true, version, sizeof(version), true, true, resp, sizeof(resp), &resp_len);
2020-03-10 00:09:41 +08:00
if (strstr("CryptoHelper", (char *)resp) == 0) {
2020-07-14 02:58:24 +08:00
if (verbose) {
PrintAndLogEx(INFO, "Found smart card helper");
}
2020-02-27 23:35:17 +08:00
return true;
}
}
2020-07-14 02:58:24 +08:00
return false;
2020-02-27 23:35:17 +08:00
}
static bool executeCrypto(uint8_t ins, uint8_t *src, uint8_t *dest) {
int resp_len = 0;
uint8_t dec[11] = {0};
cmd[1] = ins;
memcpy(cmd + 5, src, 8);
ExchangeAPDUSC(true, cmd, sizeof(cmd), false, true, dec, sizeof(dec), &resp_len);
if (resp_len == 10) {
memcpy(dest, dec, 8);
return true;
}
return false;
}
2020-03-10 00:09:41 +08:00
bool Decrypt(uint8_t *src, uint8_t *dest) {
2020-02-27 23:35:17 +08:00
return executeCrypto(CARD_INS_DECRYPT, src, dest);
}
2020-03-10 00:09:41 +08:00
bool Encrypt(uint8_t *src, uint8_t *dest) {
2020-02-27 23:35:17 +08:00
return executeCrypto(CARD_INS_ENCRYPT, src, dest);
}
2020-03-12 04:00:19 +08:00
// Call with block6
2020-02-27 23:35:17 +08:00
void DecodeBlock6(uint8_t *src) {
int resp_len = 0;
uint8_t resp[254] = {0};
uint8_t c[] = {0x96, CARD_INS_DECODE, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
memcpy(c + 6, src, 8);
// first part
ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len);
2020-03-01 23:46:31 +08:00
PrintAndLogEx(SUCCESS, "%.*s", resp_len - 11, resp + 9);
2020-02-27 23:35:17 +08:00
// second part
c[5] = 0x02;
ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len);
2020-03-01 23:46:31 +08:00
PrintAndLogEx(SUCCESS, "%.*s", resp_len - 11, resp + 9);
2020-02-27 23:35:17 +08:00
}
2020-03-12 04:00:19 +08:00
// Call with block6
uint8_t GetNumberBlocksForUserId(uint8_t *src) {
int resp_len = 0;
uint8_t resp[254] = {0};
uint8_t c[] = {0x96, CARD_INS_NUMBLOCKS, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
memcpy(c + 5, src, 8);
ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len);
return resp[8];
2020-04-16 15:01:14 +08:00
}
2020-07-20 02:45:47 +08:00
// Call with block6
uint8_t GetPinSize(uint8_t *src) {
int resp_len = 0;
uint8_t resp[254] = {0};
uint8_t c[] = {0x96, CARD_INS_PINSIZE, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
memcpy(c + 5, src, 8);
ExchangeAPDUSC(true, c, sizeof(c), false, true, resp, sizeof(resp), &resp_len);
2020-08-13 18:25:04 +08:00
if (resp[resp_len - 2] == 0x90 && resp[resp_len - 1] == 0x00) {
2020-07-20 05:08:53 +08:00
return resp[8];
}
return 0;
2020-07-20 02:45:47 +08:00
}