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 "crypto/aes.h"
22 #include "crypto/desrfb.h"
24 typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
25 struct QCryptoCipherBuiltinAES {
31 typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
32 struct QCryptoCipherBuiltinDESRFB {
37 typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
38 struct QCryptoCipherBuiltin {
40 QCryptoCipherBuiltinAES aes;
41 QCryptoCipherBuiltinDESRFB desrfb;
43 void (*free)(QCryptoCipher *cipher);
44 int (*setiv)(QCryptoCipher *cipher,
45 const uint8_t *iv, size_t niv,
47 int (*encrypt)(QCryptoCipher *cipher,
52 int (*decrypt)(QCryptoCipher *cipher,
60 static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
62 QCryptoCipherBuiltin *ctxt = cipher->opaque;
64 g_free(ctxt->state.aes.iv);
66 cipher->opaque = NULL;
70 static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
76 QCryptoCipherBuiltin *ctxt = cipher->opaque;
78 if (cipher->mode == QCRYPTO_CIPHER_MODE_ECB) {
79 const uint8_t *inptr = in;
80 uint8_t *outptr = out;
82 if (len > AES_BLOCK_SIZE) {
83 AES_encrypt(inptr, outptr, &ctxt->state.aes.encrypt_key);
84 inptr += AES_BLOCK_SIZE;
85 outptr += AES_BLOCK_SIZE;
86 len -= AES_BLOCK_SIZE;
88 uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
89 memcpy(tmp1, inptr, len);
90 /* Fill with 0 to avoid valgrind uninitialized reads */
91 memset(tmp1 + len, 0, sizeof(tmp1) - len);
92 AES_encrypt(tmp1, tmp2, &ctxt->state.aes.encrypt_key);
93 memcpy(outptr, tmp2, len);
98 AES_cbc_encrypt(in, out, len,
99 &ctxt->state.aes.encrypt_key,
100 ctxt->state.aes.iv, 1);
107 static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
113 QCryptoCipherBuiltin *ctxt = cipher->opaque;
115 if (cipher->mode == QCRYPTO_CIPHER_MODE_ECB) {
116 const uint8_t *inptr = in;
117 uint8_t *outptr = out;
119 if (len > AES_BLOCK_SIZE) {
120 AES_decrypt(inptr, outptr, &ctxt->state.aes.decrypt_key);
121 inptr += AES_BLOCK_SIZE;
122 outptr += AES_BLOCK_SIZE;
123 len -= AES_BLOCK_SIZE;
125 uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
126 memcpy(tmp1, inptr, len);
127 /* Fill with 0 to avoid valgrind uninitialized reads */
128 memset(tmp1 + len, 0, sizeof(tmp1) - len);
129 AES_decrypt(tmp1, tmp2, &ctxt->state.aes.decrypt_key);
130 memcpy(outptr, tmp2, len);
135 AES_cbc_encrypt(in, out, len,
136 &ctxt->state.aes.decrypt_key,
137 ctxt->state.aes.iv, 0);
143 static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
144 const uint8_t *iv, size_t niv,
147 QCryptoCipherBuiltin *ctxt = cipher->opaque;
149 error_setg(errp, "IV must be 16 bytes not %zu", niv);
153 g_free(ctxt->state.aes.iv);
154 ctxt->state.aes.iv = g_new0(uint8_t, niv);
155 memcpy(ctxt->state.aes.iv, iv, niv);
156 ctxt->state.aes.niv = niv;
164 static int qcrypto_cipher_init_aes(QCryptoCipher *cipher,
165 const uint8_t *key, size_t nkey,
168 QCryptoCipherBuiltin *ctxt;
170 if (cipher->mode != QCRYPTO_CIPHER_MODE_CBC &&
171 cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {
172 error_setg(errp, "Unsupported cipher mode %d", cipher->mode);
176 ctxt = g_new0(QCryptoCipherBuiltin, 1);
178 if (AES_set_encrypt_key(key, nkey * 8, &ctxt->state.aes.encrypt_key) != 0) {
179 error_setg(errp, "Failed to set encryption key");
183 if (AES_set_decrypt_key(key, nkey * 8, &ctxt->state.aes.decrypt_key) != 0) {
184 error_setg(errp, "Failed to set decryption key");
188 ctxt->free = qcrypto_cipher_free_aes;
189 ctxt->setiv = qcrypto_cipher_setiv_aes;
190 ctxt->encrypt = qcrypto_cipher_encrypt_aes;
191 ctxt->decrypt = qcrypto_cipher_decrypt_aes;
193 cipher->opaque = ctxt;
203 static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher)
205 QCryptoCipherBuiltin *ctxt = cipher->opaque;
207 g_free(ctxt->state.desrfb.key);
209 cipher->opaque = NULL;
213 static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
219 QCryptoCipherBuiltin *ctxt = cipher->opaque;
223 error_setg(errp, "Buffer size must be multiple of 8 not %zu",
228 deskey(ctxt->state.desrfb.key, EN0);
230 for (i = 0; i < len; i += 8) {
231 des((void *)in + i, out + i);
238 static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
244 QCryptoCipherBuiltin *ctxt = cipher->opaque;
248 error_setg(errp, "Buffer size must be multiple of 8 not %zu",
253 deskey(ctxt->state.desrfb.key, DE1);
255 for (i = 0; i < len; i += 8) {
256 des((void *)in + i, out + i);
263 static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher,
264 const uint8_t *iv, size_t niv,
267 error_setg(errp, "Setting IV is not supported");
272 static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,
273 const uint8_t *key, size_t nkey,
276 QCryptoCipherBuiltin *ctxt;
278 if (cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {
279 error_setg(errp, "Unsupported cipher mode %d", cipher->mode);
283 ctxt = g_new0(QCryptoCipherBuiltin, 1);
285 ctxt->state.desrfb.key = g_new0(uint8_t, nkey);
286 memcpy(ctxt->state.desrfb.key, key, nkey);
287 ctxt->state.desrfb.nkey = nkey;
289 ctxt->free = qcrypto_cipher_free_des_rfb;
290 ctxt->setiv = qcrypto_cipher_setiv_des_rfb;
291 ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
292 ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;
294 cipher->opaque = ctxt;
300 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
303 case QCRYPTO_CIPHER_ALG_DES_RFB:
304 case QCRYPTO_CIPHER_ALG_AES_128:
305 case QCRYPTO_CIPHER_ALG_AES_192:
306 case QCRYPTO_CIPHER_ALG_AES_256:
314 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
315 QCryptoCipherMode mode,
316 const uint8_t *key, size_t nkey,
319 QCryptoCipher *cipher;
321 cipher = g_new0(QCryptoCipher, 1);
325 if (!qcrypto_cipher_validate_key_length(alg, nkey, errp)) {
329 switch (cipher->alg) {
330 case QCRYPTO_CIPHER_ALG_DES_RFB:
331 if (qcrypto_cipher_init_des_rfb(cipher, key, nkey, errp) < 0) {
335 case QCRYPTO_CIPHER_ALG_AES_128:
336 case QCRYPTO_CIPHER_ALG_AES_192:
337 case QCRYPTO_CIPHER_ALG_AES_256:
338 if (qcrypto_cipher_init_aes(cipher, key, nkey, errp) < 0) {
344 "Unsupported cipher algorithm %d", cipher->alg);
355 void qcrypto_cipher_free(QCryptoCipher *cipher)
357 QCryptoCipherBuiltin *ctxt;
363 ctxt = cipher->opaque;
369 int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
375 QCryptoCipherBuiltin *ctxt = cipher->opaque;
377 return ctxt->encrypt(cipher, in, out, len, errp);
381 int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
387 QCryptoCipherBuiltin *ctxt = cipher->opaque;
389 return ctxt->decrypt(cipher, in, out, len, errp);
393 int qcrypto_cipher_setiv(QCryptoCipher *cipher,
394 const uint8_t *iv, size_t niv,
397 QCryptoCipherBuiltin *ctxt = cipher->opaque;
399 return ctxt->setiv(cipher, iv, niv, errp);