From c516f6157a35fbabcd204dd628a301734fc76f1a Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 19 Jan 2016 18:06:24 +0100 Subject: Bluetooth LE: Add support for Signed Write command. - This is how we get at the signature resolving key: 1) On connection from a client, we read the key from the respective BlueZ settings file (BlueZ 5 only, as I did not manage to find out where BlueZ 4 keeps this information). 2) Also monitor the HCI traffic for key updates (due to re-pairing). - While there is an autotest for the actual hashing procedure, the overall feature cannot be easily tested for various reasons (there is no signed write support in our client API, for one). However, to help with manual testing, the server part of our autotest now exposes a characteristic that supports signed writes. - This feature requires a Linux kernel >= 3.7. Change-Id: I7ede9b430de167fe1f4519eedf8670d88d79aa25 Reviewed-by: Alex Blasche --- .../server/qlowenergycontroller-gattserver.cpp | 2 +- .../qlowenergycontroller-gattserver/test/test.pro | 4 +- .../test/tst_qlowenergycontroller-gattserver.cpp | 43 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/qlowenergycontroller-gattserver/server/qlowenergycontroller-gattserver.cpp b/tests/auto/qlowenergycontroller-gattserver/server/qlowenergycontroller-gattserver.cpp index 4efa20ba..b7c95816 100644 --- a/tests/auto/qlowenergycontroller-gattserver/server/qlowenergycontroller-gattserver.cpp +++ b/tests/auto/qlowenergycontroller-gattserver/server/qlowenergycontroller-gattserver.cpp @@ -121,7 +121,7 @@ void addCustomService() serviceData.addCharacteristic(charData); charData.setUuid(QBluetoothUuid(quint16(0x5001))); - charData.setProperties(QLowEnergyCharacteristic::Read); + charData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::WriteSigned); charData.setReadConstraints(QBluetooth::AttAuthorizationRequired); // To test read failure. serviceData.addCharacteristic(charData); charData.setValue("something"); diff --git a/tests/auto/qlowenergycontroller-gattserver/test/test.pro b/tests/auto/qlowenergycontroller-gattserver/test/test.pro index bd1f0874..8c95106f 100644 --- a/tests/auto/qlowenergycontroller-gattserver/test/test.pro +++ b/tests/auto/qlowenergycontroller-gattserver/test/test.pro @@ -1,6 +1,8 @@ -QT = core bluetooth testlib +QT = core bluetooth bluetooth-private testlib TARGET = tst_qlowenergycontroller-gattserver CONFIG += testcase c++11 +config_linux_crypto_api:DEFINES += CONFIG_LINUX_CRYPTO_API + SOURCES += tst_qlowenergycontroller-gattserver.cpp diff --git a/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp b/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp index 00fc2152..25cbc17a 100644 --- a/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp +++ b/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp @@ -42,7 +42,12 @@ #include #include +#ifdef Q_OS_LINUX +#include +#endif + #include +#include using namespace QBluetooth; @@ -56,6 +61,8 @@ private slots: // Static, local stuff goes here. void advertisingParameters(); void advertisingData(); + void cmacVerifier(); + void cmacVerifier_data(); void connectionParameters(); void controllerType(); void serviceData(); @@ -145,6 +152,42 @@ void TestQLowEnergyControllerGattServer::advertisingData() QVERIFY(data != QLowEnergyAdvertisingData()); } +void TestQLowEnergyControllerGattServer::cmacVerifier() +{ +#ifdef CONFIG_LINUX_CRYPTO_API + // Test data comes from spec v4.2, Vol 3, Part H, Appendix D.1 + const quint128 csrk = { + { 0x3c, 0x4f, 0xcf, 0x09, 0x88, 0x15, 0xf7, 0xab, + 0xa6, 0xd2, 0xae, 0x28, 0x16, 0x15, 0x7e, 0x2b } + }; + QFETCH(QByteArray, message); + QFETCH(quint64, expectedMac); + const bool success = LeCmacVerifier().verify(message, csrk, expectedMac); + QVERIFY(success); +#else // CONFIG_LINUX_CRYPTO_API + QSKIP("CMAC verification test only applicable on Linux with crypto API"); +#endif // Q_OS_LINUX +} + +void TestQLowEnergyControllerGattServer::cmacVerifier_data() +{ + QTest::addColumn("message"); + QTest::addColumn("expectedMac"); + QTest::newRow("D1.1") << QByteArray() << Q_UINT64_C(0xbb1d6929e9593728); + QTest::newRow("D1.2") << QByteArray::fromHex("2a179373117e3de9969f402ee2bec16b") + << Q_UINT64_C(0x070a16b46b4d4144); + QByteArray messageD13 = QByteArray::fromHex("6bc1bee22e409f96e93d7e117393172aae2d8a57" + "1e03ac9c9eb76fac45af8e5130c81c46a35ce411"); + std::reverse(messageD13.begin(), messageD13.end()); + QTest::newRow("D1.3") << messageD13 << Q_UINT64_C(0xdfa66747de9ae630); + QByteArray messageD14 = QByteArray::fromHex("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"); + std::reverse(messageD14.begin(), messageD14.end()); + QTest::newRow("D1.4") << messageD14 << Q_UINT64_C(0x51f0bebf7e3b9d92); +} + void TestQLowEnergyControllerGattServer::connectionParameters() { QLowEnergyConnectionParameters connParams; -- cgit v1.2.3