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 * qcrypto_cipher_get_block_len: 112 * @alg: the cipher algorithm 113 * 114 * Get the required data block size in bytes. When 115 * encrypting data, it must be a multiple of the 116 * block size. 117 * 118 * Returns: the block size in bytes 119 */ 120 size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg); 121 122 123 /** 124 * qcrypto_cipher_get_key_len: 125 * @alg: the cipher algorithm 126 * 127 * Get the required key size in bytes. 128 * 129 * Returns: the key size in bytes 130 */ 131 size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg); 132 133 134 /** 135 * qcrypto_cipher_get_iv_len: 136 * @alg: the cipher algorithm 137 * @mode: the cipher mode 138 * 139 * Get the required initialization vector size 140 * in bytes, if one is required. 141 * 142 * Returns: the IV size in bytes, or 0 if no IV is permitted 143 */ 144 size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg, 145 QCryptoCipherMode mode); 146 147 148 /** 149 * qcrypto_cipher_new: 150 * @alg: the cipher algorithm 151 * @mode: the cipher usage mode 152 * @key: the private key bytes 153 * @nkey: the length of @key 154 * @errp: pointer to an uninitialized error object 155 * 156 * Creates a new cipher object for encrypting/decrypting 157 * data with the algorithm @alg in the usage mode @mode. 158 * 159 * The @key parameter provides the bytes representing 160 * the encryption/decryption key to use. The @nkey parameter 161 * specifies the length of @key in bytes. Each algorithm has 162 * one or more valid key lengths, and it is an error to provide 163 * a key of the incorrect length. 164 * 165 * The returned cipher object must be released with 166 * qcrypto_cipher_free() when no longer required 167 * 168 * Returns: a new cipher object, or NULL on error 169 */ 170 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, 171 QCryptoCipherMode mode, 172 const uint8_t *key, size_t nkey, 173 Error **errp); 174 175 /** 176 * qcrypto_cipher_free: 177 * @cipher: the cipher object 178 * 179 * Release the memory associated with @cipher that 180 * was previously allocated by qcrypto_cipher_new() 181 */ 182 void qcrypto_cipher_free(QCryptoCipher *cipher); 183 184 /** 185 * qcrypto_cipher_encrypt: 186 * @cipher: the cipher object 187 * @in: buffer holding the plain text input data 188 * @out: buffer to fill with the cipher text output data 189 * @len: the length of @in and @out buffers 190 * @errp: pointer to an uninitialized error object 191 * 192 * Encrypts the plain text stored in @in, filling 193 * @out with the resulting ciphered text. Both the 194 * @in and @out buffers must have the same size, 195 * given by @len. 196 * 197 * Returns: 0 on success, or -1 on error 198 */ 199 int qcrypto_cipher_encrypt(QCryptoCipher *cipher, 200 const void *in, 201 void *out, 202 size_t len, 203 Error **errp); 204 205 206 /** 207 * qcrypto_cipher_decrypt: 208 * @cipher: the cipher object 209 * @in: buffer holding the cipher text input data 210 * @out: buffer to fill with the plain text output data 211 * @len: the length of @in and @out buffers 212 * @errp: pointer to an uninitialized error object 213 * 214 * Decrypts the cipher text stored in @in, filling 215 * @out with the resulting plain text. Both the 216 * @in and @out buffers must have the same size, 217 * given by @len. 218 * 219 * Returns: 0 on success, or -1 on error 220 */ 221 int qcrypto_cipher_decrypt(QCryptoCipher *cipher, 222 const void *in, 223 void *out, 224 size_t len, 225 Error **errp); 226 227 /** 228 * qcrypto_cipher_setiv: 229 * @cipher: the cipher object 230 * @iv: the initialization vector bytes 231 * @niv: the length of @iv 232 * @errpr: pointer to an uninitialized error object 233 * 234 * If the @cipher object is setup to use a mode that requires 235 * initialization vectors, this sets the initialization vector 236 * bytes. The @iv data should have the same length as the 237 * cipher key used when originally constructing the cipher 238 * object. It is an error to set an initialization vector 239 * if the cipher mode does not require one. 240 * 241 * Returns: 0 on success, -1 on error 242 */ 243 int qcrypto_cipher_setiv(QCryptoCipher *cipher, 244 const uint8_t *iv, size_t niv, 245 Error **errp); 246 247 #endif /* QCRYPTO_CIPHER_H__ */ 248