QXmpp  Version: 1.15.1
Crypto.h
1 // SPDX-FileCopyrightText: 2026 Linus Jahn <lnj@kaidan.im>
2 //
3 // SPDX-License-Identifier: LGPL-2.1-or-later
4 
5 #ifndef CRYPTO_H
6 #define CRYPTO_H
7 
8 #include "QXmppGlobal.h"
9 
10 #include <QByteArray>
11 
12 struct evp_cipher_ctx_st;
13 
14 namespace QXmpp::Private::Crypto {
15 
16 enum Direction {
17  Encrypt,
18  Decrypt,
19 };
20 
21 // secure memory wrapper (OPENSSL_cleanse on destruction)
22 class QXMPP_EXPORT SecureByteArray
23 {
24 public:
25  SecureByteArray() = default;
26  explicit SecureByteArray(int size);
27  explicit SecureByteArray(const QByteArray &data);
28  SecureByteArray(const char *data, int size);
29  ~SecureByteArray();
30 
31  SecureByteArray(const SecureByteArray &other);
32  SecureByteArray &operator=(const SecureByteArray &other);
33  SecureByteArray(SecureByteArray &&other) noexcept;
34  SecureByteArray &operator=(SecureByteArray &&other) noexcept;
35 
36  char *data() { return m_data.data(); }
37  const char *data() const { return m_data.data(); }
38  const char *constData() const { return m_data.constData(); }
39  int size() const { return m_data.size(); }
40  bool isEmpty() const { return m_data.isEmpty(); }
41 
42  // Only shrinking is safe. Growing may reallocate without cleansing the old buffer.
43  void resize(int size);
44 
45  SecureByteArray &append(const SecureByteArray &other);
46  QByteArray toByteArray() const { return m_data; }
47 
48  bool operator==(const SecureByteArray &other) const { return m_data == other.m_data; }
49  bool operator!=(const SecureByteArray &other) const { return m_data != other.m_data; }
50 
51 private:
52  void cleanse();
53  QByteArray m_data;
54 };
55 
56 // one-shot symmetric encryption/decryption
57 QXMPP_EXPORT QByteArray aesGcmEncrypt(const QByteArray &data, const QByteArray &key, const QByteArray &iv);
58 QXMPP_EXPORT QByteArray aesGcmDecrypt(const QByteArray &data, const QByteArray &key, const QByteArray &iv);
59 QXMPP_EXPORT QByteArray aesCbcEncrypt(const QByteArray &data, const QByteArray &key, const QByteArray &iv);
60 QXMPP_EXPORT QByteArray aesCbcDecrypt(const QByteArray &data, const QByteArray &key, const QByteArray &iv);
61 QXMPP_EXPORT QByteArray aesCtrProcess(const QByteArray &data, const QByteArray &key, const QByteArray &iv);
62 
63 // HKDF-SHA256 key derivation (returns SecureByteArray to protect derived key material)
64 QXMPP_EXPORT SecureByteArray hkdfSha256(const QByteArray &key, const QByteArray &salt, const QByteArray &info, int outputLen);
65 
66 // HMAC-SHA256 (uses Qt's QMessageAuthenticationCode)
67 QXMPP_EXPORT QByteArray hmacSha256(const QByteArray &key, const QByteArray &data);
68 
69 // secure random bytes
70 QXMPP_EXPORT QByteArray randomBytes(int count);
71 
72 // constant-time comparison (prevents timing side-channel attacks)
73 QXMPP_EXPORT bool constTimeEqual(const QByteArray &a, const QByteArray &b);
74 
75 // streaming cipher context for QIODevice wrappers
76 class QXMPP_EXPORT CipherContext
77 {
78 public:
79  CipherContext(Cipher cipher, Direction direction, const QByteArray &key, const QByteArray &iv);
80  ~CipherContext();
81 
82  CipherContext(const CipherContext &) = delete;
83  CipherContext &operator=(const CipherContext &) = delete;
84 
85  QByteArray update(const QByteArray &data);
86  QByteArray finalize();
87  bool validKeyLength(int length) const;
88 
89 private:
90  evp_cipher_ctx_st *m_ctx = nullptr;
91  Cipher m_cipher;
92 };
93 
94 } // namespace QXmpp::Private::Crypto
95 
96 #endif // CRYPTO_H
Definition: Crypto.cpp:14
Cipher
Definition: QXmppGlobal.h:172