optimized_elite.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. //-----------------------------------------------------------------------------
  2. // Borrowed initially from https://github.com/holiman/loclass
  3. // Copyright (C) 2014 Martin Holst Swende
  4. // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
  5. //
  6. // This program is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // This program is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // See LICENSE.txt for the text of the license.
  17. //-----------------------------------------------------------------------------
  18. // WARNING
  19. //
  20. // THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY.
  21. //
  22. // USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL
  23. // PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL,
  24. // AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES.
  25. //
  26. // THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS.
  27. //-----------------------------------------------------------------------------
  28. // It is a reconstruction of the cipher engine used in iClass, and RFID techology.
  29. //
  30. // The implementation is based on the work performed by
  31. // Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and
  32. // Milosch Meriac in the paper "Dismantling IClass".
  33. //-----------------------------------------------------------------------------
  34. #include "optimized_elite.h"
  35. #include <stdint.h>
  36. #include <stdbool.h>
  37. #include <string.h>
  38. #include <mbedtls/des.h>
  39. #include "optimized_ikeys.h"
  40. /**
  41. * @brief Permutes a key from standard NIST format to Iclass specific format
  42. * from http://www.proxmark.org/forum/viewtopic.php?pid=11220#p11220
  43. *
  44. * If you loclass_permute [6c 8d 44 f9 2a 2d 01 bf] you get [8a 0d b9 88 bb a7 90 ea] as shown below.
  45. *
  46. * 1 0 1 1 1 1 1 1 bf
  47. * 0 0 0 0 0 0 0 1 01
  48. * 0 0 1 0 1 1 0 1 2d
  49. * 0 0 1 0 1 0 1 0 2a
  50. * 1 1 1 1 1 0 0 1 f9
  51. * 0 1 0 0 0 1 0 0 44
  52. * 1 0 0 0 1 1 0 1 8d
  53. * 0 1 1 0 1 1 0 0 6c
  54. *
  55. * 8 0 b 8 b a 9 e
  56. * a d 9 8 b 7 0 a
  57. *
  58. * @param key
  59. * @param dest
  60. */
  61. void loclass_permutekey(const uint8_t key[8], uint8_t dest[8]) {
  62. int i;
  63. for(i = 0; i < 8; i++) {
  64. dest[i] = (((key[7] & (0x80 >> i)) >> (7 - i)) << 7) |
  65. (((key[6] & (0x80 >> i)) >> (7 - i)) << 6) |
  66. (((key[5] & (0x80 >> i)) >> (7 - i)) << 5) |
  67. (((key[4] & (0x80 >> i)) >> (7 - i)) << 4) |
  68. (((key[3] & (0x80 >> i)) >> (7 - i)) << 3) |
  69. (((key[2] & (0x80 >> i)) >> (7 - i)) << 2) |
  70. (((key[1] & (0x80 >> i)) >> (7 - i)) << 1) |
  71. (((key[0] & (0x80 >> i)) >> (7 - i)) << 0);
  72. }
  73. }
  74. /**
  75. * Permutes a key from iclass specific format to NIST format
  76. * @brief loclass_permutekey_rev
  77. * @param key
  78. * @param dest
  79. */
  80. void loclass_permutekey_rev(const uint8_t key[8], uint8_t dest[8]) {
  81. int i;
  82. for(i = 0; i < 8; i++) {
  83. dest[7 - i] = (((key[0] & (0x80 >> i)) >> (7 - i)) << 7) |
  84. (((key[1] & (0x80 >> i)) >> (7 - i)) << 6) |
  85. (((key[2] & (0x80 >> i)) >> (7 - i)) << 5) |
  86. (((key[3] & (0x80 >> i)) >> (7 - i)) << 4) |
  87. (((key[4] & (0x80 >> i)) >> (7 - i)) << 3) |
  88. (((key[5] & (0x80 >> i)) >> (7 - i)) << 2) |
  89. (((key[6] & (0x80 >> i)) >> (7 - i)) << 1) |
  90. (((key[7] & (0x80 >> i)) >> (7 - i)) << 0);
  91. }
  92. }
  93. /**
  94. * Helper function for loclass_hash1
  95. * @brief loclass_rr
  96. * @param val
  97. * @return
  98. */
  99. static uint8_t loclass_rr(uint8_t val) {
  100. return val >> 1 | ((val & 1) << 7);
  101. }
  102. /**
  103. * Helper function for loclass_hash1
  104. * @brief rl
  105. * @param val
  106. * @return
  107. */
  108. static uint8_t loclass_rl(uint8_t val) {
  109. return val << 1 | ((val & 0x80) >> 7);
  110. }
  111. /**
  112. * Helper function for loclass_hash1
  113. * @brief loclass_swap
  114. * @param val
  115. * @return
  116. */
  117. static uint8_t loclass_swap(uint8_t val) {
  118. return ((val >> 4) & 0xFF) | ((val & 0xFF) << 4);
  119. }
  120. /**
  121. * Hash1 takes CSN as input, and determines what bytes in the keytable will be used
  122. * when constructing the K_sel.
  123. * @param csn the CSN used
  124. * @param k output
  125. */
  126. void loclass_hash1(const uint8_t csn[], uint8_t k[]) {
  127. k[0] = csn[0] ^ csn[1] ^ csn[2] ^ csn[3] ^ csn[4] ^ csn[5] ^ csn[6] ^ csn[7];
  128. k[1] = csn[0] + csn[1] + csn[2] + csn[3] + csn[4] + csn[5] + csn[6] + csn[7];
  129. k[2] = loclass_rr(loclass_swap(csn[2] + k[1]));
  130. k[3] = loclass_rl(loclass_swap(csn[3] + k[0]));
  131. k[4] = ~loclass_rr(csn[4] + k[2]) + 1;
  132. k[5] = ~loclass_rl(csn[5] + k[3]) + 1;
  133. k[6] = loclass_rr(csn[6] + (k[4] ^ 0x3c));
  134. k[7] = loclass_rl(csn[7] + (k[5] ^ 0xc3));
  135. k[7] &= 0x7F;
  136. k[6] &= 0x7F;
  137. k[5] &= 0x7F;
  138. k[4] &= 0x7F;
  139. k[3] &= 0x7F;
  140. k[2] &= 0x7F;
  141. k[1] &= 0x7F;
  142. k[0] &= 0x7F;
  143. }
  144. /**
  145. Definition 14. Define the rotate key function loclass_rk : (F 82 ) 8 × N → (F 82 ) 8 as
  146. loclass_rk(x [0] . . . x [7] , 0) = x [0] . . . x [7]
  147. loclass_rk(x [0] . . . x [7] , n + 1) = loclass_rk(loclass_rl(x [0] ) . . . loclass_rl(x [7] ), n)
  148. **/
  149. static void loclass_rk(const uint8_t* key, uint8_t n, uint8_t* outp_key) {
  150. memcpy(outp_key, key, 8);
  151. uint8_t j;
  152. while(n-- > 0) {
  153. for(j = 0; j < 8; j++) outp_key[j] = loclass_rl(outp_key[j]);
  154. }
  155. return;
  156. }
  157. static mbedtls_des_context loclass_ctx_enc;
  158. static mbedtls_des_context loclass_ctx_dec;
  159. static void loclass_desdecrypt_iclass(uint8_t* iclass_key, uint8_t* input, uint8_t* output) {
  160. uint8_t key_std_format[8] = {0};
  161. loclass_permutekey_rev(iclass_key, key_std_format);
  162. mbedtls_des_setkey_dec(&loclass_ctx_dec, key_std_format);
  163. mbedtls_des_crypt_ecb(&loclass_ctx_dec, input, output);
  164. }
  165. static void loclass_desencrypt_iclass(const uint8_t* iclass_key, uint8_t* input, uint8_t* output) {
  166. uint8_t key_std_format[8] = {0};
  167. loclass_permutekey_rev(iclass_key, key_std_format);
  168. mbedtls_des_setkey_enc(&loclass_ctx_enc, key_std_format);
  169. mbedtls_des_crypt_ecb(&loclass_ctx_enc, input, output);
  170. }
  171. /**
  172. * @brief Insert uint8_t[8] custom master key to calculate hash2 and return key_select.
  173. * @param key unpermuted custom key
  174. * @param loclass_hash1 loclass_hash1
  175. * @param key_sel output key_sel=h[loclass_hash1[i]]
  176. */
  177. void loclass_hash2(const uint8_t* key64, uint8_t* outp_keytable) {
  178. /**
  179. *Expected:
  180. * High Security Key Table
  181. 00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1
  182. 10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21
  183. 20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2
  184. 30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C
  185. 40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6
  186. 50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42
  187. 60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95
  188. 70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB
  189. **** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 ******/
  190. uint8_t key64_negated[8] = {0};
  191. uint8_t z[8][8] = {{0}, {0}};
  192. uint8_t temp_output[8] = {0};
  193. //calculate complement of key
  194. int i;
  195. for(i = 0; i < 8; i++) key64_negated[i] = ~key64[i];
  196. // Once again, key is on iclass-format
  197. loclass_desencrypt_iclass(key64, key64_negated, z[0]);
  198. uint8_t y[8][8] = {{0}, {0}};
  199. // y[0]=DES_dec(z[0],~key)
  200. // Once again, key is on iclass-format
  201. loclass_desdecrypt_iclass(z[0], key64_negated, y[0]);
  202. for(i = 1; i < 8; i++) {
  203. loclass_rk(key64, i, temp_output);
  204. loclass_desdecrypt_iclass(temp_output, z[i - 1], z[i]);
  205. loclass_desencrypt_iclass(temp_output, y[i - 1], y[i]);
  206. }
  207. if(outp_keytable != NULL) {
  208. for(i = 0; i < 8; i++) {
  209. memcpy(outp_keytable + i * 16, y[i], 8);
  210. memcpy(outp_keytable + 8 + i * 16, z[i], 8);
  211. }
  212. }
  213. }