Merge branch 'master' into smartcard-relay

This commit is contained in:
Grayson Martin 2023-09-12 22:30:59 -05:00
commit 7f91da8a9a
No known key found for this signature in database
GPG key ID: 4914C62F2696A273
1001 changed files with 51581 additions and 4531 deletions

View file

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

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

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

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

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

View file

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