1 /* 2 * QEMU Crypto cipher algorithms 3 * 4 * Copyright (c) 2015 Red Hat, Inc. 5 * 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. 10 * 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. 15 * 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/>. 18 * 19 */ 20 21 #ifndef QCRYPTO_CIPHER_H__ 22 #define QCRYPTO_CIPHER_H__ 23 24 #include "qemu-common.h" 25 #include "qapi/error.h" 26 27 typedef struct QCryptoCipher QCryptoCipher; 28 29 typedef enum { 30 QCRYPTO_CIPHER_ALG_AES_128, 31 QCRYPTO_CIPHER_ALG_AES_192, 32 QCRYPTO_CIPHER_ALG_AES_256, 33 QCRYPTO_CIPHER_ALG_DES_RFB, /* A stupid variant on DES for VNC */ 34 35 QCRYPTO_CIPHER_ALG_LAST 36 } QCryptoCipherAlgorithm; 37 38 typedef enum { 39 QCRYPTO_CIPHER_MODE_ECB, 40 QCRYPTO_CIPHER_MODE_CBC, 41 42 QCRYPTO_CIPHER_MODE_LAST 43 } QCryptoCipherMode; 44 45 /** 46 * QCryptoCipher: 47 * 48 * The QCryptoCipher object provides a way to perform encryption 49 * and decryption of data, with a standard API, regardless of the 50 * algorithm used. It further isolates the calling code from the 51 * details of the specific underlying implementation, whether 52 * built-in, libgcrypt or nettle. 53 * 54 * Each QCryptoCipher object is capable of performing both 55 * encryption and decryption, and can operate in a number 56 * or modes including ECB, CBC. 57 * 58 * <example> 59 * <title>Encrypting data with AES-128 in CBC mode</title> 60 * <programlisting> 61 * QCryptoCipher *cipher; 62 * uint8_t key = ....; 63 * size_t keylen = 16; 64 * uint8_t iv = ....; 65 * 66 * if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128)) { 67 * error_report(errp, "Feature <blah> requires AES cipher support"); 68 * return -1; 69 * } 70 * 71 * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128, 72 * QCRYPTO_CIPHER_MODE_CBC, 73 * key, keylen, 74 * errp); 75 * if (!cipher) { 76 * return -1; 77 * } 78 * 79 * if (qcrypto_cipher_set_iv(cipher, iv, keylen, errp) < 0) { 80 * return -1; 81 * } 82 * 83 * if (qcrypto_cipher_encrypt(cipher, rawdata, encdata, datalen, errp) < 0) { 84 * return -1; 85 * } 86 * 87 * qcrypto_cipher_free(cipher); 88 * </programlisting> 89 * </example> 90 * 91 */ 92 93 struct QCryptoCipher { 94 QCryptoCipherAlgorithm alg; 95 QCryptoCipherMode mode; 96 void *opaque; 97 }; 98 99 /** 100 * qcrypto_cipher_supports: 101 * @alg: the cipher algorithm 102 * 103 * Determine if @alg cipher algorithm is supported by the 104 * current configured build 105 * 106 * Returns: true if the algorithm is supported, false otherwise 107 */ 108 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg); 109 110 111 /** 112 * qcrypto_cipher_new: 113 * @alg: the cipher algorithm 114 * @mode: the cipher usage mode 115 * @key: the private key bytes 116 * @nkey: the length of @key 117 * @errp: pointer to an uninitialized error object 118 * 119 * Creates a new cipher object for encrypting/decrypting 120 * data with the algorithm @alg in the usage mode @mode. 121 * 122 * The @key parameter provides the bytes representing 123 * the encryption/decryption key to use. The @nkey parameter 124 * specifies the length of @key in bytes. Each algorithm has 125 * one or more valid key lengths, and it is an error to provide 126 * a key of the incorrect length. 127 * 128 * The returned cipher object must be released with 129 * qcrypto_cipher_free() when no longer required 130 * 131 * Returns: a new cipher object, or NULL on error 132 */ 133 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, 134 QCryptoCipherMode mode, 135 const uint8_t *key, size_t nkey, 136 Error **errp); 137 138 /** 139 * qcrypto_cipher_free: 140 * @cipher: the cipher object 141 * 142 * Release the memory associated with @cipher that 143 * was previously allocated by qcrypto_cipher_new() 144 */ 145 void qcrypto_cipher_free(QCryptoCipher *cipher); 146 147 /** 148 * qcrypto_cipher_encrypt: 149 * @cipher: the cipher object 150 * @in: buffer holding the plain text input data 151 * @out: buffer to fill with the cipher text output data 152 * @len: the length of @in and @out buffers 153 * @errp: pointer to an uninitialized error object 154 * 155 * Encrypts the plain text stored in @in, filling 156 * @out with the resulting ciphered text. Both the 157 * @in and @out buffers must have the same size, 158 * given by @len. 159 * 160 * Returns: 0 on success, or -1 on error 161 */ 162 int qcrypto_cipher_encrypt(QCryptoCipher *cipher, 163 const void *in, 164 void *out, 165 size_t len, 166 Error **errp); 167 168 169 /** 170 * qcrypto_cipher_decrypt: 171 * @cipher: the cipher object 172 * @in: buffer holding the cipher text input data 173 * @out: buffer to fill with the plain text output data 174 * @len: the length of @in and @out buffers 175 * @errp: pointer to an uninitialized error object 176 * 177 * Decrypts the cipher text stored in @in, filling 178 * @out with the resulting plain text. Both the 179 * @in and @out buffers must have the same size, 180 * given by @len. 181 * 182 * Returns: 0 on success, or -1 on error 183 */ 184 int qcrypto_cipher_decrypt(QCryptoCipher *cipher, 185 const void *in, 186 void *out, 187 size_t len, 188 Error **errp); 189 190 /** 191 * qcrypto_cipher_setiv: 192 * @cipher: the cipher object 193 * @iv: the initialization vector bytes 194 * @niv: the length of @iv 195 * @errpr: pointer to an uninitialized error object 196 * 197 * If the @cipher object is setup to use a mode that requires 198 * initialization vectors, this sets the initialization vector 199 * bytes. The @iv data should have the same length as the 200 * cipher key used when originally constructing the cipher 201 * object. It is an error to set an initialization vector 202 * if the cipher mode does not require one. 203 * 204 * Returns: 0 on success, -1 on error 205 */ 206 int qcrypto_cipher_setiv(QCryptoCipher *cipher, 207 const uint8_t *iv, size_t niv, 208 Error **errp); 209 210 #endif /* QCRYPTO_CIPHER_H__ */ 211