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