]>
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 | |
9 | * version 2 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 | ||
42f7a448 | 21 | #include "qemu/osdep.h" |
eaec903c DB |
22 | #include "crypto/xts.h" |
23 | ||
ed754746 DB |
24 | #include <nettle/nettle-types.h> |
25 | #include <nettle/aes.h> | |
26 | #include <nettle/des.h> | |
27 | #include <nettle/cbc.h> | |
084a85ee | 28 | #include <nettle/cast128.h> |
94318522 | 29 | #include <nettle/serpent.h> |
50f6753e | 30 | #include <nettle/twofish.h> |
ed754746 | 31 | |
becaeb72 RK |
32 | #if CONFIG_NETTLE_VERSION_MAJOR < 3 |
33 | typedef nettle_crypt_func nettle_cipher_func; | |
d3462e37 RK |
34 | |
35 | typedef void * cipher_ctx_t; | |
36 | typedef unsigned cipher_length_t; | |
621e6ae6 DB |
37 | |
38 | #define cast5_set_key cast128_set_key | |
d3462e37 RK |
39 | #else |
40 | typedef const void * cipher_ctx_t; | |
41 | typedef size_t cipher_length_t; | |
becaeb72 RK |
42 | #endif |
43 | ||
d3462e37 RK |
44 | static nettle_cipher_func aes_encrypt_wrapper; |
45 | static nettle_cipher_func aes_decrypt_wrapper; | |
46 | static nettle_cipher_func des_encrypt_wrapper; | |
47 | static nettle_cipher_func des_decrypt_wrapper; | |
48 | ||
e3ba0b67 DB |
49 | typedef struct QCryptoNettleAES { |
50 | struct aes_ctx enc; | |
51 | struct aes_ctx dec; | |
52 | } QCryptoNettleAES; | |
53 | ||
d3462e37 RK |
54 | static void aes_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, |
55 | uint8_t *dst, const uint8_t *src) | |
56 | { | |
e3ba0b67 DB |
57 | const QCryptoNettleAES *aesctx = ctx; |
58 | aes_encrypt(&aesctx->enc, length, dst, src); | |
d3462e37 RK |
59 | } |
60 | ||
61 | static void aes_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, | |
62 | uint8_t *dst, const uint8_t *src) | |
63 | { | |
e3ba0b67 DB |
64 | const QCryptoNettleAES *aesctx = ctx; |
65 | aes_decrypt(&aesctx->dec, length, dst, src); | |
d3462e37 RK |
66 | } |
67 | ||
68 | static void des_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, | |
69 | uint8_t *dst, const uint8_t *src) | |
70 | { | |
71 | des_encrypt(ctx, length, dst, src); | |
72 | } | |
73 | ||
74 | static void des_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, | |
75 | uint8_t *dst, const uint8_t *src) | |
76 | { | |
77 | des_decrypt(ctx, length, dst, src); | |
78 | } | |
79 | ||
084a85ee DB |
80 | static void cast128_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, |
81 | uint8_t *dst, const uint8_t *src) | |
82 | { | |
83 | cast128_encrypt(ctx, length, dst, src); | |
84 | } | |
85 | ||
86 | static void cast128_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, | |
87 | uint8_t *dst, const uint8_t *src) | |
88 | { | |
89 | cast128_decrypt(ctx, length, dst, src); | |
90 | } | |
91 | ||
94318522 DB |
92 | static void serpent_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, |
93 | uint8_t *dst, const uint8_t *src) | |
94 | { | |
95 | serpent_encrypt(ctx, length, dst, src); | |
96 | } | |
97 | ||
98 | static void serpent_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, | |
99 | uint8_t *dst, const uint8_t *src) | |
100 | { | |
101 | serpent_decrypt(ctx, length, dst, src); | |
102 | } | |
103 | ||
50f6753e DB |
104 | static void twofish_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, |
105 | uint8_t *dst, const uint8_t *src) | |
106 | { | |
107 | twofish_encrypt(ctx, length, dst, src); | |
108 | } | |
109 | ||
110 | static void twofish_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length, | |
111 | uint8_t *dst, const uint8_t *src) | |
112 | { | |
113 | twofish_decrypt(ctx, length, dst, src); | |
114 | } | |
115 | ||
ed754746 DB |
116 | typedef struct QCryptoCipherNettle QCryptoCipherNettle; |
117 | struct QCryptoCipherNettle { | |
eaec903c | 118 | /* Primary cipher context for all modes */ |
e3ba0b67 | 119 | void *ctx; |
eaec903c DB |
120 | /* Second cipher context for XTS mode only */ |
121 | void *ctx_tweak; | |
122 | /* Cipher callbacks for both contexts */ | |
becaeb72 RK |
123 | nettle_cipher_func *alg_encrypt; |
124 | nettle_cipher_func *alg_decrypt; | |
eaec903c | 125 | |
ed754746 | 126 | uint8_t *iv; |
3a661f1e | 127 | size_t blocksize; |
ed754746 DB |
128 | }; |
129 | ||
130 | bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg) | |
131 | { | |
132 | switch (alg) { | |
133 | case QCRYPTO_CIPHER_ALG_DES_RFB: | |
134 | case QCRYPTO_CIPHER_ALG_AES_128: | |
135 | case QCRYPTO_CIPHER_ALG_AES_192: | |
136 | case QCRYPTO_CIPHER_ALG_AES_256: | |
084a85ee | 137 | case QCRYPTO_CIPHER_ALG_CAST5_128: |
94318522 DB |
138 | case QCRYPTO_CIPHER_ALG_SERPENT_128: |
139 | case QCRYPTO_CIPHER_ALG_SERPENT_192: | |
140 | case QCRYPTO_CIPHER_ALG_SERPENT_256: | |
50f6753e DB |
141 | case QCRYPTO_CIPHER_ALG_TWOFISH_128: |
142 | case QCRYPTO_CIPHER_ALG_TWOFISH_192: | |
143 | case QCRYPTO_CIPHER_ALG_TWOFISH_256: | |
ed754746 DB |
144 | return true; |
145 | default: | |
146 | return false; | |
147 | } | |
148 | } | |
149 | ||
150 | ||
151 | QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, | |
152 | QCryptoCipherMode mode, | |
153 | const uint8_t *key, size_t nkey, | |
154 | Error **errp) | |
155 | { | |
156 | QCryptoCipher *cipher; | |
157 | QCryptoCipherNettle *ctx; | |
158 | uint8_t *rfbkey; | |
159 | ||
160 | switch (mode) { | |
161 | case QCRYPTO_CIPHER_MODE_ECB: | |
162 | case QCRYPTO_CIPHER_MODE_CBC: | |
eaec903c | 163 | case QCRYPTO_CIPHER_MODE_XTS: |
ed754746 DB |
164 | break; |
165 | default: | |
166 | error_setg(errp, "Unsupported cipher mode %d", mode); | |
167 | return NULL; | |
168 | } | |
169 | ||
eaec903c | 170 | if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { |
ed754746 DB |
171 | return NULL; |
172 | } | |
173 | ||
174 | cipher = g_new0(QCryptoCipher, 1); | |
175 | cipher->alg = alg; | |
176 | cipher->mode = mode; | |
177 | ||
178 | ctx = g_new0(QCryptoCipherNettle, 1); | |
179 | ||
180 | switch (alg) { | |
181 | case QCRYPTO_CIPHER_ALG_DES_RFB: | |
e3ba0b67 | 182 | ctx->ctx = g_new0(struct des_ctx, 1); |
ed754746 | 183 | rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey); |
e3ba0b67 | 184 | des_set_key(ctx->ctx, rfbkey); |
ed754746 DB |
185 | g_free(rfbkey); |
186 | ||
d3462e37 RK |
187 | ctx->alg_encrypt = des_encrypt_wrapper; |
188 | ctx->alg_decrypt = des_decrypt_wrapper; | |
ed754746 | 189 | |
3a661f1e | 190 | ctx->blocksize = DES_BLOCK_SIZE; |
ed754746 DB |
191 | break; |
192 | ||
193 | case QCRYPTO_CIPHER_ALG_AES_128: | |
194 | case QCRYPTO_CIPHER_ALG_AES_192: | |
195 | case QCRYPTO_CIPHER_ALG_AES_256: | |
e3ba0b67 | 196 | ctx->ctx = g_new0(QCryptoNettleAES, 1); |
ed754746 | 197 | |
eaec903c DB |
198 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { |
199 | ctx->ctx_tweak = g_new0(QCryptoNettleAES, 1); | |
200 | ||
201 | nkey /= 2; | |
202 | aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx)->enc, | |
203 | nkey, key); | |
204 | aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx)->dec, | |
205 | nkey, key); | |
206 | ||
207 | aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx_tweak)->enc, | |
208 | nkey, key + nkey); | |
209 | aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx_tweak)->dec, | |
210 | nkey, key + nkey); | |
211 | } else { | |
212 | aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx)->enc, | |
213 | nkey, key); | |
214 | aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx)->dec, | |
215 | nkey, key); | |
216 | } | |
ed754746 | 217 | |
d3462e37 RK |
218 | ctx->alg_encrypt = aes_encrypt_wrapper; |
219 | ctx->alg_decrypt = aes_decrypt_wrapper; | |
ed754746 | 220 | |
3a661f1e | 221 | ctx->blocksize = AES_BLOCK_SIZE; |
ed754746 | 222 | break; |
084a85ee DB |
223 | |
224 | case QCRYPTO_CIPHER_ALG_CAST5_128: | |
e3ba0b67 | 225 | ctx->ctx = g_new0(struct cast128_ctx, 1); |
084a85ee | 226 | |
eaec903c DB |
227 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { |
228 | ctx->ctx_tweak = g_new0(struct cast128_ctx, 1); | |
229 | ||
230 | nkey /= 2; | |
231 | cast5_set_key(ctx->ctx, nkey, key); | |
232 | cast5_set_key(ctx->ctx_tweak, nkey, key + nkey); | |
233 | } else { | |
234 | cast5_set_key(ctx->ctx, nkey, key); | |
235 | } | |
084a85ee DB |
236 | |
237 | ctx->alg_encrypt = cast128_encrypt_wrapper; | |
238 | ctx->alg_decrypt = cast128_decrypt_wrapper; | |
239 | ||
240 | ctx->blocksize = CAST128_BLOCK_SIZE; | |
241 | break; | |
94318522 DB |
242 | |
243 | case QCRYPTO_CIPHER_ALG_SERPENT_128: | |
244 | case QCRYPTO_CIPHER_ALG_SERPENT_192: | |
245 | case QCRYPTO_CIPHER_ALG_SERPENT_256: | |
e3ba0b67 | 246 | ctx->ctx = g_new0(struct serpent_ctx, 1); |
94318522 | 247 | |
eaec903c DB |
248 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { |
249 | ctx->ctx_tweak = g_new0(struct serpent_ctx, 1); | |
250 | ||
251 | nkey /= 2; | |
252 | serpent_set_key(ctx->ctx, nkey, key); | |
253 | serpent_set_key(ctx->ctx_tweak, nkey, key + nkey); | |
254 | } else { | |
255 | serpent_set_key(ctx->ctx, nkey, key); | |
256 | } | |
94318522 DB |
257 | |
258 | ctx->alg_encrypt = serpent_encrypt_wrapper; | |
259 | ctx->alg_decrypt = serpent_decrypt_wrapper; | |
260 | ||
261 | ctx->blocksize = SERPENT_BLOCK_SIZE; | |
262 | break; | |
263 | ||
50f6753e DB |
264 | case QCRYPTO_CIPHER_ALG_TWOFISH_128: |
265 | case QCRYPTO_CIPHER_ALG_TWOFISH_192: | |
266 | case QCRYPTO_CIPHER_ALG_TWOFISH_256: | |
e3ba0b67 | 267 | ctx->ctx = g_new0(struct twofish_ctx, 1); |
50f6753e | 268 | |
eaec903c DB |
269 | if (mode == QCRYPTO_CIPHER_MODE_XTS) { |
270 | ctx->ctx_tweak = g_new0(struct twofish_ctx, 1); | |
271 | ||
272 | nkey /= 2; | |
273 | twofish_set_key(ctx->ctx, nkey, key); | |
274 | twofish_set_key(ctx->ctx_tweak, nkey, key + nkey); | |
275 | } else { | |
276 | twofish_set_key(ctx->ctx, nkey, key); | |
277 | } | |
50f6753e DB |
278 | |
279 | ctx->alg_encrypt = twofish_encrypt_wrapper; | |
280 | ctx->alg_decrypt = twofish_decrypt_wrapper; | |
281 | ||
282 | ctx->blocksize = TWOFISH_BLOCK_SIZE; | |
283 | break; | |
284 | ||
ed754746 DB |
285 | default: |
286 | error_setg(errp, "Unsupported cipher algorithm %d", alg); | |
287 | goto error; | |
288 | } | |
289 | ||
3a661f1e | 290 | ctx->iv = g_new0(uint8_t, ctx->blocksize); |
ed754746 DB |
291 | cipher->opaque = ctx; |
292 | ||
293 | return cipher; | |
294 | ||
295 | error: | |
296 | g_free(cipher); | |
297 | g_free(ctx); | |
298 | return NULL; | |
299 | } | |
300 | ||
301 | ||
302 | void qcrypto_cipher_free(QCryptoCipher *cipher) | |
303 | { | |
304 | QCryptoCipherNettle *ctx; | |
305 | ||
306 | if (!cipher) { | |
307 | return; | |
308 | } | |
309 | ||
310 | ctx = cipher->opaque; | |
311 | g_free(ctx->iv); | |
e3ba0b67 | 312 | g_free(ctx->ctx); |
eaec903c | 313 | g_free(ctx->ctx_tweak); |
ed754746 DB |
314 | g_free(ctx); |
315 | g_free(cipher); | |
316 | } | |
317 | ||
318 | ||
319 | int qcrypto_cipher_encrypt(QCryptoCipher *cipher, | |
320 | const void *in, | |
321 | void *out, | |
322 | size_t len, | |
323 | Error **errp) | |
324 | { | |
325 | QCryptoCipherNettle *ctx = cipher->opaque; | |
326 | ||
3a661f1e DB |
327 | if (len % ctx->blocksize) { |
328 | error_setg(errp, "Length %zu must be a multiple of block size %zu", | |
329 | len, ctx->blocksize); | |
330 | return -1; | |
331 | } | |
332 | ||
ed754746 DB |
333 | switch (cipher->mode) { |
334 | case QCRYPTO_CIPHER_MODE_ECB: | |
e3ba0b67 | 335 | ctx->alg_encrypt(ctx->ctx, len, out, in); |
ed754746 DB |
336 | break; |
337 | ||
338 | case QCRYPTO_CIPHER_MODE_CBC: | |
e3ba0b67 | 339 | cbc_encrypt(ctx->ctx, ctx->alg_encrypt, |
3a661f1e | 340 | ctx->blocksize, ctx->iv, |
ed754746 DB |
341 | len, out, in); |
342 | break; | |
e3ba0b67 | 343 | |
eaec903c DB |
344 | case QCRYPTO_CIPHER_MODE_XTS: |
345 | xts_encrypt(ctx->ctx, ctx->ctx_tweak, | |
346 | ctx->alg_encrypt, ctx->alg_encrypt, | |
347 | ctx->iv, len, out, in); | |
348 | break; | |
349 | ||
ed754746 DB |
350 | default: |
351 | error_setg(errp, "Unsupported cipher algorithm %d", | |
352 | cipher->alg); | |
353 | return -1; | |
354 | } | |
355 | return 0; | |
356 | } | |
357 | ||
358 | ||
359 | int qcrypto_cipher_decrypt(QCryptoCipher *cipher, | |
360 | const void *in, | |
361 | void *out, | |
362 | size_t len, | |
363 | Error **errp) | |
364 | { | |
365 | QCryptoCipherNettle *ctx = cipher->opaque; | |
366 | ||
3a661f1e DB |
367 | if (len % ctx->blocksize) { |
368 | error_setg(errp, "Length %zu must be a multiple of block size %zu", | |
369 | len, ctx->blocksize); | |
370 | return -1; | |
371 | } | |
372 | ||
ed754746 DB |
373 | switch (cipher->mode) { |
374 | case QCRYPTO_CIPHER_MODE_ECB: | |
e3ba0b67 | 375 | ctx->alg_decrypt(ctx->ctx, len, out, in); |
ed754746 DB |
376 | break; |
377 | ||
378 | case QCRYPTO_CIPHER_MODE_CBC: | |
e3ba0b67 DB |
379 | cbc_decrypt(ctx->ctx, ctx->alg_decrypt, |
380 | ctx->blocksize, ctx->iv, | |
ed754746 DB |
381 | len, out, in); |
382 | break; | |
e3ba0b67 | 383 | |
eaec903c DB |
384 | case QCRYPTO_CIPHER_MODE_XTS: |
385 | if (ctx->blocksize != XTS_BLOCK_SIZE) { | |
386 | error_setg(errp, "Block size must be %d not %zu", | |
387 | XTS_BLOCK_SIZE, ctx->blocksize); | |
388 | return -1; | |
389 | } | |
390 | xts_decrypt(ctx->ctx, ctx->ctx_tweak, | |
391 | ctx->alg_encrypt, ctx->alg_decrypt, | |
392 | ctx->iv, len, out, in); | |
393 | break; | |
394 | ||
ed754746 DB |
395 | default: |
396 | error_setg(errp, "Unsupported cipher algorithm %d", | |
397 | cipher->alg); | |
398 | return -1; | |
399 | } | |
400 | return 0; | |
401 | } | |
402 | ||
403 | int qcrypto_cipher_setiv(QCryptoCipher *cipher, | |
404 | const uint8_t *iv, size_t niv, | |
405 | Error **errp) | |
406 | { | |
407 | QCryptoCipherNettle *ctx = cipher->opaque; | |
3a661f1e | 408 | if (niv != ctx->blocksize) { |
ed754746 | 409 | error_setg(errp, "Expected IV size %zu not %zu", |
3a661f1e | 410 | ctx->blocksize, niv); |
ed754746 DB |
411 | return -1; |
412 | } | |
413 | memcpy(ctx->iv, iv, niv); | |
414 | return 0; | |
415 | } |