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) { if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) {
mifare_kdf_an10922(key, dctx->kdfInput, dctx->kdfInputLen); MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen);
PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); 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) { } else if (dctx->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) {
// We will overrite any provided KDF input since a gallagher specific KDF was requested. // We will overrite any provided KDF input since a gallagher specific KDF was requested.
dctx->kdfInputLen = 11; dctx->kdfInputLen = 11;
@ -995,10 +995,9 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec
PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input"); PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input");
}*/ }*/
mifare_kdf_an10922(key, dctx->kdfInput, dctx->kdfInputLen); MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen);
PrintAndLogEx(DEBUG, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType)));
PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen));
} }
uint8_t subcommand = MFDES_AUTHENTICATE; 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->keyNum = keyNum;
ctx->keyType = keyType; ctx->keyType = keyType;
memcpy(ctx->key, key, desfire_get_key_length(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) { void DesfireSetCommandSet(DesfireContext *ctx, DesfireCommandSet cmdSet) {
@ -156,6 +157,8 @@ uint8_t *DesfireGetKey(DesfireContext *ctx, DesfireCryptoOpKeyType key_type) {
return ctx->sessionKeyMAC; return ctx->sessionKeyMAC;
} else if (key_type == DCOSessionKeyEnc) { } else if (key_type == DCOSessionKeyEnc) {
return ctx->sessionKeyEnc; return ctx->sessionKeyEnc;
} else if (key_type == DCOMasterKey) {
return ctx->masterKey;
} }
return ctx->key; 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); int kbs = desfire_get_key_block_length(ctx->keyType);
if (kbs == 0) if (kbs == 0)
return; 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 sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
uint8_t sk2[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); 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); 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) if (cmac != NULL)
memcpy(cmac, ctx->IV, kbs); memcpy(cmac, ctx->IV, kbs);
} }
void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t *cmac) { 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. // 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 int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16
if (ctx == NULL || kbs == 0 || data == NULL || len < 1 || len > 31) { if (ctx == NULL || kbs == 0 || data == NULL || len < 1 || len > 31) {
return; return;
@ -355,20 +358,20 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) {
buffer[0] = 0x01; buffer[0] = 0x01;
memcpy(&buffer[1], data, len++); 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); memcpy(ctx->key, cmac, kbs);
} else if (ctx->keyType == T_3DES) { } else if (ctx->keyType == T_3DES) {
buffer[0] = 0x21; buffer[0] = 0x21;
memcpy(&buffer[1], data, len); memcpy(&buffer[1], data, len);
DesfireClearIV(ctx); DesfireClearIV(ctx);
DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, cmac); DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac);
buffer[0] = 0x22; buffer[0] = 0x22;
memcpy(&buffer[1], data, len); memcpy(&buffer[1], data, len);
DesfireClearIV(ctx); 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); memcpy(ctx->key, cmac, kbs * 2);
} else if (ctx->keyType == T_3K3DES) { } 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); memcpy(&buffer[1], data, len);
DesfireClearIV(ctx); DesfireClearIV(ctx);
DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, cmac); DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac);
buffer[0] = 0x32; buffer[0] = 0x32;
memcpy(&buffer[1], data, len); memcpy(&buffer[1], data, len);
DesfireClearIV(ctx); 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; buffer[0] = 0x33;
memcpy(&buffer[1], data, len); memcpy(&buffer[1], data, len);
DesfireClearIV(ctx); 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); memcpy(ctx->key, cmac, kbs * 3);
} }

View file

@ -65,6 +65,7 @@ typedef enum {
} DesfireCommunicationMode; } DesfireCommunicationMode;
typedef enum { typedef enum {
DCOMasterKey,
DCOMainKey, DCOMainKey,
DCOSessionKeyMac, DCOSessionKeyMac,
DCOSessionKeyEnc DCOSessionKeyEnc
@ -74,6 +75,7 @@ typedef struct DesfireContextS {
uint8_t keyNum; uint8_t keyNum;
DesfireCryptoAlgorythm keyType; // des/2tdea/3tdea/aes DesfireCryptoAlgorythm keyType; // des/2tdea/3tdea/aes
uint8_t key[DESFIRE_MAX_KEY_SIZE]; uint8_t key[DESFIRE_MAX_KEY_SIZE];
uint8_t masterKey[DESFIRE_MAX_KEY_SIZE]; // source for kdf
// KDF finction // KDF finction
uint8_t kdfAlgo; 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 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 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 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 DesfireCryptoCMACEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac);
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);
void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version); void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version);
uint8_t DesfireDESKeyGetVersion(uint8_t *key); uint8_t DesfireDESKeyGetVersion(uint8_t *key);

View file

@ -138,10 +138,9 @@ static bool TestAn10922KDFAES(void) {
DesfireContext dctx; DesfireContext dctx;
DesfireSetKey(&dctx, 0, T_AES, key); 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}; 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}; 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); res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
@ -161,10 +160,9 @@ static bool TestAn10922KDF2TDEA(void) {
DesfireContext dctx; DesfireContext dctx;
DesfireSetKey(&dctx, 0, T_3DES, key); 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}; 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}; 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); res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
@ -184,10 +182,9 @@ static bool TestAn10922KDF3TDEA(void) {
DesfireContext dctx; DesfireContext dctx;
DesfireSetKey(&dctx, 0, T_3K3DES, key); 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}; 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, 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}; 0x55, 0xB8, 0xE0, 0x7F, 0xCD, 0xBF, 0x10, 0xEC};