mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-23 14:45:37 -07:00
Merge branch 'master' into smartcard-relay
This commit is contained in:
commit
7f91da8a9a
1001 changed files with 51581 additions and 4531 deletions
|
@ -35,26 +35,68 @@
|
|||
// look for CardHelper
|
||||
bool IsCardHelperPresent(bool verbose) {
|
||||
|
||||
if (IfPm3Smartcard()) {
|
||||
int resp_len = 0;
|
||||
uint8_t version[] = {0x96, 0x69, 0x00, 0x00, 0x00};
|
||||
uint8_t resp[30] = {0};
|
||||
ExchangeAPDUSC(verbose, version, sizeof(version), true, true, resp, sizeof(resp), &resp_len);
|
||||
if (IfPm3Smartcard() == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resp_len < 8) {
|
||||
return false;
|
||||
}
|
||||
int resp_len = 0;
|
||||
uint8_t version[] = {0x96, 0x69, 0x00, 0x00, 0x00};
|
||||
uint8_t resp[30] = {0};
|
||||
ExchangeAPDUSC(verbose, version, sizeof(version), true, true, resp, sizeof(resp), &resp_len);
|
||||
|
||||
if (strstr("CryptoHelper", (char *)resp) == 0) {
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "Found smart card helper");
|
||||
}
|
||||
return true;
|
||||
if (resp_len < 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strstr("CryptoHelper", (char *)resp) == 0) {
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "Found smart card helper");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsHIDSamPresent(bool verbose) {
|
||||
|
||||
if (IfPm3Smartcard() == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// detect SAM
|
||||
smart_card_atr_t card;
|
||||
smart_select(verbose, &card);
|
||||
if (!card.atr_len) {
|
||||
PrintAndLogEx(ERR, "Can't get ATR from a smart card");
|
||||
return false;
|
||||
}
|
||||
|
||||
// SAM identification
|
||||
uint8_t sam_atr[] = {0x3B, 0x95, 0x96, 0x80, 0xB1, 0xFE, 0x55, 0x1F, 0xC7, 0x47, 0x72, 0x61, 0x63, 0x65, 0x13};
|
||||
if (memcmp(card.atr, sam_atr, card.atr_len) < 0) {
|
||||
|
||||
uint8_t sam_atr2[] = {0x3b, 0x90, 0x96, 0x91, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0xc7, 0xd4};
|
||||
if (memcmp(card.atr, sam_atr2, card.atr_len) < 0) {
|
||||
if (verbose) {
|
||||
PrintAndLogEx(SUCCESS, "Not detecting a SAM");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Suspect some SAMs has version name in their ATR
|
||||
uint8_t T0 = card.atr[1];
|
||||
uint8_t K = T0 & 0x0F;
|
||||
if (K > 4 && verbose) {
|
||||
if (byte_strstr(card.atr, card.atr_len, (const uint8_t *)"Grace", 5) > -1) {
|
||||
PrintAndLogEx(SUCCESS, "SAM (Grace) detected");
|
||||
} else if (byte_strstr(card.atr, card.atr_len, (const uint8_t *)"Hopper", 6) > -1) {
|
||||
PrintAndLogEx(SUCCESS, "SAM (Hopper) detected");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool executeCrypto(uint8_t ins, uint8_t *src, uint8_t *dest) {
|
||||
uint8_t cmd[] = {0x96, ins, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
memcpy(cmd + 5, src, 8);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <ctype.h>
|
||||
#include "common.h"
|
||||
|
||||
bool IsHIDSamPresent(bool verbose);
|
||||
bool IsCardHelperPresent(bool verbose);
|
||||
bool Encrypt(uint8_t *src, uint8_t *dest);
|
||||
bool Decrypt(uint8_t *src, uint8_t *dest);
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* verifies the magic properties, then stores a formatted string, prefixed by
|
||||
* prefix in dst.
|
||||
*/
|
||||
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_info) {
|
||||
struct version_information_t *v = (struct version_information_t *)version_info;
|
||||
void FormatVersionInformation(char *dst, int len, const char *prefix, const void *version_info) {
|
||||
const struct version_information_t *v = (const struct version_information_t *)version_info;
|
||||
dst[0] = 0;
|
||||
strncat(dst, prefix, len - 1);
|
||||
if (v->magic != VERSION_INFORMATION_MAGIC) {
|
||||
|
@ -53,8 +53,8 @@ void FormatVersionInformation(char *dst, int len, const char *prefix, void *vers
|
|||
strncat(dst, v->armsrc, len - strlen(dst) - 1);
|
||||
}
|
||||
|
||||
void format_version_information_short(char *dst, int len, void *version_info) {
|
||||
struct version_information_t *v = (struct version_information_t *)version_info;
|
||||
void format_version_information_short(char *dst, int len, const void *version_info) {
|
||||
const struct version_information_t *v = (const struct version_information_t *)version_info;
|
||||
dst[0] = 0;
|
||||
if (v->magic != VERSION_INFORMATION_MAGIC) {
|
||||
strncat(dst, "Missing/Invalid version information", len - strlen(dst) - 1);
|
||||
|
@ -151,7 +151,7 @@ void num_to_bytes(uint64_t n, size_t len, uint8_t *dest) {
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t bytes_to_num(uint8_t *src, size_t len) {
|
||||
uint64_t bytes_to_num(const uint8_t *src, size_t len) {
|
||||
uint64_t num = 0;
|
||||
while (len--) {
|
||||
num = (num << 8) | (*src);
|
||||
|
@ -161,63 +161,255 @@ uint64_t bytes_to_num(uint8_t *src, size_t len) {
|
|||
}
|
||||
|
||||
uint16_t MemLeToUint2byte(const uint8_t *data) {
|
||||
return (data[1] << 8) + data[0];
|
||||
return (uint16_t)(
|
||||
(((uint16_t)(data[1])) << (8 * 1)) +
|
||||
(((uint16_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t MemLeToUint3byte(const uint8_t *data) {
|
||||
return (data[2] << 16) + (data[1] << 8) + data[0];
|
||||
return (uint32_t)(
|
||||
(((uint32_t)(data[2])) << (8 * 2)) +
|
||||
(((uint32_t)(data[1])) << (8 * 1)) +
|
||||
(((uint32_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t MemLeToUint4byte(const uint8_t *data) {
|
||||
return (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0];
|
||||
return (uint32_t)(
|
||||
(((uint32_t)(data[3])) << (8 * 3)) +
|
||||
(((uint32_t)(data[2])) << (8 * 2)) +
|
||||
(((uint32_t)(data[1])) << (8 * 1)) +
|
||||
(((uint32_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemLeToUint5byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[4])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[1])) << (8 * 1)) +
|
||||
(((uint64_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemLeToUint6byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[5])) << (8 * 5)) +
|
||||
(((uint64_t)(data[4])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[1])) << (8 * 1)) +
|
||||
(((uint64_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemLeToUint7byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[6])) << (8 * 6)) +
|
||||
(((uint64_t)(data[5])) << (8 * 5)) +
|
||||
(((uint64_t)(data[4])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[1])) << (8 * 1)) +
|
||||
(((uint64_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemLeToUint8byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[7])) << (8 * 7)) +
|
||||
(((uint64_t)(data[6])) << (8 * 6)) +
|
||||
(((uint64_t)(data[5])) << (8 * 5)) +
|
||||
(((uint64_t)(data[4])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[1])) << (8 * 1)) +
|
||||
(((uint64_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint16_t MemBeToUint2byte(const uint8_t *data) {
|
||||
return (data[0] << 8) + data[1];
|
||||
return (uint16_t)(
|
||||
(((uint16_t)(data[0])) << (8 * 1)) +
|
||||
(((uint16_t)(data[1])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t MemBeToUint3byte(const uint8_t *data) {
|
||||
return (data[0] << 16) + (data[1] << 8) + data[2];
|
||||
return (uint32_t)(
|
||||
(((uint32_t)(data[0])) << (8 * 2)) +
|
||||
(((uint32_t)(data[1])) << (8 * 1)) +
|
||||
(((uint32_t)(data[2])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t MemBeToUint4byte(const uint8_t *data) {
|
||||
return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
|
||||
return (uint32_t)(
|
||||
(((uint32_t)(data[0])) << (8 * 3)) +
|
||||
(((uint32_t)(data[1])) << (8 * 2)) +
|
||||
(((uint32_t)(data[2])) << (8 * 1)) +
|
||||
(((uint32_t)(data[3])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemBeToUint5byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[0])) << (8 * 4)) +
|
||||
(((uint64_t)(data[1])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[3])) << (8 * 1)) +
|
||||
(((uint64_t)(data[4])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemBeToUint6byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[0])) << (8 * 5)) +
|
||||
(((uint64_t)(data[1])) << (8 * 4)) +
|
||||
(((uint64_t)(data[2])) << (8 * 3)) +
|
||||
(((uint64_t)(data[3])) << (8 * 2)) +
|
||||
(((uint64_t)(data[4])) << (8 * 1)) +
|
||||
(((uint64_t)(data[5])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemBeToUint7byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[0])) << (8 * 6)) +
|
||||
(((uint64_t)(data[1])) << (8 * 5)) +
|
||||
(((uint64_t)(data[2])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[4])) << (8 * 2)) +
|
||||
(((uint64_t)(data[5])) << (8 * 1)) +
|
||||
(((uint64_t)(data[6])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemBeToUint8byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[0])) << (8 * 7)) +
|
||||
(((uint64_t)(data[1])) << (8 * 6)) +
|
||||
(((uint64_t)(data[2])) << (8 * 5)) +
|
||||
(((uint64_t)(data[3])) << (8 * 4)) +
|
||||
(((uint64_t)(data[4])) << (8 * 3)) +
|
||||
(((uint64_t)(data[5])) << (8 * 2)) +
|
||||
(((uint64_t)(data[6])) << (8 * 1)) +
|
||||
(((uint64_t)(data[7])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
void Uint2byteToMemLe(uint8_t *data, uint16_t value) {
|
||||
data[1] = (value >> 8) & 0xff;
|
||||
data[0] = value & 0xff;
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint3byteToMemLe(uint8_t *data, uint32_t value) {
|
||||
data[2] = (value >> 16) & 0xff;
|
||||
data[1] = (value >> 8) & 0xff;
|
||||
data[0] = value & 0xff;
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint4byteToMemLe(uint8_t *data, uint32_t value) {
|
||||
data[3] = (value >> 24) & 0xff;
|
||||
data[2] = (value >> 16) & 0xff;
|
||||
data[1] = (value >> 8) & 0xff;
|
||||
data[0] = value & 0xff;
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint5byteToMemLe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint6byteToMemLe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint7byteToMemLe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8 * 6)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint8byteToMemLe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8 * 6)) & 0xffu);
|
||||
data[7] = (uint8_t)((value >> (8 * 7)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint2byteToMemBe(uint8_t *data, uint16_t value) {
|
||||
data[0] = (value >> 8) & 0xff;
|
||||
data[1] = value & 0xff;
|
||||
data[0] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint3byteToMemBe(uint8_t *data, uint32_t value) {
|
||||
data[0] = (value >> 16) & 0xff;
|
||||
data[1] = (value >> 8) & 0xff;
|
||||
data[2] = value & 0xff;
|
||||
data[0] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint4byteToMemBe(uint8_t *data, uint32_t value) {
|
||||
data[0] = (value >> 24) & 0xff;
|
||||
data[1] = (value >> 16) & 0xff;
|
||||
data[2] = (value >> 8) & 0xff;
|
||||
data[3] = value & 0xff;
|
||||
data[0] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint5byteToMemBe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint6byteToMemBe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint7byteToMemBe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8 * 6)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint8byteToMemBe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8 * 7)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 6)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[7] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
// RotateLeft - Ultralight, Desfire
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
#endif
|
||||
|
||||
extern struct version_information_t g_version_information;
|
||||
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_info);
|
||||
void format_version_information_short(char *dst, int len, void *version_info);
|
||||
void FormatVersionInformation(char *dst, int len, const char *prefix, const void *version_info);
|
||||
void format_version_information_short(char *dst, int len, const void *version_info);
|
||||
|
||||
uint32_t reflect(uint32_t v, int b); // used in crc.c ...
|
||||
uint8_t reflect8(uint8_t b); // dedicated 8bit reversal
|
||||
|
@ -59,21 +59,40 @@ uint16_t reflect16(uint16_t b); // dedicated 16bit reversal
|
|||
uint32_t reflect32(uint32_t b); // dedicated 32bit reversal
|
||||
|
||||
void num_to_bytes(uint64_t n, size_t len, uint8_t *dest);
|
||||
uint64_t bytes_to_num(uint8_t *src, size_t len);
|
||||
uint64_t bytes_to_num(const uint8_t *src, size_t len);
|
||||
|
||||
// LE and BE to/from memory
|
||||
uint16_t MemLeToUint2byte(const uint8_t *data);
|
||||
uint32_t MemLeToUint3byte(const uint8_t *data);
|
||||
uint32_t MemLeToUint4byte(const uint8_t *data);
|
||||
uint64_t MemLeToUint5byte(const uint8_t *data);
|
||||
uint64_t MemLeToUint6byte(const uint8_t *data);
|
||||
uint64_t MemLeToUint7byte(const uint8_t *data);
|
||||
uint64_t MemLeToUint8byte(const uint8_t *data);
|
||||
|
||||
uint16_t MemBeToUint2byte(const uint8_t *data);
|
||||
uint32_t MemBeToUint3byte(const uint8_t *data);
|
||||
uint32_t MemBeToUint4byte(const uint8_t *data);
|
||||
uint64_t MemBeToUint5byte(const uint8_t *data);
|
||||
uint64_t MemBeToUint6byte(const uint8_t *data);
|
||||
uint64_t MemBeToUint7byte(const uint8_t *data);
|
||||
uint64_t MemBeToUint8byte(const uint8_t *data);
|
||||
|
||||
void Uint2byteToMemLe(uint8_t *data, uint16_t value);
|
||||
void Uint3byteToMemLe(uint8_t *data, uint32_t value);
|
||||
void Uint4byteToMemLe(uint8_t *data, uint32_t value);
|
||||
void Uint5byteToMemLe(uint8_t *data, uint64_t value);
|
||||
void Uint6byteToMemLe(uint8_t *data, uint64_t value);
|
||||
void Uint7byteToMemLe(uint8_t *data, uint64_t value);
|
||||
void Uint8byteToMemLe(uint8_t *data, uint64_t value);
|
||||
|
||||
void Uint2byteToMemBe(uint8_t *data, uint16_t value);
|
||||
void Uint3byteToMemBe(uint8_t *data, uint32_t value);
|
||||
void Uint4byteToMemBe(uint8_t *data, uint32_t value);
|
||||
void Uint5byteToMemBe(uint8_t *data, uint64_t value);
|
||||
void Uint6byteToMemBe(uint8_t *data, uint64_t value);
|
||||
void Uint7byteToMemBe(uint8_t *data, uint64_t value);
|
||||
void Uint8byteToMemBe(uint8_t *data, uint64_t value);
|
||||
|
||||
// rotate left byte array
|
||||
void rol(uint8_t *data, const size_t len);
|
||||
|
|
|
@ -3,10 +3,10 @@ CRAPTO1
|
|||
Provides a set of library functions which aid the verification
|
||||
of crypto1 weaknesses.
|
||||
|
||||
In short a partial implementation of:
|
||||
In short a partial implementation of:
|
||||
Dismantling MIFARE Classic
|
||||
URL: http://www.sos.cs.ru.nl/applications/rfid/2008-esorics.pdf
|
||||
Flavio D. Garcia, Gerhard de Koning Gans, Ruben Muijrers,
|
||||
Flavio D. Garcia, Gerhard de Koning Gans, Ruben Muijrers,
|
||||
Peter van Rossum, Roel Verdult, Ronny Wichers Schreur, Bart Jacobs
|
||||
Institute for Computing and Information Sciences,
|
||||
Radboud University Nijmegen, The Netherlands
|
||||
|
|
|
@ -26,5 +26,7 @@ const struct version_information_t SECTVERSINFO g_version_information = {
|
|||
1, /* version 1 */
|
||||
0, /* version information not present */
|
||||
2, /* cleanliness couldn't be determined */
|
||||
/* Remaining fields: zero */
|
||||
"Iceman/master/unknown",
|
||||
"1970-01-01 00:00:00",
|
||||
"no sha256"
|
||||
};
|
||||
|
|
|
@ -173,7 +173,7 @@ uint32_t ul_ev1_pwdgenD(const uint8_t *uid) {
|
|||
|
||||
// AIR purifier Xiaomi
|
||||
uint32_t ul_ev1_pwdgenE(const uint8_t *uid) {
|
||||
uint8_t hash[20];
|
||||
uint8_t hash[20] = {0};
|
||||
mbedtls_sha1(uid, 7, hash);
|
||||
uint32_t pwd = 0;
|
||||
pwd |= (hash[ hash[0] % 20 ]) << 24 ;
|
||||
|
@ -185,7 +185,7 @@ uint32_t ul_ev1_pwdgenE(const uint8_t *uid) {
|
|||
|
||||
// NDEF tools format password generator
|
||||
uint32_t ul_ev1_pwdgenF(const uint8_t *uid) {
|
||||
uint8_t hash[16];
|
||||
uint8_t hash[16] = {0};;
|
||||
mbedtls_md5(uid, 7, hash);
|
||||
uint32_t pwd = 0;
|
||||
pwd |= hash[0] << 24;
|
||||
|
@ -549,7 +549,7 @@ int mfdes_kdf_input_gallagher(uint8_t *uid, uint8_t uidLen, uint8_t keyNo, uint3
|
|||
|
||||
int mfc_generate4b_nuid(uint8_t *uid, uint8_t *nuid) {
|
||||
uint16_t crc;
|
||||
uint8_t b1, b2;
|
||||
uint8_t b1 = 0, b2 = 0;
|
||||
|
||||
compute_crc(CRC_14443_A, uid, 3, &b1, &b2);
|
||||
nuid[0] = (b2 & 0xE0) | 0xF;
|
||||
|
|
|
@ -436,10 +436,10 @@ static size_t findModStart(const uint8_t *src, size_t size, uint8_t expWaveSize)
|
|||
}
|
||||
|
||||
static int getClosestClock(int testclk) {
|
||||
const uint16_t clocks[] = {8, 16, 32, 40, 50, 64, 100, 128, 256, 384};
|
||||
const uint8_t limit[] = {1, 2, 4, 4, 5, 8, 8, 8, 8, 8};
|
||||
const uint16_t clocks[] = {8, 16, 32, 40, 50, 64, 100, 128, 256, 272, 384};
|
||||
const uint8_t limit[] = {1, 2, 4, 4, 5, 8, 8, 8, 8, 24, 24};
|
||||
|
||||
for (uint8_t i = 0; i < 10; i++) {
|
||||
for (uint8_t i = 0; i < ARRAYLEN(clocks); i++) {
|
||||
if (testclk >= clocks[i] - limit[i] && testclk <= clocks[i] + limit[i])
|
||||
return clocks[i];
|
||||
}
|
||||
|
@ -613,7 +613,7 @@ bool DetectCleanAskWave(const uint8_t *dest, size_t size, uint8_t high, uint8_t
|
|||
// based on count of low to low
|
||||
int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clock) {
|
||||
size_t i = 100;
|
||||
size_t minClk = 512;
|
||||
size_t minClk = 768;
|
||||
uint16_t shortestWaveIdx = 0;
|
||||
|
||||
// get to first full low to prime loop and skip incomplete first pulse
|
||||
|
@ -622,11 +622,11 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo
|
|||
|
||||
if (i == size)
|
||||
return -1;
|
||||
if (size < 512)
|
||||
if (size < 768)
|
||||
return -2;
|
||||
|
||||
// clock, numoftimes, first idx
|
||||
uint16_t tmpclk[10][3] = {
|
||||
uint16_t tmpclk[11][3] = {
|
||||
{8, 0, 0},
|
||||
{16, 0, 0},
|
||||
{32, 0, 0},
|
||||
|
@ -636,11 +636,12 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo
|
|||
{100, 0, 0},
|
||||
{128, 0, 0},
|
||||
{256, 0, 0},
|
||||
{272, 0, 0},
|
||||
{384, 0, 0},
|
||||
};
|
||||
|
||||
// loop through all samples (well, we don't want to go out-of-bounds)
|
||||
while (i < (size - 512)) {
|
||||
while (i < (size - 768)) {
|
||||
// measure from low to low
|
||||
size_t startwave = i;
|
||||
|
||||
|
@ -655,7 +656,7 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo
|
|||
|
||||
int foo = getClosestClock(minClk);
|
||||
if (foo > 0) {
|
||||
for (uint8_t j = 0; j < 10; j++) {
|
||||
for (uint8_t j = 0; j < 11; j++) {
|
||||
if (tmpclk[j][0] == foo) {
|
||||
tmpclk[j][1]++;
|
||||
|
||||
|
@ -669,8 +670,17 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo
|
|||
}
|
||||
|
||||
// find the clock with most hits and it the first index it was encountered.
|
||||
int possible_clks = 0;
|
||||
for (uint8_t j = 0; j < 11; j++) {
|
||||
if (tmpclk[j][1] > 0) {
|
||||
possible_clks++;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t second_shortest = 0;
|
||||
int second = 0;
|
||||
int max = 0;
|
||||
for (uint8_t j = 0; j < 10; j++) {
|
||||
for (int j = 10; j > -1; j--) {
|
||||
if (g_debugMode == 2) {
|
||||
prnt("DEBUG, ASK, clocks %u | hits %u | idx %u"
|
||||
, tmpclk[j][0]
|
||||
|
@ -678,13 +688,23 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo
|
|||
, tmpclk[j][2]
|
||||
);
|
||||
}
|
||||
|
||||
if (max < tmpclk[j][1]) {
|
||||
second = *clock;
|
||||
second_shortest = shortestWaveIdx;
|
||||
|
||||
*clock = tmpclk[j][0];
|
||||
shortestWaveIdx = tmpclk[j][2];
|
||||
max = tmpclk[j][1];
|
||||
}
|
||||
}
|
||||
|
||||
// ASK clock 8 is very rare and usually gives us false positives
|
||||
if (possible_clks > 1 && *clock == 8) {
|
||||
*clock = second;
|
||||
shortestWaveIdx = second_shortest;
|
||||
}
|
||||
|
||||
if (*clock == 0)
|
||||
return -1;
|
||||
|
||||
|
@ -712,9 +732,9 @@ int DetectASKClock(uint8_t *dest, size_t size, int *clock, int maxErr) {
|
|||
}
|
||||
|
||||
size_t i = 1;
|
||||
uint8_t num_clks = 9;
|
||||
uint8_t num_clks = 10;
|
||||
// first 255 value pos0 is placeholder for user inputed clock.
|
||||
uint16_t clk[] = {255, 8, 16, 32, 40, 50, 64, 100, 128, 255};
|
||||
uint16_t clk[] = {255, 8, 16, 32, 40, 50, 64, 100, 128, 255, 272};
|
||||
|
||||
// sometimes there is a strange end wave - filter out this
|
||||
size -= 60;
|
||||
|
@ -755,8 +775,8 @@ int DetectASKClock(uint8_t *dest, size_t size, int *clock, int maxErr) {
|
|||
|
||||
uint8_t clkCnt, tol;
|
||||
size_t j = 0;
|
||||
uint16_t bestErr[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000};
|
||||
uint8_t bestStart[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint16_t bestErr[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000};
|
||||
uint8_t bestStart[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
size_t errCnt, arrLoc, loopEnd;
|
||||
|
||||
if (found_clk) {
|
||||
|
@ -895,11 +915,11 @@ int DetectStrongNRZClk(const uint8_t *dest, size_t size, int peak, int low, bool
|
|||
// detect nrz clock by reading #peaks vs no peaks(or errors)
|
||||
int DetectNRZClock(uint8_t *dest, size_t size, int clock, size_t *clockStartIdx) {
|
||||
size_t i = 0;
|
||||
uint8_t clk[] = {8, 16, 32, 40, 50, 64, 100, 128, 255};
|
||||
uint16_t clk[] = {8, 16, 32, 40, 50, 64, 100, 128, 255, 272, 384};
|
||||
size_t loopCnt = 4096; //don't need to loop through entire array...
|
||||
|
||||
//if we already have a valid clock quit
|
||||
for (; i < 8; ++i)
|
||||
for (; i < ARRAYLEN(clk); ++i)
|
||||
if (clk[i] == clock) return clock;
|
||||
|
||||
if (size < 20) return 0;
|
||||
|
@ -926,7 +946,7 @@ int DetectNRZClock(uint8_t *dest, size_t size, int clock, size_t *clockStartIdx)
|
|||
uint8_t tol = 0;
|
||||
uint16_t smplCnt = 0;
|
||||
int16_t peakcnt = 0;
|
||||
int16_t peaksdet[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int16_t peaksdet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint16_t minPeak = 255;
|
||||
bool firstpeak = true;
|
||||
//test for large clipped waves - ignore first peak
|
||||
|
@ -949,10 +969,10 @@ int DetectNRZClock(uint8_t *dest, size_t size, int clock, size_t *clockStartIdx)
|
|||
bool errBitHigh = 0, bitHigh = 0, lastPeakHigh = 0;
|
||||
uint8_t ignoreCnt = 0, ignoreWindow = 4;
|
||||
int lastBit = 0;
|
||||
size_t bestStart[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
size_t bestStart[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
peakcnt = 0;
|
||||
//test each valid clock from smallest to greatest to see which lines up
|
||||
for (clkCnt = 0; clkCnt < 8; ++clkCnt) {
|
||||
for (clkCnt = 0; clkCnt < ARRAYLEN(bestStart); ++clkCnt) {
|
||||
//ignore clocks smaller than smallest peak
|
||||
if (clk[clkCnt] < minPeak - (clk[clkCnt] / 4)) continue;
|
||||
//try lining up the peaks by moving starting point (try first 256)
|
||||
|
@ -1005,7 +1025,7 @@ int DetectNRZClock(uint8_t *dest, size_t size, int clock, size_t *clockStartIdx)
|
|||
}
|
||||
|
||||
uint8_t best = 0;
|
||||
for (int m = 7; m > 0; m--) {
|
||||
for (int m = ARRAYLEN(peaksdet) - 1; m >= 0; m--) {
|
||||
if ((peaksdet[m] >= (peaksdet[best] - 1)) && (peaksdet[m] <= peaksdet[best] + 1) && lowestTransition) {
|
||||
if (clk[m] > (lowestTransition - (clk[m] / 8)) && clk[m] < (lowestTransition + (clk[m] / 8))) {
|
||||
best = m;
|
||||
|
@ -1098,10 +1118,12 @@ uint16_t countFC(const uint8_t *bits, size_t size, bool fskAdj) {
|
|||
fcH = fcLens[best2];
|
||||
fcL = fcLens[best1];
|
||||
}
|
||||
/*
|
||||
if ((size - 180) / fcH / 3 > fcCnts[best1] + fcCnts[best2]) {
|
||||
if (g_debugMode == 2) prnt("DEBUG countfc: fc is too large: %zu > %u. Not psk or fsk", (size - 180) / fcH / 3, fcCnts[best1] + fcCnts[best2]);
|
||||
return 0; //lots of waves not psk or fsk
|
||||
}
|
||||
*/
|
||||
// TODO: take top 3 answers and compare to known Field clocks to get top 2
|
||||
|
||||
uint16_t fcs = (((uint16_t)fcH) << 8) | fcL;
|
||||
|
@ -1112,8 +1134,8 @@ uint16_t countFC(const uint8_t *bits, size_t size, bool fskAdj) {
|
|||
// detect psk clock by reading each phase shift
|
||||
// a phase shift is determined by measuring the sample length of each wave
|
||||
int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc) {
|
||||
uint8_t clk[] = {255, 16, 32, 40, 50, 64, 100, 128, 255}; //255 is not a valid clock
|
||||
uint16_t loopCnt = 4096; //don't need to loop through entire array...
|
||||
uint16_t clk[] = {255, 16, 32, 40, 50, 64, 100, 128, 256, 272, 384}; // 255 is not a valid clock
|
||||
uint16_t loopCnt = 4096; // don't need to loop through entire array...
|
||||
|
||||
if (size < 160 + 20) return 0;
|
||||
// size must be larger than 20 here, and 160 later on.
|
||||
|
@ -1134,8 +1156,8 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif
|
|||
|
||||
uint8_t clkCnt;
|
||||
uint16_t waveLenCnt, fullWaveLen = 0;
|
||||
uint16_t bestErr[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000};
|
||||
uint16_t peaksdet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint16_t bestErr[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000};
|
||||
uint16_t peaksdet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
//find start of modulating data in trace
|
||||
size_t i = findModStart(dest, size, *fc);
|
||||
|
@ -1157,7 +1179,7 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif
|
|||
}
|
||||
|
||||
//test each valid clock from greatest to smallest to see which lines up
|
||||
for (clkCnt = 7; clkCnt >= 1 ; clkCnt--) {
|
||||
for (clkCnt = 9; clkCnt >= 1 ; clkCnt--) {
|
||||
uint8_t tol = *fc / 2;
|
||||
size_t lastClkBit = firstFullWave; //set end of wave as clock align
|
||||
size_t waveStart = 0;
|
||||
|
@ -1197,8 +1219,8 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif
|
|||
}
|
||||
//all tested with errors
|
||||
//return the highest clk with the most peaks found
|
||||
uint8_t best = 7;
|
||||
for (i = 7; i >= 1; i--) {
|
||||
uint8_t best = 9;
|
||||
for (i = 9; i >= 1; i--) {
|
||||
if (peaksdet[i] > peaksdet[best])
|
||||
best = i;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue