1 | /* |
2 | Copyright (C) 2003 Justin Karneges <justin@affinix.com> |
3 | Copyright (C) 2005-2006 Brad Hards <bradh@frogmouth.net> |
4 | |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy |
6 | of this software and associated documentation files (the "Software"), to deal |
7 | in the Software without restriction, including without limitation the rights |
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
9 | copies of the Software, and to permit persons to whom the Software is |
10 | furnished to do so, subject to the following conditions: |
11 | |
12 | The above copyright notice and this permission notice shall be included in |
13 | all copies or substantial portions of the Software. |
14 | |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
18 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
19 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
21 | */ |
22 | |
23 | // QtCrypto has the declarations for all of QCA |
24 | #include <QtCrypto> |
25 | #include <cstdio> |
26 | |
27 | #include <QCoreApplication> |
28 | |
29 | #ifdef QT_STATICPLUGIN |
30 | #include "import_plugins.h" |
31 | #endif |
32 | |
33 | int main(int argc, char **argv) |
34 | { |
35 | // the Initializer object sets things up, and |
36 | // also does cleanup when it goes out of scope |
37 | QCA::Initializer init; |
38 | |
39 | QCoreApplication app(argc, argv); |
40 | |
41 | // we use the first argument if provided, or |
42 | // use "hello" if no arguments |
43 | QCA::SecureArray arg = (argc >= 2) ? argv[1] : "hello" ; |
44 | |
45 | // AES128 testing |
46 | if (!QCA::isSupported(features: "aes128-cbc-pkcs7" )) |
47 | printf(format: "AES128-CBC not supported!\n" ); |
48 | else { |
49 | // Create a random key - you'd probably use one from another |
50 | // source in a real application |
51 | QCA::SymmetricKey key(16); |
52 | |
53 | // Create a random initialisation vector - you need this |
54 | // value to decrypt the resulting cipher text, but it |
55 | // need not be kept secret (unlike the key). |
56 | QCA::InitializationVector iv(16); |
57 | |
58 | // create a 128 bit AES cipher object using Cipher Block Chaining (CBC) mode |
59 | QCA::Cipher cipher(QStringLiteral("aes128" ), |
60 | QCA::Cipher::CBC, |
61 | // use Default padding, which is equivalent to PKCS7 for CBC |
62 | QCA::Cipher::DefaultPadding, |
63 | // this object will encrypt |
64 | QCA::Encode, |
65 | key, |
66 | iv); |
67 | |
68 | // we use the cipher object to encrypt the argument we passed in |
69 | // the result of that is returned - note that if there is less than |
70 | // 16 bytes (1 block), then nothing will be returned - it is buffered |
71 | // update() can be called as many times as required. |
72 | QCA::SecureArray u = cipher.update(a: arg); |
73 | |
74 | // We need to check if that update() call worked. |
75 | if (!cipher.ok()) { |
76 | printf(format: "Update failed\n" ); |
77 | } |
78 | // output the results of that stage |
79 | printf(format: "AES128 encryption of %s is [%s]\n" , arg.data(), qPrintable(QCA::arrayToHex(u.toByteArray()))); |
80 | |
81 | // Because we are using PKCS7 padding, we need to output the final (padded) block |
82 | // Note that we should always call final() even with no padding, to clean up |
83 | QCA::SecureArray f = cipher.final(); |
84 | |
85 | // Check if the final() call worked |
86 | if (!cipher.ok()) { |
87 | printf(format: "Final failed\n" ); |
88 | } |
89 | // and output the resulting block. The ciphertext is the results of update() |
90 | // and the result of final() |
91 | printf(format: "Final block for AES128 encryption is [0x%s]\n" , qPrintable(QCA::arrayToHex(f.toByteArray()))); |
92 | |
93 | // re-use the Cipher t decrypt. We need to use the same key and |
94 | // initialisation vector as in the encryption. |
95 | cipher.setup(dir: QCA::Decode, key, iv); |
96 | |
97 | // Build a single cipher text array. You could also call update() with |
98 | // each block as you receive it, if that is more useful. |
99 | QCA::SecureArray cipherText = u.append(a: f); |
100 | |
101 | // take that cipher text, and decrypt it |
102 | QCA::SecureArray plainText = cipher.update(a: cipherText); |
103 | |
104 | // check if the update() call worked |
105 | if (!cipher.ok()) { |
106 | printf(format: "Update failed\n" ); |
107 | } |
108 | |
109 | // output results |
110 | printf(format: "Decryption using AES128 of [0x%s] is %s\n" , |
111 | qPrintable(QCA::arrayToHex(cipherText.toByteArray())), |
112 | plainText.data()); |
113 | |
114 | // Again we need to call final(), to get the last block (with its padding removed) |
115 | plainText = cipher.final(); |
116 | |
117 | // check if the final() call worked |
118 | if (!cipher.ok()) { |
119 | printf(format: "Final failed\n" ); |
120 | } |
121 | |
122 | // output results |
123 | printf(format: "Final decryption block using AES128 is %s\n" , plainText.data()); |
124 | // instead of update() and final(), you can do the whole thing |
125 | // in one step, using process() |
126 | printf(format: "One step decryption using AES128: %s\n" , QCA::SecureArray(cipher.process(a: cipherText)).data()); |
127 | } |
128 | |
129 | return 0; |
130 | } |
131 | |