optimized_cipher.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. //-----------------------------------------------------------------------------
  2. // Borrowed initially from https://github.com/holiman/loclass
  3. // More recently from https://github.com/RfidResearchGroup/proxmark3
  4. // Copyright (C) 2014 Martin Holst Swende
  5. // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
  6. //
  7. // This program is free software: you can redistribute it and/or modify
  8. // it under the terms of the GNU General Public License as published by
  9. // the Free Software Foundation, either version 3 of the License, or
  10. // (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. // GNU General Public License for more details.
  16. //
  17. // See LICENSE.txt for the text of the license.
  18. //-----------------------------------------------------------------------------
  19. // WARNING
  20. //
  21. // THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY.
  22. //
  23. // USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL
  24. // PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL,
  25. // AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES.
  26. //
  27. // THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS.
  28. //-----------------------------------------------------------------------------
  29. // It is a reconstruction of the cipher engine used in iClass, and RFID techology.
  30. //
  31. // The implementation is based on the work performed by
  32. // Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and
  33. // Milosch Meriac in the paper "Dismantling IClass".
  34. //-----------------------------------------------------------------------------
  35. #ifndef OPTIMIZED_CIPHER_H
  36. #define OPTIMIZED_CIPHER_H
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <stdbool.h>
  40. #include <stdint.h>
  41. /**
  42. * Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2
  43. * consisting of the following four components:
  44. * 1. the left register l = (l 0 . . . l 7 ) ∈ F 8/2 ;
  45. * 2. the right register r = (r 0 . . . r 7 ) ∈ F 8/2 ;
  46. * 3. the top register t = (t 0 . . . t 15 ) ∈ F 16/2 .
  47. * 4. the bottom register b = (b 0 . . . b 7 ) ∈ F 8/2 .
  48. **/
  49. typedef struct {
  50. uint8_t l;
  51. uint8_t r;
  52. uint8_t b;
  53. uint16_t t;
  54. } LoclassState_t;
  55. /** The reader MAC is MAC(key, CC * NR )
  56. **/
  57. void loclass_opt_doReaderMAC(uint8_t* cc_nr_p, uint8_t* div_key_p, uint8_t mac[4]);
  58. void loclass_opt_doReaderMAC_2(
  59. LoclassState_t _init,
  60. const uint8_t* nr,
  61. uint8_t mac[4],
  62. const uint8_t* div_key_p);
  63. /**
  64. * The tag MAC is MAC(key, CC * NR * 32x0))
  65. */
  66. void loclass_opt_doTagMAC(uint8_t* cc_p, const uint8_t* div_key_p, uint8_t mac[4]);
  67. /**
  68. * The tag MAC can be divided (both can, but no point in dividing the reader mac) into
  69. * two functions, since the first 8 bytes are known, we can pre-calculate the state
  70. * reached after feeding CC to the cipher.
  71. * @param cc_p
  72. * @param div_key_p
  73. * @return the cipher state
  74. */
  75. LoclassState_t loclass_opt_doTagMAC_1(uint8_t* cc_p, const uint8_t* div_key_p);
  76. /**
  77. * The second part of the tag MAC calculation, since the CC is already calculated into the state,
  78. * this function is fed only the NR, and internally feeds the remaining 32 0-bits to generate the tag
  79. * MAC response.
  80. * @param _init - precalculated cipher state
  81. * @param nr - the reader challenge
  82. * @param mac - where to store the MAC
  83. * @param div_key_p - the key to use
  84. */
  85. void loclass_opt_doTagMAC_2(
  86. LoclassState_t _init,
  87. const uint8_t* nr,
  88. uint8_t mac[4],
  89. const uint8_t* div_key_p);
  90. /**
  91. * The same as loclass_opt_doTagMAC_2, but calculates both the reader and tag MACs at the same time
  92. * @param _init - precalculated cipher state
  93. * @param nr - the reader challenge
  94. * @param rmac - where to store the reader MAC
  95. * @param tmac - where to store the tag MAC
  96. * @param div_key_p - the key to use
  97. */
  98. void loclass_opt_doBothMAC_2(
  99. LoclassState_t _init,
  100. const uint8_t* nr,
  101. uint8_t rmac[4],
  102. uint8_t tmac[4],
  103. const uint8_t* div_key_p);
  104. void loclass_doMAC_N(uint8_t* in_p, uint8_t in_size, uint8_t* div_key_p, uint8_t mac[4]);
  105. void loclass_iclass_calc_div_key(
  106. const uint8_t* csn,
  107. const uint8_t* key,
  108. uint8_t* div_key,
  109. bool elite);
  110. #endif // OPTIMIZED_CIPHER_H