crypto1.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include "crypto1.h"
  2. #include <string.h>
  3. void nescrypto1_reset(Crypto1* crypto1) {
  4. furi_assert(crypto1);
  5. crypto1->even = 0;
  6. crypto1->odd = 0;
  7. }
  8. void nescrypto1_init(Crypto1* crypto1, uint64_t key) {
  9. furi_assert(crypto1);
  10. crypto1->even = 0;
  11. crypto1->odd = 0;
  12. for(int8_t i = 47; i > 0; i -= 2) {
  13. crypto1->odd = crypto1->odd << 1 | FURI_BIT(key, (i - 1) ^ 7);
  14. crypto1->even = crypto1->even << 1 | FURI_BIT(key, i ^ 7);
  15. }
  16. }
  17. uint32_t nescrypto1_filter(uint32_t in) {
  18. uint32_t out = 0;
  19. out = 0xf22c0 >> (in & 0xf) & 16;
  20. out |= 0x6c9c0 >> (in >> 4 & 0xf) & 8;
  21. out |= 0x3c8b0 >> (in >> 8 & 0xf) & 4;
  22. out |= 0x1e458 >> (in >> 12 & 0xf) & 2;
  23. out |= 0x0d938 >> (in >> 16 & 0xf) & 1;
  24. return FURI_BIT(0xEC57E80A, out);
  25. }
  26. uint8_t nescrypto1_bit(Crypto1* crypto1, uint8_t in, int is_encrypted) {
  27. furi_assert(crypto1);
  28. uint8_t out = nescrypto1_filter(crypto1->odd);
  29. uint32_t feed = out & (!!is_encrypted);
  30. feed ^= !!in;
  31. feed ^= LF_POLY_ODD & crypto1->odd;
  32. feed ^= LF_POLY_EVEN & crypto1->even;
  33. crypto1->even = crypto1->even << 1 | (evenparity32(feed));
  34. FURI_SWAP(crypto1->odd, crypto1->even);
  35. return out;
  36. }
  37. uint8_t nescrypto1_byte(Crypto1* crypto1, uint8_t in, int is_encrypted) {
  38. furi_assert(crypto1);
  39. uint8_t out = 0;
  40. for(uint8_t i = 0; i < 8; i++) {
  41. out |= nescrypto1_bit(crypto1, FURI_BIT(in, i), is_encrypted) << i;
  42. }
  43. return out;
  44. }
  45. uint32_t nescrypto1_word(Crypto1* crypto1, uint32_t in, int is_encrypted) {
  46. furi_assert(crypto1);
  47. uint32_t out = 0;
  48. for(uint8_t i = 0; i < 32; i++) {
  49. out |= (uint32_t)nescrypto1_bit(crypto1, BEBIT(in, i), is_encrypted) << (24 ^ i);
  50. }
  51. return out;
  52. }
  53. uint32_t nesprng_successor(uint32_t x, uint32_t n) {
  54. SWAPENDIAN(x);
  55. while(n--) x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
  56. return SWAPENDIAN(x);
  57. }
  58. void nescrypto1_decrypt(
  59. Crypto1* crypto,
  60. uint8_t* encrypted_data,
  61. uint16_t encrypted_data_bits,
  62. uint8_t* decrypted_data) {
  63. furi_assert(crypto);
  64. furi_assert(encrypted_data);
  65. furi_assert(decrypted_data);
  66. if(encrypted_data_bits < 8) {
  67. uint8_t decrypted_byte = 0;
  68. decrypted_byte |= (nescrypto1_bit(crypto, 0, 0) ^ FURI_BIT(encrypted_data[0], 0)) << 0;
  69. decrypted_byte |= (nescrypto1_bit(crypto, 0, 0) ^ FURI_BIT(encrypted_data[0], 1)) << 1;
  70. decrypted_byte |= (nescrypto1_bit(crypto, 0, 0) ^ FURI_BIT(encrypted_data[0], 2)) << 2;
  71. decrypted_byte |= (nescrypto1_bit(crypto, 0, 0) ^ FURI_BIT(encrypted_data[0], 3)) << 3;
  72. decrypted_data[0] = decrypted_byte;
  73. } else {
  74. for(size_t i = 0; i < encrypted_data_bits / 8; i++) {
  75. decrypted_data[i] = nescrypto1_byte(crypto, 0, 0) ^ encrypted_data[i];
  76. }
  77. }
  78. }
  79. void nescrypto1_encrypt(
  80. Crypto1* crypto,
  81. uint8_t* keystream,
  82. uint8_t* plain_data,
  83. uint16_t plain_data_bits,
  84. uint8_t* encrypted_data,
  85. uint8_t* encrypted_parity) {
  86. furi_assert(crypto);
  87. furi_assert(plain_data);
  88. furi_assert(encrypted_data);
  89. furi_assert(encrypted_parity);
  90. if(plain_data_bits < 8) {
  91. encrypted_data[0] = 0;
  92. for(size_t i = 0; i < plain_data_bits; i++) {
  93. encrypted_data[0] |= (nescrypto1_bit(crypto, 0, 0) ^ FURI_BIT(plain_data[0], i)) << i;
  94. }
  95. } else {
  96. memset(encrypted_parity, 0, plain_data_bits / 8 + 1);
  97. for(uint8_t i = 0; i < plain_data_bits / 8; i++) {
  98. encrypted_data[i] = nescrypto1_byte(crypto, keystream ? keystream[i] : 0, 0) ^
  99. plain_data[i];
  100. encrypted_parity[i / 8] |=
  101. (((nescrypto1_filter(crypto->odd) ^ oddparity8(plain_data[i])) & 0x01)
  102. << (7 - (i & 0x0007)));
  103. }
  104. }
  105. }