secure_messaging.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #include "secure_messaging.h"
  2. #define TAG "SecureMessaging"
  3. uint8_t padding[16] =
  4. {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  5. void secure_messaging_adjust_parity(uint8_t key[16]) {
  6. for(size_t i = 0; i < 16; i++) {
  7. // Set the parity bit to 1 if the number of 1 bits is even
  8. for(size_t j = 0; j < 8; j++) {
  9. if((key[i] >> j) & 0x01) {
  10. key[i] ^= 0x01;
  11. }
  12. }
  13. key[i] ^= 0x01;
  14. }
  15. }
  16. void secure_messaging_key_diversification(uint8_t input[20], size_t input_len, uint8_t* output) {
  17. uint8_t sha[20];
  18. mbedtls_sha1_context ctx;
  19. mbedtls_sha1_init(&ctx);
  20. mbedtls_sha1_starts(&ctx);
  21. mbedtls_sha1_update(&ctx, input, input_len);
  22. mbedtls_sha1_finish(&ctx, sha);
  23. memcpy(output, sha, 16);
  24. secure_messaging_adjust_parity(output);
  25. }
  26. SecureMessaging* secure_messaging_alloc(
  27. uint8_t* passport_number,
  28. uint8_t* date_of_birth,
  29. uint8_t* date_of_expiry) {
  30. SecureMessaging* secure_messaging = malloc(sizeof(SecureMessaging));
  31. memset(secure_messaging, 0, sizeof(SecureMessaging));
  32. mbedtls_sha1_context ctx;
  33. memset(secure_messaging->rndIFD, 0x00, sizeof(secure_messaging->rndIFD));
  34. memset(secure_messaging->Kifd, 0x00, sizeof(secure_messaging->Kifd));
  35. uint8_t mrz[SECURE_MESSAGING_MAX_SIZE];
  36. size_t mrz_index = 0;
  37. strncpy((char*)mrz, (char*)passport_number, 12);
  38. mrz_index += strlen((char*)passport_number);
  39. strncpy((char*)mrz + mrz_index, (char*)date_of_birth, 8);
  40. mrz_index += strlen((char*)date_of_birth);
  41. strncpy((char*)mrz + mrz_index, (char*)date_of_expiry, 8);
  42. mrz_index += strlen((char*)date_of_expiry);
  43. FURI_LOG_D(TAG, "secure_messaging_alloc mrz %s", mrz);
  44. uint8_t sha[20];
  45. mbedtls_sha1_init(&ctx);
  46. mbedtls_sha1_starts(&ctx);
  47. mbedtls_sha1_update(&ctx, mrz, mrz_index);
  48. mbedtls_sha1_finish(&ctx, sha);
  49. uint8_t D[20];
  50. memset(D, 0, sizeof(D));
  51. memcpy(D, sha, 16);
  52. D[19] = 0x01;
  53. secure_messaging_key_diversification(D, sizeof(D), secure_messaging->KENC);
  54. D[19] = 0x02;
  55. secure_messaging_key_diversification(D, sizeof(D), secure_messaging->KMAC);
  56. mbedtls_sha1_free(&ctx);
  57. return secure_messaging;
  58. }
  59. void secure_messaging_free(SecureMessaging* secure_messaging) {
  60. furi_assert(secure_messaging);
  61. // Nothing to free;
  62. free(secure_messaging);
  63. }
  64. void secure_messaging_calculate_session_keys(SecureMessaging* secure_messaging) {
  65. uint8_t Kseed[16];
  66. for(size_t i = 0; i < sizeof(Kseed); i++) {
  67. Kseed[i] = secure_messaging->Kifd[i] ^ secure_messaging->Kicc[i];
  68. }
  69. uint8_t D[20];
  70. memset(D, 0, sizeof(D));
  71. memcpy(D, Kseed, sizeof(Kseed));
  72. D[19] = 0x01;
  73. secure_messaging_key_diversification(D, sizeof(D), secure_messaging->KSenc);
  74. D[19] = 0x02;
  75. secure_messaging_key_diversification(D, sizeof(D), secure_messaging->KSmac);
  76. }
  77. void secure_messaging_increment_context(SecureMessaging* secure_messaging) {
  78. uint8_t* context = secure_messaging->SSC;
  79. size_t context_len = sizeof(secure_messaging->SSC);
  80. do {
  81. } while(++context[--context_len] == 0 && context_len > 0);
  82. }
  83. void secure_messaging_wrap_apdu(
  84. SecureMessaging* secure_messaging,
  85. uint8_t* message,
  86. size_t message_len,
  87. BitBuffer* tx_buffer) {
  88. furi_assert(secure_messaging);
  89. secure_messaging_increment_context(secure_messaging);
  90. uint8_t payload_length = 0;
  91. bool has_le = false;
  92. if(message_len == 5) { // APDU with no payload and Le
  93. has_le = true;
  94. } else {
  95. payload_length = message[4];
  96. }
  97. uint8_t cmd_header[8];
  98. memset(cmd_header, 0, sizeof(cmd_header));
  99. memcpy(cmd_header, message, 4);
  100. cmd_header[0] |= 0x0c;
  101. cmd_header[4] = 0x80;
  102. uint8_t D087[3 + 8];
  103. if(payload_length > 0) {
  104. uint8_t* payload = message + 5;
  105. if(payload_length > 7) {
  106. FURI_LOG_W(TAG, "secure_messaging_wrap_apdu payload length too large to handle");
  107. return;
  108. }
  109. uint8_t padded_payload[8];
  110. memset(padded_payload, 0, sizeof(padded_payload));
  111. memcpy(padded_payload, payload, payload_length);
  112. padded_payload[payload_length] = 0x80;
  113. uint8_t encrypted_payload[8];
  114. uint8_t iv[8];
  115. memset(iv, 0, sizeof(iv));
  116. mbedtls_des3_context ctx;
  117. mbedtls_des3_init(&ctx);
  118. mbedtls_des3_set2key_enc(&ctx, secure_messaging->KSenc);
  119. mbedtls_des3_crypt_cbc(
  120. &ctx,
  121. MBEDTLS_DES_ENCRYPT,
  122. sizeof(padded_payload),
  123. iv,
  124. padded_payload,
  125. encrypted_payload);
  126. mbedtls_des3_free(&ctx);
  127. memset(D087, 0, sizeof(D087));
  128. D087[0] = 0x87;
  129. D087[1] = 1 + sizeof(encrypted_payload);
  130. D087[2] = 0x01; // TODO: look into the meaning of this
  131. memcpy(D087 + 3, encrypted_payload, sizeof(encrypted_payload));
  132. }
  133. uint8_t D097[3];
  134. memset(D097, 0, sizeof(D097));
  135. if(has_le) {
  136. D097[0] = 0x97;
  137. D097[1] = 0x01;
  138. D097[2] = message[message_len - 1];
  139. }
  140. uint8_t M[8 + 3 + 8 /* + 2*/];
  141. uint8_t M_index = 0;
  142. memset(M, 0, sizeof(M));
  143. memcpy(M, cmd_header, sizeof(cmd_header));
  144. M_index += sizeof(cmd_header);
  145. if(payload_length > 0) {
  146. memcpy(M + M_index, D087, sizeof(D087));
  147. M_index += sizeof(D087);
  148. }
  149. if(has_le) {
  150. memcpy(M + M_index, D097, sizeof(D097));
  151. M_index += sizeof(D097);
  152. }
  153. uint8_t N[32];
  154. uint8_t N_index = 0;
  155. memset(N, 0, sizeof(N));
  156. memcpy(N, secure_messaging->SSC, sizeof(secure_messaging->SSC));
  157. N_index += sizeof(secure_messaging->SSC);
  158. memcpy(N + N_index, M, M_index);
  159. N_index += M_index;
  160. N[N_index++] = 0x80;
  161. // Align to 8 bytes
  162. uint8_t block_count = (N_index + 7) / 8;
  163. N_index = block_count * 8;
  164. uint8_t mac[8];
  165. passy_mac(secure_messaging->KSmac, N, N_index, mac, true);
  166. uint8_t D08E[2 + 8];
  167. memset(D08E, 0, sizeof(D08E));
  168. D08E[0] = 0x8E;
  169. D08E[1] = sizeof(mac);
  170. memcpy(D08E + 2, mac, sizeof(mac));
  171. bit_buffer_append_bytes(tx_buffer, cmd_header, 4);
  172. uint8_t protected_payload_length = 0;
  173. protected_payload_length += sizeof(D08E);
  174. if(payload_length > 0) {
  175. protected_payload_length += sizeof(D087);
  176. }
  177. if(has_le) {
  178. protected_payload_length += sizeof(D097);
  179. }
  180. // Lc
  181. bit_buffer_append_byte(tx_buffer, protected_payload_length);
  182. if(payload_length > 0) {
  183. bit_buffer_append_bytes(tx_buffer, D087, sizeof(D087));
  184. }
  185. if(has_le) {
  186. bit_buffer_append_bytes(tx_buffer, D097, sizeof(D097));
  187. }
  188. bit_buffer_append_bytes(tx_buffer, D08E, sizeof(D08E));
  189. bit_buffer_append_byte(tx_buffer, 0x00); // Le
  190. }
  191. void secure_messaging_unwrap_rapdu(SecureMessaging* secure_messaging, BitBuffer* rx_buffer) {
  192. secure_messaging_increment_context(secure_messaging);
  193. size_t length = bit_buffer_get_size_bytes(rx_buffer);
  194. const uint8_t* data = bit_buffer_get_data(rx_buffer);
  195. uint8_t status_word[2];
  196. uint8_t* mac = NULL;
  197. uint8_t* encrypted = NULL;
  198. uint8_t encrypted_len = 0;
  199. // Look for mac
  200. uint8_t i = 0;
  201. do {
  202. uint8_t type = data[i++];
  203. uint8_t len = data[i++];
  204. switch(type) {
  205. case 0x87:
  206. // Encrypted data always starts with a 0x01
  207. encrypted = (uint8_t*)data + i + 1;
  208. encrypted_len = len - 1;
  209. break;
  210. case 0x8E:
  211. mac = (uint8_t*)data + i;
  212. break;
  213. case 0x99:
  214. status_word[0] = data[i + 0];
  215. status_word[1] = data[i + 1];
  216. break;
  217. default:
  218. FURI_LOG_W(TAG, "Unknown type %02x", type);
  219. break;
  220. }
  221. i += len;
  222. } while(i < length - 2);
  223. if(mac) {
  224. uint8_t K[SECURE_MESSAGING_MAX_SIZE];
  225. memset(K, 0, sizeof(K));
  226. uint8_t K_index = 0;
  227. memcpy(K, secure_messaging->SSC, sizeof(secure_messaging->SSC));
  228. K_index += sizeof(secure_messaging->SSC);
  229. if(encrypted) {
  230. K[K_index++] = 0x87;
  231. K[K_index++] = encrypted_len + 1;
  232. K[K_index++] = 0x01;
  233. memcpy(K + K_index, encrypted, encrypted_len);
  234. K_index += encrypted_len;
  235. }
  236. // Assume the status word is always present
  237. K[K_index++] = 0x99;
  238. K[K_index++] = 0x02;
  239. memcpy(K + K_index, status_word, 2);
  240. K_index += 2;
  241. K[K_index++] = 0x80;
  242. // Align to 8 bytes
  243. uint8_t block_count = (K_index + 7) / 8;
  244. K_index = block_count * 8;
  245. uint8_t calculated_mac[8];
  246. passy_mac(secure_messaging->KSmac, K, K_index, calculated_mac, true);
  247. if(memcmp(mac, calculated_mac, sizeof(calculated_mac)) != 0) {
  248. FURI_LOG_W(TAG, "Invalid MAC");
  249. return;
  250. }
  251. }
  252. uint8_t decrypted[SECURE_MESSAGING_MAX_SIZE];
  253. uint8_t decrypted_len = encrypted_len;
  254. if(encrypted) {
  255. if(encrypted_len > sizeof(decrypted)) {
  256. FURI_LOG_W(TAG, "secure_messaging_unwrap_rapdu encrypted length too large to handle");
  257. return;
  258. }
  259. uint8_t iv[8];
  260. memset(iv, 0, sizeof(iv));
  261. mbedtls_des3_context ctx;
  262. mbedtls_des3_init(&ctx);
  263. mbedtls_des3_set2key_dec(&ctx, secure_messaging->KSenc);
  264. mbedtls_des3_crypt_cbc(&ctx, MBEDTLS_DES_DECRYPT, encrypted_len, iv, encrypted, decrypted);
  265. mbedtls_des3_free(&ctx);
  266. // Remove padding
  267. do {
  268. } while(decrypted[--decrypted_len] == 0 && decrypted_len > 0);
  269. }
  270. // Don't reset until after data has been decrypted
  271. bit_buffer_reset(rx_buffer);
  272. if(encrypted) {
  273. bit_buffer_append_bytes(rx_buffer, decrypted, decrypted_len);
  274. }
  275. bit_buffer_append_bytes(rx_buffer, status_word, 2);
  276. }