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:
38 #ifdef CONFIG_CRYPTO_SM4
39 case QCRYPTO_CIPHER_ALG_SM4:
47 case QCRYPTO_CIPHER_MODE_ECB:
48 case QCRYPTO_CIPHER_MODE_CBC:
49 case QCRYPTO_CIPHER_MODE_XTS:
50 case QCRYPTO_CIPHER_MODE_CTR:
57 typedef struct QCryptoCipherGcrypt {
59 gcry_cipher_hd_t handle;
61 } QCryptoCipherGcrypt;
64 static void qcrypto_gcrypt_ctx_free(QCryptoCipher *cipher)
66 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
68 gcry_cipher_close(ctx->handle);
72 static int qcrypto_gcrypt_encrypt(QCryptoCipher *cipher, const void *in,
73 void *out, size_t len, Error **errp)
75 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
78 if (len & (ctx->blocksize - 1)) {
79 error_setg(errp, "Length %zu must be a multiple of block size %zu",
84 err = gcry_cipher_encrypt(ctx->handle, out, len, in, len);
86 error_setg(errp, "Cannot encrypt data: %s", gcry_strerror(err));
94 static int qcrypto_gcrypt_decrypt(QCryptoCipher *cipher, const void *in,
95 void *out, size_t len, Error **errp)
97 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
100 if (len & (ctx->blocksize - 1)) {
101 error_setg(errp, "Length %zu must be a multiple of block size %zu",
102 len, ctx->blocksize);
106 err = gcry_cipher_decrypt(ctx->handle, out, len, in, len);
108 error_setg(errp, "Cannot decrypt data: %s",
116 static int qcrypto_gcrypt_setiv(QCryptoCipher *cipher,
117 const uint8_t *iv, size_t niv,
120 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
123 if (niv != ctx->blocksize) {
124 error_setg(errp, "Expected IV size %zu not %zu",
125 ctx->blocksize, niv);
129 gcry_cipher_reset(ctx->handle);
130 err = gcry_cipher_setiv(ctx->handle, iv, niv);
132 error_setg(errp, "Cannot set IV: %s", gcry_strerror(err));
139 static int qcrypto_gcrypt_ctr_setiv(QCryptoCipher *cipher,
140 const uint8_t *iv, size_t niv,
143 QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
146 if (niv != ctx->blocksize) {
147 error_setg(errp, "Expected IV size %zu not %zu",
148 ctx->blocksize, niv);
152 err = gcry_cipher_setctr(ctx->handle, iv, niv);
154 error_setg(errp, "Cannot set Counter: %s", gcry_strerror(err));
162 static const struct QCryptoCipherDriver qcrypto_gcrypt_driver = {
163 .cipher_encrypt = qcrypto_gcrypt_encrypt,
164 .cipher_decrypt = qcrypto_gcrypt_decrypt,
165 .cipher_setiv = qcrypto_gcrypt_setiv,
166 .cipher_free = qcrypto_gcrypt_ctx_free,
169 static const struct QCryptoCipherDriver qcrypto_gcrypt_ctr_driver = {
170 .cipher_encrypt = qcrypto_gcrypt_encrypt,
171 .cipher_decrypt = qcrypto_gcrypt_decrypt,
172 .cipher_setiv = qcrypto_gcrypt_ctr_setiv,
173 .cipher_free = qcrypto_gcrypt_ctx_free,
176 static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
177 QCryptoCipherMode mode,
182 QCryptoCipherGcrypt *ctx;
183 const QCryptoCipherDriver *drv;
185 int gcryalg, gcrymode;
187 if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
192 case QCRYPTO_CIPHER_ALG_DES:
193 gcryalg = GCRY_CIPHER_DES;
195 case QCRYPTO_CIPHER_ALG_3DES:
196 gcryalg = GCRY_CIPHER_3DES;
198 case QCRYPTO_CIPHER_ALG_AES_128:
199 gcryalg = GCRY_CIPHER_AES128;
201 case QCRYPTO_CIPHER_ALG_AES_192:
202 gcryalg = GCRY_CIPHER_AES192;
204 case QCRYPTO_CIPHER_ALG_AES_256:
205 gcryalg = GCRY_CIPHER_AES256;
207 case QCRYPTO_CIPHER_ALG_CAST5_128:
208 gcryalg = GCRY_CIPHER_CAST5;
210 case QCRYPTO_CIPHER_ALG_SERPENT_128:
211 gcryalg = GCRY_CIPHER_SERPENT128;
213 case QCRYPTO_CIPHER_ALG_SERPENT_192:
214 gcryalg = GCRY_CIPHER_SERPENT192;
216 case QCRYPTO_CIPHER_ALG_SERPENT_256:
217 gcryalg = GCRY_CIPHER_SERPENT256;
219 case QCRYPTO_CIPHER_ALG_TWOFISH_128:
220 gcryalg = GCRY_CIPHER_TWOFISH128;
222 case QCRYPTO_CIPHER_ALG_TWOFISH_256:
223 gcryalg = GCRY_CIPHER_TWOFISH;
225 #ifdef CONFIG_CRYPTO_SM4
226 case QCRYPTO_CIPHER_ALG_SM4:
227 gcryalg = GCRY_CIPHER_SM4;
231 error_setg(errp, "Unsupported cipher algorithm %s",
232 QCryptoCipherAlgorithm_str(alg));
236 drv = &qcrypto_gcrypt_driver;
238 case QCRYPTO_CIPHER_MODE_ECB:
239 gcrymode = GCRY_CIPHER_MODE_ECB;
241 case QCRYPTO_CIPHER_MODE_XTS:
242 gcrymode = GCRY_CIPHER_MODE_XTS;
244 case QCRYPTO_CIPHER_MODE_CBC:
245 gcrymode = GCRY_CIPHER_MODE_CBC;
247 case QCRYPTO_CIPHER_MODE_CTR:
248 drv = &qcrypto_gcrypt_ctr_driver;
249 gcrymode = GCRY_CIPHER_MODE_CTR;
252 error_setg(errp, "Unsupported cipher mode %s",
253 QCryptoCipherMode_str(mode));
257 ctx = g_new0(QCryptoCipherGcrypt, 1);
258 ctx->base.driver = drv;
260 err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
262 error_setg(errp, "Cannot initialize cipher: %s",
266 ctx->blocksize = gcry_cipher_get_algo_blklen(gcryalg);
268 err = gcry_cipher_setkey(ctx->handle, key, nkey);
270 error_setg(errp, "Cannot set key: %s", gcry_strerror(err));
277 gcry_cipher_close(ctx->handle);