| /* | |
| * QEMU Crypto cipher 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 | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * 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/>. | |
| * | |
| */ | |
| #ifndef QCRYPTO_CIPHER_H | |
| #define QCRYPTO_CIPHER_H | |
| #include "qapi/qapi-types-crypto.h" | |
| typedef struct QCryptoCipher QCryptoCipher; | |
| typedef struct QCryptoCipherDriver QCryptoCipherDriver; | |
| /* See also "QCryptoCipherAlgo" and "QCryptoCipherMode" | |
| * enums defined in qapi/crypto.json */ | |
| /** | |
| * QCryptoCipher: | |
| * | |
| * The QCryptoCipher object provides a way to perform encryption | |
| * and decryption of data, with a standard API, regardless of the | |
| * algorithm used. It further isolates the calling code from the | |
| * details of the specific underlying implementation, whether | |
| * built-in, libgcrypt or nettle. | |
| * | |
| * Each QCryptoCipher object is capable of performing both | |
| * encryption and decryption, and can operate in a number | |
| * or modes including ECB, CBC. | |
| * | |
| * <example> | |
| * <title>Encrypting data with AES-128 in CBC mode</title> | |
| * <programlisting> | |
| * QCryptoCipher *cipher; | |
| * uint8_t key = ....; | |
| * size_t keylen = 16; | |
| * uint8_t iv = ....; | |
| * | |
| * if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALGO_AES_128)) { | |
| * error_report(errp, "Feature <blah> requires AES cipher support"); | |
| * return -1; | |
| * } | |
| * | |
| * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128, | |
| * QCRYPTO_CIPHER_MODE_CBC, | |
| * key, keylen, | |
| * errp); | |
| * if (!cipher) { | |
| * return -1; | |
| * } | |
| * | |
| * if (qcrypto_cipher_set_iv(cipher, iv, keylen, errp) < 0) { | |
| * return -1; | |
| * } | |
| * | |
| * if (qcrypto_cipher_encrypt(cipher, rawdata, encdata, datalen, errp) < 0) { | |
| * return -1; | |
| * } | |
| * | |
| * qcrypto_cipher_free(cipher); | |
| * </programlisting> | |
| * </example> | |
| * | |
| */ | |
| struct QCryptoCipher { | |
| QCryptoCipherAlgo alg; | |
| QCryptoCipherMode mode; | |
| const QCryptoCipherDriver *driver; | |
| }; | |
| /** | |
| * qcrypto_cipher_supports: | |
| * @alg: the cipher algorithm | |
| * @mode: the cipher mode | |
| * | |
| * Determine if @alg cipher algorithm in @mode is supported by the | |
| * current configured build | |
| * | |
| * Returns: true if the algorithm is supported, false otherwise | |
| */ | |
| bool qcrypto_cipher_supports(QCryptoCipherAlgo alg, | |
| QCryptoCipherMode mode); | |
| /** | |
| * qcrypto_cipher_get_block_len: | |
| * @alg: the cipher algorithm | |
| * | |
| * Get the required data block size in bytes. When | |
| * encrypting data, it must be a multiple of the | |
| * block size. | |
| * | |
| * Returns: the block size in bytes | |
| */ | |
| size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgo alg); | |
| /** | |
| * qcrypto_cipher_get_key_len: | |
| * @alg: the cipher algorithm | |
| * | |
| * Get the required key size in bytes. | |
| * | |
| * Returns: the key size in bytes | |
| */ | |
| size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgo alg); | |
| /** | |
| * qcrypto_cipher_get_iv_len: | |
| * @alg: the cipher algorithm | |
| * @mode: the cipher mode | |
| * | |
| * Get the required initialization vector size | |
| * in bytes, if one is required. | |
| * | |
| * Returns: the IV size in bytes, or 0 if no IV is permitted | |
| */ | |
| size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgo alg, | |
| QCryptoCipherMode mode); | |
| /** | |
| * qcrypto_cipher_new: | |
| * @alg: the cipher algorithm | |
| * @mode: the cipher usage mode | |
| * @key: the private key bytes | |
| * @nkey: the length of @key | |
| * @errp: pointer to a NULL-initialized error object | |
| * | |
| * Creates a new cipher object for encrypting/decrypting | |
| * data with the algorithm @alg in the usage mode @mode. | |
| * | |
| * The @key parameter provides the bytes representing | |
| * the encryption/decryption key to use. The @nkey parameter | |
| * specifies the length of @key in bytes. Each algorithm has | |
| * one or more valid key lengths, and it is an error to provide | |
| * a key of the incorrect length. | |
| * | |
| * The returned cipher object must be released with | |
| * qcrypto_cipher_free() when no longer required | |
| * | |
| * Returns: a new cipher object, or NULL on error | |
| */ | |
| QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgo alg, | |
| QCryptoCipherMode mode, | |
| const uint8_t *key, size_t nkey, | |
| Error **errp); | |
| /** | |
| * qcrypto_cipher_free: | |
| * @cipher: the cipher object | |
| * | |
| * Release the memory associated with @cipher that | |
| * was previously allocated by qcrypto_cipher_new() | |
| */ | |
| void qcrypto_cipher_free(QCryptoCipher *cipher); | |
| G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoCipher, qcrypto_cipher_free) | |
| /** | |
| * qcrypto_cipher_encrypt: | |
| * @cipher: the cipher object | |
| * @in: buffer holding the plain text input data | |
| * @out: buffer to fill with the cipher text output data | |
| * @len: the length of @in and @out buffers | |
| * @errp: pointer to a NULL-initialized error object | |
| * | |
| * Encrypts the plain text stored in @in, filling | |
| * @out with the resulting ciphered text. Both the | |
| * @in and @out buffers must have the same size, | |
| * given by @len. | |
| * | |
| * Returns: 0 on success, or -1 on error | |
| */ | |
| int qcrypto_cipher_encrypt(QCryptoCipher *cipher, | |
| const void *in, | |
| void *out, | |
| size_t len, | |
| Error **errp); | |
| /** | |
| * qcrypto_cipher_decrypt: | |
| * @cipher: the cipher object | |
| * @in: buffer holding the cipher text input data | |
| * @out: buffer to fill with the plain text output data | |
| * @len: the length of @in and @out buffers | |
| * @errp: pointer to a NULL-initialized error object | |
| * | |
| * Decrypts the cipher text stored in @in, filling | |
| * @out with the resulting plain text. Both the | |
| * @in and @out buffers must have the same size, | |
| * given by @len. | |
| * | |
| * Returns: 0 on success, or -1 on error | |
| */ | |
| int qcrypto_cipher_decrypt(QCryptoCipher *cipher, | |
| const void *in, | |
| void *out, | |
| size_t len, | |
| Error **errp); | |
| /** | |
| * qcrypto_cipher_setiv: | |
| * @cipher: the cipher object | |
| * @iv: the initialization vector or counter (CTR mode) bytes | |
| * @niv: the length of @iv | |
| * @errpr: pointer to a NULL-initialized error object | |
| * | |
| * If the @cipher object is setup to use a mode that requires | |
| * initialization vectors or counter, this sets the @niv | |
| * bytes. The @iv data should have the same length as the | |
| * cipher key used when originally constructing the cipher | |
| * object. It is an error to set an initialization vector | |
| * or counter if the cipher mode does not require one. | |
| * | |
| * Returns: 0 on success, -1 on error | |
| */ | |
| int qcrypto_cipher_setiv(QCryptoCipher *cipher, | |
| const uint8_t *iv, size_t niv, | |
| Error **errp); | |
| /** | |
| * qcrypto_cipher_setaad: | |
| * @cipher: the cipher object | |
| * @aad: the associated data to authenticate | |
| * @len: the length of @aad | |
| * @errp: pointer to a NULL-initialized error object | |
| * | |
| * For AEAD modes such as GCM, feed the associated data (AAD) that is | |
| * authenticated but not encrypted. It must be called after | |
| * qcrypto_cipher_setiv() and before the first encrypt/decrypt call. It is | |
| * an error to call this on a mode that is not an AEAD mode. | |
| * | |
| * Returns: 0 on success, -1 on error | |
| */ | |
| int qcrypto_cipher_setaad(QCryptoCipher *cipher, | |
| const uint8_t *aad, size_t len, | |
| Error **errp); | |
| /** | |
| * qcrypto_cipher_gettag: | |
| * @cipher: the cipher object | |
| * @tag: buffer to receive the authentication tag | |
| * @len: the length of @tag | |
| * @errp: pointer to a NULL-initialized error object | |
| * | |
| * For AEAD modes such as GCM, read back the authentication tag computed | |
| * over the associated data and the message. It must be called after the | |
| * encrypt/decrypt operation. It is an error to call this on a mode that is | |
| * not an AEAD mode. | |
| * | |
| * Returns: 0 on success, -1 on error | |
| */ | |
| int qcrypto_cipher_gettag(QCryptoCipher *cipher, | |
| uint8_t *tag, size_t len, | |
| Error **errp); | |
| #endif /* QCRYPTO_CIPHER_H */ |