Skip to content

Commit

Permalink
Making a sane backup point while prfusely debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
maxieds committed Feb 13, 2022
1 parent a24fbe8 commit bf1eadc
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ void InvalidateAuthState(BYTE keepPICCAuthData) {
Iso7816FileSelected = false;
CryptoAuthMethod = CRYPTO_TYPE_ANY;
ActiveCommMode = DESFIRE_DEFAULT_COMMS_STANDARD;
DesfireCommMode = ActiveCommMode;
}

bool IsAuthenticated(void) {
Expand Down
15 changes: 5 additions & 10 deletions Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,6 @@ uint16_t EV0CmdAuthenticateLegacy1(uint8_t *Buffer, uint16_t ByteCount) {
keySize = GetDefaultCryptoMethodKeySize(CRYPTO_TYPE_2KTDEA);
Key = SessionKey;
DesfireCommandState.KeyId = KeyId;
DesfireCommandState.CryptoMethodType = CRYPTO_TYPE_3K3DES;
DesfireCommandState.ActiveCommMode = GetCryptoMethodCommSettings(CRYPTO_TYPE_3K3DES);

/* Fetch the key */
if (cryptoKeyType == CRYPTO_TYPE_DES) {
Expand Down Expand Up @@ -583,15 +581,10 @@ uint16_t EV0CmdAuthenticateLegacy2(uint8_t *Buffer, uint16_t ByteCount) {

/* Reset parameters for authentication from the first exchange */
KeyId = DesfireCommandState.KeyId;
cryptoKeyType = DesfireCommandState.CryptoMethodType;
keySize = GetDefaultCryptoMethodKeySize(CRYPTO_TYPE_3K3DES);
cryptoKeyType = CRYPTO_TYPE_2KTDEA;
keySize = GetDefaultCryptoMethodKeySize(CRYPTO_TYPE_2KTDEA);
Key = SessionKey;
if (cryptoKeyType == CRYPTO_TYPE_DES) {
ReadAppKey(SelectedApp.Slot, KeyId, Key, CRYPTO_DES_KEY_SIZE);
memcpy(Key + CRYPTO_DES_KEY_SIZE, Key, CRYPTO_DES_KEY_SIZE);
} else {
ReadAppKey(SelectedApp.Slot, KeyId, Key, keySize);
}
ReadAppKey(SelectedApp.Slot, KeyId, Key, keySize);

/* Decrypt the challenge sent back to get RndA and a shifted RndB */
BYTE challengeRndAB[2 * CRYPTO_CHALLENGE_RESPONSE_BYTES];
Expand Down Expand Up @@ -624,6 +617,8 @@ uint16_t EV0CmdAuthenticateLegacy2(uint8_t *Buffer, uint16_t ByteCount) {
AuthenticatedWithKey = KeyId;
AuthenticatedWithPICCMasterKey = (SelectedApp.Slot == DESFIRE_PICC_APP_SLOT) &&
(KeyId == DESFIRE_MASTER_KEY_ID);
DesfireCommandState.CryptoMethodType = CRYPTO_TYPE_2KTDEA;
DesfireCommandState.ActiveCommMode = GetCryptoMethodCommSettings(CRYPTO_TYPE_2KTDEA);

/* Return the status on success */
Buffer[0] = STATUS_OPERATION_OK;
Expand Down
20 changes: 10 additions & 10 deletions Firmware/Chameleon-Mini/Application/DESFire/DESFireUtils.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ This notice must be retained at the top of all source files where indicated.

#include "DESFireUtils.h"
#include "DESFirePICCControl.h"
#include "DESFireLogging.h"

void RotateArrayRight(BYTE *srcBuf, BYTE *destBuf, SIZET bufSize) {
destBuf[bufSize - 1] = srcBuf[0];
Expand Down Expand Up @@ -147,10 +148,8 @@ bool DesfireCheckParityBits(uint8_t *Buffer, uint16_t BitCount) {
}

uint16_t DesfirePreprocessAPDU(uint8_t CommMode, uint8_t *Buffer, uint16_t BufferSize) {
DEBUG_PRINT_P(PSTR("PRE -- CommMode -- 0x%02x"), CommMode);
switch (CommMode) {
case DESFIRE_COMMS_PLAINTEXT:
// Remove the CRCA bytes at the end of the buffer:
return MAX(0, BufferSize - 2);
case DESFIRE_COMMS_PLAINTEXT_MAC: {
uint16_t ChecksumBytes = 0;
if (DesfireCommandState.CryptoMethodType == CRYPTO_TYPE_DES || DesfireCommandState.CryptoMethodType == CRYPTO_TYPE_2KTDEA) {
Expand Down Expand Up @@ -189,17 +188,16 @@ uint16_t DesfirePreprocessAPDU(uint8_t CommMode, uint8_t *Buffer, uint16_t Buffe
}
return MAX(0, BufferSize - ChecksumBytes);
}
case DESFIRE_COMMS_PLAINTEXT:
default:
break;
// Leave the CRCA bytes intact:
return BufferSize;
}
return 0;
}

uint16_t DesfirePostprocessAPDU(uint8_t CommMode, uint8_t *Buffer, uint16_t BufferSize) {
DEBUG_PRINT_P(PSTR("POST -- CommMode -- 0x%02x"), CommMode);
switch (CommMode) {
case DESFIRE_COMMS_PLAINTEXT:
ISO14443AAppendCRCA(Buffer, BufferSize);
return BufferSize + 2;
case DESFIRE_COMMS_PLAINTEXT_MAC: {
if (DesfireCommandState.CryptoMethodType == CRYPTO_TYPE_DES || DesfireCommandState.CryptoMethodType == CRYPTO_TYPE_2KTDEA) {
return appendBufferMAC(SessionKey, Buffer, BufferSize);
Expand Down Expand Up @@ -238,10 +236,12 @@ uint16_t DesfirePostprocessAPDU(uint8_t CommMode, uint8_t *Buffer, uint16_t Buff
memmove(&Buffer[0], &Buffer[XferBytes], XferBytes);
return XferBytes;
}
case DESFIRE_COMMS_PLAINTEXT:
default:
break;
//ISO14443AAppendCRCA(Buffer, BufferSize);
//return BufferSize + 2;
return BufferSize;
}
return 0;
}

#endif /* CONFIG_MF_DESFIRE_SUPPORT */
48 changes: 19 additions & 29 deletions Firmware/Chameleon-Mini/Application/MifareDESFire.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,25 +174,22 @@ uint16_t MifareDesfireProcessCommand(uint8_t *Buffer, uint16_t ByteCount) {
uint16_t MifareDesfireProcess(uint8_t *Buffer, uint16_t BitCount) {
size_t ByteCount = (BitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
DesfireCmdCLA = Buffer[0];
LogEntry(LOG_INFO_DESFIRE_INCOMING_DATA, Buffer, ByteCount);
if (BitCount == 0) {
return ISO14443A_APP_NO_RESPONSE;
} else if ((ByteCount >= 8 && DesfireCLA(Buffer[0]) && Buffer[2] == 0x00 &&
} else if ((ByteCount >= 6 && DesfireCLA(Buffer[0]) && Buffer[2] == 0x00 &&
Buffer[3] == 0x00 && (Buffer[4] == ByteCount - 6 || Buffer[4] == ByteCount - 8)) || Iso7816CLA(DesfireCmdCLA)) {
// Wrapped native command structure:
/* Unwrap the PDU from ISO 7816-4 */
// Check CRC bytes appended to the buffer:
// -- Actually, just ignore parity problems if they exist,
/* Wrapped native command structure or ISO7816: */
if (Iso7816CLA(DesfireCmdCLA)) {
uint16_t iso7816ParamsStatus = SetIso7816WrappedParametersType(Buffer, ByteCount);
if (iso7816ParamsStatus != ISO7816_CMD_NO_ERROR) {
Buffer[0] = (uint8_t)((iso7816ParamsStatus >> 8) & 0x00ff);
Buffer[1] = (uint8_t)(iso7816ParamsStatus & 0x00ff);
ISO14443AAppendCRCA(Buffer, 2);
ByteCount = 2 + 2;
return ByteCount * BITS_PER_BYTE;
ByteCount = 2;
return ByteCount * BITS_PER_BYTE;
}
}
ByteCount = Buffer[4]; // also removing the trailing two parity bytes
ByteCount = Buffer[4];
Buffer[0] = Buffer[1];
memmove(&Buffer[1], &Buffer[5], ByteCount);
/* Process the command */
Expand All @@ -206,7 +203,7 @@ uint16_t MifareDesfireProcess(uint8_t *Buffer, uint16_t BitCount) {
} else {
/* Re-wrap into ISO 7816-4 */
}
//LogEntry(LOG_INFO_DESFIRE_OUTGOING_DATA, Buffer, ByteCount);
LogEntry(LOG_INFO_DESFIRE_OUTGOING_DATA, Buffer, ByteCount);
return ByteCount * BITS_PER_BYTE;
} else {
/* ISO/IEC 14443-4 PDUs: No extra work */
Expand All @@ -218,43 +215,36 @@ uint16_t MifareDesfireProcess(uint8_t *Buffer, uint16_t BitCount) {
uint16_t MifareDesfireAppProcess(uint8_t *Buffer, uint16_t BitCount) {
uint16_t ByteCount = (BitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
uint16_t ReturnedBytes = 0;
/* Is this first case really just a padded ISO7816 APDU with 2-byte prologue ??? */
//if (ByteCount >= 8 && DesfireCLA(Buffer[0]) && Buffer[2] == 0x00 &&
// Buffer[3] == 0x00 && Buffer[4] == ByteCount - 8) {
// return MifareDesfireProcess(Buffer, BitCount);
//}
if (ByteCount >= 6 && DesfireCLA(Buffer[0]) && Buffer[2] == 0x00 &&
Buffer[3] == 0x00 && Buffer[4] == ByteCount - 6) {
Buffer[3] == 0x00 && (Buffer[4] == ByteCount - 6 || Buffer[4] == ByteCount - 8)) {
uint16_t IncomingByteCount = (BitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
uint16_t UnwrappedBitCount = DesfirePreprocessAPDU(DesfireCommMode, Buffer, IncomingByteCount) * BITS_PER_BYTE;
uint16_t UnwrappedBitCount = DesfirePreprocessAPDU(ActiveCommMode, Buffer, IncomingByteCount) * BITS_PER_BYTE;
uint16_t ProcessedBitCount = MifareDesfireProcess(Buffer, UnwrappedBitCount);
uint16_t ProcessedByteCount = (ProcessedBitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
ProcessedBitCount = DesfirePostprocessAPDU(DesfireCommMode, Buffer, ProcessedByteCount) * BITS_PER_BYTE;
ProcessedBitCount = DesfirePostprocessAPDU(ActiveCommMode, Buffer, ProcessedByteCount) * BITS_PER_BYTE;
return ProcessedBitCount;
} else if (ByteCount == 4 && Buffer[2] == 0x37 && Buffer[3] == 0xC8) {
} else if (BitCount == 4 && (Buffer[0] & 0xF0) == 0xA0) {
// NXP-based PCD sent a "keep alive" response of ACK,
// so we respond with a corresponding NAK (with CRCA bytes appended):
Buffer[2] = 0x7E;
Buffer[3] = 0x44;
ISO14443AAppendCRCA(Buffer, 4);
return 6 * BITS_PER_BYTE;
Buffer[0] = 0x00;
return 4;
} else if (IsWrappedISO7816CommandType(Buffer, ByteCount)) {
uint8_t ISO7816PrologueBytes[2];
memcpy(&ISO7816PrologueBytes[0], Buffer, 2);
memmove(&Buffer[0], &Buffer[2], ByteCount - 2);
uint16_t IncomingByteCount = (BitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
uint16_t UnwrappedBitCount = DesfirePreprocessAPDU(DesfireCommMode, Buffer, IncomingByteCount) * BITS_PER_BYTE;
uint16_t ProcessedBitCount = MifareDesfireProcess(Buffer, UnwrappedBitCount);
uint16_t IncomingByteCount = DesfirePreprocessAPDU(ActiveCommMode, Buffer, IncomingByteCount);
memmove(&Buffer[0], &Buffer[2], IncomingByteCount - 2);
uint16_t UnwrappedBitCount = (IncomingByteCount - 2) * BITS_PER_BYTE;
uint16_t ProcessedBitCount = MifareDesfireProcess(Buffer, UnwrappedBitCount);
uint16_t ProcessedByteCount = (ProcessedBitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
/* Append the same ISO7816 prologue bytes to the response: */
memmove(&Buffer[2], &Buffer[0], ProcessedByteCount);
memcpy(&Buffer[0], &ISO7816PrologueBytes[0], 2);
ProcessedBitCount = DesfirePostprocessAPDU(DesfireCommMode, Buffer, ProcessedByteCount) * BITS_PER_BYTE;
ProcessedBitCount = DesfirePostprocessAPDU(ActiveCommMode, Buffer, ProcessedByteCount + 2) * BITS_PER_BYTE;
return ProcessedBitCount;
} else if ((ReturnedBytes = CallInstructionHandler(Buffer, ByteCount)) != ISO14443A_APP_NO_RESPONSE) {
/* This case should handle non-wrappped native commands. No pre/postprocessing afterwards: */
return ReturnedBytes;
} else if (!AnticolNoResp) {
} else { // if (!AnticolNoResp) {
/* This case is to exchange anticollision loop and RATS data. No need to pre/postprocess it depending
* on the CommMode, which has not been set yet if we reach this point:
*/
Expand Down
22 changes: 11 additions & 11 deletions Software/DESFireLibNFCTesting/Libs/ArduinoCryptoLib/aes/aes128.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
/*
The DESFire stack portion of this firmware source
is free software written by Maxie Dion Schmidt (@maxieds):
The DESFire stack portion of this firmware source
is free software written by Maxie Dion Schmidt (@maxieds):
You can redistribute it and/or modify
it under the terms of this license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The complete source distribution of
The complete source distribution of
this firmware is available at the following link:
https://github.com/maxieds/ChameleonMiniFirmwareDESFireStack.
Based in part on the original DESFire code created by
@dev-zzo (GitHub handle) [Dmitry Janushkevich] available at
Based in part on the original DESFire code created by
@dev-zzo (GitHub handle) [Dmitry Janushkevich] available at
https://github.com/dev-zzo/ChameleonMini/tree/desfire.
This notice must be retained at the top of all source files where indicated.
This notice must be retained at the top of all source files where indicated.
*/

/*
Expand All @@ -26,23 +26,23 @@ This notice must be retained at the top of all source files where indicated.
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

/* aes128.h : Standalone C library adapted from the ArduinoCryptoLib source to
* implement AES128 encryption with a small foorprint.
/* aes128.h : Standalone C library adapted from the ArduinoCryptoLib source to
* implement AES128 encryption with a small foorprint.
*/

#ifndef __AES128_CRYPTO_H__
Expand Down

0 comments on commit bf1eadc

Please sign in to comment.