2 * QEMU Crypto cipher libgcrypt 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.1 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/>.
23 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
24 QCryptoCipherMode mode)
27 case QCRYPTO_CIPHER_ALG_DES:
28 case QCRYPTO_CIPHER_ALG_3DES:
29 case QCRYPTO_CIPHER_ALG_AES_128:
30 case QCRYPTO_CIPHER_ALG_AES_192:
31 case QCRYPTO_CIPHER_ALG_AES_256:
32 case QCRYPTO_CIPHER_ALG_CAST5_128:
33 case QCRYPTO_CIPHER_ALG_SERPENT_128:
34 case QCRYPTO_CIPHER_ALG_SERPENT_192:
35 case QCRYPTO_CIPHER_ALG_SERPENT_256:
36 case QCRYPTO_CIPHER_ALG_TWOFISH_128:
37 case QCRYPTO_CIPHER_ALG_TWOFISH_256:
44 case QCRYPTO_CIPHER_MODE_ECB:
45 case QCRYPTO_CIPHER_MODE_CBC:
46 case QCRYPTO_CIPHER_MODE_XTS:
47 case QCRYPTO_CIPHER_MODE_CTR:
54 typedef struct QCryptoCipherGcrypt {
56 gcry_cipher_hd_t handle;
58 } QCryptoCipherGcrypt;
61 static void qcrypto_gcrypt_ctx_free(QCryptoCipher *cipher)
63 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
65 gcry_cipher_close(ctx->handle);
69 static int qcrypto_gcrypt_encrypt(QCryptoCipher *cipher, const void *in,
70 void *out, size_t len, Error **errp)
72 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
75 if (len & (ctx->blocksize - 1)) {
76 error_setg(errp, "Length %zu must be a multiple of block size %zu",
81 err = gcry_cipher_encrypt(ctx->handle, out, len, in, len);
83 error_setg(errp, "Cannot encrypt data: %s", gcry_strerror(err));
91 static int qcrypto_gcrypt_decrypt(QCryptoCipher *cipher, const void *in,
92 void *out, size_t len, Error **errp)
94 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
97 if (len & (ctx->blocksize - 1)) {
98 error_setg(errp, "Length %zu must be a multiple of block size %zu",
103 err = gcry_cipher_decrypt(ctx->handle, out, len, in, len);
105 error_setg(errp, "Cannot decrypt data: %s",
113 static int qcrypto_gcrypt_setiv(QCryptoCipher *cipher,
114 const uint8_t *iv, size_t niv,
117 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
120 if (niv != ctx->blocksize) {
121 error_setg(errp, "Expected IV size %zu not %zu",
122 ctx->blocksize, niv);
126 gcry_cipher_reset(ctx->handle);
127 err = gcry_cipher_setiv(ctx->handle, iv, niv);
129 error_setg(errp, "Cannot set IV: %s", gcry_strerror(err));
136 static int qcrypto_gcrypt_ctr_setiv(QCryptoCipher *cipher,
137 const uint8_t *iv, size_t niv,
140 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
143 if (niv != ctx->blocksize) {
144 error_setg(errp, "Expected IV size %zu not %zu",
145 ctx->blocksize, niv);
149 err = gcry_cipher_setctr(ctx->handle, iv, niv);
151 error_setg(errp, "Cannot set Counter: %s", gcry_strerror(err));
159 static const struct QCryptoCipherDriver qcrypto_gcrypt_driver = {
160 .cipher_encrypt = qcrypto_gcrypt_encrypt,
161 .cipher_decrypt = qcrypto_gcrypt_decrypt,
162 .cipher_setiv = qcrypto_gcrypt_setiv,
163 .cipher_free = qcrypto_gcrypt_ctx_free,
166 static const struct QCryptoCipherDriver qcrypto_gcrypt_ctr_driver = {
167 .cipher_encrypt = qcrypto_gcrypt_encrypt,
168 .cipher_decrypt = qcrypto_gcrypt_decrypt,
169 .cipher_setiv = qcrypto_gcrypt_ctr_setiv,
170 .cipher_free = qcrypto_gcrypt_ctx_free,
173 static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
174 QCryptoCipherMode mode,
179 QCryptoCipherGcrypt *ctx;
180 const QCryptoCipherDriver *drv;
182 int gcryalg, gcrymode;
184 if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
189 case QCRYPTO_CIPHER_ALG_DES:
190 gcryalg = GCRY_CIPHER_DES;
192 case QCRYPTO_CIPHER_ALG_3DES:
193 gcryalg = GCRY_CIPHER_3DES;
195 case QCRYPTO_CIPHER_ALG_AES_128:
196 gcryalg = GCRY_CIPHER_AES128;
198 case QCRYPTO_CIPHER_ALG_AES_192:
199 gcryalg = GCRY_CIPHER_AES192;
201 case QCRYPTO_CIPHER_ALG_AES_256:
202 gcryalg = GCRY_CIPHER_AES256;
204 case QCRYPTO_CIPHER_ALG_CAST5_128:
205 gcryalg = GCRY_CIPHER_CAST5;
207 case QCRYPTO_CIPHER_ALG_SERPENT_128:
208 gcryalg = GCRY_CIPHER_SERPENT128;
210 case QCRYPTO_CIPHER_ALG_SERPENT_192:
211 gcryalg = GCRY_CIPHER_SERPENT192;
213 case QCRYPTO_CIPHER_ALG_SERPENT_256:
214 gcryalg = GCRY_CIPHER_SERPENT256;
216 case QCRYPTO_CIPHER_ALG_TWOFISH_128:
217 gcryalg = GCRY_CIPHER_TWOFISH128;
219 case QCRYPTO_CIPHER_ALG_TWOFISH_256:
220 gcryalg = GCRY_CIPHER_TWOFISH;
223 error_setg(errp, "Unsupported cipher algorithm %s",
224 QCryptoCipherAlgorithm_str(alg));
228 drv = &qcrypto_gcrypt_driver;
230 case QCRYPTO_CIPHER_MODE_ECB:
231 gcrymode = GCRY_CIPHER_MODE_ECB;
233 case QCRYPTO_CIPHER_MODE_XTS:
234 gcrymode = GCRY_CIPHER_MODE_XTS;
236 case QCRYPTO_CIPHER_MODE_CBC:
237 gcrymode = GCRY_CIPHER_MODE_CBC;
239 case QCRYPTO_CIPHER_MODE_CTR:
240 drv = &qcrypto_gcrypt_ctr_driver;
241 gcrymode = GCRY_CIPHER_MODE_CTR;
244 error_setg(errp, "Unsupported cipher mode %s",
245 QCryptoCipherMode_str(mode));
249 ctx = g_new0(QCryptoCipherGcrypt, 1);
250 ctx->base.driver = drv;
252 err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
254 error_setg(errp, "Cannot initialize cipher: %s",
258 ctx->blocksize = gcry_cipher_get_algo_blklen(gcryalg);
260 err = gcry_cipher_setkey(ctx->handle, key, nkey);
262 error_setg(errp, "Cannot set key: %s", gcry_strerror(err));
269 gcry_cipher_close(ctx->handle);