7#include <QtCore/qbytearray.h>
8#include <QtCore/qloggingcategory.h>
9#include <QtCore/private/qcore_unix_p.h>
12#include <sys/socket.h>
16#ifdef CONFIG_LINUX_CRYPTO_API
17#include <linux/if_alg.h>
26#ifdef CONFIG_LINUX_CRYPTO_API
27 m_baseSocket =
socket(AF_ALG, SOCK_SEQPACKET, 0);
28 if (m_baseSocket == -1) {
29 qCWarning(QT_BT_BLUEZ) <<
"failed to create first level crypto socket:"
35 memset(&sa, 0,
sizeof sa);
36 sa.salg_family = AF_ALG;
37 strcpy(
reinterpret_cast<char *
>(sa.salg_type),
"hash");
38 strcpy(
reinterpret_cast<char *
>(sa.salg_name),
"cmac(aes)");
39 if (
::bind(m_baseSocket,
reinterpret_cast<sockaddr *
>(&sa),
sizeof sa) == -1) {
40 qCWarning(QT_BT_BLUEZ) <<
"bind() failed for crypto socket:" << strerror(errno);
44 qCWarning(QT_BT_BLUEZ) <<
"Linux crypto API not present, CMAC verification will fail.";
50 if (m_baseSocket != -1)
58 fullMessage.
resize(fullMessage.
size() +
sizeof signCounter);
65#ifdef CONFIG_LINUX_CRYPTO_API
66 if (m_baseSocket == -1)
69 std::reverse_copy(std::begin(csrk.
data), std::end(csrk.
data), std::begin(csrkMsb.
data));
71 sizeof csrkMsb).
toHex();
72 if (setsockopt(m_baseSocket, 279 , ALG_SET_KEY, csrkMsb.
data,
sizeof csrkMsb) == -1) {
73 qCWarning(QT_BT_BLUEZ) <<
"setsockopt() failed for crypto socket:" << strerror(errno);
86 int value()
const {
return m_socket; }
90 SocketWrapper cryptoSocket(accept(m_baseSocket,
nullptr,
nullptr));
91 if (cryptoSocket.value() == -1) {
92 qCWarning(QT_BT_BLUEZ) <<
"accept() failed for crypto socket:" << strerror(errno);
98 qint64 totalBytesWritten = 0;
101 messageSwapped.
constData() + totalBytesWritten,
102 messageSwapped.
size() - totalBytesWritten);
104 qCWarning(QT_BT_BLUEZ) <<
"writing to crypto socket failed:" << strerror(errno);
108 }
while (totalBytesWritten < messageSwapped.
size());
110 quint8 *
const macPtr =
reinterpret_cast<quint8 *
>(&mac);
111 qint64 totalBytesRead = 0;
114 sizeof mac - totalBytesRead);
115 if (bytesRead == -1) {
116 qCWarning(QT_BT_BLUEZ) <<
"reading from crypto socket failed:" << strerror(errno);
119 totalBytesRead += bytesRead;
120 }
while (totalBytesRead <
qint64(
sizeof mac));
125 qCWarning(QT_BT_BLUEZ) <<
"CMAC calculation failed due to missing Linux crypto API.";
133#ifdef CONFIG_LINUX_CRYPTO_API
135 if (actualMac != expectedMac) {
136 qCWarning(QT_BT_BLUEZ) <<
Qt::hex <<
"signature verification failed: calculated mac:"
137 << actualMac <<
"expected mac:" << expectedMac;
145 qCWarning(QT_BT_BLUEZ) <<
"CMAC verification failed due to missing Linux crypto API.";
void putBtData(T src, void *dst)
quint64 calculateMac(const QByteArray &message, QUuid::Id128Bytes csrk) const
bool verify(const QByteArray &message, QUuid::Id128Bytes csrk, quint64 expectedMac) const
static QByteArray createFullMessage(const QByteArray &message, quint32 signCounter)
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first byte in the byte-array.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
QByteArray toHex(char separator='\0') const
Returns a hex encoded copy of the byte array.
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
constexpr Initialization Uninitialized
static qint64 qt_safe_write(int fd, const void *data, qint64 len)
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr T qFromBigEndian(T source)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLenum GLsizei GLuint GLint * bytesWritten
GLuint GLsizei const GLchar * message
unsigned long long quint64
socketLayer bind(QHostAddress::Any, 4000)