secure_messaging.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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], 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, 20);
  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[10 + 7 + 7];
  36. memcpy(mrz, passport_number, 10);
  37. memcpy(mrz + 10, date_of_birth, 7);
  38. memcpy(mrz + 10 + 7, date_of_expiry, 7);
  39. FURI_LOG_D(TAG, "secure_messaging_alloc mrz %s", mrz);
  40. uint8_t sha[20];
  41. mbedtls_sha1_init(&ctx);
  42. mbedtls_sha1_starts(&ctx);
  43. mbedtls_sha1_update(&ctx, mrz, sizeof(mrz));
  44. mbedtls_sha1_finish(&ctx, sha);
  45. passy_log_buffer(TAG, "secure_messaging_alloc sha", sha, sizeof(sha));
  46. uint8_t D[20];
  47. memset(D, 0, sizeof(D));
  48. memcpy(D, sha, 16);
  49. D[19] = 0x01;
  50. mbedtls_sha1_init(&ctx);
  51. mbedtls_sha1_starts(&ctx);
  52. mbedtls_sha1_update(&ctx, D, sizeof(D));
  53. mbedtls_sha1_finish(&ctx, sha);
  54. memcpy(secure_messaging->KENC, sha, 16);
  55. passy_log_buffer(
  56. TAG, "secure_messaging_alloc KENC", secure_messaging->KENC, sizeof(secure_messaging->KENC));
  57. // Adjust the parity bits
  58. secure_messaging_adjust_parity(secure_messaging->KENC);
  59. passy_log_buffer(
  60. TAG, "secure_messaging_alloc KENC", secure_messaging->KENC, sizeof(secure_messaging->KENC));
  61. D[19] = 0x02;
  62. mbedtls_sha1_init(&ctx);
  63. mbedtls_sha1_starts(&ctx);
  64. mbedtls_sha1_update(&ctx, D, sizeof(D));
  65. mbedtls_sha1_finish(&ctx, sha);
  66. memcpy(secure_messaging->KMAC, sha, 16);
  67. passy_log_buffer(
  68. TAG, "secure_messaging_alloc KMAC", secure_messaging->KMAC, sizeof(secure_messaging->KMAC));
  69. secure_messaging_adjust_parity(secure_messaging->KMAC);
  70. passy_log_buffer(
  71. TAG, "secure_messaging_alloc KMAC", secure_messaging->KMAC, sizeof(secure_messaging->KMAC));
  72. mbedtls_sha1_free(&ctx);
  73. return secure_messaging;
  74. }
  75. void secure_messaging_free(SecureMessaging* secure_messaging) {
  76. furi_assert(secure_messaging);
  77. // Nothing to free;
  78. free(secure_messaging);
  79. }
  80. void secure_messaging_calculate_session_keys(SecureMessaging* secure_messaging) {
  81. uint8_t Kseed[16];
  82. for(size_t i = 0; i < sizeof(Kseed); i++) {
  83. Kseed[i] = secure_messaging->Kifd[i] ^ secure_messaging->Kicc[i];
  84. }
  85. passy_log_buffer(TAG, "secure_messaging_calculate_session_keys Kseed", Kseed, sizeof(Kseed));
  86. mbedtls_sha1_context ctx;
  87. uint8_t D[20];
  88. uint8_t sha[20];
  89. memset(D, 0, sizeof(D));
  90. memcpy(D, Kseed, sizeof(Kseed));
  91. D[19] = 0x01;
  92. mbedtls_sha1_init(&ctx);
  93. mbedtls_sha1_starts(&ctx);
  94. mbedtls_sha1_update(&ctx, D, sizeof(D));
  95. mbedtls_sha1_finish(&ctx, sha);
  96. memcpy(secure_messaging->KSenc, sha, 16);
  97. secure_messaging_adjust_parity(secure_messaging->KSenc);
  98. passy_log_buffer(
  99. TAG,
  100. "secure_messaging_calculate_session_keys KSenc",
  101. secure_messaging->KSenc,
  102. sizeof(secure_messaging->KSenc));
  103. memset(D, 0, sizeof(D));
  104. memcpy(D, Kseed, sizeof(Kseed));
  105. D[19] = 0x02;
  106. mbedtls_sha1_init(&ctx);
  107. mbedtls_sha1_starts(&ctx);
  108. mbedtls_sha1_update(&ctx, D, sizeof(D));
  109. mbedtls_sha1_finish(&ctx, sha);
  110. memcpy(secure_messaging->KSmac, sha, 16);
  111. secure_messaging_adjust_parity(secure_messaging->KSmac);
  112. passy_log_buffer(
  113. TAG,
  114. "secure_messaging_calculate_session_keys KSmac",
  115. secure_messaging->KSmac,
  116. sizeof(secure_messaging->KSmac));
  117. }
  118. void secure_messaging_increment_context(SecureMessaging* secure_messaging) {
  119. uint8_t* context = secure_messaging->SSC;
  120. size_t context_len = sizeof(secure_messaging->SSC);
  121. do {
  122. } while(++context[--context_len] == 0 && context_len > 0);
  123. }
  124. void secure_messaging_wrap_apdu(
  125. SecureMessaging* secure_messaging,
  126. uint8_t* message,
  127. size_t message_len,
  128. BitBuffer* tx_buffer) {
  129. furi_assert(secure_messaging);
  130. secure_messaging_increment_context(secure_messaging);
  131. uint8_t payload_length = 0;
  132. bool has_le = false;
  133. if(message_len == 5) { // APDU with no payload and Le
  134. has_le = true;
  135. } else {
  136. payload_length = message[4];
  137. }
  138. if(has_le) {
  139. FURI_LOG_I(TAG, "secure_messaging_wrap_apdu has_le %d", message[message_len - 1]);
  140. }
  141. uint8_t cmd_header[8];
  142. memset(cmd_header, 0, sizeof(cmd_header));
  143. memcpy(cmd_header, message, 4);
  144. cmd_header[0] |= 0x0c;
  145. cmd_header[4] = 0x80;
  146. uint8_t D087[3 + 8];
  147. if(payload_length > 0) {
  148. uint8_t* payload = message + 5;
  149. if(payload_length > 7) {
  150. FURI_LOG_W(TAG, "secure_messaging_wrap_apdu payload length too large to handle");
  151. return;
  152. }
  153. uint8_t padded_payload[8];
  154. memset(padded_payload, 0, sizeof(padded_payload));
  155. memcpy(padded_payload, payload, payload_length);
  156. padded_payload[payload_length] = 0x80;
  157. passy_log_buffer(
  158. TAG,
  159. "secure_messaging_wrap_apdu padded_payload",
  160. padded_payload,
  161. sizeof(padded_payload));
  162. uint8_t encrypted_payload[8];
  163. uint8_t iv[8];
  164. memset(iv, 0, sizeof(iv));
  165. mbedtls_des3_context ctx;
  166. mbedtls_des3_init(&ctx);
  167. mbedtls_des3_set2key_enc(&ctx, secure_messaging->KSenc);
  168. mbedtls_des3_crypt_cbc(
  169. &ctx,
  170. MBEDTLS_DES_ENCRYPT,
  171. sizeof(padded_payload),
  172. iv,
  173. padded_payload,
  174. encrypted_payload);
  175. mbedtls_des3_free(&ctx);
  176. memset(D087, 0, sizeof(D087));
  177. D087[0] = 0x87;
  178. D087[1] = 1 + sizeof(encrypted_payload);
  179. D087[2] = 0x01; // TODO: look into the meaning of this
  180. memcpy(D087 + 3, encrypted_payload, sizeof(encrypted_payload));
  181. }
  182. uint8_t D097[3];
  183. memset(D097, 0, sizeof(D097));
  184. if(has_le) {
  185. D097[0] = 0x97;
  186. D097[1] = 0x01;
  187. D097[2] = message[message_len - 1];
  188. }
  189. uint8_t M[8 + 3 + 8 /* + 2*/];
  190. uint8_t M_index = 0;
  191. memset(M, 0, sizeof(M));
  192. memcpy(M, cmd_header, sizeof(cmd_header));
  193. M_index += sizeof(cmd_header);
  194. if(payload_length > 0) {
  195. memcpy(M + M_index, D087, sizeof(D087));
  196. M_index += sizeof(D087);
  197. }
  198. if(has_le) {
  199. memcpy(M + M_index, D097, sizeof(D097));
  200. M_index += sizeof(D097);
  201. }
  202. passy_log_buffer(TAG, "secure_messaging_wrap_apdu M", M, M_index);
  203. uint8_t N[32];
  204. uint8_t N_index = 0;
  205. memset(N, 0, sizeof(N));
  206. memcpy(N, secure_messaging->SSC, sizeof(secure_messaging->SSC));
  207. N_index += sizeof(secure_messaging->SSC);
  208. memcpy(N + N_index, M, M_index);
  209. N_index += M_index;
  210. N[N_index++] = 0x80;
  211. // Align to 8 bytes
  212. uint8_t block_count = (N_index + 7) / 8;
  213. N_index = block_count * 8;
  214. passy_log_buffer(TAG, "secure_messaging_wrap_apdu N", N, N_index);
  215. uint8_t mac[8];
  216. passy_mac(secure_messaging->KSmac, N, N_index, mac, true);
  217. passy_log_buffer(TAG, "secure_messaging_wrap_apdu mac", mac, sizeof(mac));
  218. uint8_t D08E[2 + 8];
  219. memset(D08E, 0, sizeof(D08E));
  220. D08E[0] = 0x8E;
  221. D08E[1] = sizeof(mac);
  222. memcpy(D08E + 2, mac, sizeof(mac));
  223. bit_buffer_append_bytes(tx_buffer, cmd_header, 4);
  224. uint8_t protected_payload_length = 0;
  225. protected_payload_length += sizeof(D08E);
  226. if(payload_length > 0) {
  227. protected_payload_length += sizeof(D087);
  228. }
  229. if(has_le) {
  230. protected_payload_length += sizeof(D097);
  231. }
  232. // Lc
  233. bit_buffer_append_byte(tx_buffer, protected_payload_length);
  234. if(payload_length > 0) {
  235. bit_buffer_append_bytes(tx_buffer, D087, sizeof(D087));
  236. }
  237. if(has_le) {
  238. bit_buffer_append_bytes(tx_buffer, D097, sizeof(D097));
  239. }
  240. bit_buffer_append_bytes(tx_buffer, D08E, sizeof(D08E));
  241. bit_buffer_append_byte(tx_buffer, 0x00); // Le
  242. }
  243. void secure_messaging_unwrap_rapdu(SecureMessaging* secure_messaging, BitBuffer* rx_buffer) {
  244. secure_messaging_increment_context(secure_messaging);
  245. size_t length = bit_buffer_get_size_bytes(rx_buffer);
  246. const uint8_t* data = bit_buffer_get_data(rx_buffer);
  247. uint8_t status_word[2];
  248. uint8_t* mac = NULL;
  249. uint8_t* encrypted = NULL;
  250. uint8_t encrypted_len = 0;
  251. // Look for mac
  252. uint8_t i = 0;
  253. do {
  254. uint8_t type = data[i++];
  255. uint8_t len = data[i++];
  256. switch(type) {
  257. case 0x87:
  258. // Encrypted data always starts with a 0x01
  259. encrypted = (uint8_t*)data + i + 1;
  260. encrypted_len = len - 1;
  261. break;
  262. case 0x8E:
  263. mac = (uint8_t*)data + i;
  264. break;
  265. case 0x99:
  266. status_word[0] = data[i + 0];
  267. status_word[1] = data[i + 1];
  268. break;
  269. default:
  270. FURI_LOG_W(TAG, "Unknown type %02x", type);
  271. break;
  272. }
  273. i += len;
  274. } while(i < length - 2);
  275. if(mac) {
  276. uint8_t K[SECURE_MESSAGING_MAX_SIZE];
  277. memset(K, 0, sizeof(K));
  278. uint8_t K_index = 0;
  279. memcpy(K, secure_messaging->SSC, sizeof(secure_messaging->SSC));
  280. K_index += sizeof(secure_messaging->SSC);
  281. if(encrypted) {
  282. K[K_index++] = 0x87;
  283. K[K_index++] = encrypted_len + 1;
  284. K[K_index++] = 0x01;
  285. memcpy(K + K_index, encrypted, encrypted_len);
  286. K_index += encrypted_len;
  287. }
  288. // Assume the status word is always present
  289. K[K_index++] = 0x99;
  290. K[K_index++] = 0x02;
  291. memcpy(K + K_index, status_word, 2);
  292. K_index += 2;
  293. K[K_index++] = 0x80;
  294. // Align to 8 bytes
  295. uint8_t block_count = (K_index + 7) / 8;
  296. K_index = block_count * 8;
  297. passy_log_buffer(TAG, "secure_messaging_unwrap_rapdu K", K, K_index);
  298. uint8_t calculated_mac[8];
  299. passy_mac(secure_messaging->KSmac, K, K_index, calculated_mac, true);
  300. passy_log_buffer(
  301. TAG,
  302. "secure_messaging_unwrap_rapdu calculated_mac",
  303. calculated_mac,
  304. sizeof(calculated_mac));
  305. if(memcmp(mac, calculated_mac, sizeof(calculated_mac)) != 0) {
  306. FURI_LOG_W(TAG, "Invalid MAC");
  307. return;
  308. }
  309. }
  310. uint8_t decrypted[SECURE_MESSAGING_MAX_SIZE];
  311. uint8_t decrypted_len = encrypted_len;
  312. if(encrypted) {
  313. if(encrypted_len > sizeof(decrypted)) {
  314. FURI_LOG_W(TAG, "secure_messaging_unwrap_rapdu encrypted length too large to handle");
  315. return;
  316. }
  317. uint8_t iv[8];
  318. memset(iv, 0, sizeof(iv));
  319. mbedtls_des3_context ctx;
  320. mbedtls_des3_init(&ctx);
  321. mbedtls_des3_set2key_dec(&ctx, secure_messaging->KSenc);
  322. mbedtls_des3_crypt_cbc(&ctx, MBEDTLS_DES_DECRYPT, encrypted_len, iv, encrypted, decrypted);
  323. mbedtls_des3_free(&ctx);
  324. // Remove padding
  325. do {
  326. } while(decrypted[--decrypted_len] == 0 && decrypted_len > 0);
  327. passy_log_buffer(TAG, "secure_messaging_unwrap_rapdu decrypted", decrypted, decrypted_len);
  328. }
  329. // Don't reset until after data has been decrypted
  330. bit_buffer_reset(rx_buffer);
  331. if(encrypted) {
  332. bit_buffer_append_bytes(rx_buffer, decrypted, decrypted_len);
  333. }
  334. bit_buffer_append_bytes(rx_buffer, status_word, 2);
  335. }