1ca38a4ccSDaniel P. Berrange /* 2ca38a4ccSDaniel P. Berrange * QEMU Crypto cipher algorithms 3ca38a4ccSDaniel P. Berrange * 4ca38a4ccSDaniel P. Berrange * Copyright (c) 2015 Red Hat, Inc. 5ca38a4ccSDaniel P. Berrange * 6ca38a4ccSDaniel P. Berrange * This library is free software; you can redistribute it and/or 7ca38a4ccSDaniel P. Berrange * modify it under the terms of the GNU Lesser General Public 8ca38a4ccSDaniel P. Berrange * License as published by the Free Software Foundation; either 9b7cbb874SThomas Huth * version 2.1 of the License, or (at your option) any later version. 10ca38a4ccSDaniel P. Berrange * 11ca38a4ccSDaniel P. Berrange * This library is distributed in the hope that it will be useful, 12ca38a4ccSDaniel P. Berrange * but WITHOUT ANY WARRANTY; without even the implied warranty of 13ca38a4ccSDaniel P. Berrange * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14ca38a4ccSDaniel P. Berrange * Lesser General Public License for more details. 15ca38a4ccSDaniel P. Berrange * 16ca38a4ccSDaniel P. Berrange * You should have received a copy of the GNU Lesser General Public 17ca38a4ccSDaniel P. Berrange * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18ca38a4ccSDaniel P. Berrange * 19ca38a4ccSDaniel P. Berrange */ 20ca38a4ccSDaniel P. Berrange 212a6a4076SMarkus Armbruster #ifndef QCRYPTO_CIPHER_H 222a6a4076SMarkus Armbruster #define QCRYPTO_CIPHER_H 23ca38a4ccSDaniel P. Berrange 249af23989SMarkus Armbruster #include "qapi/qapi-types-crypto.h" 25ca38a4ccSDaniel P. Berrange 26ca38a4ccSDaniel P. Berrange typedef struct QCryptoCipher QCryptoCipher; 27954721ffSRichard Henderson typedef struct QCryptoCipherDriver QCryptoCipherDriver; 28ca38a4ccSDaniel P. Berrange 29*a092c513SMarkus Armbruster /* See also "QCryptoCipherAlgo" and "QCryptoCipherMode" 30d8c02bccSDaniel P. Berrange * enums defined in qapi/crypto.json */ 31ca38a4ccSDaniel P. Berrange 32ca38a4ccSDaniel P. Berrange /** 33ca38a4ccSDaniel P. Berrange * QCryptoCipher: 34ca38a4ccSDaniel P. Berrange * 35ca38a4ccSDaniel P. Berrange * The QCryptoCipher object provides a way to perform encryption 36ca38a4ccSDaniel P. Berrange * and decryption of data, with a standard API, regardless of the 37ca38a4ccSDaniel P. Berrange * algorithm used. It further isolates the calling code from the 38ca38a4ccSDaniel P. Berrange * details of the specific underlying implementation, whether 39ca38a4ccSDaniel P. Berrange * built-in, libgcrypt or nettle. 40ca38a4ccSDaniel P. Berrange * 41ca38a4ccSDaniel P. Berrange * Each QCryptoCipher object is capable of performing both 42ca38a4ccSDaniel P. Berrange * encryption and decryption, and can operate in a number 43ca38a4ccSDaniel P. Berrange * or modes including ECB, CBC. 44ca38a4ccSDaniel P. Berrange * 45ca38a4ccSDaniel P. Berrange * <example> 46ca38a4ccSDaniel P. Berrange * <title>Encrypting data with AES-128 in CBC mode</title> 47ca38a4ccSDaniel P. Berrange * <programlisting> 48ca38a4ccSDaniel P. Berrange * QCryptoCipher *cipher; 49ca38a4ccSDaniel P. Berrange * uint8_t key = ....; 50ca38a4ccSDaniel P. Berrange * size_t keylen = 16; 51ca38a4ccSDaniel P. Berrange * uint8_t iv = ....; 52ca38a4ccSDaniel P. Berrange * 53*a092c513SMarkus Armbruster * if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALGO_AES_128)) { 54ca38a4ccSDaniel P. Berrange * error_report(errp, "Feature <blah> requires AES cipher support"); 55ca38a4ccSDaniel P. Berrange * return -1; 56ca38a4ccSDaniel P. Berrange * } 57ca38a4ccSDaniel P. Berrange * 58*a092c513SMarkus Armbruster * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128, 59ca38a4ccSDaniel P. Berrange * QCRYPTO_CIPHER_MODE_CBC, 60ca38a4ccSDaniel P. Berrange * key, keylen, 61ca38a4ccSDaniel P. Berrange * errp); 62ca38a4ccSDaniel P. Berrange * if (!cipher) { 63ca38a4ccSDaniel P. Berrange * return -1; 64ca38a4ccSDaniel P. Berrange * } 65ca38a4ccSDaniel P. Berrange * 66ca38a4ccSDaniel P. Berrange * if (qcrypto_cipher_set_iv(cipher, iv, keylen, errp) < 0) { 67ca38a4ccSDaniel P. Berrange * return -1; 68ca38a4ccSDaniel P. Berrange * } 69ca38a4ccSDaniel P. Berrange * 70ca38a4ccSDaniel P. Berrange * if (qcrypto_cipher_encrypt(cipher, rawdata, encdata, datalen, errp) < 0) { 71ca38a4ccSDaniel P. Berrange * return -1; 72ca38a4ccSDaniel P. Berrange * } 73ca38a4ccSDaniel P. Berrange * 74ca38a4ccSDaniel P. Berrange * qcrypto_cipher_free(cipher); 75ca38a4ccSDaniel P. Berrange * </programlisting> 76ca38a4ccSDaniel P. Berrange * </example> 77ca38a4ccSDaniel P. Berrange * 78ca38a4ccSDaniel P. Berrange */ 79ca38a4ccSDaniel P. Berrange 80ca38a4ccSDaniel P. Berrange struct QCryptoCipher { 81*a092c513SMarkus Armbruster QCryptoCipherAlgo alg; 82ca38a4ccSDaniel P. Berrange QCryptoCipherMode mode; 837b5dbfb7SRichard Henderson const QCryptoCipherDriver *driver; 84ca38a4ccSDaniel P. Berrange }; 85ca38a4ccSDaniel P. Berrange 86ca38a4ccSDaniel P. Berrange /** 87ca38a4ccSDaniel P. Berrange * qcrypto_cipher_supports: 88ca38a4ccSDaniel P. Berrange * @alg: the cipher algorithm 89f844836dSGonglei * @mode: the cipher mode 90ca38a4ccSDaniel P. Berrange * 91f844836dSGonglei * Determine if @alg cipher algorithm in @mode is supported by the 92ca38a4ccSDaniel P. Berrange * current configured build 93ca38a4ccSDaniel P. Berrange * 94ca38a4ccSDaniel P. Berrange * Returns: true if the algorithm is supported, false otherwise 95ca38a4ccSDaniel P. Berrange */ 96*a092c513SMarkus Armbruster bool qcrypto_cipher_supports(QCryptoCipherAlgo alg, 97f844836dSGonglei QCryptoCipherMode mode); 98ca38a4ccSDaniel P. Berrange 99dd2bf9ebSDaniel P. Berrange /** 100dd2bf9ebSDaniel P. Berrange * qcrypto_cipher_get_block_len: 101dd2bf9ebSDaniel P. Berrange * @alg: the cipher algorithm 102dd2bf9ebSDaniel P. Berrange * 103dd2bf9ebSDaniel P. Berrange * Get the required data block size in bytes. When 104dd2bf9ebSDaniel P. Berrange * encrypting data, it must be a multiple of the 105dd2bf9ebSDaniel P. Berrange * block size. 106dd2bf9ebSDaniel P. Berrange * 107dd2bf9ebSDaniel P. Berrange * Returns: the block size in bytes 108dd2bf9ebSDaniel P. Berrange */ 109*a092c513SMarkus Armbruster size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgo alg); 110dd2bf9ebSDaniel P. Berrange 111dd2bf9ebSDaniel P. Berrange 112dd2bf9ebSDaniel P. Berrange /** 113dd2bf9ebSDaniel P. Berrange * qcrypto_cipher_get_key_len: 114dd2bf9ebSDaniel P. Berrange * @alg: the cipher algorithm 115dd2bf9ebSDaniel P. Berrange * 116dd2bf9ebSDaniel P. Berrange * Get the required key size in bytes. 117dd2bf9ebSDaniel P. Berrange * 118dd2bf9ebSDaniel P. Berrange * Returns: the key size in bytes 119dd2bf9ebSDaniel P. Berrange */ 120*a092c513SMarkus Armbruster size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgo alg); 121dd2bf9ebSDaniel P. Berrange 122dd2bf9ebSDaniel P. Berrange 123dd2bf9ebSDaniel P. Berrange /** 124dd2bf9ebSDaniel P. Berrange * qcrypto_cipher_get_iv_len: 125dd2bf9ebSDaniel P. Berrange * @alg: the cipher algorithm 126dd2bf9ebSDaniel P. Berrange * @mode: the cipher mode 127dd2bf9ebSDaniel P. Berrange * 128dd2bf9ebSDaniel P. Berrange * Get the required initialization vector size 129dd2bf9ebSDaniel P. Berrange * in bytes, if one is required. 130dd2bf9ebSDaniel P. Berrange * 131dd2bf9ebSDaniel P. Berrange * Returns: the IV size in bytes, or 0 if no IV is permitted 132dd2bf9ebSDaniel P. Berrange */ 133*a092c513SMarkus Armbruster size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgo alg, 134dd2bf9ebSDaniel P. Berrange QCryptoCipherMode mode); 135dd2bf9ebSDaniel P. Berrange 136ca38a4ccSDaniel P. Berrange 137ca38a4ccSDaniel P. Berrange /** 138ca38a4ccSDaniel P. Berrange * qcrypto_cipher_new: 139ca38a4ccSDaniel P. Berrange * @alg: the cipher algorithm 140ca38a4ccSDaniel P. Berrange * @mode: the cipher usage mode 141ca38a4ccSDaniel P. Berrange * @key: the private key bytes 142ca38a4ccSDaniel P. Berrange * @nkey: the length of @key 14307982d2eSDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 144ca38a4ccSDaniel P. Berrange * 145ca38a4ccSDaniel P. Berrange * Creates a new cipher object for encrypting/decrypting 146ca38a4ccSDaniel P. Berrange * data with the algorithm @alg in the usage mode @mode. 147ca38a4ccSDaniel P. Berrange * 148ca38a4ccSDaniel P. Berrange * The @key parameter provides the bytes representing 149ca38a4ccSDaniel P. Berrange * the encryption/decryption key to use. The @nkey parameter 150ca38a4ccSDaniel P. Berrange * specifies the length of @key in bytes. Each algorithm has 151ca38a4ccSDaniel P. Berrange * one or more valid key lengths, and it is an error to provide 152ca38a4ccSDaniel P. Berrange * a key of the incorrect length. 153ca38a4ccSDaniel P. Berrange * 154ca38a4ccSDaniel P. Berrange * The returned cipher object must be released with 155ca38a4ccSDaniel P. Berrange * qcrypto_cipher_free() when no longer required 156ca38a4ccSDaniel P. Berrange * 157ca38a4ccSDaniel P. Berrange * Returns: a new cipher object, or NULL on error 158ca38a4ccSDaniel P. Berrange */ 159*a092c513SMarkus Armbruster QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgo alg, 160ca38a4ccSDaniel P. Berrange QCryptoCipherMode mode, 161ca38a4ccSDaniel P. Berrange const uint8_t *key, size_t nkey, 162ca38a4ccSDaniel P. Berrange Error **errp); 163ca38a4ccSDaniel P. Berrange 164ca38a4ccSDaniel P. Berrange /** 165ca38a4ccSDaniel P. Berrange * qcrypto_cipher_free: 166ca38a4ccSDaniel P. Berrange * @cipher: the cipher object 167ca38a4ccSDaniel P. Berrange * 168ca38a4ccSDaniel P. Berrange * Release the memory associated with @cipher that 169ca38a4ccSDaniel P. Berrange * was previously allocated by qcrypto_cipher_new() 170ca38a4ccSDaniel P. Berrange */ 171ca38a4ccSDaniel P. Berrange void qcrypto_cipher_free(QCryptoCipher *cipher); 172ca38a4ccSDaniel P. Berrange 173133cf1e5SDaniel P. Berrangé G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoCipher, qcrypto_cipher_free) 174133cf1e5SDaniel P. Berrangé 175ca38a4ccSDaniel P. Berrange /** 176ca38a4ccSDaniel P. Berrange * qcrypto_cipher_encrypt: 177ca38a4ccSDaniel P. Berrange * @cipher: the cipher object 178ca38a4ccSDaniel P. Berrange * @in: buffer holding the plain text input data 179ca38a4ccSDaniel P. Berrange * @out: buffer to fill with the cipher text output data 180ca38a4ccSDaniel P. Berrange * @len: the length of @in and @out buffers 18107982d2eSDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 182ca38a4ccSDaniel P. Berrange * 183ca38a4ccSDaniel P. Berrange * Encrypts the plain text stored in @in, filling 184ca38a4ccSDaniel P. Berrange * @out with the resulting ciphered text. Both the 185ca38a4ccSDaniel P. Berrange * @in and @out buffers must have the same size, 186ca38a4ccSDaniel P. Berrange * given by @len. 187ca38a4ccSDaniel P. Berrange * 188ca38a4ccSDaniel P. Berrange * Returns: 0 on success, or -1 on error 189ca38a4ccSDaniel P. Berrange */ 190ca38a4ccSDaniel P. Berrange int qcrypto_cipher_encrypt(QCryptoCipher *cipher, 191ca38a4ccSDaniel P. Berrange const void *in, 192ca38a4ccSDaniel P. Berrange void *out, 193ca38a4ccSDaniel P. Berrange size_t len, 194ca38a4ccSDaniel P. Berrange Error **errp); 195ca38a4ccSDaniel P. Berrange 196ca38a4ccSDaniel P. Berrange 197ca38a4ccSDaniel P. Berrange /** 198ca38a4ccSDaniel P. Berrange * qcrypto_cipher_decrypt: 199ca38a4ccSDaniel P. Berrange * @cipher: the cipher object 200ca38a4ccSDaniel P. Berrange * @in: buffer holding the cipher text input data 201ca38a4ccSDaniel P. Berrange * @out: buffer to fill with the plain text output data 202ca38a4ccSDaniel P. Berrange * @len: the length of @in and @out buffers 20307982d2eSDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 204ca38a4ccSDaniel P. Berrange * 205ca38a4ccSDaniel P. Berrange * Decrypts the cipher text stored in @in, filling 206ca38a4ccSDaniel P. Berrange * @out with the resulting plain text. Both the 207ca38a4ccSDaniel P. Berrange * @in and @out buffers must have the same size, 208ca38a4ccSDaniel P. Berrange * given by @len. 209ca38a4ccSDaniel P. Berrange * 210ca38a4ccSDaniel P. Berrange * Returns: 0 on success, or -1 on error 211ca38a4ccSDaniel P. Berrange */ 212ca38a4ccSDaniel P. Berrange int qcrypto_cipher_decrypt(QCryptoCipher *cipher, 213ca38a4ccSDaniel P. Berrange const void *in, 214ca38a4ccSDaniel P. Berrange void *out, 215ca38a4ccSDaniel P. Berrange size_t len, 216ca38a4ccSDaniel P. Berrange Error **errp); 217ca38a4ccSDaniel P. Berrange 218ca38a4ccSDaniel P. Berrange /** 219ca38a4ccSDaniel P. Berrange * qcrypto_cipher_setiv: 220ca38a4ccSDaniel P. Berrange * @cipher: the cipher object 2213c28292fSGonglei * @iv: the initialization vector or counter (CTR mode) bytes 222ca38a4ccSDaniel P. Berrange * @niv: the length of @iv 22307982d2eSDaniel P. Berrange * @errpr: pointer to a NULL-initialized error object 224ca38a4ccSDaniel P. Berrange * 225ca38a4ccSDaniel P. Berrange * If the @cipher object is setup to use a mode that requires 2263c28292fSGonglei * initialization vectors or counter, this sets the @niv 227ca38a4ccSDaniel P. Berrange * bytes. The @iv data should have the same length as the 228ca38a4ccSDaniel P. Berrange * cipher key used when originally constructing the cipher 229ca38a4ccSDaniel P. Berrange * object. It is an error to set an initialization vector 2303c28292fSGonglei * or counter if the cipher mode does not require one. 231ca38a4ccSDaniel P. Berrange * 232ca38a4ccSDaniel P. Berrange * Returns: 0 on success, -1 on error 233ca38a4ccSDaniel P. Berrange */ 234ca38a4ccSDaniel P. Berrange int qcrypto_cipher_setiv(QCryptoCipher *cipher, 235ca38a4ccSDaniel P. Berrange const uint8_t *iv, size_t niv, 236ca38a4ccSDaniel P. Berrange Error **errp); 237ca38a4ccSDaniel P. Berrange 2382a6a4076SMarkus Armbruster #endif /* QCRYPTO_CIPHER_H */ 239