]> git.proxmox.com Git - mirror_qemu.git/blame - crypto/cipher-nettle.c
crypto: add compat cast5_set_key with nettle < 3.0.0
[mirror_qemu.git] / crypto / cipher-nettle.c
CommitLineData
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
33typedef nettle_crypt_func nettle_cipher_func;
d3462e37
RK
34
35typedef void * cipher_ctx_t;
36typedef unsigned cipher_length_t;
621e6ae6
DB
37
38#define cast5_set_key cast128_set_key
d3462e37
RK
39#else
40typedef const void * cipher_ctx_t;
41typedef size_t cipher_length_t;
becaeb72
RK
42#endif
43
d3462e37
RK
44static nettle_cipher_func aes_encrypt_wrapper;
45static nettle_cipher_func aes_decrypt_wrapper;
46static nettle_cipher_func des_encrypt_wrapper;
47static nettle_cipher_func des_decrypt_wrapper;
48
e3ba0b67
DB
49typedef struct QCryptoNettleAES {
50 struct aes_ctx enc;
51 struct aes_ctx dec;
52} QCryptoNettleAES;
53
d3462e37
RK
54static 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
61static 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
68static 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
74static 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
80static 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
86static 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
92static 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
98static 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
104static 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
110static 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
116typedef struct QCryptoCipherNettle QCryptoCipherNettle;
117struct 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
130bool 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
151QCryptoCipher *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
302void 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
319int 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
359int 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
403int 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}