QKnxCryptographicEngine Class

The QKnxCryptographicEngine class provides the means to handle all KNXnet/IP security related tasks. More...

Header: #include <QKnxCryptographicEngine>
qmake: QT += knx
Since: Qt 5.12

This class was introduced in Qt 5.12.

Static Public Members

QKnxByteArray XOR(const QKnxByteArray &left, const QKnxByteArray &right, bool adjust = true)
QKnxByteArray computeMessageAuthenticationCode(const QKnxByteArray &key, const QKnxNetIpFrameHeader &header, quint16 id, const QKnxByteArray &data, quint48 sequenceNumber = 0, const QKnxByteArray &serialNumber = {}, quint16 messageTag = 0)
QKnxByteArray decodeAndDecryptPassword(const QKnxByteArray &passwordHash, const QKnxByteArray &createdHash, const QByteArray &password)
QKnxByteArray decodeAndDecryptToolKey(const QKnxByteArray &passwordHash, const QKnxByteArray &createdHash, const QByteArray &toolKey)
QKnxByteArray decrypt(const QKnxByteArray &key, const QKnxByteArray &iv, const QKnxByteArray &data)
QKnxByteArray decryptMessageAuthenticationCode(const QKnxByteArray &key, const QKnxByteArray &mac, quint48 sequenceNumber = 0, const QKnxByteArray &serialNumber = {}, quint16 messageTag = 0)
QKnxByteArray decryptSecureWrapperPayload(const QKnxByteArray &key, const QKnxByteArray &frame, quint48 sequenceNumber, const QKnxByteArray &serialNumber, quint16 messageTag)
QKnxByteArray deviceAuthenticationCodeHash(const QByteArray &password)
QKnxByteArray encrypt(const QKnxByteArray &key, const QKnxByteArray &iv, const QKnxByteArray &data)
QKnxByteArray encryptMessageAuthenticationCode(const QKnxByteArray &key, const QKnxByteArray &mac, quint48 sequenceNumber = 0, const QKnxByteArray &serialNumber = {}, quint16 messageTag = 0)
QKnxByteArray encryptSecureWrapperPayload(const QKnxByteArray &key, const QKnxNetIpFrame &frame, quint48 sequenceNumber, const QKnxByteArray &serialNumber, quint16 messageTag)
QKnxByteArray hashSha256(const QByteArray &data)
QKnxByteArray keyringPasswordHash(const QByteArray &password)
QKnxByteArray sessionKey(const QKnxSecureKey &privateKey, const QKnxSecureKey &peerPublicKey)
QKnxByteArray sessionKey(const QKnxByteArray &privateKey, const QKnxByteArray &peerPublicKey)
QKnxByteArray sessionKey(const QKnxByteArray &sharedSecret)
long sslLibraryVersionNumber()
bool supportsCryptography()
QKnxByteArray userPasswordHash(const QByteArray &password)

Detailed Description

This class is part of the Qt KNX module and currently available as a Technology Preview, and therefore the API and functionality provided by the class may be subject to change at any time without prior notice.

Calculating Message Authentication Codes

The computeMessageAuthenticationCode() function can be used to compute a message authentication code (MAC) for a KNXnet/IP secure frame. The fields that are used to compute the MAC depend on the type of the frame, such as session response frame, session authentication frame, or timer notify frame.

The example code shows how to compute the MAC for the most common secure frames:

auto dummyMac = QKnxByteArray(16, 000); // dummy to get a valid header

// Session Response Frame

quint16 secureSessionIdentifier = 0x0001;
auto responseBuilder = QKnxNetIpSessionResponseProxy::builder();

// create an intermediate frame to fetch a valid frame header
auto netIpFrame = responseBuilder
    .setSecureSessionId(secureSessionIdentifier)
    .setPublicKey(serverPublicKey)
    .setMessageAuthenticationCode(dummyMac)
    .create();

auto deviceAuthenticationHash =
    QKnxCryptographicEngine::deviceAuthenticationCodeHash({ "trustme" });
auto XOR_X_Y = QKnxCryptographicEngine::XOR(clientPublicKey.bytes(), serverPublicKey.bytes());

auto mac = QKnxCryptographicEngine::computeMessageAuthenticationCode(deviceAuthenticationHash,
    netIpFrame.header(), secureSessionIdentifier, XOR_X_Y);

// create the final frame including the computed MAC
netIpFrame = responseBuilder.
    .setMessageAuthenticationCode(mac)
    .create();


// Session Authenticate Frame

auto authenticateBuilder = QKnxNetIpSessionAuthenticateProxy::builder()'

// create an intermediate frame to fetch a valid frame header
netIpFrame = authenticateBuilder
    .setUserId(QKnxNetIp::SecureUserId::Management)
    .setMessageAuthenticationCode(dummyMac)
    .create();

auto passwordHash = QKnxCryptographicEngine::userPasswordHash({ "secret" });

mac = QKnxCryptographicEngine::computeMessageAuthenticationCode(passwordHash,
    netIpFrame.header(), userId, XOR_X_Y);

// create the final frame including the computed MAC
netIpFrame = responseBuilder.
    .setMessageAuthenticationCode(mac)
    .create();


// Timer Notify Frame

quint48 timerValue = 211938428830917;
auto serialNumber = QKnxByteArray::fromHex("00fa12345678");
quint16 messageTag = quint16(QRandomGenerator::global()->generate();

auto timerNotifyBuilder = QKnxNetIpTimerNotifyProxy::builder();

// create an intermediate frame to fetch a valid frame header
netIpFrame = timerNotifyBuilder
    .setTimerValue(timerValue)
    .setSerialNumber(serialNumber)
    .setMessageTag(messageTag)
    .setMessageAuthenticationCode(dummyMac)
    .create();

QKnxByteArray dummyPayload;
quint16 dummySession = 0x0000;
auto backboneKey = QKnxByteArray::fromHex("000102030405060708090a0b0c0d0e0f");

mac = QKnxCryptographicEngine::computeMessageAuthenticationCode(backboneKey,
    netIpFrame.header(), dummySession, dummyPayload, timerValue, serialNumber, messageTag);

// create the final frame including the computed MAC
netIpFrame = responseBuilder.
    .setMessageAuthenticationCode(mac)
    .create();

Member Function Documentation

[static] QKnxByteArray QKnxCryptographicEngine::XOR(const QKnxByteArray &left, const QKnxByteArray &right, bool adjust = true)

Performs a byte-wise XOR operation on the arguments left and right. If the arguments are not equal in size, the function uses only the shorter array for the operation. If adjust is set to true, the arrays are made equal by padding them with 0x00 bytes.

[static] QKnxByteArray QKnxCryptographicEngine::computeMessageAuthenticationCode(const QKnxByteArray &key, const QKnxNetIpFrameHeader &header, quint16 id, const QKnxByteArray &data, quint48 sequenceNumber = 0, const QKnxByteArray &serialNumber = {}, quint16 messageTag = 0)

Computes a message authentication code (MAC) using the given key, header, and id for the given data. Returns an array of bytes that represent the computed MAC or an empty byte array in case of an error.

Note: The sequenceNumber, serialNumber, and messageTag values are required to compute a valid MAC for KNXnet/IP secure wrapper frames. For all other types of secure frames, the possibly given values are ignored and 0 is used instead. For timer notify frames, default-constructed values are used instead of the id and data values.

For an example of using this function, see Calculating Message Authentication Codes.

[static] QKnxByteArray QKnxCryptographicEngine::decodeAndDecryptPassword(const QKnxByteArray &passwordHash, const QKnxByteArray &createdHash, const QByteArray &password)

Decodes and decrypts a password password that was stored in an ETS keyring (*.knxkeys) file with the given password hash passwordHash and created hash createdHash.

Returns an array of bytes that represent the decrypted password or an empty byte array in case of an error.

[static] QKnxByteArray QKnxCryptographicEngine::decodeAndDecryptToolKey(const QKnxByteArray &passwordHash, const QKnxByteArray &createdHash, const QByteArray &toolKey)

Decodes and decrypts a tool key toolKey that was stored in an ETS keyring (*.knxkeys) file with the given password hash passwordHash and created hash createdHash.

Returns an array of bytes that represent the decrypted tool key or an empty byte array in case of an error.

[static] QKnxByteArray QKnxCryptographicEngine::decrypt(const QKnxByteArray &key, const QKnxByteArray &iv, const QKnxByteArray &data)

Decrypts the given data with key and the initial vector iv. Returns an array of bytes that represents the decrypted data.

[static] QKnxByteArray QKnxCryptographicEngine::decryptMessageAuthenticationCode(const QKnxByteArray &key, const QKnxByteArray &mac, quint48 sequenceNumber = 0, const QKnxByteArray &serialNumber = {}, quint16 messageTag = 0)

Decrypts the given message authentication code (MAC) mac with the given key key, sequence number sequenceNumber, serial number serialNumber, and message tag messageTag. Returns an array of bytes that represent the decrypted MAC or an empty byte array in case of an error.

Note: The sequenceNumber, serialNumber and messageTag values are required to properly decrypt the MAC for KNXnet/IP secure wrapper frame. For all other secure frames, the default value of 0 can be used.

[static] QKnxByteArray QKnxCryptographicEngine::decryptSecureWrapperPayload(const QKnxByteArray &key, const QKnxByteArray &frame, quint48 sequenceNumber, const QKnxByteArray &serialNumber, quint16 messageTag)

Decrypts the given KNXnet/IP frame frame with the given key key, sequence number sequenceNumber, serial number serialNumber, and message tag messageTag. Returns an array of bytes that represent the decrypted frame or an empty byte array in case of an error.

[static] QKnxByteArray QKnxCryptographicEngine::deviceAuthenticationCodeHash(const QByteArray &password)

Returns the device authentication code hash derived from the user chosen password password.

Note: The salt used in the password-based key derivation function (PBKDF2) is set to device-authentication-code.1.secure.ip.knx.org.

[static] QKnxByteArray QKnxCryptographicEngine::encrypt(const QKnxByteArray &key, const QKnxByteArray &iv, const QKnxByteArray &data)

Encrypts the given data with key and the initial vector iv. Returns an array of bytes that represents the encrypted data.

[static] QKnxByteArray QKnxCryptographicEngine::encryptMessageAuthenticationCode(const QKnxByteArray &key, const QKnxByteArray &mac, quint48 sequenceNumber = 0, const QKnxByteArray &serialNumber = {}, quint16 messageTag = 0)

Encrypts the given message authentication code (MAC) mac with the given key key, sequence number sequenceNumber, serial number serialNumber, and message tag messageTag. Returns an array of bytes that represent the encrypted MAC or an empty byte array in case of an error.

Note: The sequenceNumber, serialNumber and messageTag are mandatory to properly encrypt the MAC for KNXnet/IP secure wrapper frame, for all other secure frames the default value of 0 can be used.

[static] QKnxByteArray QKnxCryptographicEngine::encryptSecureWrapperPayload(const QKnxByteArray &key, const QKnxNetIpFrame &frame, quint48 sequenceNumber, const QKnxByteArray &serialNumber, quint16 messageTag)

Encrypts the given KNXnet/IP frame frame with the given key key, sequence number sequenceNumber, serial number serialNumber, and message tag messageTag. Returns an array of bytes that represent the encrypted frame or an empty byte array in case of an error or invalid KNXnet/IP frame frame.

[static] QKnxByteArray QKnxCryptographicEngine::hashSha256(const QByteArray &data)

Returns the hash of data using the Sha256 algorithm.

[static] QKnxByteArray QKnxCryptographicEngine::keyringPasswordHash(const QByteArray &password)

Returns the keyring password hash derived from the user chosen password password.

Note: The salt used in the password-based key derivation function (PBKDF2) is set to 1.keyring.ets.knx.org.

[static] QKnxByteArray QKnxCryptographicEngine::sessionKey(const QKnxSecureKey &privateKey, const QKnxSecureKey &peerPublicKey)

Returns the session key calculated from the given private key privateKey and the peer's public key peerPublicKey if OpenSSL is available and no error occurs; otherwise returns a default-constructed value which can be empty.

[static] QKnxByteArray QKnxCryptographicEngine::sessionKey(const QKnxByteArray &privateKey, const QKnxByteArray &peerPublicKey)

This function overloads sessionKey().

[static] QKnxByteArray QKnxCryptographicEngine::sessionKey(const QKnxByteArray &sharedSecret)

Returns the session key computed from the given secret sharedSecret.

[static] long QKnxCryptographicEngine::sslLibraryVersionNumber()

Returns the OpenSSL version number of the OpenSSL library if OpenSSL is available and used to provide cryptographic support; or 0 in any other case.

[static] bool QKnxCryptographicEngine::supportsCryptography()

Determines if cryptography support is available. Returns true on success; false otherwise.

[static] QKnxByteArray QKnxCryptographicEngine::userPasswordHash(const QByteArray &password)

Returns the password hash derived from the user chosen password password.

Note: The salt used in the password-based key derivation function (PBKDF2) is set to user-password.1.secure.ip.knx.org.

© 2021 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.