libQuotient
A Qt library for building matrix clients
Loading...
Searching...
No Matches
cryptoutils.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
2// SPDX-License-Identifier: LGPL-2.0-or-later
3
4#pragma once
5
6#include "e2ee_common.h"
7#include "../expected.h"
8
9#include "../quotient_export.h"
10
11#include <QtCore/QByteArray>
12#include <QtCore/QString>
13
14namespace Quotient {
15
16// Common remark: OpenSSL is a private dependency of libQuotient, meaning that
17// headers of libQuotient can't include OpenSSL headers. Instead, alias
18// the value or type along with a comment (see SslErrorCode e.g.) and add
19// static_assert in the .cpp file to check it against the OpenSSL definition.
20
21constexpr auto DefaultPbkdf2KeyLength = 32u;
22constexpr auto Aes256KeySize = 32u;
23constexpr auto AesBlockSize = 16u; // AES_BLOCK_SIZE
24constexpr auto HmacKeySize = 32u;
25
28 //! \brief Key to be used for AES encryption / decryption
29 auto aes() const { return asCBytes(*this).first<Aes256KeySize>(); }
30 //! \brief Key to be used for MAC creation / verification
31 auto mac() const { return asCBytes(*this).last<HmacKeySize>(); }
32};
33
38};
39
40// NOLINTNEXTLINE(google-runtime-int): the type is copied from OpenSSL
41using SslErrorCode = unsigned long; // decltype(ERR_get_error())
42
43template <size_t Size = DefaultPbkdf2KeyLength>
44using key_material_t = std::array<byte_t, Size>;
45using key_view_t = byte_view_t<DefaultPbkdf2KeyLength>;
46
48 SslErrorUserOffset = 128, // ERR_LIB_USER; never use this bare
51};
52
53//! Same as QOlmExpected but for wrapping OpenSSL instead of Olm calls
54template <typename T>
55using SslExpected = Expected<T, SslErrorCode>;
56
57// TODO, 0.9: merge zeroedByteArray() into zeroes() and replace const QByteArray& with
58// QByteArrayView where OpenSSL/Olm expect an array of signed chars
59
60inline QByteArray zeroedByteArray(QByteArray::size_type n = 32) { return { n, '\0' }; }
61
62template <size_t N, typename T = uint8_t> consteval std::array<T, N> zeroes() { return {}; }
63
64namespace _impl {
65 QUOTIENT_API SslErrorCode pbkdf2HmacSha512(const QByteArray& passphrase, const QByteArray& salt,
66 int iterations, byte_span_t<> output);
67}
68
69//! Generate a key out of the given passphrase
70template <size_t Size = DefaultPbkdf2KeyLength>
71QUOTIENT_API inline SslExpected<key_material_t<Size>> pbkdf2HmacSha512(const QByteArray& passphrase,
72 const QByteArray& salt,
73 int iterations)
74{
75 key_material_t<Size> result;
76 if (auto code = _impl::pbkdf2HmacSha512(passphrase, salt, iterations, result); code != 0)
77 return code;
78 return result;
79}
80
81//! \brief Derive a key from the input data using HKDF-SHA256
82//!
83//! The info parameter should be either 0 or 32 bytes long
84QUOTIENT_API SslExpected<HkdfKeys> hkdfSha256(key_view_t key, byte_view_t<32> salt,
85 byte_view_t<> info);
86
87//! Calculate a MAC from the given key and data
88QUOTIENT_API SslExpected<QByteArray> hmacSha256(
89 byte_view_t<HmacKeySize> hmacKey,
90 const QByteArray& data);
91
92//! \brief Decrypt the data using Curve25519-AES-Sha256
93//! \note ciphertext must be given as base64
94QUOTIENT_API QOlmExpected<QByteArray> curve25519AesSha2Decrypt(
95 QByteArray ciphertext, const QByteArray& privateKey,
96 const QByteArray& ephemeral, const QByteArray& mac);
97
98//! \brief Encrypt the data using Curve25519-AES-Sha256
99//! \note publicKey must be given as base64
100QUOTIENT_API QOlmExpected<Curve25519Encrypted> curve25519AesSha2Encrypt(
101 const QByteArray& plaintext, const QByteArray& publicKey);
102
103//! \brief Encrypt data using AES-CTR-256
104//!
105//! key and iv have a length of 32 bytes
106QUOTIENT_API SslExpected<QByteArray> aesCtr256Encrypt(
107 const QByteArray& plaintext, byte_view_t<Aes256KeySize> key,
108 byte_view_t<AesBlockSize> iv);
109
110//! \brief Decrypt data using AES-CTR-256
111//!
112//! key and iv have a length of 32 bytes
113QUOTIENT_API SslExpected<QByteArray> aesCtr256Decrypt(
114 const QByteArray& ciphertext, byte_view_t<Aes256KeySize> key,
115 byte_view_t<AesBlockSize> iv);
116
117QUOTIENT_API std::vector<byte_t> base58Decode(const QByteArray& encoded);
118
119QUOTIENT_API QByteArray sign(const QByteArray &key, const QByteArray &data);
120
121} // namespace Quotient
consteval std::array< T, N > zeroes()
Definition cryptoutils.h:62
constexpr auto DefaultPbkdf2KeyLength
Definition cryptoutils.h:21
@ SslPayloadTooLong
Definition cryptoutils.h:50
@ WrongDerivedKeyLength
Definition cryptoutils.h:49
@ SslErrorUserOffset
Definition cryptoutils.h:48
constexpr auto AesBlockSize
Definition cryptoutils.h:23
constexpr auto HmacKeySize
Definition cryptoutils.h:24
QByteArray zeroedByteArray(QByteArray::size_type n=32)
Definition cryptoutils.h:60
constexpr auto Aes256KeySize
Definition cryptoutils.h:22
#define QUOTIENT_API