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