]>
Commit | Line | Data |
---|---|---|
ed754746 DB |
1 | /* |
2 | * QEMU Crypto cipher nettle 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 | |
b7cbb874 | 9 | * version 2.1 of the License, or (at your option) any later version. |
ed754746 DB |
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 | ||
42f7a448 | 21 | #include "qemu/osdep.h" |
eaec903c | 22 | #include "crypto/xts.h" |
75c80078 | 23 | #include "cipherpriv.h" |
eaec903c | 24 | |
ed754746 DB |
25 | #include <nettle/nettle-types.h> |
26 | #include <nettle/aes.h> | |
27 | #include <nettle/des.h> | |
28 | #include <nettle/cbc.h> | |
084a85ee | 29 | #include <nettle/cast128.h> |
94318522 | 30 | #include <nettle/serpent.h> |
50f6753e | 31 | #include <nettle/twofish.h> |
3c28292f | 32 | #include <nettle/ctr.h> |
ed754746 | 33 | |
f7ac78cf DB |
34 | typedef void (*QCryptoCipherNettleFuncWrapper)(const void *ctx, |
35 | size_t length, | |
36 | uint8_t *dst, | |
37 | const uint8_t *src); | |
d3462e37 | 38 | |
f7ac78cf DB |
39 | #if CONFIG_NETTLE_VERSION_MAJOR < 3 |
40 | typedef nettle_crypt_func * QCryptoCipherNettleFuncNative; | |
d3462e37 RK |
41 | typedef void * cipher_ctx_t; |
42 | typedef unsigned cipher_length_t; | |
621e6ae6 DB |
43 | |
44 | #define cast5_set_key cast128_set_key | |
e8e67ca4 DB |
45 | |
46 | #define aes128_ctx aes_ctx | |
47 | #define aes192_ctx aes_ctx | |
48 | #define aes256_ctx aes_ctx | |
49 | #define aes128_set_encrypt_key(c, k) \ | |
50 | aes_set_encrypt_key(c, 16, k) | |
51 | #define aes192_set_encrypt_key(c, k) \ | |
52 | aes_set_encrypt_key(c, 24, k) | |
53 | #define aes256_set_encrypt_key(c, k) \ | |
54 | aes_set_encrypt_key(c, 32, k) | |
55 | #define aes128_set_decrypt_key(c, k) \ | |
56 | aes_set_decrypt_key(c, 16, k) | |
57 | #define aes192_set_decrypt_key(c, k) \ | |
58 | aes_set_decrypt_key(c, 24, k) | |
59 | #define aes256_set_decrypt_key(c, k) \ | |
60 | aes_set_decrypt_key(c, 32, k) | |
61 | #define aes128_encrypt aes_encrypt | |
62 | #define aes192_encrypt aes_encrypt | |
63 | #define aes256_encrypt aes_encrypt | |
64 | #define aes128_decrypt aes_decrypt | |
65 | #define aes192_decrypt aes_decrypt | |
66 | #define aes256_decrypt aes_decrypt | |
d3462e37 | 67 | #else |
f7ac78cf | 68 | typedef nettle_cipher_func * QCryptoCipherNettleFuncNative; |
d3462e37 RK |
69 | typedef const void * cipher_ctx_t; |
70 | typedef size_t cipher_length_t; | |
becaeb72 RK |
71 | #endif |
72 | ||
e8e67ca4 DB |
73 | typedef struct QCryptoNettleAES128 { |
74 | struct aes128_ctx enc; | |
75 | struct aes128_ctx dec; | |
76 | } QCryptoNettleAES128; | |
77 | ||
78 | typedef struct QCryptoNettleAES192 { | |
79 | struct aes192_ctx enc; | |
80 | struct aes192_ctx dec; | |
81 | } QCryptoNettleAES192; | |
82 | ||
83 | typedef struct QCryptoNettleAES256 { | |
84 | struct aes256_ctx enc; | |
85 | struct aes256_ctx dec; | |
86 | } QCryptoNettleAES256; | |
87 | ||
88 | static void aes128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
89 | uint8_t *dst, const uint8_t *src) | |
90 | { | |
91 | const QCryptoNettleAES128 *aesctx = ctx; | |
92 | aes128_encrypt(&aesctx->enc, length, dst, src); | |
93 | } | |
94 | ||
95 | static void aes128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
96 | uint8_t *dst, const uint8_t *src) | |
97 | { | |
98 | const QCryptoNettleAES128 *aesctx = ctx; | |
99 | aes128_decrypt(&aesctx->dec, length, dst, src); | |
100 | } | |
101 | ||
102 | static void aes192_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
103 | uint8_t *dst, const uint8_t *src) | |
104 | { | |
105 | const QCryptoNettleAES192 *aesctx = ctx; | |
106 | aes192_encrypt(&aesctx->enc, length, dst, src); | |
107 | } | |
108 | ||
109 | static void aes192_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
110 | uint8_t *dst, const uint8_t *src) | |
111 | { | |
112 | const QCryptoNettleAES192 *aesctx = ctx; | |
113 | aes192_decrypt(&aesctx->dec, length, dst, src); | |
114 | } | |
e3ba0b67 | 115 | |
e8e67ca4 | 116 | static void aes256_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, |
f7ac78cf DB |
117 | uint8_t *dst, const uint8_t *src) |
118 | { | |
e8e67ca4 DB |
119 | const QCryptoNettleAES256 *aesctx = ctx; |
120 | aes256_encrypt(&aesctx->enc, length, dst, src); | |
f7ac78cf DB |
121 | } |
122 | ||
e8e67ca4 | 123 | static void aes256_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, |
f7ac78cf DB |
124 | uint8_t *dst, const uint8_t *src) |
125 | { | |
e8e67ca4 DB |
126 | const QCryptoNettleAES256 *aesctx = ctx; |
127 | aes256_decrypt(&aesctx->dec, length, dst, src); | |
f7ac78cf DB |
128 | } |
129 | ||
130 | static void des_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
131 | uint8_t *dst, const uint8_t *src) | |
132 | { | |
133 | des_encrypt(ctx, length, dst, src); | |
134 | } | |
135 | ||
136 | static void des_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
137 | uint8_t *dst, const uint8_t *src) | |
138 | { | |
139 | des_decrypt(ctx, length, dst, src); | |
140 | } | |
141 | ||
ffb7bf45 LM |
142 | static void des3_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, |
143 | uint8_t *dst, const uint8_t *src) | |
144 | { | |
145 | des3_encrypt(ctx, length, dst, src); | |
146 | } | |
147 | ||
148 | static void des3_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
149 | uint8_t *dst, const uint8_t *src) | |
150 | { | |
151 | des3_decrypt(ctx, length, dst, src); | |
152 | } | |
153 | ||
f7ac78cf DB |
154 | static void cast128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, |
155 | uint8_t *dst, const uint8_t *src) | |
156 | { | |
157 | cast128_encrypt(ctx, length, dst, src); | |
158 | } | |
159 | ||
160 | static void cast128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
161 | uint8_t *dst, const uint8_t *src) | |
162 | { | |
163 | cast128_decrypt(ctx, length, dst, src); | |
164 | } | |
165 | ||
166 | static void serpent_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
167 | uint8_t *dst, const uint8_t *src) | |
168 | { | |
169 | serpent_encrypt(ctx, length, dst, src); | |
170 | } | |
171 | ||
172 | static void serpent_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
173 | uint8_t *dst, const uint8_t *src) | |
174 | { | |
175 | serpent_decrypt(ctx, length, dst, src); | |
176 | } | |
177 | ||
178 | static void twofish_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
179 | uint8_t *dst, const uint8_t *src) | |
180 | { | |
181 | twofish_encrypt(ctx, length, dst, src); | |
182 | } | |
183 | ||
184 | static void twofish_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, | |
185 | uint8_t *dst, const uint8_t *src) | |
186 | { | |
187 | twofish_decrypt(ctx, length, dst, src); | |
188 | } | |
189 | ||
e8e67ca4 DB |
190 | static void aes128_encrypt_wrapper(const void *ctx, size_t length, |
191 | uint8_t *dst, const uint8_t *src) | |
192 | { | |
193 | const QCryptoNettleAES128 *aesctx = ctx; | |
194 | aes128_encrypt(&aesctx->enc, length, dst, src); | |
195 | } | |
196 | ||
197 | static void aes128_decrypt_wrapper(const void *ctx, size_t length, | |
d3462e37 RK |
198 | uint8_t *dst, const uint8_t *src) |
199 | { | |
e8e67ca4 DB |
200 | const QCryptoNettleAES128 *aesctx = ctx; |
201 | aes128_decrypt(&aesctx->dec, length, dst, src); | |
d3462e37 RK |
202 | } |
203 | ||
e8e67ca4 | 204 | static void aes192_encrypt_wrapper(const void *ctx, size_t length, |
d3462e37 RK |
205 | uint8_t *dst, const uint8_t *src) |
206 | { | |
e8e67ca4 DB |
207 | const QCryptoNettleAES192 *aesctx = ctx; |
208 | aes192_encrypt(&aesctx->enc, length, dst, src); | |
209 | } | |
210 | ||
211 | static void aes192_decrypt_wrapper(const void *ctx, size_t length, | |
212 | uint8_t *dst, const uint8_t *src) | |
213 | { | |
214 | const QCryptoNettleAES192 *aesctx = ctx; | |
215 | aes192_decrypt(&aesctx->dec, length, dst, src); | |
216 | } | |
217 | ||
218 | static void aes256_encrypt_wrapper(const void *ctx, size_t length, | |
219 | uint8_t *dst, const uint8_t *src) | |
220 | { | |
221 | const QCryptoNettleAES256 *aesctx = ctx; | |
222 | aes256_encrypt(&aesctx->enc, length, dst, src); | |
223 | } | |
224 | ||
225 | static void aes256_decrypt_wrapper(const void *ctx, size_t length, | |
226 | uint8_t *dst, const uint8_t *src) | |
227 | { | |
228 | const QCryptoNettleAES256 *aesctx = ctx; | |
229 | aes256_decrypt(&aesctx->dec, length, dst, src); | |
d3462e37 RK |
230 | } |
231 | ||
f7ac78cf | 232 | static void des_encrypt_wrapper(const void *ctx, size_t length, |
d3462e37 RK |
233 | uint8_t *dst, const uint8_t *src) |
234 | { | |
235 | des_encrypt(ctx, length, dst, src); | |
236 | } | |
237 | ||
f7ac78cf | 238 | static void des_decrypt_wrapper(const void *ctx, size_t length, |
d3462e37 RK |
239 | uint8_t *dst, const uint8_t *src) |
240 | { | |
241 | des_decrypt(ctx, length, dst, src); | |
242 | } | |
243 | ||
ffb7bf45 LM |
244 | static void des3_encrypt_wrapper(const void *ctx, size_t length, |
245 | uint8_t *dst, const uint8_t *src) | |
246 | { | |
247 | des3_encrypt(ctx, length, dst, src); | |
248 | } | |
249 | ||
250 | static void des3_decrypt_wrapper(const void *ctx, size_t length, | |
251 | uint8_t *dst, const uint8_t *src) | |
252 | { | |
253 | des3_decrypt(ctx, length, dst, src); | |
254 | } | |
255 | ||
f7ac78cf | 256 | static void cast128_encrypt_wrapper(const void *ctx, size_t length, |
084a85ee DB |
257 | uint8_t *dst, const uint8_t *src) |
258 | { | |
259 | cast128_encrypt(ctx, length, dst, src); | |
260 | } | |
261 | ||
f7ac78cf | 262 | static void cast128_decrypt_wrapper(const void *ctx, size_t length, |
084a85ee DB |
263 | uint8_t *dst, const uint8_t *src) |
264 | { | |
265 | cast128_decrypt(ctx, length, dst, src); | |
266 | } | |
267 | ||
f7ac78cf | 268 | static void serpent_encrypt_wrapper(const void *ctx, size_t length, |
94318522 DB |
269 | uint8_t *dst, const uint8_t *src) |
270 | { | |
271 | serpent_encrypt(ctx, length, dst, src); | |
272 | } | |
273 | ||
f7ac78cf | 274 | static void serpent_decrypt_wrapper(const void *ctx, size_t length, |
94318522 DB |
275 | uint8_t *dst, const uint8_t *src) |
276 | { | |
277 | serpent_decrypt(ctx, length, dst, src); | |
278 | } | |
279 | ||
f7ac78cf | 280 | static void twofish_encrypt_wrapper(const void *ctx, size_t length, |
50f6753e DB |
281 | uint8_t *dst, const uint8_t *src) |
282 | { | |
283 | twofish_encrypt(ctx, length, dst, src); | |
284 | } | |
285 | ||
f7ac78cf | 286 | static void twofish_decrypt_wrapper(const void *ctx, size_t length, |
50f6753e DB |
287 | uint8_t *dst, const uint8_t *src) |
288 | { | |
289 | twofish_decrypt(ctx, length, dst, src); | |
290 | } | |
291 | ||
ed754746 DB |
292 | typedef struct QCryptoCipherNettle QCryptoCipherNettle; |
293 | struct QCryptoCipherNettle { | |
eaec903c | 294 | /* Primary cipher context for all modes */ |
e3ba0b67 | 295 | void *ctx; |
eaec903c DB |
296 | /* Second cipher context for XTS mode only */ |
297 | void *ctx_tweak; | |
298 | /* Cipher callbacks for both contexts */ | |
f7ac78cf DB |
299 | QCryptoCipherNettleFuncNative alg_encrypt_native; |
300 | QCryptoCipherNettleFuncNative alg_decrypt_native; | |
301 | QCryptoCipherNettleFuncWrapper alg_encrypt_wrapper; | |
302 | QCryptoCipherNettleFuncWrapper alg_decrypt_wrapper; | |
3c28292f | 303 | /* Initialization vector or Counter */ |
ed754746 | 304 | uint8_t *iv; |
3a661f1e | 305 | size_t blocksize; |
ed754746 DB |
306 | }; |
307 | ||
f844836d GA |
308 | bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, |
309 | QCryptoCipherMode mode) | |
ed754746 DB |
310 | { |
311 | switch (alg) { | |
312 | case QCRYPTO_CIPHER_ALG_DES_RFB: | |
ffb7bf45 | 313 | case QCRYPTO_CIPHER_ALG_3DES: |
ed754746 DB |
314 | case QCRYPTO_CIPHER_ALG_AES_128: |
315 | case QCRYPTO_CIPHER_ALG_AES_192: | |
316 | case QCRYPTO_CIPHER_ALG_AES_256: | |
084a85ee | 317 | case QCRYPTO_CIPHER_ALG_CAST5_128: |
94318522 DB |
318 | case QCRYPTO_CIPHER_ALG_SERPENT_128: |
319 | case QCRYPTO_CIPHER_ALG_SERPENT_192: | |
320 | case QCRYPTO_CIPHER_ALG_SERPENT_256: | |
50f6753e DB |
321 | case QCRYPTO_CIPHER_ALG_TWOFISH_128: |
322 | case QCRYPTO_CIPHER_ALG_TWOFISH_192: | |
323 | case QCRYPTO_CIPHER_ALG_TWOFISH_256: | |
f844836d GA |
324 | break; |
325 | default: | |
326 | return false; | |
327 | } | |
328 | ||
329 | switch (mode) { | |
330 | case QCRYPTO_CIPHER_MODE_ECB: | |
331 | case QCRYPTO_CIPHER_MODE_CBC: | |
332 | case QCRYPTO_CIPHER_MODE_XTS: | |
333 | case QCRYPTO_CIPHER_MODE_CTR: | |
ed754746 DB |
334 | return true; |
335 | default: | |
336 | return false; | |
337 | } | |
338 | } | |
339 | ||
340 | ||
75c80078 LM |
341 | static void |
342 | qcrypto_nettle_cipher_free_ctx(QCryptoCipherNettle *ctx) | |
cc5eff01 LM |
343 | { |
344 | if (!ctx) { | |
345 | return; | |
346 | } | |
347 | ||
348 | g_free(ctx->iv); | |
349 | g_free(ctx->ctx); | |
350 | g_free(ctx->ctx_tweak); | |
351 | g_free(ctx); | |
352 | } | |
353 | ||
354 | ||
eabe6c58 LM |
355 | static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, |
356 | QCryptoCipherMode mode, | |
357 | const uint8_t *key, | |
358 | size_t nkey, | |
359 | Error **errp) | |
ed754746 | 360 | { |
ed754746 DB |
361 | QCryptoCipherNettle *ctx; |
362 | uint8_t *rfbkey; | |
363 | ||
364 | switch (mode) { | |
365 | case QCRYPTO_CIPHER_MODE_ECB: | |
366 | case QCRYPTO_CIPHER_MODE_CBC: | |
eaec903c | 367 | case QCRYPTO_CIPHER_MODE_XTS: |
3c28292f | 368 | case QCRYPTO_CIPHER_MODE_CTR: |
ed754746 DB |
369 | break; |
370 | default: | |
90d6f60d | 371 | error_setg(errp, "Unsupported cipher mode %s", |
977c736f | 372 | QCryptoCipherMode_str(mode)); |
ed754746 DB |
373 | return NULL; |
374 | } | |
375 | ||
eaec903c | 376 | if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { |
ed754746 DB |
377 | return NULL; |
378 | } | |
379 | ||
ed754746 DB |
380 | ctx = g_new0(QCryptoCipherNettle, 1); |
381 | ||
382 | switch (alg) { | |
383 | case QCRYPTO_CIPHER_ALG_DES_RFB: | |
e3ba0b67 | 384 | ctx->ctx = g_new0(struct des_ctx, 1); |
ed754746 | 385 | rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey); |
e3ba0b67 | 386 | des_set_key(ctx->ctx, rfbkey); |
ed754746 DB |
387 | g_free(rfbkey); |
388 | ||
f7ac78cf DB |
389 | ctx->alg_encrypt_native = des_encrypt_native; |
390 | ctx->alg_decrypt_native = des_decrypt_native; | |
391 | ctx->alg_encrypt_wrapper = des_encrypt_wrapper; | |
392 | ctx->alg_decrypt_wrapper = des_decrypt_wrapper; | |
ed754746 | 393 | |
3a661f1e | 394 | ctx->blocksize = DES_BLOCK_SIZE; |
ed754746 DB |
395 | break; |
396 | ||
ffb7bf45 LM |
397 | case QCRYPTO_CIPHER_ALG_3DES: |
398 | ctx->ctx = g_new0(struct des3_ctx, 1); | |
399 | des3_set_key(ctx->ctx, key); | |
400 | ||
401 | ctx->alg_encrypt_native = des3_encrypt_native; | |
402 | ctx->alg_decrypt_native = des3_decrypt_native; | |
403 | ctx->alg_encrypt_wrapper = des3_encrypt_wrapper; | |
404 | ctx->alg_decrypt_wrapper = des3_decrypt_wrapper; | |
405 | ||
406 | ctx->blocksize = DES3_BLOCK_SIZE; | |
407 | break; | |
408 | ||
ed754746 | 409 | case QCRYPTO_CIPHER_ALG_AES_128: |
e8e67ca4 DB |
410 | ctx->ctx = g_new0(QCryptoNettleAES128, 1); |
411 | ||
412 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { | |
413 | ctx->ctx_tweak = g_new0(QCryptoNettleAES128, 1); | |
414 | ||
415 | nkey /= 2; | |
416 | aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->enc, | |
417 | key); | |
418 | aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->dec, | |
419 | key); | |
420 | ||
421 | aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx_tweak)-> | |
422 | enc, key + nkey); | |
423 | aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx_tweak)-> | |
424 | dec, key + nkey); | |
425 | } else { | |
426 | aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->enc, | |
427 | key); | |
428 | aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->dec, | |
429 | key); | |
430 | } | |
431 | ||
432 | ctx->alg_encrypt_native = aes128_encrypt_native; | |
433 | ctx->alg_decrypt_native = aes128_decrypt_native; | |
434 | ctx->alg_encrypt_wrapper = aes128_encrypt_wrapper; | |
435 | ctx->alg_decrypt_wrapper = aes128_decrypt_wrapper; | |
436 | ||
437 | ctx->blocksize = AES_BLOCK_SIZE; | |
438 | break; | |
439 | ||
ed754746 | 440 | case QCRYPTO_CIPHER_ALG_AES_192: |
e8e67ca4 DB |
441 | ctx->ctx = g_new0(QCryptoNettleAES192, 1); |
442 | ||
443 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { | |
444 | ctx->ctx_tweak = g_new0(QCryptoNettleAES192, 1); | |
445 | ||
446 | nkey /= 2; | |
447 | aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->enc, | |
448 | key); | |
449 | aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->dec, | |
450 | key); | |
451 | ||
452 | aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx_tweak)-> | |
453 | enc, key + nkey); | |
454 | aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx_tweak)-> | |
455 | dec, key + nkey); | |
456 | } else { | |
457 | aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->enc, | |
458 | key); | |
459 | aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->dec, | |
460 | key); | |
461 | } | |
462 | ||
463 | ctx->alg_encrypt_native = aes192_encrypt_native; | |
464 | ctx->alg_decrypt_native = aes192_decrypt_native; | |
465 | ctx->alg_encrypt_wrapper = aes192_encrypt_wrapper; | |
466 | ctx->alg_decrypt_wrapper = aes192_decrypt_wrapper; | |
467 | ||
468 | ctx->blocksize = AES_BLOCK_SIZE; | |
469 | break; | |
470 | ||
ed754746 | 471 | case QCRYPTO_CIPHER_ALG_AES_256: |
e8e67ca4 | 472 | ctx->ctx = g_new0(QCryptoNettleAES256, 1); |
ed754746 | 473 | |
eaec903c | 474 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { |
e8e67ca4 | 475 | ctx->ctx_tweak = g_new0(QCryptoNettleAES256, 1); |
eaec903c DB |
476 | |
477 | nkey /= 2; | |
e8e67ca4 DB |
478 | aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->enc, |
479 | key); | |
480 | aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->dec, | |
481 | key); | |
482 | ||
483 | aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx_tweak)-> | |
484 | enc, key + nkey); | |
485 | aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx_tweak)-> | |
486 | dec, key + nkey); | |
eaec903c | 487 | } else { |
e8e67ca4 DB |
488 | aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->enc, |
489 | key); | |
490 | aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->dec, | |
491 | key); | |
eaec903c | 492 | } |
ed754746 | 493 | |
e8e67ca4 DB |
494 | ctx->alg_encrypt_native = aes256_encrypt_native; |
495 | ctx->alg_decrypt_native = aes256_decrypt_native; | |
496 | ctx->alg_encrypt_wrapper = aes256_encrypt_wrapper; | |
497 | ctx->alg_decrypt_wrapper = aes256_decrypt_wrapper; | |
ed754746 | 498 | |
3a661f1e | 499 | ctx->blocksize = AES_BLOCK_SIZE; |
ed754746 | 500 | break; |
084a85ee DB |
501 | |
502 | case QCRYPTO_CIPHER_ALG_CAST5_128: | |
e3ba0b67 | 503 | ctx->ctx = g_new0(struct cast128_ctx, 1); |
084a85ee | 504 | |
eaec903c DB |
505 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { |
506 | ctx->ctx_tweak = g_new0(struct cast128_ctx, 1); | |
507 | ||
508 | nkey /= 2; | |
509 | cast5_set_key(ctx->ctx, nkey, key); | |
510 | cast5_set_key(ctx->ctx_tweak, nkey, key + nkey); | |
511 | } else { | |
512 | cast5_set_key(ctx->ctx, nkey, key); | |
513 | } | |
084a85ee | 514 | |
f7ac78cf DB |
515 | ctx->alg_encrypt_native = cast128_encrypt_native; |
516 | ctx->alg_decrypt_native = cast128_decrypt_native; | |
517 | ctx->alg_encrypt_wrapper = cast128_encrypt_wrapper; | |
518 | ctx->alg_decrypt_wrapper = cast128_decrypt_wrapper; | |
084a85ee DB |
519 | |
520 | ctx->blocksize = CAST128_BLOCK_SIZE; | |
521 | break; | |
94318522 DB |
522 | |
523 | case QCRYPTO_CIPHER_ALG_SERPENT_128: | |
524 | case QCRYPTO_CIPHER_ALG_SERPENT_192: | |
525 | case QCRYPTO_CIPHER_ALG_SERPENT_256: | |
e3ba0b67 | 526 | ctx->ctx = g_new0(struct serpent_ctx, 1); |
94318522 | 527 | |
eaec903c DB |
528 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { |
529 | ctx->ctx_tweak = g_new0(struct serpent_ctx, 1); | |
530 | ||
531 | nkey /= 2; | |
532 | serpent_set_key(ctx->ctx, nkey, key); | |
533 | serpent_set_key(ctx->ctx_tweak, nkey, key + nkey); | |
534 | } else { | |
535 | serpent_set_key(ctx->ctx, nkey, key); | |
536 | } | |
94318522 | 537 | |
f7ac78cf DB |
538 | ctx->alg_encrypt_native = serpent_encrypt_native; |
539 | ctx->alg_decrypt_native = serpent_decrypt_native; | |
540 | ctx->alg_encrypt_wrapper = serpent_encrypt_wrapper; | |
541 | ctx->alg_decrypt_wrapper = serpent_decrypt_wrapper; | |
94318522 DB |
542 | |
543 | ctx->blocksize = SERPENT_BLOCK_SIZE; | |
544 | break; | |
545 | ||
50f6753e DB |
546 | case QCRYPTO_CIPHER_ALG_TWOFISH_128: |
547 | case QCRYPTO_CIPHER_ALG_TWOFISH_192: | |
548 | case QCRYPTO_CIPHER_ALG_TWOFISH_256: | |
e3ba0b67 | 549 | ctx->ctx = g_new0(struct twofish_ctx, 1); |
50f6753e | 550 | |
eaec903c DB |
551 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { |
552 | ctx->ctx_tweak = g_new0(struct twofish_ctx, 1); | |
553 | ||
554 | nkey /= 2; | |
555 | twofish_set_key(ctx->ctx, nkey, key); | |
556 | twofish_set_key(ctx->ctx_tweak, nkey, key + nkey); | |
557 | } else { | |
558 | twofish_set_key(ctx->ctx, nkey, key); | |
559 | } | |
50f6753e | 560 | |
f7ac78cf DB |
561 | ctx->alg_encrypt_native = twofish_encrypt_native; |
562 | ctx->alg_decrypt_native = twofish_decrypt_native; | |
563 | ctx->alg_encrypt_wrapper = twofish_encrypt_wrapper; | |
564 | ctx->alg_decrypt_wrapper = twofish_decrypt_wrapper; | |
50f6753e DB |
565 | |
566 | ctx->blocksize = TWOFISH_BLOCK_SIZE; | |
567 | break; | |
568 | ||
ed754746 | 569 | default: |
90d6f60d | 570 | error_setg(errp, "Unsupported cipher algorithm %s", |
977c736f | 571 | QCryptoCipherAlgorithm_str(alg)); |
ed754746 DB |
572 | goto error; |
573 | } | |
574 | ||
a5d2f44d DB |
575 | if (mode == QCRYPTO_CIPHER_MODE_XTS && |
576 | ctx->blocksize != XTS_BLOCK_SIZE) { | |
577 | error_setg(errp, "Cipher block size %zu must equal XTS block size %d", | |
578 | ctx->blocksize, XTS_BLOCK_SIZE); | |
579 | goto error; | |
580 | } | |
581 | ||
3a661f1e | 582 | ctx->iv = g_new0(uint8_t, ctx->blocksize); |
ed754746 | 583 | |
eabe6c58 | 584 | return ctx; |
ed754746 DB |
585 | |
586 | error: | |
75c80078 | 587 | qcrypto_nettle_cipher_free_ctx(ctx); |
ed754746 DB |
588 | return NULL; |
589 | } | |
590 | ||
591 | ||
75c80078 LM |
592 | static void |
593 | qcrypto_nettle_cipher_ctx_free(QCryptoCipher *cipher) | |
ed754746 DB |
594 | { |
595 | QCryptoCipherNettle *ctx; | |
596 | ||
ed754746 | 597 | ctx = cipher->opaque; |
75c80078 | 598 | qcrypto_nettle_cipher_free_ctx(ctx); |
ed754746 DB |
599 | } |
600 | ||
601 | ||
75c80078 LM |
602 | static int |
603 | qcrypto_nettle_cipher_encrypt(QCryptoCipher *cipher, | |
604 | const void *in, | |
605 | void *out, | |
606 | size_t len, | |
607 | Error **errp) | |
ed754746 DB |
608 | { |
609 | QCryptoCipherNettle *ctx = cipher->opaque; | |
610 | ||
3a661f1e DB |
611 | if (len % ctx->blocksize) { |
612 | error_setg(errp, "Length %zu must be a multiple of block size %zu", | |
613 | len, ctx->blocksize); | |
614 | return -1; | |
615 | } | |
616 | ||
ed754746 DB |
617 | switch (cipher->mode) { |
618 | case QCRYPTO_CIPHER_MODE_ECB: | |
f7ac78cf | 619 | ctx->alg_encrypt_wrapper(ctx->ctx, len, out, in); |
ed754746 DB |
620 | break; |
621 | ||
622 | case QCRYPTO_CIPHER_MODE_CBC: | |
f7ac78cf | 623 | cbc_encrypt(ctx->ctx, ctx->alg_encrypt_native, |
3a661f1e | 624 | ctx->blocksize, ctx->iv, |
ed754746 DB |
625 | len, out, in); |
626 | break; | |
e3ba0b67 | 627 | |
eaec903c DB |
628 | case QCRYPTO_CIPHER_MODE_XTS: |
629 | xts_encrypt(ctx->ctx, ctx->ctx_tweak, | |
f7ac78cf | 630 | ctx->alg_encrypt_wrapper, ctx->alg_encrypt_wrapper, |
eaec903c DB |
631 | ctx->iv, len, out, in); |
632 | break; | |
633 | ||
3c28292f GA |
634 | case QCRYPTO_CIPHER_MODE_CTR: |
635 | ctr_crypt(ctx->ctx, ctx->alg_encrypt_native, | |
636 | ctx->blocksize, ctx->iv, | |
637 | len, out, in); | |
638 | break; | |
639 | ||
ed754746 | 640 | default: |
90d6f60d | 641 | error_setg(errp, "Unsupported cipher mode %s", |
977c736f | 642 | QCryptoCipherMode_str(cipher->mode)); |
ed754746 DB |
643 | return -1; |
644 | } | |
645 | return 0; | |
646 | } | |
647 | ||
648 | ||
75c80078 LM |
649 | static int |
650 | qcrypto_nettle_cipher_decrypt(QCryptoCipher *cipher, | |
651 | const void *in, | |
652 | void *out, | |
653 | size_t len, | |
654 | Error **errp) | |
ed754746 DB |
655 | { |
656 | QCryptoCipherNettle *ctx = cipher->opaque; | |
657 | ||
3a661f1e DB |
658 | if (len % ctx->blocksize) { |
659 | error_setg(errp, "Length %zu must be a multiple of block size %zu", | |
660 | len, ctx->blocksize); | |
661 | return -1; | |
662 | } | |
663 | ||
ed754746 DB |
664 | switch (cipher->mode) { |
665 | case QCRYPTO_CIPHER_MODE_ECB: | |
f7ac78cf | 666 | ctx->alg_decrypt_wrapper(ctx->ctx, len, out, in); |
ed754746 DB |
667 | break; |
668 | ||
669 | case QCRYPTO_CIPHER_MODE_CBC: | |
f7ac78cf | 670 | cbc_decrypt(ctx->ctx, ctx->alg_decrypt_native, |
e3ba0b67 | 671 | ctx->blocksize, ctx->iv, |
ed754746 DB |
672 | len, out, in); |
673 | break; | |
e3ba0b67 | 674 | |
eaec903c | 675 | case QCRYPTO_CIPHER_MODE_XTS: |
eaec903c | 676 | xts_decrypt(ctx->ctx, ctx->ctx_tweak, |
f7ac78cf | 677 | ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper, |
eaec903c DB |
678 | ctx->iv, len, out, in); |
679 | break; | |
3c28292f GA |
680 | case QCRYPTO_CIPHER_MODE_CTR: |
681 | ctr_crypt(ctx->ctx, ctx->alg_encrypt_native, | |
682 | ctx->blocksize, ctx->iv, | |
683 | len, out, in); | |
684 | break; | |
eaec903c | 685 | |
ed754746 | 686 | default: |
90d6f60d | 687 | error_setg(errp, "Unsupported cipher mode %s", |
977c736f | 688 | QCryptoCipherMode_str(cipher->mode)); |
ed754746 DB |
689 | return -1; |
690 | } | |
691 | return 0; | |
692 | } | |
693 | ||
75c80078 LM |
694 | static int |
695 | qcrypto_nettle_cipher_setiv(QCryptoCipher *cipher, | |
696 | const uint8_t *iv, size_t niv, | |
697 | Error **errp) | |
ed754746 DB |
698 | { |
699 | QCryptoCipherNettle *ctx = cipher->opaque; | |
3a661f1e | 700 | if (niv != ctx->blocksize) { |
ed754746 | 701 | error_setg(errp, "Expected IV size %zu not %zu", |
3a661f1e | 702 | ctx->blocksize, niv); |
ed754746 DB |
703 | return -1; |
704 | } | |
705 | memcpy(ctx->iv, iv, niv); | |
706 | return 0; | |
707 | } | |
eabe6c58 LM |
708 | |
709 | ||
75c80078 LM |
710 | static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = { |
711 | .cipher_encrypt = qcrypto_nettle_cipher_encrypt, | |
712 | .cipher_decrypt = qcrypto_nettle_cipher_decrypt, | |
713 | .cipher_setiv = qcrypto_nettle_cipher_setiv, | |
714 | .cipher_free = qcrypto_nettle_cipher_ctx_free, | |
715 | }; |