Merge branch 'master' into bruteforce-smart-mode

This commit is contained in:
PhaseLoop 2024-01-13 16:53:05 +00:00
commit 8e0e8e2240
1273 changed files with 74746 additions and 17013 deletions

View file

@ -22,6 +22,7 @@
#include "cmdsmartcard.h"
#include "ui.h"
#include "util.h"
#include "commonutil.h"
#define CARD_INS_DECRYPT 0x01
#define CARD_INS_ENCRYPT 0x02
@ -35,26 +36,77 @@
// 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) {
PrintAndLogEx(WARNING, "Proxmark3 does not have SMARTCARD support enabled, exiting");
return false;
}
// detect SAM
smart_card_atr_t card;
smart_select(verbose, &card);
if (card.atr_len == 0) {
PrintAndLogEx(ERR, "Can't get ATR from a smart card");
return false;
}
// SAM identification
smart_card_atr_t supported[] = {
{15, {0x3B, 0x95, 0x96, 0x80, 0xB1, 0xFE, 0x55, 0x1F, 0xC7, 0x47, 0x72, 0x61, 0x63, 0x65, 0x13}},
{11, {0x3b, 0x90, 0x96, 0x91, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0xc7, 0xd4}},
};
bool found = false;
for (int i = 0; i < ARRAYLEN(supported); i++) {
if ((card.atr_len == supported[i].atr_len) &&
(memcmp(card.atr, supported[i].atr, supported[i].atr_len) == 0)) {
found = true;
break;
}
}
if (found == false) {
if (verbose) {
PrintAndLogEx(SUCCESS, "Not detecting a SAM");
}
return false;
}
// Suspect some SAMs has version name in the historical bytes
uint8_t T0 = card.atr[1];
uint8_t K = T0 & 0x0F; // Number of historical bytes
if (K > 0 && (K < (card.atr_len - 3)) && verbose) {
// Last byte of ATR is CRC and before that we have K bytes of
// "historical bytes".
// By construction K can't go above 15
char sam_name[16] = {0};
memcpy(sam_name, &card.atr[card.atr_len - 1 - K], K);
PrintAndLogEx(SUCCESS, "SAM (%s) detected", sam_name);
}
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);

View file

@ -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);

View file

@ -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
@ -293,3 +485,45 @@ void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest) {
dest[i] = src[(src_len - 1) - i];
}
}
static int hexchar_to_dec(char ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
}
if (ch >= 'a' && ch <= 'f') {
return ch - 'a' + 10;
}
if (ch >= 'A' && ch <= 'F') {
return ch - 'A' + 10;
}
return -1;
}
// no spaces allowed for input hex string
bool hexstr_to_byte_array(const char *hexstr, uint8_t *d, size_t *n) {
size_t hexstr_len = strlen(hexstr);
if (hexstr_len & 1) {
return false;
}
*n = (hexstr_len >> 1);
for (int i = 0; i < *n; i++) {
char c1 = *hexstr++;
char c2 = *hexstr++;
if (c1 == '\0' || c2 == '\0') {
return false;
}
int b = (hexchar_to_dec(c1) << 4) | hexchar_to_dec(c2);
if (b < 0) {
// Error: invalid hex character
return false;
}
d[i] = (uint8_t) b;
}
return true;
}

View file

@ -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);
@ -90,4 +109,5 @@ uint16_t get_sw(const uint8_t *d, uint16_t n);
void reverse_array(uint8_t *d, size_t n);
void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest);
bool hexstr_to_byte_array(const char *hexstr, uint8_t *d, size_t *n);
#endif

View file

@ -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

View file

@ -42,10 +42,14 @@ void init_table(CrcType_t crctype) {
case CRC_15693:
case CRC_ICLASS:
case CRC_CRYPTORF:
case CRC_KERMIT:
generate_table(CRC16_POLY_CCITT, true);
break;
case CRC_FELICA:
case CRC_XMODEM:
case CRC_CCITT:
case CRC_11784:
case CRC_PHILIPS:
generate_table(CRC16_POLY_CCITT, false);
break;
case CRC_LEGIC:
@ -54,15 +58,6 @@ void init_table(CrcType_t crctype) {
case CRC_LEGIC_16:
generate_table(CRC16_POLY_LEGIC_16, true);
break;
case CRC_CCITT:
generate_table(CRC16_POLY_CCITT, false);
break;
case CRC_KERMIT:
generate_table(CRC16_POLY_CCITT, true);
break;
case CRC_11784:
generate_table(CRC16_POLY_CCITT, false);
break;
case CRC_NONE:
crc_table_init = false;
current_crc_type = CRC_NONE;
@ -210,6 +205,9 @@ void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8
case CRC_LEGIC_16:
// TODO
return;
case CRC_PHILIPS:
crc = crc16_philips(d, n);
break;
case CRC_NONE:
return;
}
@ -244,6 +242,8 @@ uint16_t Crc16ex(CrcType_t ct, const uint8_t *d, size_t n) {
case CRC_LEGIC_16:
// TODO
return 0;
case CRC_PHILIPS:
return crc16_philips(d, n);
case CRC_NONE:
default:
break;
@ -290,6 +290,8 @@ bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) {
case CRC_LEGIC_16:
// TODO
return false;
case CRC_PHILIPS:
return (crc16_philips(d, n) == 0);
case CRC_NONE:
default:
break;
@ -350,3 +352,6 @@ uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) {
return crc16_fast(d, n, initial, true, false);
}
uint16_t crc16_philips(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0x49A3, false, false);
}

View file

@ -42,6 +42,7 @@ typedef enum {
CRC_KERMIT,
CRC_XMODEM,
CRC_CRYPTORF,
CRC_PHILIPS,
} CrcType_t;
uint16_t update_crc16_ex(uint16_t crc, uint8_t c, uint16_t polynomial);
@ -78,6 +79,9 @@ uint16_t crc16_iclass(uint8_t const *d, size_t n);
// ie: uidcrc = 0x78 then initial_value == 0x7878
uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc);
// Calculate CRC-16/ Philips.
uint16_t crc16_philips(uint8_t const *d, size_t n);
// table implementation
void init_table(CrcType_t crctype);
void reset_table(void);

View file

@ -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"
};

View file

@ -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;
@ -195,6 +195,20 @@ uint32_t ul_ev1_pwdgenF(const uint8_t *uid) {
return pwd;
}
// Solution from @atc1441
// https://gist.github.com/atc1441/41af75048e4c22af1f5f0d4c1d94bb56
// Philips Sonicare toothbrush NFC head
uint32_t ul_ev1_pwdgenG(const uint8_t *uid, const uint8_t *mfg) {
init_table(CRC_PHILIPS);
// UID
uint32_t crc1 = crc16_philips(uid, 7);
// MFG string
uint32_t crc2 = crc16_fast(mfg, 10, crc1, false, false);
return (BSWAP_16(crc2) << 16 | BSWAP_16(crc1));
}
// pack generation for algo 1-3
uint16_t ul_ev1_packgenA(const uint8_t *uid) {
uint16_t pack = (uid[0] ^ uid[1] ^ uid[2]) << 8 | (uid[2] ^ 8);
@ -224,13 +238,26 @@ uint16_t ul_ev1_packgenD(const uint8_t *uid) {
p ^= 0x5555;
return BSWAP_16(p & 0xFFFF);
}
uint16_t ul_ev1_packgenE(const uint8_t *uid) {
uint32_t pwd = ul_ev1_pwdgenE(uid);
return (0xAD << 8 | ((pwd >> 24) & 0xFF));
}
uint16_t ul_ev1_packgenG(const uint8_t *uid, const uint8_t *mfg) {
init_table(CRC_PHILIPS);
// UID
uint32_t crc1 = crc16_philips(uid, 7);
// MFG string
uint32_t crc2 = crc16_fast(mfg, 10, crc1, false, false);
// PWD
uint32_t pwd = (BSWAP_16(crc2) << 16 | BSWAP_16(crc1));
uint8_t pb[4];
num_to_bytes(pwd, 4, pb);
return BSWAP_16(crc16_fast(pb, 4, crc2, false, false));
}
// default shims
uint32_t ul_ev1_pwdgen_def(const uint8_t *uid) {
@ -299,10 +326,41 @@ int mfc_algo_yale_all(uint8_t *uid, uint8_t *keys) {
int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) {
if (sector > 15) return PM3_EINVARG;
if (key == NULL) return PM3_EINVARG;
if (keytype > 2) return PM3_EINVARG;
*key = 0;
if (keytype == 0 && sector == 2) {
*key = 0xFFFFFFFFFFFF;
return PM3_SUCCESS;
}
if (keytype == 0 && sector == 1) {
*key = 0x2a2c13cc242a;
return PM3_SUCCESS;
}
if (keytype == 0) {
uint64_t lut[16] = {
0xf057b39ee3d8ULL, 0x969d954ac157ULL, 0x8f43580d2c9dULL, 0xffcce0050c43ULL,
0x341b15a690ccULL, 0x89585612e71bULL, 0xbb74b0953658ULL, 0xfb97f84b5b74ULL,
0xc9d188359f92ULL, 0x8f92e97f5897ULL, 0x166ca2b09fd1ULL, 0x27dd93101c6cULL,
0xda3e3fd649ddULL, 0x58dded078e3eULL, 0x5cd005cfd907ULL, 0x118dd00187d0ULL
};
uint8_t h = ((uid[3] >> 4) & 0xF);
h += ((uid[2] >> 4) & 0xF);
h += uid[0] & 0xF;
uint64_t m = lut[h & 0xF];
uint64_t id = (bytes_to_num(uid, 4) << 8);
*key = (h + (id + m + ((uint64_t)h << 40ULL))) & 0xFFFFFFFFFFFFULL;
} else {
*key = 0xFFFFFFFFFFFF;
}
return PM3_SUCCESS;
}
int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys) {
if (keys == NULL) return PM3_EINVARG;
@ -522,7 +580,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;
@ -556,7 +614,7 @@ int mfc_algo_touch_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *
int generator_selftest(void) {
#ifndef ON_DEVICE
#define NUM_OF_TEST 8
#define NUM_OF_TEST 10
PrintAndLogEx(INFO, "PWD / KEY generator selftest");
PrintAndLogEx(INFO, "----------------------------");
@ -569,64 +627,81 @@ int generator_selftest(void) {
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid1, 7), pwd1, success ? "OK" : "->8432EB17<-");
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid1, 7), pwd1, success ? _GREEN_("ok") : "->8432EB17<-");
uint8_t uid2[] = {0x04, 0x1f, 0x98, 0xea, 0x1e, 0x3e, 0x81};
uint32_t pwd2 = ul_ev1_pwdgenB(uid2);
success = (pwd2 == 0x5fd37eca);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid2, 7), pwd2, success ? "OK" : "->5fd37eca<--");
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid2, 7), pwd2, success ? _GREEN_("ok") : "->5fd37eca<--");
uint8_t uid3[] = {0x04, 0x62, 0xB6, 0x8A, 0xB4, 0x42, 0x80};
uint32_t pwd3 = ul_ev1_pwdgenC(uid3);
success = (pwd3 == 0x5a349515);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid3, 7), pwd3, success ? "OK" : "->5a349515<--");
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid3, 7), pwd3, success ? _GREEN_("ok") : "->5a349515<--");
uint8_t uid4[] = {0x04, 0xC5, 0xDF, 0x4A, 0x6D, 0x51, 0x80};
uint32_t pwd4 = ul_ev1_pwdgenD(uid4);
success = (pwd4 == 0x72B1EC61);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid4, 7), pwd4, success ? "OK" : "->72B1EC61<--");
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid4, 7), pwd4, success ? _GREEN_("ok") : "->72B1EC61<--");
uint8_t uid5[] = {0x04, 0xA0, 0x3C, 0xAA, 0x1E, 0x70, 0x80};
uint32_t pwd5 = ul_ev1_pwdgenE(uid5);
success = (pwd5 == 0xCD91AFCC);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid5, 7), pwd5, success ? "OK" : "->CD91AFCC<--");
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid5, 7), pwd5, success ? _GREEN_("ok") : "->CD91AFCC<--");
uint8_t uid6[] = {0x04, 0x77, 0x42, 0xAB, 0xEF, 0x42, 0x70};
uint32_t pwd6 = ul_ev1_pwdgenF(uid6);
success = (pwd6 == 0xA9C4C3C0);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid6, 7), pwd6, success ? "OK" : "->A9C4C3C0<--");
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid6, 7), pwd6, success ? _GREEN_("ok") : "->A9C4C3C0<--");
uint8_t uid7[] = {0x04, 0x0D, 0x4B, 0x5A, 0xC5, 0x71, 0x81};
uint8_t mfg[] = {0x32, 0x31, 0x30, 0x36, 0x32, 0x38, 0x20, 0x35, 0x32, 0x4D};
uint32_t pwd7 = ul_ev1_pwdgenG(uid7, mfg);
success = (pwd7 == 0xFBCFACC1);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid7, 7), pwd7, success ? _GREEN_("ok") : "->FBCFACC1<--");
// uint8_t uid5[] = {0x11, 0x22, 0x33, 0x44};
// uint64_t key1 = mfc_algo_a(uid5);
// success = (key1 == 0xD1E2AA68E39A);
// PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" - %s", sprint_hex(uid5, 4), key1, success ? "OK" : "->D1E2AA68E39A<--");
// PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" - %s", sprint_hex(uid5, 4), key1, success ? _GREEN_("ok") : "->D1E2AA68E39A<--");
uint8_t uid7[] = {0x74, 0x57, 0xCA, 0xA9};
uint64_t key7 = 0;
mfc_algo_sky_one(uid7, 15, 0, &key7);
success = (key7 == 0x82c7e64bc565);
uint8_t uid8[] = {0x74, 0x57, 0xCA, 0xA9};
uint64_t key8 = 0;
mfc_algo_sky_one(uid8, 15, 0, &key8);
success = (key8 == 0x82c7e64bc565);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" - %s", sprint_hex(uid7, 4), key7, success ? "OK" : "->82C7E64BC565<--");
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" - %s", sprint_hex(uid8, 4), key8, success ? _GREEN_("ok") : "->82C7E64BC565<--");
// MFC SAFLOK
uint8_t uid9[] = {0x11, 0x22, 0x33, 0x44};
uint64_t key9 = 0;
mfc_algo_saflok_one(uid9, 0, 0, &key9);
success = (key9 == 0xD1E2AA68E39A);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIX64" - %s", sprint_hex(uid9, 4), key9, success ? _GREEN_("ok") : _RED_(">> D1E2AA68E39A <<"));
uint32_t lf_id = lf_t55xx_white_pwdgen(0x00000080);
success = (lf_id == 0x00018383);
if (success)
testresult++;
PrintAndLogEx(success ? SUCCESS : WARNING, "ID | 0x00000080 | %08"PRIx32 " - %s", lf_id, success ? "OK" : "->00018383<--");
PrintAndLogEx(success ? SUCCESS : WARNING, "ID | 0x00000080 | %08"PRIx32 " - %s", lf_id, success ? _GREEN_("ok") : "->00018383<--");
PrintAndLogEx(SUCCESS, "------------------- Selftest %s", (testresult == NUM_OF_TEST) ? "OK" : "fail");
PrintAndLogEx(SUCCESS, "------------------- Selftest %s", (testresult == NUM_OF_TEST) ? _GREEN_("ok") : _RED_("fail"));
#endif
return PM3_SUCCESS;

View file

@ -28,6 +28,7 @@ uint32_t ul_ev1_pwdgenC(const uint8_t *uid);
uint32_t ul_ev1_pwdgenD(const uint8_t *uid);
uint32_t ul_ev1_pwdgenE(const uint8_t *uid);
uint32_t ul_ev1_pwdgenF(const uint8_t *uid);
uint32_t ul_ev1_pwdgenG(const uint8_t *uid, const uint8_t *mfg);
uint16_t ul_ev1_packgen_def(const uint8_t *uid);
uint16_t ul_ev1_packgenA(const uint8_t *uid);
@ -35,6 +36,7 @@ uint16_t ul_ev1_packgenB(const uint8_t *uid);
uint16_t ul_ev1_packgenC(const uint8_t *uid);
uint16_t ul_ev1_packgenD(const uint8_t *uid);
uint16_t ul_ev1_packgenE(const uint8_t *uid);
uint16_t ul_ev1_packgenG(const uint8_t *uid, const uint8_t *mfg);
uint32_t ul_c_otpgenA(const uint8_t *uid);

View file

@ -53,8 +53,8 @@
// **********************************************************************************************
// ---------------------------------Utilities Section--------------------------------------------
// **********************************************************************************************
#define LOWEST_DEFAULT_CLOCK 32
#define FSK_PSK_THRESHOLD 123
#define LOWEST_DEFAULT_CLOCK 32
#define FSK_PSK_THRESHOLD 123
//to allow debug print calls when used not on dev
@ -268,12 +268,20 @@ static size_t removeEm410xParity(uint8_t *bits, size_t startIdx, bool isLong, bo
*validLong = false;
uint8_t bLen = isLong ? 110 : 55;
uint16_t parityCol[4] = { 0, 0, 0, 0 };
for (int word = 0; word < bLen; word += 5) {
for (int bit = 0; bit < 5; bit++) {
if (word + bit >= bLen) break;
if (word + bit >= bLen) {
break;
}
parityWd = (parityWd << 1) | bits[startIdx + word + bit];
if ((word <= 50) && (bit < 4))
if ((word <= 50) && (bit < 4)) {
parityCol[bit] = (parityCol[bit] << 1) | bits[startIdx + word + bit];
}
bits[bitCnt++] = (bits[startIdx + word + bit]);
}
if (word + 5 > bLen) break;
@ -293,12 +301,15 @@ static size_t removeEm410xParity(uint8_t *bits, size_t startIdx, bool isLong, bo
if (!isLong && validRowParitySkipColP && validColParity) {
*validShort = true;
}
if (isLong && validRowParity) {
*validLong = true;
}
if (isLong && validRowParitySkipColP && validColParity) {
*validShortExtended = true;
}
if (*validShort || *validShortExtended || *validLong) {
return bitCnt;
} else {
@ -425,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];
}
@ -602,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
@ -611,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},
@ -625,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;
@ -644,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]++;
@ -658,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]
@ -667,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;
@ -701,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;
@ -744,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) {
@ -884,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;
@ -915,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
@ -938,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)
@ -994,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;
@ -1087,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;
@ -1101,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.
@ -1123,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);
@ -1146,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;
@ -1186,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;
@ -1463,7 +1496,7 @@ bool DetectST(uint8_t *buffer, size_t *size, int *foundclock, size_t *ststart, s
static int millerRawDecode(uint8_t *bits, size_t *size, int invert) {
if (*size < 16) return -1;
uint16_t MaxBits = 512, errCnt = 0;
uint16_t MaxBits = MAX_DEMODULATION_BITS, errCnt = 0;
size_t i, bitCnt = 0;
uint8_t alignCnt = 0, curBit = bits[0], alignedIdx = 0, halfClkErr = 0;
@ -1507,7 +1540,7 @@ int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert) {
uint16_t bitnum = 0;
uint16_t errCnt = 0;
size_t i = *offset;
uint16_t maxbits = 512;
uint16_t maxbits = MAX_DEMODULATION_BITS;
//check for phase change faults - skip one sample if faulty
bool offsetA = true, offsetB = true;
@ -1547,7 +1580,7 @@ uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alig
if (*size < 16) return 0xFFFF;
int errCnt = 0, bestErr = 1000;
uint16_t bitnum = 0, maxBits = 512, bestRun = 0;
uint16_t bitnum = 0, maxBits = MAX_DEMODULATION_BITS, bestRun = 0;
size_t i;
//find correct start position [alignment]

View file

@ -30,6 +30,9 @@
// ignore first x samples of the buffer
#define SIGNAL_IGNORE_FIRST_SAMPLES 10
// Max number of bits when demodulating a signal
#define MAX_DEMODULATION_BITS 4096
// generic
typedef struct {
int low;

View file

@ -21,7 +21,10 @@ MYSRCS = \
cipher.c \
cmac.c \
des.c \
ecc_point_compression.c \
ecdh.c \
ecdsa.c \
gcm.c \
md.c \
md5.c \
oid.c \
@ -43,7 +46,8 @@ MYSRCS = \
threading.c \
x509.c \
x509_crl.c \
x509_crt.c
x509_crt.c \
net_sockets.c
LIB_A = libmbedtls.a

View file

@ -2811,7 +2811,7 @@
* This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
* requisites are enabled as well.
*/
//#define MBEDTLS_GCM_C
#define MBEDTLS_GCM_C
/**
* \def MBEDTLS_HAVEGE_C
@ -2979,7 +2979,7 @@
*
* This module provides networking routines.
*/
//#define MBEDTLS_NET_C
#define MBEDTLS_NET_C
/**
* \def MBEDTLS_OID_C

View file

@ -0,0 +1,130 @@
/*
* Not original to the mbedtls library. Taken from
* https://github.com/mwarning/mbedtls_ecp_compression
* to solve mbedtls' lack of support for elliptic point
* compression and decompression
*
* Released under CC0 1.0 Universal License
*/
/*
* This is all about mbedtls_ecp_decompress() and mbedtls_ecp_compress()
*
* Perform X25519 / Curve25519 point compression and decompression for mbedtls.
* As of mbedtls 2.5.1, mbedtls does not support decompression yet.
*
*/
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
#include "ecc_point_compression.h"
int mbedtls_ecp_decompress(
const mbedtls_ecp_group *grp,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize
) {
int ret;
size_t plen;
mbedtls_mpi r;
mbedtls_mpi x;
mbedtls_mpi n;
plen = mbedtls_mpi_size(&grp->P);
*olen = 2 * plen + 1;
if (osize < *olen)
return (MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
if (ilen != plen + 1)
return (MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
if (input[0] != 0x02 && input[0] != 0x03)
return (MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
// output will consist of 0x04|X|Y
memcpy(output, input, ilen);
output[0] = 0x04;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&x);
mbedtls_mpi_init(&n);
// x <= input
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&x, input + 1, plen));
// r = x^2
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&r, &x, &x));
// r = x^2 + a
if (grp->A.p == NULL) {
// Special case where a is -3
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&r, &r, 3));
} else {
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&r, &r, &grp->A));
}
// r = x^3 + ax
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&r, &r, &x));
// r = x^3 + ax + b
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&r, &r, &grp->B));
// Calculate square root of r over finite field P:
// r = sqrt(x^3 + ax + b) = (x^3 + ax + b) ^ ((P + 1) / 4) (mod P)
// n = P + 1
MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&n, &grp->P, 1));
// n = (P + 1) / 4
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&n, 2));
// r ^ ((P + 1) / 4) (mod p)
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&r, &r, &n, &grp->P, NULL));
// Select solution that has the correct "sign" (equals odd/even solution in finite group)
if ((input[0] == 0x03) != mbedtls_mpi_get_bit(&r, 0)) {
// r = p - r
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&r, &grp->P, &r));
}
// y => output
ret = mbedtls_mpi_write_binary(&r, output + 1 + plen, plen);
cleanup:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&x);
mbedtls_mpi_free(&n);
return (ret);
}
int mbedtls_ecp_compress(
const mbedtls_ecp_group *grp,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize
) {
size_t plen;
plen = mbedtls_mpi_size(&grp->P);
*olen = plen + 1;
if (osize < *olen)
return (MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
if (ilen != 2 * plen + 1)
return (MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
if (input[0] != 0x04)
return (MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
// output will consist of 0x0?|X
memcpy(output, input, *olen);
// Encode even/odd of Y into first byte (either 0x02 or 0x03)
output[0] = 0x02 + (input[2 * plen] & 1);
return (0);
}

View file

@ -0,0 +1,32 @@
/*
* Not original to the mbedtls library. Taken from
* https://github.com/mwarning/mbedtls_ecp_compression
* to solve mbedtls' lack of support for elliptic point
* compression and decompression
*
* Released under CC0 1.0 Universal License
*/
/*
* This is all about mbedtls_ecp_decompress() and mbedtls_ecp_compress()
*
* Perform X25519 / Curve25519 point compression and decompression for mbedtls.
* As of mbedtls 2.5.1, mbedtls does not support decompression yet.
*
*/
#include <string.h>
#include "mbedtls/ecp.h"
int mbedtls_ecp_decompress(
const mbedtls_ecp_group *grp,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize
);
int mbedtls_ecp_compress(
const mbedtls_ecp_group *grp,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize
);