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 
17 #include "crypto_toolbox.h"
18 
19 #include <bluetooth/log.h>
20 #include <endian.h>
21 
22 #include <algorithm>
23 
24 #include "hci/octets.h"
25 
26 using bluetooth::hci::kOctet16Length;
27 using bluetooth::hci::kOctet32Length;
28 using bluetooth::hci::Octet16;
29 
30 namespace crypto_toolbox {
31 
h6(const Octet16 & w,std::array<uint8_t,4> keyid)32 Octet16 h6(const Octet16& w, std::array<uint8_t, 4> keyid) {
33   return aes_cmac(w, keyid.data(), keyid.size());
34 }
35 
h7(const Octet16 & salt,const Octet16 & w)36 Octet16 h7(const Octet16& salt, const Octet16& w) {
37   return aes_cmac(salt, w.data(), w.size());
38 }
39 
f4(const uint8_t * u,const uint8_t * v,const Octet16 & x,uint8_t z)40 Octet16 f4(const uint8_t* u, const uint8_t* v, const Octet16& x, uint8_t z) {
41   constexpr size_t msg_len =
42       kOctet32Length /* U size */ + kOctet32Length /* V size */ + 1 /* Z size */;
43 
44 #if 0
45   log::verbose("U={}, V={}, X={}, Z={:x}", HexEncode(u, kOctet32Length),
46                HexEncode(v, kOctet32Length), HexEncode(x.data(), x.size()), z);
47 #endif
48 
49   std::array<uint8_t, msg_len> msg;
50   auto it = msg.begin();
51   it = std::copy(&z, &z + 1, it);
52   it = std::copy(v, v + kOctet32Length, it);
53   it = std::copy(u, u + kOctet32Length, it);
54   return aes_cmac(x, msg.data(), msg.size());
55 }
56 
57 /** helper for f5 */
calculate_mac_key_or_ltk(const Octet16 & t,uint8_t counter,uint8_t * key_id,const Octet16 & n1,const Octet16 & n2,uint8_t * a1,uint8_t * a2,uint8_t * length)58 static Octet16 calculate_mac_key_or_ltk(
59     const Octet16& t,
60     uint8_t counter,
61     uint8_t* key_id,
62     const Octet16& n1,
63     const Octet16& n2,
64     uint8_t* a1,
65     uint8_t* a2,
66     uint8_t* length) {
67   constexpr size_t msg_len = 1 /* Counter size */ + 4 /* keyID size */ +
68                              kOctet16Length /* N1 size */ + kOctet16Length /* N2 size */ +
69                              7 /* A1 size*/ + 7 /* A2 size*/ + 2 /* Length size */;
70 
71   std::array<uint8_t, msg_len> msg;
72   auto it = msg.begin();
73   it = std::copy(length, length + 2, it);
74   it = std::copy(a2, a2 + 7, it);
75   it = std::copy(a1, a1 + 7, it);
76   it = std::copy(n2.begin(), n2.end(), it);
77   it = std::copy(n1.begin(), n1.end(), it);
78   it = std::copy(key_id, key_id + 4, it);
79   it = std::copy(&counter, &counter + 1, it);
80 
81   return aes_cmac(t, msg.data(), msg.size());
82 }
83 
f5(const uint8_t * w,const Octet16 & n1,const Octet16 & n2,uint8_t * a1,uint8_t * a2,Octet16 * mac_key,Octet16 * ltk)84 void f5(
85     const uint8_t* w,
86     const Octet16& n1,
87     const Octet16& n2,
88     uint8_t* a1,
89     uint8_t* a2,
90     Octet16* mac_key,
91     Octet16* ltk) {
92 #if 0
93  log::verbose("W={}, N1={}, N2={}, A1={}, A2={}", HexEncode(w, kOctet32Length),
94               HexEncode(n1.data(), n1.size()), HexEncode(n2.data(), n2.size()),
95               HexEncode(a1, 7), HexEncode(a2, 7));
96 #endif
97 
98   const Octet16 salt{0xBE, 0x83, 0x60, 0x5A, 0xDB, 0x0B, 0x37, 0x60, 0x38, 0xA5, 0xF5, 0xAA, 0x91, 0x83, 0x88, 0x6C};
99   Octet16 t = aes_cmac(salt, w, kOctet32Length);
100 
101 #if 0
102   log::verbose("T={}", HexEncode(t.data(), t.size()));
103 #endif
104 
105   uint8_t key_id[4] = {0x65, 0x6c, 0x74, 0x62}; /* 0x62746c65 */
106   uint8_t length[2] = {0x00, 0x01};             /* 0x0100 */
107 
108   *mac_key = calculate_mac_key_or_ltk(t, 0, key_id, n1, n2, a1, a2, length);
109 
110   *ltk = calculate_mac_key_or_ltk(t, 1, key_id, n1, n2, a1, a2, length);
111 
112 #if 0
113   log::verbose("mac_key={}", HexEncode(mac_key->data(), mac_key->size()));
114   log::verbose("ltk={}", HexEncode(ltk->data(), ltk->size()));
115 #endif
116 }
117 
118 Octet16
f6(const Octet16 & w,const Octet16 & n1,const Octet16 & n2,const Octet16 & r,uint8_t * iocap,uint8_t * a1,uint8_t * a2)119 f6(const Octet16& w, const Octet16& n1, const Octet16& n2, const Octet16& r, uint8_t* iocap, uint8_t* a1, uint8_t* a2) {
120   const uint8_t msg_len = kOctet16Length /* N1 size */ + kOctet16Length /* N2 size */ +
121                           kOctet16Length /* R size */ + 3 /* IOcap size */ + 7 /* A1 size*/ +
122                           7 /* A2 size*/;
123 #if 0
124   log::verbose("W={}, N1={}, N2={}, R={}, IOcap={}, A1={}, A2={}",
125                HexEncode(w.data(), w.size()), HexEncode(n1.data(), n1.size()),
126                HexEncode(n2.data(), n2.size()), HexEncode(r.data(), r.size()),
127                HexEncode(iocap, 3), HexEncode(a1, 7), HexEncode(a2, 7));
128 #endif
129 
130   std::array<uint8_t, msg_len> msg;
131   auto it = msg.begin();
132   it = std::copy(a2, a2 + 7, it);
133   it = std::copy(a1, a1 + 7, it);
134   it = std::copy(iocap, iocap + 3, it);
135   it = std::copy(r.begin(), r.end(), it);
136   it = std::copy(n2.begin(), n2.end(), it);
137   it = std::copy(n1.begin(), n1.end(), it);
138 
139   return aes_cmac(w, msg.data(), msg.size());
140 }
141 
g2(const uint8_t * u,const uint8_t * v,const Octet16 & x,const Octet16 & y)142 uint32_t g2(const uint8_t* u, const uint8_t* v, const Octet16& x, const Octet16& y) {
143   constexpr size_t msg_len = kOctet32Length /* U size */ + kOctet32Length /* V size */
144                              + kOctet16Length /* Y size */;
145 #if 0
146   log::verbose("U={}, V={}, X={}, Y={}", HexEncode(u, kOctet32Length),
147                HexEncode(v, kOctet32Length), HexEncode(x.data(), x.size()),
148                HexEncode(y.data(), y.size()));
149 #endif
150 
151   std::array<uint8_t, msg_len> msg;
152   auto it = msg.begin();
153   it = std::copy(y.begin(), y.end(), it);
154   it = std::copy(v, v + kOctet32Length, it);
155   it = std::copy(u, u + kOctet32Length, it);
156 
157   Octet16 cmac = aes_cmac(x, msg.data(), msg.size());
158 
159   /* vres = cmac mod 2**32 mod 10**6 */
160   return le32toh(*(uint32_t*)cmac.data()) % 1000000;
161 }
162 
ltk_to_link_key(const Octet16 & ltk,bool use_h7)163 Octet16 ltk_to_link_key(const Octet16& ltk, bool use_h7) {
164   Octet16 ilk; /* intermidiate link key */
165   if (use_h7) {
166     constexpr Octet16 salt{
167         0x31, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
168     ilk = h7(salt, ltk);
169   } else {
170     /* "tmp1" mapping to extended ASCII, little endian*/
171     constexpr std::array<uint8_t, 4> keyID_tmp1 = {0x31, 0x70, 0x6D, 0x74};
172     ilk = h6(ltk, keyID_tmp1);
173   }
174 
175   /* "lebr" mapping to extended ASCII, little endian */
176   constexpr std::array<uint8_t, 4> keyID_lebr = {0x72, 0x62, 0x65, 0x6c};
177   return h6(ilk, keyID_lebr);
178 }
179 
link_key_to_ltk(const Octet16 & link_key,bool use_h7)180 Octet16 link_key_to_ltk(const Octet16& link_key, bool use_h7) {
181   Octet16 iltk; /* intermidiate long term key */
182   if (use_h7) {
183     constexpr Octet16 salt{
184         0x32, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
185     iltk = h7(salt, link_key);
186   } else {
187     /* "tmp2" mapping to extended ASCII, little endian */
188     constexpr std::array<uint8_t, 4> keyID_tmp2 = {0x32, 0x70, 0x6D, 0x74};
189     iltk = h6(link_key, keyID_tmp2);
190   }
191 
192   /* "brle" mapping to extended ASCII, little endian */
193   constexpr std::array<uint8_t, 4> keyID_brle = {0x65, 0x6c, 0x72, 0x62};
194   return h6(iltk, keyID_brle);
195 }
196 
c1(const Octet16 & k,const Octet16 & r,const uint8_t * preq,const uint8_t * pres,const uint8_t iat,const uint8_t * ia,const uint8_t rat,const uint8_t * ra)197 Octet16 c1(
198     const Octet16& k,
199     const Octet16& r,
200     const uint8_t* preq,
201     const uint8_t* pres,
202     const uint8_t iat,
203     const uint8_t* ia,
204     const uint8_t rat,
205     const uint8_t* ra) {
206   Octet16 p1;
207   auto it = p1.begin();
208   it = std::copy(&iat, &iat + 1, it);
209   it = std::copy(&rat, &rat + 1, it);
210   it = std::copy(preq, preq + 7, it);
211   it = std::copy(pres, pres + 7, it);
212 
213   for (uint8_t i = 0; i < kOctet16Length; i++) {
214     p1[i] = r[i] ^ p1[i];
215   }
216 
217   Octet16 p1bis = aes_128(k, p1);
218 
219   std::array<uint8_t, 4> padding{0};
220   Octet16 p2;
221   it = p2.begin();
222   it = std::copy(ra, ra + 6, it);
223   it = std::copy(ia, ia + 6, it);
224   it = std::copy(padding.begin(), padding.end(), it);
225 
226   for (uint8_t i = 0; i < kOctet16Length; i++) {
227     p2[i] = p1bis[i] ^ p2[i];
228   }
229 
230   return aes_128(k, p2);
231 }
232 
s1(const Octet16 & k,const Octet16 & r1,const Octet16 & r2)233 Octet16 s1(const Octet16& k, const Octet16& r1, const Octet16& r2) {
234   Octet16 text{0};
235   memcpy(text.data(), r1.data(), kOctet16Length / 2);
236   memcpy(text.data() + kOctet16Length / 2, r2.data(), kOctet16Length / 2);
237 
238   return aes_128(k, text);
239 }
240 
241 }  // namespace crypto_toolbox
242