1 /* 2 * Copyright (c) 2023, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef BLE_SECURE_HPP_ 30 #define BLE_SECURE_HPP_ 31 32 #include "openthread-core-config.h" 33 34 #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE 35 36 #include <openthread/ble_secure.h> 37 38 #include "meshcop/meshcop.hpp" 39 #include "meshcop/secure_transport.hpp" 40 #include "meshcop/tcat_agent.hpp" 41 42 /** 43 * @file 44 * Includes definitions for the secure BLE agent. 45 */ 46 47 namespace ot { 48 49 namespace Ble { 50 51 #if !OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE 52 #error "BLE TCAT feature requires `OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE`" 53 #endif 54 55 class BleSecure : public InstanceLocator, public MeshCoP::Tls::Extension, private NonCopyable 56 { 57 public: 58 /** 59 * Pointer to call when the secure BLE connection state changes. 60 * 61 * Please see otHandleBleSecureConnect for details. 62 */ 63 typedef otHandleBleSecureConnect ConnectCallback; 64 65 /** 66 * Pointer to call when data was received over the TLS connection. 67 * If line mode is activated the function is called only after EOL has been received. 68 * 69 * Please see otHandleBleSecureReceive for details. 70 */ 71 typedef otHandleBleSecureReceive ReceiveCallback; 72 73 /** 74 * Represents a TCAT command class. 75 */ 76 typedef MeshCoP::TcatAgent::CommandClass CommandClass; 77 78 /** 79 * Constructor initializes the object. 80 * 81 * @param[in] aInstance A reference to the OpenThread instance. 82 */ 83 explicit BleSecure(Instance &aInstance); 84 85 /** 86 * Starts the secure BLE agent. 87 * 88 * @param[in] aConnectHandler A pointer to a function that will be called when the connection 89 * state changes. 90 * @param[in] aReceiveHandler A pointer to a function that will be called once data has been received 91 * over the TLS connection. 92 * @param[in] aTlvMode A boolean value indicating if line mode shall be activated. 93 * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used. 94 * 95 * @retval kErrorNone Successfully started the BLE agent. 96 * @retval kErrorAlready Already started. 97 */ 98 Error Start(ConnectCallback aConnectHandler, ReceiveCallback aReceiveHandler, bool aTlvMode, void *aContext); 99 100 /** 101 * Enables the TCAT protocol over BLE Secure. 102 * 103 * @param[in] aHandler Callback to a function that is called when the join operation completes. 104 * 105 * @retval kErrorNone Successfully started the BLE Secure Joiner role. 106 * @retval kErrorInvalidArgs The aVendorInfo is invalid. 107 * @retval kErrorInvaidState The BLE function has not been started or line mode is not selected. 108 */ 109 Error TcatStart(MeshCoP::TcatAgent::JoinCallback aHandler); 110 111 /** 112 * Set the TCAT Vendor Info object 113 * 114 * @param[in] aVendorInfo A pointer to the Vendor Information (must remain valid after the method call). 115 */ TcatSetVendorInfo(const MeshCoP::TcatAgent::VendorInfo & aVendorInfo)116 Error TcatSetVendorInfo(const MeshCoP::TcatAgent::VendorInfo &aVendorInfo) 117 { 118 return mTcatAgent.SetTcatVendorInfo(aVendorInfo); 119 } 120 121 /** 122 * Stops the secure BLE agent. 123 */ 124 void Stop(void); 125 126 /** 127 * Initializes TLS session with a peer using an already open BLE connection. 128 * 129 * @retval kErrorNone Successfully started TLS connection. 130 */ 131 Error Connect(void); 132 133 /** 134 * Stops the BLE and TLS connection. 135 */ 136 void Disconnect(void); 137 138 /** 139 * Indicates whether or not the TLS session is active (connected or connecting). 140 * 141 * @retval TRUE If TLS session is active. 142 * @retval FALSE If TLS session is not active. 143 */ IsConnectionActive(void) const144 bool IsConnectionActive(void) const { return mTls.IsConnectionActive(); } 145 146 /** 147 * Indicates whether or not the TLS session is connected. 148 * 149 * @retval TRUE The TLS session is connected. 150 * @retval FALSE The TLS session is not connected. 151 */ IsConnected(void) const152 bool IsConnected(void) const { return mTls.IsConnected(); } 153 154 /** 155 * Indicates whether or not the TCAT agent is enabled. 156 * 157 * @retval TRUE The TCAT agent is enabled. 158 * @retval FALSE The TCAT agent is not enabled. 159 */ IsTcatEnabled(void) const160 bool IsTcatEnabled(void) const { return mTcatAgent.IsEnabled(); } 161 162 /** 163 * Indicates whether or not a TCAT command class is authorized for use. 164 * 165 * @param[in] aInstance A pointer to an OpenThread instance. 166 * @param[in] aCommandClass A command class to subject to authorization check. 167 * 168 * @retval TRUE The command class is authorized for use by the present TCAT commissioner. 169 * @retval FALSE The command class is not authorized for use. 170 */ IsCommandClassAuthorized(CommandClass aCommandClass) const171 bool IsCommandClassAuthorized(CommandClass aCommandClass) const 172 { 173 return mTcatAgent.IsCommandClassAuthorized(aCommandClass); 174 } 175 176 /** 177 * Sets the PSK. 178 * 179 * @param[in] aPsk A pointer to the PSK. 180 * @param[in] aPskLength The PSK length. 181 * 182 * @retval kErrorNone Successfully set the PSK. 183 * @retval kErrorInvalidArgs The PSK is invalid. 184 */ SetPsk(const uint8_t * aPsk,uint8_t aPskLength)185 Error SetPsk(const uint8_t *aPsk, uint8_t aPskLength) { return mTls.SetPsk(aPsk, aPskLength); } 186 187 /** 188 * Sets the PSK. 189 * 190 * @param[in] aPskd A Joiner PSKd. 191 */ 192 void SetPsk(const MeshCoP::JoinerPskd &aPskd); 193 194 /** 195 * Sends a secure BLE message. 196 * 197 * @param[in] aMessage A pointer to the message to send. 198 * 199 * If the return value is kErrorNone, OpenThread takes ownership of @p aMessage, and the caller should no longer 200 * reference @p aMessage. If the return value is not kErrorNone, the caller retains ownership of @p aMessage, 201 * including freeing @p aMessage if the message buffer is no longer needed. 202 * 203 * @retval kErrorNone Successfully sent message. 204 * @retval kErrorNoBufs Failed to allocate buffer memory. 205 * @retval kErrorInvalidState TLS connection was not initialized. 206 */ 207 Error SendMessage(Message &aMessage); 208 209 /** 210 * Sends a secure BLE data packet. 211 * 212 * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. 213 * @param[in] aLength A number indicating the length of the data buffer. 214 * 215 * @retval kErrorNone Successfully sent data. 216 * @retval kErrorNoBufs Failed to allocate buffer memory. 217 * @retval kErrorInvalidState TLS connection was not initialized. 218 */ 219 Error Send(uint8_t *aBuf, uint16_t aLength); 220 221 /** 222 * Sends a secure BLE data packet containing a TCAT Send Application Data TLV. 223 * 224 * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. 225 * @param[in] aLength A number indicating the length of the data buffer. 226 * 227 * @retval kErrorNone Successfully sent data. 228 * @retval kErrorNoBufs Failed to allocate buffer memory. 229 * @retval kErrorInvalidState TLS connection was not initialized. 230 */ 231 Error SendApplicationTlv(uint8_t *aBuf, uint16_t aLength); 232 233 /** 234 * Sends all remaining bytes in the send buffer. 235 * 236 * @retval kErrorNone Successfully enqueued data into the output interface. 237 * @retval kErrorNoBufs Failed to allocate buffer memory. 238 * @retval kErrorInvalidState TLS connection was not initialized. 239 */ 240 Error Flush(void); 241 242 /** 243 * Used to pass data received over a BLE link to the secure BLE server. 244 * 245 * @param[in] aBuf A pointer to the data received. 246 * @param[in] aLength A number indicating the length of the data buffer. 247 */ 248 Error HandleBleReceive(uint8_t *aBuf, uint16_t aLength); 249 250 /** 251 * Used to notify the secure BLE server that a BLE Device has been connected. 252 * 253 * @param[in] aConnectionId The identifier of the open connection. 254 */ 255 void HandleBleConnected(uint16_t aConnectionId); 256 257 /** 258 * Used to notify the secure BLE server that the BLE Device has been disconnected. 259 * 260 * @param[in] aConnectionId The identifier of the open connection. 261 */ 262 void HandleBleDisconnected(uint16_t aConnectionId); 263 264 /** 265 * Used to notify the secure BLE server that the BLE Device has updated ATT_MTU size. 266 * 267 * @param[in] aMtu The updated ATT_MTU value. 268 */ 269 Error HandleBleMtuUpdate(uint16_t aMtu); 270 271 /** 272 * @brief Gets the Install Code Verify Status during the current session. 273 * 274 * @return TRUE The install code was correctly verfied. 275 * @return FALSE The install code was not verified. 276 */ GetInstallCodeVerifyStatus(void) const277 bool GetInstallCodeVerifyStatus(void) const { return mTcatAgent.GetInstallCodeVerifyStatus(); } 278 279 private: 280 enum BleState : uint8_t 281 { 282 kStopped = 0, // Ble secure not started. 283 kAdvertising = 1, // Ble secure not advertising. 284 kConnected = 2, // Ble secure not connected. 285 }; 286 287 static constexpr uint8_t kInitialMtuSize = 23; // ATT_MTU 288 static constexpr uint8_t kGattOverhead = 3; // BLE GATT payload fits MTU size - 3 bytes 289 static constexpr uint8_t kPacketBufferSize = OT_BLE_ATT_MTU_MAX - kGattOverhead; 290 static constexpr uint16_t kTxBleHandle = 0; // Characteristics Handle for TX (not used) 291 292 static void HandleTlsConnectEvent(MeshCoP::Tls::ConnectEvent aEvent, void *aContext); 293 void HandleTlsConnectEvent(MeshCoP::Tls::ConnectEvent aEvent); 294 295 static void HandleTlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength); 296 void HandleTlsReceive(uint8_t *aBuf, uint16_t aLength); 297 298 void HandleTransmit(void); 299 300 static Error HandleTransport(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 301 Error HandleTransport(ot::Message &aMessage); 302 303 using TxTask = TaskletIn<BleSecure, &BleSecure::HandleTransmit>; 304 305 MeshCoP::Tls mTls; 306 MeshCoP::TcatAgent mTcatAgent; 307 Callback<ConnectCallback> mConnectCallback; 308 Callback<ReceiveCallback> mReceiveCallback; 309 bool mTlvMode; 310 ot::Message *mReceivedMessage; 311 ot::Message *mSendMessage; 312 ot::MessageQueue mTransmitQueue; 313 TxTask mTransmitTask; 314 uint8_t mPacketBuffer[kPacketBufferSize]; 315 BleState mBleState; 316 uint16_t mMtuSize; 317 }; 318 319 } // namespace Ble 320 } // namespace ot 321 322 #endif // OPENTHREAD_CONFIG_BLE_TCAT_ENABLE 323 324 #endif // BLE_SECURE_HPP_ 325