+crypto_toolbox_srcs = [
+ "crypto_toolbox/aes.cc",
+ "crypto_toolbox/aes_cmac.cc",
+ "crypto_toolbox/crypto_toolbox.cc",
+]
+
// Bluetooth stack static library for target
// ========================================================
cc_library_static {
"system/bt/bta/sys",
"system/bt/utils/include",
],
- srcs: [
+ srcs: crypto_toolbox_srcs + [
"a2dp/a2dp_aac.cc",
"a2dp/a2dp_aac_decoder.cc",
"a2dp/a2dp_aac_encoder.cc",
"sdp/sdp_main.cc",
"sdp/sdp_server.cc",
"sdp/sdp_utils.cc",
- "smp/crypto_toolbox.cc",
- "smp/aes.cc",
"smp/p_256_curvepara.cc",
"smp/p_256_ecc_pp.cc",
"smp/p_256_multprecision.cc",
"smp/smp_act.cc",
"smp/smp_api.cc",
"smp/smp_br_main.cc",
- "smp/smp_cmac.cc",
"smp/smp_keys.cc",
"smp/smp_l2c.cc",
"smp/smp_main.cc",
required: [
"libldacBT_enc",
"libldacBT_abr",
- ]
+ ],
}
// Bluetooth stack unit tests for target
}
cc_test {
- name: "net_test_stack_rfcomm",
- defaults: ["fluoride_defaults"],
- host_supported: true,
- local_include_dirs: [
- "include",
- "btm",
- "l2cap",
- "smp",
- "rfcomm",
- "test/common",
- ],
- include_dirs: [
- "system/bt",
- "system/bt/internal_include",
- "system/bt/btcore/include",
- "system/bt/hci/include",
- "system/bt/utils/include",
- ],
- srcs: [
- "rfcomm/port_api.cc",
- "rfcomm/port_rfc.cc",
- "rfcomm/port_utils.cc",
- "rfcomm/rfc_l2cap_if.cc",
- "rfcomm/rfc_mx_fsm.cc",
- "rfcomm/rfc_port_fsm.cc",
- "rfcomm/rfc_port_if.cc",
- "rfcomm/rfc_ts_frames.cc",
- "rfcomm/rfc_utils.cc",
- "test/common/mock_btm_layer.cc",
- "test/common/mock_btu_layer.cc",
- "test/common/mock_l2cap_layer.cc",
- "test/common/stack_test_packet_utils.cc",
- "test/rfcomm/stack_rfcomm_test.cc",
- "test/rfcomm/stack_rfcomm_test_main.cc",
- "test/rfcomm/stack_rfcomm_test_utils.cc",
- "test/rfcomm/stack_rfcomm_test_utils_test.cc",
- ],
- shared_libs: [
- "libcutils",
- "libprotobuf-cpp-lite",
- ],
- static_libs: [
- "liblog",
- "libgmock",
- "libosi",
- "libbt-protos-lite",
- ],
+ name: "net_test_stack_rfcomm",
+ defaults: ["fluoride_defaults"],
+ host_supported: true,
+ local_include_dirs: [
+ "include",
+ "btm",
+ "l2cap",
+ "smp",
+ "rfcomm",
+ "test/common",
+ ],
+ include_dirs: [
+ "system/bt",
+ "system/bt/internal_include",
+ "system/bt/btcore/include",
+ "system/bt/hci/include",
+ "system/bt/utils/include",
+ ],
+ srcs: [
+ "rfcomm/port_api.cc",
+ "rfcomm/port_rfc.cc",
+ "rfcomm/port_utils.cc",
+ "rfcomm/rfc_l2cap_if.cc",
+ "rfcomm/rfc_mx_fsm.cc",
+ "rfcomm/rfc_port_fsm.cc",
+ "rfcomm/rfc_port_if.cc",
+ "rfcomm/rfc_ts_frames.cc",
+ "rfcomm/rfc_utils.cc",
+ "test/common/mock_btm_layer.cc",
+ "test/common/mock_btu_layer.cc",
+ "test/common/mock_l2cap_layer.cc",
+ "test/common/stack_test_packet_utils.cc",
+ "test/rfcomm/stack_rfcomm_test.cc",
+ "test/rfcomm/stack_rfcomm_test_main.cc",
+ "test/rfcomm/stack_rfcomm_test_utils.cc",
+ "test/rfcomm/stack_rfcomm_test_utils_test.cc",
+ ],
+ shared_libs: [
+ "libcutils",
+ "libprotobuf-cpp-lite",
+ ],
+ static_libs: [
+ "liblog",
+ "libgmock",
+ "libosi",
+ "libbt-protos-lite",
+ ],
}
// Bluetooth stack smp unit tests for target
"system/bt/hci/include",
"system/bt/utils/include",
],
- srcs: [
+ srcs: crypto_toolbox_srcs + [
"smp/smp_keys.cc",
- "smp/crypto_toolbox.cc",
- "smp/aes.cc",
+ "smp/p_256_curvepara.cc",
+ "smp/p_256_ecc_pp.cc",
+ "smp/p_256_multprecision.cc",
"smp/smp_api.cc",
- "smp/smp_cmac.cc",
"smp/smp_main.cc",
"smp/smp_utils.cc",
- "test/stack_smp_test.cc",
"test/crypto_toolbox_test.cc",
+ "test/stack_smp_test.cc",
],
shared_libs: [
"libcutils",
],
}
-
// Bluetooth stack multi-advertising unit tests for target
// ========================================================
cc_test {
# limitations under the License.
#
+static_library("crypto_toolbox") {
+ sources = [
+ "crypto_toolbox/crypto_toolbox.cc",
+ "crypto_toolbox/aes.cc",
+ "crypto_toolbox/aes_cmac.cc",
+ ]
+
+ include_dirs = [
+ "//",
+ ]
+
+ deps = [
+ "//third_party/libchrome:base",
+ ]
+}
+
static_library("stack") {
sources = [
"a2dp/a2dp_aac.cc",
"sdp/sdp_main.cc",
"sdp/sdp_server.cc",
"sdp/sdp_utils.cc",
- "smp/aes.cc",
"smp/p_256_curvepara.cc",
"smp/p_256_ecc_pp.cc",
"smp/p_256_multprecision.cc",
"smp/smp_act.cc",
"smp/smp_api.cc",
"smp/smp_br_main.cc",
- "smp/smp_cmac.cc",
"smp/smp_keys.cc",
"smp/smp_l2c.cc",
"smp/smp_main.cc",
]
deps = [
+ ":crypto_toolbox",
"//types",
"//third_party/libchrome:base",
"//third_party/libldac:libldacBT_enc",
]
}
+executable("net_test_stack_crypto_toolbox") {
+ testonly = true
+ sources = [
+ "test/crypto_toolbox_test.cc",
+ ]
+
+ include_dirs = [
+ "//",
+ ]
+
+ deps = [
+ ":crypto_toolbox",
+ "//third_party/googletest:gmock_main",
+ "//third_party/libchrome:base",
+ ]
+}
+
+executable("net_test_stack_smp") {
+ testonly = true
+ sources = [
+ "smp/smp_keys.cc",
+ "smp/smp_api.cc",
+ "smp/smp_main.cc",
+ "smp/smp_utils.cc",
+ "test/stack_smp_test.cc",
+ ]
+
+ include_dirs = [
+ "//",
+ "//internal_include",
+ "//btcore/include",
+ "//hci/include",
+ "//utils/include",
+ "//bta/include",
+ "//bta/sys",
+ "//btcore/include",
+ "//embdrv/sbc/encoder/include",
+ "//hci/include",
+ "//internal_include",
+ "//stack/a2dp",
+ "//stack/l2cap",
+ "//stack/btm",
+ "//stack/include",
+ "//third_party/tinyxml2",
+ "//udrv/include",
+ "//utils/include",
+ "//vnd/include"
+ ]
+
+ libs = [
+ "-ldl",
+ "-lpthread",
+ "-lresolv",
+ "-lrt",
+ "-lz",
+ "-latomic",
+ ]
+
+ deps = [
+ ":crypto_toolbox",
+ "//osi",
+ "//types",
+ "//third_party/googletest:gmock_main",
+ "//third_party/libchrome:base",
+ ]
+}
+
executable("net_test_stack_multi_adv") {
testonly = true
sources = [
#include "l2c_int.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
-#include "smp_api.h"
+#include "stack/crypto_toolbox/crypto_toolbox.h"
extern void gatt_notify_phy_updated(uint8_t status, uint16_t handle,
uint8_t tx_phy, uint8_t rx_phy);
UINT32_TO_STREAM(pp, p_rec->ble.keys.local_counter);
UINT32_TO_STREAM(p_mac, p_rec->ble.keys.local_counter);
- aes_cipher_msg_auth_code(p_rec->ble.keys.lcsrk, p_buf, (uint16_t)(len + 4),
+ crypto_toolbox::aes_cmac(p_rec->ble.keys.lcsrk, p_buf, (uint16_t)(len + 4),
BTM_CMAC_TLEN_SIZE, p_mac);
btm_ble_increment_sign_ctr(bd_addr, true);
BTM_TRACE_DEBUG("%s rcv_cnt=%d >= expected_cnt=%d", __func__, counter,
p_rec->ble.keys.counter);
- aes_cipher_msg_auth_code(p_rec->ble.keys.pcsrk, p_orig, len,
+ crypto_toolbox::aes_cmac(p_rec->ble.keys.pcsrk, p_orig, len,
BTM_CMAC_TLEN_SIZE, p_mac);
if (memcmp(p_mac, p_comp, BTM_CMAC_TLEN_SIZE) == 0) {
btm_ble_increment_sign_ctr(bd_addr, false);
/* generate DHK= Eir({0x03, 0x00, 0x00 ...}) */
btm_cb.devcb.id_keys.dhk =
- SMP_Encrypt(btm_cb.devcb.id_keys.ir, &btm_ble_dhk_pt, 1);
+ crypto_toolbox::aes_128(btm_cb.devcb.id_keys.ir, &btm_ble_dhk_pt, 1);
uint8_t btm_ble_irk_pt = 0x01;
/* IRK = D1(IR, 1) */
btm_cb.devcb.id_keys.irk =
- SMP_Encrypt(btm_cb.devcb.id_keys.ir, &btm_ble_irk_pt, 1);
+ crypto_toolbox::aes_128(btm_cb.devcb.id_keys.ir, &btm_ble_irk_pt, 1);
btm_notify_new_key(BTM_BLE_KEY_TYPE_ID);
#include "hcimsgs.h"
#include "btm_ble_int.h"
-#include "smp_api.h"
+#include "stack/crypto_toolbox/crypto_toolbox.h"
/* This function generates Resolvable Private Address (RPA) from Identity
* Resolving Key |irk| and |random|*/
address.address[0] = random[2];
/* encrypt with IRK */
- Octet16 p = SMP_Encrypt(irk, random, 3);
+ Octet16 p = crypto_toolbox::aes_128(irk, random, 3);
/* set hash to be LSB of rpAddress */
address.address[5] = p[0];
rand[2] = rpa.address[0];
/* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */
- Octet16 x = SMP_Encrypt(irk, &rand[0], 3);
+ Octet16 x = crypto_toolbox::aes_128(irk, &rand[0], 3);
rand[0] = rpa.address[5];
rand[1] = rpa.address[4];
#endif
#endif
+#include <stdint.h>
#include <stdlib.h>
-/* add the target configuration to allow using internal data types and
- * compilation options */
-#include "bt_target.h"
-
/* define if you have fast 32-bit types on your system */
#if 1
#define HAVE_UINT_32T
/******************************************************************************
*
- * This file contains the implementation of the AES128 CMAC algorithm.
+ * This file contains the implementation of the AES128 and AES CMAC algorithm.
*
******************************************************************************/
-#include "bt_target.h"
+#include "stack/crypto_toolbox/aes.h"
+#include "stack/crypto_toolbox/crypto_toolbox.h"
-#include <stdio.h>
-#include <string.h>
+#include <base/logging.h>
+#include <base/strings/string_number_conversions.h>
-#include "btm_ble_api.h"
-#include "hcimsgs.h"
-#include "smp_int.h"
+namespace crypto_toolbox {
+
+namespace {
typedef struct {
uint8_t* text;
Octet16 const_Rb{0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-void print128(const Octet16& x, const uint8_t* key_name) {
-#if (SMP_DEBUG == TRUE && SMP_DEBUG_VERBOSE == TRUE)
- uint8_t* p = (uint8_t*)x;
- uint8_t i;
-
- SMP_TRACE_WARNING("%s(MSB ~ LSB) = ", key_name);
+/** utility function to do an biteise exclusive-OR of two bit strings of the
+ * length of OCTET16_LEN. Result is stored in first argument.
+ */
+static void xor_128(Octet16* a, const Octet16& b) {
+ CHECK(a);
+ uint8_t i, *aa = a->data();
+ const uint8_t* bb = b.data();
- for (i = 0; i < 4; i++) {
- SMP_TRACE_WARNING("%02x %02x %02x %02x", p[OCTET16_LEN - i * 4 - 1],
- p[OCTET16_LEN - i * 4 - 2], p[OCTET16_LEN - i * 4 - 3],
- p[OCTET16_LEN - i * 4 - 4]);
+ for (i = 0; i < OCTET16_LEN; i++) {
+ aa[i] = aa[i] ^ bb[i];
}
-#endif
+}
+} // namespace
+
+/* This function computes AES_128(key, message) */
+Octet16 aes_128(const Octet16& key, const Octet16& message) {
+ Octet16 key_reversed;
+ Octet16 message_reversed;
+ Octet16 output;
+
+ std::reverse_copy(key.begin(), key.end(), key_reversed.begin());
+ std::reverse_copy(message.begin(), message.end(), message_reversed.begin());
+
+ aes_context ctx;
+ aes_set_key(key_reversed.data(), key_reversed.size(), &ctx);
+ aes_encrypt(message_reversed.data(), output.data(), &ctx);
+
+ std::reverse(output.begin(), output.end());
+ return output;
}
/** utility function to padding the given text to be a 128 bits data. The
/** utility function to left shift one bit for a 128 bits value. */
static void leftshift_onebit(uint8_t* input, uint8_t* output) {
uint8_t i, overflow = 0, next_overflow = 0;
- SMP_TRACE_EVENT("leftshift_onebit ");
+ DVLOG(2) << __func__;
/* input[0] is LSB */
for (i = 0; i < OCTET16_LEN; i++) {
next_overflow = (input[i] & 0x80) ? 1 : 0;
return;
}
-/** clean up function for AES_CMAC algorithm. */
-static void cmac_aes_cleanup(void) {
- osi_free(cmac_cb.text);
- memset(&cmac_cb, 0, sizeof(tCMAC_CB));
-}
-
/** This function is the calculation of block cipher using AES-128. */
-static void cmac_aes_k_calculate(const Octet16& key, uint8_t* p_signature,
- uint16_t tlen) {
+static Octet16 cmac_aes_k_calculate(const Octet16& key) {
Octet16 output;
Octet16 x{0}; // zero initialized
- SMP_TRACE_EVENT("cmac_aes_k_calculate ");
+ DVLOG(2) << __func__;
uint8_t i = 1;
while (i <= cmac_cb.round) {
/* Mi' := Mi (+) X */
- smp_xor_128((Octet16*)&cmac_cb.text[(cmac_cb.round - i) * OCTET16_LEN], x);
+ xor_128((Octet16*)&cmac_cb.text[(cmac_cb.round - i) * OCTET16_LEN], x);
- output = SMP_Encrypt(key, &cmac_cb.text[(cmac_cb.round - i) * OCTET16_LEN],
- OCTET16_LEN);
+ output = aes_128(key, &cmac_cb.text[(cmac_cb.round - i) * OCTET16_LEN],
+ OCTET16_LEN);
x = output;
i++;
}
- uint8_t* p_mac = output.data() + (OCTET16_LEN - tlen);
- memcpy(p_signature, p_mac, tlen);
-
- SMP_TRACE_DEBUG("tlen = %d p_mac = %d", tlen, p_mac);
- SMP_TRACE_DEBUG(
- "p_mac[0] = 0x%02x p_mac[1] = 0x%02x p_mac[2] = 0x%02x p_mac[3] = "
- "0x%02x",
- *p_mac, *(p_mac + 1), *(p_mac + 2), *(p_mac + 3));
- SMP_TRACE_DEBUG(
- "p_mac[4] = 0x%02x p_mac[5] = 0x%02x p_mac[6] = 0x%02x p_mac[7] = "
- "0x%02x",
- *(p_mac + 4), *(p_mac + 5), *(p_mac + 6), *(p_mac + 7));
+ return output;
}
/** This function proceeed to prepare the last block of message Mn depending on
// uint8_t x[16] = {0};
bool flag;
- SMP_TRACE_EVENT("cmac_prepare_last_block ");
+ DVLOG(2) << __func__;
/* last block is a complete block set flag to 1 */
flag = ((cmac_cb.len % OCTET16_LEN) == 0 && cmac_cb.len != 0) ? true : false;
- SMP_TRACE_WARNING("flag = %d round = %d", flag, cmac_cb.round);
+ DVLOG(2) << "flag=" << flag << " round=" << cmac_cb.round;
if (flag) { /* last block is complete block */
- smp_xor_128((Octet16*)&cmac_cb.text[0], k1);
+ xor_128((Octet16*)&cmac_cb.text[0], k1);
} else /* padding then xor with k2 */
{
padding((Octet16*)&cmac_cb.text[0], (uint8_t)(cmac_cb.len % 16));
- smp_xor_128((Octet16*)&cmac_cb.text[0], k2);
+ xor_128((Octet16*)&cmac_cb.text[0], k2);
}
}
* |key| is CMAC key, expect SRK when used by SMP.
*/
static void cmac_generate_subkey(const Octet16& key) {
- SMP_TRACE_EVENT(" cmac_generate_subkey");
+ DVLOG(2) << __func__;
Octet16 zero{};
- Octet16 p = SMP_Encrypt(key, zero.data(), OCTET16_LEN);
- print128(p, (const uint8_t*)"K1 before shift");
+ Octet16 p = aes_128(key, zero.data(), OCTET16_LEN);
Octet16 k1, k2;
uint8_t* pp = p.data();
if ((pp[OCTET16_LEN - 1] & 0x80) != 0) {
/* Else K1 = ( L << 1 ) (+) Rb */
leftshift_onebit(pp, k1.data());
- smp_xor_128(&k1, const_Rb);
+ xor_128(&k1, const_Rb);
} else {
leftshift_onebit(pp, k1.data());
}
if ((k1[OCTET16_LEN - 1] & 0x80) != 0) {
/* K2 = (K1 << 1) (+) Rb */
leftshift_onebit(k1.data(), k2.data());
- smp_xor_128(&k2, const_Rb);
+ xor_128(&k2, const_Rb);
} else {
/* If MSB(K1) = 0, then K2 = K1 << 1 */
leftshift_onebit(k1.data(), k2.data());
}
- print128(k1, (const uint8_t*)"K1");
- print128(k2, (const uint8_t*)"K2");
-
cmac_prepare_last_block(k1, k2);
}
-/*******************************************************************************
- *
- * Function aes_cipher_msg_auth_code
- *
- * Description This is the AES-CMAC Generation Function with tlen
- * implemented.
- *
- * Parameters key - CMAC key in little endian order, expect SRK when used
- * by SMP.
- * input - text to be signed in little endian byte order.
- * length - length of the input in byte.
- * tlen - lenth of mac desired
- * p_signature - data pointer to where signed data to be
- * stored, tlen long.
- *
- ******************************************************************************/
-void aes_cipher_msg_auth_code(const Octet16& key, const uint8_t* input,
- uint16_t length, uint16_t tlen,
- uint8_t* p_signature) {
+
+/** key - CMAC key in little endian order
+ * input - text to be signed in little endian byte order.
+ * length - length of the input in byte.
+ */
+Octet16 aes_cmac(const Octet16& key, const uint8_t* input, uint16_t length) {
uint16_t len, diff;
/* n is number of rounds */
uint16_t n = (length + OCTET16_LEN - 1) / OCTET16_LEN;
- SMP_TRACE_EVENT("%s", __func__);
+ DVLOG(2) << __func__;
if (n == 0) n = 1;
len = n * OCTET16_LEN;
- SMP_TRACE_WARNING("AES128_CMAC started, allocate buffer size = %d", len);
+ DVLOG(2) << "AES128_CMAC started, allocate buffer size=" << len;
/* allocate a memory space of multiple of 16 bytes to hold text */
- cmac_cb.text = (uint8_t*)osi_calloc(len);
+ cmac_cb.text = (uint8_t*)alloca(len);
cmac_cb.round = n;
diff = len - length;
/* prepare calculation for subkey s and last block of data */
cmac_generate_subkey(key);
/* start calculation */
- cmac_aes_k_calculate(key, p_signature, tlen);
+ Octet16 signature = cmac_aes_k_calculate(key);
/* clean up */
- cmac_aes_cleanup();
+ memset(&cmac_cb, 0, sizeof(tCMAC_CB));
+ // cmac_cb.text is auto-freed by alloca
+
+ return signature;
}
+
+} // namespace crypto_toolbox
* limitations under the License.
*/
-#include "bt_target.h"
-
-#include "aes.h"
-#include "bt_utils.h"
-#include "p_256_ecc_pp.h"
-#include "smp_int.h"
+#include "stack/crypto_toolbox/crypto_toolbox.h"
+#include "stack/crypto_toolbox/aes.h"
#include <algorithm>
using base::HexEncode;
-Octet16 smp_calculate_h6(const Octet16& w, std::array<uint8_t, 4> keyid) {
+namespace crypto_toolbox {
+
+Octet16 h6(const Octet16& w, std::array<uint8_t, 4> keyid) {
return aes_cmac(w, keyid.data(), keyid.size());
}
-Octet16 smp_calculate_h7(const Octet16& salt, const Octet16& w) {
+Octet16 h7(const Octet16& salt, const Octet16& w) {
return aes_cmac(salt, w.data(), w.size());
}
-Octet16 smp_calculate_f4(uint8_t* u, uint8_t* v, const Octet16& x, uint8_t z) {
+Octet16 f4(uint8_t* u, uint8_t* v, const Octet16& x, uint8_t z) {
constexpr size_t msg_len = BT_OCTET32_LEN /* U size */ +
BT_OCTET32_LEN /* V size */ + 1 /* Z size */;
DVLOG(2) << "U=" << HexEncode(u, BT_OCTET32_LEN)
<< ", V=" << HexEncode(v, BT_OCTET32_LEN)
- << ", X=" << HexEncode(x.data(), x.size()) << " Z=" << loghex(z);
+ << ", X=" << HexEncode(x.data(), x.size()) << ", Z=" << std::hex
+ << +z;
- uint8_t msg[msg_len];
- uint8_t* p = msg;
- UINT8_TO_STREAM(p, z);
- ARRAY_TO_STREAM(p, v, BT_OCTET32_LEN);
- ARRAY_TO_STREAM(p, u, BT_OCTET32_LEN);
-
- return aes_cmac(x, msg, msg_len);
+ std::array<uint8_t, msg_len> msg;
+ auto it = msg.begin();
+ it = std::copy(&z, &z + 1, it);
+ it = std::copy(v, v + BT_OCTET32_LEN, it);
+ it = std::copy(u, u + BT_OCTET32_LEN, it);
+ return aes_cmac(x, msg.data(), msg.size());
}
-/** helper for smp_calculate_f5 */
+/** helper for f5 */
static Octet16 calculate_mac_key_or_ltk(const Octet16& t, uint8_t counter,
uint8_t* key_id, const Octet16& n1,
const Octet16& n2, uint8_t* a1,
OCTET16_LEN /* N1 size */ +
OCTET16_LEN /* N2 size */ + 7 /* A1 size*/ +
7 /* A2 size*/ + 2 /* Length size */;
- uint8_t msg[msg_len];
- uint8_t* p = msg;
- ARRAY_TO_STREAM(p, length, 2);
- ARRAY_TO_STREAM(p, a2, 7);
- ARRAY_TO_STREAM(p, a1, 7);
- ARRAY_TO_STREAM(p, n2.data(), OCTET16_LEN);
- ARRAY_TO_STREAM(p, n1.data(), OCTET16_LEN);
- ARRAY_TO_STREAM(p, key_id, 4);
- ARRAY_TO_STREAM(p, &counter, 1);
-
- return aes_cmac(t, msg, msg_len);
+ std::array<uint8_t, msg_len> msg;
+ auto it = msg.begin();
+ it = std::copy(length, length + 2, it);
+ it = std::copy(a2, a2 + 7, it);
+ it = std::copy(a1, a1 + 7, it);
+ it = std::copy(n2.begin(), n2.end(), it);
+ it = std::copy(n1.begin(), n1.end(), it);
+ it = std::copy(key_id, key_id + 4, it);
+ it = std::copy(&counter, &counter + 1, it);
+
+ return aes_cmac(t, msg.data(), msg.size());
}
-void smp_calculate_f5(uint8_t* w, const Octet16& n1, const Octet16& n2,
- uint8_t* a1, uint8_t* a2, Octet16* mac_key,
- Octet16* ltk) {
+void f5(uint8_t* w, const Octet16& n1, const Octet16& n2, uint8_t* a1,
+ uint8_t* a2, Octet16* mac_key, Octet16* ltk) {
DVLOG(2) << __func__ << "W=" << HexEncode(w, BT_OCTET32_LEN)
<< ", N1=" << HexEncode(n1.data(), n1.size())
<< ", N2=" << HexEncode(n2.data(), n2.size())
DVLOG(2) << "ltk=" << HexEncode(ltk->data(), ltk->size());
}
-Octet16 smp_calculate_f6(const Octet16& w, const Octet16& n1, const Octet16& n2,
- const Octet16& r, uint8_t* iocap, uint8_t* a1,
- uint8_t* a2) {
+Octet16 f6(const Octet16& w, const Octet16& n1, const Octet16& n2,
+ const Octet16& r, uint8_t* iocap, uint8_t* a1, uint8_t* a2) {
const uint8_t msg_len = OCTET16_LEN /* N1 size */ +
OCTET16_LEN /* N2 size */ + OCTET16_LEN /* R size */ +
3 /* IOcap size */ + 7 /* A1 size*/
return aes_cmac(w, msg.data(), msg.size());
}
-uint32_t smp_calculate_g2(uint8_t* u, uint8_t* v, const Octet16& x,
- const Octet16& y) {
+uint32_t g2(uint8_t* u, uint8_t* v, const Octet16& x, const Octet16& y) {
constexpr size_t msg_len = BT_OCTET32_LEN /* U size */ +
BT_OCTET32_LEN /* V size */
+ OCTET16_LEN /* Y size */;
<< ", X=" << HexEncode(x.data(), x.size())
<< ", Y=" << HexEncode(y.data(), y.size());
- uint8_t msg[msg_len];
- uint8_t* p = msg;
- ARRAY_TO_STREAM(p, y.data(), OCTET16_LEN);
- ARRAY_TO_STREAM(p, v, BT_OCTET32_LEN);
- ARRAY_TO_STREAM(p, u, BT_OCTET32_LEN);
+ std::array<uint8_t, msg_len> msg;
+ auto it = msg.begin();
+ it = std::copy(y.begin(), y.end(), it);
+ it = std::copy(v, v + BT_OCTET32_LEN, it);
+ it = std::copy(u, u + BT_OCTET32_LEN, it);
- Octet16 cmac = aes_cmac(x, msg, msg_len);
+ Octet16 cmac = aes_cmac(x, msg.data(), msg.size());
/* vres = cmac mod 2**32 mod 10**6 */
uint32_t vres;
- p = cmac.data();
+ uint8_t* p = cmac.data();
STREAM_TO_UINT32(vres, p);
- vres = vres % (BTM_MAX_PASSKEY_VAL + 1);
+ vres = vres % 1000000;
return vres;
}
-Octet16 smp_calculate_ltk_to_link_key(const Octet16& ltk, bool use_h7) {
+Octet16 ltk_to_link_key(const Octet16& ltk, bool use_h7) {
Octet16 ilk; /* intermidiate link key */
if (use_h7) {
constexpr Octet16 salt{0x31, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- ilk = smp_calculate_h7(salt, ltk);
+ ilk = h7(salt, ltk);
} else {
/* "tmp1" mapping to extended ASCII, little endian*/
constexpr std::array<uint8_t, 4> keyID_tmp1 = {0x31, 0x70, 0x6D, 0x74};
- ilk = smp_calculate_h6(ltk, keyID_tmp1);
+ ilk = h6(ltk, keyID_tmp1);
}
/* "lebr" mapping to extended ASCII, little endian */
constexpr std::array<uint8_t, 4> keyID_lebr = {0x72, 0x62, 0x65, 0x6c};
- return smp_calculate_h6(ilk, keyID_lebr);
+ return h6(ilk, keyID_lebr);
}
-Octet16 smp_calculate_link_key_to_ltk(const Octet16& link_key, bool use_h7) {
+Octet16 link_key_to_ltk(const Octet16& link_key, bool use_h7) {
Octet16 iltk; /* intermidiate long term key */
if (use_h7) {
constexpr Octet16 salt{0x32, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- iltk = smp_calculate_h7(salt, link_key);
+ iltk = h7(salt, link_key);
} else {
/* "tmp2" mapping to extended ASCII, little endian */
constexpr std::array<uint8_t, 4> keyID_tmp2 = {0x32, 0x70, 0x6D, 0x74};
- iltk = smp_calculate_h6(link_key, keyID_tmp2);
+ iltk = h6(link_key, keyID_tmp2);
}
/* "brle" mapping to extended ASCII, little endian */
constexpr std::array<uint8_t, 4> keyID_brle = {0x65, 0x6c, 0x72, 0x62};
- return smp_calculate_h6(iltk, keyID_brle);
+ return h6(iltk, keyID_brle);
}
+
+} // namespace crypto_toolbox
--- /dev/null
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "stack/include/bt_types.h"
+
+namespace crypto_toolbox {
+
+extern Octet16 aes_128(const Octet16& key, const Octet16& message);
+extern Octet16 aes_cmac(const Octet16& key, const uint8_t* message,
+ uint16_t length);
+extern Octet16 f4(uint8_t* u, uint8_t* v, const Octet16& x, uint8_t z);
+extern void f5(uint8_t* w, const Octet16& n1, const Octet16& n2, uint8_t* a1,
+ uint8_t* a2, Octet16* mac_key, Octet16* ltk);
+extern Octet16 f6(const Octet16& w, const Octet16& n1, const Octet16& n2,
+ const Octet16& r, uint8_t* iocap, uint8_t* a1, uint8_t* a2);
+extern Octet16 h6(const Octet16& w, std::array<uint8_t, 4> keyid);
+extern Octet16 h7(const Octet16& salt, const Octet16& w);
+extern uint32_t g2(uint8_t* u, uint8_t* v, const Octet16& x, const Octet16& y);
+extern Octet16 ltk_to_link_key(const Octet16& ltk, bool use_h7);
+extern Octet16 link_key_to_ltk(const Octet16& link_key, bool use_h7);
+
+/* This function computes AES_128(key, message). |key| must be 128bit.
+ * |message| can be at most 16 bytes long, it's length in bytes is given in
+ * |length| */
+inline Octet16 aes_128(const Octet16& key, const uint8_t* message,
+ const uint8_t length) {
+ CHECK(length <= OCTET16_LEN) << "you tried aes_128 more than 16 bytes!";
+ Octet16 msg{0};
+ std::copy(message, message + length, msg.begin());
+ return aes_128(key, msg);
+}
+
+// |tlen| - lenth of mac desired
+// |p_signature| - data pointer to where signed data to be stored, tlen long.
+inline void aes_cmac(const Octet16& key, const uint8_t* message,
+ uint16_t length, uint16_t tlen, uint8_t* p_signature) {
+ Octet16 signature = aes_cmac(key, message, length);
+
+ uint8_t* p_mac = signature.data() + (OCTET16_LEN - tlen);
+ memcpy(p_signature, p_mac, tlen);
+}
+
+inline Octet16 aes_cmac(const Octet16& key, const Octet16& message) {
+ return aes_cmac(key, message.data(), message.size());
+}
+
+} // namespace crypto_toolbox
\ No newline at end of file
******************************************************************************/
extern void SMP_SecureConnectionOobDataReply(uint8_t* p_data);
-/* This function computes AES_128(key, message). |key| must be 128bit.
- * |message| can be at most 16 bytes long, it's length in bytes is given in
- * |length| */
-extern Octet16 SMP_Encrypt(const Octet16& key, uint8_t* message,
- uint8_t length);
-
/*******************************************************************************
*
* Function SMP_KeypressNotification
// Proceed to send LTK, DIV and ER to master if bonding the devices.
extern void smp_link_encrypted(const RawAddress& bda, uint8_t encr_enable);
-//
-// The AES-CMAC Generation Function with tlen implemented.
-// |key| - CMAC key in little endian order, expect SRK when used by SMP.
-// |message| - text to be signed in little endian byte order.
-// |length| - length of the message in byte.
-// |tlen| - lenth of mac desired
-// |p_signature| - data pointer to where signed data to be stored, tlen long.
-//
-void aes_cipher_msg_auth_code(const Octet16& key, const uint8_t* message,
- uint16_t length, uint16_t tlen,
- uint8_t* p_signature);
-
-inline Octet16 aes_cmac(const Octet16& key, const uint8_t* message,
- const uint16_t length) {
- Octet16 ret;
- aes_cipher_msg_auth_code(key, message, length, 16, ret.data());
- return ret;
-}
-
-inline Octet16 aes_cmac(const Octet16& key, const Octet16& message) {
- return aes_cmac(key, message.data(), message.size());
-}
-
#endif /* SMP_API_H */
p_cb->sc_oob_data.loc_oob_data.randomizer = p_cb->rand;
p_cb->sc_oob_data.loc_oob_data.commitment =
- smp_calculate_f4(p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
- p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
- p_cb->sc_oob_data.loc_oob_data.randomizer, 0);
+ crypto_toolbox::f4(p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
+ p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
+ p_cb->sc_oob_data.loc_oob_data.randomizer, 0);
#if (SMP_DEBUG == TRUE)
uint8_t* p_print = NULL;
smp_sm_event(&smp_cb, SMP_SC_OOB_DATA_EVT, &smp_int_data);
}
-/* This function computes AES_128(key, message). |key| must be 128bit.
- * |message| can be at most 16 bytes long, it's length in bytes is given in
- * |length| */
-Octet16 SMP_Encrypt(const Octet16& key, uint8_t* message, uint8_t length) {
- return smp_encrypt_data(key, message, length);
-}
-
/*******************************************************************************
*
* Function SMP_KeypressNotification
#include "btm_api.h"
#include "btm_ble_api.h"
#include "btu.h"
-#include "crypto_toolbox.h"
#include "smp_api.h"
+#include "stack/crypto_toolbox/crypto_toolbox.h"
/* Legacy mode */
#define SMP_MODEL_ENCRYPTION_ONLY 0 /* Just Works model */
/* check if authentication requirement need MITM protection */
#define SMP_NO_MITM_REQUIRED(x) (((x)&SMP_AUTH_YN_BIT) == 0)
-#define SMP_ENCRYT_KEY_SIZE 16
-#define SMP_ENCRYT_DATA_SIZE 16
-#define SMP_ECNCRPYT_STATUS HCI_SUCCESS
-
typedef struct {
RawAddress bd_addr;
BT_HDR* p_copy;
extern void smp_mask_enc_key(uint8_t loc_enc_size, Octet16* p_data);
extern void smp_rsp_timeout(void* data);
extern void smp_delayed_auth_complete_timeout(void* data);
-extern void smp_xor_128(Octet16* a, const Octet16& b);
-extern Octet16 smp_encrypt_data(const Octet16& key, uint8_t* message,
- uint8_t length);
extern bool smp_command_has_invalid_parameters(tSMP_CB* p_cb);
extern void smp_reject_unexpected_pairing_command(const RawAddress& bd_addr);
extern tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB* p_cb);
#endif
extern void print128(const Octet16& x, const uint8_t* key_name);
+extern void smp_xor_128(Octet16* a, const Octet16& b);
#endif /* SMP_INT_H */
#endif
#include <base/bind.h>
#include <string.h>
-#include "aes.h"
#include "bt_utils.h"
#include "btm_ble_api.h"
#include "btm_ble_int.h"
#include "osi/include/osi.h"
#include "p_256_ecc_pp.h"
#include "smp_int.h"
-#include "stack/smp/crypto_toolbox.h"
+#include "stack/crypto_toolbox/crypto_toolbox.h"
#include <algorithm>
using base::Bind;
+using crypto_toolbox::aes_128;
#ifndef SMP_MAX_ENC_REPEAT
#define SMP_MAX_ENC_REPEAT 3
#endif
}
-/* This function computes AES_128(key, message). |key| must be 128bit.
- * |message| can be at most 16 bytes long, it's length in bytes is given in
- * |length| */
-Octet16 smp_encrypt_data(const Octet16& key, uint8_t* message, uint8_t length) {
- uint8_t* p = NULL;
- uint8_t* p_rev_data = NULL; /* input data in big endilan format */
- uint8_t* p_rev_key = NULL; /* input key in big endilan format */
- uint8_t* p_rev_output = NULL; /* encrypted output in big endilan format */
-
- SMP_TRACE_DEBUG("%s", __func__);
-
- if (length > SMP_ENCRYT_DATA_SIZE) length = SMP_ENCRYT_DATA_SIZE;
-
- uint8_t p_start[SMP_ENCRYT_DATA_SIZE * 4];
- memset(p_start, 0, SMP_ENCRYT_DATA_SIZE * 4);
- p = p_start;
- ARRAY_TO_STREAM(p, message, length); /* byte 0 to byte 15 */
- p_rev_data = p = p_start + SMP_ENCRYT_DATA_SIZE; /* start at byte 16 */
- REVERSE_ARRAY_TO_STREAM(p, p_start,
- SMP_ENCRYT_DATA_SIZE); /* byte 16 to byte 31 */
- p_rev_key = p; /* start at byte 32 */
- REVERSE_ARRAY_TO_STREAM(p, key.data(),
- SMP_ENCRYT_KEY_SIZE); /* byte 32 to byte 47 */
-
-#if (SMP_DEBUG == TRUE && SMP_DEBUG_VERBOSE == TRUE)
- smp_debug_print_nbyte_little_endian(key.data(), "Key", SMP_ENCRYT_KEY_SIZE);
- smp_debug_print_nbyte_little_endian(p_start, "Plain text",
- SMP_ENCRYT_DATA_SIZE);
-#endif
- p_rev_output = p;
-
- aes_context ctx;
- aes_set_key(p_rev_key, SMP_ENCRYT_KEY_SIZE, &ctx);
- aes_encrypt(p_rev_data, p, &ctx); /* outputs in byte 48 to byte 63 */
-
- Octet16 output;
- p = output.data();
- REVERSE_ARRAY_TO_STREAM(p, p_rev_output, SMP_ENCRYT_DATA_SIZE);
-#if (SMP_DEBUG == TRUE && SMP_DEBUG_VERBOSE == TRUE)
- smp_debug_print_nbyte_little_endian(p_out->param_buf, "Encrypted text",
- SMP_ENCRYT_KEY_SIZE);
-#endif
- return output;
-}
-
/** This function is called to process a passkey. */
void smp_proc_passkey(tSMP_CB* p_cb, BT_OCTET8 rand) {
uint8_t* tt = p_cb->tk.data();
UINT16_TO_STREAM(p, p_cb->div);
UINT16_TO_STREAM(p, r);
- p_cb->csrk = SMP_Encrypt(er, buffer, 4);
+ p_cb->csrk = aes_128(er, buffer, 4);
smp_send_csrk_info(p_cb, NULL);
}
smp_debug_print_nbyte_little_endian(p1, "p1' = p1 XOR r", 16);
/* calculate e1 = e(k, p1'), where k = TK */
smp_debug_print_nbyte_little_endian(p_cb->tk.data(), "TK", 16);
- Octet16 e1 = SMP_Encrypt(p_cb->tk, p1.data(), OCTET16_LEN);
+ Octet16 e1 = aes_128(p_cb->tk, p1);
smp_debug_print_nbyte_little_endian(e1.data(), "e1 = e(k, p1')", 16);
/* generate p2 = padding || ia || ra */
Octet16 p2 = smp_gen_p2_4_confirm(p_cb, remote_bda);
smp_xor_128(&p2, e1);
smp_debug_print_nbyte_little_endian(p2, "p2' = p2 XOR e1", 16);
/* calculate: c1 = e(k, p2') */
- *output = SMP_Encrypt(p_cb->tk, p2.data(), OCTET16_LEN);
+ *output = aes_128(p_cb->tk, p2);
return SMP_SUCCESS;
}
const Octet16& dhk = BTM_GetDeviceDHK();
memcpy(p_cb->enc_rand, rand, BT_OCTET8_LEN);
- Octet16 output = SMP_Encrypt(dhk, rand, BT_OCTET8_LEN);
+ Octet16 output = aes_128(dhk, rand, BT_OCTET8_LEN);
smp_process_ediv(p_cb, output);
}
const Octet16& er = BTM_GetDeviceEncRoot();
/* LTK = d1(ER, DIV, 0)= e(ER, DIV)*/
- Octet16 ltk = SMP_Encrypt(er, (uint8_t*)&p_cb->div, sizeof(uint16_t));
+ Octet16 ltk = aes_128(er, (uint8_t*)&p_cb->div, sizeof(uint16_t));
/* mask the LTK */
smp_mask_enc_key(p_cb->loc_enc_size, <k);
p_cb->ltk = ltk;
}
/* generate STK = Etk(rand|rrand)*/
- return SMP_Encrypt(p_cb->tk, text.data(), OCTET16_LEN);
+ return aes_128(p_cb->tk, text);
}
/*******************************************************************************
SMP_TRACE_WARNING(
"local commitment calc on master is not expected "
"for Just Works/Numeric Comparison models");
- p_cb->commitment = smp_calculate_f4(p_cb->loc_publ_key.x,
- p_cb->peer_publ_key.x, p_cb->rand, 0);
+ p_cb->commitment = crypto_toolbox::f4(
+ p_cb->loc_publ_key.x, p_cb->peer_publ_key.x, p_cb->rand, 0);
break;
case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
random_input =
smp_calculate_random_input(p_cb->local_random.data(), p_cb->round);
p_cb->commitment =
- smp_calculate_f4(p_cb->loc_publ_key.x, p_cb->peer_publ_key.x,
- p_cb->rand, random_input);
+ crypto_toolbox::f4(p_cb->loc_publ_key.x, p_cb->peer_publ_key.x,
+ p_cb->rand, random_input);
break;
case SMP_MODEL_SEC_CONN_OOB:
SMP_TRACE_WARNING(
"local commitment calc is expected for OOB model BEFORE pairing");
- p_cb->commitment = smp_calculate_f4(
+ p_cb->commitment = crypto_toolbox::f4(
p_cb->loc_publ_key.x, p_cb->loc_publ_key.x, p_cb->local_random, 0);
break;
default:
SMP_TRACE_WARNING(
"peer commitment calc on slave is not expected "
"for Just Works/Numeric Comparison models");
- output = smp_calculate_f4(p_cb->peer_publ_key.x, p_cb->loc_publ_key.x,
- p_cb->rrand, 0);
+ output = crypto_toolbox::f4(p_cb->peer_publ_key.x, p_cb->loc_publ_key.x,
+ p_cb->rrand, 0);
break;
case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
ri = smp_calculate_random_input(p_cb->peer_random.data(), p_cb->round);
- output = smp_calculate_f4(p_cb->peer_publ_key.x, p_cb->loc_publ_key.x,
- p_cb->rrand, ri);
+ output = crypto_toolbox::f4(p_cb->peer_publ_key.x, p_cb->loc_publ_key.x,
+ p_cb->rrand, ri);
break;
case SMP_MODEL_SEC_CONN_OOB:
- output = smp_calculate_f4(p_cb->peer_publ_key.x, p_cb->peer_publ_key.x,
- p_cb->peer_random, 0);
+ output = crypto_toolbox::f4(p_cb->peer_publ_key.x, p_cb->peer_publ_key.x,
+ p_cb->peer_random, 0);
break;
default:
SMP_TRACE_ERROR("Association Model = %d is not used in LE SC",
SMP_TRACE_DEBUG("%s", __func__);
if (p_cb->role == HCI_ROLE_MASTER) {
- p_cb->number_to_display = smp_calculate_g2(
+ p_cb->number_to_display = crypto_toolbox::g2(
p_cb->loc_publ_key.x, p_cb->peer_publ_key.x, p_cb->rand, p_cb->rrand);
} else {
- p_cb->number_to_display = smp_calculate_g2(
+ p_cb->number_to_display = crypto_toolbox::g2(
p_cb->peer_publ_key.x, p_cb->loc_publ_key.x, p_cb->rrand, p_cb->rand);
}
return;
}
-/*******************************************************************************
- *
- * Function smp_calculate_f5_mackey_or_long_term_key
- *
- * Description The function calculates the value of MacKey or LTK by the
- * rules defined for f5 function.
- * At the moment exactly the same formula is used to calculate
- * LTK and MacKey.
- * The difference is the value of input parameter Counter:
- * - in MacKey calculations the value is 0;
- * - in LTK calculations the value is 1.
- * The formula:
- * mac = AES-CMAC (Counter||keyID||N1||N2||A1||A2||Length)
- * T
- * where
- * input: T is 256 bits;
- * Counter is 8 bits, its value is 0 for MacKey,
- * 1 for LTK;
- * keyID is 32 bits, its value is 0x62746c65;
- * N1 is 128 bits;
- * N2 is 128 bits;
- * A1 is 56 bits;
- * A2 is 56 bits;
- * Length is 16 bits, its value is 0x0100
- * output: LTK is 128 bit.
- *
- * Note The LSB is the first octet, the MSB is the last octet of
- * the AES-CMAC input/output stream.
- *
- ******************************************************************************/
-Octet16 smp_calculate_f5_mackey_or_long_term_key(
- 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) {
- constexpr size_t msg_len = 1 /* Counter size */ + 4 /* keyID size */ +
- OCTET16_LEN /* N1 size */ +
- OCTET16_LEN /* N2 size */ + 7 /* A1 size*/ +
- 7 /* A2 size*/ + 2 /* Length size */;
-
- SMP_TRACE_DEBUG("%s", __func__);
-#if (SMP_DEBUG == TRUE)
- uint8_t* p_prnt = t;
- smp_debug_print_nbyte_little_endian(p_prnt, "T", OCTET16_LEN);
- p_prnt = counter;
- smp_debug_print_nbyte_little_endian(p_prnt, "Counter", 1);
- p_prnt = key_id;
- smp_debug_print_nbyte_little_endian(p_prnt, "KeyID", 4);
- p_prnt = n1;
- smp_debug_print_nbyte_little_endian(p_prnt, "N1", OCTET16_LEN);
- p_prnt = n2;
- smp_debug_print_nbyte_little_endian(p_prnt, "N2", OCTET16_LEN);
- p_prnt = a1;
- smp_debug_print_nbyte_little_endian(p_prnt, "A1", 7);
- p_prnt = a2;
- smp_debug_print_nbyte_little_endian(p_prnt, "A2", 7);
- p_prnt = length;
- smp_debug_print_nbyte_little_endian(p_prnt, "Length", 2);
-#endif
-
- uint8_t msg[msg_len];
- uint8_t* p = msg;
- ARRAY_TO_STREAM(p, length, 2);
- ARRAY_TO_STREAM(p, a2, 7);
- ARRAY_TO_STREAM(p, a1, 7);
- ARRAY_TO_STREAM(p, n2.data(), OCTET16_LEN);
- ARRAY_TO_STREAM(p, n1.data(), OCTET16_LEN);
- ARRAY_TO_STREAM(p, key_id, 4);
- ARRAY_TO_STREAM(p, counter, 1);
-#if (SMP_DEBUG == TRUE)
- p_prnt = msg;
- smp_debug_print_nbyte_little_endian(p_prnt, "M", msg_len);
-#endif
-
- Octet16 cmac = aes_cmac(t, msg, msg_len);
-
-#if (SMP_DEBUG == TRUE)
- p_prnt = cmac;
- smp_debug_print_nbyte_little_endian(p_prnt, "AES-CMAC", OCTET16_LEN);
-#endif
-
- return cmac;
-}
/*******************************************************************************
*
smp_collect_local_ble_address(a, p_cb);
smp_collect_peer_ble_address(b, p_cb);
- p_cb->dhkey_check = smp_calculate_f6(p_cb->mac_key, p_cb->rand, p_cb->rrand,
- p_cb->peer_random, iocap, a, b);
+ p_cb->dhkey_check = crypto_toolbox::f6(p_cb->mac_key, p_cb->rand, p_cb->rrand,
+ p_cb->peer_random, iocap, a, b);
SMP_TRACE_EVENT("local DHKey check calculation is completed");
}
smp_collect_local_ble_address(a, p_cb);
smp_collect_peer_ble_address(b, p_cb);
- Octet16 param_buf = smp_calculate_f6(p_cb->mac_key, p_cb->rrand, p_cb->rand,
- p_cb->local_random, iocap, b, a);
+ Octet16 param_buf = crypto_toolbox::f6(p_cb->mac_key, p_cb->rrand, p_cb->rand,
+ p_cb->local_random, iocap, b, a);
SMP_TRACE_EVENT("peer DHKey check calculation is completed");
#if (SMP_DEBUG == TRUE)
}
Octet16 link_key =
- smp_calculate_ltk_to_link_key(p_cb->ltk, p_cb->key_derivation_h7_used);
+ crypto_toolbox::ltk_to_link_key(p_cb->ltk, p_cb->key_derivation_h7_used);
uint8_t link_key_type;
if (btm_cb.security_mode == BTM_SEC_MODE_SC) {
Octet16 rev_link_key;
std::reverse_copy(p_dev_rec->link_key.begin(), p_dev_rec->link_key.end(),
rev_link_key.begin());
- p_cb->ltk =
- smp_calculate_link_key_to_ltk(rev_link_key, p_cb->key_derivation_h7_used);
+ p_cb->ltk = crypto_toolbox::link_key_to_ltk(rev_link_key,
+ p_cb->key_derivation_h7_used);
p_cb->sec_level = (br_link_key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256)
? SMP_SEC_AUTHENTICATED
uint8_t i, *aa = a->data();
const uint8_t* bb = b.data();
- SMP_TRACE_EVENT("smp_xor_128");
for (i = 0; i < OCTET16_LEN; i++) {
aa[i] = aa[i] ^ bb[i];
}
nb = p_cb->rand;
}
- smp_calculate_f5(p_cb->dhkey, na, nb, a, b, &p_cb->mac_key, &p_cb->ltk);
+ crypto_toolbox::f5(p_cb->dhkey, na, nb, a, b, &p_cb->mac_key, &p_cb->ltk);
SMP_TRACE_EVENT("%s is completed", __func__);
}
return true;
}
+
+void print128(const Octet16& x, const uint8_t* key_name) {
+ if (VLOG_IS_ON(2) && DLOG_IS_ON(INFO)) {
+ uint8_t* p = (uint8_t*)x.data();
+
+ DVLOG(2) << key_name << " (MSB ~ LSB) = ";
+ for (int i = 0; i < 4; i++) {
+ DVLOG(2) << +p[OCTET16_LEN - i * 4 - 1] << +p[OCTET16_LEN - i * 4 - 2]
+ << +p[OCTET16_LEN - i * 4 - 3] << +p[OCTET16_LEN - i * 4 - 4];
+ }
+ }
+}
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include "stack/include/smp_api.h"
-#include "stack/smp/aes.h"
-#include "stack/smp/crypto_toolbox.h"
+#include "stack/crypto_toolbox/aes.h"
+#include "stack/crypto_toolbox/crypto_toolbox.h"
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
using ::testing::ElementsAreArray;
+namespace crypto_toolbox {
+
// BT Spec 5.0 | Vol 3, Part H D.1
TEST(CryptoToolboxTest, bt_spec_test_d_1_test) {
uint8_t k[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
std::reverse(std::begin(x), std::end(x));
std::reverse(std::begin(aes_cmac_k_m), std::end(aes_cmac_k_m));
- Octet16 output = smp_calculate_f4(u.data(), v.data(), x, z);
+ Octet16 output = f4(u.data(), v.data(), x, z);
EXPECT_EQ(output, aes_cmac_k_m);
}
std::reverse(std::begin(expected_mac_key), std::end(expected_mac_key));
Octet16 mac_key, ltk;
- smp_calculate_f5(dhkey_w.data(), n1, n2, a1.data(), a2.data(), &mac_key,
- <k);
+ f5(dhkey_w.data(), n1, n2, a1.data(), a2.data(), &mac_key, <k);
EXPECT_EQ(mac_key, expected_mac_key);
EXPECT_EQ(ltk, expected_ltk);
std::reverse(std::begin(MacKey), std::end(MacKey));
std::reverse(std::begin(expected_aes_cmac), std::end(expected_aes_cmac));
- Octet16 aes_cmac =
- smp_calculate_f6(MacKey, n1, n2, r, IOcap.data(), a1.data(), a2.data());
+ Octet16 aes_cmac = f6(MacKey, n1, n2, r, IOcap.data(), a1.data(), a2.data());
EXPECT_EQ(aes_cmac, expected_aes_cmac);
}
std::reverse(std::begin(x), std::end(x));
std::reverse(std::begin(y), std::end(y));
- uint32_t g2 = smp_calculate_g2(u.data(), v.data(), x, y);
+ uint32_t val = g2(u.data(), v.data(), x, y);
/* the returned value is already mod 1000000, so do mod on the test result
* value too */
- EXPECT_EQ(g2, 0x2f9ed5baU % 1000000);
+ EXPECT_EQ(val, 0x2f9ed5baU % 1000000);
}
// BT Spec 5.0 | Vol 3, Part H D.6
std::reverse(std::begin(keyID), std::end(keyID));
std::reverse(std::begin(expected_aes_cmac), std::end(expected_aes_cmac));
- Octet16 aes_cmac = smp_calculate_h6(key, keyID);
+ Octet16 aes_cmac = h6(key, keyID);
EXPECT_EQ(aes_cmac, expected_aes_cmac);
}
std::reverse(std::begin(expected_aes_128), std::end(expected_aes_128));
std::reverse(std::begin(expected_ah), std::end(expected_ah));
- Octet16 aes_128 = SMP_Encrypt(IRK, prand.data(), 3);
- EXPECT_EQ(expected_aes_128, aes_128);
+ Octet16 result = aes_128(IRK, prand.data(), 3);
+ EXPECT_EQ(expected_aes_128, result);
// little/big endian 24 bits
- EXPECT_EQ(aes_128[0], expected_ah[0]);
- EXPECT_EQ(aes_128[1], expected_ah[1]);
- EXPECT_EQ(aes_128[2], expected_ah[2]);
+ EXPECT_EQ(result[0], expected_ah[0]);
+ EXPECT_EQ(result[1], expected_ah[1]);
+ EXPECT_EQ(result[2], expected_ah[2]);
}
// BT Spec 5.0 | Vol 3, Part H D.8
std::reverse(std::begin(SALT), std::end(SALT));
std::reverse(std::begin(expected_aes_cmac), std::end(expected_aes_cmac));
- Octet16 aes_cmac = smp_calculate_h7(SALT, Key);
+ Octet16 aes_cmac = h7(SALT, Key);
EXPECT_EQ(expected_aes_cmac, aes_cmac);
}
std::reverse(std::begin(LTK), std::end(LTK));
std::reverse(std::begin(expected_link_key), std::end(expected_link_key));
- Octet16 link_key = smp_calculate_ltk_to_link_key(LTK, true);
+ Octet16 link_key = ltk_to_link_key(LTK, true);
EXPECT_EQ(expected_link_key, link_key);
}
std::reverse(std::begin(LTK), std::end(LTK));
std::reverse(std::begin(expected_link_key), std::end(expected_link_key));
- Octet16 link_key = smp_calculate_ltk_to_link_key(LTK, false);
+ Octet16 link_key = ltk_to_link_key(LTK, false);
EXPECT_EQ(expected_link_key, link_key);
}
-extern Octet16 smp_calculate_link_key_to_ltk(const Octet16& link_key,
- bool use_h7);
-
// // BT Spec 5.0 | Vol 3, Part H D.11
TEST(CryptoToolboxTest, bt_spec_example_d_11_test) {
Octet16 link_key{0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x09, 0x08,
std::reverse(std::begin(link_key), std::end(link_key));
std::reverse(std::begin(expected_ltk), std::end(expected_ltk));
- Octet16 ltk = smp_calculate_link_key_to_ltk(link_key, true);
+ Octet16 ltk = link_key_to_ltk(link_key, true);
EXPECT_EQ(expected_ltk, ltk);
}
std::reverse(std::begin(link_key), std::end(link_key));
std::reverse(std::begin(expected_ltk), std::end(expected_ltk));
- Octet16 ltk = smp_calculate_link_key_to_ltk(link_key, false);
+ Octet16 ltk = link_key_to_ltk(link_key, false);
EXPECT_EQ(expected_ltk, ltk);
}
+
+} // namespace crypto_toolbox
ASSERT_THAT(p2_str, StrEq(expected_p2_str));
}
-// Test smp_gen_p1_4_confirm and SMP_Encrypt function implementation
-TEST_F(SmpCalculateConfirmTest, test_SMP_Encrypt_as_master) {
+// Test smp_gen_p1_4_confirm and aes_128 function implementation
+TEST_F(SmpCalculateConfirmTest, test_aes_128_as_master) {
RawAddress remote_bda;
tBLE_ADDR_TYPE remote_bd_addr_type = 0;
BTM_ReadRemoteConnectionAddr(p_cb_.pairing_bda, remote_bda,
char p1_xor_r_str[2 * OCTET16_LEN + 1];
dump_uint128_reverse(p1, p1_xor_r_str);
ASSERT_THAT(p1_xor_r_str, StrEq(expected_p1_xor_r_str));
- Octet16 output = SMP_Encrypt(p_cb_.tk, p1.data(), OCTET16_LEN);
+ Octet16 output = crypto_toolbox::aes_128(p_cb_.tk, p1.data(), OCTET16_LEN);
const char expected_p1_prime_str[] = "02c7aa2a9857ac866ff91232df0e3c95";
char p1_prime_str[2 * OCTET16_LEN + 1];
dump_uint128_reverse(output, p1_prime_str);