| /* |
| * 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); |
| |
| #endif /* QCRYPTO_CIPHER_H */ |