mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-12-28 19:31:19 +08:00
added a staticnested program that uses two different implementations. The Chameleon Ultra impl and PM3 Impl.\nRunning the test script will show how the CU impl has some issues
This commit is contained in:
parent
a36cfbdb1f
commit
ecd7f53eda
7 changed files with 522 additions and 3 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
|||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added `tools\mfkeys\staticnested` - program to recover static nested keys (@iceman1001)
|
||||
- Added `pm3_gen_dictionary.py` - python script to extract and save all keys from MFC dump files. (@iceman1001)
|
||||
- Changed `hf mfu info` - now detect MIFARE Ultralight AES (@iceman1001)
|
||||
- Changed `hf mf autopwn` - now supports multiple user supplied keys (@iceman1001)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
MYSRCPATHS = ../../common ../../common/crapto1
|
||||
MYSRCS = crypto1.c crapto1.c bucketsort.c
|
||||
MYSRCS = crypto1.c crapto1.c bucketsort.c nested_util.c
|
||||
MYINCLUDES = -I../../include -I../../common
|
||||
MYCFLAGS = -O3
|
||||
MYDEFS =
|
||||
|
||||
BINS = mfkey32 mfkey32v2 mfkey64
|
||||
BINS = mfkey32 mfkey32v2 mfkey64 staticnested
|
||||
INSTALLTOOLS = $(BINS)
|
||||
|
||||
include ../../Makefile.host
|
||||
|
@ -24,3 +24,4 @@ endif
|
|||
mfkey32 : $(OBJDIR)/mfkey32.o $(MYOBJS)
|
||||
mfkey32v2 : $(OBJDIR)/mfkey32v2.o $(MYOBJS)
|
||||
mfkey64 : $(OBJDIR)/mfkey64.o $(MYOBJS)
|
||||
staticnested : $(OBJDIR)/staticnested.o $(MYOBJS)
|
||||
|
|
257
tools/mfkey/nested_util.c
Normal file
257
tools/mfkey/nested_util.c
Normal file
|
@ -0,0 +1,257 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
#include <ctype.h>
|
||||
#include "parity.h"
|
||||
|
||||
#ifdef __WIN32
|
||||
#include "windows.h"
|
||||
#else
|
||||
#include "unistd.h"
|
||||
#endif
|
||||
|
||||
#include "pthread.h"
|
||||
#include "nested_util.h"
|
||||
|
||||
|
||||
#define MEM_CHUNK 10000
|
||||
#define TRY_KEYS 50
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t key;
|
||||
int count;
|
||||
} countKeys;
|
||||
|
||||
typedef struct {
|
||||
NtpKs1 *pNK;
|
||||
uint32_t authuid;
|
||||
|
||||
uint64_t *keys;
|
||||
uint32_t keyCount;
|
||||
|
||||
uint32_t startPos;
|
||||
uint32_t endPos;
|
||||
} RecPar;
|
||||
|
||||
|
||||
static int compar_int(const void *a, const void *b) {
|
||||
return (*(uint64_t *)b - * (uint64_t *)a);
|
||||
}
|
||||
|
||||
// Compare countKeys structure
|
||||
static int compar_special_int(const void *a, const void *b) {
|
||||
return (((countKeys *)b)->count - ((countKeys *)a)->count);
|
||||
}
|
||||
|
||||
// keys qsort and unique.
|
||||
static countKeys *uniqsort(uint64_t *possibleKeys, uint32_t size) {
|
||||
unsigned int i, j = 0;
|
||||
int count = 0;
|
||||
countKeys *our_counts;
|
||||
|
||||
qsort(possibleKeys, size, sizeof(uint64_t), compar_int);
|
||||
|
||||
our_counts = calloc(size, sizeof(countKeys));
|
||||
if (our_counts == NULL) {
|
||||
printf("Memory allocation error for our_counts");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (possibleKeys[i + 1] == possibleKeys[i]) {
|
||||
count++;
|
||||
} else {
|
||||
our_counts[j].key = possibleKeys[i];
|
||||
our_counts[j].count = count;
|
||||
j++;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
qsort(our_counts, j, sizeof(countKeys), compar_special_int);
|
||||
return (our_counts);
|
||||
}
|
||||
|
||||
// nested decrypt
|
||||
static void *nested_revover(void *args) {
|
||||
struct Crypto1State *revstate, * revstate_start = NULL;
|
||||
uint64_t lfsr = 0;
|
||||
uint32_t i, kcount = 0;
|
||||
bool is_ok = true;
|
||||
|
||||
RecPar *rp = (RecPar *)args;
|
||||
|
||||
rp->keyCount = 0;
|
||||
rp->keys = NULL;
|
||||
|
||||
//printf("Start pos is %d, End pos is %d\r\n", rp->startPos, rp->endPos);
|
||||
|
||||
for (i = rp->startPos; i < rp->endPos; i++) {
|
||||
uint32_t nt_probe = rp->pNK[i].ntp ^ rp->authuid;
|
||||
uint32_t ks1 = rp->pNK[i].ks1;
|
||||
|
||||
/*
|
||||
printf(" ntp = %"PRIu32"\r\n", nt_probe);
|
||||
printf(" ks1 = %"PRIu32"\r\n", ks1);
|
||||
printf("\r\n");
|
||||
*/
|
||||
|
||||
// And finally recover the first 32 bits of the key
|
||||
revstate = lfsr_recovery32(ks1, nt_probe);
|
||||
if (revstate_start == NULL) {
|
||||
revstate_start = revstate;
|
||||
}
|
||||
|
||||
while ((revstate->odd != 0x0) || (revstate->even != 0x0)) {
|
||||
lfsr_rollback_word(revstate, nt_probe, 0);
|
||||
crypto1_get_lfsr(revstate, &lfsr);
|
||||
if (((kcount % MEM_CHUNK) == 0) || (kcount >= rp->keyCount)) {
|
||||
rp->keyCount += MEM_CHUNK;
|
||||
// printf("New chunk by %d, sizeof %lu\n", kcount, rp->keyCount * sizeof(uint64_t));
|
||||
void *tmp = realloc(rp->keys, rp->keyCount * sizeof(uint64_t));
|
||||
if (tmp == NULL) {
|
||||
printf("Memory allocation error for pk->possibleKeys");
|
||||
rp->keyCount = 0;
|
||||
is_ok = false;
|
||||
break;
|
||||
}
|
||||
rp->keys = (uint64_t *)tmp;
|
||||
}
|
||||
rp->keys[kcount] = lfsr;
|
||||
kcount++;
|
||||
revstate++;
|
||||
}
|
||||
--kcount;
|
||||
free(revstate_start);
|
||||
revstate_start = NULL;
|
||||
if (!is_ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_ok) {
|
||||
if (kcount != 0) {
|
||||
rp->keyCount = kcount;
|
||||
void *tmp = (uint64_t *)realloc(rp->keys, rp->keyCount * sizeof(uint64_t));
|
||||
if (tmp == NULL) {
|
||||
printf("Memory allocation error for pk->possibleKeys");
|
||||
rp->keyCount = 0;
|
||||
free(rp->keys);
|
||||
} else {
|
||||
rp->keys = tmp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rp->keyCount = 0;
|
||||
free(rp->keys);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t *nested(NtpKs1 *pNK, uint32_t sizePNK, uint32_t authuid, uint32_t *keyCount) {
|
||||
#define THREAD_MAX 4
|
||||
|
||||
*keyCount = 0;
|
||||
uint32_t i, j, manyThread;
|
||||
uint64_t *keys = (uint64_t *)NULL;
|
||||
|
||||
manyThread = THREAD_MAX;
|
||||
if (manyThread > sizePNK) {
|
||||
manyThread = sizePNK;
|
||||
}
|
||||
|
||||
// pthread handle
|
||||
pthread_t *threads = calloc(sizePNK, sizeof(pthread_t));
|
||||
if (threads == NULL) return NULL;
|
||||
|
||||
// Param
|
||||
RecPar *pRPs = calloc(sizePNK, sizeof(RecPar));
|
||||
if (pRPs == NULL) {
|
||||
free(threads);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t average = sizePNK / manyThread;
|
||||
uint32_t modules = sizePNK % manyThread;
|
||||
|
||||
// Assign tasks
|
||||
for (i = 0, j = 0; i < manyThread; i++, j += average) {
|
||||
pRPs[i].pNK = pNK;
|
||||
pRPs[i].authuid = authuid;
|
||||
pRPs[i].startPos = j;
|
||||
pRPs[i].endPos = j + average;
|
||||
pRPs[i].keys = NULL;
|
||||
// last thread can decrypt more pNK
|
||||
if (i == (manyThread - 1) && modules > 0) {
|
||||
(pRPs[i].endPos) += modules;
|
||||
}
|
||||
pthread_create(&threads[i], NULL, nested_revover, &(pRPs[i]));
|
||||
}
|
||||
|
||||
for (i = 0; i < manyThread; i++) {
|
||||
// wait thread exit...
|
||||
pthread_join(threads[i], NULL);
|
||||
*keyCount += pRPs[i].keyCount;
|
||||
}
|
||||
free(threads);
|
||||
|
||||
if (*keyCount != 0) {
|
||||
keys = malloc((*keyCount) * sizeof(uint64_t));
|
||||
if (keys != NULL) {
|
||||
for (i = 0, j = 0; i < manyThread; i++) {
|
||||
if (pRPs[i].keyCount > 0) {
|
||||
// printf("The thread %d recover %d keys.\r\n", i, pRPs[i].keyCount);
|
||||
if (pRPs[i].keys != NULL) {
|
||||
memcpy(
|
||||
keys + j,
|
||||
pRPs[i].keys,
|
||||
pRPs[i].keyCount * sizeof(uint64_t)
|
||||
);
|
||||
j += pRPs[i].keyCount;
|
||||
free(pRPs[i].keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
countKeys *ck = uniqsort(keys, *keyCount);
|
||||
free(keys);
|
||||
keys = (uint64_t *)NULL;
|
||||
*keyCount = 0;
|
||||
|
||||
if (ck != NULL) {
|
||||
for (i = 0; i < TRY_KEYS; i++) {
|
||||
// We don't known this key, try to break it
|
||||
// This key can be found here two or more times
|
||||
if (ck[i].count > 0) {
|
||||
*keyCount += 1;
|
||||
void *tmp = realloc(keys, sizeof(uint64_t) * (*keyCount));
|
||||
if (tmp != NULL) {
|
||||
keys = tmp;
|
||||
keys[*keyCount - 1] = ck[i].key;
|
||||
} else {
|
||||
printf("Cannot allocate memory for keys on merge.");
|
||||
free(keys);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("Cannot allocate memory for ck on uniqsort.");
|
||||
}
|
||||
} else {
|
||||
printf("Cannot allocate memory to merge keys.\r\n");
|
||||
}
|
||||
}
|
||||
free(pRPs);
|
||||
return keys;
|
||||
}
|
||||
|
||||
// Return 1 if the nonce is invalid else return 0
|
||||
uint8_t valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
|
||||
return (
|
||||
(oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) && \
|
||||
(oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) && \
|
||||
(oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0)))
|
||||
) ? 1 : 0;
|
||||
}
|
15
tools/mfkey/nested_util.h
Normal file
15
tools/mfkey/nested_util.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef NESTED_H__
|
||||
#define NESTED_H__
|
||||
|
||||
#include "crapto1/crapto1.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t ntp;
|
||||
uint32_t ks1;
|
||||
} NtpKs1;
|
||||
|
||||
|
||||
uint8_t valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity);
|
||||
uint64_t *nested(NtpKs1 *pNK, uint32_t sizePNK, uint32_t authuid, uint32_t *keyCount);
|
||||
|
||||
#endif
|
234
tools/mfkey/staticnested.c
Normal file
234
tools/mfkey/staticnested.c
Normal file
|
@ -0,0 +1,234 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include "common.h"
|
||||
#include "nested_util.h"
|
||||
#include "crapto1/crapto1.h"
|
||||
|
||||
|
||||
#define AEND "\x1b[0m"
|
||||
#define _RED_(s) "\x1b[31m" s AEND
|
||||
#define _GREEN_(s) "\x1b[32m" s AEND
|
||||
#define _YELLOW_(s) "\x1b[33m" s AEND
|
||||
#define _CYAN_(s) "\x1b[36m" s AEND
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct Crypto1State *slhead;
|
||||
uint64_t *keyhead;
|
||||
} head;
|
||||
union {
|
||||
struct Crypto1State *sltail;
|
||||
uint64_t *keytail;
|
||||
} tail;
|
||||
uint32_t len;
|
||||
uint32_t uid;
|
||||
uint32_t blockNo;
|
||||
uint32_t keyType;
|
||||
uint32_t nt_enc;
|
||||
uint32_t ks1;
|
||||
} StateList_t;
|
||||
|
||||
|
||||
inline static int compare_uint64(const void *a, const void *b) {
|
||||
if (*(uint64_t *)b == *(uint64_t *)a) return 0;
|
||||
if (*(uint64_t *)b < * (uint64_t *)a) return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Compare 16 Bits out of cryptostate
|
||||
inline static int compare16Bits(const void *a, const void *b) {
|
||||
if ((*(uint64_t *)b & 0x00ff000000ff0000) == (*(uint64_t *)a & 0x00ff000000ff0000)) return 0;
|
||||
if ((*(uint64_t *)b & 0x00ff000000ff0000) > (*(uint64_t *)a & 0x00ff000000ff0000)) return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// create the intersection (common members) of two sorted lists. Lists are terminated by -1. Result will be in list1. Number of elements is returned.
|
||||
static uint32_t intersection(uint64_t *listA, uint64_t *listB) {
|
||||
if (listA == NULL || listB == NULL)
|
||||
return 0;
|
||||
|
||||
uint64_t *p1, *p2, *p3;
|
||||
p1 = p3 = listA;
|
||||
p2 = listB;
|
||||
|
||||
while (*p1 != UINT64_C(-1) && *p2 != UINT64_C(-1)) {
|
||||
if (compare_uint64(p1, p2) == 0) {
|
||||
*p3++ = *p1++;
|
||||
p2++;
|
||||
} else {
|
||||
while (compare_uint64(p1, p2) < 0) ++p1;
|
||||
while (compare_uint64(p1, p2) > 0) ++p2;
|
||||
}
|
||||
}
|
||||
*p3 = UINT64_C(-1);
|
||||
return p3 - listA;
|
||||
}
|
||||
|
||||
// wrapper function for multi-threaded lfsr_recovery32
|
||||
static void
|
||||
#ifdef __has_attribute
|
||||
#if __has_attribute(force_align_arg_pointer)
|
||||
__attribute__((force_align_arg_pointer))
|
||||
#endif
|
||||
#endif
|
||||
*nested_worker_thread(void *arg) {
|
||||
struct Crypto1State *p1;
|
||||
StateList_t *statelist = arg;
|
||||
statelist->head.slhead = lfsr_recovery32(statelist->ks1, statelist->nt_enc ^ statelist->uid);
|
||||
|
||||
for (p1 = statelist->head.slhead; p1->odd | p1->even; p1++) {};
|
||||
|
||||
statelist->len = p1 - statelist->head.slhead;
|
||||
statelist->tail.sltail = --p1;
|
||||
|
||||
qsort(statelist->head.slhead, statelist->len, sizeof(uint64_t), compare16Bits);
|
||||
|
||||
return statelist->head.slhead;
|
||||
}
|
||||
|
||||
static void pm3_staticnested(uint32_t uid, uint32_t nt1, uint32_t ks1, uint32_t nt2, uint32_t ks2) {
|
||||
|
||||
StateList_t statelists[2];
|
||||
struct Crypto1State *p1, * p2, * p3, * p4;
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
statelists[i].uid = uid;
|
||||
}
|
||||
|
||||
statelists[0].nt_enc = nt1;
|
||||
statelists[0].ks1 = ks1;
|
||||
statelists[1].nt_enc = nt2;
|
||||
statelists[1].ks1 = ks2;
|
||||
|
||||
// calc keys
|
||||
pthread_t thread_id[2];
|
||||
|
||||
// create and run worker threads
|
||||
for (uint8_t i = 0; i < 2; i++)
|
||||
pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]);
|
||||
|
||||
// wait for threads to terminate:
|
||||
for (uint8_t i = 0; i < 2; i++)
|
||||
pthread_join(thread_id[i], (void *)&statelists[i].head.slhead);
|
||||
|
||||
// the first 16 Bits of the cryptostate already contain part of our key.
|
||||
// Create the intersection of the two lists based on these 16 Bits and
|
||||
// roll back the cryptostate
|
||||
p1 = p3 = statelists[0].head.slhead;
|
||||
p2 = p4 = statelists[1].head.slhead;
|
||||
|
||||
while (p1 <= statelists[0].tail.sltail && p2 <= statelists[1].tail.sltail) {
|
||||
if (compare16Bits(p1, p2) == 0) {
|
||||
|
||||
struct Crypto1State savestate;
|
||||
savestate = *p1;
|
||||
while (compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) {
|
||||
*p3 = *p1;
|
||||
lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0);
|
||||
p3++;
|
||||
p1++;
|
||||
}
|
||||
savestate = *p2;
|
||||
while (compare16Bits(p2, &savestate) == 0 && p2 <= statelists[1].tail.sltail) {
|
||||
*p4 = *p2;
|
||||
lfsr_rollback_word(p4, statelists[1].nt_enc ^ statelists[1].uid, 0);
|
||||
p4++;
|
||||
p2++;
|
||||
}
|
||||
} else {
|
||||
while (compare16Bits(p1, p2) == -1) p1++;
|
||||
while (compare16Bits(p1, p2) == 1) p2++;
|
||||
}
|
||||
}
|
||||
|
||||
p3->odd = -1;
|
||||
p3->even = -1;
|
||||
p4->odd = -1;
|
||||
p4->even = -1;
|
||||
statelists[0].len = p3 - statelists[0].head.slhead;
|
||||
statelists[1].len = p4 - statelists[1].head.slhead;
|
||||
statelists[0].tail.sltail = --p3;
|
||||
statelists[1].tail.sltail = --p4;
|
||||
|
||||
// the statelists now contain possible keys. The key we are searching for must be in the
|
||||
// intersection of both lists
|
||||
qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compare_uint64);
|
||||
qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compare_uint64);
|
||||
// Create the intersection
|
||||
statelists[0].len = intersection(statelists[0].head.keyhead, statelists[1].head.keyhead);
|
||||
|
||||
uint32_t keycnt = statelists[0].len;
|
||||
if (keycnt) {
|
||||
printf("PM3 Static nested --> Found " _YELLOW_("%u") " key candidates\n", keycnt);
|
||||
for (uint32_t k = 0; k < keycnt; k++) {
|
||||
uint64_t key64 = 0;
|
||||
crypto1_get_lfsr(statelists[0].head.slhead + k, &key64);
|
||||
printf("[ %d ] " _GREEN_("%012" PRIx64) "\n", k + 1, key64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int usage(void) {
|
||||
printf("\n");
|
||||
printf("\nProgram tries to recover keys from static encrypted nested MFC cards\n");
|
||||
printf("using two different implementations, Chameleon Ultra (CU) and Proxmark3.\n");
|
||||
printf("It uses the nonce, keystream sent from pm3 device to client.\n");
|
||||
printf("ie: NOT the CU data which is data in the trace.\n");
|
||||
printf("\n");
|
||||
printf("syntax: staticnested <uid> <nt1> <ks1> <nt2> <ks2>\n\n");
|
||||
printf("samples:\n");
|
||||
printf("\n");
|
||||
printf(" ./staticnested 461dce03 7eef3586 ffb02eda 322bc14d ffc875ca\n");
|
||||
printf("\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *const argv[]) {
|
||||
|
||||
printf("\nMIFARE Classic static nested key recovery\n\n");
|
||||
|
||||
if (argc < 5) return usage();
|
||||
|
||||
printf("Init...\n");
|
||||
NtpKs1 *pNK = calloc(2, sizeof(NtpKs1));
|
||||
if (pNK == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
uint32_t uid = 0;
|
||||
|
||||
sscanf(argv[1], "%x", &uid);
|
||||
sscanf(argv[2], "%x", &pNK[0].ntp);
|
||||
sscanf(argv[3], "%x", &pNK[0].ks1);
|
||||
sscanf(argv[4], "%x", &pNK[1].ntp);
|
||||
sscanf(argv[5], "%x", &pNK[1].ks1);
|
||||
|
||||
printf("uid... %08x\n", uid);
|
||||
printf("nt1... %08x\n", pNK[0].ntp);
|
||||
printf("ks1... %08x\n", pNK[0].ks1);
|
||||
printf("nt2... %08x\n", pNK[1].ntp);
|
||||
printf("ks2... %08x\n", pNK[1].ks1);
|
||||
|
||||
// process all args.
|
||||
printf("Recovery...\n");
|
||||
|
||||
uint32_t key_count = 0;
|
||||
uint64_t *keys = nested(pNK, 2, uid, &key_count);
|
||||
if (key_count) {
|
||||
printf("Ultra Static nested --> Found " _YELLOW_("%u") " key candidates\n", key_count);
|
||||
for (uint32_t k = 0; k < key_count; k++) {
|
||||
printf("[ %d ] " _GREEN_("%012" PRIx64) "\n", k + 1, keys[k]);
|
||||
}
|
||||
}
|
||||
|
||||
pm3_staticnested(uid, pNK[0].ntp, pNK[0].ks1, pNK[1].ntp, pNK[1].ks1);
|
||||
|
||||
fflush(stdout);
|
||||
free(keys);
|
||||
exit(EXIT_SUCCESS);
|
||||
error:
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
9
tools/mfkey/test_static.sh
Executable file
9
tools/mfkey/test_static.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
./staticnested 461dce03 7eef3586 ffb02eda 322bc14d ffc875ca;
|
||||
./staticnested 461dce03 7eef3586 7f21594f 322bc14d 7f815fba;
|
||||
./staticnested 461dce03 7eef3586 ff315fe7 322bc14d ffc1364d;
|
||||
./staticnested 461dce03 7eef3586 d742a617 322bc14d d7f2f337;
|
||||
./staticnested 461dce03 7eef3586 5e3e037c 322bc14d 5ef705c2;
|
||||
./staticnested 461dce03 7eef3586 5fcaebc6 322bc14d 5f72de17;
|
||||
./staticnested 461dce03 7eef3586 3fbcfb30 322bc14d 3fe4c47c;
|
||||
./staticnested 461dce03 7eef3586 1fb6b496 322bc14d 1f4eebdd;
|
||||
./staticnested 461dce03 7eef3586 7fa28c7e 322bc14d 7f62b3d6;
|
|
@ -283,13 +283,15 @@ while true; do
|
|||
if ! CheckFileExist "fpgacompress exists" "$FPGACPMPRESSBIN"; then break; fi
|
||||
fi
|
||||
if $TESTALL || $TESTMFKEY; then
|
||||
echo -e "\n${C_BLUE}Testing mfkey:${C_NC} ${MFKEY32V2BIN:=./tools/mfkey/mfkey32v2} ${MFKEY64BIN:=./tools/mfkey/mfkey64}"
|
||||
echo -e "\n${C_BLUE}Testing mfkey:${C_NC} ${MFKEY32V2BIN:=./tools/mfkey/mfkey32v2} ${MFKEY64BIN:=./tools/mfkey/mfkey64} ${STATICNESTEDBIN:=./tools/mfkey/staticnested}"
|
||||
if ! CheckFileExist "mfkey32v2 exists" "$MFKEY32V2BIN"; then break; fi
|
||||
if ! CheckFileExist "mfkey64 exists" "$MFKEY64BIN"; then break; fi
|
||||
if ! CheckFileExist "staticnested exists" "$STATICNESTEDBIN"; then break; fi
|
||||
# Need a decent example for mfkey32...
|
||||
if ! CheckExecute "mfkey32v2 test" "$MFKEY32V2BIN 12345678 1AD8DF2B 1D316024 620EF048 30D6CB07 C52077E2 837AC61A" "Found Key: \[a0a1a2a3a4a5\]"; then break; fi
|
||||
if ! CheckExecute "mfkey64 test" "$MFKEY64BIN 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439" "Found Key: \[ffffffffffff\]"; then break; fi
|
||||
if ! CheckExecute "mfkey64 long trace test" "$MFKEY64BIN 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea" "Found Key: \[091e639cb715\]"; then break; fi
|
||||
if ! CheckExecute "staticnested test" "$STATICNESTEDBIN 461dce03 7eef3586 7fa28c7e 322bc14d 7f62b3d6" "\[ 2 \].*ffffffffff40.*"; then break; fi
|
||||
fi
|
||||
if $TESTALL || $TESTNONCE2KEY; then
|
||||
echo -e "\n${C_BLUE}Testing nonce2key:${C_NC} ${NONCE2KEYBIN:=./tools/nonce2key/nonce2key}"
|
||||
|
|
Loading…
Reference in a new issue