passy_common.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include "passy_common.h"
  2. #define PASSY_WORKER_MAX_BUFFER_SIZE 128
  3. #define TAG "PassyCommon"
  4. static char asn1_log[PASSY_WORKER_MAX_BUFFER_SIZE];
  5. int print_struct_callback(const void* buffer, size_t size, void* app_key) {
  6. if(app_key) {
  7. char* str = (char*)app_key;
  8. size_t next = strlen(str);
  9. strncpy(str + next, buffer, size);
  10. } else {
  11. uint8_t next = strlen(asn1_log);
  12. strncpy(asn1_log + next, buffer, size);
  13. }
  14. return 0;
  15. }
  16. void passy_log_bitbuffer(char* tag, char* prefix, BitBuffer* buffer) {
  17. furi_assert(buffer);
  18. size_t length = bit_buffer_get_size_bytes(buffer);
  19. const uint8_t* data = bit_buffer_get_data(buffer);
  20. char display[PASSY_WORKER_MAX_BUFFER_SIZE * 2 + 1];
  21. size_t limit = MIN((size_t)PASSY_WORKER_MAX_BUFFER_SIZE, length);
  22. memset(display, 0, sizeof(display));
  23. for(uint8_t i = 0; i < limit; i++) {
  24. snprintf(display + (i * 2), sizeof(display), "%02x", data[i]);
  25. }
  26. if(prefix) {
  27. FURI_LOG_D(tag, "%s %d: %s", prefix, length, display);
  28. } else {
  29. FURI_LOG_D(tag, "Buffer %d: %s", length, display);
  30. }
  31. }
  32. void passy_log_buffer(char* tag, char* prefix, uint8_t* buffer, size_t buffer_len) {
  33. char display[PASSY_WORKER_MAX_BUFFER_SIZE * 2 + 1];
  34. size_t limit = MIN((size_t)PASSY_WORKER_MAX_BUFFER_SIZE, buffer_len);
  35. memset(display, 0, sizeof(display));
  36. for(uint8_t i = 0; i < limit; i++) {
  37. snprintf(display + (i * 2), sizeof(display), "%02x", buffer[i]);
  38. }
  39. if(prefix) {
  40. FURI_LOG_D(tag, "%s %d: %s", prefix, limit, display);
  41. } else {
  42. FURI_LOG_D(tag, "Buffer %d: %s", limit, display);
  43. }
  44. }
  45. // ISO/IEC 9797-1 MAC Algorithm 3
  46. void passy_mac(uint8_t* key, uint8_t* data, size_t data_length, uint8_t* mac, bool prepadded) {
  47. size_t block_count = data_length / 8;
  48. uint8_t y[8];
  49. memset(y, 0, sizeof(y));
  50. for(size_t i = 0; i < block_count; i++) {
  51. uint8_t* x = data + (i * 8);
  52. //passy_log_buffer(TAG, "x", x, 8);
  53. uint8_t iv[8];
  54. memcpy(iv, y, sizeof(y));
  55. mbedtls_des_context ctx;
  56. mbedtls_des_init(&ctx);
  57. mbedtls_des_setkey_enc(&ctx, key); // uses 8 bytes
  58. mbedtls_des_crypt_cbc(&ctx, MBEDTLS_DES_ENCRYPT, 8, iv, x, y);
  59. mbedtls_des_free(&ctx);
  60. //passy_log_buffer(TAG, "y", y, 8);
  61. }
  62. mbedtls_des_context ctx;
  63. if(!prepadded) {
  64. // last block
  65. uint8_t last_block[8] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  66. uint8_t iv[8];
  67. memcpy(iv, y, sizeof(y));
  68. mbedtls_des_init(&ctx);
  69. mbedtls_des_setkey_enc(&ctx, key); // uses 8 bytes
  70. mbedtls_des_crypt_cbc(&ctx, MBEDTLS_DES_ENCRYPT, 8, iv, last_block, y);
  71. //passy_log_buffer(TAG, "y", y, 8);
  72. }
  73. uint8_t b[8];
  74. mbedtls_des_init(&ctx);
  75. mbedtls_des_setkey_dec(&ctx, key + 8); // uses 8 bytes
  76. mbedtls_des_crypt_ecb(&ctx, y, b);
  77. //passy_log_buffer(TAG, "b", b, 8);
  78. mbedtls_des_init(&ctx);
  79. mbedtls_des_setkey_enc(&ctx, key); // uses 8 bytes
  80. mbedtls_des_crypt_ecb(&ctx, b, mac);
  81. //passy_log_buffer(TAG, "mac", mac, 8);
  82. mbedtls_des_free(&ctx);
  83. }
  84. // https://en.wikipedia.org/wiki/Machine-readable_passport
  85. char passy_checksum(char* str) {
  86. size_t sum = 0;
  87. uint8_t weight_map[] = {7, 3, 1};
  88. for(uint8_t i = 0; i < strlen(str); i++) {
  89. uint8_t value;
  90. char c = toupper(str[i]);
  91. uint8_t weight = weight_map[(i % 3)];
  92. if(c >= '0' && c <= '9') {
  93. value = c - '0';
  94. } else if(c >= 'A' && c <= 'Z') {
  95. value = c - 'A' + 10;
  96. } else if(c == '<') {
  97. value = 0;
  98. } else {
  99. FURI_LOG_E(TAG, "Invalid character %02x", c);
  100. return -1;
  101. }
  102. sum += value * weight;
  103. }
  104. return 0x30 + (sum % 10);
  105. }