mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
client: fix mix of spaces & tabs
This commit is contained in:
@@ -89,7 +89,7 @@ endif
|
||||
print-%: ; @echo $* = $($*)
|
||||
|
||||
style:
|
||||
find . \( -name "*.[ch]" -or -name "*.cpp" \) -exec perl -pi -e 's/[ \t\r]+$$//' {} \;
|
||||
find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" \) -exec perl -pi -e 's/[ \t\r]+$$//' {} \;
|
||||
|
||||
# Dummy target to test for GNU make availability
|
||||
_test:
|
||||
|
||||
+113
-113
@@ -13,168 +13,168 @@
|
||||
#define HMAC_POS_TAG 0x1B4
|
||||
|
||||
void nfc3d_amiibo_calc_seed(const uint8_t * dump, uint8_t * key) {
|
||||
memcpy(key + 0x00, dump + 0x029, 0x02);
|
||||
memset(key + 0x02, 0x00, 0x0E);
|
||||
memcpy(key + 0x10, dump + 0x1D4, 0x08);
|
||||
memcpy(key + 0x18, dump + 0x1D4, 0x08);
|
||||
memcpy(key + 0x20, dump + 0x1E8, 0x20);
|
||||
memcpy(key + 0x00, dump + 0x029, 0x02);
|
||||
memset(key + 0x02, 0x00, 0x0E);
|
||||
memcpy(key + 0x10, dump + 0x1D4, 0x08);
|
||||
memcpy(key + 0x18, dump + 0x1D4, 0x08);
|
||||
memcpy(key + 0x20, dump + 0x1E8, 0x20);
|
||||
}
|
||||
|
||||
void nfc3d_amiibo_keygen(const nfc3d_keygen_masterkeys * masterKeys, const uint8_t * dump, nfc3d_keygen_derivedkeys * derivedKeys) {
|
||||
uint8_t seed[NFC3D_KEYGEN_SEED_SIZE];
|
||||
uint8_t seed[NFC3D_KEYGEN_SEED_SIZE];
|
||||
|
||||
nfc3d_amiibo_calc_seed(dump, seed);
|
||||
nfc3d_keygen(masterKeys, seed, derivedKeys);
|
||||
nfc3d_amiibo_calc_seed(dump, seed);
|
||||
nfc3d_keygen(masterKeys, seed, derivedKeys);
|
||||
}
|
||||
|
||||
void nfc3d_amiibo_cipher(const nfc3d_keygen_derivedkeys * keys, const uint8_t * in, uint8_t * out) {
|
||||
mbedtls_aes_context aes;
|
||||
size_t nc_off = 0;
|
||||
unsigned char nonce_counter[16];
|
||||
unsigned char stream_block[16];
|
||||
mbedtls_aes_context aes;
|
||||
size_t nc_off = 0;
|
||||
unsigned char nonce_counter[16];
|
||||
unsigned char stream_block[16];
|
||||
|
||||
mbedtls_aes_setkey_enc( &aes, keys->aesKey, 128 );
|
||||
memset(nonce_counter, 0, sizeof(nonce_counter));
|
||||
memset(stream_block, 0, sizeof(stream_block));
|
||||
memcpy(nonce_counter, keys->aesIV, sizeof(nonce_counter));
|
||||
mbedtls_aes_crypt_ctr( &aes, 0x188, &nc_off, nonce_counter, stream_block, in + 0x02C, out + 0x02C );
|
||||
mbedtls_aes_setkey_enc( &aes, keys->aesKey, 128 );
|
||||
memset(nonce_counter, 0, sizeof(nonce_counter));
|
||||
memset(stream_block, 0, sizeof(stream_block));
|
||||
memcpy(nonce_counter, keys->aesIV, sizeof(nonce_counter));
|
||||
mbedtls_aes_crypt_ctr( &aes, 0x188, &nc_off, nonce_counter, stream_block, in + 0x02C, out + 0x02C );
|
||||
|
||||
memcpy(out + 0x000, in + 0x000, 0x008);
|
||||
// Data signature NOT copied
|
||||
memcpy(out + 0x028, in + 0x028, 0x004);
|
||||
// Tag signature NOT copied
|
||||
memcpy(out + 0x1D4, in + 0x1D4, 0x034);
|
||||
memcpy(out + 0x000, in + 0x000, 0x008);
|
||||
// Data signature NOT copied
|
||||
memcpy(out + 0x028, in + 0x028, 0x004);
|
||||
// Tag signature NOT copied
|
||||
memcpy(out + 0x1D4, in + 0x1D4, 0x034);
|
||||
}
|
||||
|
||||
void nfc3d_amiibo_tag_to_internal(const uint8_t * tag, uint8_t * intl) {
|
||||
memcpy(intl + 0x000, tag + 0x008, 0x008);
|
||||
memcpy(intl + 0x008, tag + 0x080, 0x020);
|
||||
memcpy(intl + 0x028, tag + 0x010, 0x024);
|
||||
memcpy(intl + 0x04C, tag + 0x0A0, 0x168);
|
||||
memcpy(intl + 0x1B4, tag + 0x034, 0x020);
|
||||
memcpy(intl + 0x1D4, tag + 0x000, 0x008);
|
||||
memcpy(intl + 0x1DC, tag + 0x054, 0x02C);
|
||||
memcpy(intl + 0x000, tag + 0x008, 0x008);
|
||||
memcpy(intl + 0x008, tag + 0x080, 0x020);
|
||||
memcpy(intl + 0x028, tag + 0x010, 0x024);
|
||||
memcpy(intl + 0x04C, tag + 0x0A0, 0x168);
|
||||
memcpy(intl + 0x1B4, tag + 0x034, 0x020);
|
||||
memcpy(intl + 0x1D4, tag + 0x000, 0x008);
|
||||
memcpy(intl + 0x1DC, tag + 0x054, 0x02C);
|
||||
}
|
||||
|
||||
void nfc3d_amiibo_internal_to_tag(const uint8_t * intl, uint8_t * tag) {
|
||||
memcpy(tag + 0x008, intl + 0x000, 0x008);
|
||||
memcpy(tag + 0x080, intl + 0x008, 0x020);
|
||||
memcpy(tag + 0x010, intl + 0x028, 0x024);
|
||||
memcpy(tag + 0x0A0, intl + 0x04C, 0x168);
|
||||
memcpy(tag + 0x034, intl + 0x1B4, 0x020);
|
||||
memcpy(tag + 0x000, intl + 0x1D4, 0x008);
|
||||
memcpy(tag + 0x054, intl + 0x1DC, 0x02C);
|
||||
memcpy(tag + 0x008, intl + 0x000, 0x008);
|
||||
memcpy(tag + 0x080, intl + 0x008, 0x020);
|
||||
memcpy(tag + 0x010, intl + 0x028, 0x024);
|
||||
memcpy(tag + 0x0A0, intl + 0x04C, 0x168);
|
||||
memcpy(tag + 0x034, intl + 0x1B4, 0x020);
|
||||
memcpy(tag + 0x000, intl + 0x1D4, 0x008);
|
||||
memcpy(tag + 0x054, intl + 0x1DC, 0x02C);
|
||||
}
|
||||
|
||||
bool nfc3d_amiibo_unpack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * tag, uint8_t * plain) {
|
||||
uint8_t internal[NFC3D_AMIIBO_SIZE];
|
||||
nfc3d_keygen_derivedkeys dataKeys;
|
||||
nfc3d_keygen_derivedkeys tagKeys;
|
||||
uint8_t internal[NFC3D_AMIIBO_SIZE];
|
||||
nfc3d_keygen_derivedkeys dataKeys;
|
||||
nfc3d_keygen_derivedkeys tagKeys;
|
||||
|
||||
// Convert format
|
||||
nfc3d_amiibo_tag_to_internal(tag, internal);
|
||||
// Convert format
|
||||
nfc3d_amiibo_tag_to_internal(tag, internal);
|
||||
|
||||
// Generate keys
|
||||
nfc3d_amiibo_keygen(&amiiboKeys->data, internal, &dataKeys);
|
||||
nfc3d_amiibo_keygen(&amiiboKeys->tag, internal, &tagKeys);
|
||||
// Generate keys
|
||||
nfc3d_amiibo_keygen(&amiiboKeys->data, internal, &dataKeys);
|
||||
nfc3d_amiibo_keygen(&amiiboKeys->tag, internal, &tagKeys);
|
||||
|
||||
// Decrypt
|
||||
nfc3d_amiibo_cipher(&dataKeys, internal, plain);
|
||||
// Decrypt
|
||||
nfc3d_amiibo_cipher(&dataKeys, internal, plain);
|
||||
|
||||
// Regenerate tag HMAC. Note: order matters, data HMAC depends on tag HMAC!
|
||||
mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tagKeys.hmacKey, sizeof(tagKeys.hmacKey),
|
||||
plain + 0x1D4, 0x34, plain + HMAC_POS_TAG );
|
||||
// Regenerate tag HMAC. Note: order matters, data HMAC depends on tag HMAC!
|
||||
mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tagKeys.hmacKey, sizeof(tagKeys.hmacKey),
|
||||
plain + 0x1D4, 0x34, plain + HMAC_POS_TAG );
|
||||
|
||||
// Regenerate data HMAC
|
||||
mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), dataKeys.hmacKey, sizeof(dataKeys.hmacKey),
|
||||
plain + 0x029, 0x1DF, plain + HMAC_POS_DATA );
|
||||
// Regenerate data HMAC
|
||||
mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), dataKeys.hmacKey, sizeof(dataKeys.hmacKey),
|
||||
plain + 0x029, 0x1DF, plain + HMAC_POS_DATA );
|
||||
|
||||
return
|
||||
memcmp(plain + HMAC_POS_DATA, internal + HMAC_POS_DATA, 32) == 0 &&
|
||||
memcmp(plain + HMAC_POS_TAG, internal + HMAC_POS_TAG, 32) == 0;
|
||||
return
|
||||
memcmp(plain + HMAC_POS_DATA, internal + HMAC_POS_DATA, 32) == 0 &&
|
||||
memcmp(plain + HMAC_POS_TAG, internal + HMAC_POS_TAG, 32) == 0;
|
||||
}
|
||||
|
||||
void nfc3d_amiibo_pack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * plain, uint8_t * tag) {
|
||||
uint8_t cipher[NFC3D_AMIIBO_SIZE];
|
||||
nfc3d_keygen_derivedkeys tagKeys;
|
||||
nfc3d_keygen_derivedkeys dataKeys;
|
||||
uint8_t cipher[NFC3D_AMIIBO_SIZE];
|
||||
nfc3d_keygen_derivedkeys tagKeys;
|
||||
nfc3d_keygen_derivedkeys dataKeys;
|
||||
|
||||
// Generate keys
|
||||
nfc3d_amiibo_keygen(&amiiboKeys->tag, plain, &tagKeys);
|
||||
nfc3d_amiibo_keygen(&amiiboKeys->data, plain, &dataKeys);
|
||||
// Generate keys
|
||||
nfc3d_amiibo_keygen(&amiiboKeys->tag, plain, &tagKeys);
|
||||
nfc3d_amiibo_keygen(&amiiboKeys->data, plain, &dataKeys);
|
||||
|
||||
// Generate tag HMAC
|
||||
mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tagKeys.hmacKey, sizeof(tagKeys.hmacKey),
|
||||
plain + 0x1D4, 0x34, cipher + HMAC_POS_TAG );
|
||||
// Generate tag HMAC
|
||||
mbedtls_md_hmac( mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tagKeys.hmacKey, sizeof(tagKeys.hmacKey),
|
||||
plain + 0x1D4, 0x34, cipher + HMAC_POS_TAG );
|
||||
|
||||
// Init mbedtls HMAC context
|
||||
mbedtls_md_context_t ctx;
|
||||
mbedtls_md_init( &ctx );
|
||||
mbedtls_md_setup( &ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1 );
|
||||
// Init mbedtls HMAC context
|
||||
mbedtls_md_context_t ctx;
|
||||
mbedtls_md_init( &ctx );
|
||||
mbedtls_md_setup( &ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1 );
|
||||
|
||||
// Generate data HMAC
|
||||
mbedtls_md_hmac_starts( &ctx, dataKeys.hmacKey, sizeof(dataKeys.hmacKey) );
|
||||
mbedtls_md_hmac_update( &ctx, plain + 0x029, 0x18B ); // Data
|
||||
mbedtls_md_hmac_update( &ctx, cipher + HMAC_POS_TAG, 0x20 ); // Tag HMAC
|
||||
mbedtls_md_hmac_update( &ctx, plain + 0x1D4, 0x34 ); // Here be dragons
|
||||
// Generate data HMAC
|
||||
mbedtls_md_hmac_starts( &ctx, dataKeys.hmacKey, sizeof(dataKeys.hmacKey) );
|
||||
mbedtls_md_hmac_update( &ctx, plain + 0x029, 0x18B ); // Data
|
||||
mbedtls_md_hmac_update( &ctx, cipher + HMAC_POS_TAG, 0x20 ); // Tag HMAC
|
||||
mbedtls_md_hmac_update( &ctx, plain + 0x1D4, 0x34 ); // Here be dragons
|
||||
|
||||
mbedtls_md_hmac_finish( &ctx, cipher + HMAC_POS_DATA );
|
||||
mbedtls_md_hmac_finish( &ctx, cipher + HMAC_POS_DATA );
|
||||
|
||||
// HMAC cleanup
|
||||
mbedtls_md_free( &ctx );
|
||||
// HMAC cleanup
|
||||
mbedtls_md_free( &ctx );
|
||||
|
||||
// Encrypt
|
||||
nfc3d_amiibo_cipher(&dataKeys, plain, cipher);
|
||||
// Encrypt
|
||||
nfc3d_amiibo_cipher(&dataKeys, plain, cipher);
|
||||
|
||||
// Convert back to hardware
|
||||
nfc3d_amiibo_internal_to_tag(cipher, tag);
|
||||
// Convert back to hardware
|
||||
nfc3d_amiibo_internal_to_tag(cipher, tag);
|
||||
}
|
||||
|
||||
bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys * amiiboKeys, const char * path) {
|
||||
FILE * f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
return false;
|
||||
}
|
||||
FILE * f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fread(amiiboKeys, sizeof(*amiiboKeys), 1, f)) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
fclose(f);
|
||||
if (!fread(amiiboKeys, sizeof(*amiiboKeys), 1, f)) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if (
|
||||
(amiiboKeys->data.magicBytesSize > 16) ||
|
||||
(amiiboKeys->tag.magicBytesSize > 16)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
(amiiboKeys->data.magicBytesSize > 16) ||
|
||||
(amiiboKeys->tag.magicBytesSize > 16)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void nfc3d_amiibo_copy_app_data(const uint8_t * src, uint8_t * dst) {
|
||||
|
||||
|
||||
//uint16_t *ami_nb_wr = (uint16_t*)(dst + 0x29);
|
||||
//uint16_t *cfg_nb_wr = (uint16_t*)(dst + 0xB4);
|
||||
//uint16_t *ami_nb_wr = (uint16_t*)(dst + 0x29);
|
||||
//uint16_t *cfg_nb_wr = (uint16_t*)(dst + 0xB4);
|
||||
|
||||
/* increment write counters */
|
||||
//*ami_nb_wr = htobe16(be16toh(*ami_nb_wr) + 1);
|
||||
//*cfg_nb_wr = htobe16(be16toh(*cfg_nb_wr) + 1);
|
||||
/* increment write counters */
|
||||
//*ami_nb_wr = htobe16(be16toh(*ami_nb_wr) + 1);
|
||||
//*cfg_nb_wr = htobe16(be16toh(*cfg_nb_wr) + 1);
|
||||
|
||||
uint16_t ami_nb_wr = ((uint16_t)bytes_to_num(dst + 0x29, 2)) + 1;
|
||||
uint16_t cfg_nb_wr = ((uint16_t)bytes_to_num(dst + 0xB4, 2)) + 1;
|
||||
uint16_t ami_nb_wr = ((uint16_t)bytes_to_num(dst + 0x29, 2)) + 1;
|
||||
uint16_t cfg_nb_wr = ((uint16_t)bytes_to_num(dst + 0xB4, 2)) + 1;
|
||||
|
||||
num_to_bytes(ami_nb_wr, 2, dst + 0x29);
|
||||
num_to_bytes(cfg_nb_wr, 2, dst + 0xB4);
|
||||
num_to_bytes(ami_nb_wr, 2, dst + 0x29);
|
||||
num_to_bytes(cfg_nb_wr, 2, dst + 0xB4);
|
||||
|
||||
/* copy flags */
|
||||
dst[0x2C] = src[0x2C];
|
||||
/* copy programID */
|
||||
memcpy(dst + 0xAC, src + 0xAC, 8);
|
||||
/* copy AppID */
|
||||
memcpy(dst + 0xB6, src + 0xB6, 4);
|
||||
/* copy AppData */
|
||||
memcpy(dst + 0xDC, src + 0xDC, 216);
|
||||
/* copy flags */
|
||||
dst[0x2C] = src[0x2C];
|
||||
/* copy programID */
|
||||
memcpy(dst + 0xAC, src + 0xAC, 8);
|
||||
/* copy AppID */
|
||||
memcpy(dst + 0xB6, src + 0xB6, 4);
|
||||
/* copy AppData */
|
||||
memcpy(dst + 0xDC, src + 0xDC, 216);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
nfc3d_keygen_masterkeys data;
|
||||
nfc3d_keygen_masterkeys tag;
|
||||
nfc3d_keygen_masterkeys data;
|
||||
nfc3d_keygen_masterkeys tag;
|
||||
} nfc3d_amiibo_keys;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
+137
-137
@@ -15,161 +15,161 @@
|
||||
static char * self;
|
||||
|
||||
void amiitool_usage() {
|
||||
fprintf(stderr,
|
||||
"amiitool build %i (commit %s-%08x)\n"
|
||||
"by Marcos Del Sol Vives <marcos@dracon.es>\n"
|
||||
"\n"
|
||||
"Usage: %s (-e|-d|-c) -k keyfile [-i input] [-s input2] [-o output]\n"
|
||||
" -e encrypt and sign amiibo\n"
|
||||
" -d decrypt and test amiibo\n"
|
||||
" -c decrypt, copy AppData and encrypt amiibo\n"
|
||||
" -k key set file. For retail amiibo, use \"retail unfixed\" key set\n"
|
||||
" -i input file. If not specified, stdin will be used.\n"
|
||||
" -s input save file, save from this file will replace input file ones.\n"
|
||||
" -o output file. If not specified, stdout will be used.\n"
|
||||
" -l decrypt files with invalid signatures.\n",
|
||||
, self
|
||||
);
|
||||
fprintf(stderr,
|
||||
"amiitool build %i (commit %s-%08x)\n"
|
||||
"by Marcos Del Sol Vives <marcos@dracon.es>\n"
|
||||
"\n"
|
||||
"Usage: %s (-e|-d|-c) -k keyfile [-i input] [-s input2] [-o output]\n"
|
||||
" -e encrypt and sign amiibo\n"
|
||||
" -d decrypt and test amiibo\n"
|
||||
" -c decrypt, copy AppData and encrypt amiibo\n"
|
||||
" -k key set file. For retail amiibo, use \"retail unfixed\" key set\n"
|
||||
" -i input file. If not specified, stdin will be used.\n"
|
||||
" -s input save file, save from this file will replace input file ones.\n"
|
||||
" -o output file. If not specified, stdout will be used.\n"
|
||||
" -l decrypt files with invalid signatures.\n",
|
||||
, self
|
||||
);
|
||||
}
|
||||
|
||||
static bool LoadAmiikey(nfc3d_amiibo_keys keys, char* keyfile) {
|
||||
|
||||
if (!nfc3d_amiibo_load_keys(&keys, keyfile)) {
|
||||
PrintAndLogEx(ERR, "Could not load keys from '%s'", keyfile);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (!nfc3d_amiibo_load_keys(&keys, keyfile)) {
|
||||
PrintAndLogEx(ERR, "Could not load keys from '%s'", keyfile);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
self = argv[0];
|
||||
self = argv[0];
|
||||
|
||||
char * infile = NULL;
|
||||
char * savefile = NULL;
|
||||
char * outfile = NULL;
|
||||
char * keyfile = NULL;
|
||||
char op = '\0';
|
||||
bool lenient = false;
|
||||
char * infile = NULL;
|
||||
char * savefile = NULL;
|
||||
char * outfile = NULL;
|
||||
char * keyfile = NULL;
|
||||
char op = '\0';
|
||||
bool lenient = false;
|
||||
|
||||
char c;
|
||||
while ((c = getopt(argc, argv, "edci:s:o:k:l")) != -1) {
|
||||
switch (c) {
|
||||
case 'e':
|
||||
case 'd':
|
||||
case 'c':
|
||||
op = c;
|
||||
break;
|
||||
case 'i':
|
||||
infile = optarg;
|
||||
break;
|
||||
case 's':
|
||||
savefile = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
lenient = true;
|
||||
break;
|
||||
default:
|
||||
amiitool_usage();
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
char c;
|
||||
while ((c = getopt(argc, argv, "edci:s:o:k:l")) != -1) {
|
||||
switch (c) {
|
||||
case 'e':
|
||||
case 'd':
|
||||
case 'c':
|
||||
op = c;
|
||||
break;
|
||||
case 'i':
|
||||
infile = optarg;
|
||||
break;
|
||||
case 's':
|
||||
savefile = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
lenient = true;
|
||||
break;
|
||||
default:
|
||||
amiitool_usage();
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == '\0' || keyfile == NULL) {
|
||||
amiitool_usage();
|
||||
return 1;
|
||||
}
|
||||
if (op == '\0' || keyfile == NULL) {
|
||||
amiitool_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
nfc3d_amiibo_keys amiiboKeys;
|
||||
nfc3d_amiibo_keys amiiboKeys;
|
||||
|
||||
|
||||
uint8_t original[NTAG215_SIZE];
|
||||
uint8_t modified[NFC3D_AMIIBO_SIZE];
|
||||
uint8_t original[NTAG215_SIZE];
|
||||
uint8_t modified[NFC3D_AMIIBO_SIZE];
|
||||
|
||||
FILE * f = stdin;
|
||||
if (infile) {
|
||||
f = fopen(infile, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open input file\n");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
size_t readPages = fread(original, 4, NTAG215_SIZE / 4, f);
|
||||
if (readPages < NFC3D_AMIIBO_SIZE / 4) {
|
||||
fprintf(stderr, "Could not read from input\n");
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
fclose(f);
|
||||
FILE * f = stdin;
|
||||
if (infile) {
|
||||
f = fopen(infile, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open input file\n");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
size_t readPages = fread(original, 4, NTAG215_SIZE / 4, f);
|
||||
if (readPages < NFC3D_AMIIBO_SIZE / 4) {
|
||||
fprintf(stderr, "Could not read from input\n");
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
|
||||
if (op == 'e') {
|
||||
nfc3d_amiibo_pack(&amiiboKeys, original, modified);
|
||||
} else if (op == 'd') {
|
||||
if (!nfc3d_amiibo_unpack(&amiiboKeys, original, modified)) {
|
||||
fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n");
|
||||
if (!lenient) {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
} else { /* copy */
|
||||
uint8_t plain_base[NFC3D_AMIIBO_SIZE];
|
||||
uint8_t plain_save[NFC3D_AMIIBO_SIZE];
|
||||
if (op == 'e') {
|
||||
nfc3d_amiibo_pack(&amiiboKeys, original, modified);
|
||||
} else if (op == 'd') {
|
||||
if (!nfc3d_amiibo_unpack(&amiiboKeys, original, modified)) {
|
||||
fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n");
|
||||
if (!lenient) {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
} else { /* copy */
|
||||
uint8_t plain_base[NFC3D_AMIIBO_SIZE];
|
||||
uint8_t plain_save[NFC3D_AMIIBO_SIZE];
|
||||
|
||||
if (!nfc3d_amiibo_unpack(&amiiboKeys, original, plain_base)) {
|
||||
fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n");
|
||||
if (!lenient) {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
if (savefile) {
|
||||
f = fopen(savefile, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open save file\n");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
size_t readPages = fread(original, 4, NTAG215_SIZE / 4, f);
|
||||
if (readPages < NFC3D_AMIIBO_SIZE / 4) {
|
||||
fprintf(stderr, "Could not read from save\n");
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
fclose(f);
|
||||
if (!nfc3d_amiibo_unpack(&amiiboKeys, original, plain_base)) {
|
||||
fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n");
|
||||
if (!lenient) {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
if (savefile) {
|
||||
f = fopen(savefile, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open save file\n");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
size_t readPages = fread(original, 4, NTAG215_SIZE / 4, f);
|
||||
if (readPages < NFC3D_AMIIBO_SIZE / 4) {
|
||||
fprintf(stderr, "Could not read from save\n");
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if (!nfc3d_amiibo_unpack(&amiiboKeys, original, plain_save)) {
|
||||
fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n");
|
||||
if (!lenient) {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
if (!nfc3d_amiibo_unpack(&amiiboKeys, original, plain_save)) {
|
||||
fprintf(stderr, "!!! WARNING !!!: Tag signature was NOT valid\n");
|
||||
if (!lenient) {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
nfc3d_amiibo_copy_app_data(plain_save, plain_base);
|
||||
nfc3d_amiibo_pack(&amiiboKeys, plain_base, modified);
|
||||
}
|
||||
nfc3d_amiibo_copy_app_data(plain_save, plain_base);
|
||||
nfc3d_amiibo_pack(&amiiboKeys, plain_base, modified);
|
||||
}
|
||||
|
||||
f = stdout;
|
||||
if (outfile) {
|
||||
f = fopen(outfile, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open output file\n");
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
if (fwrite(modified, NFC3D_AMIIBO_SIZE, 1, f) != 1) {
|
||||
fprintf(stderr, "Could not write to output\n");
|
||||
fclose(f);
|
||||
return 4;
|
||||
}
|
||||
if (readPages > NFC3D_AMIIBO_SIZE / 4) {
|
||||
if (fwrite(original + NFC3D_AMIIBO_SIZE, readPages * 4 - NFC3D_AMIIBO_SIZE, 1, f) != 1) {
|
||||
fprintf(stderr, "Could not write to output:\n");
|
||||
fclose(f);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
f = stdout;
|
||||
if (outfile) {
|
||||
f = fopen(outfile, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open output file\n");
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
if (fwrite(modified, NFC3D_AMIIBO_SIZE, 1, f) != 1) {
|
||||
fprintf(stderr, "Could not write to output\n");
|
||||
fclose(f);
|
||||
return 4;
|
||||
}
|
||||
if (readPages > NFC3D_AMIIBO_SIZE / 4) {
|
||||
if (fwrite(original + NFC3D_AMIIBO_SIZE, readPages * 4 - NFC3D_AMIIBO_SIZE, 1, f) != 1) {
|
||||
fprintf(stderr, "Could not write to output:\n");
|
||||
fclose(f);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+45
-45
@@ -11,68 +11,68 @@
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
void nfc3d_drbg_init(nfc3d_drbg_ctx * ctx, const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize) {
|
||||
assert(ctx != NULL);
|
||||
assert(hmacKey != NULL);
|
||||
assert(seed != NULL);
|
||||
assert(seedSize <= NFC3D_DRBG_MAX_SEED_SIZE);
|
||||
assert(ctx != NULL);
|
||||
assert(hmacKey != NULL);
|
||||
assert(seed != NULL);
|
||||
assert(seedSize <= NFC3D_DRBG_MAX_SEED_SIZE);
|
||||
|
||||
// Initialize primitives
|
||||
ctx->used = false;
|
||||
ctx->iteration = 0;
|
||||
ctx->bufferSize = sizeof(ctx->iteration) + seedSize;
|
||||
// Initialize primitives
|
||||
ctx->used = false;
|
||||
ctx->iteration = 0;
|
||||
ctx->bufferSize = sizeof(ctx->iteration) + seedSize;
|
||||
|
||||
// The 16-bit counter is prepended to the seed when hashing, so we'll leave 2 bytes at the start
|
||||
memcpy(ctx->buffer + sizeof(uint16_t), seed, seedSize);
|
||||
// The 16-bit counter is prepended to the seed when hashing, so we'll leave 2 bytes at the start
|
||||
memcpy(ctx->buffer + sizeof(uint16_t), seed, seedSize);
|
||||
|
||||
// Initialize underlying HMAC context
|
||||
mbedtls_md_init(&ctx->hmacCtx);
|
||||
mbedtls_md_setup(&ctx->hmacCtx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1);
|
||||
mbedtls_md_hmac_starts(&ctx->hmacCtx, hmacKey, hmacKeySize);
|
||||
// Initialize underlying HMAC context
|
||||
mbedtls_md_init(&ctx->hmacCtx);
|
||||
mbedtls_md_setup(&ctx->hmacCtx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1);
|
||||
mbedtls_md_hmac_starts(&ctx->hmacCtx, hmacKey, hmacKeySize);
|
||||
}
|
||||
|
||||
void nfc3d_drbg_step(nfc3d_drbg_ctx * ctx, uint8_t * output) {
|
||||
assert(ctx != NULL);
|
||||
assert(output != NULL);
|
||||
assert(ctx != NULL);
|
||||
assert(output != NULL);
|
||||
|
||||
if (ctx->used) {
|
||||
// If used at least once, reinitialize the HMAC
|
||||
mbedtls_md_hmac_reset(&ctx->hmacCtx);
|
||||
} else {
|
||||
ctx->used = true;
|
||||
}
|
||||
if (ctx->used) {
|
||||
// If used at least once, reinitialize the HMAC
|
||||
mbedtls_md_hmac_reset(&ctx->hmacCtx);
|
||||
} else {
|
||||
ctx->used = true;
|
||||
}
|
||||
|
||||
// Store counter in big endian, and increment it
|
||||
ctx->buffer[0] = ctx->iteration >> 8;
|
||||
ctx->buffer[1] = ctx->iteration >> 0;
|
||||
ctx->iteration++;
|
||||
// Store counter in big endian, and increment it
|
||||
ctx->buffer[0] = ctx->iteration >> 8;
|
||||
ctx->buffer[1] = ctx->iteration >> 0;
|
||||
ctx->iteration++;
|
||||
|
||||
// Do HMAC magic
|
||||
mbedtls_md_hmac_update(&ctx->hmacCtx, ctx->buffer, ctx->bufferSize);
|
||||
mbedtls_md_hmac_finish(&ctx->hmacCtx, output);
|
||||
// Do HMAC magic
|
||||
mbedtls_md_hmac_update(&ctx->hmacCtx, ctx->buffer, ctx->bufferSize);
|
||||
mbedtls_md_hmac_finish(&ctx->hmacCtx, output);
|
||||
}
|
||||
|
||||
void nfc3d_drbg_cleanup(nfc3d_drbg_ctx * ctx) {
|
||||
assert(ctx != NULL);
|
||||
mbedtls_md_free(&ctx->hmacCtx);
|
||||
assert(ctx != NULL);
|
||||
mbedtls_md_free(&ctx->hmacCtx);
|
||||
}
|
||||
|
||||
void nfc3d_drbg_generate_bytes(const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize, uint8_t * output, size_t outputSize) {
|
||||
uint8_t temp[NFC3D_DRBG_OUTPUT_SIZE];
|
||||
uint8_t temp[NFC3D_DRBG_OUTPUT_SIZE];
|
||||
|
||||
nfc3d_drbg_ctx rngCtx;
|
||||
nfc3d_drbg_init(&rngCtx, hmacKey, hmacKeySize, seed, seedSize);
|
||||
nfc3d_drbg_ctx rngCtx;
|
||||
nfc3d_drbg_init(&rngCtx, hmacKey, hmacKeySize, seed, seedSize);
|
||||
|
||||
while (outputSize > 0) {
|
||||
if (outputSize < NFC3D_DRBG_OUTPUT_SIZE) {
|
||||
nfc3d_drbg_step(&rngCtx, temp);
|
||||
memcpy(output, temp, outputSize);
|
||||
break;
|
||||
}
|
||||
while (outputSize > 0) {
|
||||
if (outputSize < NFC3D_DRBG_OUTPUT_SIZE) {
|
||||
nfc3d_drbg_step(&rngCtx, temp);
|
||||
memcpy(output, temp, outputSize);
|
||||
break;
|
||||
}
|
||||
|
||||
nfc3d_drbg_step(&rngCtx, output);
|
||||
output += NFC3D_DRBG_OUTPUT_SIZE;
|
||||
outputSize -= NFC3D_DRBG_OUTPUT_SIZE;
|
||||
}
|
||||
nfc3d_drbg_step(&rngCtx, output);
|
||||
output += NFC3D_DRBG_OUTPUT_SIZE;
|
||||
outputSize -= NFC3D_DRBG_OUTPUT_SIZE;
|
||||
}
|
||||
|
||||
nfc3d_drbg_cleanup(&rngCtx);
|
||||
nfc3d_drbg_cleanup(&rngCtx);
|
||||
}
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
#include <stdint.h>
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#define NFC3D_DRBG_MAX_SEED_SIZE 480 /* Hardcoded max size in 3DS NFC module */
|
||||
#define NFC3D_DRBG_OUTPUT_SIZE 32 /* Every iteration generates 32 bytes */
|
||||
#define NFC3D_DRBG_MAX_SEED_SIZE 480 /* Hardcoded max size in 3DS NFC module */
|
||||
#define NFC3D_DRBG_OUTPUT_SIZE 32 /* Every iteration generates 32 bytes */
|
||||
|
||||
typedef struct {
|
||||
mbedtls_md_context_t hmacCtx;
|
||||
bool used;
|
||||
uint16_t iteration;
|
||||
mbedtls_md_context_t hmacCtx;
|
||||
bool used;
|
||||
uint16_t iteration;
|
||||
|
||||
uint8_t buffer[sizeof(uint16_t) + NFC3D_DRBG_MAX_SEED_SIZE];
|
||||
size_t bufferSize;
|
||||
uint8_t buffer[sizeof(uint16_t) + NFC3D_DRBG_MAX_SEED_SIZE];
|
||||
size_t bufferSize;
|
||||
} nfc3d_drbg_ctx;
|
||||
|
||||
void nfc3d_drbg_init(nfc3d_drbg_ctx * ctx, const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize);
|
||||
|
||||
+28
-28
@@ -11,43 +11,43 @@
|
||||
#include <string.h>
|
||||
|
||||
void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys * baseKeys, const uint8_t * baseSeed, uint8_t * output, size_t * outputSize) {
|
||||
assert(baseKeys != NULL);
|
||||
assert(baseSeed != NULL);
|
||||
assert(output != NULL);
|
||||
assert(outputSize != NULL);
|
||||
assert(baseKeys != NULL);
|
||||
assert(baseSeed != NULL);
|
||||
assert(output != NULL);
|
||||
assert(outputSize != NULL);
|
||||
|
||||
uint8_t * start = output;
|
||||
uint8_t * start = output;
|
||||
|
||||
// 1: Copy whole type string
|
||||
output = memccpy(output, baseKeys->typeString, '\0', sizeof(baseKeys->typeString));
|
||||
// 1: Copy whole type string
|
||||
output = memccpy(output, baseKeys->typeString, '\0', sizeof(baseKeys->typeString));
|
||||
|
||||
// 2: Append (16 - magicBytesSize) from the input seed
|
||||
size_t leadingSeedBytes = 16 - baseKeys->magicBytesSize;
|
||||
memcpy(output, baseSeed, leadingSeedBytes);
|
||||
output += leadingSeedBytes;
|
||||
// 2: Append (16 - magicBytesSize) from the input seed
|
||||
size_t leadingSeedBytes = 16 - baseKeys->magicBytesSize;
|
||||
memcpy(output, baseSeed, leadingSeedBytes);
|
||||
output += leadingSeedBytes;
|
||||
|
||||
// 3: Append all bytes from magicBytes
|
||||
memcpy(output, baseKeys->magicBytes, baseKeys->magicBytesSize);
|
||||
output += baseKeys->magicBytesSize;
|
||||
// 3: Append all bytes from magicBytes
|
||||
memcpy(output, baseKeys->magicBytes, baseKeys->magicBytesSize);
|
||||
output += baseKeys->magicBytesSize;
|
||||
|
||||
// 4: Append bytes 0x10-0x1F from input seed
|
||||
memcpy(output, baseSeed + 0x10, 16);
|
||||
output += 16;
|
||||
// 4: Append bytes 0x10-0x1F from input seed
|
||||
memcpy(output, baseSeed + 0x10, 16);
|
||||
output += 16;
|
||||
|
||||
// 5: Xor last bytes 0x20-0x3F of input seed with AES XOR pad and append them
|
||||
unsigned int i;
|
||||
for (i = 0; i < 32; i++) {
|
||||
output[i] = baseSeed[i + 32] ^ baseKeys->xorPad[i];
|
||||
}
|
||||
output += 32;
|
||||
// 5: Xor last bytes 0x20-0x3F of input seed with AES XOR pad and append them
|
||||
unsigned int i;
|
||||
for (i = 0; i < 32; i++) {
|
||||
output[i] = baseSeed[i + 32] ^ baseKeys->xorPad[i];
|
||||
}
|
||||
output += 32;
|
||||
|
||||
*outputSize = output - start;
|
||||
*outputSize = output - start;
|
||||
}
|
||||
|
||||
void nfc3d_keygen(const nfc3d_keygen_masterkeys * baseKeys, const uint8_t * baseSeed, nfc3d_keygen_derivedkeys * derivedKeys) {
|
||||
uint8_t preparedSeed[NFC3D_DRBG_MAX_SEED_SIZE];
|
||||
size_t preparedSeedSize;
|
||||
uint8_t preparedSeed[NFC3D_DRBG_MAX_SEED_SIZE];
|
||||
size_t preparedSeedSize;
|
||||
|
||||
nfc3d_keygen_prepare_seed(baseKeys, baseSeed, preparedSeed, &preparedSeedSize);
|
||||
nfc3d_drbg_generate_bytes(baseKeys->hmacKey, sizeof(baseKeys->hmacKey), preparedSeed, preparedSeedSize, (uint8_t *) derivedKeys, sizeof(*derivedKeys));
|
||||
nfc3d_keygen_prepare_seed(baseKeys, baseSeed, preparedSeed, &preparedSeedSize);
|
||||
nfc3d_drbg_generate_bytes(baseKeys->hmacKey, sizeof(baseKeys->hmacKey), preparedSeed, preparedSeedSize, (uint8_t *) derivedKeys, sizeof(*derivedKeys));
|
||||
}
|
||||
|
||||
@@ -14,18 +14,18 @@
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
uint8_t hmacKey[16];
|
||||
char typeString[14];
|
||||
uint8_t rfu;
|
||||
uint8_t magicBytesSize;
|
||||
uint8_t magicBytes[16];
|
||||
uint8_t xorPad[32];
|
||||
uint8_t hmacKey[16];
|
||||
char typeString[14];
|
||||
uint8_t rfu;
|
||||
uint8_t magicBytesSize;
|
||||
uint8_t magicBytes[16];
|
||||
uint8_t xorPad[32];
|
||||
} nfc3d_keygen_masterkeys;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t aesKey[16];
|
||||
const uint8_t aesIV[16];
|
||||
const uint8_t hmacKey[16];
|
||||
const uint8_t aesKey[16];
|
||||
const uint8_t aesIV[16];
|
||||
const uint8_t hmacKey[16];
|
||||
} nfc3d_keygen_derivedkeys;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
+884
-884
File diff suppressed because it is too large
Load Diff
+131
-131
@@ -20,186 +20,186 @@ char *programHelp = NULL;
|
||||
char buf[500] = {0};
|
||||
|
||||
int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp) {
|
||||
argtable = NULL;
|
||||
argtableLen = 0;
|
||||
programName = vprogramName;
|
||||
programHint = vprogramHint;
|
||||
programHelp = vprogramHelp;
|
||||
memset(buf, 0x00, 500);
|
||||
argtable = NULL;
|
||||
argtableLen = 0;
|
||||
programName = vprogramName;
|
||||
programHint = vprogramHint;
|
||||
programHelp = vprogramHelp;
|
||||
memset(buf, 0x00, 500);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CLIParserParseArg(int argc, char **argv, void* vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
||||
int nerrors;
|
||||
int nerrors;
|
||||
|
||||
argtable = vargtable;
|
||||
argtableLen = vargtableLen;
|
||||
argtable = vargtable;
|
||||
argtableLen = vargtableLen;
|
||||
|
||||
/* verify the argtable[] entries were allocated sucessfully */
|
||||
if (arg_nullcheck(argtable) != 0) {
|
||||
/* NULL entries were detected, some allocations must have failed */
|
||||
printf("ERROR: Insufficient memory\n");
|
||||
return 2;
|
||||
}
|
||||
/* Parse the command line as defined by argtable[] */
|
||||
nerrors = arg_parse(argc, argv, argtable);
|
||||
/* verify the argtable[] entries were allocated sucessfully */
|
||||
if (arg_nullcheck(argtable) != 0) {
|
||||
/* NULL entries were detected, some allocations must have failed */
|
||||
printf("ERROR: Insufficient memory\n");
|
||||
return 2;
|
||||
}
|
||||
/* Parse the command line as defined by argtable[] */
|
||||
nerrors = arg_parse(argc, argv, argtable);
|
||||
|
||||
/* special case: '--help' takes precedence over error reporting */
|
||||
if ((argc < 2 && !allowEmptyExec) ||((struct arg_lit *)argtable[0])->count > 0) { // help must be the first record
|
||||
printf("Usage: %s", programName);
|
||||
arg_print_syntaxv(stdout, argtable, "\n");
|
||||
if (programHint)
|
||||
printf("%s\n\n", programHint);
|
||||
arg_print_glossary(stdout, argtable, " %-20s %s\n");
|
||||
printf("\n");
|
||||
if (programHelp)
|
||||
printf("%s \n", programHelp);
|
||||
/* special case: '--help' takes precedence over error reporting */
|
||||
if ((argc < 2 && !allowEmptyExec) ||((struct arg_lit *)argtable[0])->count > 0) { // help must be the first record
|
||||
printf("Usage: %s", programName);
|
||||
arg_print_syntaxv(stdout, argtable, "\n");
|
||||
if (programHint)
|
||||
printf("%s\n\n", programHint);
|
||||
arg_print_glossary(stdout, argtable, " %-20s %s\n");
|
||||
printf("\n");
|
||||
if (programHelp)
|
||||
printf("%s \n", programHelp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If the parser returned any errors then display them and exit */
|
||||
if (nerrors > 0) {
|
||||
/* Display the error details contained in the arg_end struct.*/
|
||||
arg_print_errors(stdout, ((struct arg_end *)argtable[vargtableLen - 1]), programName);
|
||||
printf("Try '%s --help' for more information.\n", programName);
|
||||
/* If the parser returned any errors then display them and exit */
|
||||
if (nerrors > 0) {
|
||||
/* Display the error details contained in the arg_end struct.*/
|
||||
arg_print_errors(stdout, ((struct arg_end *)argtable[vargtableLen - 1]), programName);
|
||||
printf("Try '%s --help' for more information.\n", programName);
|
||||
|
||||
return 3;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum ParserState {
|
||||
PS_FIRST,
|
||||
PS_ARGUMENT,
|
||||
PS_OPTION,
|
||||
PS_FIRST,
|
||||
PS_ARGUMENT,
|
||||
PS_OPTION,
|
||||
};
|
||||
|
||||
#define isSpace(c)(c == ' ' || c == '\t')
|
||||
|
||||
int CLIParserParseString(const char* str, void* vargtable[], size_t vargtableLen, bool allowEmptyExec) {
|
||||
return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false);
|
||||
return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false);
|
||||
}
|
||||
|
||||
int CLIParserParseStringEx(const char* str, void* vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) {
|
||||
int argc = 0;
|
||||
char *argv[200] = {NULL};
|
||||
int argc = 0;
|
||||
char *argv[200] = {NULL};
|
||||
|
||||
int len = strlen(str);
|
||||
char *bufptr = buf;
|
||||
char *spaceptr = NULL;
|
||||
enum ParserState state = PS_FIRST;
|
||||
int len = strlen(str);
|
||||
char *bufptr = buf;
|
||||
char *spaceptr = NULL;
|
||||
enum ParserState state = PS_FIRST;
|
||||
|
||||
argv[argc++] = bufptr;
|
||||
// param0 = program name
|
||||
memcpy(buf, programName, strlen(programName) + 1); // with 0x00
|
||||
bufptr += strlen(programName) + 1;
|
||||
if (len)
|
||||
argv[argc++] = bufptr;
|
||||
argv[argc++] = bufptr;
|
||||
// param0 = program name
|
||||
memcpy(buf, programName, strlen(programName) + 1); // with 0x00
|
||||
bufptr += strlen(programName) + 1;
|
||||
if (len)
|
||||
argv[argc++] = bufptr;
|
||||
|
||||
// parse params
|
||||
for (int i = 0; i < len; i++) {
|
||||
switch(state){
|
||||
case PS_FIRST: // first char
|
||||
if (!clueData || str[i] == '-'){ // first char before space is '-' - next element - option OR not "clueData" for not-option fields
|
||||
state = PS_OPTION;
|
||||
// parse params
|
||||
for (int i = 0; i < len; i++) {
|
||||
switch(state){
|
||||
case PS_FIRST: // first char
|
||||
if (!clueData || str[i] == '-'){ // first char before space is '-' - next element - option OR not "clueData" for not-option fields
|
||||
state = PS_OPTION;
|
||||
|
||||
if (spaceptr) {
|
||||
bufptr = spaceptr;
|
||||
*bufptr = 0x00;
|
||||
bufptr++;
|
||||
argv[argc++] = bufptr;
|
||||
}
|
||||
}
|
||||
spaceptr = NULL;
|
||||
case PS_ARGUMENT:
|
||||
if (state == PS_FIRST)
|
||||
state = PS_ARGUMENT;
|
||||
if (isSpace(str[i])) {
|
||||
spaceptr = bufptr;
|
||||
state = PS_FIRST;
|
||||
}
|
||||
*bufptr = str[i];
|
||||
bufptr++;
|
||||
break;
|
||||
case PS_OPTION:
|
||||
if (isSpace(str[i])){
|
||||
state = PS_FIRST;
|
||||
if (spaceptr) {
|
||||
bufptr = spaceptr;
|
||||
*bufptr = 0x00;
|
||||
bufptr++;
|
||||
argv[argc++] = bufptr;
|
||||
}
|
||||
}
|
||||
spaceptr = NULL;
|
||||
case PS_ARGUMENT:
|
||||
if (state == PS_FIRST)
|
||||
state = PS_ARGUMENT;
|
||||
if (isSpace(str[i])) {
|
||||
spaceptr = bufptr;
|
||||
state = PS_FIRST;
|
||||
}
|
||||
*bufptr = str[i];
|
||||
bufptr++;
|
||||
break;
|
||||
case PS_OPTION:
|
||||
if (isSpace(str[i])){
|
||||
state = PS_FIRST;
|
||||
|
||||
*bufptr = 0x00;
|
||||
bufptr++;
|
||||
argv[argc++] = bufptr;
|
||||
break;
|
||||
}
|
||||
*bufptr = 0x00;
|
||||
bufptr++;
|
||||
argv[argc++] = bufptr;
|
||||
break;
|
||||
}
|
||||
|
||||
*bufptr = str[i];
|
||||
bufptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*bufptr = str[i];
|
||||
bufptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CLIParserParseArg(argc, argv, vargtable, vargtableLen, allowEmptyExec);
|
||||
return CLIParserParseArg(argc, argv, vargtable, vargtableLen, allowEmptyExec);
|
||||
}
|
||||
|
||||
void CLIParserFree() {
|
||||
arg_freetable(argtable, argtableLen);
|
||||
argtable = NULL;
|
||||
arg_freetable(argtable, argtableLen);
|
||||
argtable = NULL;
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
// convertors
|
||||
int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) {
|
||||
*datalen = 0;
|
||||
*datalen = 0;
|
||||
|
||||
int ibuf = 0;
|
||||
uint8_t buf[256] = {0};
|
||||
int res = CLIParamStrToBuf(argstr, buf, maxdatalen * 2, &ibuf); // *2 because here HEX
|
||||
if (res || !ibuf)
|
||||
return res;
|
||||
int ibuf = 0;
|
||||
uint8_t buf[256] = {0};
|
||||
int res = CLIParamStrToBuf(argstr, buf, maxdatalen * 2, &ibuf); // *2 because here HEX
|
||||
if (res || !ibuf)
|
||||
return res;
|
||||
|
||||
switch(param_gethex_to_eol((char *)buf, 0, data, maxdatalen, datalen)) {
|
||||
case 1:
|
||||
printf("Parameter error: Invalid HEX value.\n");
|
||||
return 1;
|
||||
case 2:
|
||||
printf("Parameter error: parameter too large.\n");
|
||||
return 2;
|
||||
case 3:
|
||||
printf("Parameter error: Hex string must have even number of digits.\n");
|
||||
return 3;
|
||||
}
|
||||
switch(param_gethex_to_eol((char *)buf, 0, data, maxdatalen, datalen)) {
|
||||
case 1:
|
||||
printf("Parameter error: Invalid HEX value.\n");
|
||||
return 1;
|
||||
case 2:
|
||||
printf("Parameter error: parameter too large.\n");
|
||||
return 2;
|
||||
case 3:
|
||||
printf("Parameter error: Hex string must have even number of digits.\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) {
|
||||
*datalen = 0;
|
||||
if (!argstr->count)
|
||||
return 0;
|
||||
*datalen = 0;
|
||||
if (!argstr->count)
|
||||
return 0;
|
||||
|
||||
uint8_t buf[256] = {0};
|
||||
int ibuf = 0;
|
||||
uint8_t buf[256] = {0};
|
||||
int ibuf = 0;
|
||||
|
||||
for (int i = 0; i < argstr->count; i++) {
|
||||
int len = strlen(argstr->sval[i]);
|
||||
memcpy(&buf[ibuf], argstr->sval[i], len);
|
||||
ibuf += len;
|
||||
}
|
||||
buf[ibuf] = 0;
|
||||
for (int i = 0; i < argstr->count; i++) {
|
||||
int len = strlen(argstr->sval[i]);
|
||||
memcpy(&buf[ibuf], argstr->sval[i], len);
|
||||
ibuf += len;
|
||||
}
|
||||
buf[ibuf] = 0;
|
||||
|
||||
if (!ibuf)
|
||||
return 0;
|
||||
if (!ibuf)
|
||||
return 0;
|
||||
|
||||
if (ibuf > maxdatalen)
|
||||
return 2;
|
||||
if (ibuf > maxdatalen)
|
||||
return 2;
|
||||
|
||||
memcpy(data, buf, ibuf);
|
||||
*datalen = ibuf;
|
||||
memcpy(data, buf, ibuf);
|
||||
*datalen = ibuf;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+22
-22
@@ -1,5 +1,5 @@
|
||||
/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
|
||||
@@ -46,34 +46,34 @@
|
||||
#define optional_argument 2
|
||||
|
||||
struct option {
|
||||
/* name of long option */
|
||||
const char *name;
|
||||
/*
|
||||
* one of no_argument, required_argument, and optional_argument:
|
||||
* whether option takes an argument
|
||||
*/
|
||||
int has_arg;
|
||||
/* if not NULL, set *flag to val when option found */
|
||||
int *flag;
|
||||
/* if flag not NULL, value to set *flag to; else return value */
|
||||
int val;
|
||||
/* name of long option */
|
||||
const char *name;
|
||||
/*
|
||||
* one of no_argument, required_argument, and optional_argument:
|
||||
* whether option takes an argument
|
||||
*/
|
||||
int has_arg;
|
||||
/* if not NULL, set *flag to val when option found */
|
||||
int *flag;
|
||||
/* if flag not NULL, value to set *flag to; else return value */
|
||||
int val;
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
int getopt_long(int, char * const *, const char *,
|
||||
const struct option *, int *);
|
||||
int getopt_long_only(int, char * const *, const char *,
|
||||
const struct option *, int *);
|
||||
int getopt_long(int, char * const *, const char *,
|
||||
const struct option *, int *);
|
||||
int getopt_long_only(int, char * const *, const char *,
|
||||
const struct option *, int *);
|
||||
#ifndef _GETOPT_DECLARED
|
||||
#define _GETOPT_DECLARED
|
||||
int getopt(int, char * const [], const char *);
|
||||
#define _GETOPT_DECLARED
|
||||
int getopt(int, char * const [], const char *);
|
||||
|
||||
extern char *optarg; /* getopt(3) external variables */
|
||||
extern char *optarg; /* getopt(3) external variables */
|
||||
extern int optind, opterr, optopt;
|
||||
#endif
|
||||
#ifndef _OPTRESET_DECLARED
|
||||
#define _OPTRESET_DECLARED
|
||||
extern int optreset; /* getopt(3) external variable */
|
||||
#define _OPTRESET_DECLARED
|
||||
extern int optreset; /* getopt(3) external variable */
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
|
||||
+631
-631
File diff suppressed because it is too large
Load Diff
+5
-5
@@ -11,20 +11,20 @@
|
||||
#ifndef CMDANALYSE_H__
|
||||
#define CMDANALYSE_H__
|
||||
|
||||
#include <stdlib.h> //size_t
|
||||
#include <stdlib.h> // size_t
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "cmdmain.h"
|
||||
#include "proxmark3.h"
|
||||
#include "ui.h" // PrintAndLog
|
||||
#include "ui.h" // PrintAndLog
|
||||
#include "util.h"
|
||||
#include "crc.h"
|
||||
#include "crc16.h" // crc16 ccitt
|
||||
#include "crc16.h" // crc16 ccitt
|
||||
#include "tea.h"
|
||||
#include "legic_prng.h"
|
||||
#include "loclass/elite_crack.h"
|
||||
#include "mifare/mfkey.h" //nonce2key
|
||||
#include "util_posix.h" // msclock
|
||||
#include "mifare/mfkey.h" // nonce2key
|
||||
#include "util_posix.h" // msclock
|
||||
|
||||
|
||||
int usage_analyse_lcr(void);
|
||||
|
||||
+368
-368
File diff suppressed because it is too large
Load Diff
+1538
-1538
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -22,7 +22,7 @@
|
||||
#include <limits.h> // for CmdNorm INT_MIN && INT_MAX
|
||||
#include "util.h"
|
||||
#include "cmdmain.h"
|
||||
#include "proxmark3.h" // sendcommand
|
||||
#include "proxmark3.h"// sendcommand
|
||||
#include "ui.h" // for show graph controls
|
||||
#include "graph.h" // for graph data
|
||||
#include "comms.h"
|
||||
|
||||
+429
-429
File diff suppressed because it is too large
Load Diff
@@ -22,15 +22,15 @@
|
||||
#include "cmdparser.h"
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "util_posix.h" // msclock
|
||||
#include "loclass/fileutils.h" //saveFile
|
||||
#include "comms.h" //getfromdevice
|
||||
#include "util_posix.h" // msclock
|
||||
#include "loclass/fileutils.h" //saveFile
|
||||
#include "comms.h" //getfromdevice
|
||||
|
||||
typedef enum {
|
||||
DICTIONARY_NONE = 0,
|
||||
DICTIONARY_MIFARE,
|
||||
DICTIONARY_T55XX,
|
||||
DICTIONARY_ICLASS
|
||||
DICTIONARY_NONE = 0,
|
||||
DICTIONARY_MIFARE,
|
||||
DICTIONARY_T55XX,
|
||||
DICTIONARY_ICLASS
|
||||
} Dictionary_t;
|
||||
|
||||
extern int CmdFlashMem(const char *Cmd);
|
||||
|
||||
+98
-98
@@ -13,128 +13,128 @@
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
int usage_hf_search(){
|
||||
PrintAndLogEx(NORMAL, "Usage: hf search");
|
||||
PrintAndLogEx(NORMAL, "Will try to find a HF read out of the unknown tag. Stops when found.");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h - This help");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return 0;
|
||||
PrintAndLogEx(NORMAL, "Usage: hf search");
|
||||
PrintAndLogEx(NORMAL, "Will try to find a HF read out of the unknown tag. Stops when found.");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h - This help");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return 0;
|
||||
}
|
||||
int usage_hf_snoop(){
|
||||
PrintAndLogEx(NORMAL, "Usage: hf snoop <skip pairs> <skip triggers>");
|
||||
PrintAndLogEx(NORMAL, "The high frequence snoop will assign all available memory on device for snooped data");
|
||||
PrintAndLogEx(NORMAL, "User the 'data samples' command to download from device, and 'data plot' to look at it");
|
||||
PrintAndLogEx(NORMAL, "Press button to quit the snooping.");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h - This help");
|
||||
PrintAndLogEx(NORMAL, " <skip pairs> - skip sample pairs");
|
||||
PrintAndLogEx(NORMAL, " <skip triggers> - skip number of triggers");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf snoop");
|
||||
PrintAndLogEx(NORMAL, " hf snoop 1000 0");
|
||||
return 0;
|
||||
PrintAndLogEx(NORMAL, "Usage: hf snoop <skip pairs> <skip triggers>");
|
||||
PrintAndLogEx(NORMAL, "The high frequence snoop will assign all available memory on device for snooped data");
|
||||
PrintAndLogEx(NORMAL, "User the 'data samples' command to download from device, and 'data plot' to look at it");
|
||||
PrintAndLogEx(NORMAL, "Press button to quit the snooping.");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h - This help");
|
||||
PrintAndLogEx(NORMAL, " <skip pairs> - skip sample pairs");
|
||||
PrintAndLogEx(NORMAL, " <skip triggers> - skip number of triggers");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf snoop");
|
||||
PrintAndLogEx(NORMAL, " hf snoop 1000 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFSearch(const char *Cmd){
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_search();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_search();
|
||||
|
||||
int ans = CmdHF14AInfo("s");
|
||||
if (ans > 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid ISO14443-A Tag Found\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HF15Reader("", false);
|
||||
if (ans) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid ISO15693 Tag Found\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HFLegicReader("", false);
|
||||
if ( ans == 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid LEGIC Tag Found\n");
|
||||
return 1;
|
||||
}
|
||||
ans = CmdHFTopazReader("s");
|
||||
if (ans == 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid Topaz Tag Found\n");
|
||||
return 1;
|
||||
}
|
||||
// 14b and iclass is the longest test (put last)
|
||||
ans = HF14BReader(false); //CmdHF14BReader("s");
|
||||
if (ans) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid ISO14443-B Tag Found\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HFiClassReader("", false, false);
|
||||
if (ans) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid iClass Tag (or PicoPass Tag) Found\n");
|
||||
return ans;
|
||||
}
|
||||
int ans = CmdHF14AInfo("s");
|
||||
if (ans > 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid ISO14443-A Tag Found\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HF15Reader("", false);
|
||||
if (ans) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid ISO15693 Tag Found\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HFLegicReader("", false);
|
||||
if ( ans == 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid LEGIC Tag Found\n");
|
||||
return 1;
|
||||
}
|
||||
ans = CmdHFTopazReader("s");
|
||||
if (ans == 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid Topaz Tag Found\n");
|
||||
return 1;
|
||||
}
|
||||
// 14b and iclass is the longest test (put last)
|
||||
ans = HF14BReader(false); //CmdHF14BReader("s");
|
||||
if (ans) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid ISO14443-B Tag Found\n");
|
||||
return ans;
|
||||
}
|
||||
ans = HFiClassReader("", false, false);
|
||||
if (ans) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid iClass Tag (or PicoPass Tag) Found\n");
|
||||
return ans;
|
||||
}
|
||||
|
||||
/*
|
||||
ans = CmdHFFelicaReader("s");
|
||||
if (ans) {
|
||||
PrintAndLogEx(NORMAL, "\nValid ISO18092 / FeliCa Found\n");
|
||||
return ans;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
ans = CmdHFFelicaReader("s");
|
||||
if (ans) {
|
||||
PrintAndLogEx(NORMAL, "\nValid ISO18092 / FeliCa Found\n");
|
||||
return ans;
|
||||
}
|
||||
*/
|
||||
|
||||
PrintAndLogEx(FAILED, "\nno known/supported 13.56 MHz tags found\n");
|
||||
return 0;
|
||||
PrintAndLogEx(FAILED, "\nno known/supported 13.56 MHz tags found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFTune(const char *Cmd) {
|
||||
PrintAndLogEx(SUCCESS, "Measuring HF antenna, press button to exit");
|
||||
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING_HF};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
PrintAndLogEx(SUCCESS, "Measuring HF antenna, press button to exit");
|
||||
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING_HF};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFSnoop(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_snoop();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_snoop();
|
||||
|
||||
int skippairs = param_get32ex(Cmd, 0, 0, 10);
|
||||
int skiptriggers = param_get32ex(Cmd, 1, 0, 10);
|
||||
int skippairs = param_get32ex(Cmd, 0, 0, 10);
|
||||
int skiptriggers = param_get32ex(Cmd, 1, 0, 10);
|
||||
|
||||
UsbCommand c = {CMD_HF_SNIFFER, {skippairs, skiptriggers, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
UsbCommand c = {CMD_HF_SNIFFER, {skippairs, skiptriggers, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"14a", CmdHF14A, 1, "{ ISO14443A RFIDs... }"},
|
||||
{"14b", CmdHF14B, 1, "{ ISO14443B RFIDs... }"},
|
||||
{"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"},
|
||||
{"epa", CmdHFEPA, 1, "{ German Identification Card... }"},
|
||||
{"felica", CmdHFFelica, 1, "{ ISO18092 / Felica RFIDs... }"},
|
||||
{"legic", CmdHFLegic, 1, "{ LEGIC RFIDs... }"},
|
||||
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
|
||||
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
|
||||
{"mfp", CmdHFMFP, 1, "{ MIFARE Plus RFIDs... }"},
|
||||
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
|
||||
{"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"},
|
||||
{"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||
{"fido", CmdHFFido, 1, "{ FIDO and FIDO2 authenticators... }"},
|
||||
{"list", CmdTraceList, 0, "List protocol data in trace buffer"},
|
||||
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
|
||||
{"search", CmdHFSearch, 1, "Search for known HF tags [preliminary]"},
|
||||
{"snoop", CmdHFSnoop, 0, "<samples to skip (10000)> <triggers to skip (1)> Generic HF Snoop"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"14a", CmdHF14A, 1, "{ ISO14443A RFIDs... }"},
|
||||
{"14b", CmdHF14B, 1, "{ ISO14443B RFIDs... }"},
|
||||
{"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"},
|
||||
{"epa", CmdHFEPA, 1, "{ German Identification Card... }"},
|
||||
{"felica", CmdHFFelica, 1, "{ ISO18092 / Felica RFIDs... }"},
|
||||
{"legic", CmdHFLegic, 1, "{ LEGIC RFIDs... }"},
|
||||
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
|
||||
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
|
||||
{"mfp", CmdHFMFP, 1, "{ MIFARE Plus RFIDs... }"},
|
||||
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
|
||||
{"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"},
|
||||
{"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||
{"fido", CmdHFFido, 1, "{ FIDO and FIDO2 authenticators... }"},
|
||||
{"list", CmdTraceList, 0, "List protocol data in trace buffer"},
|
||||
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
|
||||
{"search", CmdHFSearch, 1, "Search for known HF tags [preliminary]"},
|
||||
{"snoop", CmdHFSnoop, 0, "<samples to skip (10000)> <triggers to skip (1)> Generic HF Snoop"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdHF(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
clearCommandBuffer();
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd) {
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+13
-13
@@ -18,20 +18,20 @@
|
||||
#include "graph.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhf14a.h" // ISO14443-A
|
||||
#include "cmdhf14b.h" // ISO14443-B
|
||||
#include "cmdhf15.h" // ISO15693
|
||||
#include "cmdhf14a.h" // ISO14443-A
|
||||
#include "cmdhf14b.h" // ISO14443-B
|
||||
#include "cmdhf15.h" // ISO15693
|
||||
#include "cmdhfepa.h"
|
||||
#include "cmdhflegic.h" // LEGIC
|
||||
#include "cmdhficlass.h" // ICLASS
|
||||
#include "cmdhfmf.h" // CLASSIC
|
||||
#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc
|
||||
#include "cmdhfmfp.h" // Mifare Plus
|
||||
#include "cmdhfmfdes.h" // DESFIRE
|
||||
#include "cmdhftopaz.h" // TOPAZ
|
||||
#include "cmdhffelica.h" // ISO18092 / FeliCa
|
||||
#include "cmdhffido.h" // FIDO authenticators
|
||||
#include "cmdtrace.h" // trace list
|
||||
#include "cmdhflegic.h" // LEGIC
|
||||
#include "cmdhficlass.h" // ICLASS
|
||||
#include "cmdhfmf.h" // CLASSIC
|
||||
#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc
|
||||
#include "cmdhfmfp.h" // Mifare Plus
|
||||
#include "cmdhfmfdes.h" // DESFIRE
|
||||
#include "cmdhftopaz.h" // TOPAZ
|
||||
#include "cmdhffelica.h" // ISO18092 / FeliCa
|
||||
#include "cmdhffido.h" // FIDO authenticators
|
||||
#include "cmdtrace.h" // trace list
|
||||
|
||||
extern int CmdHF(const char *Cmd);
|
||||
extern int CmdHFTune(const char *Cmd);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user