crypto: add support for the serpent cipher algorithm
[qemu/ar7.git] / crypto / cipher-nettle.c
blob74b55abee0eae955946f05c4fc85ca8f918fc3f7
1 /*
2 * QEMU Crypto cipher nettle 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 <nettle/nettle-types.h>
23 #include <nettle/aes.h>
24 #include <nettle/des.h>
25 #include <nettle/cbc.h>
26 #include <nettle/cast128.h>
27 #include <nettle/serpent.h>
29 #if CONFIG_NETTLE_VERSION_MAJOR < 3
30 typedef nettle_crypt_func nettle_cipher_func;
32 typedef void * cipher_ctx_t;
33 typedef unsigned cipher_length_t;
34 #else
35 typedef const void * cipher_ctx_t;
36 typedef size_t cipher_length_t;
37 #endif
39 static nettle_cipher_func aes_encrypt_wrapper;
40 static nettle_cipher_func aes_decrypt_wrapper;
41 static nettle_cipher_func des_encrypt_wrapper;
42 static nettle_cipher_func des_decrypt_wrapper;
44 static void aes_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
45 uint8_t *dst, const uint8_t *src)
47 aes_encrypt(ctx, length, dst, src);
50 static void aes_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
51 uint8_t *dst, const uint8_t *src)
53 aes_decrypt(ctx, length, dst, src);
56 static void des_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
57 uint8_t *dst, const uint8_t *src)
59 des_encrypt(ctx, length, dst, src);
62 static void des_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
63 uint8_t *dst, const uint8_t *src)
65 des_decrypt(ctx, length, dst, src);
68 static void cast128_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
69 uint8_t *dst, const uint8_t *src)
71 cast128_encrypt(ctx, length, dst, src);
74 static void cast128_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
75 uint8_t *dst, const uint8_t *src)
77 cast128_decrypt(ctx, length, dst, src);
80 static void serpent_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
81 uint8_t *dst, const uint8_t *src)
83 serpent_encrypt(ctx, length, dst, src);
86 static void serpent_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
87 uint8_t *dst, const uint8_t *src)
89 serpent_decrypt(ctx, length, dst, src);
92 typedef struct QCryptoCipherNettle QCryptoCipherNettle;
93 struct QCryptoCipherNettle {
94 void *ctx_encrypt;
95 void *ctx_decrypt;
96 nettle_cipher_func *alg_encrypt;
97 nettle_cipher_func *alg_decrypt;
98 uint8_t *iv;
99 size_t blocksize;
102 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
104 switch (alg) {
105 case QCRYPTO_CIPHER_ALG_DES_RFB:
106 case QCRYPTO_CIPHER_ALG_AES_128:
107 case QCRYPTO_CIPHER_ALG_AES_192:
108 case QCRYPTO_CIPHER_ALG_AES_256:
109 case QCRYPTO_CIPHER_ALG_CAST5_128:
110 case QCRYPTO_CIPHER_ALG_SERPENT_128:
111 case QCRYPTO_CIPHER_ALG_SERPENT_192:
112 case QCRYPTO_CIPHER_ALG_SERPENT_256:
113 return true;
114 default:
115 return false;
120 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
121 QCryptoCipherMode mode,
122 const uint8_t *key, size_t nkey,
123 Error **errp)
125 QCryptoCipher *cipher;
126 QCryptoCipherNettle *ctx;
127 uint8_t *rfbkey;
129 switch (mode) {
130 case QCRYPTO_CIPHER_MODE_ECB:
131 case QCRYPTO_CIPHER_MODE_CBC:
132 break;
133 default:
134 error_setg(errp, "Unsupported cipher mode %d", mode);
135 return NULL;
138 if (!qcrypto_cipher_validate_key_length(alg, nkey, errp)) {
139 return NULL;
142 cipher = g_new0(QCryptoCipher, 1);
143 cipher->alg = alg;
144 cipher->mode = mode;
146 ctx = g_new0(QCryptoCipherNettle, 1);
148 switch (alg) {
149 case QCRYPTO_CIPHER_ALG_DES_RFB:
150 ctx->ctx_encrypt = g_new0(struct des_ctx, 1);
151 ctx->ctx_decrypt = NULL; /* 1 ctx can do both */
152 rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
153 des_set_key(ctx->ctx_encrypt, rfbkey);
154 g_free(rfbkey);
156 ctx->alg_encrypt = des_encrypt_wrapper;
157 ctx->alg_decrypt = des_decrypt_wrapper;
159 ctx->blocksize = DES_BLOCK_SIZE;
160 break;
162 case QCRYPTO_CIPHER_ALG_AES_128:
163 case QCRYPTO_CIPHER_ALG_AES_192:
164 case QCRYPTO_CIPHER_ALG_AES_256:
165 ctx->ctx_encrypt = g_new0(struct aes_ctx, 1);
166 ctx->ctx_decrypt = g_new0(struct aes_ctx, 1);
168 aes_set_encrypt_key(ctx->ctx_encrypt, nkey, key);
169 aes_set_decrypt_key(ctx->ctx_decrypt, nkey, key);
171 ctx->alg_encrypt = aes_encrypt_wrapper;
172 ctx->alg_decrypt = aes_decrypt_wrapper;
174 ctx->blocksize = AES_BLOCK_SIZE;
175 break;
177 case QCRYPTO_CIPHER_ALG_CAST5_128:
178 ctx->ctx_encrypt = g_new0(struct cast128_ctx, 1);
179 ctx->ctx_decrypt = NULL; /* 1 ctx can do both */
181 cast5_set_key(ctx->ctx_encrypt, nkey, key);
183 ctx->alg_encrypt = cast128_encrypt_wrapper;
184 ctx->alg_decrypt = cast128_decrypt_wrapper;
186 ctx->blocksize = CAST128_BLOCK_SIZE;
187 break;
189 case QCRYPTO_CIPHER_ALG_SERPENT_128:
190 case QCRYPTO_CIPHER_ALG_SERPENT_192:
191 case QCRYPTO_CIPHER_ALG_SERPENT_256:
192 ctx->ctx_encrypt = g_new0(struct serpent_ctx, 1);
193 ctx->ctx_decrypt = NULL; /* 1 ctx can do both */
195 serpent_set_key(ctx->ctx_encrypt, nkey, key);
197 ctx->alg_encrypt = serpent_encrypt_wrapper;
198 ctx->alg_decrypt = serpent_decrypt_wrapper;
200 ctx->blocksize = SERPENT_BLOCK_SIZE;
201 break;
203 default:
204 error_setg(errp, "Unsupported cipher algorithm %d", alg);
205 goto error;
208 ctx->iv = g_new0(uint8_t, ctx->blocksize);
209 cipher->opaque = ctx;
211 return cipher;
213 error:
214 g_free(cipher);
215 g_free(ctx);
216 return NULL;
220 void qcrypto_cipher_free(QCryptoCipher *cipher)
222 QCryptoCipherNettle *ctx;
224 if (!cipher) {
225 return;
228 ctx = cipher->opaque;
229 g_free(ctx->iv);
230 g_free(ctx->ctx_encrypt);
231 g_free(ctx->ctx_decrypt);
232 g_free(ctx);
233 g_free(cipher);
237 int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
238 const void *in,
239 void *out,
240 size_t len,
241 Error **errp)
243 QCryptoCipherNettle *ctx = cipher->opaque;
245 if (len % ctx->blocksize) {
246 error_setg(errp, "Length %zu must be a multiple of block size %zu",
247 len, ctx->blocksize);
248 return -1;
251 switch (cipher->mode) {
252 case QCRYPTO_CIPHER_MODE_ECB:
253 ctx->alg_encrypt(ctx->ctx_encrypt, len, out, in);
254 break;
256 case QCRYPTO_CIPHER_MODE_CBC:
257 cbc_encrypt(ctx->ctx_encrypt, ctx->alg_encrypt,
258 ctx->blocksize, ctx->iv,
259 len, out, in);
260 break;
261 default:
262 error_setg(errp, "Unsupported cipher algorithm %d",
263 cipher->alg);
264 return -1;
266 return 0;
270 int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
271 const void *in,
272 void *out,
273 size_t len,
274 Error **errp)
276 QCryptoCipherNettle *ctx = cipher->opaque;
278 if (len % ctx->blocksize) {
279 error_setg(errp, "Length %zu must be a multiple of block size %zu",
280 len, ctx->blocksize);
281 return -1;
284 switch (cipher->mode) {
285 case QCRYPTO_CIPHER_MODE_ECB:
286 ctx->alg_decrypt(ctx->ctx_decrypt ? ctx->ctx_decrypt : ctx->ctx_encrypt,
287 len, out, in);
288 break;
290 case QCRYPTO_CIPHER_MODE_CBC:
291 cbc_decrypt(ctx->ctx_decrypt ? ctx->ctx_decrypt : ctx->ctx_encrypt,
292 ctx->alg_decrypt, ctx->blocksize, ctx->iv,
293 len, out, in);
294 break;
295 default:
296 error_setg(errp, "Unsupported cipher algorithm %d",
297 cipher->alg);
298 return -1;
300 return 0;
303 int qcrypto_cipher_setiv(QCryptoCipher *cipher,
304 const uint8_t *iv, size_t niv,
305 Error **errp)
307 QCryptoCipherNettle *ctx = cipher->opaque;
308 if (niv != ctx->blocksize) {
309 error_setg(errp, "Expected IV size %zu not %zu",
310 ctx->blocksize, niv);
311 return -1;
313 memcpy(ctx->iv, iv, niv);
314 return 0;