summarylogtreecommitdiffstats
path: root/0001-Add-support-for-Twofish-in-KeePass2-code.patch
blob: f18f81106bda54ec867a7469ca1ee12e5252137f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From c259ce3d6ae1476a8ad8b6093fc7c81efc24173e Mon Sep 17 00:00:00 2001
From: Timothy Redaelli <timothy.redaelli@gmail.com>
Date: Tue, 4 Aug 2015 15:18:41 +0200
Subject: [PATCH 1/3] Add support for Twofish in KeePass2 code

---
 src/format/KeePass2.h         |  1 +
 src/format/KeePass2Reader.cpp | 25 ++++++++++++++++---------
 src/format/KeePass2Writer.cpp | 21 ++++++++++++++-------
 3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/src/format/KeePass2.h b/src/format/KeePass2.h
index b49ae4f6..91ee4829 100644
--- a/src/format/KeePass2.h
+++ b/src/format/KeePass2.h
@@ -33,6 +33,7 @@ namespace KeePass2
     const QSysInfo::Endian BYTEORDER = QSysInfo::LittleEndian;
 
     const Uuid CIPHER_AES = Uuid(QByteArray::fromHex("31c1f2e6bf714350be5805216afc5aff"));
+    const Uuid CIPHER_TWOFISH = Uuid(QByteArray::fromHex("ad68f29f576f4bb9a36ad47af965346c"));
 
     const QByteArray INNER_STREAM_SALSA20_IV("\xE8\x30\x09\x4B\x97\x20\x5D\x2A");
 
diff --git a/src/format/KeePass2Reader.cpp b/src/format/KeePass2Reader.cpp
index 2a25001c..9b5a8684 100644
--- a/src/format/KeePass2Reader.cpp
+++ b/src/format/KeePass2Reader.cpp
@@ -44,6 +44,7 @@ KeePass2Reader::KeePass2Reader()
 
 Database* KeePass2Reader::readDatabase(QIODevice* device, const CompositeKey& key)
 {
+    QScopedPointer<SymmetricCipherStream> cipherStream;
     QScopedPointer<Database> db(new Database());
     m_db = db.data();
     m_device = device;
@@ -110,25 +111,31 @@ Database* KeePass2Reader::readDatabase(QIODevice* device, const CompositeKey& ke
     hash.addData(m_db->transformedMasterKey());
     QByteArray finalKey = hash.result();
 
-    SymmetricCipherStream cipherStream(m_device, SymmetricCipher::Aes256,
-                                       SymmetricCipher::Cbc, SymmetricCipher::Decrypt);
-    if (!cipherStream.init(finalKey, m_encryptionIV)) {
-        raiseError(cipherStream.errorString());
+    if (m_db->cipher() == KeePass2::CIPHER_AES) {
+        cipherStream.reset(new SymmetricCipherStream(m_device, SymmetricCipher::Aes256,
+                                                     SymmetricCipher::Cbc, SymmetricCipher::Decrypt));
+    }
+    else {
+         cipherStream.reset(new SymmetricCipherStream(m_device, SymmetricCipher::Twofish,
+                                                      SymmetricCipher::Cbc, SymmetricCipher::Decrypt));
+    }
+    if (!cipherStream->init(finalKey, m_encryptionIV)) {
+        raiseError(cipherStream->errorString());
         return Q_NULLPTR;
     }
-    if (!cipherStream.open(QIODevice::ReadOnly)) {
-        raiseError(cipherStream.errorString());
+    if (!cipherStream->open(QIODevice::ReadOnly)) {
+        raiseError(cipherStream->errorString());
         return Q_NULLPTR;
     }
 
-    QByteArray realStart = cipherStream.read(32);
+    QByteArray realStart = cipherStream->read(32);
 
     if (realStart != m_streamStartBytes) {
         raiseError(tr("Wrong key or database file is corrupt."));
         return Q_NULLPTR;
     }
 
-    HashedBlockStream hashedStream(&cipherStream);
+    HashedBlockStream hashedStream(cipherStream.data());
     if (!hashedStream.open(QIODevice::ReadOnly)) {
         raiseError(hashedStream.errorString());
         return Q_NULLPTR;
@@ -312,7 +319,7 @@ void KeePass2Reader::setCipher(const QByteArray& data)
     else {
         Uuid uuid(data);
 
-        if (uuid != KeePass2::CIPHER_AES) {
+        if (uuid != KeePass2::CIPHER_AES && uuid != KeePass2::CIPHER_TWOFISH) {
             raiseError("Unsupported cipher");
         }
         else {
diff --git a/src/format/KeePass2Writer.cpp b/src/format/KeePass2Writer.cpp
index f233ac73..4a6ad713 100644
--- a/src/format/KeePass2Writer.cpp
+++ b/src/format/KeePass2Writer.cpp
@@ -86,18 +86,25 @@ void KeePass2Writer::writeDatabase(QIODevice* device, Database* db)
     m_device = device;
     QByteArray headerHash = CryptoHash::hash(header.data(), CryptoHash::Sha256);
     CHECK_RETURN(writeData(header.data()));
+    QScopedPointer<SymmetricCipherStream> cipherStream;
 
-    SymmetricCipherStream cipherStream(device, SymmetricCipher::Aes256, SymmetricCipher::Cbc,
-                                       SymmetricCipher::Encrypt);
-    cipherStream.init(finalKey, encryptionIV);
-    if (!cipherStream.open(QIODevice::WriteOnly)) {
-        raiseError(cipherStream.errorString());
+    if (db->cipher() == KeePass2::CIPHER_AES) {
+        cipherStream.reset(new SymmetricCipherStream(device, SymmetricCipher::Aes256,
+                                                     SymmetricCipher::Cbc, SymmetricCipher::Encrypt));
+    }
+    else {
+        cipherStream.reset(new SymmetricCipherStream(device, SymmetricCipher::Twofish,
+                                                     SymmetricCipher::Cbc, SymmetricCipher::Encrypt));
+    }
+    cipherStream->init(finalKey, encryptionIV);
+    if (!cipherStream->open(QIODevice::WriteOnly)) {
+        raiseError(cipherStream->errorString());
         return;
     }
-    m_device = &cipherStream;
+    m_device = cipherStream.data();
     CHECK_RETURN(writeData(startBytes));
 
-    HashedBlockStream hashedStream(&cipherStream);
+    HashedBlockStream hashedStream(cipherStream.data());
     if (!hashedStream.open(QIODevice::WriteOnly)) {
         raiseError(hashedStream.errorString());
         return;
-- 
2.5.0