File indexing completed on 2024-04-28 05:50:04
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com> 0004 */ 0005 #include "secrets/secrets.h" 0006 0007 #include <QTest> 0008 #include <QtDebug> 0009 0010 #include <string.h> 0011 0012 class EncryptionDecryptionRoundTripTest: public QObject 0013 { 0014 Q_OBJECT 0015 private Q_SLOTS: 0016 void testEncryptionDecryptionRoundTrip(void); 0017 void testDecryptionOfCorruptInputs(void); 0018 }; 0019 0020 void EncryptionDecryptionRoundTripTest::testEncryptionDecryptionRoundTrip(void) 0021 { 0022 QScopedPointer<secrets::SecureMemory> passwd(secrets::SecureMemory::allocate(13ULL)); 0023 QVERIFY2(passwd, "password memory should be allocated"); 0024 memcpy(passwd->data(), "Hello, world!", passwd->size()); 0025 0026 std::optional<secrets::KeyDerivationParameters> defaults = secrets::KeyDerivationParameters::create(); 0027 QVERIFY2(defaults, "defaults should yield a valid key parameters object"); 0028 0029 QScopedPointer<secrets::SecureMasterKey> masterKey(secrets::SecureMasterKey::derive(passwd.data(), *defaults)); 0030 QVERIFY2(masterKey, "key derivation should succeed"); 0031 0032 QScopedPointer<secrets::SecureMemory> payload(secrets::SecureMemory::allocate(42ULL)); 0033 QVERIFY2(payload, "allocating the secure memory input buffer should succeed"); 0034 0035 memset(payload->data(), 'B', 42ULL); 0036 0037 std::optional<secrets::EncryptedSecret> encrypted = masterKey->encrypt(payload.data()); 0038 QVERIFY2(encrypted, "encryption of the payload should succeed"); 0039 0040 QScopedPointer<secrets::SecureMemory> decrypted(masterKey->decrypt(*encrypted)); 0041 QVERIFY2(decrypted, "decryption should succeed"); 0042 0043 QCOMPARE(decrypted->size(), 42ULL); 0044 0045 QByteArray copyOfDecrypted; 0046 copyOfDecrypted.append(reinterpret_cast<const char *>(decrypted->constData()), 42ULL); 0047 0048 QByteArray expected(42, 'B'); 0049 QCOMPARE(copyOfDecrypted, expected); 0050 } 0051 0052 void EncryptionDecryptionRoundTripTest::testDecryptionOfCorruptInputs(void) 0053 { 0054 QScopedPointer<secrets::SecureMemory> passwd(secrets::SecureMemory::allocate(13ULL)); 0055 QVERIFY2(passwd, "password memory should be allocated"); 0056 memcpy(passwd->data(), "Hello, world!", passwd->size()); 0057 0058 std::optional<secrets::KeyDerivationParameters> defaults = secrets::KeyDerivationParameters::create(); 0059 QVERIFY2(defaults, "defaults should yield a valid key parameters object"); 0060 0061 QScopedPointer<secrets::SecureMasterKey> masterKey(secrets::SecureMasterKey::derive(passwd.data(), *defaults)); 0062 QVERIFY2(masterKey, "key derivation should succeed"); 0063 0064 QScopedPointer<secrets::SecureMemory> payload(secrets::SecureMemory::allocate(42ULL)); 0065 QVERIFY2(payload, "allocating the secure memory input buffer should succeed"); 0066 0067 memset(payload->data(), 'B', 42ULL); 0068 0069 std::optional<secrets::EncryptedSecret> encrypted = masterKey->encrypt(payload.data()); 0070 QVERIFY2(encrypted, "encryption of the payload should succeed"); 0071 0072 QByteArray brokenTag(encrypted->cryptText()); 0073 brokenTag[0] = brokenTag[0] ^ ((char) 0xFF); 0074 0075 std::optional<secrets::EncryptedSecret> fakedTag = secrets::EncryptedSecret::from(brokenTag, encrypted->nonce()); 0076 QVERIFY2(fakedTag, "should be able to construct the 'fake' encrypted input (tag)"); 0077 0078 QScopedPointer<secrets::SecureMemory> decryptedUsingFakeTag(masterKey->decrypt(*fakedTag)); 0079 QVERIFY2(!decryptedUsingFakeTag, "decryption should fail when the authentication tag has been tampered with"); 0080 0081 QByteArray brokenPayload(encrypted->cryptText()); 0082 brokenPayload[brokenPayload.size() - 1] = brokenPayload[brokenPayload.size() - 1] ^ ((char) 0xFF); 0083 0084 std::optional<secrets::EncryptedSecret> fakedPayload = secrets::EncryptedSecret::from(brokenPayload, encrypted->nonce()); 0085 QVERIFY2(fakedPayload, "should be able to construct the 'fake' encrypted input (payload)"); 0086 0087 QScopedPointer<secrets::SecureMemory> decryptedUsingFakePayload(masterKey->decrypt(*fakedPayload)); 0088 QVERIFY2(!decryptedUsingFakePayload, "decryption should fail when the payload has been tampered with"); 0089 0090 QByteArray brokenNonce(encrypted->nonce()); 0091 brokenNonce[0] = brokenNonce[0] ^ ((char) 0xFF); 0092 0093 std::optional<secrets::EncryptedSecret> fakedNonce = secrets::EncryptedSecret::from(encrypted->cryptText(), brokenNonce); 0094 QVERIFY2(fakedNonce, "should be able to construct the 'fake' encrypted input (nonce)"); 0095 0096 QScopedPointer<secrets::SecureMemory> decryptedUsingFakeNonce(masterKey->decrypt(*fakedNonce)); 0097 QVERIFY2(!decryptedUsingFakeNonce, "decryption should fail when the nonce has been tampered with"); 0098 } 0099 0100 QTEST_APPLESS_MAIN(EncryptionDecryptionRoundTripTest) 0101 0102 #include "encrypt-decrypt-rt.moc"