diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-23 20:52:28 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-23 20:52:28 +0000 |
commit | 37140ec2012aafb58ccf5ea73d3192362f423860 (patch) | |
tree | 2b1527344fb26916f154f4723602e4178fd925fd | |
parent | e1f6df4ccdfc6e9436987e6544a3127baa1c8700 (diff) | |
parent | 3daa949cc15c59a3c3006700348830d0726f8975 (diff) | |
download | bt-37140ec2012aafb58ccf5ea73d3192362f423860.tar.gz |
Merge cherrypicks of ['googleplex-android-review.googlesource.com/24738554', 'googleplex-android-review.googlesource.com/24738555', 'googleplex-android-review.googlesource.com/24738556', 'googleplex-android-review.googlesource.com/24738557', 'googleplex-android-review.googlesource.com/24738558', 'googleplex-android-review.googlesource.com/24834612', 'googleplex-android-review.googlesource.com/24931700', 'googleplex-android-review.googlesource.com/24933651', 'googleplex-android-review.googlesource.com/23356859'] into sc-platform-release.
Change-Id: Ia29331258fdc18e1dc444476c67fba0b2842a2f3
-rw-r--r-- | btif/src/btif_avrcp_audio_track.cc | 8 | ||||
-rw-r--r-- | main/Android.bp | 1 | ||||
-rw-r--r-- | main/shim/Android.bp | 1 | ||||
-rw-r--r-- | main/shim/BUILD.gn | 1 | ||||
-rw-r--r-- | main/shim/le_advertising_manager.cc | 78 | ||||
-rw-r--r-- | main/shim/utils.cc | 44 | ||||
-rw-r--r-- | main/shim/utils.h | 32 | ||||
-rw-r--r-- | stack/btm/btm_ble.cc | 3 | ||||
-rw-r--r-- | stack/btm/btm_sec.cc | 145 | ||||
-rw-r--r-- | stack/btm/security_device_record.h | 1 |
10 files changed, 194 insertions, 120 deletions
diff --git a/btif/src/btif_avrcp_audio_track.cc b/btif/src/btif_avrcp_audio_track.cc index 8ca5c9798..e17f80f5f 100644 --- a/btif/src/btif_avrcp_audio_track.cc +++ b/btif/src/btif_avrcp_audio_track.cc @@ -23,6 +23,8 @@ #include <base/logging.h> #include <utils/StrongPointer.h> +#include <algorithm> + #include "bt_target.h" #include "osi/include/log.h" @@ -152,7 +154,7 @@ static size_t transcodeQ15ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; - for (; i <= length / sampleSize; i++) { + for (; i < std::min(trackHolder->bufferLength, length / sampleSize); i++) { trackHolder->buffer[i] = ((int16_t*)buffer)[i] * kScaleQ15ToFloat; } return i * sampleSize; @@ -162,7 +164,7 @@ static size_t transcodeQ23ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; - for (; i <= length / sampleSize; i++) { + for (; i < std::min(trackHolder->bufferLength, length / sampleSize); i++) { size_t offset = i * sampleSize; int32_t sample = *((int32_t*)(buffer + offset - 1)) & 0x00FFFFFF; trackHolder->buffer[i] = sample * kScaleQ23ToFloat; @@ -174,7 +176,7 @@ static size_t transcodeQ31ToFloat(uint8_t* buffer, size_t length, BtifAvrcpAudioTrack* trackHolder) { size_t sampleSize = sampleSizeFor(trackHolder); size_t i = 0; - for (; i <= length / sampleSize; i++) { + for (; i < std::min(trackHolder->bufferLength, length / sampleSize); i++) { trackHolder->buffer[i] = ((int32_t*)buffer)[i] * kScaleQ31ToFloat; } return i * sampleSize; diff --git a/main/Android.bp b/main/Android.bp index 67cb3eca4..993a4b9a8 100644 --- a/main/Android.bp +++ b/main/Android.bp @@ -239,6 +239,7 @@ cc_test { "shim/metrics_api.cc", "shim/shim.cc", "shim/stack.cc", + "shim/utils.cc", "test/main_shim_test.cc", ], static_libs: [ diff --git a/main/shim/Android.bp b/main/shim/Android.bp index b8aca32fa..b7fd7dfb2 100644 --- a/main/shim/Android.bp +++ b/main/shim/Android.bp @@ -29,5 +29,6 @@ filegroup { "metrics_api.cc", "shim.cc", "stack.cc", + "utils.cc", ] } diff --git a/main/shim/BUILD.gn b/main/shim/BUILD.gn index 5e6485898..d93a646ba 100644 --- a/main/shim/BUILD.gn +++ b/main/shim/BUILD.gn @@ -35,6 +35,7 @@ source_set("LibBluetoothShimSources") { "metrics_api.cc", "shim.cc", "stack.cc", + "utils.cc", ] include_dirs = [ diff --git a/main/shim/le_advertising_manager.cc b/main/shim/le_advertising_manager.cc index a91f7426b..850beb866 100644 --- a/main/shim/le_advertising_manager.cc +++ b/main/shim/le_advertising_manager.cc @@ -17,6 +17,7 @@ #define LOG_TAG "bt_shim_advertiser" #include "le_advertising_manager.h" +#include "utils.h" #include <hardware/bluetooth.h> #include <hardware/bt_gatt.h> @@ -40,6 +41,7 @@ using bluetooth::hci::AddressType; using bluetooth::hci::ErrorCode; using bluetooth::hci::GapData; using bluetooth::hci::OwnAddressType; +using bluetooth::shim::parse_gap_data; using std::vector; class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, @@ -79,22 +81,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, StatusCallback cb) override { LOG(INFO) << __func__ << " in shim layer"; - size_t offset = 0; std::vector<GapData> advertising_data = {}; - - while (offset < data.size()) { - GapData gap_data; - uint8_t len = data[offset]; - auto begin = data.begin() + offset; - auto end = begin + len + 1; // 1 byte for len - auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end); - bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet( - data_copy); - GapData::Parse(&gap_data, packet.begin()); - advertising_data.push_back(gap_data); - offset += len + 1; // 1 byte for len - } - + parse_gap_data(data, advertising_data); bluetooth::shim::GetAdvertising()->SetData(advertiser_id, set_scan_rsp, advertising_data); } @@ -135,47 +123,9 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, periodic_params.periodic_advertising_properties; config.periodic_advertising_parameters = periodic_parameters; - size_t offset = 0; - while (offset < advertise_data.size()) { - GapData gap_data; - uint8_t len = advertise_data[offset]; - auto begin = advertise_data.begin() + offset; - auto end = begin + len + 1; // 1 byte for len - auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end); - bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet( - data_copy); - GapData::Parse(&gap_data, packet.begin()); - config.advertisement.push_back(gap_data); - offset += len + 1; // 1 byte for len - } - - offset = 0; - while (offset < scan_response_data.size()) { - GapData gap_data; - uint8_t len = scan_response_data[offset]; - auto begin = scan_response_data.begin() + offset; - auto end = begin + len + 1; // 1 byte for len - auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end); - bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet( - data_copy); - GapData::Parse(&gap_data, packet.begin()); - config.scan_response.push_back(gap_data); - offset += len + 1; // 1 byte for len - } - - offset = 0; - while (offset < periodic_data.size()) { - GapData gap_data; - uint8_t len = periodic_data[offset]; - auto begin = periodic_data.begin() + offset; - auto end = begin + len + 1; // 1 byte for len - auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end); - bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet( - data_copy); - GapData::Parse(&gap_data, packet.begin()); - config.periodic_data.push_back(gap_data); - offset += len + 1; // 1 byte for len - } + parse_gap_data(advertise_data, config.advertisement); + parse_gap_data(scan_response_data, config.scan_response); + parse_gap_data(periodic_data, config.periodic_data); bluetooth::hci::AdvertiserId id = bluetooth::shim::GetAdvertising()->ExtendedCreateAdvertiser( @@ -202,22 +152,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, StatusCallback cb) override { LOG(INFO) << __func__ << " in shim layer"; - size_t offset = 0; std::vector<GapData> advertising_data = {}; - - while (offset < data.size()) { - GapData gap_data; - uint8_t len = data[offset]; - auto begin = data.begin() + offset; - auto end = begin + len + 1; // 1 byte for len - auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end); - bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet( - data_copy); - GapData::Parse(&gap_data, packet.begin()); - advertising_data.push_back(gap_data); - offset += len + 1; // 1 byte for len - } - + parse_gap_data(data, advertising_data); bluetooth::shim::GetAdvertising()->SetPeriodicData(advertiser_id, advertising_data); } diff --git a/main/shim/utils.cc b/main/shim/utils.cc new file mode 100644 index 000000000..9f18ddc4f --- /dev/null +++ b/main/shim/utils.cc @@ -0,0 +1,44 @@ +/* + * Copyright 2023 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. + */ + +#include "utils.h" + +namespace bluetooth { +namespace shim { +void parse_gap_data(const std::vector<uint8_t> &raw_data, + std::vector<hci::GapData> &output) { + size_t offset = 0; + while (offset < raw_data.size()) { + hci::GapData gap_data; + uint8_t len = raw_data[offset]; + + if (offset + len + 1 > raw_data.size()) { + break; + } + + auto begin = raw_data.begin() + offset; + auto end = begin + len + 1; // 1 byte for len + auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end); + bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet( + data_copy); + hci::GapData::Parse(&gap_data, packet.begin()); + output.push_back(gap_data); + offset += len + 1; // 1 byte for len + } +} + +} // namespace shim +} // namespace bluetooth diff --git a/main/shim/utils.h b/main/shim/utils.h new file mode 100644 index 000000000..56da2a0a0 --- /dev/null +++ b/main/shim/utils.h @@ -0,0 +1,32 @@ +/* + * Copyright 2023 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 <vector> + +#include "hci/hci_packets.h" + +namespace bluetooth { +namespace shim { +/** + * @brief Parsing gap data from raw bytes + * + * @param raw_data input, raw bytes + * @param output vector of GapData + */ +void parse_gap_data(const std::vector<uint8_t> &raw_data, + std::vector<hci::GapData> &output); +} // namespace shim +} // namespace bluetooth diff --git a/stack/btm/btm_ble.cc b/stack/btm/btm_ble.cc index ae7b9ba59..601d85be0 100644 --- a/stack/btm/btm_ble.cc +++ b/stack/btm/btm_ble.cc @@ -31,6 +31,7 @@ #include "main/shim/btm_api.h" #include "main/shim/l2c_api.h" #include "main/shim/shim.h" +#include "openssl/mem.h" #include "stack/btm/btm_dev.h" #include "stack/btm/btm_int_types.h" #include "stack/btm/security_device_record.h" @@ -1960,7 +1961,7 @@ bool BTM_BleVerifySignature(const RawAddress& bd_addr, uint8_t* p_orig, 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) { + if (CRYPTO_memcmp(p_mac, p_comp, BTM_CMAC_TLEN_SIZE) == 0) { btm_ble_increment_sign_ctr(bd_addr, false); verified = true; } diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc index b3d9fb2a9..bfb045c5a 100644 --- a/stack/btm/btm_sec.cc +++ b/stack/btm/btm_sec.cc @@ -111,7 +111,7 @@ static tBTM_STATUS btm_sec_send_hci_disconnect(tBTM_SEC_DEV_REC* p_dev_rec, uint16_t conn_handle); tBTM_SEC_DEV_REC* btm_sec_find_dev_by_sec_state(uint8_t state); -static bool btm_dev_authenticated(tBTM_SEC_DEV_REC* p_dev_rec); +static bool btm_dev_authenticated(const tBTM_SEC_DEV_REC* p_dev_rec); static bool btm_dev_encrypted(tBTM_SEC_DEV_REC* p_dev_rec); static uint16_t btm_sec_set_serv_level4_flags(uint16_t cur_security, bool is_originator); @@ -163,7 +163,7 @@ void NotifyBondingCanceled(tBTM_STATUS btm_status) { * Returns bool true or false * ******************************************************************************/ -static bool btm_dev_authenticated(tBTM_SEC_DEV_REC* p_dev_rec) { +static bool btm_dev_authenticated(const tBTM_SEC_DEV_REC* p_dev_rec) { if (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) { return (true); } @@ -205,6 +205,25 @@ static bool btm_dev_16_digit_authenticated(tBTM_SEC_DEV_REC* p_dev_rec) { /******************************************************************************* * + * Function access_secure_service_from_temp_bond + * + * Description a utility function to test whether an access to + * secure service from temp bonding is happening + * + * Returns true if the aforementioned condition holds, + * false otherwise + * + ******************************************************************************/ +static bool access_secure_service_from_temp_bond(const tBTM_SEC_DEV_REC* p_dev_rec, + bool locally_initiated, + uint16_t security_req) { + return !locally_initiated && (security_req & BTM_SEC_IN_AUTHENTICATE) && + btm_dev_authenticated(p_dev_rec) && + p_dev_rec->is_bond_type_temporary(); +} + +/******************************************************************************* + * * Function BTM_SecRegister * * Description Application manager calls this function to register for @@ -1573,9 +1592,13 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( } if (rc == BTM_SUCCESS) { + if (access_secure_service_from_temp_bond(p_dev_rec, is_originator, security_required)) { + LOG_ERROR("Trying to access a secure service from a temp bonding, rejecting"); + rc = BTM_FAILED_ON_SECURITY; + } if (p_callback) - (*p_callback)(&bd_addr, transport, (void*)p_ref_data, BTM_SUCCESS); - return (BTM_SUCCESS); + (*p_callback)(&bd_addr, transport, (void*)p_ref_data, rc); + return (rc); } } @@ -1592,14 +1615,14 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( if (BTM_SEC_IS_SM4(p_dev_rec->sm4)) { if (is_originator) { /* SM4 to SM4 -> always authenticate & encrypt */ - security_required |= (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT); + security_required |= BTM_SEC_OUT_ENCRYPT; } else /* acceptor */ { /* SM4 to SM4: the acceptor needs to make sure the authentication is * already done */ chk_acp_auth_done = true; /* SM4 to SM4 -> always authenticate & encrypt */ - security_required |= (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT); + security_required |= BTM_SEC_IN_ENCRYPT; } } else if (!(BTM_SM4_KNOWN & p_dev_rec->sm4)) { /* the remote features are not known yet */ @@ -1837,6 +1860,11 @@ tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, p_callback, p_ref_data); } else /* rc == BTM_SUCCESS */ { + if (access_secure_service_from_temp_bond(p_dev_rec, + is_originator, security_required)) { + LOG_ERROR("Trying to access a secure rfcomm service from a temp bonding, reject"); + rc = BTM_FAILED_ON_SECURITY; + } if (p_callback) { LOG_DEBUG("Notifying client that security access has been granted"); (*p_callback)(&bd_addr, transport, p_ref_data, rc); @@ -4268,48 +4296,67 @@ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { /* If connection is not authenticated and authentication is required */ /* start authentication and return PENDING to the caller */ - if ((((!(p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)) && - ((p_dev_rec->IsLocallyInitiated() && - (p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE)) || - (!p_dev_rec->IsLocallyInitiated() && - (p_dev_rec->security_required & BTM_SEC_IN_AUTHENTICATE)))) || - (!(p_dev_rec->sec_flags & BTM_SEC_16_DIGIT_PIN_AUTHED) && - (!p_dev_rec->IsLocallyInitiated() && - (p_dev_rec->security_required & BTM_SEC_IN_MIN_16_DIGIT_PIN)))) && - (p_dev_rec->hci_handle != HCI_INVALID_HANDLE)) { - /* - * We rely on BTM_SEC_16_DIGIT_PIN_AUTHED being set if MITM is in use, - * as 16 DIGIT is only needed if MITM is not used. Unfortunately, the - * BTM_SEC_AUTHENTICATED is used for both MITM and non-MITM - * authenticated connections, hence we cannot distinguish here. - */ - - LOG_DEBUG("Security Manager: Start authentication"); + if (p_dev_rec->hci_handle != HCI_INVALID_HANDLE) { + bool start_auth = false; + + // Check link status of BR/EDR + if (!(p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)) { + if (p_dev_rec->IsLocallyInitiated()) { + if (p_dev_rec->security_required & + (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) { + LOG_DEBUG("Outgoing authentication/encryption Required"); + start_auth = true; + } + } else { + if (p_dev_rec->security_required & + (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) { + LOG_DEBUG("Incoming authentication/encryption Required"); + start_auth = true; + } + } + } - /* - * If we do have a link-key, but we end up here because we need an - * upgrade, then clear the link-key known and authenticated flag before - * restarting authentication. - * WARNING: If the controller has link-key, it is optional and - * recommended for the controller to send a Link_Key_Request. - * In case we need an upgrade, the only alternative would be to delete - * the existing link-key. That could lead to very bad user experience - * or even IOP issues, if a reconnect causes a new connection that - * requires an upgrade. - */ - if ((p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) && - (!(p_dev_rec->sec_flags & BTM_SEC_16_DIGIT_PIN_AUTHED) && - (!p_dev_rec->IsLocallyInitiated() && - (p_dev_rec->security_required & BTM_SEC_IN_MIN_16_DIGIT_PIN)))) { - p_dev_rec->sec_flags &= - ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED | - BTM_SEC_AUTHENTICATED); + if (!(p_dev_rec->sec_flags & BTM_SEC_16_DIGIT_PIN_AUTHED)) { + /* + * We rely on BTM_SEC_16_DIGIT_PIN_AUTHED being set if MITM is in use, + * as 16 DIGIT is only needed if MITM is not used. Unfortunately, the + * BTM_SEC_AUTHENTICATED is used for both MITM and non-MITM + * authenticated connections, hence we cannot distinguish here. + */ + if (!p_dev_rec->IsLocallyInitiated()) { + if (p_dev_rec->security_required & BTM_SEC_IN_MIN_16_DIGIT_PIN) { + LOG_DEBUG("BTM_SEC_IN_MIN_16_DIGIT_PIN Required"); + start_auth = true; + } + } } - btm_sec_start_authentication(p_dev_rec); - return (BTM_CMD_STARTED); - } else { - LOG_DEBUG("Authentication not required"); + if (start_auth) { + LOG_DEBUG("Security Manager: Start authentication"); + + /* + * If we do have a link-key, but we end up here because we need an + * upgrade, then clear the link-key known and authenticated flag before + * restarting authentication. + * WARNING: If the controller has link-key, it is optional and + * recommended for the controller to send a Link_Key_Request. + * In case we need an upgrade, the only alternative would be to delete + * the existing link-key. That could lead to very bad user experience + * or even IOP issues, if a reconnect causes a new connection that + * requires an upgrade. + */ + if ((p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) && + (!(p_dev_rec->sec_flags & BTM_SEC_16_DIGIT_PIN_AUTHED) && + (!p_dev_rec->IsLocallyInitiated() && + (p_dev_rec->security_required & BTM_SEC_IN_MIN_16_DIGIT_PIN)))) { + p_dev_rec->sec_flags &= + ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED | + BTM_SEC_AUTHENTICATED); + } + + btm_sec_start_authentication(p_dev_rec); + return (BTM_CMD_STARTED); + } } /* If connection is not encrypted and encryption is required */ @@ -4337,6 +4384,14 @@ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { return (BTM_FAILED_ON_SECURITY); } + + if (access_secure_service_from_temp_bond(p_dev_rec, + p_dev_rec->is_originator, + p_dev_rec->security_required)) { + LOG_ERROR("Trying to access a secure service from a temp bonding, rejecting"); + return (BTM_FAILED_ON_SECURITY); + } + /* All required security procedures already established */ p_dev_rec->security_required &= ~(BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_IN_AUTHENTICATE | diff --git a/stack/btm/security_device_record.h b/stack/btm/security_device_record.h index 56d8108a0..6423810d9 100644 --- a/stack/btm/security_device_record.h +++ b/stack/btm/security_device_record.h @@ -356,6 +356,7 @@ struct tBTM_SEC_DEV_REC { uint16_t security_required, tBTM_SEC_CALLBACK* p_callback, void* p_ref_data); + friend tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec); public: bool IsLocallyInitiated() const { return is_originator; } |