mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
Merge pull request #2942 from mistial-dev/feature-desfire-commands
DESFire: fix value file operations and improve MAC mode compatibility
This commit is contained in:
commit
43a012b613
5 changed files with 353 additions and 9 deletions
|
@ -463,7 +463,7 @@ static void swap24(uint8_t *data) {
|
||||||
|
|
||||||
// default parameters
|
// default parameters
|
||||||
static uint8_t defaultKeyNum = 0;
|
static uint8_t defaultKeyNum = 0;
|
||||||
static DesfireCryptoAlgorithm defaultAlgoId = T_DES;
|
static DesfireCryptoAlgorithm defaultAlgoId = T_3DES; // Real DESFire cards seem to use 2TDEA by default
|
||||||
static uint8_t defaultKey[DESFIRE_MAX_KEY_SIZE] = {0};
|
static uint8_t defaultKey[DESFIRE_MAX_KEY_SIZE] = {0};
|
||||||
static int defaultKdfAlgo = MFDES_KDF_ALGO_NONE;
|
static int defaultKdfAlgo = MFDES_KDF_ALGO_NONE;
|
||||||
static int defaultKdfInputLen = 0;
|
static int defaultKdfInputLen = 0;
|
||||||
|
@ -4034,7 +4034,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
|
||||||
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
||||||
arg_lit0("v", "verbose", "Verbose output"),
|
arg_lit0("v", "verbose", "Verbose output"),
|
||||||
arg_int0("n", "keyno", "<dec>", "Key number"),
|
arg_int0("n", "keyno", "<dec>", "Key number"),
|
||||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
|
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo (deft: 2TDEA)"),
|
||||||
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
||||||
arg_str0(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
arg_str0(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
||||||
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
||||||
|
@ -4474,7 +4474,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
|
||||||
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
||||||
arg_lit0("v", "verbose", "Verbose output"),
|
arg_lit0("v", "verbose", "Verbose output"),
|
||||||
arg_int0("n", "keyno", "<dec>", "Key number"),
|
arg_int0("n", "keyno", "<dec>", "Key number"),
|
||||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
|
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo (deft: 2TDEA)"),
|
||||||
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
||||||
arg_str0(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
arg_str0(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
||||||
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
||||||
|
|
|
@ -2240,6 +2240,20 @@ int DesfireValueFileOperations(DesfireContext_t *dctx, uint8_t fid, uint8_t oper
|
||||||
|
|
||||||
int res = DesfireCommand(dctx, operation, data, datalen, resp, &resplen, -1);
|
int res = DesfireCommand(dctx, operation, data, datalen, resp, &resplen, -1);
|
||||||
|
|
||||||
|
// Auto-detection fallback: if MAC mode fails with length error, retry with plain mode
|
||||||
|
if ((res == 0x7E || res == -20) && dctx->commMode == DCMMACed) {
|
||||||
|
PrintAndLogEx(INFO, "MAC mode failed with length error, retrying with plain mode");
|
||||||
|
DesfireCommunicationMode original_mode = dctx->commMode;
|
||||||
|
dctx->commMode = DCMPlain;
|
||||||
|
|
||||||
|
memset(resp, 0, sizeof(resp));
|
||||||
|
resplen = 0;
|
||||||
|
res = DesfireCommand(dctx, operation, data, datalen, resp, &resplen, -1);
|
||||||
|
|
||||||
|
// Restore original mode for future commands
|
||||||
|
dctx->commMode = original_mode;
|
||||||
|
}
|
||||||
|
|
||||||
if (resplen == 4 && value) {
|
if (resplen == 4 && value) {
|
||||||
*value = MemLeToUint4byte(resp);
|
*value = MemLeToUint4byte(resp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,9 +219,6 @@ static uint8_t DesfireGetCmdHeaderLen(uint8_t cmd) {
|
||||||
|
|
||||||
static const uint8_t EV1D40TransmitMAC[] = {
|
static const uint8_t EV1D40TransmitMAC[] = {
|
||||||
MFDES_WRITE_DATA,
|
MFDES_WRITE_DATA,
|
||||||
MFDES_CREDIT,
|
|
||||||
MFDES_LIMITED_CREDIT,
|
|
||||||
MFDES_DEBIT,
|
|
||||||
MFDES_WRITE_RECORD,
|
MFDES_WRITE_RECORD,
|
||||||
MFDES_UPDATE_RECORD,
|
MFDES_UPDATE_RECORD,
|
||||||
MFDES_COMMIT_READER_ID,
|
MFDES_COMMIT_READER_ID,
|
||||||
|
|
191
doc/desfire.md
191
doc/desfire.md
|
@ -23,6 +23,7 @@
|
||||||
- [How to create files](#how-to-create-files)
|
- [How to create files](#how-to-create-files)
|
||||||
- [How to delete files](#how-to-delete-files)
|
- [How to delete files](#how-to-delete-files)
|
||||||
- [How to read/write files](#how-to-readwrite-files)
|
- [How to read/write files](#how-to-readwrite-files)
|
||||||
|
- [How to work with value files](#how-to-work-with-value-files)
|
||||||
- [How to work with transaction mac](#how-to-work-with-transaction-mac)
|
- [How to work with transaction mac](#how-to-work-with-transaction-mac)
|
||||||
- [How to switch DESFire Light to LRP mode](#how-to-switch-desfire-light-to-lrp-mode)
|
- [How to switch DESFire Light to LRP mode](#how-to-switch-desfire-light-to-lrp-mode)
|
||||||
|
|
||||||
|
@ -254,7 +255,7 @@ Create standard file with mac access mode and specified access settings. access
|
||||||
|
|
||||||
`hf mfdes createfile --aid 123456 --fid 01 --isofid 0001 --size 000010 --amode mac --rrights free --wrights free --rwrights free --chrights key0`
|
`hf mfdes createfile --aid 123456 --fid 01 --isofid 0001 --size 000010 --amode mac --rrights free --wrights free --rwrights free --chrights key0`
|
||||||
|
|
||||||
`hf mfdes createvaluefile --aid 123456 --fid 01 --isofid 0001 --lower 00000010 --upper 00010000 --value 00000100` - create value file
|
`hf mfdes createvaluefile --aid 123456 --fid 01 --isofid 0001 --lower 00000010 --upper 00010000 --value 00000100` - create value file (see [How to work with value files](#how-to-work-with-value-files) for detailed examples)
|
||||||
|
|
||||||
`hf mfdes createrecordfile --aid 123456 --fid 01 --isofid 0001 --size 000010 --maxrecord 000010` - create linear record file
|
`hf mfdes createrecordfile --aid 123456 --fid 01 --isofid 0001 --size 000010 --maxrecord 000010` - create linear record file
|
||||||
|
|
||||||
|
@ -294,9 +295,11 @@ Here it is needed to specify the type of the file because there is no `hf mfdes
|
||||||
|
|
||||||
`hf mfdes write --aid 123456 --fid 01 --type data -d 01020304 --commit` - write backup data file and commit
|
`hf mfdes write --aid 123456 --fid 01 --type data -d 01020304 --commit` - write backup data file and commit
|
||||||
|
|
||||||
`hf mfdes write --aid 123456 --fid 01 --type value -d 00000001` increment value file
|
`hf mfdes write --aid 123456 --fid 01 --type value -d 00000001` increment value file (deprecated, use `hf mfdes value` command)
|
||||||
|
|
||||||
`hf mfdes write --aid 123456 --fid 01 --type value -d 00000001 --debit` decrement value file
|
`hf mfdes write --aid 123456 --fid 01 --type value -d 00000001 --debit` decrement value file (deprecated, use `hf mfdes value` command)
|
||||||
|
|
||||||
|
For modern value file operations, see [How to work with value files](#how-to-work-with-value-files)
|
||||||
|
|
||||||
`hf mfdes write --aid 123456 --fid 01 --type record -d 01020304` write data to a record file
|
`hf mfdes write --aid 123456 --fid 01 --type record -d 01020304` write data to a record file
|
||||||
|
|
||||||
|
@ -314,6 +317,188 @@ For more detailed samples look at the next howto.
|
||||||
|
|
||||||
`hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203` write data to the file with CommitReaderID command before and CommitTransaction after write
|
`hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203` write data to the file with CommitReaderID command before and CommitTransaction after write
|
||||||
|
|
||||||
|
### How to work with value files
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
Value files are specialized files designed for storing and manipulating monetary values or counters. They provide atomic operations for incrementing (credit) and decrementing (debit) values with built-in limits and security features.
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- 32-bit value storage (represented internally as unsigned)
|
||||||
|
- Lower and upper limits to prevent underflow/overflow
|
||||||
|
- Atomic operations with automatic transaction commit
|
||||||
|
- Transaction logging support
|
||||||
|
- Secure communication modes (plain, MAC, encrypted)
|
||||||
|
|
||||||
|
**Value File Structure:**
|
||||||
|
- Current value: 32-bit value
|
||||||
|
- Lower limit: minimum allowed value (prevents underflow)
|
||||||
|
- Upper limit: maximum allowed value (prevents overflow)
|
||||||
|
|
||||||
|
**Access Rights:**
|
||||||
|
Value files use four access right categories:
|
||||||
|
- **Read**: Required to get the current value (`hf mfdes value --op get`)
|
||||||
|
- **Write**: Required for debit operations (`hf mfdes value --op debit`)
|
||||||
|
- **Read/Write**: Required for credit operations (`hf mfdes value --op credit`)
|
||||||
|
- **Change**: Required to modify file settings or delete the file
|
||||||
|
|
||||||
|
Access rights can be set to:
|
||||||
|
- `key0` through `keyE`: Requires authentication with the specified key
|
||||||
|
- `free`: No authentication required
|
||||||
|
- `deny`: Operation is forbidden
|
||||||
|
|
||||||
|
*Create value file:*
|
||||||
|
|
||||||
|
Creating a Bitcoin wallet on your DESFire card:
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes createapp --aid 425443 --ks1 0B --ks2 0E
|
||||||
|
[+] Desfire application 425443 successfully created
|
||||||
|
|
||||||
|
pm3 --> hf mfdes createvaluefile --aid 425443 --fid 01 --lower 00000000 --upper 01406F40 --value 00000032
|
||||||
|
[=] ---- Create file settings ----
|
||||||
|
[+] File type : Value
|
||||||
|
[+] File number : 0x01 (1)
|
||||||
|
[+] File comm mode : Plain
|
||||||
|
[+] Additional access: No
|
||||||
|
[+] Access rights : EEEE
|
||||||
|
[+] read......... free
|
||||||
|
[+] write........ free
|
||||||
|
[+] read/write... free
|
||||||
|
[+] change....... free
|
||||||
|
[=] Lower limit... 0 / 0x00000000
|
||||||
|
[=] Upper limit... 21000000 / 0x01406F40
|
||||||
|
[=] Value............ 50 / 0x00000032
|
||||||
|
[=] Limited credit... 0 - disabled
|
||||||
|
[=] GetValue access... Not Free
|
||||||
|
[+] Value file 01 in the app 425443 created successfully
|
||||||
|
```
|
||||||
|
This creates a DESFire Bitcoin wallet with:
|
||||||
|
- Application ID 0x425443 (ASCII "BTC")
|
||||||
|
- File ID 0x01 for the wallet
|
||||||
|
- Lower limit: 0 BTC (no overdrafts in crypto)
|
||||||
|
- Upper limit: 21,000,000 BTC (respecting Satoshi's vision)
|
||||||
|
- Initial value: 50 BTC (the original block reward)
|
||||||
|
|
||||||
|
Creating the infamous Pizza Day wallet:
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes createvaluefile --aid 425443 --fid 02 --lower 00000000 --upper 01406F40 --value 00002710
|
||||||
|
[=] ---- Create file settings ----
|
||||||
|
[+] File type : Value
|
||||||
|
[+] File number : 0x02 (2)
|
||||||
|
[+] File comm mode : Plain
|
||||||
|
[+] Additional access: No
|
||||||
|
[+] Access rights : EEEE
|
||||||
|
[+] read......... free
|
||||||
|
[+] write........ free
|
||||||
|
[+] read/write... free
|
||||||
|
[+] change....... free
|
||||||
|
[=] Lower limit... 0 / 0x00000000
|
||||||
|
[=] Upper limit... 21000000 / 0x01406F40
|
||||||
|
[=] Value............ 10000 / 0x00002710
|
||||||
|
[=] Limited credit... 0 - disabled
|
||||||
|
[=] GetValue access... Not Free
|
||||||
|
[+] Value file 02 in the app 425443 created successfully
|
||||||
|
```
|
||||||
|
This creates a wallet pre-loaded with 10,000 BTC (historical exchange rate: 2 pizzas)
|
||||||
|
|
||||||
|
*Value file operations:*
|
||||||
|
|
||||||
|
Check your Bitcoin balance:
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op get
|
||||||
|
[+] Value: 50 (0x00000032)
|
||||||
|
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op get -m mac
|
||||||
|
[+] Value: 50 (0x00000032)
|
||||||
|
```
|
||||||
|
|
||||||
|
Loading Bitcoin IOUs onto your card:
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op credit -d 00000019
|
||||||
|
[+] Value changed successfully
|
||||||
|
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op get
|
||||||
|
[+] Value: 75 (0x0000004b)
|
||||||
|
```
|
||||||
|
Card now holds 75 BTC in IOUs ($9,000,000 in debt obligations)
|
||||||
|
|
||||||
|
Buying coffee with Bitcoin IOUs:
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op debit -d 00000001
|
||||||
|
[+] Value changed successfully # You now owe the coffee shop $120,000
|
||||||
|
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op get
|
||||||
|
[+] Value: 74 (0x0000004a) # Remaining debt capacity
|
||||||
|
```
|
||||||
|
|
||||||
|
The legendary Pizza Day recreation:
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 02 --op debit -d 00002710
|
||||||
|
[+] Value changed successfully # You now owe Papa John's $1.2 billion
|
||||||
|
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 02 --op get
|
||||||
|
[+] Value: 0 (0x00000000) # Card empty, bankruptcy imminent
|
||||||
|
```
|
||||||
|
|
||||||
|
*Communication modes:*
|
||||||
|
|
||||||
|
Value files support different communication modes for security:
|
||||||
|
|
||||||
|
Plain mode (no encryption):
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes value --aid 123456 --fid 02 --op get -m plain
|
||||||
|
[+] Value: 125 (0x0000007d)
|
||||||
|
```
|
||||||
|
|
||||||
|
MAC mode (message authentication):
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes value --aid 123456 --fid 02 --op credit -d 00000032 -m mac
|
||||||
|
[+] Value changed successfully
|
||||||
|
```
|
||||||
|
|
||||||
|
Encrypted mode (full encryption):
|
||||||
|
```
|
||||||
|
pm3 --> hf mfdes value --aid 123456 --fid 02 --op debit -d 00000014 -m encrypted
|
||||||
|
[+] Value changed successfully
|
||||||
|
```
|
||||||
|
|
||||||
|
*Error handling and compatibility:*
|
||||||
|
|
||||||
|
The Proxmark3 implementation includes automatic fallback for compatibility:
|
||||||
|
- If MAC mode fails with a length error (-20), it automatically retries in plain mode
|
||||||
|
- This ensures compatibility across different DESFire card generations
|
||||||
|
- Original communication mode is restored after fallback
|
||||||
|
|
||||||
|
*Transaction behavior:*
|
||||||
|
|
||||||
|
Value operations are atomic with automatic commit:
|
||||||
|
- The `hf mfdes value` command automatically issues CommitTransaction after credit/debit operations
|
||||||
|
- Get operations do not require a commit
|
||||||
|
- Operations either complete fully (including commit) or fail completely
|
||||||
|
- No manual transaction management required when using the `hf mfdes value` command
|
||||||
|
- Transaction MAC files can log all value operations for audit trails
|
||||||
|
|
||||||
|
*Practical examples:*
|
||||||
|
|
||||||
|
Daily Bitcoin IOU catastrophes:
|
||||||
|
```
|
||||||
|
# Check morning IOU balance
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op get
|
||||||
|
[+] Value: 50 (0x00000032) # $6 million in IOUs
|
||||||
|
|
||||||
|
# Friend sends you more IOUs via NFC bump
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op credit -d 000000C8
|
||||||
|
[+] Value changed successfully # +200 BTC IOUs ($24M more debt)
|
||||||
|
|
||||||
|
# Buy a Tesla (tap payment)
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op debit -d 00000001
|
||||||
|
[+] Value changed successfully
|
||||||
|
|
||||||
|
# Check remaining IOU capacity
|
||||||
|
pm3 --> hf mfdes value --aid 425443 --fid 01 --op get
|
||||||
|
[+] Value: 273 (0x00000111) # $32.76M in transferable debt
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### How to work with transaction mac
|
### How to work with transaction mac
|
||||||
^[Top](#top)
|
^[Top](#top)
|
||||||
|
|
||||||
|
|
148
tools/pm3_online_tests.sh
Executable file
148
tools/pm3_online_tests.sh
Executable file
|
@ -0,0 +1,148 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Online tests that require actual PM3 device connection
|
||||||
|
# This is used to make sure that the language for the functions is english instead of the system default language.
|
||||||
|
LANG=C
|
||||||
|
|
||||||
|
PM3PATH="$(dirname "$0")/.."
|
||||||
|
cd "$PM3PATH" || exit 1
|
||||||
|
|
||||||
|
TESTALL=false
|
||||||
|
TESTDESFIREVALUE=false
|
||||||
|
|
||||||
|
# https://medium.com/@Drew_Stokes/bash-argument-parsing-54f3b81a6a8f
|
||||||
|
PARAMS=""
|
||||||
|
while (( "$#" )); do
|
||||||
|
case "$1" in
|
||||||
|
-h|--help)
|
||||||
|
echo """
|
||||||
|
Usage: $0 [--pm3bin /path/to/pm3] [desfire_value]
|
||||||
|
--pm3bin ...: Specify path to pm3 binary to test
|
||||||
|
desfire_value: Test DESFire value operations with card
|
||||||
|
You must specify a test target - no default 'all' for online tests
|
||||||
|
"""
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--pm3bin)
|
||||||
|
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
|
||||||
|
PM3BIN=$2
|
||||||
|
shift 2
|
||||||
|
else
|
||||||
|
echo "Error: Argument for $1 is missing" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
desfire_value)
|
||||||
|
TESTALL=false
|
||||||
|
TESTDESFIREVALUE=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-*|--*=) # unsupported flags
|
||||||
|
echo "Error: Unsupported flag $1" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*) # preserve positional arguments
|
||||||
|
PARAMS="$PARAMS $1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
# set positional arguments in their proper place
|
||||||
|
eval set -- "$PARAMS"
|
||||||
|
|
||||||
|
C_RED='\033[0;31m'
|
||||||
|
C_GREEN='\033[0;32m'
|
||||||
|
C_YELLOW='\033[0;33m'
|
||||||
|
C_BLUE='\033[0;34m'
|
||||||
|
C_NC='\033[0m' # No Color
|
||||||
|
C_OK='\xe2\x9c\x94\xef\xb8\x8f'
|
||||||
|
C_FAIL='\xe2\x9d\x8c'
|
||||||
|
|
||||||
|
# Check if file exists
|
||||||
|
function CheckFileExist() {
|
||||||
|
printf "%-40s" "$1 "
|
||||||
|
if [ -f "$2" ]; then
|
||||||
|
echo -e "[ ${C_GREEN}OK${C_NC} ] ${C_OK}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if ls "$2" 1> /dev/null 2>&1; then
|
||||||
|
echo -e "[ ${C_GREEN}OK${C_NC} ] ${C_OK}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo -e "[ ${C_RED}FAIL${C_NC} ] ${C_FAIL}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute command and check result
|
||||||
|
function CheckExecute() {
|
||||||
|
printf "%-40s" "$1 "
|
||||||
|
|
||||||
|
start=$(date +%s)
|
||||||
|
TIMEINFO=""
|
||||||
|
RES=$(eval "$2")
|
||||||
|
end=$(date +%s)
|
||||||
|
delta=$(expr $end - $start)
|
||||||
|
if [ $delta -gt 2 ]; then
|
||||||
|
TIMEINFO=" ($delta s)"
|
||||||
|
fi
|
||||||
|
if echo "$RES" | grep -E -q "$3"; then
|
||||||
|
echo -e "[ ${C_GREEN}OK${C_NC} ] ${C_OK} $TIMEINFO"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo -e "[ ${C_RED}FAIL${C_NC} ] ${C_FAIL} $TIMEINFO"
|
||||||
|
echo "Execution trace:"
|
||||||
|
echo "$RES"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo -e "${C_BLUE}Iceman Proxmark3 online test tool${C_NC}"
|
||||||
|
echo ""
|
||||||
|
echo "work directory: $(pwd)"
|
||||||
|
|
||||||
|
if command -v git >/dev/null && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
echo -n "git branch: "
|
||||||
|
git describe --all
|
||||||
|
echo -n "git sha: "
|
||||||
|
git rev-parse HEAD
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check that user specified a test
|
||||||
|
if [ "$TESTDESFIREVALUE" = false ]; then
|
||||||
|
echo "Error: You must specify a test target. Use -h for help."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
# DESFire value tests
|
||||||
|
if $TESTDESFIREVALUE; then
|
||||||
|
echo -e "\n${C_BLUE}Testing DESFire card value operations${C_NC} ${PM3BIN:=./pm3}"
|
||||||
|
echo " PLACE A FACTORY DESFIRE CARD ON THE READER NOW"
|
||||||
|
if ! CheckFileExist "pm3 exists" "$PM3BIN"; then break; fi
|
||||||
|
|
||||||
|
echo " Formatting card to clean state..."
|
||||||
|
if ! CheckExecute "format card" "$PM3BIN -c 'hf mfdes formatpicc'" "done"; then break; fi
|
||||||
|
|
||||||
|
echo " Running value operation tests..."
|
||||||
|
if ! CheckExecute "card auth test" "$PM3BIN -c 'hf mfdes auth -n 0 -t 2tdea -k 00000000000000000000000000000000 --kdf none'" "authenticated.*succes"; then break; fi
|
||||||
|
if ! CheckExecute "card app creation" "$PM3BIN -c 'hf mfdes createapp --aid 123456 --ks1 0F --ks2 0E --numkeys 1'" "successfully created"; then break; fi
|
||||||
|
if ! CheckExecute "card value file creation" "$PM3BIN -c 'hf mfdes createvaluefile --aid 123456 --fid 02 --lower 00000000 --upper 000003E8 --value 00000064'" "created successfully"; then break; fi
|
||||||
|
if ! CheckExecute "card value get plain" "$PM3BIN -c 'hf mfdes value --aid 123456 --fid 02 --op get -m plain'" "Value.*100"; then break; fi
|
||||||
|
if ! CheckExecute "card value get mac" "$PM3BIN -c 'hf mfdes value --aid 123456 --fid 02 --op get -m mac'" "Value.*100"; then break; fi
|
||||||
|
if ! CheckExecute "card value credit plain" "$PM3BIN -c 'hf mfdes value --aid 123456 --fid 02 --op credit -d 00000032 -m plain'" "Value.*changed"; then break; fi
|
||||||
|
if ! CheckExecute "card value get after credit" "$PM3BIN -c 'hf mfdes value --aid 123456 --fid 02 --op get -m plain'" "Value.*150"; then break; fi
|
||||||
|
if ! CheckExecute "card value credit mac" "$PM3BIN -c 'hf mfdes value --aid 123456 --fid 02 --op credit -d 0000000A -m mac'" "Value.*changed"; then break; fi
|
||||||
|
if ! CheckExecute "card value debit plain" "$PM3BIN -c 'hf mfdes value --aid 123456 --fid 02 --op debit -d 00000014 -m plain'" "Value.*changed"; then break; fi
|
||||||
|
if ! CheckExecute "card value debit mac" "$PM3BIN -c 'hf mfdes value --aid 123456 --fid 02 --op debit -d 00000014 -m mac'" "Value.*changed"; then break; fi
|
||||||
|
if ! CheckExecute "card value final check" "$PM3BIN -c 'hf mfdes value --aid 123456 --fid 02 --op get -m mac'" "Value.*120"; then break; fi
|
||||||
|
if ! CheckExecute "card cleanup" "$PM3BIN -c 'hf mfdes selectapp --aid 000000; hf mfdes auth -n 0 -t 2tdea -k 00000000000000000000000000000000 --kdf none; hf mfdes deleteapp --aid 123456'" "application.*deleted"; then break; fi
|
||||||
|
echo " card value operation tests completed successfully!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n------------------------------------------------------------"
|
||||||
|
echo -e "Tests [ ${C_GREEN}OK${C_NC} ] ${C_OK}\n"
|
||||||
|
exit 0
|
||||||
|
done
|
||||||
|
echo -e "\n------------------------------------------------------------"
|
||||||
|
echo -e "\nTests [ ${C_RED}FAIL${C_NC} ] ${C_FAIL}\n"
|
||||||
|
exit 1
|
Loading…
Add table
Add a link
Reference in a new issue