mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-24 15:15:39 -07:00
add masterkey for kdf
This commit is contained in:
parent
455b9a4e38
commit
0ef41b7b78
4 changed files with 26 additions and 25 deletions
|
@ -985,8 +985,8 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec
|
|||
}
|
||||
|
||||
if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) {
|
||||
mifare_kdf_an10922(key, dctx->kdfInput, dctx->kdfInputLen);
|
||||
PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key)));
|
||||
MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen);
|
||||
PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType)));
|
||||
} else if (dctx->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) {
|
||||
// We will overrite any provided KDF input since a gallagher specific KDF was requested.
|
||||
dctx->kdfInputLen = 11;
|
||||
|
@ -995,10 +995,9 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec
|
|||
PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input");
|
||||
}*/
|
||||
|
||||
mifare_kdf_an10922(key, dctx->kdfInput, dctx->kdfInputLen);
|
||||
PrintAndLogEx(DEBUG, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen));
|
||||
PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key)));
|
||||
|
||||
MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen);
|
||||
PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType)));
|
||||
PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen));
|
||||
}
|
||||
|
||||
uint8_t subcommand = MFDES_AUTHENTICATE;
|
||||
|
|
|
@ -74,6 +74,7 @@ void DesfireSetKey(DesfireContext *ctx, uint8_t keyNum, enum DESFIRE_CRYPTOALGO
|
|||
ctx->keyNum = keyNum;
|
||||
ctx->keyType = keyType;
|
||||
memcpy(ctx->key, key, desfire_get_key_length(keyType));
|
||||
memcpy(ctx->masterKey, key, desfire_get_key_length(keyType));
|
||||
}
|
||||
|
||||
void DesfireSetCommandSet(DesfireContext *ctx, DesfireCommandSet cmdSet) {
|
||||
|
@ -156,6 +157,8 @@ uint8_t *DesfireGetKey(DesfireContext *ctx, DesfireCryptoOpKeyType key_type) {
|
|||
return ctx->sessionKeyMAC;
|
||||
} else if (key_type == DCOSessionKeyEnc) {
|
||||
return ctx->sessionKeyEnc;
|
||||
} else if (key_type == DCOMasterKey) {
|
||||
return ctx->masterKey;
|
||||
}
|
||||
|
||||
return ctx->key;
|
||||
|
@ -303,7 +306,7 @@ void DesfireCMACGenerateSubkeys(DesfireContext *ctx, DesfireCryptoOpKeyType key_
|
|||
}
|
||||
}
|
||||
|
||||
void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac) {
|
||||
void DesfireCryptoCMACEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac) {
|
||||
int kbs = desfire_get_key_block_length(ctx->keyType);
|
||||
if (kbs == 0)
|
||||
return;
|
||||
|
@ -313,7 +316,7 @@ void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t
|
|||
|
||||
uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||
uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||
DesfireCMACGenerateSubkeys(ctx, DCOSessionKeyMac, sk1, sk2);
|
||||
DesfireCMACGenerateSubkeys(ctx, key_type, sk1, sk2);
|
||||
|
||||
memcpy(buffer, data, len);
|
||||
|
||||
|
@ -327,18 +330,18 @@ void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t
|
|||
bin_xor(buffer + len - kbs, sk1, kbs);
|
||||
}
|
||||
|
||||
DesfireCryptoEncDec(ctx, DCOSessionKeyMac, buffer, len, NULL, true);
|
||||
DesfireCryptoEncDec(ctx, key_type, buffer, len, NULL, true);
|
||||
|
||||
if (cmac != NULL)
|
||||
memcpy(cmac, ctx->IV, kbs);
|
||||
}
|
||||
|
||||
void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t *cmac) {
|
||||
DesfireCryptoCMACEx(ctx, data, len, 0, cmac);
|
||||
DesfireCryptoCMACEx(ctx, DCOSessionKeyMac, data, len, 0, cmac);
|
||||
}
|
||||
|
||||
// This function is almot like cmac(...). but with some key differences.
|
||||
void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) {
|
||||
void MifareKdfAn10922(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, const uint8_t *data, size_t len) {
|
||||
int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16
|
||||
if (ctx == NULL || kbs == 0 || data == NULL || len < 1 || len > 31) {
|
||||
return;
|
||||
|
@ -355,20 +358,20 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) {
|
|||
buffer[0] = 0x01;
|
||||
memcpy(&buffer[1], data, len++);
|
||||
|
||||
DesfireCryptoCMACEx(ctx, buffer, len, kbs * 2, cmac);
|
||||
DesfireCryptoCMACEx(ctx, key_type, buffer, len, kbs * 2, cmac);
|
||||
memcpy(ctx->key, cmac, kbs);
|
||||
} else if (ctx->keyType == T_3DES) {
|
||||
buffer[0] = 0x21;
|
||||
memcpy(&buffer[1], data, len);
|
||||
|
||||
DesfireClearIV(ctx);
|
||||
DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, cmac);
|
||||
DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac);
|
||||
|
||||
buffer[0] = 0x22;
|
||||
memcpy(&buffer[1], data, len);
|
||||
|
||||
DesfireClearIV(ctx);
|
||||
DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs]);
|
||||
DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs]);
|
||||
|
||||
memcpy(ctx->key, cmac, kbs * 2);
|
||||
} else if (ctx->keyType == T_3K3DES) {
|
||||
|
@ -376,19 +379,19 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) {
|
|||
memcpy(&buffer[1], data, len);
|
||||
|
||||
DesfireClearIV(ctx);
|
||||
DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, cmac);
|
||||
DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac);
|
||||
|
||||
buffer[0] = 0x32;
|
||||
memcpy(&buffer[1], data, len);
|
||||
|
||||
DesfireClearIV(ctx);
|
||||
DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs]);
|
||||
DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs]);
|
||||
|
||||
buffer[0] = 0x33;
|
||||
memcpy(&buffer[1], data, len);
|
||||
|
||||
DesfireClearIV(ctx);
|
||||
DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs * 2]);
|
||||
DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs * 2]);
|
||||
|
||||
memcpy(ctx->key, cmac, kbs * 3);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ typedef enum {
|
|||
} DesfireCommunicationMode;
|
||||
|
||||
typedef enum {
|
||||
DCOMasterKey,
|
||||
DCOMainKey,
|
||||
DCOSessionKeyMac,
|
||||
DCOSessionKeyEnc
|
||||
|
@ -74,6 +75,7 @@ typedef struct DesfireContextS {
|
|||
uint8_t keyNum;
|
||||
DesfireCryptoAlgorythm keyType; // des/2tdea/3tdea/aes
|
||||
uint8_t key[DESFIRE_MAX_KEY_SIZE];
|
||||
uint8_t masterKey[DESFIRE_MAX_KEY_SIZE]; // source for kdf
|
||||
|
||||
// KDF finction
|
||||
uint8_t kdfAlgo;
|
||||
|
@ -113,8 +115,8 @@ void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, u
|
|||
void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv);
|
||||
void DesfireCMACGenerateSubkeys(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *sk1, uint8_t *sk2);
|
||||
void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac);
|
||||
void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac);
|
||||
void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len);
|
||||
void DesfireCryptoCMACEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac);
|
||||
void MifareKdfAn10922(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, const uint8_t *data, size_t len);
|
||||
|
||||
void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version);
|
||||
uint8_t DesfireDESKeyGetVersion(uint8_t *key);
|
||||
|
|
|
@ -138,10 +138,9 @@ static bool TestAn10922KDFAES(void) {
|
|||
|
||||
DesfireContext dctx;
|
||||
DesfireSetKey(&dctx, 0, T_AES, key);
|
||||
memcpy(dctx.sessionKeyMAC, key, sizeof(key));
|
||||
|
||||
uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50, 0x20, 0x41, 0x62, 0x75};
|
||||
MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput));
|
||||
MifareKdfAn10922(&dctx, DCOMainKey, kdfInput, sizeof(kdfInput));
|
||||
|
||||
uint8_t dkey[] = {0xA8, 0xDD, 0x63, 0xA3, 0xB8, 0x9D, 0x54, 0xB3, 0x7C, 0xA8, 0x02, 0x47, 0x3F, 0xDA, 0x91, 0x75};
|
||||
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
||||
|
@ -161,10 +160,9 @@ static bool TestAn10922KDF2TDEA(void) {
|
|||
|
||||
DesfireContext dctx;
|
||||
DesfireSetKey(&dctx, 0, T_3DES, key);
|
||||
memcpy(dctx.sessionKeyMAC, key, sizeof(key));
|
||||
|
||||
uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50, 0x20, 0x41};
|
||||
MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput));
|
||||
MifareKdfAn10922(&dctx, DCOMainKey, kdfInput, sizeof(kdfInput));
|
||||
|
||||
uint8_t dkey[] = {0x16, 0xF8, 0x59, 0x7C, 0x9E, 0x89, 0x10, 0xC8, 0x6B, 0x96, 0x48, 0xD0, 0x06, 0x10, 0x7D, 0xD7};
|
||||
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
||||
|
@ -184,10 +182,9 @@ static bool TestAn10922KDF3TDEA(void) {
|
|||
|
||||
DesfireContext dctx;
|
||||
DesfireSetKey(&dctx, 0, T_3K3DES, key);
|
||||
memcpy(dctx.sessionKeyMAC, key, sizeof(key));
|
||||
|
||||
uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50};
|
||||
MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput));
|
||||
MifareKdfAn10922(&dctx, DCOMainKey, kdfInput, sizeof(kdfInput));
|
||||
|
||||
uint8_t dkey[] = {0x2F, 0x0D, 0xD0, 0x36, 0x75, 0xD3, 0xFB, 0x9A, 0x57, 0x05, 0xAB, 0x0B, 0xDA, 0x91, 0xCA, 0x0B,
|
||||
0x55, 0xB8, 0xE0, 0x7F, 0xCD, 0xBF, 0x10, 0xEC};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue