Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AES-256/GCM fixes #8968

Merged
merged 7 commits into from
Jan 29, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions share/translations/keepassxc_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5823,6 +5823,10 @@ We recommend you use the AppImage available on our downloads page.</source>
<source>Unexpected EOF when writing private key</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>AES-256/GCM is currently not supported</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PasswordEditWidget</name>
Expand Down
21 changes: 20 additions & 1 deletion src/crypto/SymmetricCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ SymmetricCipher::Mode SymmetricCipher::stringToMode(const QString& cipher)
return Aes128_CTR;
} else if (cipher.compare("aes-256-ctr", cs) == 0 || cipher.compare("aes256-ctr", cs) == 0) {
return Aes256_CTR;
} else if (cipher.compare("aes-256-gcm", cs) == 0 || cipher.compare("aes256-gcm", cs) == 0) {
} else if (cipher.compare("aes-256-gcm", cs) == 0 || cipher.startsWith("aes256-gcm", cs)) {
novasharper marked this conversation as resolved.
Show resolved Hide resolved
return Aes256_GCM;
} else if (cipher.startsWith("twofish", cs)) {
return Twofish_CBC;
Expand Down Expand Up @@ -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;
}
}
1 change: 1 addition & 0 deletions src/crypto/SymmetricCipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class SymmetricCipher
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);
Expand Down
9 changes: 6 additions & 3 deletions src/sshagent/OpenSSHKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ bool OpenSSHKey::openKey(const QString& passphrase)
if (cipherMode == SymmetricCipher::InvalidMode) {
m_error = tr("Unknown cipher: %1").arg(m_cipherName);
return false;
} else if (cipherMode == SymmetricCipher::Aes256_GCM) {
m_error = tr("AES-256/GCM is currently not supported");
return false;
}

QByteArray keyData, ivData;
Expand All @@ -325,7 +328,7 @@ bool OpenSSHKey::openKey(const QString& passphrase)
}

int keySize = cipher->keySize(cipherMode);
int blockSize = 16;
int ivSize = cipher->ivSize(cipherMode);

BinaryStream optionStream(&m_kdfOptions);

Expand All @@ -335,7 +338,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);
Expand All @@ -351,7 +354,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");
Expand Down