Chameleon-Mini
DESFireCryptoTests.h
1 /*
2 The DESFire stack portion of this firmware source
3 is free software written by Maxie Dion Schmidt (@maxieds):
4 You can redistribute it and/or modify
5 it under the terms of this license.
6 
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 
11 The complete source distribution of
12 this firmware is available at the following link:
13 https://github.com/maxieds/ChameleonMiniFirmwareDESFireStack.
14 
15 Based in part on the original DESFire code created by
16 @dev-zzo (GitHub handle) [Dmitry Janushkevich] available at
17 https://github.com/dev-zzo/ChameleonMini/tree/desfire.
18 */
19 
20 /* DESFireCryptoTests.h : Since we cannot easily compile the crypto sources as a standalone unit,
21  * this mechanism will allow to print some unit tests to the live logging
22  * console when a new DESFire emulation instance is initiated. At a minimum,
23  * this should help to verify that any side effects and errors in the
24  * protocols are not based on this logical part of the scheme.
25  */
26 
27 #ifndef __DESFIRE_CRYPTO_TESTS_H__
28 #define __DESFIRE_CRYPTO_TESTS_H__
29 
30 #ifdef DESFIRE_RUN_CRYPTO_TESTING_PROCEDURE
31 
32 #include "../../Common.h"
33 
34 #include "DESFireFirmwareSettings.h"
35 #include "DESFireMemoryOperations.h"
36 #include "DESFireLogging.h"
37 #include "DESFireCrypto.h"
38 
39 typedef bool (*UnitTestResultFunc)(uint8_t *errorResultBuf, uint8_t *bufSize);
40 
41 INLINE bool DiffCryptoResult(const uint8_t *bufData, const uint8_t *cmpBuf, uint8_t bufSize);
42 INLINE bool RunUnitTest(UnitTestResultFunc unitTestRunnerFunc);
43 INLINE bool RunCryptoUnitTests(void);
44 
45 INLINE bool TestDesfire2KTDEA(uint8_t *errorResultBuf, uint8_t *bufSize);
46 INLINE bool TestDesfire3K3DES(uint8_t *errorResultBuf, uint8_t *bufSize);
47 INLINE bool TestDesfireAES128(uint8_t *errorResultBuf, uint8_t *bufSize);
48 
49 INLINE bool
50 DiffCryptoResult(const uint8_t *bufData, const uint8_t *cmpBuf, uint8_t bufSize) {
51  return !memcmp(bufData, cmpBuf, bufSize);
52 }
53 
54 INLINE bool
55 RunUnitTest(UnitTestResultFunc unitTestRunnerFunc) {
56  uint16_t printResultLogSize = 0x00;
57  uint8_t errorResultBuf[CRYPTO_MAX_BLOCK_SIZE];
58  uint8_t errorBufSize = CRYPTO_MAX_BLOCK_SIZE;
59  bool unitTestPassed = unitTestRunnerFunc(errorResultBuf, &errorBufSize);
60  return unitTestPassed;
61 }
62 
63 INLINE bool
64 RunCryptoUnitTests(void) {
65  UnitTestResultFunc unitTestRunnerFuncs[] = {
66  //&TestDesfire2KTDEA,
67  //&TestDesfire3K3DES,
68  //&TestDesfireAES128,
69  };
70  uint8_t numUnitTests = sizeof(unitTestRunnerFuncs) / sizeof(UnitTestResultFunc);
71  uint8_t utIndex = 0x00;
72  while (utIndex < numUnitTests) {
73  if (!RunUnitTest(unitTestRunnerFuncs[utIndex])) {
74  uint8_t resultLogSize = 0x00;
75  return false;
76  }
77  utIndex++;
78  }
79  uint8_t resultLogSize = 0x00;
80  snprintf_P(__InternalStringBuffer, STRING_BUFFER_SIZE, PSTR("All crypto unit tests passed!"));
81  resultLogSize = StringLength(__InternalStringBuffer, STRING_BUFFER_SIZE);
82  DesfireLogEntry(LOG_INFO_DESFIRE_DEBUGGING_OUTPUT, (void *) __InternalStringBuffer, resultLogSize);
83  return true;
84 }
85 
86 #if 0
87 INLINE bool TestDesfire2KTDEA(uint8_t *errorResultBuf, uint8_t *bufSize) {
88 
89  uint8_t cryptoDataByteCount = 2 * CRYPTO_DES_BLOCK_SIZE;
90  uint8_t keyData[CRYPTO_2KTDEA_KEY_SIZE] = {
91  0xB4, 0x28, 0x2E, 0xFA, 0x9E, 0xB8, 0x2C, 0xAE,
92  0xB4, 0x28, 0x2E, 0xFA, 0x9E, 0xB8, 0x2C, 0xAE
93  };
94  uint8_t cryptoGramData[] = {
95  0x00, 0x10, 0x20, 0x31, 0x40, 0x50, 0x60, 0x70,
96  0x80, 0x90, 0xA0, 0xB0, 0xB0, 0xA0, 0x90, 0x80,
97  //0xC5, 0xFF, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00
98  };
99  uint8_t cryptoGramEncData[] = {
100  0x87, 0x99, 0x59, 0x11, 0x8B, 0xD7, 0x7C, 0x70,
101  0x10, 0x7B, 0xCD, 0xB0, 0xC0, 0x9C, 0xC7, 0xDA,
102  //0x82, 0x15, 0x04, 0xAA, 0x1E, 0x36, 0x04, 0x9C
103  };
104  uint8_t cryptoResult[cryptoDataByteCount];
105  uint8_t ivBuf[CRYPTO_2KTDEA_BLOCK_SIZE];
106 
107  memset(ivBuf, 0x00, CRYPTO_2KTDEA_BLOCK_SIZE);
108  CryptoEncrypt2KTDEA_CBCSend(cryptoDataByteCount, cryptoGramData, cryptoResult, ivBuf, keyData);
109  if (!DiffCryptoResult(cryptoGramEncData, cryptoResult, cryptoDataByteCount)) {
110  BufferToHexString(__InternalStringBuffer, STRING_BUFFER_SIZE, cryptoResult, cryptoDataByteCount);
111  DesfireLogEntry(LOG_INFO_DESFIRE_DEBUGGING_OUTPUT, (void *) __InternalStringBuffer, 2 * cryptoDataByteCount);
112  return false;
113  }
114  return true;
115 
116 }
117 #endif
118 
119 #if 0
120 INLINE bool TestDesfire3K3DES(uint8_t *errorResultBuf, uint8_t *bufSize) {
121 
122  const uint8_t cryptoDataByteCount = 2 * CRYPTO_3KTDEA_BLOCK_SIZE;
123  const uint8_t keyData[CRYPTO_3KTDEA_KEY_SIZE] = {
124  0xF4, 0x68, 0x6E, 0x3A, 0xBA, 0x90, 0x36, 0xBA,
125  0xD2, 0x8E, 0xBC, 0x10, 0x32, 0xE6, 0x38, 0xF0,
126  0x80, 0x44, 0x5A, 0xF6, 0x06, 0x86, 0xD0, 0xC4
127  };
128  const uint8_t cryptoGramData[] = {
129  0x00, 0x10, 0x20, 0x31, 0x40, 0x50, 0x60, 0x70,
130  0x80, 0x90, 0xA0, 0xB0, 0xB0, 0xA0, 0x90, 0x80,
131  //0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
132  //0xD6, 0x3E, 0x00, 0xA2, 0x00, 0x00, 0x00, 0x00
133  };
134  const uint8_t cryptoGramEncData[] = {
135  0x7F, 0x88, 0x90, 0xC7, 0xCA, 0xB9, 0xA4, 0x22,
136  0x81, 0x73, 0xA6, 0x41, 0xB6, 0x5F, 0x0F, 0x43,
137  //0xFD, 0x40, 0x4A, 0x01, 0x13, 0x71, 0xA9, 0x90,
138  //0x4A, 0x62, 0x9E, 0x3C, 0x20, 0xB2, 0xFF, 0x63
139  };
140  uint8_t cryptoResult[cryptoDataByteCount];
141  uint8_t ivBuf[CRYPTO_3KTDEA_BLOCK_SIZE];
142 
143  memset(ivBuf, 0x00, CRYPTO_3KTDEA_BLOCK_SIZE);
144  CryptoEncrypt3KTDEA_CBCSend(cryptoDataByteCount, cryptoGramData, cryptoResult, ivBuf, keyData);
145  if (!DiffCryptoResult(cryptoGramEncData, cryptoResult, cryptoDataByteCount)) {
146  BufferToHexString(__InternalStringBuffer, STRING_BUFFER_SIZE, cryptoResult, cryptoDataByteCount);
147  DesfireLogEntry(LOG_INFO_DESFIRE_DEBUGGING_OUTPUT, (void *) __InternalStringBuffer, 2 * cryptoDataByteCount);
148  return false;
149  }
150  return true;
151 
152 }
153 #endif
154 
155 #if 0
156 INLINE bool TestDesfireAES128(uint8_t *errorResultBuf, uint8_t *bufSize) {
157 
158  const uint8_t cryptoDataByteCount = 2 * CRYPTO_AES_BLOCK_SIZE;
159  const uint8_t keyData[CRYPTO_AES_KEY_SIZE] = {
160  0x73, 0xAE, 0x5D, 0x30, 0x1F, 0x45, 0x19, 0x27,
161  0x1F, 0x2A, 0x69, 0x8C, 0xEF, 0x69, 0x76, 0x04
162  };
163  const uint8_t cryptoGramData[] = {
164  0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
165  0x80, 0x90, 0xA0, 0xB0, 0xB0, 0xA0, 0x90, 0x80,
166  0x10, 0xD2, 0xC6, 0xE6, 0x6B, 0x00, 0x00, 0x00,
167  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
168  };
169  const uint8_t cryptoGramEncData[] = {
170  0x97, 0x41, 0x8E, 0x6C, 0xC0, 0x1C, 0x4E, 0x6F,
171  0xAD, 0x4D, 0x87, 0x4D, 0x8D, 0x42, 0x5C, 0xEA,
172  0x32, 0x51, 0x36, 0x11, 0x47, 0x2C, 0xDA, 0x04,
173  0xE3, 0x5E, 0xFB, 0x77, 0x9A, 0x7D, 0xA0, 0xE4
174  };
175  uint8_t cryptoResult[cryptoDataByteCount];
176  uint8_t ivBuf[CRYPTO_AES_BLOCK_SIZE];
177 
178  AESCryptoKeySizeBytes = 16;
179  DesfireAESCryptoInit(keyData, AESCryptoKeySizeBytes, &AESCryptoContext);
180  memset(ivBuf, 0x00, CRYPTO_AES_BLOCK_SIZE);
181  CryptoEncryptAES_CBCSend(cryptoDataByteCount, cryptoGramData, cryptoResult, ivBuf, &AESCryptoContext);
182  if (!DiffCryptoResult(cryptoGramEncData, cryptoResult, cryptoDataByteCount)) {
183  BufferToHexString(__InternalStringBuffer, STRING_BUFFER_SIZE, cryptoResult, cryptoDataByteCount);
184  DesfireLogEntry(LOG_INFO_DESFIRE_DEBUGGING_OUTPUT, (void *) __InternalStringBuffer, 2 * cryptoDataByteCount);
185  return false;
186  }
187  return true;
188 
189 }
190 #endif
191 
192 #endif
193 
194 #endif