From ca7047d4af12a59df3af442fe8a5a4ff04f97b53 Mon Sep 17 00:00:00 2001 From: Johannes Huber Date: Tue, 20 Jan 2015 21:07:59 +0000 Subject: [PATCH] Revision bumps backports upstream patch to fix CVE-2013-7252, bug #496768. Package-Manager: portage-2.2.15/cvs/Linux x86_64 Manifest-Sign-Key: 0xF3CFD2BD --- kde-base/kwalletd/ChangeLog | 10 +- kde-base/kwalletd/Manifest | 24 +- .../files/kwalletd-4.14.3-CVE-2013-7252.patch | 777 ++++++++++++++++++ kde-base/kwalletd/kwalletd-4.14.3-r1.ebuild | 34 + 4 files changed, 842 insertions(+), 3 deletions(-) create mode 100644 kde-base/kwalletd/files/kwalletd-4.14.3-CVE-2013-7252.patch create mode 100644 kde-base/kwalletd/kwalletd-4.14.3-r1.ebuild diff --git a/kde-base/kwalletd/ChangeLog b/kde-base/kwalletd/ChangeLog index d8a6ff2558fc..2d3f013d7786 100644 --- a/kde-base/kwalletd/ChangeLog +++ b/kde-base/kwalletd/ChangeLog @@ -1,6 +1,12 @@ # ChangeLog for kde-base/kwalletd -# Copyright 1999-2014 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/kde-base/kwalletd/ChangeLog,v 1.228 2014/12/11 15:45:07 mrueg Exp $ +# Copyright 1999-2015 Gentoo Foundation; Distributed under the GPL v2 +# $Header: /var/cvsroot/gentoo-x86/kde-base/kwalletd/ChangeLog,v 1.229 2015/01/20 21:07:52 johu Exp $ + +*kwalletd-4.14.3-r1 (20 Jan 2015) + + 20 Jan 2015; Johannes Huber + +files/kwalletd-4.14.3-CVE-2013-7252.patch, +kwalletd-4.14.3-r1.ebuild: + Revision bumps backports upstream patch to fix CVE-2013-7252, bug #496768. 11 Dec 2014; Manuel Rüger -kwalletd-4.14.2.ebuild: Remove KDE SC 4.14.2 diff --git a/kde-base/kwalletd/Manifest b/kde-base/kwalletd/Manifest index 298ac78e1af3..068e4a498140 100644 --- a/kde-base/kwalletd/Manifest +++ b/kde-base/kwalletd/Manifest @@ -1,6 +1,28 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +AUX kwalletd-4.14.3-CVE-2013-7252.patch 21806 SHA256 08d048f6a90be17d51522660d02acda1fdb55fc375ce0214bc554ef2c3d940c4 SHA512 f1091235ab0ad4f6ef8e52ef2d2b5090c195596ba7ff21221c7b69935db5ad37741340c7cd24d7da0e931e05504b3d2b5800c1c7a368a4f9c1589462cb7b5892 WHIRLPOOL 2d091daa76f699b02a1e58150b0d542dcbcca57eb4c1dd85dc1760247c55ec0d68fecb758a9bc619e3720bfca152d8ed7ca1380b9a84455dd40c3e4fddf322a8 DIST kde-runtime-4.12.5.tar.xz 7856352 SHA256 b43e1aebd7e9dd13677f2205bb6eef7ee02a7085ae9fd34a39bad55d5df56fe7 SHA512 777916ea15cf5e36218e36a2b67758dbaa2bbdbdc50c3c67d65b69085416502962ece4977a81a182197ab733f44735ddf9b539a3c76cc70a98bdcece368491dd WHIRLPOOL 8c7adec7a55d8126ac7aba4964c42057831c7d26f69e33aa319adc701ef7f368d094c9b3e88b12e729682aa0da8789b5b69cab55737b4be1d1a9020649dc5ac5 DIST kde-runtime-4.14.3.tar.xz 7867308 SHA256 78a74e519b4e897ffcee14be98eebd7b672ad2bb6e71a4aa2fe77682b5bc8605 SHA512 63b13f947915bb2eca5b85886610d1af480956b9e95a1ae77ce7c10b11576883a71bebf519335323a1f6c5dfcebe2ee0561b727cea6243756d412d9323feb244 WHIRLPOOL 4d021d826eb2ba553bb6fa320f71ed3d1f1614aef29f2d9e26285eabb9c015e6577e85ee6b0874cd1f8b89ef33cfa3dde5a6002e2178a11ede38cb8bf471a5a2 EBUILD kwalletd-4.12.5.ebuild 694 SHA256 d938bb7c226149dd7150f0f577fdaa5fa9a0bd70313aad0037c106bf3213fe4e SHA512 75c43d6bfe4164181bbe60d4e5c94a352b4731c07daa19e9005f727da35cfab45f2f2155aa7ee2e6790cd18de473c8d60d1526006b4ac7e4d2331a67dc07e6e3 WHIRLPOOL 6fa8f0c0f0600c8981bd8f517a9d27e832561d2c80420aac8a304956d93ba8a01cfe1a188b54832fb42e3127a2f0eb29ab3c4932c05d89283f8f38432a497ef5 +EBUILD kwalletd-4.14.3-r1.ebuild 781 SHA256 9f287cb559c5a96781cc556a9f95497aff3af55ff2d5934d7152e53fe5be8964 SHA512 4ec2e6ba792d59b7f4fc1497e66d1ec9d3490ff7fb5a0873345ee8733dcd8e3895a488411de2cb1873ad73b01e85cea01ab2fe09f85dd14ab1e6a8217718fce2 WHIRLPOOL ef3d5b07dcdaf684f80e0eee49bbe66d6a597a1028676bb87a8549581f4c4165f4ea49cebb77aae5fde5af789e877da764cd68b65310f25f06e678e95f08e8b2 EBUILD kwalletd-4.14.3.ebuild 728 SHA256 e17ced270175345cf919a706cb40d0ef334d6901bb6a98939a4639d972d32ed5 SHA512 a4582692d9766c09373625b14c20e61937999f1dd48699fb6c9651ac555b3420d7f93b93de4f4caf144da85d93e60cfce5ac36d3cb87bef0e84adfa8d645f109 WHIRLPOOL c2ce234062e1941fac0414900f7fe6bb0734c09aada8afe93bc8ab4904135153688a6d4254e9b314af0d1a0f1af9cdbfad2dc4cb496640b207c34b725a5a7c5d -MISC ChangeLog 26788 SHA256 48d523f2c7228fde92c426291bf72ff6838e5ca64d3ae9341f3aa153bacd4a49 SHA512 4c6aae330188795e406c4a0bf1a8b88e8d23942112b68987dc861a3327103661b472e1e93ceba058429eb748f42e0a92c528e36a264440f06263ff6fdca30fd7 WHIRLPOOL b696eb481ebbb052146354714204b080d526a53ec2e383a137ae376f40db1189da64f1d713a1e75b25458fc1dc09ef97f75cb996516226a3a5c03fac4c9d3fbc +MISC ChangeLog 27022 SHA256 1c336811b7b1ed9f6d9e69ec82b3075935f6bb8e5e127201d689394271ee00be SHA512 a5847e4e386fd22ca9ea595388e9539103f8dd3b26b7a4672c69b8b225490c66fee0df13c947529fcd07cf1411a881e69c1ce4eb7a217ae001275cb836b19cc1 WHIRLPOOL 6767bca53b8a46e80b77b170cf077e970ab4029d5fa03f56aa622225cb043b884d3d41b0f2618cb14f9f9b55182302719c73eb420b0f02a8ca6bff1c19b8dc5b MISC metadata.xml 280 SHA256 2a89088a60a3a553f10e587547ae1f20d6f9ef11a19adea0ee1f1bf64c7699b1 SHA512 872f8f6e475a90b03742078986ae1776e83c1c9f2cb7259c4e134b24e00990a81a9381921bd40e7fc5aeb3106c828dfa81f57969fd185866c44d285b991cc413 WHIRLPOOL f5974a759fda2aebc8e2954afba7172c5e8bc92d6e0fa5da48f2c7264bcec14e2f1114ae2db2cba40221457808b007102a29e6176f2cd335b997cd69b14827d8 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQIcBAEBCAAGBQJUvsOsAAoJEGVpnaTzz9K9UdUQAILn3D8Dgv5AWy9s2gN/MAM8 +3WiWTD20BpJWYEb0rnTJhbK8SOXHjfqXTV7U9CFiS1qCzlj+yzhfqtXva/Tw/cWu +jXj5Hrlmrx2oUELFr9vjie2TrVl6UeUSxqDQ7VAZUFOVOSnfX5UM3f0lNNl/Etxg +lVNaoC3HScPuu+jTPofY5f0HOSHWORPLniPaGc1J0zQCmlSxUpR3teN6xT1W0t3K +FebtZ49rsNAWo0b5dsrogUBhEGnOs+foQvDXYYtSoC3F9czXpx7gYTkfZuJjSvj4 +mLhTCVAsptftAVg2HB4KiHi5U9ukXzQ8OSFOqgTLl3kcnll7CkAbvxH+IVPrHR1f +M66Ym7UJ1PWNz7imHE/HhNcyMYb6S4QU9+eSlzn3gejfIJwcHYMFL5J3th1+AVoM +Qv7w6Dh9IAnIFH3bfD5aLjq3igqlB4FnFghbAL2llLQocxO8wQAlp8N1YQFM04Zd +4fZaT5R268gXGO1KEHHnawW/Rq1yItgNROBz3T1daVH0PB0OklsbDaqq2HA1yOR1 +mmFRIX0Veh3c5jfq/gr/jeZhWbcSpBLhY6neAOJV7+IwbIvXXvU0wflQRkMWLSY7 +w0YHYd+5RLwtA9catY4hUBMrIuFWkCU20aV6UK4c5sG3RceG7CDuTFmPr4+aRUeX +UYzLj3Hm5Q1Wz3lKu2J/ +=cWFU +-----END PGP SIGNATURE----- diff --git a/kde-base/kwalletd/files/kwalletd-4.14.3-CVE-2013-7252.patch b/kde-base/kwalletd/files/kwalletd-4.14.3-CVE-2013-7252.patch new file mode 100644 index 000000000000..9019e17516b0 --- /dev/null +++ b/kde-base/kwalletd/files/kwalletd-4.14.3-CVE-2013-7252.patch @@ -0,0 +1,777 @@ +From 466859302095a4ee4a9214ab24144eab7697224f Mon Sep 17 00:00:00 2001 +From: Valentin Rusu +Date: Mon, 5 Jan 2015 23:00:58 +0100 +Subject: [PATCH] Backporting CBC algorithm fix from frameworks/kwallet + +The CBC algorithm was not enrcrypting in CBC but in ECB, despite it being +named CBC. This problem was found by Itay Duvdevani who let us know it on the +security mailing list. His mail eventually got forwarded to me and here is the +fix. I also fixed the test program which was incorrectly checking the +expected bytes. + +This commit corresponds to the following commits from: +frameworks/kwallet + 88bc1ff01e5fdf59a13fe012aa03e31e9eb8a3b1 + 6e588d795e6631c3c9d84d85fd3884a159b45849 +--- + kwalletd/backend/backendpersisthandler.cpp | 67 ++++--- + kwalletd/backend/backendpersisthandler.h | 4 +- + kwalletd/backend/cbc.cc | 273 ++++++++++++++++++----------- + kwalletd/backend/cbc.h | 44 ++--- + kwalletd/backend/tests/testbf.cpp | 96 +++++----- + 5 files changed, 279 insertions(+), 205 deletions(-) + +diff --git a/kwalletd/backend/backendpersisthandler.cpp b/kwalletd/backend/backendpersisthandler.cpp +index 126210a..5c321c9 100644 +--- a/kwalletd/backend/backendpersisthandler.cpp ++++ b/kwalletd/backend/backendpersisthandler.cpp +@@ -40,14 +40,15 @@ + #include "sha1.h" + #include "cbc.h" + +-#ifdef Q_OS_WIN ++#ifdef Q_OS_WIN + #include + #include + #endif + +-#define KWALLET_CIPHER_BLOWFISH_CBC 0 ++#define KWALLET_CIPHER_BLOWFISH_ECB 0 // this was the old KWALLET_CIPHER_BLOWFISH_CBC + #define KWALLET_CIPHER_3DES_CBC 1 // unsupported + #define KWALLET_CIPHER_GPG 2 ++#define KWALLET_CIPHER_BLOWFISH_CBC 3 + + #define KWALLET_HASH_SHA1 0 + #define KWALLET_HASH_MD5 1 // unsupported +@@ -164,13 +165,18 @@ BackendPersistHandler *BackendPersistHandler::getPersistHandler(BackendCipherTyp + return 0; + } + } +- ++ + BackendPersistHandler *BackendPersistHandler::getPersistHandler(char magicBuf[12]) + { +- if (magicBuf[2] == KWALLET_CIPHER_BLOWFISH_CBC && ++ if ((magicBuf[2] == KWALLET_CIPHER_BLOWFISH_ECB || magicBuf[2] == KWALLET_CIPHER_BLOWFISH_CBC) && + (magicBuf[3] == KWALLET_HASH_SHA1 || magicBuf[3] == KWALLET_HASH_PBKDF2_SHA512)) { +- if (0 == blowfishHandler) +- blowfishHandler = new BlowfishPersistHandler; ++ if (0 == blowfishHandler) { ++ bool useECBforReading = magicBuf[2] == KWALLET_CIPHER_BLOWFISH_ECB; ++ if (useECBforReading) { ++ qDebug() << "this wallet uses ECB encryption. It'll be converted to CBC on next save."; ++ } ++ blowfishHandler = new BlowfishPersistHandler(useECBforReading); ++ } + return blowfishHandler; + } + #ifdef HAVE_QGPGME +@@ -183,11 +189,16 @@ BackendPersistHandler *BackendPersistHandler::getPersistHandler(char magicBuf[12 + #endif // HAVE_QGPGME + return 0; // unknown cipher or hash + } +- ++ + int BlowfishPersistHandler::write(Backend* wb, KSaveFile& sf, QByteArray& version, WId) + { + assert(wb->_cipherType == BACKEND_CIPHER_BLOWFISH); + ++ if (_useECBforReading) { ++ qDebug() << "This wallet used ECB and is now saved using CBC"; ++ _useECBforReading = false; ++ } ++ + version[2] = KWALLET_CIPHER_BLOWFISH_CBC; + if(!wb->_useNewHash) { + version[3] = KWALLET_HASH_SHA1; +@@ -358,7 +369,7 @@ int BlowfishPersistHandler::read(Backend* wb, QFile& db, WId) + assert(encrypted.size() < db.size()); + + BlowFish _bf; +- CipherBlockChain bf(&_bf); ++ CipherBlockChain bf(&_bf, _useECBforReading); + int blksz = bf.blockSize(); + if ((encrypted.size() % blksz) != 0) { + return -5; // invalid file structure +@@ -502,7 +513,7 @@ int GpgPersistHandler::write(Backend* wb, KSaveFile& sf, QByteArray& version, WI + sf.abort(); + return -5; + } +- ++ + boost::shared_ptr< GpgME::Context > ctx( GpgME::Context::createForProtocol(GpgME::OpenPGP) ); + if (0 == ctx) { + kDebug() << "Cannot setup OpenPGP context!"; +@@ -511,7 +522,7 @@ int GpgPersistHandler::write(Backend* wb, KSaveFile& sf, QByteArray& version, WI + } + + assert(wb->_cipherType == BACKEND_CIPHER_GPG); +- ++ + QByteArray hashes; + QDataStream hashStream(&hashes, QIODevice::WriteOnly); + KMD5 md5; +@@ -549,7 +560,7 @@ int GpgPersistHandler::write(Backend* wb, KSaveFile& sf, QByteArray& version, WI + dataStream << keyID; + dataStream << hashes; + dataStream << values; +- ++ + GpgME::Data decryptedData(dataBuffer.data(), dataBuffer.size(), false); + GpgME::Data encryptedData; + std::vector< GpgME::Key > keys; +@@ -574,7 +585,7 @@ int GpgPersistHandler::write(Backend* wb, KSaveFile& sf, QByteArray& version, WI + return -4; // write error + } + } +- ++ + return 0; + } + +@@ -596,7 +607,7 @@ int GpgPersistHandler::read(Backend* wb, QFile& sf, WId w) + while (bytes = sf.read(buffer, sizeof(buffer)/sizeof(buffer[0]))){ + encryptedData.write(buffer, bytes); + } +- ++ + retry_label: + boost::shared_ptr< GpgME::Context > ctx( GpgME::Context::createForProtocol(GpgME::OpenPGP) ); + if (0 == ctx) { +@@ -620,13 +631,13 @@ int GpgPersistHandler::read(Backend* wb, QFile& sf, WId w) + } + return -1; + } +- ++ + decryptedData.seek(0, SEEK_SET); + QByteArray dataBuffer; + while (bytes = decryptedData.read(buffer, sizeof(buffer)/sizeof(buffer[0]))){ + dataBuffer.append(buffer, bytes); + } +- ++ + // load the wallet from the decrypted data + QDataStream dataStream(dataBuffer); + QString keyID; +@@ -661,10 +672,10 @@ int GpgPersistHandler::read(Backend* wb, QFile& sf, WId w) + return -1; + } + +- ++ + QDataStream hashStream(hashes); + QDataStream valueStream(values); +- ++ + quint32 hashCount; + hashStream >> hashCount; + if (hashCount > 0xFFFF) { +@@ -675,10 +686,10 @@ int GpgPersistHandler::read(Backend* wb, QFile& sf, WId w) + while (hashCount--){ + KMD5::Digest d; + hashStream.readRawData(reinterpret_cast(d), 16); +- ++ + quint32 folderSize; + hashStream >> folderSize; +- ++ + MD5Digest ba = MD5Digest(reinterpret_cast(d)); + QMap >::iterator it = wb->_hashes.insert(ba, QList()); + while (folderSize--){ +@@ -688,27 +699,27 @@ int GpgPersistHandler::read(Backend* wb, QFile& sf, WId w) + (*it).append(ba); + } + } +- ++ + while (folderCount--){ + QString folder; + valueStream >> folder; +- ++ + quint32 entryCount; + valueStream >> entryCount; +- ++ + wb->_entries[folder].clear(); +- ++ + while (entryCount--){ + KWallet::Wallet::EntryType et = KWallet::Wallet::Unknown; + Entry *e = new Entry; +- ++ + QString key; + valueStream >> key; +- ++ + qint32 x =0; // necessary to read properly + valueStream >> x; + et = static_cast(x); +- ++ + switch (et) { + case KWallet::Wallet::Password: + case KWallet::Wallet::Stream: +@@ -718,7 +729,7 @@ int GpgPersistHandler::read(Backend* wb, QFile& sf, WId w) + delete e; + continue; + } +- ++ + QByteArray a; + valueStream >> a; + e->setValue(a); +@@ -727,7 +738,7 @@ int GpgPersistHandler::read(Backend* wb, QFile& sf, WId w) + wb->_entries[folder][key] = e; + } + } +- ++ + wb->_open = true; + + return 0; +diff --git a/kwalletd/backend/backendpersisthandler.h b/kwalletd/backend/backendpersisthandler.h +index a33db48..11d67f2 100644 +--- a/kwalletd/backend/backendpersisthandler.h ++++ b/kwalletd/backend/backendpersisthandler.h +@@ -60,11 +60,13 @@ public: + + class BlowfishPersistHandler : public BackendPersistHandler { + public: +- BlowfishPersistHandler() {} ++ explicit BlowfishPersistHandler(bool useECBforReading =false) : _useECBforReading(useECBforReading) {} + virtual ~BlowfishPersistHandler() {} + + virtual int write(Backend* wb, KSaveFile& sf, QByteArray& version, WId w); + virtual int read(Backend* wb, QFile& sf, WId w); ++private: ++ bool _useECBforReading; + }; + + #ifdef HAVE_QGPGME +diff --git a/kwalletd/backend/cbc.cc b/kwalletd/backend/cbc.cc +index 7bc5f38..772f3de 100644 +--- a/kwalletd/backend/cbc.cc ++++ b/kwalletd/backend/cbc.cc +@@ -1,149 +1,212 @@ + /* This file is part of the KDE project + Copyright (C) 2001 George Staikos +- ++ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. +- ++ + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. +- ++ + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +- + #include "cbc.h" + #include +- +- +- +-CipherBlockChain::CipherBlockChain(BlockCipher *cipher) : _cipher(cipher) { +- _next = 0L; +- _register = 0L; +- _len = -1; +- _reader = _writer = 0L; +- if (cipher) { +- _blksz = cipher->blockSize(); +- } ++#include ++ ++CipherBlockChain::CipherBlockChain(BlockCipher *cipher, bool useECBforReading) : ++ _cipher(cipher) ++ , _useECBforReading(useECBforReading) ++{ ++ _next = 0L; ++ _register = 0L; ++ _len = -1; ++ _reader = _writer = 0L; ++ if (cipher) { ++ _blksz = cipher->blockSize(); ++ } + } + +- +-CipherBlockChain::~CipherBlockChain() { +- delete[] (char *)_register; +- _register = 0L; +- delete[] (char *)_next; +- _next = 0L; ++CipherBlockChain::~CipherBlockChain() ++{ ++ delete[](char *)_register; ++ _register = 0L; ++ delete[](char *)_next; ++ _next = 0L; + } + +- +-bool CipherBlockChain::setKey(void *key, int bitlength) { +- if (_cipher) { +- return _cipher->setKey(key, bitlength); +- } +- return false; ++bool CipherBlockChain::setKey(void *key, int bitlength) ++{ ++ if (_cipher) { ++ return _cipher->setKey(key, bitlength); ++ } ++ return false; + } + +- +-int CipherBlockChain::keyLen() const { +- if (_cipher) { +- return _cipher->keyLen(); +- } +- return -1; ++int CipherBlockChain::keyLen() const ++{ ++ if (_cipher) { ++ return _cipher->keyLen(); ++ } ++ return -1; + } + +- +-bool CipherBlockChain::variableKeyLen() const { +- if (_cipher) { +- return _cipher->variableKeyLen(); +- } +- return false; ++bool CipherBlockChain::variableKeyLen() const ++{ ++ if (_cipher) { ++ return _cipher->variableKeyLen(); ++ } ++ return false; + } + +- +-bool CipherBlockChain::readyToGo() const { +- if (_cipher) { +- return _cipher->readyToGo(); +- } +- return false; ++bool CipherBlockChain::readyToGo() const ++{ ++ if (_cipher) { ++ return _cipher->readyToGo(); ++ } ++ return false; + } + +- +-int CipherBlockChain::encrypt(void *block, int len) { +- if (_cipher && !_reader) { +- int rc; +- +- _writer |= 1; +- +- if (!_register) { +- _register = new unsigned char[len]; +- _len = len; +- memset(_register, 0, len); +- } else if (len > _len) { +- return -1; +- } +- +- // This might be optimizable +- char *tb = (char *)block; +- for (int i = 0; i < len; i++) { +- tb[i] ^= ((char *)_register)[i]; +- } +- +- rc = _cipher->encrypt(block, len); +- +- if (rc != -1) { +- memcpy(_register, block, len); +- } +- +- return rc; +- } +- return -1; ++void CipherBlockChain::initRegister() { ++ if (_register == 0L) { ++ size_t registerLen = _cipher->blockSize(); ++ _register = new unsigned char[registerLen]; ++ _len = registerLen; ++ } ++ memset(_register, 0, _len); + } + ++int CipherBlockChain::encrypt(void *block, int len) ++{ ++ if (_cipher && !_reader) { ++ int rc; + +-int CipherBlockChain::decrypt(void *block, int len) { +- if (_cipher && !_writer) { +- int rc; ++ _writer |= 1; + +- _reader |= 1; ++ initRegister(); + +- if (!_register) { +- _register = new unsigned char[len]; +- _len = len; +- memset(_register, 0, len); +- } else if (len > _len) { +- return -1; +- } ++ if ((len % _len) >0) { ++ kDebug() << "Block length given encrypt (" << len << ") is not a multiple of " << _len; ++ return -1; ++ } + +- if (!_next) +- _next = new unsigned char[_len]; +- memcpy(_next, block, _len); ++ char *elemBlock = static_cast(block); ++ for (int b = 0; b < len/_len; b++) { + +- rc = _cipher->decrypt(block, len); ++ // This might be optimizable ++ char *tb = static_cast(elemBlock); ++ for (int i = 0; i < _len; i++) { ++ *tb++ ^= ((char *)_register)[i]; ++ } + +- if (rc != -1) { +- // This might be optimizable +- char *tb = (char *)block; +- for (int i = 0; i < len; i++) { +- tb[i] ^= ((char *)_register)[i]; +- } +- } ++ rc = _cipher->encrypt(elemBlock, _len); + +- void *temp; +- temp = _next; +- _next = _register; +- _register = temp; ++ if (rc != -1) { ++ memcpy(_register, elemBlock, _len); ++ } ++ elemBlock += _len; ++ } + +- return rc; +- } +- return -1; ++ return rc; ++ } ++ return -1; + } + ++// This is the old decrypt method, that was decrypting using ECB ++// instead of CBC ++int CipherBlockChain::decryptECB(void *block, int len) { ++ if (_cipher && !_writer) { ++ int rc; ++ ++ _reader |= 1; ++ ++ if (!_register) { ++ _register = new unsigned char[len]; ++ _len = len; ++ memset(_register, 0, len); ++ } else if (len > _len) { ++ return -1; ++ } ++ ++ if (!_next) { ++ _next = new unsigned char[_len]; ++ } ++ memcpy(_next, block, _len); ++ ++ rc = _cipher->decrypt(block, len); ++ ++ if (rc != -1) { ++ // This might be optimizable ++ char *tb = (char *)block; ++ for (int i = 0; i < len; i++) { ++ tb[i] ^= ((char *)_register)[i]; ++ } ++ } ++ ++ void *temp; ++ temp = _next; ++ _next = _register; ++ _register = temp; ++ ++ return rc; ++ } ++ return -1; ++} + +- ++int CipherBlockChain::decrypt(void *block, int len) ++{ ++ if (_useECBforReading) { ++ kDebug() << "decrypting using ECB!"; ++ return decryptECB(block, len); ++ } ++ ++ if (_cipher && !_writer) { ++ int rc = 0; ++ ++ _reader |= 1; ++ ++ initRegister(); ++ ++ if ((len % _len) >0) { ++ kDebug() << "Block length given for decrypt (" << len << ") is not a multiple of " << _len; ++ return -1; ++ } ++ ++ char *elemBlock = static_cast(block); ++ for (int b = 0; b < len/_len; b++) { ++ if (_next == 0L) { ++ _next = new unsigned char[_len]; ++ } ++ memcpy(_next, elemBlock, _len); ++ ++ int bytesDecrypted = _cipher->decrypt(elemBlock, _len); ++ ++ if (bytesDecrypted != -1) { ++ rc += bytesDecrypted; ++ // This might be optimizable ++ char *tb = (char *)elemBlock; ++ for (int i = 0; i < _len; i++) { ++ *tb++ ^= ((char *)_register)[i]; ++ } ++ } ++ ++ void *temp; ++ temp = _next; ++ _next = _register; ++ _register = temp; ++ ++ elemBlock += _len; ++ } ++ ++ return rc; ++ } ++ return -1; ++} + +diff --git a/kwalletd/backend/cbc.h b/kwalletd/backend/cbc.h +index 1ce971a..8750785 100644 +--- a/kwalletd/backend/cbc.h ++++ b/kwalletd/backend/cbc.h +@@ -1,24 +1,22 @@ + /* This file is part of the KDE project + Copyright (C) 2001 George Staikos +- ++ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. +- ++ + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. +- ++ + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +- +- + #ifndef __CBC__KO__H + #define __CBC__KO__H + +@@ -33,30 +31,34 @@ + * calls to the other will fail in this instance. + */ + +-class CipherBlockChain : public BlockCipher { +- public: +- CipherBlockChain(BlockCipher *cipher); +- virtual ~CipherBlockChain(); ++class CipherBlockChain : public BlockCipher ++{ ++public: ++ CipherBlockChain(BlockCipher *cipher, bool useECBforReading =false); ++ virtual ~CipherBlockChain(); + +- virtual bool setKey(void *key, int bitlength); ++ virtual bool setKey(void *key, int bitlength); + +- virtual int keyLen() const; ++ virtual int keyLen() const; + +- virtual bool variableKeyLen() const; ++ virtual bool variableKeyLen() const; + +- virtual bool readyToGo() const; ++ virtual bool readyToGo() const; + +- virtual int encrypt(void *block, int len); ++ virtual int encrypt(void *block, int len); + +- virtual int decrypt(void *block, int len); ++ virtual int decrypt(void *block, int len); + +- private: +- BlockCipher *_cipher; +- void *_register; +- void *_next; +- int _len; +- int _reader, _writer; ++private: ++ void initRegister(); ++ int decryptECB(void *block, int len); + ++ BlockCipher *_cipher; ++ void *_register; ++ void *_next; ++ int _len; ++ int _reader, _writer; ++ bool _useECBforReading; + }; + + #endif +diff --git a/kwalletd/backend/tests/testbf.cpp b/kwalletd/backend/tests/testbf.cpp +index 12dc746..b3d554a 100644 +--- a/kwalletd/backend/tests/testbf.cpp ++++ b/kwalletd/backend/tests/testbf.cpp +@@ -4,64 +4,60 @@ + #include "blowfish.h" + #include "cbc.h" + +- +-int main() { +-BlockCipher *bf; +-char data[] = "This is a test."; +-char expect[] = "\x22\x30\x7e\x2f\x42\x28\x44\x01\xda\xdf\x5a\x81\xd7\xe5\x7c\xd0"; +-char key[] = "testkey"; +-unsigned long et[] = {0x11223344}; +- +- printf("%d: 0x11 == %d and 0x44 == %d\n", ((unsigned char *)et)[0], +- 0x11, 0x44); +- bf = new BlowFish(); ++int main() ++{ ++ BlockCipher *bf; ++ char data[] = "This is a test."; ++ char expect[] = "\x3f\x3c\x2d\xae\x8c\x7\x84\xf2\xa7\x6d\x28\xbd\xd\xb\xb8\x79"; ++ char key[] = "testkey"; ++ unsigned long et[] = {0x11223344}; ++ ++ printf("%d: 0x11 == %d and 0x44 == %d\n", ((unsigned char *)et)[0], ++ 0x11, 0x44); ++ bf = new BlowFish(); + // bf = new CipherBlockChain(new BlowFish()); + +- bf->setKey((void *)key, 7*8); +- +- if (!bf->readyToGo()) { +- printf("Error: not ready to go!\n"); +- return -1; +- } ++ bf->setKey((void *)key, 7 * 8); + +- printf("About to encrypt...\n"); fflush(stdout); +- if (-1 == bf->encrypt((void *)data, 8)) { +- printf("Error: encrypt failed!\n"); +- return -1; +- } +- printf("About to encrypt part 2...\n"); fflush(stdout); +- bf->encrypt((void *)(data+8), 8); +- +- printf("Encryption done. data[] is now: "); +- for (int i = 0; i < 16; i++) { +- printf("0x%x ", data[i]&0xff); +- if ((data[i]&0xff) != (expect[i]&0xff)) { +- printf("Error. This byte failed the comparison. It should have been 0x%x.\n", expect[i]&0xff); ++ if (!bf->readyToGo()) { ++ printf("Error: not ready to go!\n"); + return -1; +- } +- } +- printf("\n"); ++ } + +- delete bf; +- bf = new BlowFish(); ++ printf("About to encrypt...\n"); fflush(stdout); ++ if (-1 == bf->encrypt((void *)data, 16)) { ++ printf("Error: encrypt failed!\n"); ++ return -1; ++ } ++ ++ printf("Encryption done. data[] is now: "); ++ for (int i = 0; i < 16; i++) { ++ printf("0x%x ", data[i] & 0xff); ++ if ((data[i] & 0xff) != (expect[i] & 0xff)) { ++ printf("Error. This byte failed the comparison. It should have been 0x%x.\n", expect[i] & 0xff); ++ break; ++ } ++ } ++ printf("\n"); ++ ++ delete bf; ++ bf = new BlowFish(); + // bf = new CipherBlockChain(new BlowFish()); +- bf->setKey((void *)key, 7*8); ++ bf->setKey((void *)key, 7 * 8); + +- printf("About to decrypt...\n"); fflush(stdout); +- if (-1 == bf->decrypt((void *)data, 16)) { +- printf("Error: decrypt failed!\n"); +- return -1; +- } +- //bf->decrypt((void *)(data+8), 8); ++ printf("About to decrypt...\n"); fflush(stdout); ++ if (-1 == bf->decrypt((void *)data, 16)) { ++ printf("Error: decrypt failed!\n"); ++ return -1; ++ } ++ //bf->decrypt((void *)(data+8), 8); + +- printf("All done! Result... data[] = \"%s\"\n", data); +- if (strcmp(data, "This is a test.")) { +- printf("ERROR. Decryption failed.\n"); +- return -1; +- } ++ printf("All done! Result... data[] = \"%s\"\n", data); ++ if (strcmp(data, "This is a test.")) { ++ printf("ERROR. Decryption failed.\n"); ++ return -1; ++ } + +- delete bf; ++ delete bf; + } + +- +- +-- +2.2.1 + diff --git a/kde-base/kwalletd/kwalletd-4.14.3-r1.ebuild b/kde-base/kwalletd/kwalletd-4.14.3-r1.ebuild new file mode 100644 index 000000000000..44ea2f0bd694 --- /dev/null +++ b/kde-base/kwalletd/kwalletd-4.14.3-r1.ebuild @@ -0,0 +1,34 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/kde-base/kwalletd/kwalletd-4.14.3-r1.ebuild,v 1.1 2015/01/20 21:07:52 johu Exp $ + +EAPI=5 + +KMNAME="kde-runtime" +inherit kde4-meta + +DESCRIPTION="KDE Password Server" +KEYWORDS="~amd64 ~arm ~ppc ~ppc64 ~x86 ~x86-fbsd ~amd64-linux ~x86-linux" +IUSE="debug gpg" + +DEPEND=" + gpg? ( + app-crypt/gpgme + $(add_kdebase_dep kdepimlibs) + ) +" +RDEPEND="${DEPEND}" + +RESTRICT="test" +# testpamopen crashes with a buffer overflow (__fortify_fail) + +PATCHES=( "${FILESDIR}/${P}-CVE-2013-7252.patch" ) + +src_configure() { + local mycmakeargs=( + $(cmake-utils_use_find_package gpg Gpgme) + $(cmake-utils_use_find_package gpg QGpgme) + ) + + kde4-base_src_configure +} -- 2.26.2