passy_common.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "passy_common.h"
  2. #define PASSY_WORKER_MAX_BUFFER_SIZE 128
  3. #define TAG "PassyCommon"
  4. void passy_log_bitbuffer(char* tag, char* prefix, BitBuffer* buffer) {
  5. furi_assert(buffer);
  6. size_t length = bit_buffer_get_size_bytes(buffer);
  7. const uint8_t* data = bit_buffer_get_data(buffer);
  8. char display[PASSY_WORKER_MAX_BUFFER_SIZE * 2 + 1];
  9. size_t limit = MIN((size_t)PASSY_WORKER_MAX_BUFFER_SIZE, length);
  10. memset(display, 0, sizeof(display));
  11. for(uint8_t i = 0; i < limit; i++) {
  12. snprintf(display + (i * 2), sizeof(display), "%02x", data[i]);
  13. }
  14. if(prefix) {
  15. FURI_LOG_D(tag, "%s %d: %s", prefix, length, display);
  16. } else {
  17. FURI_LOG_D(tag, "Buffer %d: %s", length, display);
  18. }
  19. }
  20. void passy_log_buffer(char* tag, char* prefix, uint8_t* buffer, size_t buffer_len) {
  21. char display[PASSY_WORKER_MAX_BUFFER_SIZE * 2 + 1];
  22. size_t limit = MIN((size_t)PASSY_WORKER_MAX_BUFFER_SIZE, buffer_len);
  23. memset(display, 0, sizeof(display));
  24. for(uint8_t i = 0; i < limit; i++) {
  25. snprintf(display + (i * 2), sizeof(display), "%02x", buffer[i]);
  26. }
  27. if(prefix) {
  28. FURI_LOG_D(tag, "%s %d: %s", prefix, limit, display);
  29. } else {
  30. FURI_LOG_D(tag, "Buffer %d: %s", limit, display);
  31. }
  32. }
  33. // ISO/IEC 9797-1 MAC Algorithm 3
  34. void passy_mac(uint8_t* key, uint8_t* data, size_t data_length, uint8_t* mac, bool prepadded) {
  35. size_t block_count = data_length / 8;
  36. uint8_t y[8];
  37. memset(y, 0, sizeof(y));
  38. for(size_t i = 0; i < block_count; i++) {
  39. uint8_t* x = data + (i * 8);
  40. //passy_log_buffer(TAG, "x", x, 8);
  41. uint8_t iv[8];
  42. memcpy(iv, y, sizeof(y));
  43. mbedtls_des_context ctx;
  44. mbedtls_des_init(&ctx);
  45. mbedtls_des_setkey_enc(&ctx, key); // uses 8 bytes
  46. mbedtls_des_crypt_cbc(&ctx, MBEDTLS_DES_ENCRYPT, 8, iv, x, y);
  47. mbedtls_des_free(&ctx);
  48. //passy_log_buffer(TAG, "y", y, 8);
  49. }
  50. mbedtls_des_context ctx;
  51. if(!prepadded) {
  52. // last block
  53. uint8_t last_block[8] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  54. uint8_t iv[8];
  55. memcpy(iv, y, sizeof(y));
  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, last_block, y);
  59. //passy_log_buffer(TAG, "y", y, 8);
  60. }
  61. uint8_t b[8];
  62. mbedtls_des_init(&ctx);
  63. mbedtls_des_setkey_dec(&ctx, key + 8); // uses 8 bytes
  64. mbedtls_des_crypt_ecb(&ctx, y, b);
  65. //passy_log_buffer(TAG, "b", b, 8);
  66. mbedtls_des_init(&ctx);
  67. mbedtls_des_setkey_enc(&ctx, key); // uses 8 bytes
  68. mbedtls_des_crypt_ecb(&ctx, b, mac);
  69. //passy_log_buffer(TAG, "mac", mac, 8);
  70. mbedtls_des_free(&ctx);
  71. }
  72. // https://en.wikipedia.org/wiki/Machine-readable_passport
  73. char passy_checksum(char* str) {
  74. uint8_t values[] = {
  75. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  76. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
  77. // < = filler
  78. // A = 10
  79. // B = 11
  80. // C = 12
  81. // D = 13
  82. // E = 14
  83. // F = 15
  84. // G = 16
  85. // H = 17
  86. // I = 18
  87. // J = 19
  88. // K = 20
  89. // L = 21
  90. // M = 22
  91. // N = 23
  92. // O = 24
  93. // P = 25
  94. // Q = 26
  95. // R = 27
  96. // S = 28
  97. // T = 29
  98. // U = 30
  99. // V = 31
  100. // W = 32
  101. // X = 33
  102. // Y = 34
  103. // Z = 35
  104. };
  105. size_t sum = 0;
  106. uint8_t weight_map[] = {7, 3, 1};
  107. for(uint8_t i = 0; i < strlen(str); i++) {
  108. uint8_t value;
  109. uint8_t weight = weight_map[(i % 3)];
  110. if(str[i] >= '0' && str[i] <= '9') {
  111. value = values[str[i] - '0'];
  112. } else if(str[i] >= 'A' && str[i] <= 'Z') {
  113. value = values[str[i] - 'A' + 10];
  114. } else if(str[i] == '<') {
  115. value = 0;
  116. } else {
  117. FURI_LOG_E(TAG, "Invalid character %02x", str[i]);
  118. return -1;
  119. }
  120. sum += value * weight;
  121. }
  122. return 0x30 + (sum % 10);
  123. }