secure_messaging.c 10 KB

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