crypto_toolbox.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (C) 2018 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "stack/crypto_toolbox/crypto_toolbox.h"
  17. #include "stack/crypto_toolbox/aes.h"
  18. #include <algorithm>
  19. #include <base/logging.h>
  20. #include <base/strings/string_number_conversions.h>
  21. using base::HexEncode;
  22. namespace crypto_toolbox {
  23. Octet16 h6(const Octet16& w, std::array<uint8_t, 4> keyid) {
  24. return aes_cmac(w, keyid.data(), keyid.size());
  25. }
  26. Octet16 h7(const Octet16& salt, const Octet16& w) {
  27. return aes_cmac(salt, w.data(), w.size());
  28. }
  29. Octet16 f4(uint8_t* u, uint8_t* v, const Octet16& x, uint8_t z) {
  30. constexpr size_t msg_len = BT_OCTET32_LEN /* U size */ +
  31. BT_OCTET32_LEN /* V size */ + 1 /* Z size */;
  32. DVLOG(2) << "U=" << HexEncode(u, BT_OCTET32_LEN)
  33. << ", V=" << HexEncode(v, BT_OCTET32_LEN)
  34. << ", X=" << HexEncode(x.data(), x.size()) << ", Z=" << std::hex
  35. << +z;
  36. std::array<uint8_t, msg_len> msg;
  37. auto it = msg.begin();
  38. it = std::copy(&z, &z + 1, it);
  39. it = std::copy(v, v + BT_OCTET32_LEN, it);
  40. it = std::copy(u, u + BT_OCTET32_LEN, it);
  41. return aes_cmac(x, msg.data(), msg.size());
  42. }
  43. /** helper for f5 */
  44. static Octet16 calculate_mac_key_or_ltk(const Octet16& t, uint8_t counter,
  45. uint8_t* key_id, const Octet16& n1,
  46. const Octet16& n2, uint8_t* a1,
  47. uint8_t* a2, uint8_t* length) {
  48. constexpr size_t msg_len = 1 /* Counter size */ + 4 /* keyID size */ +
  49. OCTET16_LEN /* N1 size */ +
  50. OCTET16_LEN /* N2 size */ + 7 /* A1 size*/ +
  51. 7 /* A2 size*/ + 2 /* Length size */;
  52. std::array<uint8_t, msg_len> msg;
  53. auto it = msg.begin();
  54. it = std::copy(length, length + 2, it);
  55. it = std::copy(a2, a2 + 7, it);
  56. it = std::copy(a1, a1 + 7, it);
  57. it = std::copy(n2.begin(), n2.end(), it);
  58. it = std::copy(n1.begin(), n1.end(), it);
  59. it = std::copy(key_id, key_id + 4, it);
  60. it = std::copy(&counter, &counter + 1, it);
  61. return aes_cmac(t, msg.data(), msg.size());
  62. }
  63. void f5(uint8_t* w, const Octet16& n1, const Octet16& n2, uint8_t* a1,
  64. uint8_t* a2, Octet16* mac_key, Octet16* ltk) {
  65. DVLOG(2) << __func__ << "W=" << HexEncode(w, BT_OCTET32_LEN)
  66. << ", N1=" << HexEncode(n1.data(), n1.size())
  67. << ", N2=" << HexEncode(n2.data(), n2.size())
  68. << ", A1=" << HexEncode(a1, 7) << ", A2=" << HexEncode(a2, 7);
  69. const Octet16 salt{0xBE, 0x83, 0x60, 0x5A, 0xDB, 0x0B, 0x37, 0x60,
  70. 0x38, 0xA5, 0xF5, 0xAA, 0x91, 0x83, 0x88, 0x6C};
  71. Octet16 t = aes_cmac(salt, w, BT_OCTET32_LEN);
  72. DVLOG(2) << "T=" << HexEncode(t.data(), t.size());
  73. uint8_t key_id[4] = {0x65, 0x6c, 0x74, 0x62}; /* 0x62746c65 */
  74. uint8_t length[2] = {0x00, 0x01}; /* 0x0100 */
  75. *mac_key = calculate_mac_key_or_ltk(t, 0, key_id, n1, n2, a1, a2, length);
  76. *ltk = calculate_mac_key_or_ltk(t, 1, key_id, n1, n2, a1, a2, length);
  77. DVLOG(2) << "mac_key=" << HexEncode(mac_key->data(), mac_key->size());
  78. DVLOG(2) << "ltk=" << HexEncode(ltk->data(), ltk->size());
  79. }
  80. Octet16 f6(const Octet16& w, const Octet16& n1, const Octet16& n2,
  81. const Octet16& r, uint8_t* iocap, uint8_t* a1, uint8_t* a2) {
  82. const uint8_t msg_len = OCTET16_LEN /* N1 size */ +
  83. OCTET16_LEN /* N2 size */ + OCTET16_LEN /* R size */ +
  84. 3 /* IOcap size */ + 7 /* A1 size*/
  85. + 7 /* A2 size*/;
  86. DVLOG(2) << __func__ << "W=" << HexEncode(w.data(), w.size())
  87. << ", N1=" << HexEncode(n1.data(), n1.size())
  88. << ", N2=" << HexEncode(n2.data(), n2.size())
  89. << ", R=" << HexEncode(r.data(), r.size())
  90. << ", IOcap=" << HexEncode(iocap, 3) << ", A1=" << HexEncode(a1, 7)
  91. << ", A2=" << HexEncode(a2, 7);
  92. std::array<uint8_t, msg_len> msg;
  93. auto it = msg.begin();
  94. it = std::copy(a2, a2 + 7, it);
  95. it = std::copy(a1, a1 + 7, it);
  96. it = std::copy(iocap, iocap + 3, it);
  97. it = std::copy(r.begin(), r.end(), it);
  98. it = std::copy(n2.begin(), n2.end(), it);
  99. it = std::copy(n1.begin(), n1.end(), it);
  100. return aes_cmac(w, msg.data(), msg.size());
  101. }
  102. uint32_t g2(uint8_t* u, uint8_t* v, const Octet16& x, const Octet16& y) {
  103. constexpr size_t msg_len = BT_OCTET32_LEN /* U size */ +
  104. BT_OCTET32_LEN /* V size */
  105. + OCTET16_LEN /* Y size */;
  106. DVLOG(2) << __func__ << "U=" << HexEncode(u, BT_OCTET32_LEN)
  107. << ", V=" << HexEncode(v, BT_OCTET32_LEN)
  108. << ", X=" << HexEncode(x.data(), x.size())
  109. << ", Y=" << HexEncode(y.data(), y.size());
  110. std::array<uint8_t, msg_len> msg;
  111. auto it = msg.begin();
  112. it = std::copy(y.begin(), y.end(), it);
  113. it = std::copy(v, v + BT_OCTET32_LEN, it);
  114. it = std::copy(u, u + BT_OCTET32_LEN, it);
  115. Octet16 cmac = aes_cmac(x, msg.data(), msg.size());
  116. /* vres = cmac mod 2**32 mod 10**6 */
  117. uint32_t vres;
  118. uint8_t* p = cmac.data();
  119. STREAM_TO_UINT32(vres, p);
  120. vres = vres % 1000000;
  121. return vres;
  122. }
  123. Octet16 ltk_to_link_key(const Octet16& ltk, bool use_h7) {
  124. Octet16 ilk; /* intermidiate link key */
  125. if (use_h7) {
  126. constexpr Octet16 salt{0x31, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00,
  127. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  128. ilk = h7(salt, ltk);
  129. } else {
  130. /* "tmp1" mapping to extended ASCII, little endian*/
  131. constexpr std::array<uint8_t, 4> keyID_tmp1 = {0x31, 0x70, 0x6D, 0x74};
  132. ilk = h6(ltk, keyID_tmp1);
  133. }
  134. /* "lebr" mapping to extended ASCII, little endian */
  135. constexpr std::array<uint8_t, 4> keyID_lebr = {0x72, 0x62, 0x65, 0x6c};
  136. return h6(ilk, keyID_lebr);
  137. }
  138. Octet16 link_key_to_ltk(const Octet16& link_key, bool use_h7) {
  139. Octet16 iltk; /* intermidiate long term key */
  140. if (use_h7) {
  141. constexpr Octet16 salt{0x32, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00,
  142. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  143. iltk = h7(salt, link_key);
  144. } else {
  145. /* "tmp2" mapping to extended ASCII, little endian */
  146. constexpr std::array<uint8_t, 4> keyID_tmp2 = {0x32, 0x70, 0x6D, 0x74};
  147. iltk = h6(link_key, keyID_tmp2);
  148. }
  149. /* "brle" mapping to extended ASCII, little endian */
  150. constexpr std::array<uint8_t, 4> keyID_brle = {0x65, 0x6c, 0x72, 0x62};
  151. return h6(iltk, keyID_brle);
  152. }
  153. } // namespace crypto_toolbox