File indexing completed on 2024-04-28 04:43:43
0001 /* 0002 * Copyright (C) 2004 Justin Karneges <justin@affinix.com> 0003 * Copyright (C) 2004-2006 Brad Hards <bradh@frogmouth.net> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2.1 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public 0016 * License along with this library; if not, write to the Free Software 0017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 0018 * 0019 */ 0020 #include <QtCrypto> 0021 0022 #include <QtCore/qplugin.h> 0023 0024 #include <QElapsedTimer> 0025 0026 #include <gcrypt.h> 0027 #include <iostream> 0028 #include <qstringlist.h> 0029 0030 namespace gcryptQCAPlugin { 0031 0032 #include "hkdf.c" 0033 #include "pkcs5.c" 0034 0035 void check_error(const char *label, gcry_error_t err) 0036 { 0037 // we ignore the case where it is not an error, and 0038 // we also don't flag weak keys. 0039 if ((GPG_ERR_NO_ERROR != err) && (GPG_ERR_WEAK_KEY != gpg_err_code(err))) { 0040 std::cout << "Failure (" << label << "): "; 0041 std::cout << gcry_strsource(err) << "/"; 0042 std::cout << gcry_strerror(err) << std::endl; 0043 } 0044 } 0045 0046 class gcryHashContext : public QCA::HashContext 0047 { 0048 Q_OBJECT 0049 public: 0050 gcryHashContext(int hashAlgorithm, QCA::Provider *p, const QString &type) 0051 : QCA::HashContext(p, type) 0052 { 0053 m_hashAlgorithm = hashAlgorithm; 0054 err = gcry_md_open(&context, m_hashAlgorithm, 0); 0055 if (GPG_ERR_NO_ERROR != err) { 0056 std::cout << "Failure: "; 0057 std::cout << gcry_strsource(err) << "/"; 0058 std::cout << gcry_strerror(err) << std::endl; 0059 } 0060 } 0061 0062 ~gcryHashContext() override 0063 { 0064 gcry_md_close(context); 0065 } 0066 0067 Context *clone() const override 0068 { 0069 return new gcryHashContext(m_hashAlgorithm, provider(), type()); 0070 } 0071 0072 void clear() override 0073 { 0074 gcry_md_reset(context); 0075 } 0076 0077 void update(const QCA::MemoryRegion &a) override 0078 { 0079 gcry_md_write(context, a.data(), a.size()); 0080 } 0081 0082 QCA::MemoryRegion final() override 0083 { 0084 unsigned char *md; 0085 QCA::SecureArray a(gcry_md_get_algo_dlen(m_hashAlgorithm)); 0086 md = gcry_md_read(context, m_hashAlgorithm); 0087 memcpy(a.data(), md, a.size()); 0088 return a; 0089 } 0090 0091 protected: 0092 gcry_md_hd_t context; 0093 gcry_error_t err; 0094 int m_hashAlgorithm; 0095 }; 0096 0097 class gcryHMACContext : public QCA::MACContext 0098 { 0099 Q_OBJECT 0100 public: 0101 gcryHMACContext(int hashAlgorithm, QCA::Provider *p, const QString &type) 0102 : QCA::MACContext(p, type) 0103 { 0104 m_hashAlgorithm = hashAlgorithm; 0105 err = gcry_md_open(&context, m_hashAlgorithm, GCRY_MD_FLAG_HMAC); 0106 if (GPG_ERR_NO_ERROR != err) { 0107 std::cout << "Failure: "; 0108 std::cout << gcry_strsource(err) << "/"; 0109 std::cout << gcry_strerror(err) << std::endl; 0110 } 0111 } 0112 0113 ~gcryHMACContext() override 0114 { 0115 gcry_md_close(context); 0116 } 0117 0118 void setup(const QCA::SymmetricKey &key) override 0119 { 0120 gcry_md_setkey(context, key.data(), key.size()); 0121 } 0122 0123 Context *clone() const override 0124 { 0125 return new gcryHMACContext(m_hashAlgorithm, provider(), type()); 0126 } 0127 0128 void clear() 0129 { 0130 gcry_md_reset(context); 0131 } 0132 0133 QCA::KeyLength keyLength() const override 0134 { 0135 return anyKeyLength(); 0136 } 0137 0138 void update(const QCA::MemoryRegion &a) override 0139 { 0140 gcry_md_write(context, a.data(), a.size()); 0141 } 0142 0143 void final(QCA::MemoryRegion *out) override 0144 { 0145 QCA::SecureArray sa(gcry_md_get_algo_dlen(m_hashAlgorithm), 0); 0146 unsigned char *md; 0147 md = gcry_md_read(context, m_hashAlgorithm); 0148 memcpy(sa.data(), md, sa.size()); 0149 *out = sa; 0150 } 0151 0152 protected: 0153 gcry_md_hd_t context; 0154 gcry_error_t err; 0155 int m_hashAlgorithm; 0156 }; 0157 0158 class gcryCipherContext : public QCA::CipherContext 0159 { 0160 Q_OBJECT 0161 public: 0162 gcryCipherContext(int algorithm, int mode, bool pad, QCA::Provider *p, const QString &type) 0163 : QCA::CipherContext(p, type) 0164 { 0165 m_cryptoAlgorithm = algorithm; 0166 m_mode = mode; 0167 m_pad = pad; 0168 } 0169 0170 void setup(QCA::Direction dir, 0171 const QCA::SymmetricKey &key, 0172 const QCA::InitializationVector &iv, 0173 const QCA::AuthTag &tag) override 0174 { 0175 Q_UNUSED(tag); 0176 m_direction = dir; 0177 err = gcry_cipher_open(&context, m_cryptoAlgorithm, m_mode, 0); 0178 check_error("gcry_cipher_open", err); 0179 if ((GCRY_CIPHER_3DES == m_cryptoAlgorithm) && (key.size() == 16)) { 0180 // this is triple DES with two keys, and gcrypt wants three 0181 QCA::SymmetricKey keyCopy(key); 0182 QCA::SecureArray thirdKey(key); 0183 thirdKey.resize(8); 0184 keyCopy += thirdKey; 0185 err = gcry_cipher_setkey(context, keyCopy.data(), keyCopy.size()); 0186 } else { 0187 err = gcry_cipher_setkey(context, key.data(), key.size()); 0188 } 0189 check_error("gcry_cipher_setkey", err); 0190 err = gcry_cipher_setiv(context, iv.data(), iv.size()); 0191 check_error("gcry_cipher_setiv", err); 0192 } 0193 0194 Context *clone() const override 0195 { 0196 return new gcryCipherContext(*this); 0197 } 0198 0199 int blockSize() const override 0200 { 0201 size_t blockSize; 0202 gcry_cipher_algo_info(m_cryptoAlgorithm, GCRYCTL_GET_BLKLEN, nullptr, &blockSize); 0203 return blockSize; 0204 } 0205 0206 QCA::AuthTag tag() const override 0207 { 0208 // For future implementation 0209 return QCA::AuthTag(); 0210 } 0211 0212 bool update(const QCA::SecureArray &in, QCA::SecureArray *out) override 0213 { 0214 QCA::SecureArray result(in.size()); 0215 if (QCA::Encode == m_direction) { 0216 err = gcry_cipher_encrypt( 0217 context, (unsigned char *)result.data(), result.size(), (unsigned char *)in.data(), in.size()); 0218 } else { 0219 err = gcry_cipher_decrypt( 0220 context, (unsigned char *)result.data(), result.size(), (unsigned char *)in.data(), in.size()); 0221 } 0222 check_error("update cipher encrypt/decrypt", err); 0223 result.resize(in.size()); 0224 *out = result; 0225 return true; 0226 } 0227 0228 bool final(QCA::SecureArray *out) override 0229 { 0230 QCA::SecureArray result; 0231 if (m_pad) { 0232 result.resize(blockSize()); 0233 if (QCA::Encode == m_direction) { 0234 err = gcry_cipher_encrypt(context, (unsigned char *)result.data(), result.size(), nullptr, 0); 0235 } else { 0236 err = gcry_cipher_decrypt(context, (unsigned char *)result.data(), result.size(), nullptr, 0); 0237 } 0238 check_error("final cipher encrypt/decrypt", err); 0239 } else { 0240 // just return null 0241 } 0242 *out = result; 0243 return true; 0244 } 0245 0246 QCA::KeyLength keyLength() const override 0247 { 0248 switch (m_cryptoAlgorithm) { 0249 case GCRY_CIPHER_DES: 0250 return QCA::KeyLength(8, 8, 1); 0251 case GCRY_CIPHER_AES128: 0252 return QCA::KeyLength(16, 16, 1); 0253 case GCRY_CIPHER_AES192: 0254 return QCA::KeyLength(24, 24, 1); 0255 case GCRY_CIPHER_3DES: 0256 // we do two and three key versions 0257 return QCA::KeyLength(16, 24, 8); 0258 case GCRY_CIPHER_AES256: 0259 return QCA::KeyLength(32, 32, 1); 0260 case GCRY_CIPHER_BLOWFISH: 0261 // Don't know - TODO 0262 return QCA::KeyLength(1, 32, 1); 0263 default: 0264 return QCA::KeyLength(0, 1, 1); 0265 } 0266 } 0267 0268 protected: 0269 gcry_cipher_hd_t context; 0270 gcry_error_t err; 0271 int m_cryptoAlgorithm; 0272 QCA::Direction m_direction; 0273 int m_mode; 0274 bool m_pad; 0275 }; 0276 0277 class pbkdf1Context : public QCA::KDFContext 0278 { 0279 Q_OBJECT 0280 public: 0281 pbkdf1Context(int algorithm, QCA::Provider *p, const QString &type) 0282 : QCA::KDFContext(p, type) 0283 { 0284 m_hashAlgorithm = algorithm; 0285 err = gcry_md_open(&context, m_hashAlgorithm, 0); 0286 if (GPG_ERR_NO_ERROR != err) { 0287 std::cout << "Failure: "; 0288 std::cout << gcry_strsource(err) << "/"; 0289 std::cout << gcry_strerror(err) << std::endl; 0290 } 0291 } 0292 0293 ~pbkdf1Context() override 0294 { 0295 gcry_md_close(context); 0296 } 0297 0298 Context *clone() const override 0299 { 0300 return new pbkdf1Context(m_hashAlgorithm, provider(), type()); 0301 } 0302 0303 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, 0304 const QCA::InitializationVector &salt, 0305 unsigned int keyLength, 0306 unsigned int iterationCount) override 0307 { 0308 /* from RFC2898: 0309 Steps: 0310 0311 1. If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output 0312 "derived key too long" and stop. 0313 */ 0314 if (keyLength > gcry_md_get_algo_dlen(m_hashAlgorithm)) { 0315 std::cout << "derived key too long" << std::endl; 0316 return QCA::SymmetricKey(); 0317 } 0318 0319 /* 0320 2. Apply the underlying hash function Hash for c iterations to the 0321 concatenation of the password P and the salt S, then extract 0322 the first dkLen octets to produce a derived key DK: 0323 0324 T_1 = Hash (P || S) , 0325 T_2 = Hash (T_1) , 0326 ... 0327 T_c = Hash (T_{c-1}) , 0328 DK = Tc<0..dkLen-1> 0329 */ 0330 // calculate T_1 0331 gcry_md_write(context, secret.data(), secret.size()); 0332 gcry_md_write(context, salt.data(), salt.size()); 0333 unsigned char *md; 0334 md = gcry_md_read(context, m_hashAlgorithm); 0335 QCA::SecureArray a(gcry_md_get_algo_dlen(m_hashAlgorithm)); 0336 memcpy(a.data(), md, a.size()); 0337 0338 // calculate T_2 up to T_c 0339 for (unsigned int i = 2; i <= iterationCount; ++i) { 0340 gcry_md_reset(context); 0341 gcry_md_write(context, a.data(), a.size()); 0342 md = gcry_md_read(context, m_hashAlgorithm); 0343 memcpy(a.data(), md, a.size()); 0344 } 0345 0346 // shrink a to become DK, of the required length 0347 a.resize(keyLength); 0348 0349 /* 0350 3. Output the derived key DK. 0351 */ 0352 return a; 0353 } 0354 0355 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, 0356 const QCA::InitializationVector &salt, 0357 unsigned int keyLength, 0358 int msecInterval, 0359 unsigned int *iterationCount) override 0360 { 0361 Q_ASSERT(iterationCount != nullptr); 0362 QElapsedTimer timer; 0363 0364 /* 0365 from RFC2898: 0366 Steps: 0367 0368 1. If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output 0369 "derived key too long" and stop. 0370 */ 0371 if (keyLength > gcry_md_get_algo_dlen(m_hashAlgorithm)) { 0372 std::cout << "derived key too long" << std::endl; 0373 return QCA::SymmetricKey(); 0374 } 0375 0376 /* 0377 2. Apply the underlying hash function Hash for M milliseconds 0378 to the concatenation of the password P and the salt S, incrementing c, 0379 then extract the first dkLen octets to produce a derived key DK: 0380 0381 time from 0 to M 0382 T_1 = Hash (P || S) , 0383 T_2 = Hash (T_1) , 0384 ... 0385 T_c = Hash (T_{c-1}) , 0386 when time = 0: stop, 0387 DK = Tc<0..dkLen-1> 0388 */ 0389 // calculate T_1 0390 gcry_md_write(context, secret.data(), secret.size()); 0391 gcry_md_write(context, salt.data(), salt.size()); 0392 unsigned char *md; 0393 md = gcry_md_read(context, m_hashAlgorithm); 0394 QCA::SecureArray a(gcry_md_get_algo_dlen(m_hashAlgorithm)); 0395 memcpy(a.data(), md, a.size()); 0396 0397 // calculate T_2 up to T_c 0398 *iterationCount = 2 - 1; // <- Have to remove 1, unless it computes one 0399 timer.start(); // ^ time more than the base function 0400 // ^ with the same iterationCount 0401 while (timer.elapsed() < msecInterval) { 0402 gcry_md_reset(context); 0403 gcry_md_write(context, a.data(), a.size()); 0404 md = gcry_md_read(context, m_hashAlgorithm); 0405 memcpy(a.data(), md, a.size()); 0406 ++(*iterationCount); 0407 } 0408 0409 // shrink a to become DK, of the required length 0410 a.resize(keyLength); 0411 0412 /* 0413 3. Output the derived key DK. 0414 */ 0415 return a; 0416 } 0417 0418 protected: 0419 gcry_md_hd_t context; 0420 gcry_error_t err; 0421 int m_hashAlgorithm; 0422 }; 0423 0424 class pbkdf2Context : public QCA::KDFContext 0425 { 0426 Q_OBJECT 0427 public: 0428 pbkdf2Context(int algorithm, QCA::Provider *p, const QString &type) 0429 : QCA::KDFContext(p, type) 0430 { 0431 m_algorithm = algorithm; 0432 } 0433 0434 Context *clone() const override 0435 { 0436 return new pbkdf2Context(*this); 0437 } 0438 0439 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, 0440 const QCA::InitializationVector &salt, 0441 unsigned int keyLength, 0442 unsigned int iterationCount) override 0443 { 0444 QCA::SymmetricKey result(keyLength); 0445 gcry_error_t retval = gcry_pbkdf2(m_algorithm, 0446 secret.data(), 0447 secret.size(), 0448 salt.data(), 0449 salt.size(), 0450 iterationCount, 0451 keyLength, 0452 result.data()); 0453 if (retval == GPG_ERR_NO_ERROR) { 0454 return result; 0455 } else { 0456 // std::cout << "got: " << retval << std::endl; 0457 return QCA::SymmetricKey(); 0458 } 0459 } 0460 0461 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, 0462 const QCA::InitializationVector &salt, 0463 unsigned int keyLength, 0464 int msecInterval, 0465 unsigned int *iterationCount) override 0466 { 0467 Q_ASSERT(iterationCount != nullptr); 0468 QCA::SymmetricKey result(keyLength); 0469 QElapsedTimer timer; 0470 0471 *iterationCount = 0; 0472 timer.start(); 0473 0474 while (timer.elapsed() < msecInterval) { 0475 gcry_pbkdf2( 0476 m_algorithm, secret.data(), secret.size(), salt.data(), salt.size(), 1, keyLength, result.data()); 0477 ++(*iterationCount); 0478 } 0479 0480 return makeKey(secret, salt, keyLength, *iterationCount); 0481 } 0482 0483 protected: 0484 int m_algorithm; 0485 }; 0486 0487 class hkdfContext : public QCA::HKDFContext 0488 { 0489 Q_OBJECT 0490 public: 0491 hkdfContext(int algorithm, QCA::Provider *p, const QString &type) 0492 : QCA::HKDFContext(p, type) 0493 { 0494 m_algorithm = algorithm; 0495 } 0496 0497 Context *clone() const override 0498 { 0499 return new hkdfContext(*this); 0500 } 0501 0502 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret, 0503 const QCA::InitializationVector &salt, 0504 const QCA::InitializationVector &info, 0505 unsigned int keyLength) override 0506 { 0507 QCA::SymmetricKey result(keyLength); 0508 gcry_error_t retval = gcry_hkdf(m_algorithm, 0509 secret.data(), 0510 secret.size(), 0511 salt.data(), 0512 salt.size(), 0513 info.data(), 0514 info.size(), 0515 result.data(), 0516 result.size()); 0517 if (retval == GPG_ERR_NO_ERROR) { 0518 return result; 0519 } else { 0520 return QCA::SymmetricKey(); 0521 } 0522 } 0523 0524 protected: 0525 int m_algorithm; 0526 }; 0527 0528 } 0529 0530 extern "C" { 0531 0532 static void *qca_func_malloc(size_t n) 0533 { 0534 return qca_secure_alloc(n); 0535 } 0536 0537 static void *qca_func_secure_malloc(size_t n) 0538 { 0539 return qca_secure_alloc(n); 0540 } 0541 0542 static void *qca_func_realloc(void *oldBlock, size_t newBlockSize) 0543 { 0544 return qca_secure_realloc(oldBlock, newBlockSize); 0545 } 0546 0547 static void qca_func_free(void *mem) 0548 { 0549 qca_secure_free(mem); 0550 } 0551 0552 int qca_func_secure_check(const void *) 0553 { 0554 return (int)QCA::haveSecureMemory(); 0555 } 0556 } // extern "C" 0557 0558 class gcryptProvider : public QCA::Provider 0559 { 0560 public: 0561 void init() override 0562 { 0563 if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) { /* No other library has already initialized libgcrypt. */ 0564 0565 if (!gcry_check_version(GCRYPT_VERSION)) { 0566 std::cout << "libgcrypt is too old (need " << GCRYPT_VERSION; 0567 std::cout << ", have " << gcry_check_version(nullptr) << ")" << std::endl; 0568 } 0569 gcry_set_allocation_handler( 0570 qca_func_malloc, qca_func_secure_malloc, qca_func_secure_check, qca_func_realloc, qca_func_free); 0571 gcry_control(GCRYCTL_INITIALIZATION_FINISHED); 0572 } 0573 } 0574 0575 int qcaVersion() const override 0576 { 0577 return QCA_VERSION; 0578 } 0579 0580 QString name() const override 0581 { 0582 return QStringLiteral("qca-gcrypt"); 0583 } 0584 0585 QStringList features() const override 0586 { 0587 QStringList list; 0588 list += QStringLiteral("sha1"); 0589 list += QStringLiteral("md4"); 0590 list += QStringLiteral("md5"); 0591 list += QStringLiteral("ripemd160"); 0592 #ifdef GCRY_MD_SHA224 0593 list += QStringLiteral("sha224"); 0594 #endif 0595 list += QStringLiteral("sha256"); 0596 list += QStringLiteral("sha384"); 0597 list += QStringLiteral("sha512"); 0598 list += QStringLiteral("hmac(md5)"); 0599 list += QStringLiteral("hmac(sha1)"); 0600 #ifdef GCRY_MD_SHA224 0601 list += QStringLiteral("hmac(sha224)"); 0602 #endif 0603 list += QStringLiteral("hmac(sha256)"); 0604 if (!(nullptr == gcry_check_version("1.3.0"))) { 0605 // 1.2 and earlier have broken implementation 0606 list += QStringLiteral("hmac(sha384)"); 0607 list += QStringLiteral("hmac(sha512)"); 0608 } 0609 list += QStringLiteral("hmac(ripemd160)"); 0610 list += QStringLiteral("aes128-ecb"); 0611 list += QStringLiteral("aes128-cfb"); 0612 list += QStringLiteral("aes128-cbc"); 0613 list += QStringLiteral("aes192-ecb"); 0614 list += QStringLiteral("aes192-cfb"); 0615 list += QStringLiteral("aes192-cbc"); 0616 list += QStringLiteral("aes256-ecb"); 0617 list += QStringLiteral("aes256-cfb"); 0618 list += QStringLiteral("aes256-cbc"); 0619 list += QStringLiteral("blowfish-ecb"); 0620 list += QStringLiteral("blowfish-cbc"); 0621 list += QStringLiteral("blowfish-cfb"); 0622 list += QStringLiteral("tripledes-ecb"); 0623 // list += QStringLiteral("des-ecb"); 0624 list += QStringLiteral("des-cbc"); 0625 list += QStringLiteral("des-cfb"); 0626 if (!(nullptr == gcry_check_version("1.3.0"))) { 0627 // 1.2 branch and earlier doesn't support OFB mode 0628 list += QStringLiteral("aes128-ofb"); 0629 list += QStringLiteral("aes192-ofb"); 0630 list += QStringLiteral("aes256-ofb"); 0631 list += QStringLiteral("des-ofb"); 0632 list += QStringLiteral("tripledes-ofb"); 0633 list += QStringLiteral("blowfish-ofb"); 0634 } 0635 list += QStringLiteral("pbkdf1(sha1)"); 0636 list += QStringLiteral("pbkdf2(sha1)"); 0637 list += QStringLiteral("hkdf(sha256)"); 0638 return list; 0639 } 0640 0641 Context *createContext(const QString &type) override 0642 { 0643 // std::cout << "type: " << qPrintable(type) << std::endl; 0644 if (type == QLatin1String("sha1")) 0645 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA1, this, type); 0646 else if (type == QLatin1String("md4")) 0647 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_MD4, this, type); 0648 else if (type == QLatin1String("md5")) 0649 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_MD5, this, type); 0650 else if (type == QLatin1String("ripemd160")) 0651 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_RMD160, this, type); 0652 #ifdef GCRY_MD_SHA224 0653 else if (type == QLatin1String("sha224")) 0654 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA224, this, type); 0655 #endif 0656 else if (type == QLatin1String("sha256")) 0657 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA256, this, type); 0658 else if (type == QLatin1String("sha384")) 0659 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA384, this, type); 0660 else if (type == QLatin1String("sha512")) 0661 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA512, this, type); 0662 else if (type == QLatin1String("hmac(md5)")) 0663 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_MD5, this, type); 0664 else if (type == QLatin1String("hmac(sha1)")) 0665 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA1, this, type); 0666 #ifdef GCRY_MD_SHA224 0667 else if (type == QLatin1String("hmac(sha224)")) 0668 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA224, this, type); 0669 #endif 0670 else if (type == QLatin1String("hmac(sha256)")) 0671 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA256, this, type); 0672 else if (type == QLatin1String("hmac(sha384)")) 0673 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA384, this, type); 0674 else if (type == QLatin1String("hmac(sha512)")) 0675 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA512, this, type); 0676 else if (type == QLatin1String("hmac(ripemd160)")) 0677 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_RMD160, this, type); 0678 else if (type == QLatin1String("aes128-ecb")) 0679 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, false, this, type); 0680 else if (type == QLatin1String("aes128-cfb")) 0681 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB, false, this, type); 0682 else if (type == QLatin1String("aes128-ofb")) 0683 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB, false, this, type); 0684 else if (type == QLatin1String("aes128-cbc")) 0685 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, false, this, type); 0686 else if (type == QLatin1String("aes192-ecb")) 0687 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, false, this, type); 0688 else if (type == QLatin1String("aes192-cfb")) 0689 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, false, this, type); 0690 else if (type == QLatin1String("aes192-ofb")) 0691 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, false, this, type); 0692 else if (type == QLatin1String("aes192-cbc")) 0693 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, false, this, type); 0694 else if (type == QLatin1String("aes256-ecb")) 0695 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, false, this, type); 0696 else if (type == QLatin1String("aes256-cfb")) 0697 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, false, this, type); 0698 else if (type == QLatin1String("aes256-ofb")) 0699 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, false, this, type); 0700 else if (type == QLatin1String("aes256-cbc")) 0701 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, false, this, type); 0702 else if (type == QLatin1String("blowfish-ecb")) 0703 return new gcryptQCAPlugin::gcryCipherContext( 0704 GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, false, this, type); 0705 else if (type == QLatin1String("blowfish-cbc")) 0706 return new gcryptQCAPlugin::gcryCipherContext( 0707 GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, false, this, type); 0708 else if (type == QLatin1String("blowfish-cfb")) 0709 return new gcryptQCAPlugin::gcryCipherContext( 0710 GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB, false, this, type); 0711 else if (type == QLatin1String("blowfish-ofb")) 0712 return new gcryptQCAPlugin::gcryCipherContext( 0713 GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB, false, this, type); 0714 else if (type == QLatin1String("tripledes-ecb")) 0715 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, false, this, type); 0716 else if (type == QLatin1String("tripledes-ofb")) 0717 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB, false, this, type); 0718 else if (type == QLatin1String("des-ecb")) 0719 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, false, this, type); 0720 else if (type == QLatin1String("des-cbc")) 0721 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, false, this, type); 0722 else if (type == QLatin1String("des-cfb")) 0723 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB, false, this, type); 0724 else if (type == QLatin1String("des-ofb")) 0725 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB, false, this, type); 0726 else if (type == QLatin1String("pbkdf1(sha1)")) 0727 return new gcryptQCAPlugin::pbkdf1Context(GCRY_MD_SHA1, this, type); 0728 else if (type == QLatin1String("pbkdf2(sha1)")) 0729 return new gcryptQCAPlugin::pbkdf2Context(GCRY_MD_SHA1, this, type); 0730 else if (type == QLatin1String("hkdf(sha256)")) 0731 return new gcryptQCAPlugin::hkdfContext(GCRY_MD_SHA256, this, type); 0732 else 0733 return nullptr; 0734 } 0735 }; 0736 0737 class gcryptPlugin : public QObject, public QCAPlugin 0738 { 0739 Q_OBJECT 0740 Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0") 0741 Q_INTERFACES(QCAPlugin) 0742 public: 0743 QCA::Provider *createProvider() override 0744 { 0745 return new gcryptProvider; 0746 } 0747 }; 0748 0749 #include "qca-gcrypt.moc"