From 19e0d1cda43c8da7e6274ecd3dcae47cbfee31ba Mon Sep 17 00:00:00 2001 From: Maxie Dion Schmidt Date: Wed, 30 Mar 2022 12:46:06 -0400 Subject: [PATCH] Stashing LibNFC external USB reader test code online to test on Linux (builds on MacOS) --- .../Chameleon-Mini/Application/CryptoAES128.h | 2 +- .../Application/DESFire/DESFireInstructions.c | 7 +- .../LocalInclude/Config.h | 10 +- .../LocalInclude/CryptoUtils.h | 169 ++++++++++++++---- .../LocalInclude/DesfireUtils.h | 12 +- .../LocalInclude/ErrorHandling.h | 8 +- Software/DESFireLibNFCTesting/Makefile | 18 +- 7 files changed, 169 insertions(+), 57 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/CryptoAES128.h b/Firmware/Chameleon-Mini/Application/CryptoAES128.h index 20ccca8c..3d2bc27f 100644 --- a/Firmware/Chameleon-Mini/Application/CryptoAES128.h +++ b/Firmware/Chameleon-Mini/Application/CryptoAES128.h @@ -65,7 +65,7 @@ #define CRYPTO_AES_KEY_SIZE 16 typedef uint8_t CryptoAESKey_t[CRYPTO_AES_KEY_SIZE]; -#define CRYPTO_AES_BLOCK_SIZE 16 +#define CRYPTO_AES_BLOCK_SIZE 16 typedef uint8_t CryptoAESBlock_t[CRYPTO_AES_BLOCK_SIZE]; #define CryptoAESBytesToBlocks(byteCount) \ diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c b/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c index cd746565..6745ace7 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c @@ -551,8 +551,8 @@ uint16_t EV0CmdAuthenticateLegacy2(uint8_t *Buffer, uint16_t ByteCount) { BYTE challengeRndB[CRYPTO_CHALLENGE_RESPONSE_BYTES]; Decrypt2K3DESBuffer(2 * CRYPTO_CHALLENGE_RESPONSE_BYTES, challengeRndAB, &Buffer[1], NULL, Key); - RotateArrayRight(challengeRndAB + CRYPTO_CHALLENGE_RESPONSE_BYTES, challengeRndB, - CRYPTO_CHALLENGE_RESPONSE_BYTES); + RotateArrayLeft(challengeRndAB + CRYPTO_CHALLENGE_RESPONSE_BYTES, challengeRndB, + CRYPTO_CHALLENGE_RESPONSE_BYTES); memcpy(challengeRndA, challengeRndAB, CRYPTO_CHALLENGE_RESPONSE_BYTES); /* Check that the returned RndB matches what we sent in the previous round */ @@ -562,7 +562,7 @@ uint16_t EV0CmdAuthenticateLegacy2(uint8_t *Buffer, uint16_t ByteCount) { } /* Encrypt and send back the once rotated RndA buffer to the PCD */ - RotateArrayLeft(challengeRndA, challengeRndAB, CRYPTO_CHALLENGE_RESPONSE_BYTES); + RotateArrayRight(challengeRndA, challengeRndAB, CRYPTO_CHALLENGE_RESPONSE_BYTES); Encrypt2K3DESBuffer(CRYPTO_CHALLENGE_RESPONSE_BYTES, challengeRndAB, &Buffer[1], NULL, Key); @@ -845,7 +845,6 @@ uint16_t EV0CmdDeleteApplication(uint8_t *Buffer, uint16_t ByteCount) { } PiccKeySettings = GetPiccKeySettings(); const char *logMsg = PSTR("PICC key settings -- %02x"); - DEBUG_PRINT_P(logMsg, PiccKeySettings); /* Check the PICC key settings whether it is OK to delete using app master key */ if ((PiccKeySettings & DESFIRE_FREE_CREATE_DELETE) == 0x00) { Status = STATUS_AUTHENTICATION_ERROR; diff --git a/Software/DESFireLibNFCTesting/LocalInclude/Config.h b/Software/DESFireLibNFCTesting/LocalInclude/Config.h index b25ad036..0a313221 100644 --- a/Software/DESFireLibNFCTesting/LocalInclude/Config.h +++ b/Software/DESFireLibNFCTesting/LocalInclude/Config.h @@ -6,17 +6,17 @@ #define MAX_FRAME_LENGTH (264) #define APPLICATION_AID_LENGTH (3) -static const inline uint8_t MASTER_APPLICATION_AID[] = { +static const uint8_t MASTER_APPLICATION_AID[] = { 0x00, 0x00, 0x00 }; -static const inline uint8_t MASTER_KEY_INDEX = 0x00; +static const uint8_t MASTER_KEY_INDEX = 0x00; -static inline uint8_t CRYPTO_RNDB_STATE[] = { +static uint8_t CRYPTO_RNDB_STATE[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static inline bool AUTHENTICATED = false; -static inline int AUTHENTICATED_PROTO = 0; +static bool AUTHENTICATED = false; +static int AUTHENTICATED_PROTO = 0; #endif diff --git a/Software/DESFireLibNFCTesting/LocalInclude/CryptoUtils.h b/Software/DESFireLibNFCTesting/LocalInclude/CryptoUtils.h index c2e3b4a5..a09e8315 100644 --- a/Software/DESFireLibNFCTesting/LocalInclude/CryptoUtils.h +++ b/Software/DESFireLibNFCTesting/LocalInclude/CryptoUtils.h @@ -13,6 +13,14 @@ #include "LibNFCUtils.h" +/* DES Operation cipher mode */ +#define CRYPTO_DES_ECB_MODE 0 // Electronic Code Book mode +#define CRYPTO_DES_CBC_MODE 1 // Cipher Block Chaining mode + +/* AES Operation cipher mode */ +#define CRYPTO_AES_ECB_MODE 0 // Electronic Code Book mode +#define CRYPTO_AES_CBC_MODE 1 // Cipher Block Chaining mode + #define DESFIRE_CRYPTO_AUTHTYPE_AES128 (1) #define DESFIRE_CRYPTO_AUTHTYPE_ISODES (2) #define DESFIRE_CRYPTO_AUTHTYPE_LEGACY (3) @@ -23,24 +31,32 @@ #define CRYPTO_DES_BLOCK_SIZE (8) #define CRYPTO_3KTDEA_BLOCK_SIZE (CRYPTO_DES_BLOCK_SIZE) #define AES128_BLOCK_SIZE (16) +#define CRYPTO_MAX_BLOCK_SIZE (16) + +typedef uint8_t CryptoAESBlock_t[AES128_BLOCK_SIZE]; +static uint8_t SessionIV[CRYPTO_MAX_BLOCK_SIZE]; + +/* Key sizes, block sizes (in bytes): */ +#define CRYPTO_MAX_KEY_SIZE (24) +#define CRYPTO_MAX_BLOCK_SIZE (16) #define CRYPTO_CHALLENGE_RESPONSE_SIZE (16) -static const inline uint8_t ZERO_KEY[] = { +static const uint8_t ZERO_KEY[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const inline uint8_t TEST_KEY1[] = { +static const uint8_t TEST_KEY1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; -static const inline uint8_t TEST_KEY1_INDEX = 0x01; +static const uint8_t TEST_KEY1_INDEX = 0x01; typedef AES128Context DesfireAESCryptoContext; @@ -82,25 +98,34 @@ static inline void PrintAESCryptoContext(DesfireAESCryptoContext *cryptoCtx) { print_hex(cryptoCtx->keyData, 16); } +/* Set the last operation mode (ECB or CBC) init for the context */ +static uint8_t __CryptoAESOpMode = CRYPTO_AES_ECB_MODE; + static inline size_t EncryptAES128(const uint8_t *plainSrcBuf, size_t bufSize, uint8_t *encDestBuf, CryptoData_t cdata) { DesfireAESCryptoContext *cryptoCtx = &(cdata.cryptoCtx); DesfireAESCryptoInit(cdata.keyData, cdata.keySize, cryptoCtx); size_t bufBlocks = bufSize / AES128_BLOCK_SIZE; bool padLastBlock = (bufSize % AES128_BLOCK_SIZE) != 0; - uint8_t IV[AES128_BLOCK_SIZE]; + uint8_t *IV = SessionIV; + uint8_t inputBlock[AES128_BLOCK_SIZE]; memset(IV, 0x00, AES128_BLOCK_SIZE); for (int blk = 0; blk < bufBlocks; blk++) { - uint8_t inputBlock[AES128_BLOCK_SIZE]; - if (blk == 0) { - memcpy(inputBlock, &plainSrcBuf[0], AES128_BLOCK_SIZE); + if (__CryptoAESOpMode == CRYPTO_AES_CBC_MODE) { + if (blk == 0) { + memcpy(inputBlock, &plainSrcBuf[0], AES128_BLOCK_SIZE); + CryptoMemoryXOR(IV, inputBlock, AES128_BLOCK_SIZE); + } else { + memcpy(inputBlock, &encDestBuf[(blk - 1) * AES128_BLOCK_SIZE], AES128_BLOCK_SIZE); + CryptoMemoryXOR(&plainSrcBuf[blk * AES128_BLOCK_SIZE], inputBlock, AES128_BLOCK_SIZE); + } + aes128EncryptBlock(cryptoCtx, encDestBuf + blk * AES128_BLOCK_SIZE, inputBlock); + } else { /* ECB mode */ + memcpy(inputBlock, &plainSrcBuf[blk * AES128_BLOCK_SIZE], AES128_BLOCK_SIZE); CryptoMemoryXOR(IV, inputBlock, AES128_BLOCK_SIZE); - } else { - memcpy(inputBlock, &encDestBuf[(blk - 1) * AES128_BLOCK_SIZE], AES128_BLOCK_SIZE); - CryptoMemoryXOR(&plainSrcBuf[blk * AES128_BLOCK_SIZE], inputBlock, AES128_BLOCK_SIZE); + aes128EncryptBlock(cryptoCtx, encDestBuf + blk * AES128_BLOCK_SIZE, inputBlock); + memcpy(IV, encDestBuf + blk * AES128_BLOCK_SIZE, AES128_BLOCK_SIZE); } - aes128EncryptBlock(cryptoCtx, encDestBuf + blk * AES128_BLOCK_SIZE, - inputBlock); } return bufSize; } @@ -111,27 +136,36 @@ static inline size_t DecryptAES128(const uint8_t *encSrcBuf, size_t bufSize, DesfireAESCryptoInit(cdata.keyData, cdata.keySize, cryptoCtx); size_t bufBlocks = (bufSize + AES128_BLOCK_SIZE - 1) / AES128_BLOCK_SIZE; bool padLastBlock = (bufSize % AES128_BLOCK_SIZE) != 0; - uint8_t IV[AES128_BLOCK_SIZE]; + uint8_t *IV = SessionIV; + uint8_t inputBlock[AES128_BLOCK_SIZE]; memset(IV, 0x00, AES128_BLOCK_SIZE); for (int blk = 0; blk < bufBlocks; blk++) { - uint8_t inputBlock[AES128_BLOCK_SIZE]; - aes128DecryptBlock(cryptoCtx, inputBlock, encSrcBuf + blk * AES128_BLOCK_SIZE); - if (blk == 0) { - memcpy(plainDestBuf + blk * AES128_BLOCK_SIZE, inputBlock, AES128_BLOCK_SIZE); + if (__CryptoAESOpMode == CRYPTO_AES_CBC_MODE) { + aes128DecryptBlock(cryptoCtx, inputBlock, encSrcBuf + blk * AES128_BLOCK_SIZE); + if (blk == 0) { + memcpy(plainDestBuf + blk * AES128_BLOCK_SIZE, inputBlock, AES128_BLOCK_SIZE); + CryptoMemoryXOR(IV, plainDestBuf + blk * AES128_BLOCK_SIZE, AES128_BLOCK_SIZE); + } else { + memcpy(plainDestBuf + blk * AES128_BLOCK_SIZE, inputBlock, AES128_BLOCK_SIZE); + CryptoMemoryXOR(&encSrcBuf[(blk - 1) * AES128_BLOCK_SIZE], + plainDestBuf + blk * AES128_BLOCK_SIZE, AES128_BLOCK_SIZE); + } + } else { /* ECB mode */ + aes128DecryptBlock(cryptoCtx, plainDestBuf + blk * AES128_BLOCK_SIZE, encSrcBuf + blk * AES128_BLOCK_SIZE); CryptoMemoryXOR(IV, plainDestBuf + blk * AES128_BLOCK_SIZE, AES128_BLOCK_SIZE); - } else { - memcpy(plainDestBuf + blk * AES128_BLOCK_SIZE, inputBlock, AES128_BLOCK_SIZE); - CryptoMemoryXOR(&encSrcBuf[(blk - 1) * AES128_BLOCK_SIZE], - plainDestBuf + blk * AES128_BLOCK_SIZE, AES128_BLOCK_SIZE); + memcpy(IV, encSrcBuf + blk * AES128_BLOCK_SIZE, AES128_BLOCK_SIZE); } } return bufSize; } +/* Set the last operation mode (ECB or CBC) init for the context */ +static uint8_t __CryptoDESOpMode = CRYPTO_DES_ECB_MODE; + static inline size_t Encrypt2K3DES(const uint8_t *plainSrcBuf, size_t bufSize, uint8_t *encDestBuf, const uint8_t *IVIn, CryptoData_t cdata) { DES_key_schedule keySched1, keySched2; - uint8_t IV[2 * CRYPTO_DES_BLOCK_SIZE]; + uint8_t *IV = SessionIV; uint8_t *kd1 = cdata.keyData, *kd2 = &(cdata.keyData[CRYPTO_DES_BLOCK_SIZE]); DES_set_key(kd1, &keySched1); DES_set_key(kd2, &keySched2); @@ -140,14 +174,26 @@ static inline size_t Encrypt2K3DES(const uint8_t *plainSrcBuf, size_t bufSize, } else { memcpy(IV, IVIn, 2 * CRYPTO_DES_BLOCK_SIZE); } - DES_ede2_cbc_encrypt(plainSrcBuf, encDestBuf, bufSize, &keySched1, &keySched2, &IV, DES_ENCRYPT); + if (__CryptoDESOpMode == CRYPTO_DES_CBC_MODE) { + DES_ede2_cbc_encrypt(plainSrcBuf, encDestBuf, bufSize, &keySched1, &keySched2, &IV, DES_ENCRYPT); + } else { + uint8_t inputBlock[CRYPTO_DES_BLOCK_SIZE]; + uint16_t numBlocks = bufSize / CRYPTO_DES_BLOCK_SIZE; + for (int blk = 0; blk < numBlocks; blk++) { + memcpy(inputBlock, &plainSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + CryptoMemoryXOR(IV, inputBlock, CRYPTO_DES_BLOCK_SIZE); + DES_ecb2_encrypt(&encDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], + &plainSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], &keySched1, &keySched2, DES_ENCRYPT); + memcpy(IV, &encDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + } + } return bufSize; } static inline size_t Decrypt2K3DES(const uint8_t *encSrcBuf, size_t bufSize, uint8_t *plainDestBuf, const uint8_t *IVIn, CryptoData_t cdata) { DES_key_schedule keySched1, keySched2; - uint8_t IV[2 * CRYPTO_DES_BLOCK_SIZE]; + uint8_t *IV = SessionIV; uint8_t *kd1 = cdata.keyData, *kd2 = &(cdata.keyData[CRYPTO_DES_BLOCK_SIZE]); DES_set_key(kd1, &keySched1); DES_set_key(kd2, &keySched2); @@ -156,14 +202,25 @@ static inline size_t Decrypt2K3DES(const uint8_t *encSrcBuf, size_t bufSize, } else { memcpy(IV, IVIn, 2 * CRYPTO_DES_BLOCK_SIZE); } - DES_ede2_cbc_encrypt(encSrcBuf, plainDestBuf, bufSize, &keySched1, &keySched2, &IV, DES_DECRYPT); + if (__CryptoDESOpMode == CRYPTO_DES_CBC_MODE) { + DES_ede2_cbc_encrypt(encSrcBuf, plainDestBuf, bufSize, &keySched1, &keySched2, &IV, DES_DECRYPT); + } else { + uint8_t inputBlock[CRYPTO_DES_BLOCK_SIZE]; + uint16_t numBlocks = bufSize / CRYPTO_DES_BLOCK_SIZE; + for (int blk = 0; blk < numBlocks; blk++) { + DES_ecb2_encrypt(&encSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], + &plainDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], &keySched1, &keySched2, DES_DECRYPT); + CryptoMemoryXOR(IV, &plainDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + memcpy(IV, &encSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + } + } return bufSize; } static inline size_t Encrypt3DES(const uint8_t *plainSrcBuf, size_t bufSize, uint8_t *encDestBuf, const uint8_t *IVIn, CryptoData_t cdata) { DES_key_schedule keySched1, keySched2, keySched3; - uint8_t IV[CRYPTO_DES_BLOCK_SIZE]; + uint8_t *IV = SessionIV; uint8_t *kd1 = cdata.keyData, *kd2 = &(cdata.keyData[CRYPTO_DES_BLOCK_SIZE]), *kd3 = &(cdata.keyData[2 * CRYPTO_DES_BLOCK_SIZE]); DES_set_key(kd1, &keySched1); DES_set_key(kd2, &keySched2); @@ -173,14 +230,26 @@ static inline size_t Encrypt3DES(const uint8_t *plainSrcBuf, size_t bufSize, } else { memcpy(IV, IVIn, CRYPTO_DES_BLOCK_SIZE); } - DES_ede3_cbc_encrypt(plainSrcBuf, encDestBuf, bufSize, &keySched1, &keySched2, &keySched3, &IV, DES_ENCRYPT); + if (__CryptoDESOpMode == CRYPTO_DES_CBC_MODE) { + DES_ede3_cbc_encrypt(plainSrcBuf, encDestBuf, bufSize, &keySched1, &keySched2, &keySched3, &IV, DES_ENCRYPT); + } else { + uint8_t inputBlock[CRYPTO_DES_BLOCK_SIZE]; + uint16_t numBlocks = bufSize / CRYPTO_DES_BLOCK_SIZE; + for (int blk = 0; blk < numBlocks; blk++) { + memcpy(inputBlock, &plainSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + CryptoMemoryXOR(IV, inputBlock, CRYPTO_DES_BLOCK_SIZE); + DES_ecb3_encrypt(&encDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], + &plainSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], &keySched1, &keySched2, &keySched3, DES_ENCRYPT); + memcpy(IV, &encDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + } + } return bufSize; } static inline size_t Decrypt3DES(const uint8_t *encSrcBuf, size_t bufSize, uint8_t *plainDestBuf, const uint8_t *IVIn, CryptoData_t cdata) { DES_key_schedule keySched1, keySched2, keySched3; - uint8_t IV[CRYPTO_DES_BLOCK_SIZE]; + uint8_t *IV = SessionIV; uint8_t *kd1 = cdata.keyData, *kd2 = &(cdata.keyData[CRYPTO_DES_BLOCK_SIZE]), *kd3 = &(cdata.keyData[2 * CRYPTO_DES_BLOCK_SIZE]); DES_set_key(kd1, &keySched1); DES_set_key(kd2, &keySched2); @@ -190,7 +259,18 @@ static inline size_t Decrypt3DES(const uint8_t *encSrcBuf, size_t bufSize, } else { memcpy(IV, IVIn, CRYPTO_DES_BLOCK_SIZE); } - DES_ede3_cbc_encrypt(encSrcBuf, plainDestBuf, bufSize, &keySched1, &keySched2, &keySched3, &IV, DES_DECRYPT); + if (__CryptoDESOpMode == CRYPTO_DES_CBC_MODE) { + DES_ede3_cbc_encrypt(encSrcBuf, plainDestBuf, bufSize, &keySched1, &keySched2, &keySched3, &IV, DES_DECRYPT); + } else { + uint8_t inputBlock[CRYPTO_DES_BLOCK_SIZE]; + uint16_t numBlocks = bufSize / CRYPTO_DES_BLOCK_SIZE; + for (int blk = 0; blk < numBlocks; blk++) { + DES_ecb3_encrypt(&encSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], + &plainDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], &keySched1, &keySched2, &keySched3, DES_DECRYPT); + CryptoMemoryXOR(IV, &plainDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + memcpy(IV, &encSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + } + } return bufSize; } @@ -200,13 +280,25 @@ static inline size_t EncryptDES(const uint8_t *plainSrcBuf, size_t bufSize, DES_key_schedule keySched; uint8_t *kd = cdata.keyData; DES_set_key(kd, &keySched); - uint8_t IV[CRYPTO_DES_BLOCK_SIZE]; + uint8_t *IV = SessionIV; if (IVIn == NULL) { memset(IV, 0x00, CRYPTO_DES_BLOCK_SIZE); } else { memcpy(IV, IVIn, CRYPTO_DES_BLOCK_SIZE); } - DES_cbc_encrypt(plainSrcBuf, encDestBuf, bufSize, &keySched, &IV, DES_ENCRYPT); + if (__CryptoDESOpMode == CRYPTO_DES_CBC_MODE) { + DES_cbc_encrypt(plainSrcBuf, encDestBuf, bufSize, &keySched, &IV, DES_ENCRYPT); + } else { + uint8_t inputBlock[CRYPTO_DES_BLOCK_SIZE]; + uint16_t numBlocks = bufSize / CRYPTO_DES_BLOCK_SIZE; + for (int blk = 0; blk < numBlocks; blk++) { + memcpy(inputBlock, &plainSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + CryptoMemoryXOR(IV, inputBlock, CRYPTO_DES_BLOCK_SIZE); + DES_ecb_encrypt(&encDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], + &plainSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], &keySched, DES_ENCRYPT); + memcpy(IV, &encDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + } + } return bufSize; } @@ -215,13 +307,24 @@ static inline size_t DecryptDES(const uint8_t *encSrcBuf, size_t bufSize, DES_key_schedule keySched; uint8_t *kd = cdata.keyData; DES_set_key(kd, &keySched); - uint8_t IV[CRYPTO_DES_BLOCK_SIZE]; + uint8_t *IV = SessionIV; if (IVIn == NULL) { memset(IV, 0x00, CRYPTO_DES_BLOCK_SIZE); } else { memcpy(IV, IVIn, CRYPTO_DES_BLOCK_SIZE); } - DES_cbc_encrypt(encSrcBuf, plainDestBuf, bufSize, &keySched, &IV, DES_DECRYPT); + if (__CryptoDESOpMode == CRYPTO_DES_CBC_MODE) { + DES_cbc_encrypt(encSrcBuf, plainDestBuf, bufSize, &keySched, &IV, DES_DECRYPT); + } else { + uint8_t inputBlock[CRYPTO_DES_BLOCK_SIZE]; + uint16_t numBlocks = bufSize / CRYPTO_DES_BLOCK_SIZE; + for (int blk = 0; blk < numBlocks; blk++) { + DES_ecb_encrypt(&encSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], + &plainDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], &keySched, DES_DECRYPT); + CryptoMemoryXOR(IV, &plainDestBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + memcpy(IV, &encSrcBuf[blk * CRYPTO_DES_BLOCK_SIZE], CRYPTO_DES_BLOCK_SIZE); + } + } return bufSize; } diff --git a/Software/DESFireLibNFCTesting/LocalInclude/DesfireUtils.h b/Software/DESFireLibNFCTesting/LocalInclude/DesfireUtils.h index 33b55f37..6a96cc70 100644 --- a/Software/DESFireLibNFCTesting/LocalInclude/DesfireUtils.h +++ b/Software/DESFireLibNFCTesting/LocalInclude/DesfireUtils.h @@ -58,7 +58,7 @@ static inline int AuthenticateAES128(nfc_device *nfcConnDev, uint8_t keyIndex, c aesCryptoData.keyData = keyData; aesCryptoData.ivSize = CRYPTO_CHALLENGE_RESPONSE_SIZE; DecryptAES128(encryptedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE, plainTextRndB, aesCryptoData); - RotateArrayLeft(plainTextRndB, rotatedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE); + RotateArrayRight(plainTextRndB, rotatedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE); memset(IVBuf, 0x00, CRYPTO_CHALLENGE_RESPONSE_SIZE); aesCryptoData.ivData = IVBuf; GenerateRandomBytes(rndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); @@ -99,7 +99,7 @@ static inline int AuthenticateAES128(nfc_device *nfcConnDev, uint8_t keyIndex, c // and report back whether they match: uint8_t decryptedRndAFromPICCRotated[CRYPTO_CHALLENGE_RESPONSE_SIZE], decryptedRndA[CRYPTO_CHALLENGE_RESPONSE_SIZE]; DecryptAES128(rxDataStorage->rxDataBuf, CRYPTO_CHALLENGE_RESPONSE_SIZE, decryptedRndAFromPICCRotated, aesCryptoData); - RotateArrayRight(decryptedRndAFromPICCRotated, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); + RotateArrayLeft(decryptedRndAFromPICCRotated, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); if (!memcmp(rndA, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE)) { if (PRINT_STATUS_EXCHANGE_MESSAGES) { fprintf(stdout, " ... AUTH OK! :)\n\n"); @@ -162,7 +162,7 @@ static inline int AuthenticateISO(nfc_device *nfcConnDev, uint8_t keyIndex, cons desCryptoData.keyData = keyData; desCryptoData.ivSize = CRYPTO_CHALLENGE_RESPONSE_SIZE; Decrypt3DES(encryptedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE, plainTextRndB, NULL, desCryptoData); - RotateArrayLeft(plainTextRndB, rotatedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE); + RotateArrayRight(plainTextRndB, rotatedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE); memset(IVBuf, 0x00, CRYPTO_CHALLENGE_RESPONSE_SIZE); desCryptoData.ivData = IVBuf; GenerateRandomBytes(rndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); @@ -203,7 +203,7 @@ static inline int AuthenticateISO(nfc_device *nfcConnDev, uint8_t keyIndex, cons // and report back whether they match: uint8_t decryptedRndAFromPICCRotated[CRYPTO_CHALLENGE_RESPONSE_SIZE], decryptedRndA[CRYPTO_CHALLENGE_RESPONSE_SIZE]; Decrypt3DES(rxDataStorage->rxDataBuf, CRYPTO_CHALLENGE_RESPONSE_SIZE, decryptedRndAFromPICCRotated, NULL, desCryptoData); - RotateArrayRight(decryptedRndAFromPICCRotated, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); + RotateArrayLeft(decryptedRndAFromPICCRotated, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); if (!memcmp(rndA, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE)) { if (PRINT_STATUS_EXCHANGE_MESSAGES) { fprintf(stdout, " ... AUTH OK! :)\n\n"); @@ -266,7 +266,7 @@ static inline int AuthenticateLegacy(nfc_device *nfcConnDev, uint8_t keyIndex, c desCryptoData.keyData = keyData; desCryptoData.ivSize = CRYPTO_CHALLENGE_RESPONSE_SIZE; Decrypt2K3DES(encryptedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE, plainTextRndB, NULL, desCryptoData); - RotateArrayLeft(plainTextRndB, rotatedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE); + RotateArrayRight(plainTextRndB, rotatedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE); memset(IVBuf, 0x00, CRYPTO_CHALLENGE_RESPONSE_SIZE); desCryptoData.ivData = IVBuf; GenerateRandomBytes(rndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); @@ -307,7 +307,7 @@ static inline int AuthenticateLegacy(nfc_device *nfcConnDev, uint8_t keyIndex, c // and report back whether they match: uint8_t decryptedRndAFromPICCRotated[CRYPTO_CHALLENGE_RESPONSE_SIZE], decryptedRndA[CRYPTO_CHALLENGE_RESPONSE_SIZE]; Decrypt2K3DES(rxDataStorage->rxDataBuf, CRYPTO_CHALLENGE_RESPONSE_SIZE, decryptedRndAFromPICCRotated, NULL, desCryptoData); - RotateArrayRight(decryptedRndAFromPICCRotated, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); + RotateArrayLeft(decryptedRndAFromPICCRotated, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE); if (!memcmp(rndA, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE)) { if (PRINT_STATUS_EXCHANGE_MESSAGES) { fprintf(stdout, " ... AUTH OK! :)\n\n"); diff --git a/Software/DESFireLibNFCTesting/LocalInclude/ErrorHandling.h b/Software/DESFireLibNFCTesting/LocalInclude/ErrorHandling.h index 6723f727..4d068eb6 100644 --- a/Software/DESFireLibNFCTesting/LocalInclude/ErrorHandling.h +++ b/Software/DESFireLibNFCTesting/LocalInclude/ErrorHandling.h @@ -8,7 +8,7 @@ #include #define STRING_BUFFER_SIZE (256) -static inline char __InternalLoggingStringBuffer[STRING_BUFFER_SIZE] = { '\0' }; +static char __InternalLoggingStringBuffer[STRING_BUFFER_SIZE] = { '\0' }; #define GetSourceFileLoggingData(outputDataBuf, maxBufSize) ({ \ char *strBuffer; \ @@ -48,7 +48,7 @@ typedef enum { LAST_ERROR, } ErrorType_t; -static inline const char *LOCAL_ERROR_MSGS[] = { +static const char *LOCAL_ERROR_MSGS[] = { [NO_ERROR] = "No error", [LIBC_ERROR] = "Libc function error", [GENERIC_OTHER_ERROR] = "Unspecified (generic) error", @@ -58,8 +58,8 @@ static inline const char *LOCAL_ERROR_MSGS[] = { [LAST_ERROR] = NULL, }; -static inline bool RUNTIME_QUIET_MODE = false; -static inline bool RUNTIME_VERBOSE_MODE = true; +static bool RUNTIME_QUIET_MODE = false; +static bool RUNTIME_VERBOSE_MODE = true; static bool PRINT_STATUS_EXCHANGE_MESSAGES = true; #define STATUS_OK (0x00) diff --git a/Software/DESFireLibNFCTesting/Makefile b/Software/DESFireLibNFCTesting/Makefile index 99648973..3d0a6128 100644 --- a/Software/DESFireLibNFCTesting/Makefile +++ b/Software/DESFireLibNFCTesting/Makefile @@ -1,18 +1,28 @@ #### Makefile for the libnfc-based tests in C #### These tests are compiled for the local host system, not for AVR platforms -#CC=gcc-10 # for MacOS +#CC=gcc-10 # for MacOS CC=gcc -CFLAGS= -ILocalInclude -ISource \ +CFLAGS_BASE= -ILocalInclude -ISource \ -g -O0 -Wall -pedantic -Wextra -std=c99 -Du_int8_t=uint8_t -Du_int16_t=uint16_t \ `pkg-config libnfc --cflags` -I/usr/local/opt/openssl/include \ -DHOST_BUILD -DCRYPTO_AES_DEFAULT=1 \ -ILibs/ArduinoCryptoLib -#LD=gcc-10 +#LD=gcc-10 # for MacOS LD=gcc -LDFLAGS= $(CFLAGS) -lc `pkg-config libnfc --libs` \ +LDFLAGS_BASE= $(CFLAGS) -lc `pkg-config libnfc --libs` \ -L/usr/local/opt/openssl/lib -lssl -lcrypto +ifeq ("$(shell uname -s)", "Darwin") + CC=/usr/local/opt/llvm/bin/clang-13 + CFLAGS=$(CFLAGS_BASE) -I/usr/local/opt/llvm/include + LD=/usr/local/opt/llvm/bin/clang-13 + LDFLAGS=$(LDFLAGS_BASE) -L/usr/local/opt/llvm/lib +else + CFLAGS=$(CFLAGS_BASE) + LDFLAGS=$(LDFLAGS_BASE) +endif + BINDIR=./Bin BINEXT=exe OBJDIR=./Obj