Picopass standard KDF dictionary (#2478)

* Split iclass dictionaries based on KDF
* Allow cancelling during key test

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Eric Betts 2023-03-15 05:35:11 -07:00 committed by GitHub
parent 3a242e5fc3
commit e22668e196
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 41 deletions

View File

@ -5,6 +5,7 @@
#define ICLASS_ELITE_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_elite_dict.txt")
#define ICLASS_ELITE_DICT_USER_NAME APP_DATA_PATH("assets/iclass_elite_dict_user.txt")
#define ICLASS_STANDARD_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_standard_dict.txt")
#define TAG "IclassEliteDict"
@ -25,6 +26,9 @@ bool iclass_elite_dict_check_presence(IclassEliteDictType dict_type) {
(storage_common_stat(storage, ICLASS_ELITE_DICT_FLIPPER_NAME, NULL) == FSE_OK);
} else if(dict_type == IclassEliteDictTypeUser) {
dict_present = (storage_common_stat(storage, ICLASS_ELITE_DICT_USER_NAME, NULL) == FSE_OK);
} else if(dict_type == IclassStandardDictTypeFlipper) {
dict_present =
(storage_common_stat(storage, ICLASS_STANDARD_DICT_FLIPPER_NAME, NULL) == FSE_OK);
}
furi_record_close(RECORD_STORAGE);
@ -52,6 +56,15 @@ IclassEliteDict* iclass_elite_dict_alloc(IclassEliteDictType dict_type) {
buffered_file_stream_close(dict->stream);
break;
}
} else if(dict_type == IclassStandardDictTypeFlipper) {
if(!buffered_file_stream_open(
dict->stream,
ICLASS_STANDARD_DICT_FLIPPER_NAME,
FSAM_READ,
FSOM_OPEN_EXISTING)) {
buffered_file_stream_close(dict->stream);
break;
}
}
// Read total amount of keys
@ -148,4 +161,4 @@ bool iclass_elite_dict_add_key(IclassEliteDict* dict, uint8_t* key) {
furi_string_free(key_str);
return key_added;
}
}

View File

@ -9,6 +9,7 @@
typedef enum {
IclassEliteDictTypeUser,
IclassEliteDictTypeFlipper,
IclassStandardDictTypeFlipper,
} IclassEliteDictType;
typedef struct IclassEliteDict IclassEliteDict;
@ -25,4 +26,4 @@ bool iclass_elite_dict_get_next_key(IclassEliteDict* dict, uint8_t* key);
bool iclass_elite_dict_rewind(IclassEliteDict* dict);
bool iclass_elite_dict_add_key(IclassEliteDict* dict, uint8_t* key);
bool iclass_elite_dict_add_key(IclassEliteDict* dict, uint8_t* key);

View File

@ -172,14 +172,18 @@ ReturnCode picopass_read_preauth(PicopassBlock* AA1) {
return ERR_NONE;
}
static ReturnCode picopass_auth_dict(
uint8_t* csn,
PicopassPacs* pacs,
uint8_t* div_key,
IclassEliteDictType dict_type,
bool elite) {
static ReturnCode
picopass_auth_dict(PicopassWorker* picopass_worker, IclassEliteDictType dict_type) {
rfalPicoPassReadCheckRes rcRes;
rfalPicoPassCheckRes chkRes;
bool elite = (dict_type != IclassStandardDictTypeFlipper);
PicopassDeviceData* dev_data = picopass_worker->dev_data;
PicopassBlock* AA1 = dev_data->AA1;
PicopassPacs* pacs = &dev_data->pacs;
uint8_t* csn = AA1[PICOPASS_CSN_BLOCK_INDEX].data;
uint8_t* div_key = AA1[PICOPASS_KD_BLOCK_INDEX].data;
ReturnCode err = ERR_PARAM;
@ -204,7 +208,8 @@ static ReturnCode picopass_auth_dict(
while(iclass_elite_dict_get_next_key(dict, key)) {
FURI_LOG_D(
TAG,
"Try to auth with key %zu %02x%02x%02x%02x%02x%02x%02x%02x",
"Try to %s auth with key %zu %02x%02x%02x%02x%02x%02x%02x%02x",
elite ? "elite" : "standard",
index++,
key[0],
key[1],
@ -230,6 +235,8 @@ static ReturnCode picopass_auth_dict(
memcpy(pacs->key, key, PICOPASS_BLOCK_LEN);
break;
}
if(picopass_worker->state != PicopassWorkerStateDetect) break;
}
iclass_elite_dict_free(dict);
@ -237,38 +244,23 @@ static ReturnCode picopass_auth_dict(
return err;
}
ReturnCode picopass_auth(PicopassBlock* AA1, PicopassPacs* pacs) {
ReturnCode picopass_auth(PicopassWorker* picopass_worker) {
ReturnCode err;
FURI_LOG_I(TAG, "Starting system dictionary attack [Standard KDF]");
err = picopass_auth_dict(
AA1[PICOPASS_CSN_BLOCK_INDEX].data,
pacs,
AA1[PICOPASS_KD_BLOCK_INDEX].data,
IclassEliteDictTypeFlipper,
false);
err = picopass_auth_dict(picopass_worker, IclassStandardDictTypeFlipper);
if(err == ERR_NONE) {
return ERR_NONE;
}
FURI_LOG_I(TAG, "Starting user dictionary attack [Elite KDF]");
err = picopass_auth_dict(
AA1[PICOPASS_CSN_BLOCK_INDEX].data,
pacs,
AA1[PICOPASS_KD_BLOCK_INDEX].data,
IclassEliteDictTypeUser,
true);
err = picopass_auth_dict(picopass_worker, IclassEliteDictTypeUser);
if(err == ERR_NONE) {
return ERR_NONE;
}
FURI_LOG_I(TAG, "Starting system dictionary attack [Elite KDF]");
err = picopass_auth_dict(
AA1[PICOPASS_CSN_BLOCK_INDEX].data,
pacs,
AA1[PICOPASS_KD_BLOCK_INDEX].data,
IclassEliteDictTypeFlipper,
true);
err = picopass_auth_dict(picopass_worker, IclassEliteDictTypeFlipper);
if(err == ERR_NONE) {
return ERR_NONE;
}
@ -520,7 +512,7 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) {
}
if(nextState == PicopassWorkerEventSuccess) {
err = picopass_auth(AA1, pacs);
err = picopass_auth(picopass_worker);
if(err != ERR_NONE) {
FURI_LOG_E(TAG, "picopass_try_auth error %d", err);
nextState = PicopassWorkerEventFail;

View File

@ -1,16 +1,10 @@
## From https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/iclass_default_keys.dic
# AA1
AEA684A6DAB23278
# key1/Kc from PicoPass 2k documentation
7665544332211000
# SAGEM
0123456789ABCDEF
# from loclass demo file.
5b7c62c491c11b39
# Kd from PicoPass 2k documentation
F0E1D2C3B4A59687
# PicoPass Default Exchange Key
5CBCF1DA45D5FB4F
# From HID multiclassSE reader
@ -19,12 +13,6 @@ F0E1D2C3B4A59687
6EFD46EFCBB3C875
E033CA419AEE43F9
# iCopy-x DRM keys
# iCL tags
2020666666668888
# iCS tags reversed from the SOs
6666202066668888
# default picopass KD / Page 0 / Book 1
FDCB5A52EA8F3090
237FF9079863DF44

View File

@ -0,0 +1,47 @@
## From https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/iclass_default_keys.dic
# AA1
AEA684A6DAB23278
# key1/Kc from PicoPass 2k documentation
7665544332211000
# SAGEM
0123456789ABCDEF
# from loclass demo file.
5b7c62c491c11b39
# Kd from PicoPass 2k documentation
F0E1D2C3B4A59687
# PicoPass Default Exchange Key
5CBCF1DA45D5FB4F
# From HID multiclassSE reader
31ad7ebd2f282168
# From pastebin: https://pastebin.com/uHqpjiuU
6EFD46EFCBB3C875
E033CA419AEE43F9
# iCopy-x DRM keys
# iCL tags
2020666666668888
# iCS tags reversed from the SOs
6666202066668888
# default picopass KD / Page 0 / Book 1
FDCB5A52EA8F3090
237FF9079863DF44
5ADC25FB27181D32
83B881F2936B2E49
43644E61EE866BA5
897034143D016080
82D17B44C0122963
4895CA7DE65E2025
DADAD4C57BE271B7
E41E9EDEF5719ABF
293D275EC3AF9C7F
C3C169251B8A70FB
F41DAF58B20C8B91
28877A609EC0DD2B
66584C91EE80D5E5
C1B74D7478053AE2
# default iCLASS RFIDeas
6B65797374726B72