diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts
index c26090a7..590fec57 100644
--- a/share/translations/keepassxc_en.ts
+++ b/share/translations/keepassxc_en.ts
@@ -5764,6 +5764,10 @@ We recommend you use the AppImage available on our downloads page.
Unexpected EOF when writing private key
+
+ AES-256/GCM is currently not supported
+
+
PasswordEditWidget
diff --git a/src/crypto/SymmetricCipher.cpp b/src/crypto/SymmetricCipher.cpp
index 4d3a7bdf..1ed05bb3 100644
--- a/src/crypto/SymmetricCipher.cpp
+++ b/src/crypto/SymmetricCipher.cpp
@@ -267,3 +267,22 @@ int SymmetricCipher::blockSize(Mode mode)
return 0;
}
}
+
+int SymmetricCipher::ivSize(Mode mode)
+{
+ switch (mode) {
+ case Aes128_CBC:
+ case Aes256_CBC:
+ case Aes128_CTR:
+ case Aes256_CTR:
+ case Twofish_CBC:
+ return 16;
+ case Aes256_GCM:
+ return 12;
+ case Salsa20:
+ case ChaCha20:
+ return 8;
+ default:
+ return 0;
+ }
+}
diff --git a/src/crypto/SymmetricCipher.h b/src/crypto/SymmetricCipher.h
index 83b54658..e18f623f 100644
--- a/src/crypto/SymmetricCipher.h
+++ b/src/crypto/SymmetricCipher.h
@@ -70,6 +70,7 @@ public:
static int defaultIvSize(Mode mode);
static int keySize(Mode mode);
static int blockSize(Mode mode);
+ static int ivSize(Mode mode);
private:
static QString modeToString(const Mode mode);
diff --git a/src/sshagent/OpenSSHKey.cpp b/src/sshagent/OpenSSHKey.cpp
index e7a2a9b8..e6b21c86 100644
--- a/src/sshagent/OpenSSHKey.cpp
+++ b/src/sshagent/OpenSSHKey.cpp
@@ -30,6 +30,7 @@
const QString OpenSSHKey::TYPE_DSA_PRIVATE = "DSA PRIVATE KEY";
const QString OpenSSHKey::TYPE_RSA_PRIVATE = "RSA PRIVATE KEY";
const QString OpenSSHKey::TYPE_OPENSSH_PRIVATE = "OPENSSH PRIVATE KEY";
+const QString OpenSSHKey::OPENSSH_CIPHER_SUFFIX = "@openssh.com";
OpenSSHKey::OpenSSHKey(QObject* parent)
: QObject(parent)
@@ -310,9 +311,16 @@ bool OpenSSHKey::openKey(const QString& passphrase)
QByteArray rawData = m_rawData;
if (m_cipherName != "none") {
- auto cipherMode = SymmetricCipher::stringToMode(m_cipherName);
+ QString l_cipherName(m_cipherName);
+ if (l_cipherName.endsWith(OPENSSH_CIPHER_SUFFIX)) {
+ l_cipherName.remove(OPENSSH_CIPHER_SUFFIX);
+ }
+ auto cipherMode = SymmetricCipher::stringToMode(l_cipherName);
if (cipherMode == SymmetricCipher::InvalidMode) {
- m_error = tr("Unknown cipher: %1").arg(m_cipherName);
+ m_error = tr("Unknown cipher: %1").arg(l_cipherName);
+ return false;
+ } else if (cipherMode == SymmetricCipher::Aes256_GCM) {
+ m_error = tr("AES-256/GCM is currently not supported");
return false;
}
@@ -325,7 +333,7 @@ bool OpenSSHKey::openKey(const QString& passphrase)
}
int keySize = cipher->keySize(cipherMode);
- int blockSize = 16;
+ int ivSize = cipher->ivSize(cipherMode);
BinaryStream optionStream(&m_kdfOptions);
@@ -335,7 +343,7 @@ bool OpenSSHKey::openKey(const QString& passphrase)
optionStream.readString(salt);
optionStream.read(rounds);
- QByteArray decryptKey(keySize + blockSize, '\0');
+ QByteArray decryptKey(keySize + ivSize, '\0');
try {
auto baPass = passphrase.toUtf8();
auto pwhash = Botan::PasswordHashFamily::create_or_throw("Bcrypt-PBKDF")->from_iterations(rounds);
@@ -351,7 +359,7 @@ bool OpenSSHKey::openKey(const QString& passphrase)
}
keyData = decryptKey.left(keySize);
- ivData = decryptKey.right(blockSize);
+ ivData = decryptKey.right(ivSize);
} else if (m_kdfName == "md5") {
if (m_cipherIV.length() < 8) {
m_error = tr("Cipher IV is too short for MD5 kdf");
diff --git a/src/sshagent/OpenSSHKey.h b/src/sshagent/OpenSSHKey.h
index 78ccf719..a42e433d 100644
--- a/src/sshagent/OpenSSHKey.h
+++ b/src/sshagent/OpenSSHKey.h
@@ -58,6 +58,7 @@ public:
static const QString TYPE_DSA_PRIVATE;
static const QString TYPE_RSA_PRIVATE;
static const QString TYPE_OPENSSH_PRIVATE;
+ static const QString OPENSSH_CIPHER_SUFFIX;
private:
enum KeyPart