2 * QEMU Crypto cipher built-in algorithms
4 * Copyright (c) 2015 Red Hat, Inc.
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.
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.
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/>.
21 #include "qemu/osdep.h"
22 #include "crypto/aes.h"
23 #include "crypto/desrfb.h"
24 #include "crypto/xts.h"
25 #include "cipherpriv.h"
27 typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext
;
28 struct QCryptoCipherBuiltinAESContext
{
32 typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES
;
33 struct QCryptoCipherBuiltinAES
{
34 QCryptoCipherBuiltinAESContext key
;
35 QCryptoCipherBuiltinAESContext key_tweak
;
36 uint8_t iv
[AES_BLOCK_SIZE
];
38 typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB
;
39 struct QCryptoCipherBuiltinDESRFB
{
44 typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin
;
45 struct QCryptoCipherBuiltin
{
47 QCryptoCipherBuiltinAES aes
;
48 QCryptoCipherBuiltinDESRFB desrfb
;
51 void (*free
)(QCryptoCipher
*cipher
);
52 int (*setiv
)(QCryptoCipher
*cipher
,
53 const uint8_t *iv
, size_t niv
,
55 int (*encrypt
)(QCryptoCipher
*cipher
,
60 int (*decrypt
)(QCryptoCipher
*cipher
,
68 static void qcrypto_cipher_free_aes(QCryptoCipher
*cipher
)
70 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
73 cipher
->opaque
= NULL
;
77 static void qcrypto_cipher_aes_ecb_encrypt(AES_KEY
*key
,
82 const uint8_t *inptr
= in
;
83 uint8_t *outptr
= out
;
85 if (len
> AES_BLOCK_SIZE
) {
86 AES_encrypt(inptr
, outptr
, key
);
87 inptr
+= AES_BLOCK_SIZE
;
88 outptr
+= AES_BLOCK_SIZE
;
89 len
-= AES_BLOCK_SIZE
;
91 uint8_t tmp1
[AES_BLOCK_SIZE
], tmp2
[AES_BLOCK_SIZE
];
92 memcpy(tmp1
, inptr
, len
);
93 /* Fill with 0 to avoid valgrind uninitialized reads */
94 memset(tmp1
+ len
, 0, sizeof(tmp1
) - len
);
95 AES_encrypt(tmp1
, tmp2
, key
);
96 memcpy(outptr
, tmp2
, len
);
103 static void qcrypto_cipher_aes_ecb_decrypt(AES_KEY
*key
,
108 const uint8_t *inptr
= in
;
109 uint8_t *outptr
= out
;
111 if (len
> AES_BLOCK_SIZE
) {
112 AES_decrypt(inptr
, outptr
, key
);
113 inptr
+= AES_BLOCK_SIZE
;
114 outptr
+= AES_BLOCK_SIZE
;
115 len
-= AES_BLOCK_SIZE
;
117 uint8_t tmp1
[AES_BLOCK_SIZE
], tmp2
[AES_BLOCK_SIZE
];
118 memcpy(tmp1
, inptr
, len
);
119 /* Fill with 0 to avoid valgrind uninitialized reads */
120 memset(tmp1
+ len
, 0, sizeof(tmp1
) - len
);
121 AES_decrypt(tmp1
, tmp2
, key
);
122 memcpy(outptr
, tmp2
, len
);
129 static void qcrypto_cipher_aes_xts_encrypt(const void *ctx
,
134 const QCryptoCipherBuiltinAESContext
*aesctx
= ctx
;
136 qcrypto_cipher_aes_ecb_encrypt((AES_KEY
*)&aesctx
->enc
,
141 static void qcrypto_cipher_aes_xts_decrypt(const void *ctx
,
146 const QCryptoCipherBuiltinAESContext
*aesctx
= ctx
;
148 qcrypto_cipher_aes_ecb_decrypt((AES_KEY
*)&aesctx
->dec
,
153 static int qcrypto_cipher_encrypt_aes(QCryptoCipher
*cipher
,
159 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
161 switch (cipher
->mode
) {
162 case QCRYPTO_CIPHER_MODE_ECB
:
163 qcrypto_cipher_aes_ecb_encrypt(&ctxt
->state
.aes
.key
.enc
,
166 case QCRYPTO_CIPHER_MODE_CBC
:
167 AES_cbc_encrypt(in
, out
, len
,
168 &ctxt
->state
.aes
.key
.enc
,
169 ctxt
->state
.aes
.iv
, 1);
171 case QCRYPTO_CIPHER_MODE_XTS
:
172 xts_encrypt(&ctxt
->state
.aes
.key
,
173 &ctxt
->state
.aes
.key_tweak
,
174 qcrypto_cipher_aes_xts_encrypt
,
175 qcrypto_cipher_aes_xts_decrypt
,
180 g_assert_not_reached();
187 static int qcrypto_cipher_decrypt_aes(QCryptoCipher
*cipher
,
193 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
195 switch (cipher
->mode
) {
196 case QCRYPTO_CIPHER_MODE_ECB
:
197 qcrypto_cipher_aes_ecb_decrypt(&ctxt
->state
.aes
.key
.dec
,
200 case QCRYPTO_CIPHER_MODE_CBC
:
201 AES_cbc_encrypt(in
, out
, len
,
202 &ctxt
->state
.aes
.key
.dec
,
203 ctxt
->state
.aes
.iv
, 0);
205 case QCRYPTO_CIPHER_MODE_XTS
:
206 xts_decrypt(&ctxt
->state
.aes
.key
,
207 &ctxt
->state
.aes
.key_tweak
,
208 qcrypto_cipher_aes_xts_encrypt
,
209 qcrypto_cipher_aes_xts_decrypt
,
214 g_assert_not_reached();
220 static int qcrypto_cipher_setiv_aes(QCryptoCipher
*cipher
,
221 const uint8_t *iv
, size_t niv
,
224 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
225 if (niv
!= AES_BLOCK_SIZE
) {
226 error_setg(errp
, "IV must be %d bytes not %zu",
227 AES_BLOCK_SIZE
, niv
);
231 memcpy(ctxt
->state
.aes
.iv
, iv
, AES_BLOCK_SIZE
);
239 static QCryptoCipherBuiltin
*
240 qcrypto_cipher_init_aes(QCryptoCipherMode mode
,
241 const uint8_t *key
, size_t nkey
,
244 QCryptoCipherBuiltin
*ctxt
;
246 if (mode
!= QCRYPTO_CIPHER_MODE_CBC
&&
247 mode
!= QCRYPTO_CIPHER_MODE_ECB
&&
248 mode
!= QCRYPTO_CIPHER_MODE_XTS
) {
249 error_setg(errp
, "Unsupported cipher mode %s",
250 QCryptoCipherMode_lookup
[mode
]);
254 ctxt
= g_new0(QCryptoCipherBuiltin
, 1);
256 if (mode
== QCRYPTO_CIPHER_MODE_XTS
) {
257 if (AES_set_encrypt_key(key
, nkey
* 4, &ctxt
->state
.aes
.key
.enc
) != 0) {
258 error_setg(errp
, "Failed to set encryption key");
262 if (AES_set_decrypt_key(key
, nkey
* 4, &ctxt
->state
.aes
.key
.dec
) != 0) {
263 error_setg(errp
, "Failed to set decryption key");
267 if (AES_set_encrypt_key(key
+ (nkey
/ 2), nkey
* 4,
268 &ctxt
->state
.aes
.key_tweak
.enc
) != 0) {
269 error_setg(errp
, "Failed to set encryption key");
273 if (AES_set_decrypt_key(key
+ (nkey
/ 2), nkey
* 4,
274 &ctxt
->state
.aes
.key_tweak
.dec
) != 0) {
275 error_setg(errp
, "Failed to set decryption key");
279 if (AES_set_encrypt_key(key
, nkey
* 8, &ctxt
->state
.aes
.key
.enc
) != 0) {
280 error_setg(errp
, "Failed to set encryption key");
284 if (AES_set_decrypt_key(key
, nkey
* 8, &ctxt
->state
.aes
.key
.dec
) != 0) {
285 error_setg(errp
, "Failed to set decryption key");
290 ctxt
->blocksize
= AES_BLOCK_SIZE
;
291 ctxt
->free
= qcrypto_cipher_free_aes
;
292 ctxt
->setiv
= qcrypto_cipher_setiv_aes
;
293 ctxt
->encrypt
= qcrypto_cipher_encrypt_aes
;
294 ctxt
->decrypt
= qcrypto_cipher_decrypt_aes
;
304 static void qcrypto_cipher_free_des_rfb(QCryptoCipher
*cipher
)
306 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
308 g_free(ctxt
->state
.desrfb
.key
);
310 cipher
->opaque
= NULL
;
314 static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher
*cipher
,
320 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
324 error_setg(errp
, "Buffer size must be multiple of 8 not %zu",
329 deskey(ctxt
->state
.desrfb
.key
, EN0
);
331 for (i
= 0; i
< len
; i
+= 8) {
332 des((void *)in
+ i
, out
+ i
);
339 static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher
*cipher
,
345 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
349 error_setg(errp
, "Buffer size must be multiple of 8 not %zu",
354 deskey(ctxt
->state
.desrfb
.key
, DE1
);
356 for (i
= 0; i
< len
; i
+= 8) {
357 des((void *)in
+ i
, out
+ i
);
364 static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher
*cipher
,
365 const uint8_t *iv
, size_t niv
,
368 error_setg(errp
, "Setting IV is not supported");
373 static QCryptoCipherBuiltin
*
374 qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode
,
375 const uint8_t *key
, size_t nkey
,
378 QCryptoCipherBuiltin
*ctxt
;
380 if (mode
!= QCRYPTO_CIPHER_MODE_ECB
) {
381 error_setg(errp
, "Unsupported cipher mode %s",
382 QCryptoCipherMode_lookup
[mode
]);
386 ctxt
= g_new0(QCryptoCipherBuiltin
, 1);
388 ctxt
->state
.desrfb
.key
= g_new0(uint8_t, nkey
);
389 memcpy(ctxt
->state
.desrfb
.key
, key
, nkey
);
390 ctxt
->state
.desrfb
.nkey
= nkey
;
393 ctxt
->free
= qcrypto_cipher_free_des_rfb
;
394 ctxt
->setiv
= qcrypto_cipher_setiv_des_rfb
;
395 ctxt
->encrypt
= qcrypto_cipher_encrypt_des_rfb
;
396 ctxt
->decrypt
= qcrypto_cipher_decrypt_des_rfb
;
402 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg
,
403 QCryptoCipherMode mode
)
406 case QCRYPTO_CIPHER_ALG_DES_RFB
:
407 case QCRYPTO_CIPHER_ALG_AES_128
:
408 case QCRYPTO_CIPHER_ALG_AES_192
:
409 case QCRYPTO_CIPHER_ALG_AES_256
:
416 case QCRYPTO_CIPHER_MODE_ECB
:
417 case QCRYPTO_CIPHER_MODE_CBC
:
418 case QCRYPTO_CIPHER_MODE_XTS
:
420 case QCRYPTO_CIPHER_MODE_CTR
:
428 static QCryptoCipherBuiltin
*qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg
,
429 QCryptoCipherMode mode
,
434 QCryptoCipherBuiltin
*ctxt
;
437 case QCRYPTO_CIPHER_MODE_ECB
:
438 case QCRYPTO_CIPHER_MODE_CBC
:
439 case QCRYPTO_CIPHER_MODE_XTS
:
442 error_setg(errp
, "Unsupported cipher mode %s",
443 QCryptoCipherMode_lookup
[mode
]);
447 if (!qcrypto_cipher_validate_key_length(alg
, mode
, nkey
, errp
)) {
452 case QCRYPTO_CIPHER_ALG_DES_RFB
:
453 ctxt
= qcrypto_cipher_init_des_rfb(mode
, key
, nkey
, errp
);
455 case QCRYPTO_CIPHER_ALG_AES_128
:
456 case QCRYPTO_CIPHER_ALG_AES_192
:
457 case QCRYPTO_CIPHER_ALG_AES_256
:
458 ctxt
= qcrypto_cipher_init_aes(mode
, key
, nkey
, errp
);
462 "Unsupported cipher algorithm %s",
463 QCryptoCipherAlgorithm_lookup
[alg
]);
471 qcrypto_builtin_cipher_ctx_free(QCryptoCipher
*cipher
)
473 QCryptoCipherBuiltin
*ctxt
;
475 ctxt
= cipher
->opaque
;
481 qcrypto_builtin_cipher_encrypt(QCryptoCipher
*cipher
,
487 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
489 if (len
% ctxt
->blocksize
) {
490 error_setg(errp
, "Length %zu must be a multiple of block size %zu",
491 len
, ctxt
->blocksize
);
495 return ctxt
->encrypt(cipher
, in
, out
, len
, errp
);
500 qcrypto_builtin_cipher_decrypt(QCryptoCipher
*cipher
,
506 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
508 if (len
% ctxt
->blocksize
) {
509 error_setg(errp
, "Length %zu must be a multiple of block size %zu",
510 len
, ctxt
->blocksize
);
514 return ctxt
->decrypt(cipher
, in
, out
, len
, errp
);
519 qcrypto_builtin_cipher_setiv(QCryptoCipher
*cipher
,
520 const uint8_t *iv
, size_t niv
,
523 QCryptoCipherBuiltin
*ctxt
= cipher
->opaque
;
525 return ctxt
->setiv(cipher
, iv
, niv
, errp
);
529 static struct QCryptoCipherDriver qcrypto_cipher_lib_driver
= {
530 .cipher_encrypt
= qcrypto_builtin_cipher_encrypt
,
531 .cipher_decrypt
= qcrypto_builtin_cipher_decrypt
,
532 .cipher_setiv
= qcrypto_builtin_cipher_setiv
,
533 .cipher_free
= qcrypto_builtin_cipher_ctx_free
,