]> git.proxmox.com Git - mirror_qemu.git/blob - crypto/cipher-builtin.c.inc
qdev: Avoid using prop->name unnecessarily
[mirror_qemu.git] / crypto / cipher-builtin.c.inc
1 /*
2 * QEMU Crypto cipher built-in algorithms
3 *
4 * Copyright (c) 2015 Red Hat, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #include "crypto/aes.h"
22 #include "crypto/desrfb.h"
23 #include "crypto/xts.h"
24
25 typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext;
26 struct QCryptoCipherBuiltinAESContext {
27 AES_KEY enc;
28 AES_KEY dec;
29 };
30
31 typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
32 struct QCryptoCipherBuiltinAES {
33 QCryptoCipher base;
34 QCryptoCipherBuiltinAESContext key;
35 QCryptoCipherBuiltinAESContext key_tweak;
36 uint8_t iv[AES_BLOCK_SIZE];
37 };
38
39
40 static inline bool qcrypto_length_check(size_t len, size_t blocksize,
41 Error **errp)
42 {
43 if (unlikely(len & (blocksize - 1))) {
44 error_setg(errp, "Length %zu must be a multiple of block size %zu",
45 len, blocksize);
46 return false;
47 }
48 return true;
49 }
50
51 static void qcrypto_cipher_ctx_free(QCryptoCipher *cipher)
52 {
53 g_free(cipher);
54 }
55
56 static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher,
57 const uint8_t *iv, size_t niv,
58 Error **errp)
59 {
60 error_setg(errp, "Setting IV is not supported");
61 return -1;
62 }
63
64 static void do_aes_encrypt_ecb(const void *vctx,
65 size_t len,
66 uint8_t *out,
67 const uint8_t *in)
68 {
69 const QCryptoCipherBuiltinAESContext *ctx = vctx;
70
71 /* We have already verified that len % AES_BLOCK_SIZE == 0. */
72 while (len) {
73 AES_encrypt(in, out, &ctx->enc);
74 in += AES_BLOCK_SIZE;
75 out += AES_BLOCK_SIZE;
76 len -= AES_BLOCK_SIZE;
77 }
78 }
79
80 static void do_aes_decrypt_ecb(const void *vctx,
81 size_t len,
82 uint8_t *out,
83 const uint8_t *in)
84 {
85 const QCryptoCipherBuiltinAESContext *ctx = vctx;
86
87 /* We have already verified that len % AES_BLOCK_SIZE == 0. */
88 while (len) {
89 AES_decrypt(in, out, &ctx->dec);
90 in += AES_BLOCK_SIZE;
91 out += AES_BLOCK_SIZE;
92 len -= AES_BLOCK_SIZE;
93 }
94 }
95
96 static void do_aes_encrypt_cbc(const AES_KEY *key,
97 size_t len,
98 uint8_t *out,
99 const uint8_t *in,
100 uint8_t *ivec)
101 {
102 uint8_t tmp[AES_BLOCK_SIZE];
103 size_t n;
104
105 /* We have already verified that len % AES_BLOCK_SIZE == 0. */
106 while (len) {
107 for (n = 0; n < AES_BLOCK_SIZE; ++n) {
108 tmp[n] = in[n] ^ ivec[n];
109 }
110 AES_encrypt(tmp, out, key);
111 memcpy(ivec, out, AES_BLOCK_SIZE);
112 len -= AES_BLOCK_SIZE;
113 in += AES_BLOCK_SIZE;
114 out += AES_BLOCK_SIZE;
115 }
116 }
117
118 static void do_aes_decrypt_cbc(const AES_KEY *key,
119 size_t len,
120 uint8_t *out,
121 const uint8_t *in,
122 uint8_t *ivec)
123 {
124 uint8_t tmp[AES_BLOCK_SIZE];
125 size_t n;
126
127 /* We have already verified that len % AES_BLOCK_SIZE == 0. */
128 while (len) {
129 memcpy(tmp, in, AES_BLOCK_SIZE);
130 AES_decrypt(in, out, key);
131 for (n = 0; n < AES_BLOCK_SIZE; ++n) {
132 out[n] ^= ivec[n];
133 }
134 memcpy(ivec, tmp, AES_BLOCK_SIZE);
135 len -= AES_BLOCK_SIZE;
136 in += AES_BLOCK_SIZE;
137 out += AES_BLOCK_SIZE;
138 }
139 }
140
141 static int qcrypto_cipher_aes_encrypt_ecb(QCryptoCipher *cipher,
142 const void *in, void *out,
143 size_t len, Error **errp)
144 {
145 QCryptoCipherBuiltinAES *ctx
146 = container_of(cipher, QCryptoCipherBuiltinAES, base);
147
148 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
149 return -1;
150 }
151 do_aes_encrypt_ecb(&ctx->key, len, out, in);
152 return 0;
153 }
154
155 static int qcrypto_cipher_aes_decrypt_ecb(QCryptoCipher *cipher,
156 const void *in, void *out,
157 size_t len, Error **errp)
158 {
159 QCryptoCipherBuiltinAES *ctx
160 = container_of(cipher, QCryptoCipherBuiltinAES, base);
161
162 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
163 return -1;
164 }
165 do_aes_decrypt_ecb(&ctx->key, len, out, in);
166 return 0;
167 }
168
169 static int qcrypto_cipher_aes_encrypt_cbc(QCryptoCipher *cipher,
170 const void *in, void *out,
171 size_t len, Error **errp)
172 {
173 QCryptoCipherBuiltinAES *ctx
174 = container_of(cipher, QCryptoCipherBuiltinAES, base);
175
176 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
177 return -1;
178 }
179 do_aes_encrypt_cbc(&ctx->key.enc, len, out, in, ctx->iv);
180 return 0;
181 }
182
183 static int qcrypto_cipher_aes_decrypt_cbc(QCryptoCipher *cipher,
184 const void *in, void *out,
185 size_t len, Error **errp)
186 {
187 QCryptoCipherBuiltinAES *ctx
188 = container_of(cipher, QCryptoCipherBuiltinAES, base);
189
190 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
191 return -1;
192 }
193 do_aes_decrypt_cbc(&ctx->key.dec, len, out, in, ctx->iv);
194 return 0;
195 }
196
197 static int qcrypto_cipher_aes_encrypt_xts(QCryptoCipher *cipher,
198 const void *in, void *out,
199 size_t len, Error **errp)
200 {
201 QCryptoCipherBuiltinAES *ctx
202 = container_of(cipher, QCryptoCipherBuiltinAES, base);
203
204 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
205 return -1;
206 }
207 xts_encrypt(&ctx->key, &ctx->key_tweak,
208 do_aes_encrypt_ecb, do_aes_decrypt_ecb,
209 ctx->iv, len, out, in);
210 return 0;
211 }
212
213 static int qcrypto_cipher_aes_decrypt_xts(QCryptoCipher *cipher,
214 const void *in, void *out,
215 size_t len, Error **errp)
216 {
217 QCryptoCipherBuiltinAES *ctx
218 = container_of(cipher, QCryptoCipherBuiltinAES, base);
219
220 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
221 return -1;
222 }
223 xts_decrypt(&ctx->key, &ctx->key_tweak,
224 do_aes_encrypt_ecb, do_aes_decrypt_ecb,
225 ctx->iv, len, out, in);
226 return 0;
227 }
228
229
230 static int qcrypto_cipher_aes_setiv(QCryptoCipher *cipher, const uint8_t *iv,
231 size_t niv, Error **errp)
232 {
233 QCryptoCipherBuiltinAES *ctx
234 = container_of(cipher, QCryptoCipherBuiltinAES, base);
235
236 if (niv != AES_BLOCK_SIZE) {
237 error_setg(errp, "IV must be %d bytes not %zu",
238 AES_BLOCK_SIZE, niv);
239 return -1;
240 }
241
242 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
243 return 0;
244 }
245
246 static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_ecb = {
247 .cipher_encrypt = qcrypto_cipher_aes_encrypt_ecb,
248 .cipher_decrypt = qcrypto_cipher_aes_decrypt_ecb,
249 .cipher_setiv = qcrypto_cipher_no_setiv,
250 .cipher_free = qcrypto_cipher_ctx_free,
251 };
252
253 static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_cbc = {
254 .cipher_encrypt = qcrypto_cipher_aes_encrypt_cbc,
255 .cipher_decrypt = qcrypto_cipher_aes_decrypt_cbc,
256 .cipher_setiv = qcrypto_cipher_aes_setiv,
257 .cipher_free = qcrypto_cipher_ctx_free,
258 };
259
260 static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_xts = {
261 .cipher_encrypt = qcrypto_cipher_aes_encrypt_xts,
262 .cipher_decrypt = qcrypto_cipher_aes_decrypt_xts,
263 .cipher_setiv = qcrypto_cipher_aes_setiv,
264 .cipher_free = qcrypto_cipher_ctx_free,
265 };
266
267
268 typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
269 struct QCryptoCipherBuiltinDESRFB {
270 QCryptoCipher base;
271
272 /* C.f. alg_key_len[QCRYPTO_CIPHER_ALG_DES_RFB] */
273 uint8_t key[8];
274 };
275
276 static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
277 const void *in, void *out,
278 size_t len, Error **errp)
279 {
280 QCryptoCipherBuiltinDESRFB *ctx
281 = container_of(cipher, QCryptoCipherBuiltinDESRFB, base);
282 size_t i;
283
284 if (!qcrypto_length_check(len, 8, errp)) {
285 return -1;
286 }
287
288 deskey(ctx->key, EN0);
289
290 for (i = 0; i < len; i += 8) {
291 des((void *)in + i, out + i);
292 }
293
294 return 0;
295 }
296
297 static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
298 const void *in, void *out,
299 size_t len, Error **errp)
300 {
301 QCryptoCipherBuiltinDESRFB *ctx
302 = container_of(cipher, QCryptoCipherBuiltinDESRFB, base);
303 size_t i;
304
305 if (!qcrypto_length_check(len, 8, errp)) {
306 return -1;
307 }
308
309 deskey(ctx->key, DE1);
310
311 for (i = 0; i < len; i += 8) {
312 des((void *)in + i, out + i);
313 }
314
315 return 0;
316 }
317
318 static const struct QCryptoCipherDriver qcrypto_cipher_des_rfb_driver = {
319 .cipher_encrypt = qcrypto_cipher_encrypt_des_rfb,
320 .cipher_decrypt = qcrypto_cipher_decrypt_des_rfb,
321 .cipher_setiv = qcrypto_cipher_no_setiv,
322 .cipher_free = qcrypto_cipher_ctx_free,
323 };
324
325 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
326 QCryptoCipherMode mode)
327 {
328 switch (alg) {
329 case QCRYPTO_CIPHER_ALG_DES_RFB:
330 return mode == QCRYPTO_CIPHER_MODE_ECB;
331 case QCRYPTO_CIPHER_ALG_AES_128:
332 case QCRYPTO_CIPHER_ALG_AES_192:
333 case QCRYPTO_CIPHER_ALG_AES_256:
334 switch (mode) {
335 case QCRYPTO_CIPHER_MODE_ECB:
336 case QCRYPTO_CIPHER_MODE_CBC:
337 case QCRYPTO_CIPHER_MODE_XTS:
338 return true;
339 default:
340 return false;
341 }
342 break;
343 default:
344 return false;
345 }
346 }
347
348 static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
349 QCryptoCipherMode mode,
350 const uint8_t *key,
351 size_t nkey,
352 Error **errp)
353 {
354 if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
355 return NULL;
356 }
357
358 switch (alg) {
359 case QCRYPTO_CIPHER_ALG_DES_RFB:
360 if (mode == QCRYPTO_CIPHER_MODE_ECB) {
361 QCryptoCipherBuiltinDESRFB *ctx;
362
363 ctx = g_new0(QCryptoCipherBuiltinDESRFB, 1);
364 ctx->base.driver = &qcrypto_cipher_des_rfb_driver;
365 memcpy(ctx->key, key, sizeof(ctx->key));
366
367 return &ctx->base;
368 }
369 goto bad_mode;
370
371 case QCRYPTO_CIPHER_ALG_AES_128:
372 case QCRYPTO_CIPHER_ALG_AES_192:
373 case QCRYPTO_CIPHER_ALG_AES_256:
374 {
375 QCryptoCipherBuiltinAES *ctx;
376 const QCryptoCipherDriver *drv;
377
378 switch (mode) {
379 case QCRYPTO_CIPHER_MODE_ECB:
380 drv = &qcrypto_cipher_aes_driver_ecb;
381 break;
382 case QCRYPTO_CIPHER_MODE_CBC:
383 drv = &qcrypto_cipher_aes_driver_cbc;
384 break;
385 case QCRYPTO_CIPHER_MODE_XTS:
386 drv = &qcrypto_cipher_aes_driver_xts;
387 break;
388 default:
389 goto bad_mode;
390 }
391
392 ctx = g_new0(QCryptoCipherBuiltinAES, 1);
393 ctx->base.driver = drv;
394
395 if (mode == QCRYPTO_CIPHER_MODE_XTS) {
396 nkey /= 2;
397 if (AES_set_encrypt_key(key + nkey, nkey * 8,
398 &ctx->key_tweak.enc)) {
399 error_setg(errp, "Failed to set encryption key");
400 goto error;
401 }
402 if (AES_set_decrypt_key(key + nkey, nkey * 8,
403 &ctx->key_tweak.dec)) {
404 error_setg(errp, "Failed to set decryption key");
405 goto error;
406 }
407 }
408 if (AES_set_encrypt_key(key, nkey * 8, &ctx->key.enc)) {
409 error_setg(errp, "Failed to set encryption key");
410 goto error;
411 }
412 if (AES_set_decrypt_key(key, nkey * 8, &ctx->key.dec)) {
413 error_setg(errp, "Failed to set decryption key");
414 goto error;
415 }
416
417 return &ctx->base;
418
419 error:
420 g_free(ctx);
421 return NULL;
422 }
423
424 default:
425 error_setg(errp,
426 "Unsupported cipher algorithm %s",
427 QCryptoCipherAlgorithm_str(alg));
428 return NULL;
429 }
430
431 bad_mode:
432 error_setg(errp, "Unsupported cipher mode %s",
433 QCryptoCipherMode_str(mode));
434 return NULL;
435 }