1/*
2 * Copyright (C) 2004 Justin Karneges <justin@affinix.com>
3 * Copyright (C) 2004-2006 Brad Hards <bradh@frogmouth.net>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 */
20#include <QtCrypto>
21
22#include <QtCore/qplugin.h>
23
24#include <QElapsedTimer>
25
26#include <gcrypt.h>
27#include <iostream>
28#include <qstringlist.h>
29
30namespace gcryptQCAPlugin {
31
32#include "hkdf.c"
33#include "pkcs5.c"
34
35void check_error(const char *label, gcry_error_t err)
36{
37 // we ignore the case where it is not an error, and
38 // we also don't flag weak keys.
39 if ((GPG_ERR_NO_ERROR != err) && (GPG_ERR_WEAK_KEY != gpg_err_code(err))) {
40 std::cout << "Failure (" << label << "): ";
41 std::cout << gcry_strsource(err) << "/";
42 std::cout << gcry_strerror(err) << std::endl;
43 }
44}
45
46class gcryHashContext : public QCA::HashContext
47{
48 Q_OBJECT
49public:
50 gcryHashContext(int hashAlgorithm, QCA::Provider *p, const QString &type)
51 : QCA::HashContext(p, type)
52 {
53 m_hashAlgorithm = hashAlgorithm;
54 err = gcry_md_open(h: &context, algo: m_hashAlgorithm, flags: 0);
55 if (GPG_ERR_NO_ERROR != err) {
56 std::cout << "Failure: ";
57 std::cout << gcry_strsource(err) << "/";
58 std::cout << gcry_strerror(err) << std::endl;
59 }
60 }
61
62 ~gcryHashContext() override
63 {
64 gcry_md_close(hd: context);
65 }
66
67 Context *clone() const override
68 {
69 return new gcryHashContext(m_hashAlgorithm, provider(), type());
70 }
71
72 void clear() override
73 {
74 gcry_md_reset(hd: context);
75 }
76
77 void update(const QCA::MemoryRegion &a) override
78 {
79 gcry_md_write(hd: context, buffer: a.data(), length: a.size());
80 }
81
82 QCA::MemoryRegion final() override
83 {
84 unsigned char *md;
85 QCA::SecureArray a(gcry_md_get_algo_dlen(algo: m_hashAlgorithm));
86 md = gcry_md_read(hd: context, algo: m_hashAlgorithm);
87 memcpy(dest: a.data(), src: md, n: a.size());
88 return a;
89 }
90
91protected:
92 gcry_md_hd_t context;
93 gcry_error_t err;
94 int m_hashAlgorithm;
95};
96
97class gcryHMACContext : public QCA::MACContext
98{
99 Q_OBJECT
100public:
101 gcryHMACContext(int hashAlgorithm, QCA::Provider *p, const QString &type)
102 : QCA::MACContext(p, type)
103 {
104 m_hashAlgorithm = hashAlgorithm;
105 err = gcry_md_open(h: &context, algo: m_hashAlgorithm, flags: GCRY_MD_FLAG_HMAC);
106 if (GPG_ERR_NO_ERROR != err) {
107 std::cout << "Failure: ";
108 std::cout << gcry_strsource(err) << "/";
109 std::cout << gcry_strerror(err) << std::endl;
110 }
111 }
112
113 ~gcryHMACContext() override
114 {
115 gcry_md_close(hd: context);
116 }
117
118 void setup(const QCA::SymmetricKey &key) override
119 {
120 gcry_md_setkey(hd: context, key: key.data(), keylen: key.size());
121 }
122
123 Context *clone() const override
124 {
125 return new gcryHMACContext(m_hashAlgorithm, provider(), type());
126 }
127
128 void clear()
129 {
130 gcry_md_reset(hd: context);
131 }
132
133 QCA::KeyLength keyLength() const override
134 {
135 return anyKeyLength();
136 }
137
138 void update(const QCA::MemoryRegion &a) override
139 {
140 gcry_md_write(hd: context, buffer: a.data(), length: a.size());
141 }
142
143 void final(QCA::MemoryRegion *out) override
144 {
145 QCA::SecureArray sa(gcry_md_get_algo_dlen(algo: m_hashAlgorithm), 0);
146 unsigned char *md;
147 md = gcry_md_read(hd: context, algo: m_hashAlgorithm);
148 memcpy(dest: sa.data(), src: md, n: sa.size());
149 *out = sa;
150 }
151
152protected:
153 gcry_md_hd_t context;
154 gcry_error_t err;
155 int m_hashAlgorithm;
156};
157
158class gcryCipherContext : public QCA::CipherContext
159{
160 Q_OBJECT
161public:
162 gcryCipherContext(int algorithm, int mode, bool pad, QCA::Provider *p, const QString &type)
163 : QCA::CipherContext(p, type)
164 {
165 m_cryptoAlgorithm = algorithm;
166 m_mode = mode;
167 m_pad = pad;
168 }
169
170 void setup(QCA::Direction dir,
171 const QCA::SymmetricKey &key,
172 const QCA::InitializationVector &iv,
173 const QCA::AuthTag &tag) override
174 {
175 Q_UNUSED(tag);
176 m_direction = dir;
177 err = gcry_cipher_open(handle: &context, algo: m_cryptoAlgorithm, mode: m_mode, flags: 0);
178 check_error(label: "gcry_cipher_open", err);
179 if ((GCRY_CIPHER_3DES == m_cryptoAlgorithm) && (key.size() == 16)) {
180 // this is triple DES with two keys, and gcrypt wants three
181 QCA::SymmetricKey keyCopy(key);
182 QCA::SecureArray thirdKey(key);
183 thirdKey.resize(size: 8);
184 keyCopy += thirdKey;
185 err = gcry_cipher_setkey(hd: context, key: keyCopy.data(), keylen: keyCopy.size());
186 } else {
187 err = gcry_cipher_setkey(hd: context, key: key.data(), keylen: key.size());
188 }
189 check_error(label: "gcry_cipher_setkey", err);
190 err = gcry_cipher_setiv(hd: context, iv: iv.data(), ivlen: iv.size());
191 check_error(label: "gcry_cipher_setiv", err);
192 }
193
194 Context *clone() const override
195 {
196 return new gcryCipherContext(*this);
197 }
198
199 int blockSize() const override
200 {
201 size_t blockSize;
202 gcry_cipher_algo_info(algo: m_cryptoAlgorithm, what: GCRYCTL_GET_BLKLEN, buffer: nullptr, nbytes: &blockSize);
203 return blockSize;
204 }
205
206 QCA::AuthTag tag() const override
207 {
208 // For future implementation
209 return QCA::AuthTag();
210 }
211
212 bool update(const QCA::SecureArray &in, QCA::SecureArray *out) override
213 {
214 QCA::SecureArray result(in.size());
215 if (QCA::Encode == m_direction) {
216 err = gcry_cipher_encrypt(
217 h: context, out: (unsigned char *)result.data(), outsize: result.size(), in: (unsigned char *)in.data(), inlen: in.size());
218 } else {
219 err = gcry_cipher_decrypt(
220 h: context, out: (unsigned char *)result.data(), outsize: result.size(), in: (unsigned char *)in.data(), inlen: in.size());
221 }
222 check_error(label: "update cipher encrypt/decrypt", err);
223 result.resize(size: in.size());
224 *out = result;
225 return true;
226 }
227
228 bool final(QCA::SecureArray *out) override
229 {
230 QCA::SecureArray result;
231 if (m_pad) {
232 result.resize(size: blockSize());
233 if (QCA::Encode == m_direction) {
234 err = gcry_cipher_encrypt(h: context, out: (unsigned char *)result.data(), outsize: result.size(), in: nullptr, inlen: 0);
235 } else {
236 err = gcry_cipher_decrypt(h: context, out: (unsigned char *)result.data(), outsize: result.size(), in: nullptr, inlen: 0);
237 }
238 check_error(label: "final cipher encrypt/decrypt", err);
239 } else {
240 // just return null
241 }
242 *out = result;
243 return true;
244 }
245
246 QCA::KeyLength keyLength() const override
247 {
248 switch (m_cryptoAlgorithm) {
249 case GCRY_CIPHER_DES:
250 return QCA::KeyLength(8, 8, 1);
251 case GCRY_CIPHER_AES128:
252 return QCA::KeyLength(16, 16, 1);
253 case GCRY_CIPHER_AES192:
254 return QCA::KeyLength(24, 24, 1);
255 case GCRY_CIPHER_3DES:
256 // we do two and three key versions
257 return QCA::KeyLength(16, 24, 8);
258 case GCRY_CIPHER_AES256:
259 return QCA::KeyLength(32, 32, 1);
260 case GCRY_CIPHER_BLOWFISH:
261 // Don't know - TODO
262 return QCA::KeyLength(1, 32, 1);
263 default:
264 return QCA::KeyLength(0, 1, 1);
265 }
266 }
267
268protected:
269 gcry_cipher_hd_t context;
270 gcry_error_t err;
271 int m_cryptoAlgorithm;
272 QCA::Direction m_direction;
273 int m_mode;
274 bool m_pad;
275};
276
277class pbkdf1Context : public QCA::KDFContext
278{
279 Q_OBJECT
280public:
281 pbkdf1Context(int algorithm, QCA::Provider *p, const QString &type)
282 : QCA::KDFContext(p, type)
283 {
284 m_hashAlgorithm = algorithm;
285 err = gcry_md_open(h: &context, algo: m_hashAlgorithm, flags: 0);
286 if (GPG_ERR_NO_ERROR != err) {
287 std::cout << "Failure: ";
288 std::cout << gcry_strsource(err) << "/";
289 std::cout << gcry_strerror(err) << std::endl;
290 }
291 }
292
293 ~pbkdf1Context() override
294 {
295 gcry_md_close(hd: context);
296 }
297
298 Context *clone() const override
299 {
300 return new pbkdf1Context(m_hashAlgorithm, provider(), type());
301 }
302
303 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret,
304 const QCA::InitializationVector &salt,
305 unsigned int keyLength,
306 unsigned int iterationCount) override
307 {
308 /* from RFC2898:
309 Steps:
310
311 1. If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output
312 "derived key too long" and stop.
313 */
314 if (keyLength > gcry_md_get_algo_dlen(algo: m_hashAlgorithm)) {
315 std::cout << "derived key too long" << std::endl;
316 return QCA::SymmetricKey();
317 }
318
319 /*
320 2. Apply the underlying hash function Hash for c iterations to the
321 concatenation of the password P and the salt S, then extract
322 the first dkLen octets to produce a derived key DK:
323
324 T_1 = Hash (P || S) ,
325 T_2 = Hash (T_1) ,
326 ...
327 T_c = Hash (T_{c-1}) ,
328 DK = Tc<0..dkLen-1>
329 */
330 // calculate T_1
331 gcry_md_write(hd: context, buffer: secret.data(), length: secret.size());
332 gcry_md_write(hd: context, buffer: salt.data(), length: salt.size());
333 unsigned char *md;
334 md = gcry_md_read(hd: context, algo: m_hashAlgorithm);
335 QCA::SecureArray a(gcry_md_get_algo_dlen(algo: m_hashAlgorithm));
336 memcpy(dest: a.data(), src: md, n: a.size());
337
338 // calculate T_2 up to T_c
339 for (unsigned int i = 2; i <= iterationCount; ++i) {
340 gcry_md_reset(hd: context);
341 gcry_md_write(hd: context, buffer: a.data(), length: a.size());
342 md = gcry_md_read(hd: context, algo: m_hashAlgorithm);
343 memcpy(dest: a.data(), src: md, n: a.size());
344 }
345
346 // shrink a to become DK, of the required length
347 a.resize(size: keyLength);
348
349 /*
350 3. Output the derived key DK.
351 */
352 return a;
353 }
354
355 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret,
356 const QCA::InitializationVector &salt,
357 unsigned int keyLength,
358 int msecInterval,
359 unsigned int *iterationCount) override
360 {
361 Q_ASSERT(iterationCount != nullptr);
362 QElapsedTimer timer;
363
364 /*
365 from RFC2898:
366 Steps:
367
368 1. If dkLen > 16 for MD2 and MD5, or dkLen > 20 for SHA-1, output
369 "derived key too long" and stop.
370 */
371 if (keyLength > gcry_md_get_algo_dlen(algo: m_hashAlgorithm)) {
372 std::cout << "derived key too long" << std::endl;
373 return QCA::SymmetricKey();
374 }
375
376 /*
377 2. Apply the underlying hash function Hash for M milliseconds
378 to the concatenation of the password P and the salt S, incrementing c,
379 then extract the first dkLen octets to produce a derived key DK:
380
381 time from 0 to M
382 T_1 = Hash (P || S) ,
383 T_2 = Hash (T_1) ,
384 ...
385 T_c = Hash (T_{c-1}) ,
386 when time = 0: stop,
387 DK = Tc<0..dkLen-1>
388 */
389 // calculate T_1
390 gcry_md_write(hd: context, buffer: secret.data(), length: secret.size());
391 gcry_md_write(hd: context, buffer: salt.data(), length: salt.size());
392 unsigned char *md;
393 md = gcry_md_read(hd: context, algo: m_hashAlgorithm);
394 QCA::SecureArray a(gcry_md_get_algo_dlen(algo: m_hashAlgorithm));
395 memcpy(dest: a.data(), src: md, n: a.size());
396
397 // calculate T_2 up to T_c
398 *iterationCount = 2 - 1; // <- Have to remove 1, unless it computes one
399 timer.start(); // ^ time more than the base function
400 // ^ with the same iterationCount
401 while (timer.elapsed() < msecInterval) {
402 gcry_md_reset(hd: context);
403 gcry_md_write(hd: context, buffer: a.data(), length: a.size());
404 md = gcry_md_read(hd: context, algo: m_hashAlgorithm);
405 memcpy(dest: a.data(), src: md, n: a.size());
406 ++(*iterationCount);
407 }
408
409 // shrink a to become DK, of the required length
410 a.resize(size: keyLength);
411
412 /*
413 3. Output the derived key DK.
414 */
415 return a;
416 }
417
418protected:
419 gcry_md_hd_t context;
420 gcry_error_t err;
421 int m_hashAlgorithm;
422};
423
424class pbkdf2Context : public QCA::KDFContext
425{
426 Q_OBJECT
427public:
428 pbkdf2Context(int algorithm, QCA::Provider *p, const QString &type)
429 : QCA::KDFContext(p, type)
430 {
431 m_algorithm = algorithm;
432 }
433
434 Context *clone() const override
435 {
436 return new pbkdf2Context(*this);
437 }
438
439 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret,
440 const QCA::InitializationVector &salt,
441 unsigned int keyLength,
442 unsigned int iterationCount) override
443 {
444 QCA::SymmetricKey result(keyLength);
445 gcry_error_t retval = gcry_pbkdf2(PRF: m_algorithm,
446 P: secret.data(),
447 Plen: secret.size(),
448 S: salt.data(),
449 Slen: salt.size(),
450 c: iterationCount,
451 dkLen: keyLength,
452 DK: result.data());
453 if (retval == GPG_ERR_NO_ERROR) {
454 return result;
455 } else {
456 // std::cout << "got: " << retval << std::endl;
457 return QCA::SymmetricKey();
458 }
459 }
460
461 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret,
462 const QCA::InitializationVector &salt,
463 unsigned int keyLength,
464 int msecInterval,
465 unsigned int *iterationCount) override
466 {
467 Q_ASSERT(iterationCount != nullptr);
468 QCA::SymmetricKey result(keyLength);
469 QElapsedTimer timer;
470
471 *iterationCount = 0;
472 timer.start();
473
474 while (timer.elapsed() < msecInterval) {
475 gcry_pbkdf2(
476 PRF: m_algorithm, P: secret.data(), Plen: secret.size(), S: salt.data(), Slen: salt.size(), c: 1, dkLen: keyLength, DK: result.data());
477 ++(*iterationCount);
478 }
479
480 return makeKey(secret, salt, keyLength, iterationCount: *iterationCount);
481 }
482
483protected:
484 int m_algorithm;
485};
486
487class hkdfContext : public QCA::HKDFContext
488{
489 Q_OBJECT
490public:
491 hkdfContext(int algorithm, QCA::Provider *p, const QString &type)
492 : QCA::HKDFContext(p, type)
493 {
494 m_algorithm = algorithm;
495 }
496
497 Context *clone() const override
498 {
499 return new hkdfContext(*this);
500 }
501
502 QCA::SymmetricKey makeKey(const QCA::SecureArray &secret,
503 const QCA::InitializationVector &salt,
504 const QCA::InitializationVector &info,
505 unsigned int keyLength) override
506 {
507 QCA::SymmetricKey result(keyLength);
508 gcry_error_t retval = gcry_hkdf(algo: m_algorithm,
509 input: secret.data(),
510 n_input: secret.size(),
511 salt: salt.data(),
512 n_salt: salt.size(),
513 info: info.data(),
514 n_info: info.size(),
515 output: result.data(),
516 n_output: result.size());
517 if (retval == GPG_ERR_NO_ERROR) {
518 return result;
519 } else {
520 return QCA::SymmetricKey();
521 }
522 }
523
524protected:
525 int m_algorithm;
526};
527
528}
529
530extern "C" {
531
532static void *qca_func_malloc(size_t n)
533{
534 return qca_secure_alloc(bytes: n);
535}
536
537static void *qca_func_secure_malloc(size_t n)
538{
539 return qca_secure_alloc(bytes: n);
540}
541
542static void *qca_func_realloc(void *oldBlock, size_t newBlockSize)
543{
544 return qca_secure_realloc(p: oldBlock, bytes: newBlockSize);
545}
546
547static void qca_func_free(void *mem)
548{
549 qca_secure_free(p: mem);
550}
551
552int qca_func_secure_check(const void *)
553{
554 return (int)QCA::haveSecureMemory();
555}
556} // extern "C"
557
558class gcryptProvider : public QCA::Provider
559{
560public:
561 void init() override
562 {
563 if (!gcry_control(CMD: GCRYCTL_ANY_INITIALIZATION_P)) { /* No other library has already initialized libgcrypt. */
564
565 if (!gcry_check_version(GCRYPT_VERSION)) {
566 std::cout << "libgcrypt is too old (need " << GCRYPT_VERSION;
567 std::cout << ", have " << gcry_check_version(req_version: nullptr) << ")" << std::endl;
568 }
569 gcry_set_allocation_handler(
570 func_alloc: qca_func_malloc, func_alloc_secure: qca_func_secure_malloc, func_secure_check: qca_func_secure_check, func_realloc: qca_func_realloc, func_free: qca_func_free);
571 gcry_control(CMD: GCRYCTL_INITIALIZATION_FINISHED);
572 }
573 }
574
575 int qcaVersion() const override
576 {
577 return QCA_VERSION;
578 }
579
580 QString name() const override
581 {
582 return QStringLiteral("qca-gcrypt");
583 }
584
585 QStringList features() const override
586 {
587 QStringList list;
588 list += QStringLiteral("sha1");
589 list += QStringLiteral("md4");
590 list += QStringLiteral("md5");
591 list += QStringLiteral("ripemd160");
592#ifdef GCRY_MD_SHA224
593 list += QStringLiteral("sha224");
594#endif
595 list += QStringLiteral("sha256");
596 list += QStringLiteral("sha384");
597 list += QStringLiteral("sha512");
598 list += QStringLiteral("hmac(md5)");
599 list += QStringLiteral("hmac(sha1)");
600#ifdef GCRY_MD_SHA224
601 list += QStringLiteral("hmac(sha224)");
602#endif
603 list += QStringLiteral("hmac(sha256)");
604 if (!(nullptr == gcry_check_version(req_version: "1.3.0"))) {
605 // 1.2 and earlier have broken implementation
606 list += QStringLiteral("hmac(sha384)");
607 list += QStringLiteral("hmac(sha512)");
608 }
609 list += QStringLiteral("hmac(ripemd160)");
610 list += QStringLiteral("aes128-ecb");
611 list += QStringLiteral("aes128-cfb");
612 list += QStringLiteral("aes128-cbc");
613 list += QStringLiteral("aes192-ecb");
614 list += QStringLiteral("aes192-cfb");
615 list += QStringLiteral("aes192-cbc");
616 list += QStringLiteral("aes256-ecb");
617 list += QStringLiteral("aes256-cfb");
618 list += QStringLiteral("aes256-cbc");
619 list += QStringLiteral("blowfish-ecb");
620 list += QStringLiteral("blowfish-cbc");
621 list += QStringLiteral("blowfish-cfb");
622 list += QStringLiteral("tripledes-ecb");
623 // list += QStringLiteral("des-ecb");
624 list += QStringLiteral("des-cbc");
625 list += QStringLiteral("des-cfb");
626 if (!(nullptr == gcry_check_version(req_version: "1.3.0"))) {
627 // 1.2 branch and earlier doesn't support OFB mode
628 list += QStringLiteral("aes128-ofb");
629 list += QStringLiteral("aes192-ofb");
630 list += QStringLiteral("aes256-ofb");
631 list += QStringLiteral("des-ofb");
632 list += QStringLiteral("tripledes-ofb");
633 list += QStringLiteral("blowfish-ofb");
634 }
635 list += QStringLiteral("pbkdf1(sha1)");
636 list += QStringLiteral("pbkdf2(sha1)");
637 list += QStringLiteral("hkdf(sha256)");
638 return list;
639 }
640
641 Context *createContext(const QString &type) override
642 {
643 // std::cout << "type: " << qPrintable(type) << std::endl;
644 if (type == QLatin1String("sha1"))
645 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA1, this, type);
646 else if (type == QLatin1String("md4"))
647 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_MD4, this, type);
648 else if (type == QLatin1String("md5"))
649 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_MD5, this, type);
650 else if (type == QLatin1String("ripemd160"))
651 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_RMD160, this, type);
652#ifdef GCRY_MD_SHA224
653 else if (type == QLatin1String("sha224"))
654 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA224, this, type);
655#endif
656 else if (type == QLatin1String("sha256"))
657 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA256, this, type);
658 else if (type == QLatin1String("sha384"))
659 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA384, this, type);
660 else if (type == QLatin1String("sha512"))
661 return new gcryptQCAPlugin::gcryHashContext(GCRY_MD_SHA512, this, type);
662 else if (type == QLatin1String("hmac(md5)"))
663 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_MD5, this, type);
664 else if (type == QLatin1String("hmac(sha1)"))
665 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA1, this, type);
666#ifdef GCRY_MD_SHA224
667 else if (type == QLatin1String("hmac(sha224)"))
668 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA224, this, type);
669#endif
670 else if (type == QLatin1String("hmac(sha256)"))
671 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA256, this, type);
672 else if (type == QLatin1String("hmac(sha384)"))
673 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA384, this, type);
674 else if (type == QLatin1String("hmac(sha512)"))
675 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_SHA512, this, type);
676 else if (type == QLatin1String("hmac(ripemd160)"))
677 return new gcryptQCAPlugin::gcryHMACContext(GCRY_MD_RMD160, this, type);
678 else if (type == QLatin1String("aes128-ecb"))
679 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, false, this, type);
680 else if (type == QLatin1String("aes128-cfb"))
681 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB, false, this, type);
682 else if (type == QLatin1String("aes128-ofb"))
683 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB, false, this, type);
684 else if (type == QLatin1String("aes128-cbc"))
685 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, false, this, type);
686 else if (type == QLatin1String("aes192-ecb"))
687 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, false, this, type);
688 else if (type == QLatin1String("aes192-cfb"))
689 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, false, this, type);
690 else if (type == QLatin1String("aes192-ofb"))
691 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, false, this, type);
692 else if (type == QLatin1String("aes192-cbc"))
693 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, false, this, type);
694 else if (type == QLatin1String("aes256-ecb"))
695 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, false, this, type);
696 else if (type == QLatin1String("aes256-cfb"))
697 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, false, this, type);
698 else if (type == QLatin1String("aes256-ofb"))
699 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, false, this, type);
700 else if (type == QLatin1String("aes256-cbc"))
701 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, false, this, type);
702 else if (type == QLatin1String("blowfish-ecb"))
703 return new gcryptQCAPlugin::gcryCipherContext(
704 GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, false, this, type);
705 else if (type == QLatin1String("blowfish-cbc"))
706 return new gcryptQCAPlugin::gcryCipherContext(
707 GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, false, this, type);
708 else if (type == QLatin1String("blowfish-cfb"))
709 return new gcryptQCAPlugin::gcryCipherContext(
710 GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB, false, this, type);
711 else if (type == QLatin1String("blowfish-ofb"))
712 return new gcryptQCAPlugin::gcryCipherContext(
713 GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB, false, this, type);
714 else if (type == QLatin1String("tripledes-ecb"))
715 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, false, this, type);
716 else if (type == QLatin1String("tripledes-ofb"))
717 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB, false, this, type);
718 else if (type == QLatin1String("des-ecb"))
719 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, false, this, type);
720 else if (type == QLatin1String("des-cbc"))
721 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, false, this, type);
722 else if (type == QLatin1String("des-cfb"))
723 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB, false, this, type);
724 else if (type == QLatin1String("des-ofb"))
725 return new gcryptQCAPlugin::gcryCipherContext(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB, false, this, type);
726 else if (type == QLatin1String("pbkdf1(sha1)"))
727 return new gcryptQCAPlugin::pbkdf1Context(GCRY_MD_SHA1, this, type);
728 else if (type == QLatin1String("pbkdf2(sha1)"))
729 return new gcryptQCAPlugin::pbkdf2Context(GCRY_MD_SHA1, this, type);
730 else if (type == QLatin1String("hkdf(sha256)"))
731 return new gcryptQCAPlugin::hkdfContext(GCRY_MD_SHA256, this, type);
732 else
733 return nullptr;
734 }
735};
736
737class gcryptPlugin : public QObject, public QCAPlugin
738{
739 Q_OBJECT
740 Q_PLUGIN_METADATA(IID "com.affinix.qca.Plugin/1.0")
741 Q_INTERFACES(QCAPlugin)
742public:
743 QCA::Provider *createProvider() override
744 {
745 return new gcryptProvider;
746 }
747};
748
749#include "qca-gcrypt.moc"
750

source code of qca/plugins/qca-gcrypt/qca-gcrypt.cpp