mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
added tesla info command, with some of the data that is available. Needed to fix the apdu chaining and a sneaky bug in get_sw since the apdu response was larger then 256
This commit is contained in:
parent
e1902ffa96
commit
f9a65505de
9 changed files with 281 additions and 16 deletions
|
@ -293,6 +293,7 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/client/src/cmdhfseos.c
|
${PM3_ROOT}/client/src/cmdhfseos.c
|
||||||
${PM3_ROOT}/client/src/cmdhfst.c
|
${PM3_ROOT}/client/src/cmdhfst.c
|
||||||
${PM3_ROOT}/client/src/cmdhfst25ta.c
|
${PM3_ROOT}/client/src/cmdhfst25ta.c
|
||||||
|
${PM3_ROOT}/client/src/cmdhftesla.c
|
||||||
${PM3_ROOT}/client/src/cmdhftexkom.c
|
${PM3_ROOT}/client/src/cmdhftexkom.c
|
||||||
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
||||||
${PM3_ROOT}/client/src/cmdhftopaz.c
|
${PM3_ROOT}/client/src/cmdhftopaz.c
|
||||||
|
|
|
@ -583,6 +583,7 @@ SRCS = mifare/aiddesfire.c \
|
||||||
cmdhfseos.c \
|
cmdhfseos.c \
|
||||||
cmdhfst.c \
|
cmdhfst.c \
|
||||||
cmdhfst25ta.c \
|
cmdhfst25ta.c \
|
||||||
|
cmdhftesla.c \
|
||||||
cmdhfthinfilm.c \
|
cmdhfthinfilm.c \
|
||||||
cmdhftopaz.c \
|
cmdhftopaz.c \
|
||||||
cmdhftexkom.c \
|
cmdhftexkom.c \
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "cmdhftexkom.h" // Texkom
|
#include "cmdhftexkom.h" // Texkom
|
||||||
#include "cmdhfxerox.h" // Xerox
|
#include "cmdhfxerox.h" // Xerox
|
||||||
#include "cmdhffudan.h" // Fudan cards
|
#include "cmdhffudan.h" // Fudan cards
|
||||||
|
#include "cmdhftesla.h" // Tesla
|
||||||
#include "cmdtrace.h" // trace list
|
#include "cmdtrace.h" // trace list
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "proxgui.h"
|
#include "proxgui.h"
|
||||||
|
@ -493,9 +494,10 @@ static command_t CommandTable[] = {
|
||||||
{"ntag424", CmdHF_ntag424, AlwaysAvailable, "{ NXP NTAG 4242 DNA RFIDs... }"},
|
{"ntag424", CmdHF_ntag424, AlwaysAvailable, "{ NXP NTAG 4242 DNA RFIDs... }"},
|
||||||
{"seos", CmdHFSeos, AlwaysAvailable, "{ SEOS RFIDs... }"},
|
{"seos", CmdHFSeos, AlwaysAvailable, "{ SEOS RFIDs... }"},
|
||||||
{"st25ta", CmdHFST25TA, AlwaysAvailable, "{ ST25TA RFIDs... }"},
|
{"st25ta", CmdHFST25TA, AlwaysAvailable, "{ ST25TA RFIDs... }"},
|
||||||
|
{"tesla", CmdHFTESLA, AlwaysAvailable, "{ TESLA Cards... }"},
|
||||||
|
{"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"},
|
||||||
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
|
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
|
||||||
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||||
{"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"},
|
|
||||||
{"xerox", CmdHFXerox, AlwaysAvailable, "{ Fuji/Xerox cartridge RFIDs... }"},
|
{"xerox", CmdHFXerox, AlwaysAvailable, "{ Fuji/Xerox cartridge RFIDs... }"},
|
||||||
{"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"},
|
{"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"},
|
||||||
{"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
|
{"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
|
||||||
|
|
|
@ -42,7 +42,13 @@
|
||||||
#include "desfire.h" // desfire enums
|
#include "desfire.h" // desfire enums
|
||||||
#include "mifare/desfirecore.h" // desfire context
|
#include "mifare/desfirecore.h" // desfire context
|
||||||
|
|
||||||
static bool APDUInFramingEnable = true;
|
static bool g_apdu_in_framing_enable = true;
|
||||||
|
bool Get_apdu_in_framing(void) {
|
||||||
|
return g_apdu_in_framing_enable;
|
||||||
|
}
|
||||||
|
void Set_apdu_in_framing(bool v) {
|
||||||
|
g_apdu_in_framing_enable = v;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
static int waitCmd(bool i_select, uint32_t timeout, bool verbose);
|
static int waitCmd(bool i_select, uint32_t timeout, bool verbose);
|
||||||
|
@ -1050,7 +1056,7 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
// 3 byte here - 1b framing header, 2b crc16
|
// 3 byte here - 1b framing header, 2b crc16
|
||||||
if (APDUInFramingEnable &&
|
if (g_apdu_in_framing_enable &&
|
||||||
((gs_frame_len && (datainlen > gs_frame_len - 3)) || (datainlen > PM3_CMD_DATA_SIZE - 3))) {
|
((gs_frame_len && (datainlen > gs_frame_len - 3)) || (datainlen > PM3_CMD_DATA_SIZE - 3))) {
|
||||||
|
|
||||||
int clen = 0;
|
int clen = 0;
|
||||||
|
@ -1454,29 +1460,34 @@ static int CmdHF14AChaining(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf 14a chaining",
|
CLIParserInit(&ctx, "hf 14a chaining",
|
||||||
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
|
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
|
||||||
"hf 14a chaining disable -> disable chaining\n"
|
"hf 14a chaining --off -> disable chaining\n"
|
||||||
"hf 14a chaining -> show chaining enable/disable state\n");
|
"hf 14a chaining -> show chaining enable/disable state\n");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0(NULL, NULL, "<enable/disable or 0/1>", NULL),
|
arg_lit0("1", "on", "enabled chaining"),
|
||||||
|
arg_lit0("0", "off", "disable chaining"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
struct arg_str *str = arg_get_str(ctx, 1);
|
bool on = arg_get_lit(ctx, 1);
|
||||||
int len = arg_get_str_len(ctx, 1);
|
bool off = arg_get_lit(ctx, 2);
|
||||||
|
|
||||||
if (len && (!strcmp(str->sval[0], "enable") || !strcmp(str->sval[0], "1")))
|
if ((on + off) > 1) {
|
||||||
APDUInFramingEnable = true;
|
PrintAndLogEx(INFO, "Select only one option");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (len && (!strcmp(str->sval[0], "disable") || !strcmp(str->sval[0], "0")))
|
if (on)
|
||||||
APDUInFramingEnable = false;
|
Set_apdu_in_framing(true);
|
||||||
|
|
||||||
|
if (off)
|
||||||
|
Set_apdu_in_framing(false);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", APDUInFramingEnable ? "enabled" : "disabled");
|
PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", g_apdu_in_framing_enable ? "enabled" : "disabled");
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,4 +53,7 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea
|
||||||
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode);
|
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode);
|
||||||
|
|
||||||
int SelectCard14443A_4(bool disconnect, bool verbose, iso14a_card_select_t *card);
|
int SelectCard14443A_4(bool disconnect, bool verbose, iso14a_card_select_t *card);
|
||||||
|
|
||||||
|
bool Get_apdu_in_framing(void);
|
||||||
|
void Set_apdu_in_framing(bool v);
|
||||||
#endif
|
#endif
|
||||||
|
|
221
client/src/cmdhftesla.c
Normal file
221
client/src/cmdhftesla.c
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// See LICENSE.txt for the text of the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// High frequency ISO14443A / TESLA commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "cmdhftesla.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h" // clearCommandBuffer
|
||||||
|
#include "cmdtrace.h"
|
||||||
|
#include "cliparser.h"
|
||||||
|
#include "cmdhf14a.h"
|
||||||
|
#include "protocols.h" // definitions of ISO14A/7816 protocol
|
||||||
|
#include "iso7816/apduinfo.h" // GetAPDUCodeDescription
|
||||||
|
#include "commonutil.h" // get_sw
|
||||||
|
#include "protocols.h" // ISO7816 APDU return co-des
|
||||||
|
#include "ui.h"
|
||||||
|
#include "cmdhf14a.h" // apdu chaining
|
||||||
|
|
||||||
|
#define TIMEOUT 2000
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0x80 0x00 0x00 0x00 - get interface object
|
||||||
|
0x80 0x01 0x00 0x00 - load data from storage
|
||||||
|
0x80 0x02 KEY_INDEX 0x00 - initialize key pair
|
||||||
|
0x80 0x03 KEY_INDEX 0x00 - generate key pair
|
||||||
|
0x80 0x04 KEY_INDEX 0x00 - get public key
|
||||||
|
0x80 0x05 CRT_INDEX 0x00 - load certificate
|
||||||
|
0x80 0x06 CRT_INDEX 0x00 - get certificate
|
||||||
|
0x80 0x07 0x00 0x00 - get version
|
||||||
|
0x80 0x08 0x00 0x00 - confirm prepersonalization
|
||||||
|
0x80 0x10 KEY_INDEX 0x00 - sign challenge
|
||||||
|
0x80 0x11 KEY_INDEX 0x00 - dh key exchange
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TESLA
|
||||||
|
static int info_hf_tesla(void) {
|
||||||
|
|
||||||
|
bool activate_field = true;
|
||||||
|
bool keep_field_on = true;
|
||||||
|
uint8_t response[PM3_CMD_DATA_SIZE];
|
||||||
|
int resplen = 0;
|
||||||
|
|
||||||
|
// --------------- Select TESLA application ----------------
|
||||||
|
uint8_t aSELECT_AID[80];
|
||||||
|
int aSELECT_AID_n = 0;
|
||||||
|
param_gethex_to_eol("00a404000a7465736c614c6f676963", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n);
|
||||||
|
int res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
DropField();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resplen < 2) {
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sw = get_sw(response, resplen);
|
||||||
|
if (sw != ISO7816_OK) {
|
||||||
|
PrintAndLogEx(ERR, "Selecting TESLA aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
activate_field = false;
|
||||||
|
keep_field_on = true;
|
||||||
|
|
||||||
|
// --------------- ECDH public key file reading ----------------
|
||||||
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
|
|
||||||
|
uint8_t aSELECT_PK[5] = {0x80, 0x04, i, 0x00, 0x00};
|
||||||
|
res = ExchangeAPDU14a(aSELECT_PK, sizeof(aSELECT_PK), activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sw = get_sw(response, resplen);
|
||||||
|
if (sw == ISO7816_OK) {
|
||||||
|
// save PK for later
|
||||||
|
uint8_t pk[65] = {0};
|
||||||
|
memcpy(pk, response, resplen - 2);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "PUBLIC KEY # %i", i);
|
||||||
|
PrintAndLogEx(INFO, "%s", sprint_hex_inrow(pk, sizeof(pk)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t aREAD_FORM_FACTOR[30];
|
||||||
|
int aREAD_FORM_FACTOR_n = 0;
|
||||||
|
param_gethex_to_eol("80140000", 0, aREAD_FORM_FACTOR, sizeof(aREAD_FORM_FACTOR), &aREAD_FORM_FACTOR_n);
|
||||||
|
res = ExchangeAPDU14a(aREAD_FORM_FACTOR, aREAD_FORM_FACTOR_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
DropField();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
sw = get_sw(response, resplen);
|
||||||
|
if (sw != ISO7816_OK) {
|
||||||
|
PrintAndLogEx(ERR, "reading FORM FACTOR file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store form factor for later
|
||||||
|
uint8_t form_factor[resplen - 2];
|
||||||
|
memcpy(form_factor, response, sizeof(form_factor));
|
||||||
|
|
||||||
|
uint8_t aREAD_VERSION[30];
|
||||||
|
int aREAD_VERSION_n = 0;
|
||||||
|
param_gethex_to_eol("80170000", 0, aREAD_VERSION, sizeof(aREAD_VERSION), &aREAD_VERSION_n);
|
||||||
|
res = ExchangeAPDU14a(aREAD_VERSION, aREAD_VERSION_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
DropField();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t version[resplen - 2];
|
||||||
|
|
||||||
|
sw = get_sw(response, resplen);
|
||||||
|
if (sw == ISO7816_OK) {
|
||||||
|
// store version for later
|
||||||
|
memcpy(version, response, sizeof(version));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- CERT reading ----------------
|
||||||
|
Set_apdu_in_framing(true);
|
||||||
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
|
||||||
|
uint8_t aSELECT_CERT[PM3_CMD_DATA_SIZE] = {0x80, 0x06, i, 0x00, 0x00, 0x00, 0xFF};
|
||||||
|
int aSELECT_CERT_n = 7;
|
||||||
|
|
||||||
|
res = ExchangeAPDU14a(aSELECT_CERT, aSELECT_CERT_n, activate_field, keep_field_on, response, PM3_CMD_DATA_SIZE, &resplen);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sw = get_sw(response, resplen);
|
||||||
|
|
||||||
|
if (sw == ISO7816_OK) {
|
||||||
|
// save CETT for later
|
||||||
|
uint8_t cert[515] = {0};
|
||||||
|
memcpy(cert, response, resplen - 2);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "CERT # %i", i);
|
||||||
|
PrintAndLogEx(INFO, "%s", sprint_hex_inrow(cert, resplen - 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set_apdu_in_framing(false);
|
||||||
|
keep_field_on = false;
|
||||||
|
DropField();
|
||||||
|
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
// PrintAndLogEx(INFO, "PUBLIC KEY");
|
||||||
|
// PrintAndLogEx(INFO, "%zu - %s", sizeof(pk), sprint_hex_inrow(pk, sizeof(pk)));
|
||||||
|
PrintAndLogEx(INFO, "Form factor");
|
||||||
|
PrintAndLogEx(INFO, "%zu - %s", sizeof(form_factor), sprint_hex_inrow(form_factor, sizeof(form_factor)));
|
||||||
|
PrintAndLogEx(INFO, "VERSION");
|
||||||
|
PrintAndLogEx(INFO, "%zu - %s", sizeof(version), sprint_hex_inrow(version, sizeof(version)));
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// menu command to get and print all info known about any known ST25TA tag
|
||||||
|
static int CmdHFTeslaInfo(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf telsa info",
|
||||||
|
"Get info about TESLA Key tag",
|
||||||
|
"hf tesla info"
|
||||||
|
);
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return info_hf_tesla();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int CmdHFTeslaList(const char *Cmd) {
|
||||||
|
return CmdTraceListAlias(Cmd, "hf tesla", "7816");
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
|
{"info", CmdHFTeslaInfo, IfPm3Iso14443a, "Tag information"},
|
||||||
|
{"list", CmdHFTeslaList, AlwaysAvailable, "List ISO 14443A/7816 history"},
|
||||||
|
{NULL, NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd) {
|
||||||
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdHFTESLA(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
return CmdsParse(CommandTable, Cmd);
|
||||||
|
}
|
26
client/src/cmdhftesla.h
Normal file
26
client/src/cmdhftesla.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// See LICENSE.txt for the text of the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// High frequency ISO14443A / TESLA commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CMDHFTESLA_H__
|
||||||
|
#define CMDHFTESLA_H__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
int CmdHFTESLA(const char *Cmd);
|
||||||
|
|
||||||
|
#endif
|
|
@ -262,10 +262,10 @@ uint32_t rotr(uint32_t a, uint8_t n) {
|
||||||
return (a >> n) | (a << (32 - n));
|
return (a >> n) | (a << (32 - n));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t get_sw(const uint8_t *d, uint8_t n) {
|
uint16_t get_sw(const uint8_t *d, uint16_t n) {
|
||||||
if (n < 2)
|
if (n < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
n -= 2;
|
n -= 2;
|
||||||
return d[n] * 0x0100 + d[n + 1];
|
return (d[n] << 8 | d[n + 1]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,5 +85,5 @@ void htole24(uint32_t val, uint8_t data[3]);
|
||||||
uint32_t rotl(uint32_t a, uint8_t n);
|
uint32_t rotl(uint32_t a, uint8_t n);
|
||||||
uint32_t rotr(uint32_t a, uint8_t n);
|
uint32_t rotr(uint32_t a, uint8_t n);
|
||||||
|
|
||||||
uint16_t get_sw(const uint8_t *d, uint8_t n);
|
uint16_t get_sw(const uint8_t *d, uint16_t n);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue