keeloq_common.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "keeloq_common.h"
  2. #include <furi.h>
  3. #include <m-string.h>
  4. #include <m-array.h>
  5. /** Simple Learning Encrypt
  6. * @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
  7. * @param key - manufacture (64bit)
  8. * @return keeloq encrypt data
  9. */
  10. inline uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key) {
  11. uint32_t x = data, r;
  12. for(r = 0; r < 528; r++)
  13. x = (x >> 1) ^ ((bit(x, 0) ^ bit(x, 16) ^ (uint32_t)bit(key, r & 63) ^
  14. bit(KEELOQ_NLF, g5(x, 1, 9, 20, 26, 31)))
  15. << 31);
  16. return x;
  17. }
  18. /** Simple Learning Decrypt
  19. * @param data - keelog encrypt data
  20. * @param key - manufacture (64bit)
  21. * @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
  22. */
  23. inline uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key) {
  24. uint32_t x = data, r;
  25. for(r = 0; r < 528; r++)
  26. x = (x << 1) ^ bit(x, 31) ^ bit(x, 15) ^ (uint32_t)bit(key, (15 - r) & 63) ^
  27. bit(KEELOQ_NLF, g5(x, 0, 8, 19, 25, 30));
  28. return x;
  29. }
  30. /** Normal Learning
  31. * @param data - serial number (28bit)
  32. * @param key - manufacture (64bit)
  33. * @return manufacture for this serial number (64bit)
  34. */
  35. inline uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key) {
  36. uint32_t k1, k2;
  37. data &= 0x0FFFFFFF;
  38. data |= 0x20000000;
  39. k1 = subghz_protocol_keeloq_common_decrypt(data, key);
  40. data &= 0x0FFFFFFF;
  41. data |= 0x60000000;
  42. k2 = subghz_protocol_keeloq_common_decrypt(data, key);
  43. return ((uint64_t)k2 << 32) | k1; // key - shifrovanoya
  44. }
  45. /** Secure Learning
  46. * @param data - serial number (28bit)
  47. * @param seed - seed number (32bit)
  48. * @param key - manufacture (64bit)
  49. * @return manufacture for this serial number (64bit)
  50. */
  51. inline uint64_t subghz_protocol_keeloq_common_secure_learning(
  52. uint32_t data,
  53. uint32_t seed,
  54. const uint64_t key) {
  55. uint32_t k1, k2;
  56. data &= 0x0FFFFFFF;
  57. k1 = subghz_protocol_keeloq_common_decrypt(data, key);
  58. k2 = subghz_protocol_keeloq_common_decrypt(seed, key);
  59. return ((uint64_t)k1 << 32) | k2;
  60. }
  61. /** Magic_xor_type1 Learning
  62. * @param data - serial number (28bit)
  63. * @param xor - magic xor (64bit)
  64. * @return manufacture for this serial number (64bit)
  65. */
  66. inline uint64_t
  67. subghz_protocol_keeloq_common_magic_xor_type1_learning(uint32_t data, uint64_t xor) {
  68. data &= 0x0FFFFFFF;
  69. return (((uint64_t)data << 32) | data) ^ xor;
  70. }