diff options
Diffstat (limited to 'qemu/include/crypto')
-rw-r--r-- | qemu/include/crypto/aes.h | 68 | ||||
-rw-r--r-- | qemu/include/crypto/cipher.h | 210 | ||||
-rw-r--r-- | qemu/include/crypto/desrfb.h | 49 | ||||
-rw-r--r-- | qemu/include/crypto/hash.h | 189 | ||||
-rw-r--r-- | qemu/include/crypto/init.h | 29 |
5 files changed, 545 insertions, 0 deletions
diff --git a/qemu/include/crypto/aes.h b/qemu/include/crypto/aes.h new file mode 100644 index 000000000..a006da222 --- /dev/null +++ b/qemu/include/crypto/aes.h @@ -0,0 +1,68 @@ +#ifndef QEMU_AES_H +#define QEMU_AES_H + +#define AES_MAXNR 14 +#define AES_BLOCK_SIZE 16 + +struct aes_key_st { + uint32_t rd_key[4 *(AES_MAXNR + 1)]; + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +/* FreeBSD has its own AES_set_decrypt_key in -lcrypto, avoid conflicts */ +#ifdef __FreeBSD__ +#define AES_set_encrypt_key QEMU_AES_set_encrypt_key +#define AES_set_decrypt_key QEMU_AES_set_decrypt_key +#define AES_encrypt QEMU_AES_encrypt +#define AES_decrypt QEMU_AES_decrypt +#define AES_cbc_encrypt QEMU_AES_cbc_encrypt +#endif + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + const unsigned long length, const AES_KEY *key, + unsigned char *ivec, const int enc); + +extern const uint8_t AES_sbox[256]; +extern const uint8_t AES_isbox[256]; + +/* AES ShiftRows and InvShiftRows */ +extern const uint8_t AES_shifts[16]; +extern const uint8_t AES_ishifts[16]; + +/* AES InvMixColumns */ +/* AES_imc[x][0] = [x].[0e, 09, 0d, 0b]; */ +/* AES_imc[x][1] = [x].[0b, 0e, 09, 0d]; */ +/* AES_imc[x][2] = [x].[0d, 0b, 0e, 09]; */ +/* AES_imc[x][3] = [x].[09, 0d, 0b, 0e]; */ +extern const uint32_t AES_imc[256][4]; + +/* +AES_Te0[x] = S [x].[02, 01, 01, 03]; +AES_Te1[x] = S [x].[03, 02, 01, 01]; +AES_Te2[x] = S [x].[01, 03, 02, 01]; +AES_Te3[x] = S [x].[01, 01, 03, 02]; +AES_Te4[x] = S [x].[01, 01, 01, 01]; + +AES_Td0[x] = Si[x].[0e, 09, 0d, 0b]; +AES_Td1[x] = Si[x].[0b, 0e, 09, 0d]; +AES_Td2[x] = Si[x].[0d, 0b, 0e, 09]; +AES_Td3[x] = Si[x].[09, 0d, 0b, 0e]; +AES_Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +extern const uint32_t AES_Te0[256], AES_Te1[256], AES_Te2[256], + AES_Te3[256], AES_Te4[256]; +extern const uint32_t AES_Td0[256], AES_Td1[256], AES_Td2[256], + AES_Td3[256], AES_Td4[256]; + +#endif diff --git a/qemu/include/crypto/cipher.h b/qemu/include/crypto/cipher.h new file mode 100644 index 000000000..b4d714f26 --- /dev/null +++ b/qemu/include/crypto/cipher.h @@ -0,0 +1,210 @@ +/* + * 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 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 "qemu-common.h" +#include "qapi/error.h" + +typedef struct QCryptoCipher QCryptoCipher; + +typedef enum { + QCRYPTO_CIPHER_ALG_AES_128, + QCRYPTO_CIPHER_ALG_AES_192, + QCRYPTO_CIPHER_ALG_AES_256, + QCRYPTO_CIPHER_ALG_DES_RFB, /* A stupid variant on DES for VNC */ + + QCRYPTO_CIPHER_ALG_LAST +} QCryptoCipherAlgorithm; + +typedef enum { + QCRYPTO_CIPHER_MODE_ECB, + QCRYPTO_CIPHER_MODE_CBC, + + QCRYPTO_CIPHER_MODE_LAST +} QCryptoCipherMode; + +/** + * 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_ALG_AES_128)) { + * error_report(errp, "Feature <blah> requires AES cipher support"); + * return -1; + * } + * + * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_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 { + QCryptoCipherAlgorithm alg; + QCryptoCipherMode mode; + void *opaque; +}; + +/** + * qcrypto_cipher_supports: + * @alg: the cipher algorithm + * + * Determine if @alg cipher algorithm is supported by the + * current configured build + * + * Returns: true if the algorithm is supported, false otherwise + */ +bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg); + + +/** + * 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 an uninitialized 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(QCryptoCipherAlgorithm 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); + +/** + * 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 an uninitialized 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 an uninitialized 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 bytes + * @niv: the length of @iv + * @errpr: pointer to an uninitialized error object + * + * If the @cipher object is setup to use a mode that requires + * initialization vectors, this sets the initialization vector + * 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 + * 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__ */ diff --git a/qemu/include/crypto/desrfb.h b/qemu/include/crypto/desrfb.h new file mode 100644 index 000000000..773667ee7 --- /dev/null +++ b/qemu/include/crypto/desrfb.h @@ -0,0 +1,49 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC. + * + * These changes are: + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This software 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. + */ +#ifndef D3DES_H +#define D3DES_H 1 + +/* d3des.h - + * + * Headers and defines for d3des.c + * Graven Imagery, 1992. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge + * (GEnie : OUTER; CIS : [71755,204]) + */ + +#define EN0 0 /* MODE == encrypt */ +#define DE1 1 /* MODE == decrypt */ + +void deskey(unsigned char *, int); +/* hexkey[8] MODE + * Sets the internal key register according to the hexadecimal + * key contained in the 8 bytes of hexkey, according to the DES, + * for encryption or decryption according to MODE. + */ + +void usekey(unsigned long *); +/* cookedkey[32] + * Loads the internal key register with the data in cookedkey. + */ + +void des(unsigned char *, unsigned char *); +/* from[8] to[8] + * Encrypts/Decrypts (according to the key currently loaded in the + * internal key register) one block of eight bytes at address 'from' + * into the block at address 'to'. They can be the same. + */ + +/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery + ********************************************************************/ + +#endif diff --git a/qemu/include/crypto/hash.h b/qemu/include/crypto/hash.h new file mode 100644 index 000000000..b5acbf638 --- /dev/null +++ b/qemu/include/crypto/hash.h @@ -0,0 +1,189 @@ +/* + * QEMU Crypto hash 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 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_HASH_H__ +#define QCRYPTO_HASH_H__ + +#include "qemu-common.h" +#include "qapi/error.h" + +typedef enum { + QCRYPTO_HASH_ALG_MD5, + QCRYPTO_HASH_ALG_SHA1, + QCRYPTO_HASH_ALG_SHA256, + + QCRYPTO_HASH_ALG_LAST +} QCryptoHashAlgorithm; + + +/** + * qcrypto_hash_supports: + * @alg: the hash algorithm + * + * Determine if @alg hash algorithm is supported by the + * current configured build. + * + * Returns: true if the algorithm is supported, false otherwise + */ +gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg); + +/** + * qcrypto_hash_bytesv: + * @alg: the hash algorithm + * @iov: the array of memory regions to hash + * @niov: the length of @iov + * @result: pointer to hold output hash + * @resultlen: pointer to hold length of @result + * @errp: pointer to uninitialized error object + * + * Computes the hash across all the memory regions + * present in @iov. The @result pointer will be + * filled with raw bytes representing the computed + * hash, which will have length @resultlen. The + * memory pointer in @result must be released + * with a call to g_free() when no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg, + const struct iovec *iov, + size_t niov, + uint8_t **result, + size_t *resultlen, + Error **errp); + +/** + * qcrypto_hash_bytes: + * @alg: the hash algorithm + * @buf: the memory region to hash + * @len: the length of @buf + * @result: pointer to hold output hash + * @resultlen: pointer to hold length of @result + * @errp: pointer to uninitialized error object + * + * Computes the hash across all the memory region + * @buf of length @len. The @result pointer will be + * filled with raw bytes representing the computed + * hash, which will have length @resultlen. The + * memory pointer in @result must be released + * with a call to g_free() when no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_bytes(QCryptoHashAlgorithm alg, + const char *buf, + size_t len, + uint8_t **result, + size_t *resultlen, + Error **errp); + +/** + * qcrypto_hash_digestv: + * @alg: the hash algorithm + * @iov: the array of memory regions to hash + * @niov: the length of @iov + * @digest: pointer to hold output hash + * @errp: pointer to uninitialized error object + * + * Computes the hash across all the memory regions + * present in @iov. The @digest pointer will be + * filled with the printable hex digest of the computed + * hash, which will be terminated by '\0'. The + * memory pointer in @digest must be released + * with a call to g_free() when no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_digestv(QCryptoHashAlgorithm alg, + const struct iovec *iov, + size_t niov, + char **digest, + Error **errp); + +/** + * qcrypto_hash_digest: + * @alg: the hash algorithm + * @buf: the memory region to hash + * @len: the length of @buf + * @digest: pointer to hold output hash + * @errp: pointer to uninitialized error object + * + * Computes the hash across all the memory region + * @buf of length @len. The @digest pointer will be + * filled with the printable hex digest of the computed + * hash, which will be terminated by '\0'. The + * memory pointer in @digest must be released + * with a call to g_free() when no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_digest(QCryptoHashAlgorithm alg, + const char *buf, + size_t len, + char **digest, + Error **errp); + +/** + * qcrypto_hash_base64v: + * @alg: the hash algorithm + * @iov: the array of memory regions to hash + * @niov: the length of @iov + * @base64: pointer to hold output hash + * @errp: pointer to uninitialized error object + * + * Computes the hash across all the memory regions + * present in @iov. The @base64 pointer will be + * filled with the base64 encoding of the computed + * hash, which will be terminated by '\0'. The + * memory pointer in @base64 must be released + * with a call to g_free() when no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_base64v(QCryptoHashAlgorithm alg, + const struct iovec *iov, + size_t niov, + char **base64, + Error **errp); + +/** + * qcrypto_hash_base64: + * @alg: the hash algorithm + * @buf: the memory region to hash + * @len: the length of @buf + * @base64: pointer to hold output hash + * @errp: pointer to uninitialized error object + * + * Computes the hash across all the memory region + * @buf of length @len. The @base64 pointer will be + * filled with the base64 encoding of the computed + * hash, which will be terminated by '\0'. The + * memory pointer in @base64 must be released + * with a call to g_free() when no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_base64(QCryptoHashAlgorithm alg, + const char *buf, + size_t len, + char **base64, + Error **errp); + +#endif /* QCRYPTO_HASH_H__ */ diff --git a/qemu/include/crypto/init.h b/qemu/include/crypto/init.h new file mode 100644 index 000000000..5fc510c4f --- /dev/null +++ b/qemu/include/crypto/init.h @@ -0,0 +1,29 @@ +/* + * QEMU Crypto initialization + * + * 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 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_INIT_H__ +#define QCRYPTO_INIT_H__ + +#include "qemu-common.h" +#include "qapi/error.h" + +int qcrypto_init(Error **errp); + +#endif /* QCRYPTO_INIT_H__ */ |