add masterkey for kdf

This commit is contained in:
merlokk 2021-08-08 19:15:06 +03:00
commit 0ef41b7b78
4 changed files with 26 additions and 25 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -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);

View file

@ -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};