crypto1.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include "crypto1.h"
  2. #include <nfc/helpers/nfc_util.h>
  3. #include <bit_lib/bit_lib.h>
  4. #include <furi.h>
  5. // Algorithm from https://github.com/RfidResearchGroup/proxmark3.git
  6. #define SWAPENDIAN(x) \
  7. ((x) = ((x) >> 8 & 0xff00ff) | ((x) & 0xff00ff) << 8, (x) = (x) >> 16 | (x) << 16)
  8. #define LF_POLY_ODD (0x29CE5C)
  9. #define LF_POLY_EVEN (0x870804)
  10. #define BEBIT(x, n) FURI_BIT(x, (n) ^ 24)
  11. Crypto1* crypto1_alloc() {
  12. Crypto1* instance = malloc(sizeof(Crypto1));
  13. return instance;
  14. }
  15. void crypto1_free(Crypto1* instance) {
  16. furi_assert(instance);
  17. free(instance);
  18. }
  19. void crypto1_reset(Crypto1* crypto1) {
  20. furi_assert(crypto1);
  21. crypto1->even = 0;
  22. crypto1->odd = 0;
  23. }
  24. void crypto1_init(Crypto1* crypto1, uint64_t key) {
  25. furi_assert(crypto1);
  26. crypto1->even = 0;
  27. crypto1->odd = 0;
  28. for(int8_t i = 47; i > 0; i -= 2) {
  29. crypto1->odd = crypto1->odd << 1 | FURI_BIT(key, (i - 1) ^ 7);
  30. crypto1->even = crypto1->even << 1 | FURI_BIT(key, i ^ 7);
  31. }
  32. }
  33. static uint32_t crypto1_filter(uint32_t in) {
  34. uint32_t out = 0;
  35. out = 0xf22c0 >> (in & 0xf) & 16;
  36. out |= 0x6c9c0 >> (in >> 4 & 0xf) & 8;
  37. out |= 0x3c8b0 >> (in >> 8 & 0xf) & 4;
  38. out |= 0x1e458 >> (in >> 12 & 0xf) & 2;
  39. out |= 0x0d938 >> (in >> 16 & 0xf) & 1;
  40. return FURI_BIT(0xEC57E80A, out);
  41. }
  42. uint8_t crypto1_bit(Crypto1* crypto1, uint8_t in, int is_encrypted) {
  43. furi_assert(crypto1);
  44. uint8_t out = crypto1_filter(crypto1->odd);
  45. uint32_t feed = out & (!!is_encrypted);
  46. feed ^= !!in;
  47. feed ^= LF_POLY_ODD & crypto1->odd;
  48. feed ^= LF_POLY_EVEN & crypto1->even;
  49. crypto1->even = crypto1->even << 1 | (nfc_util_even_parity32(feed));
  50. FURI_SWAP(crypto1->odd, crypto1->even);
  51. return out;
  52. }
  53. uint8_t crypto1_byte(Crypto1* crypto1, uint8_t in, int is_encrypted) {
  54. furi_assert(crypto1);
  55. uint8_t out = 0;
  56. for(uint8_t i = 0; i < 8; i++) {
  57. out |= crypto1_bit(crypto1, FURI_BIT(in, i), is_encrypted) << i;
  58. }
  59. return out;
  60. }
  61. uint32_t crypto1_word(Crypto1* crypto1, uint32_t in, int is_encrypted) {
  62. furi_assert(crypto1);
  63. uint32_t out = 0;
  64. for(uint8_t i = 0; i < 32; i++) {
  65. out |= (uint32_t)crypto1_bit(crypto1, BEBIT(in, i), is_encrypted) << (24 ^ i);
  66. }
  67. return out;
  68. }
  69. uint32_t prng_successor(uint32_t x, uint32_t n) {
  70. SWAPENDIAN(x);
  71. while(n--)
  72. x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
  73. return SWAPENDIAN(x);
  74. }
  75. void crypto1_decrypt(Crypto1* crypto, const BitBuffer* buff, BitBuffer* out) {
  76. furi_assert(crypto);
  77. furi_assert(buff);
  78. furi_assert(out);
  79. size_t bits = bit_buffer_get_size(buff);
  80. bit_buffer_set_size(out, bits);
  81. const uint8_t* encrypted_data = bit_buffer_get_data(buff);
  82. if(bits < 8) {
  83. uint8_t decrypted_byte = 0;
  84. uint8_t encrypted_byte = encrypted_data[0];
  85. decrypted_byte |= (crypto1_bit(crypto, 0, 0) ^ FURI_BIT(encrypted_byte, 0)) << 0;
  86. decrypted_byte |= (crypto1_bit(crypto, 0, 0) ^ FURI_BIT(encrypted_byte, 1)) << 1;
  87. decrypted_byte |= (crypto1_bit(crypto, 0, 0) ^ FURI_BIT(encrypted_byte, 2)) << 2;
  88. decrypted_byte |= (crypto1_bit(crypto, 0, 0) ^ FURI_BIT(encrypted_byte, 3)) << 3;
  89. bit_buffer_set_byte(out, 0, decrypted_byte);
  90. } else {
  91. for(size_t i = 0; i < bits / 8; i++) {
  92. uint8_t decrypted_byte = crypto1_byte(crypto, 0, 0) ^ encrypted_data[i];
  93. bit_buffer_set_byte(out, i, decrypted_byte);
  94. }
  95. }
  96. }
  97. void crypto1_encrypt(Crypto1* crypto, uint8_t* keystream, const BitBuffer* buff, BitBuffer* out) {
  98. furi_assert(crypto);
  99. furi_assert(buff);
  100. furi_assert(out);
  101. size_t bits = bit_buffer_get_size(buff);
  102. bit_buffer_set_size(out, bits);
  103. const uint8_t* plain_data = bit_buffer_get_data(buff);
  104. if(bits < 8) {
  105. uint8_t encrypted_byte = 0;
  106. for(size_t i = 0; i < bits; i++) {
  107. encrypted_byte |= (crypto1_bit(crypto, 0, 0) ^ FURI_BIT(plain_data[0], i)) << i;
  108. }
  109. bit_buffer_set_byte(out, 0, encrypted_byte);
  110. } else {
  111. for(size_t i = 0; i < bits / 8; i++) {
  112. uint8_t encrypted_byte = crypto1_byte(crypto, keystream ? keystream[i] : 0, 0) ^
  113. plain_data[i];
  114. bool parity_bit =
  115. ((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(plain_data[i])) & 0x01);
  116. bit_buffer_set_byte_with_parity(out, i, encrypted_byte, parity_bit);
  117. }
  118. }
  119. }
  120. void crypto1_encrypt_reader_nonce(
  121. Crypto1* crypto,
  122. uint64_t key,
  123. uint32_t cuid,
  124. uint8_t* nt,
  125. uint8_t* nr,
  126. BitBuffer* out,
  127. bool is_nested) {
  128. furi_assert(crypto);
  129. furi_assert(nt);
  130. furi_assert(nr);
  131. furi_assert(out);
  132. bit_buffer_set_size_bytes(out, 8);
  133. uint32_t nt_num = bit_lib_bytes_to_num_be(nt, sizeof(uint32_t));
  134. crypto1_init(crypto, key);
  135. if(is_nested) {
  136. nt_num = crypto1_word(crypto, nt_num ^ cuid, 1) ^ nt_num;
  137. } else {
  138. crypto1_word(crypto, nt_num ^ cuid, 0);
  139. }
  140. for(size_t i = 0; i < 4; i++) {
  141. uint8_t byte = crypto1_byte(crypto, nr[i], 0) ^ nr[i];
  142. bool parity_bit = ((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nr[i])) & 0x01);
  143. bit_buffer_set_byte_with_parity(out, i, byte, parity_bit);
  144. nr[i] = byte;
  145. }
  146. nt_num = prng_successor(nt_num, 32);
  147. for(size_t i = 4; i < 8; i++) {
  148. nt_num = prng_successor(nt_num, 8);
  149. uint8_t byte = crypto1_byte(crypto, 0, 0) ^ (uint8_t)(nt_num);
  150. bool parity_bit = ((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nt_num)) & 0x01);
  151. bit_buffer_set_byte_with_parity(out, i, byte, parity_bit);
  152. }
  153. }