1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "crypto/aes.h"
22#include "crypto/desrfb.h"
23
24typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
25struct QCryptoCipherBuiltinAES {
26 AES_KEY encrypt_key;
27 AES_KEY decrypt_key;
28 uint8_t *iv;
29 size_t niv;
30};
31typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
32struct QCryptoCipherBuiltinDESRFB {
33 uint8_t *key;
34 size_t nkey;
35};
36
37typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
38struct QCryptoCipherBuiltin {
39 union {
40 QCryptoCipherBuiltinAES aes;
41 QCryptoCipherBuiltinDESRFB desrfb;
42 } state;
43 void (*free)(QCryptoCipher *cipher);
44 int (*setiv)(QCryptoCipher *cipher,
45 const uint8_t *iv, size_t niv,
46 Error **errp);
47 int (*encrypt)(QCryptoCipher *cipher,
48 const void *in,
49 void *out,
50 size_t len,
51 Error **errp);
52 int (*decrypt)(QCryptoCipher *cipher,
53 const void *in,
54 void *out,
55 size_t len,
56 Error **errp);
57};
58
59
60static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
61{
62 QCryptoCipherBuiltin *ctxt = cipher->opaque;
63
64 g_free(ctxt->state.aes.iv);
65 g_free(ctxt);
66 cipher->opaque = NULL;
67}
68
69
70static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
71 const void *in,
72 void *out,
73 size_t len,
74 Error **errp)
75{
76 QCryptoCipherBuiltin *ctxt = cipher->opaque;
77
78 if (cipher->mode == QCRYPTO_CIPHER_MODE_ECB) {
79 const uint8_t *inptr = in;
80 uint8_t *outptr = out;
81 while (len) {
82 if (len > AES_BLOCK_SIZE) {
83 AES_encrypt(inptr, outptr, &ctxt->state.aes.encrypt_key);
84 inptr += AES_BLOCK_SIZE;
85 outptr += AES_BLOCK_SIZE;
86 len -= AES_BLOCK_SIZE;
87 } else {
88 uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
89 memcpy(tmp1, inptr, len);
90
91 memset(tmp1 + len, 0, sizeof(tmp1) - len);
92 AES_encrypt(tmp1, tmp2, &ctxt->state.aes.encrypt_key);
93 memcpy(outptr, tmp2, len);
94 len = 0;
95 }
96 }
97 } else {
98 AES_cbc_encrypt(in, out, len,
99 &ctxt->state.aes.encrypt_key,
100 ctxt->state.aes.iv, 1);
101 }
102
103 return 0;
104}
105
106
107static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
108 const void *in,
109 void *out,
110 size_t len,
111 Error **errp)
112{
113 QCryptoCipherBuiltin *ctxt = cipher->opaque;
114
115 if (cipher->mode == QCRYPTO_CIPHER_MODE_ECB) {
116 const uint8_t *inptr = in;
117 uint8_t *outptr = out;
118 while (len) {
119 if (len > AES_BLOCK_SIZE) {
120 AES_decrypt(inptr, outptr, &ctxt->state.aes.decrypt_key);
121 inptr += AES_BLOCK_SIZE;
122 outptr += AES_BLOCK_SIZE;
123 len -= AES_BLOCK_SIZE;
124 } else {
125 uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
126 memcpy(tmp1, inptr, len);
127
128 memset(tmp1 + len, 0, sizeof(tmp1) - len);
129 AES_decrypt(tmp1, tmp2, &ctxt->state.aes.decrypt_key);
130 memcpy(outptr, tmp2, len);
131 len = 0;
132 }
133 }
134 } else {
135 AES_cbc_encrypt(in, out, len,
136 &ctxt->state.aes.decrypt_key,
137 ctxt->state.aes.iv, 0);
138 }
139
140 return 0;
141}
142
143static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
144 const uint8_t *iv, size_t niv,
145 Error **errp)
146{
147 QCryptoCipherBuiltin *ctxt = cipher->opaque;
148 if (niv != 16) {
149 error_setg(errp, "IV must be 16 bytes not %zu", niv);
150 return -1;
151 }
152
153 g_free(ctxt->state.aes.iv);
154 ctxt->state.aes.iv = g_new0(uint8_t, niv);
155 memcpy(ctxt->state.aes.iv, iv, niv);
156 ctxt->state.aes.niv = niv;
157
158 return 0;
159}
160
161
162
163
164static int qcrypto_cipher_init_aes(QCryptoCipher *cipher,
165 const uint8_t *key, size_t nkey,
166 Error **errp)
167{
168 QCryptoCipherBuiltin *ctxt;
169
170 if (cipher->mode != QCRYPTO_CIPHER_MODE_CBC &&
171 cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {
172 error_setg(errp, "Unsupported cipher mode %d", cipher->mode);
173 return -1;
174 }
175
176 ctxt = g_new0(QCryptoCipherBuiltin, 1);
177
178 if (AES_set_encrypt_key(key, nkey * 8, &ctxt->state.aes.encrypt_key) != 0) {
179 error_setg(errp, "Failed to set encryption key");
180 goto error;
181 }
182
183 if (AES_set_decrypt_key(key, nkey * 8, &ctxt->state.aes.decrypt_key) != 0) {
184 error_setg(errp, "Failed to set decryption key");
185 goto error;
186 }
187
188 ctxt->free = qcrypto_cipher_free_aes;
189 ctxt->setiv = qcrypto_cipher_setiv_aes;
190 ctxt->encrypt = qcrypto_cipher_encrypt_aes;
191 ctxt->decrypt = qcrypto_cipher_decrypt_aes;
192
193 cipher->opaque = ctxt;
194
195 return 0;
196
197 error:
198 g_free(ctxt);
199 return -1;
200}
201
202
203static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher)
204{
205 QCryptoCipherBuiltin *ctxt = cipher->opaque;
206
207 g_free(ctxt->state.desrfb.key);
208 g_free(ctxt);
209 cipher->opaque = NULL;
210}
211
212
213static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
214 const void *in,
215 void *out,
216 size_t len,
217 Error **errp)
218{
219 QCryptoCipherBuiltin *ctxt = cipher->opaque;
220 size_t i;
221
222 if (len % 8) {
223 error_setg(errp, "Buffer size must be multiple of 8 not %zu",
224 len);
225 return -1;
226 }
227
228 deskey(ctxt->state.desrfb.key, EN0);
229
230 for (i = 0; i < len; i += 8) {
231 des((void *)in + i, out + i);
232 }
233
234 return 0;
235}
236
237
238static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
239 const void *in,
240 void *out,
241 size_t len,
242 Error **errp)
243{
244 QCryptoCipherBuiltin *ctxt = cipher->opaque;
245 size_t i;
246
247 if (len % 8) {
248 error_setg(errp, "Buffer size must be multiple of 8 not %zu",
249 len);
250 return -1;
251 }
252
253 deskey(ctxt->state.desrfb.key, DE1);
254
255 for (i = 0; i < len; i += 8) {
256 des((void *)in + i, out + i);
257 }
258
259 return 0;
260}
261
262
263static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher,
264 const uint8_t *iv, size_t niv,
265 Error **errp)
266{
267 error_setg(errp, "Setting IV is not supported");
268 return -1;
269}
270
271
272static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,
273 const uint8_t *key, size_t nkey,
274 Error **errp)
275{
276 QCryptoCipherBuiltin *ctxt;
277
278 if (cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {
279 error_setg(errp, "Unsupported cipher mode %d", cipher->mode);
280 return -1;
281 }
282
283 ctxt = g_new0(QCryptoCipherBuiltin, 1);
284
285 ctxt->state.desrfb.key = g_new0(uint8_t, nkey);
286 memcpy(ctxt->state.desrfb.key, key, nkey);
287 ctxt->state.desrfb.nkey = nkey;
288
289 ctxt->free = qcrypto_cipher_free_des_rfb;
290 ctxt->setiv = qcrypto_cipher_setiv_des_rfb;
291 ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
292 ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;
293
294 cipher->opaque = ctxt;
295
296 return 0;
297}
298
299
300bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
301{
302 switch (alg) {
303 case QCRYPTO_CIPHER_ALG_DES_RFB:
304 case QCRYPTO_CIPHER_ALG_AES_128:
305 case QCRYPTO_CIPHER_ALG_AES_192:
306 case QCRYPTO_CIPHER_ALG_AES_256:
307 return true;
308 default:
309 return false;
310 }
311}
312
313
314QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
315 QCryptoCipherMode mode,
316 const uint8_t *key, size_t nkey,
317 Error **errp)
318{
319 QCryptoCipher *cipher;
320
321 cipher = g_new0(QCryptoCipher, 1);
322 cipher->alg = alg;
323 cipher->mode = mode;
324
325 if (!qcrypto_cipher_validate_key_length(alg, nkey, errp)) {
326 goto error;
327 }
328
329 switch (cipher->alg) {
330 case QCRYPTO_CIPHER_ALG_DES_RFB:
331 if (qcrypto_cipher_init_des_rfb(cipher, key, nkey, errp) < 0) {
332 goto error;
333 }
334 break;
335 case QCRYPTO_CIPHER_ALG_AES_128:
336 case QCRYPTO_CIPHER_ALG_AES_192:
337 case QCRYPTO_CIPHER_ALG_AES_256:
338 if (qcrypto_cipher_init_aes(cipher, key, nkey, errp) < 0) {
339 goto error;
340 }
341 break;
342 default:
343 error_setg(errp,
344 "Unsupported cipher algorithm %d", cipher->alg);
345 goto error;
346 }
347
348 return cipher;
349
350 error:
351 g_free(cipher);
352 return NULL;
353}
354
355void qcrypto_cipher_free(QCryptoCipher *cipher)
356{
357 QCryptoCipherBuiltin *ctxt;
358
359 if (!cipher) {
360 return;
361 }
362
363 ctxt = cipher->opaque;
364 ctxt->free(cipher);
365 g_free(cipher);
366}
367
368
369int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
370 const void *in,
371 void *out,
372 size_t len,
373 Error **errp)
374{
375 QCryptoCipherBuiltin *ctxt = cipher->opaque;
376
377 return ctxt->encrypt(cipher, in, out, len, errp);
378}
379
380
381int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
382 const void *in,
383 void *out,
384 size_t len,
385 Error **errp)
386{
387 QCryptoCipherBuiltin *ctxt = cipher->opaque;
388
389 return ctxt->decrypt(cipher, in, out, len, errp);
390}
391
392
393int qcrypto_cipher_setiv(QCryptoCipher *cipher,
394 const uint8_t *iv, size_t niv,
395 Error **errp)
396{
397 QCryptoCipherBuiltin *ctxt = cipher->opaque;
398
399 return ctxt->setiv(cipher, iv, niv, errp);
400}
401