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

Static Public Members

QKnxByteArray XOR(const QKnxByteArray &left, const QKnxByteArray &right, bool adjust = true)
QKnxByteArray calculateMessageAuthenticationCode(const QKnxByteArray &key, const QKnxNetIpFrameHeader &header, quint16 id, const QKnxByteArray &data, quint48 sequenceNumber = 0, const QKnxByteArray &serialNumber = {}, quint16 messageTag = 0)
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 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 pkcs5Pbkdf2HmacSha256(const QByteArray &password, const QKnxByteArray &salt, qint32 iterations, quint8 derivedKeyLength)
QKnxByteArray sessionKey(const QKnxByteArray &sharedSecret)
QKnxByteArray sessionKey(const QKnxCurve25519PublicKey &pub, const QKnxCurve25519PrivateKey &priv)
QKnxByteArray sharedSecret(const QKnxCurve25519PublicKey &pub, const QKnxCurve25519PrivateKey &priv)
QKnxByteArray userPasswordHash(const QByteArray &password)

Detailed Description

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

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 calculateMessageAuthenticationCode() function can be used to compute a message authentication code (MAC) for a KNXnet/IP secure frame. The fields that are used to calculate 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 calculate 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::calculateMessageAuthenticationCode(deviceAuthenticationHash,
    netIpFrame.header(), secureSessionIdentifier, XOR_X_Y);

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


// Session Authenticate Frame

quint16 userId = 0x0001; // management level access
auto authenticateBuilder = QKnxNetIpSessionAuthenticateProxy::builder()'

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

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

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

// create the final frame including the calculated 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::calculateMessageAuthenticationCode(backboneKey,
    netIpFrame.header(), dummySession, dummyPayload, timerValue, serialNumber, messageTag);

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

Member Function Documentation

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

Performs a bytewise 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::calculateMessageAuthenticationCode(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 calculated MAC or an empty byte array in case of an error.

Note: The sequenceNumber, serialNumber, and messageTag values are required to calculate 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::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) function is set to device-authentication-code.1.secure.ip.knx.org.

See also pkcs5Pbkdf2HmacSha256().

[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::pkcs5Pbkdf2HmacSha256(const QByteArray &password, const QKnxByteArray &salt, qint32 iterations, quint8 derivedKeyLength)

Returns the hash code derived from the user chosen password password, with the given salt and iterations. The value of derivedKeyLength should be in the range 0 to 32.

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

Returns the session key calculated from the given secret sharedSecret.

[static] QKnxByteArray QKnxCryptographicEngine::sessionKey(const QKnxCurve25519PublicKey &pub, const QKnxCurve25519PrivateKey &priv)

Returns the session key calculated from the given peer public key pub and the private key priv.

[static] QKnxByteArray QKnxCryptographicEngine::sharedSecret(const QKnxCurve25519PublicKey &pub, const QKnxCurve25519PrivateKey &priv)

Derives and returns the shared secret from the given public peer key pub and the private key priv if OpenSSL is available and no error occurs; otherwise returns a default-constructed value which can be empty.

[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) function is set to user-password.1.secure.ip.knx.org.

See also pkcs5Pbkdf2HmacSha256().

© 2018 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.