@@ -326,7 +326,7 @@ uint16_t CallInstructionHandler(uint8_t *Buffer, uint16_t ByteCount) {
326
326
while (curInsUpper >= curInsLower ) {
327
327
curInsIndex = curInsLower + (curInsUpper + 1 - curInsLower ) / 2 ;
328
328
dfCmd = DESFireCommandSet [curInsIndex ];
329
- if (dfCmd .insCode == insCode ) {
329
+ if (dfCmd .insCode == insCode ) {
330
330
if (dfCmd .insFunc == NULL ) {
331
331
return CmdNotImplemented (Buffer , ByteCount );
332
332
}
@@ -1713,6 +1713,7 @@ uint16_t DesfireCmdAuthenticate3KTDEA1(uint8_t *Buffer, uint16_t ByteCount) {
1713
1713
1714
1714
BYTE KeyId , Status ;
1715
1715
BYTE keySize ;
1716
+ BYTE CryptoChallengeResponseBytesSize ;
1716
1717
BYTE * Key ;
1717
1718
1718
1719
/* Validate command length */
@@ -1728,10 +1729,10 @@ uint16_t DesfireCmdAuthenticate3KTDEA1(uint8_t *Buffer, uint16_t ByteCount) {
1728
1729
* in the event of an error.
1729
1730
*/
1730
1731
KeyId = Buffer [1 ];
1731
- if (!Authenticated || ! AuthenticatedWithPICCMasterKey ) {
1732
+ if (!AuthenticatedWithPICCMasterKey && KeyId != DESFIRE_MASTER_KEY_ID ) {
1732
1733
Buffer [0 ] = STATUS_PERMISSION_DENIED ;
1733
1734
return DESFIRE_STATUS_RESPONSE_SIZE ;
1734
- } else if (AuthenticatedWithKey != KeyId ) {
1735
+ } else if (( Authenticated || AuthenticatedWithPICCMasterKey ) && AuthenticatedWithKey != KeyId ) {
1735
1736
Buffer [0 ] = STATUS_NO_SUCH_KEY ;
1736
1737
return DESFIRE_STATUS_RESPONSE_SIZE ;
1737
1738
} else {
@@ -1750,21 +1751,28 @@ uint16_t DesfireCmdAuthenticate3KTDEA1(uint8_t *Buffer, uint16_t ByteCount) {
1750
1751
return DESFIRE_STATUS_RESPONSE_SIZE ;
1751
1752
}
1752
1753
1753
- keySize = GetDefaultCryptoMethodKeySize ( CRYPTO_TYPE_3K3DES );
1754
+ /* Update state */
1754
1755
Key = SessionKey ;
1755
-
1756
- /* Indicate that we are in AES key authentication land */
1757
1756
DesfireCommandState .KeyId = KeyId ;
1758
- DesfireCommandState .CryptoMethodType = CRYPTO_TYPE_3K3DES ;
1759
- DesfireCommandState .ActiveCommMode = GetCryptoMethodCommSettings (CRYPTO_TYPE_3K3DES );
1757
+ if (!AuthenticatedWithPICCMasterKey ) {
1758
+ keySize = GetDefaultCryptoMethodKeySize (CRYPTO_TYPE_DES );
1759
+ DesfireCommandState .CryptoMethodType = CRYPTO_TYPE_DES ;
1760
+ DesfireCommandState .ActiveCommMode = GetCryptoMethodCommSettings (CRYPTO_TYPE_DES );
1761
+
1762
+ } else {
1763
+ keySize = GetDefaultCryptoMethodKeySize (CRYPTO_TYPE_3K3DES );
1764
+ DesfireCommandState .CryptoMethodType = CRYPTO_TYPE_3K3DES ;
1765
+ DesfireCommandState .ActiveCommMode = GetCryptoMethodCommSettings (CRYPTO_TYPE_3K3DES );
1766
+ }
1767
+ CryptoChallengeResponseBytesSize = keySize ;
1760
1768
1761
1769
/* Fetch the key */
1762
1770
ReadAppKey (SelectedApp .Slot , KeyId , Key , keySize );
1763
1771
LogEntry (LOG_APP_AUTH_KEY , (const void * ) Key , keySize );
1764
1772
1765
1773
/* Generate the nonce B (RndB / Challenge response) */
1766
1774
if (LocalTestingMode == 0 ) {
1767
- RandomGetBuffer (DesfireCommandState .RndB , CRYPTO_CHALLENGE_RESPONSE_BYTES );
1775
+ RandomGetBuffer (DesfireCommandState .RndB , CryptoChallengeResponseBytesSize );
1768
1776
} else {
1769
1777
/* Fixed nonce for testing */
1770
1778
DesfireCommandState .RndB [0 ] = 0xCA ;
@@ -1784,10 +1792,10 @@ uint16_t DesfireCmdAuthenticate3KTDEA1(uint8_t *Buffer, uint16_t ByteCount) {
1784
1792
DesfireCommandState .RndB [14 ] = 0x22 ;
1785
1793
DesfireCommandState .RndB [15 ] = 0x33 ;
1786
1794
}
1787
- LogEntry (LOG_APP_NONCE_B , DesfireCommandState .RndB , CRYPTO_CHALLENGE_RESPONSE_BYTES );
1795
+ LogEntry (LOG_APP_NONCE_B , DesfireCommandState .RndB , CryptoChallengeResponseBytesSize );
1788
1796
1789
1797
/* Encrypt RndB with the selected key and transfer it back to the PCD */
1790
- Encrypt3DESBuffer (CRYPTO_CHALLENGE_RESPONSE_BYTES , DesfireCommandState .RndB ,
1798
+ Encrypt3DESBuffer (CryptoChallengeResponseBytesSize , DesfireCommandState .RndB ,
1791
1799
& Buffer [1 ], NULL , Key );
1792
1800
1793
1801
/* Scrub the key */
@@ -1796,54 +1804,57 @@ uint16_t DesfireCmdAuthenticate3KTDEA1(uint8_t *Buffer, uint16_t ByteCount) {
1796
1804
/* Done */
1797
1805
DesfireState = DESFIRE_ISO_AUTHENTICATE2 ;
1798
1806
Buffer [0 ] = STATUS_ADDITIONAL_FRAME ;
1799
- return DESFIRE_STATUS_RESPONSE_SIZE + CRYPTO_CHALLENGE_RESPONSE_BYTES ;
1807
+ return DESFIRE_STATUS_RESPONSE_SIZE + CryptoChallengeResponseBytesSize ;
1800
1808
1801
1809
}
1802
1810
1803
1811
uint16_t DesfireCmdAuthenticate3KTDEA2 (uint8_t * Buffer , uint16_t ByteCount ) {
1804
1812
BYTE KeyId ;
1805
1813
BYTE cryptoKeyType , keySize ;
1814
+ BYTE CryptoChallengeResponseBytesSize ;
1806
1815
BYTE * Key ;
1807
1816
1817
+ cryptoKeyType = DesfireCommandState .CryptoMethodType ;
1818
+ keySize = GetDefaultCryptoMethodKeySize (cryptoKeyType );
1819
+ CryptoChallengeResponseBytesSize = keySize ;
1820
+
1808
1821
/* Set status for the next incoming command on error */
1809
1822
DesfireState = DESFIRE_IDLE ;
1810
1823
/* Validate command length */
1811
- if (ByteCount != 2 * CRYPTO_CHALLENGE_RESPONSE_BYTES + 1 ) {
1824
+ if (ByteCount != 2 * CryptoChallengeResponseBytesSize + 1 ) {
1812
1825
Buffer [0 ] = STATUS_LENGTH_ERROR ;
1813
1826
return DESFIRE_STATUS_RESPONSE_SIZE ;
1814
1827
}
1815
1828
1816
1829
/* Reset parameters for authentication from the first exchange */
1817
1830
KeyId = DesfireCommandState .KeyId ;
1818
- cryptoKeyType = DesfireCommandState .CryptoMethodType ;
1819
- keySize = GetDefaultCryptoMethodKeySize (CRYPTO_TYPE_3K3DES );
1820
1831
Key = SessionKey ;
1821
1832
ReadAppKey (SelectedApp .Slot , KeyId , Key , keySize );
1822
1833
1823
1834
/* Decrypt the challenge sent back to get RndA and a shifted RndB */
1824
- BYTE challengeRndAB [2 * CRYPTO_CHALLENGE_RESPONSE_BYTES ];
1825
- BYTE challengeRndA [CRYPTO_CHALLENGE_RESPONSE_BYTES ];
1826
- BYTE challengeRndB [CRYPTO_CHALLENGE_RESPONSE_BYTES ];
1827
- Decrypt3DESBuffer (2 * CRYPTO_CHALLENGE_RESPONSE_BYTES , challengeRndAB ,
1835
+ BYTE challengeRndAB [2 * CryptoChallengeResponseBytesSize ];
1836
+ BYTE challengeRndA [CryptoChallengeResponseBytesSize ];
1837
+ BYTE challengeRndB [CryptoChallengeResponseBytesSize ];
1838
+ Decrypt3DESBuffer (2 * CryptoChallengeResponseBytesSize , challengeRndAB ,
1828
1839
& Buffer [1 ], NULL , Key );
1829
- RotateArrayRight (challengeRndAB + CRYPTO_CHALLENGE_RESPONSE_BYTES , challengeRndB ,
1830
- CRYPTO_CHALLENGE_RESPONSE_BYTES );
1831
- memcpy (challengeRndA , challengeRndAB , CRYPTO_CHALLENGE_RESPONSE_BYTES );
1840
+ RotateArrayRight (challengeRndAB + CryptoChallengeResponseBytesSize , challengeRndB ,
1841
+ CryptoChallengeResponseBytesSize );
1842
+ memcpy (challengeRndA , challengeRndAB , CryptoChallengeResponseBytesSize );
1832
1843
1833
1844
/* Check that the returned RndB matches what we sent in the previous round */
1834
- if (memcmp (DesfireCommandState .RndB , challengeRndB , CRYPTO_CHALLENGE_RESPONSE_BYTES )) {
1835
- LogEntry (LOG_ERR_DESFIRE_GENERIC_ERROR , (const void * ) challengeRndB , CRYPTO_CHALLENGE_RESPONSE_BYTES );
1845
+ if (memcmp (DesfireCommandState .RndB , challengeRndB , CryptoChallengeResponseBytesSize )) {
1846
+ LogEntry (LOG_ERR_DESFIRE_GENERIC_ERROR , (const void * ) challengeRndB , CryptoChallengeResponseBytesSize );
1836
1847
Buffer [0 ] = STATUS_AUTHENTICATION_ERROR ;
1837
1848
return DESFIRE_STATUS_RESPONSE_SIZE ;
1838
1849
}
1839
1850
1840
1851
/* Encrypt and send back the once rotated RndA buffer to the PCD */
1841
- RotateArrayLeft (challengeRndA , challengeRndAB , CRYPTO_CHALLENGE_RESPONSE_BYTES );
1842
- Encrypt3DESBuffer (CRYPTO_CHALLENGE_RESPONSE_BYTES , challengeRndAB ,
1852
+ RotateArrayLeft (challengeRndA , challengeRndAB , CryptoChallengeResponseBytesSize );
1853
+ Encrypt3DESBuffer (CryptoChallengeResponseBytesSize , challengeRndAB ,
1843
1854
& Buffer [1 ], NULL , Key );
1844
1855
1845
1856
/* Create the session key based on the previous exchange */
1846
- generateSessionKey (SessionKey , challengeRndA , challengeRndB , CRYPTO_TYPE_3K3DES );
1857
+ generateSessionKey (SessionKey , challengeRndA , challengeRndB , cryptoKeyType );
1847
1858
1848
1859
/* Now that we have auth'ed with the legacy command, a ChangeKey command will
1849
1860
* allow for subsequent authentication with the ISO or AES routines
@@ -1855,7 +1866,7 @@ uint16_t DesfireCmdAuthenticate3KTDEA2(uint8_t *Buffer, uint16_t ByteCount) {
1855
1866
1856
1867
/* Return the status on success */
1857
1868
Buffer [0 ] = STATUS_OPERATION_OK ;
1858
- return DESFIRE_STATUS_RESPONSE_SIZE + CRYPTO_CHALLENGE_RESPONSE_BYTES ;
1869
+ return DESFIRE_STATUS_RESPONSE_SIZE + CryptoChallengeResponseBytesSize ;
1859
1870
1860
1871
}
1861
1872
@@ -1990,7 +2001,6 @@ uint16_t DesfireCmdAuthenticateAES2(uint8_t *Buffer, uint16_t ByteCount) {
1990
2001
if (memcmp (DesfireCommandState .RndB , challengeRndB , CRYPTO_CHALLENGE_RESPONSE_BYTES )) {
1991
2002
memcpy (challengeRndAB , DesfireCommandState .RndB , CRYPTO_CHALLENGE_RESPONSE_BYTES );
1992
2003
memcpy (challengeRndAB + CRYPTO_CHALLENGE_RESPONSE_BYTES , challengeRndB , CRYPTO_CHALLENGE_RESPONSE_BYTES );
1993
- LogEntry (LOG_APP_NONCE_B , challengeRndAB , 2 * CRYPTO_CHALLENGE_RESPONSE_BYTES );
1994
2004
Buffer [0 ] = STATUS_AUTHENTICATION_ERROR ;
1995
2005
return DESFIRE_STATUS_RESPONSE_SIZE ;
1996
2006
}
0 commit comments