| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | /* | 
					
						
							|  |  |  |  * QEMU Crypto cipher built-in algorithms | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2015 Red Hat, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2019-02-13 16:54:59 +01:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License along with this library; if not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "crypto/aes.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  | typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext; | 
					
						
							|  |  |  | struct QCryptoCipherBuiltinAESContext { | 
					
						
							|  |  |  |     AES_KEY enc; | 
					
						
							|  |  |  |     AES_KEY dec; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES; | 
					
						
							|  |  |  | struct QCryptoCipherBuiltinAES { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     QCryptoCipher base; | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  |     QCryptoCipherBuiltinAESContext key; | 
					
						
							| 
									
										
										
										
											2015-10-16 13:23:13 +01:00
										 |  |  |     uint8_t iv[AES_BLOCK_SIZE]; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static inline bool qcrypto_length_check(size_t len, size_t blocksize, | 
					
						
							|  |  |  |                                         Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (unlikely(len & (blocksize - 1))) { | 
					
						
							|  |  |  |         error_setg(errp, "Length %zu must be a multiple of block size %zu", | 
					
						
							|  |  |  |                    len, blocksize); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static void qcrypto_cipher_ctx_free(QCryptoCipher *cipher) | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:14 -07:00
										 |  |  |     g_free(cipher); | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher, | 
					
						
							|  |  |  |                                    const uint8_t *iv, size_t niv, | 
					
						
							|  |  |  |                                    Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     error_setg(errp, "Setting IV is not supported"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:18 -07:00
										 |  |  | static void do_aes_encrypt_ecb(const void *vctx, | 
					
						
							|  |  |  |                                size_t len, | 
					
						
							|  |  |  |                                uint8_t *out, | 
					
						
							|  |  |  |                                const uint8_t *in) | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:18 -07:00
										 |  |  |     const QCryptoCipherBuiltinAESContext *ctx = vctx; | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* We have already verified that len % AES_BLOCK_SIZE == 0. */ | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  |     while (len) { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:18 -07:00
										 |  |  |         AES_encrypt(in, out, &ctx->enc); | 
					
						
							|  |  |  |         in += AES_BLOCK_SIZE; | 
					
						
							|  |  |  |         out += AES_BLOCK_SIZE; | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:17 -07:00
										 |  |  |         len -= AES_BLOCK_SIZE; | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:18 -07:00
										 |  |  | static void do_aes_decrypt_ecb(const void *vctx, | 
					
						
							|  |  |  |                                size_t len, | 
					
						
							|  |  |  |                                uint8_t *out, | 
					
						
							|  |  |  |                                const uint8_t *in) | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:18 -07:00
										 |  |  |     const QCryptoCipherBuiltinAESContext *ctx = vctx; | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* We have already verified that len % AES_BLOCK_SIZE == 0. */ | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  |     while (len) { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:18 -07:00
										 |  |  |         AES_decrypt(in, out, &ctx->dec); | 
					
						
							|  |  |  |         in += AES_BLOCK_SIZE; | 
					
						
							|  |  |  |         out += AES_BLOCK_SIZE; | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:17 -07:00
										 |  |  |         len -= AES_BLOCK_SIZE; | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:20 -07:00
										 |  |  | static void do_aes_encrypt_cbc(const AES_KEY *key, | 
					
						
							|  |  |  |                                size_t len, | 
					
						
							|  |  |  |                                uint8_t *out, | 
					
						
							|  |  |  |                                const uint8_t *in, | 
					
						
							|  |  |  |                                uint8_t *ivec) | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:19 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:20 -07:00
										 |  |  |     uint8_t tmp[AES_BLOCK_SIZE]; | 
					
						
							|  |  |  |     size_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* We have already verified that len % AES_BLOCK_SIZE == 0. */ | 
					
						
							|  |  |  |     while (len) { | 
					
						
							|  |  |  |         for (n = 0; n < AES_BLOCK_SIZE; ++n) { | 
					
						
							|  |  |  |             tmp[n] = in[n] ^ ivec[n]; | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:19 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:20 -07:00
										 |  |  |         AES_encrypt(tmp, out, key); | 
					
						
							|  |  |  |         memcpy(ivec, out, AES_BLOCK_SIZE); | 
					
						
							|  |  |  |         len -= AES_BLOCK_SIZE; | 
					
						
							|  |  |  |         in += AES_BLOCK_SIZE; | 
					
						
							|  |  |  |         out += AES_BLOCK_SIZE; | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:19 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:20 -07:00
										 |  |  | static void do_aes_decrypt_cbc(const AES_KEY *key, | 
					
						
							|  |  |  |                                size_t len, | 
					
						
							|  |  |  |                                uint8_t *out, | 
					
						
							|  |  |  |                                const uint8_t *in, | 
					
						
							|  |  |  |                                uint8_t *ivec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint8_t tmp[AES_BLOCK_SIZE]; | 
					
						
							|  |  |  |     size_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* We have already verified that len % AES_BLOCK_SIZE == 0. */ | 
					
						
							|  |  |  |     while (len) { | 
					
						
							|  |  |  |         memcpy(tmp, in, AES_BLOCK_SIZE); | 
					
						
							|  |  |  |         AES_decrypt(in, out, key); | 
					
						
							|  |  |  |         for (n = 0; n < AES_BLOCK_SIZE; ++n) { | 
					
						
							|  |  |  |             out[n] ^= ivec[n]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         memcpy(ivec, tmp, AES_BLOCK_SIZE); | 
					
						
							|  |  |  |         len -= AES_BLOCK_SIZE; | 
					
						
							|  |  |  |         in += AES_BLOCK_SIZE; | 
					
						
							|  |  |  |         out += AES_BLOCK_SIZE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static int qcrypto_cipher_aes_encrypt_ecb(QCryptoCipher *cipher, | 
					
						
							|  |  |  |                                           const void *in, void *out, | 
					
						
							|  |  |  |                                           size_t len, Error **errp) | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     QCryptoCipherBuiltinAES *ctx | 
					
						
							|  |  |  |         = container_of(cipher, QCryptoCipherBuiltinAES, base); | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     do_aes_encrypt_ecb(&ctx->key, len, out, in); | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static int qcrypto_cipher_aes_decrypt_ecb(QCryptoCipher *cipher, | 
					
						
							|  |  |  |                                           const void *in, void *out, | 
					
						
							|  |  |  |                                           size_t len, Error **errp) | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     QCryptoCipherBuiltinAES *ctx | 
					
						
							|  |  |  |         = container_of(cipher, QCryptoCipherBuiltinAES, base); | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     do_aes_decrypt_ecb(&ctx->key, len, out, in); | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static int qcrypto_cipher_aes_encrypt_cbc(QCryptoCipher *cipher, | 
					
						
							|  |  |  |                                           const void *in, void *out, | 
					
						
							|  |  |  |                                           size_t len, Error **errp) | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     QCryptoCipherBuiltinAES *ctx | 
					
						
							|  |  |  |         = container_of(cipher, QCryptoCipherBuiltinAES, base); | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     do_aes_encrypt_cbc(&ctx->key.enc, len, out, in, ctx->iv); | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static int qcrypto_cipher_aes_decrypt_cbc(QCryptoCipher *cipher, | 
					
						
							|  |  |  |                                           const void *in, void *out, | 
					
						
							|  |  |  |                                           size_t len, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QCryptoCipherBuiltinAES *ctx | 
					
						
							|  |  |  |         = container_of(cipher, QCryptoCipherBuiltinAES, base); | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     do_aes_decrypt_cbc(&ctx->key.dec, len, out, in, ctx->iv); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static int qcrypto_cipher_aes_setiv(QCryptoCipher *cipher, const uint8_t *iv, | 
					
						
							|  |  |  |                              size_t niv, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QCryptoCipherBuiltinAES *ctx | 
					
						
							|  |  |  |         = container_of(cipher, QCryptoCipherBuiltinAES, base); | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     if (niv != AES_BLOCK_SIZE) { | 
					
						
							|  |  |  |         error_setg(errp, "IV must be %d bytes not %zu", | 
					
						
							|  |  |  |                    AES_BLOCK_SIZE, niv); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |     memcpy(ctx->iv, iv, AES_BLOCK_SIZE); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_ecb = { | 
					
						
							|  |  |  |     .cipher_encrypt = qcrypto_cipher_aes_encrypt_ecb, | 
					
						
							|  |  |  |     .cipher_decrypt = qcrypto_cipher_aes_decrypt_ecb, | 
					
						
							|  |  |  |     .cipher_setiv = qcrypto_cipher_no_setiv, | 
					
						
							|  |  |  |     .cipher_free = qcrypto_cipher_ctx_free, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  | static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_cbc = { | 
					
						
							|  |  |  |     .cipher_encrypt = qcrypto_cipher_aes_encrypt_cbc, | 
					
						
							|  |  |  |     .cipher_decrypt = qcrypto_cipher_aes_decrypt_cbc, | 
					
						
							|  |  |  |     .cipher_setiv = qcrypto_cipher_aes_setiv, | 
					
						
							|  |  |  |     .cipher_free = qcrypto_cipher_ctx_free, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-26 17:23:21 +08:00
										 |  |  | bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, | 
					
						
							|  |  |  |                              QCryptoCipherMode mode) | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     switch (alg) { | 
					
						
							|  |  |  |     case QCRYPTO_CIPHER_ALG_AES_128: | 
					
						
							|  |  |  |     case QCRYPTO_CIPHER_ALG_AES_192: | 
					
						
							|  |  |  |     case QCRYPTO_CIPHER_ALG_AES_256: | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |         switch (mode) { | 
					
						
							|  |  |  |         case QCRYPTO_CIPHER_MODE_ECB: | 
					
						
							|  |  |  |         case QCRYPTO_CIPHER_MODE_CBC: | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-09-26 17:23:21 +08:00
										 |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:14 -07:00
										 |  |  | static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, | 
					
						
							|  |  |  |                                              QCryptoCipherMode mode, | 
					
						
							|  |  |  |                                              const uint8_t *key, | 
					
						
							|  |  |  |                                              size_t nkey, | 
					
						
							|  |  |  |                                              Error **errp) | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-02-11 14:05:21 +00:00
										 |  |  |     if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { | 
					
						
							| 
									
										
										
										
											2017-07-14 14:03:57 -04:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-14 14:03:57 -04:00
										 |  |  |     switch (alg) { | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     case QCRYPTO_CIPHER_ALG_AES_128: | 
					
						
							|  |  |  |     case QCRYPTO_CIPHER_ALG_AES_192: | 
					
						
							|  |  |  |     case QCRYPTO_CIPHER_ALG_AES_256: | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |         { | 
					
						
							|  |  |  |             QCryptoCipherBuiltinAES *ctx; | 
					
						
							|  |  |  |             const QCryptoCipherDriver *drv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             switch (mode) { | 
					
						
							|  |  |  |             case QCRYPTO_CIPHER_MODE_ECB: | 
					
						
							|  |  |  |                 drv = &qcrypto_cipher_aes_driver_ecb; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case QCRYPTO_CIPHER_MODE_CBC: | 
					
						
							|  |  |  |                 drv = &qcrypto_cipher_aes_driver_cbc; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 goto bad_mode; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ctx = g_new0(QCryptoCipherBuiltinAES, 1); | 
					
						
							|  |  |  |             ctx->base.driver = drv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (AES_set_encrypt_key(key, nkey * 8, &ctx->key.enc)) { | 
					
						
							|  |  |  |                 error_setg(errp, "Failed to set encryption key"); | 
					
						
							|  |  |  |                 goto error; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (AES_set_decrypt_key(key, nkey * 8, &ctx->key.dec)) { | 
					
						
							|  |  |  |                 error_setg(errp, "Failed to set decryption key"); | 
					
						
							|  |  |  |                 goto error; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return &ctx->base; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         error: | 
					
						
							|  |  |  |             g_free(ctx); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     default: | 
					
						
							|  |  |  |         error_setg(errp, | 
					
						
							| 
									
										
										
										
											2016-09-05 18:02:05 +01:00
										 |  |  |                    "Unsupported cipher algorithm %s", | 
					
						
							| 
									
										
										
										
											2017-08-24 10:46:08 +02:00
										 |  |  |                    QCryptoCipherAlgorithm_str(alg)); | 
					
						
							| 
									
										
										
										
											2017-07-14 14:03:57 -04:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 10:05:21 -07:00
										 |  |  |  bad_mode: | 
					
						
							|  |  |  |     error_setg(errp, "Unsupported cipher mode %s", | 
					
						
							|  |  |  |                QCryptoCipherMode_str(mode)); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2015-07-01 18:10:32 +01:00
										 |  |  | } |