Merge misc crypto changes & fixes
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJWeoF6AAoJEL6G67QVEE/ff7MP/jcF8c21q28DLPvHFTQdLCDS HsrJhUXlPBQk6knQrZQpb5PU8/s2NeyJdglzxFI7LaOlTAjlUh+bZIoU7Y9iGht9 HOKAgUX1eApkMfhpV+pzPXIrF3b7TCiWWOKsWW8SkqSnIYgigBM+8xA0XspduWvQ cSklbwvhs3duawrg8lVnRJQgbrVtDVFKrzBiUCke6qSrKqO/2iuLrpZMiv6b5uTQ tWzBb2gT/BDcZHRF6Br6DApBe1uqkL/oXmo5DtM/ouwPjuTHMnx8gYFgyIz1vbQN Ti0FrKtwrr8aK5hSnNbNcizKdst7Txw7jV5PiIDdTKV5CvYza4zdeppXXa0rSIyI ByThHzeR5J11hDiIAZ72/yHo9gIifOLqKZtQsCrRB8niyQ93rr85UWA2JWdLqRXs gbbLRK3UXwSZVWmdAlrFIZUxBUdTnc/qcLIU0cgnffC7ozZbwyjt3dnIUM6WmlxW DjY7Z5wcFbbnYsufwBZgZUhWbTj3AdAaiIdBuY33GqqtVs59nICBrtSCYmP1j4+u fDv4QlElETC5hGH9ZPeo08yGrgRA6hGlopnnKSzlfmeb62UU2aYcTW6fNP9OkZI2 HHyGa4XeaeYzYhYbbtRngSI9QjJVf5qzFq2rSFuZcf/9t0n1dztFd36DLca6sW4x fMahe7XiEmKqBBAwFaAr =fHY5 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/berrange/tags/pull-crypto-fixes-2015-12-23-1' into staging Merge misc crypto changes & fixes # gpg: Signature made Wed 23 Dec 2015 11:11:54 GMT using RSA key ID 15104FDF # gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>" # gpg: aka "Daniel P. Berrange <berrange@redhat.com>" * remotes/berrange/tags/pull-crypto-fixes-2015-12-23-1: crypto: fix transposed arguments in cipher error message crypto: ensure qapi/crypto.json is listed in qapi-modules crypto: move QCryptoCipherAlgorithm/Mode enum definitions into QAPI crypto: move QCryptoHashAlgorithm enum definition into QAPI crypto: add ability to query hash digest len crypto: add additional query accessors for cipher instances Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
38a762fec6
3
Makefile
3
Makefile
@ -271,7 +271,8 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||
|
||||
qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
|
||||
$(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
|
||||
$(SRC_PATH)/qapi/event.json $(SRC_PATH)/qapi/introspect.json
|
||||
$(SRC_PATH)/qapi/event.json $(SRC_PATH)/qapi/introspect.json \
|
||||
$(SRC_PATH)/qapi/crypto.json
|
||||
|
||||
qapi-types.c qapi-types.h :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
||||
|
@ -21,19 +21,67 @@
|
||||
#include "crypto/cipher.h"
|
||||
|
||||
|
||||
static size_t alg_key_len[QCRYPTO_CIPHER_ALG_LAST] = {
|
||||
static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
|
||||
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
|
||||
[QCRYPTO_CIPHER_ALG_AES_192] = 24,
|
||||
[QCRYPTO_CIPHER_ALG_AES_256] = 32,
|
||||
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
|
||||
};
|
||||
|
||||
static size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
|
||||
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
|
||||
[QCRYPTO_CIPHER_ALG_AES_192] = 16,
|
||||
[QCRYPTO_CIPHER_ALG_AES_256] = 16,
|
||||
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
|
||||
};
|
||||
|
||||
static bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
|
||||
[QCRYPTO_CIPHER_MODE_ECB] = false,
|
||||
[QCRYPTO_CIPHER_MODE_CBC] = true,
|
||||
};
|
||||
|
||||
|
||||
size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg)
|
||||
{
|
||||
if (alg >= G_N_ELEMENTS(alg_key_len)) {
|
||||
return 0;
|
||||
}
|
||||
return alg_block_len[alg];
|
||||
}
|
||||
|
||||
|
||||
size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg)
|
||||
{
|
||||
if (alg >= G_N_ELEMENTS(alg_key_len)) {
|
||||
return 0;
|
||||
}
|
||||
return alg_key_len[alg];
|
||||
}
|
||||
|
||||
|
||||
size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg,
|
||||
QCryptoCipherMode mode)
|
||||
{
|
||||
if (alg >= G_N_ELEMENTS(alg_block_len)) {
|
||||
return 0;
|
||||
}
|
||||
if (mode >= G_N_ELEMENTS(mode_need_iv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mode_need_iv[mode]) {
|
||||
return alg_block_len[alg];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
|
||||
size_t nkey,
|
||||
Error **errp)
|
||||
{
|
||||
if ((unsigned)alg >= QCRYPTO_CIPHER_ALG_LAST) {
|
||||
if ((unsigned)alg >= QCRYPTO_CIPHER_ALG__MAX) {
|
||||
error_setg(errp, "Cipher algorithm %d out of range",
|
||||
alg);
|
||||
return false;
|
||||
@ -41,7 +89,7 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
|
||||
|
||||
if (alg_key_len[alg] != nkey) {
|
||||
error_setg(errp, "Cipher key length %zu should be %zu",
|
||||
alg_key_len[alg], nkey);
|
||||
nkey, alg_key_len[alg]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -24,12 +24,18 @@
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h>
|
||||
|
||||
static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG_LAST] = {
|
||||
static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
|
||||
[QCRYPTO_HASH_ALG_MD5] = GNUTLS_DIG_MD5,
|
||||
[QCRYPTO_HASH_ALG_SHA1] = GNUTLS_DIG_SHA1,
|
||||
[QCRYPTO_HASH_ALG_SHA256] = GNUTLS_DIG_SHA256,
|
||||
};
|
||||
|
||||
static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALG__MAX] = {
|
||||
[QCRYPTO_HASH_ALG_MD5] = 16,
|
||||
[QCRYPTO_HASH_ALG_SHA1] = 20,
|
||||
[QCRYPTO_HASH_ALG_SHA256] = 32,
|
||||
};
|
||||
|
||||
gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
|
||||
{
|
||||
if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map)) {
|
||||
@ -38,6 +44,15 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg)
|
||||
{
|
||||
if (alg >= G_N_ELEMENTS(qcrypto_hash_alg_size)) {
|
||||
return 0;
|
||||
}
|
||||
return qcrypto_hash_alg_size[alg];
|
||||
}
|
||||
|
||||
|
||||
int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
|
||||
const struct iovec *iov,
|
||||
size_t niov,
|
||||
|
@ -26,21 +26,8 @@
|
||||
|
||||
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;
|
||||
/* See also "QCryptoCipherAlgorithm" and "QCryptoCipherMode"
|
||||
* enums defined in qapi/crypto.json */
|
||||
|
||||
/**
|
||||
* QCryptoCipher:
|
||||
@ -107,6 +94,43 @@ struct QCryptoCipher {
|
||||
*/
|
||||
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg);
|
||||
|
||||
/**
|
||||
* 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(QCryptoCipherAlgorithm 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(QCryptoCipherAlgorithm 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(QCryptoCipherAlgorithm alg,
|
||||
QCryptoCipherMode mode);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_new:
|
||||
|
@ -24,14 +24,7 @@
|
||||
#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;
|
||||
|
||||
/* See also "QCryptoHashAlgorithm" defined in qapi/crypto.json */
|
||||
|
||||
/**
|
||||
* qcrypto_hash_supports:
|
||||
@ -44,6 +37,17 @@ typedef enum {
|
||||
*/
|
||||
gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_hash_digest_len:
|
||||
* @alg: the hash algorithm
|
||||
*
|
||||
* Determine the size of the hash digest in bytes
|
||||
*
|
||||
* Returns: the digest length in bytes
|
||||
*/
|
||||
size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg);
|
||||
|
||||
/**
|
||||
* qcrypto_hash_bytesv:
|
||||
* @alg: the hash algorithm
|
||||
|
@ -33,3 +33,48 @@
|
||||
{ 'enum': 'QCryptoSecretFormat',
|
||||
'prefix': 'QCRYPTO_SECRET_FORMAT',
|
||||
'data': ['raw', 'base64']}
|
||||
|
||||
|
||||
##
|
||||
# QCryptoHashAlgorithm:
|
||||
#
|
||||
# The supported algorithms for computing content digests
|
||||
#
|
||||
# @md5: MD5. Should not be used in any new code, legacy compat only
|
||||
# @sha1: SHA-1. Should not be used in any new code, legacy compat only
|
||||
# @sha256: SHA-256. Current recommended strong hash.
|
||||
# Since: 2.6
|
||||
##
|
||||
{ 'enum': 'QCryptoHashAlgorithm',
|
||||
'prefix': 'QCRYPTO_HASH_ALG',
|
||||
'data': ['md5', 'sha1', 'sha256']}
|
||||
|
||||
|
||||
##
|
||||
# QCryptoCipherAlgorithm:
|
||||
#
|
||||
# The supported algorithms for content encryption ciphers
|
||||
#
|
||||
# @aes-128: AES with 128 bit / 16 byte keys
|
||||
# @aes-192: AES with 192 bit / 24 byte keys
|
||||
# @aes-256: AES with 256 bit / 32 byte keys
|
||||
# @des-rfb: RFB specific variant of single DES. Do not use except in VNC.
|
||||
# Since: 2.6
|
||||
##
|
||||
{ 'enum': 'QCryptoCipherAlgorithm',
|
||||
'prefix': 'QCRYPTO_CIPHER_ALG',
|
||||
'data': ['aes-128', 'aes-192', 'aes-256', 'des-rfb']}
|
||||
|
||||
|
||||
##
|
||||
# QCryptoCipherMode:
|
||||
#
|
||||
# The supported modes for content encryption ciphers
|
||||
#
|
||||
# @ecb: Electronic Code Book
|
||||
# @cbc: Cipher Block Chaining
|
||||
# Since: 2.6
|
||||
##
|
||||
{ 'enum': 'QCryptoCipherMode',
|
||||
'prefix': 'QCRYPTO_CIPHER_MODE',
|
||||
'data': ['ecb', 'cbc']}
|
||||
|
@ -229,6 +229,7 @@ static void test_cipher(const void *opaque)
|
||||
uint8_t *key, *iv, *ciphertext, *plaintext, *outtext;
|
||||
size_t nkey, niv, nciphertext, nplaintext;
|
||||
char *outtexthex;
|
||||
size_t ivsize, keysize, blocksize;
|
||||
|
||||
nkey = unhex_string(data->key, &key);
|
||||
niv = unhex_string(data->iv, &iv);
|
||||
@ -245,6 +246,15 @@ static void test_cipher(const void *opaque)
|
||||
&error_abort);
|
||||
g_assert(cipher != NULL);
|
||||
|
||||
keysize = qcrypto_cipher_get_key_len(data->alg);
|
||||
blocksize = qcrypto_cipher_get_block_len(data->alg);
|
||||
ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode);
|
||||
|
||||
g_assert_cmpint(keysize, ==, nkey);
|
||||
g_assert_cmpint(ivsize, ==, niv);
|
||||
if (niv) {
|
||||
g_assert_cmpint(blocksize, ==, niv);
|
||||
}
|
||||
|
||||
if (iv) {
|
||||
g_assert(qcrypto_cipher_setiv(cipher,
|
||||
|
@ -163,6 +163,11 @@ static void test_hash_digest(void)
|
||||
for (i = 0; i < G_N_ELEMENTS(expected_outputs) ; i++) {
|
||||
int ret;
|
||||
char *digest;
|
||||
size_t digestsize;
|
||||
|
||||
digestsize = qcrypto_hash_digest_len(i);
|
||||
|
||||
g_assert_cmpint(digestsize * 2, ==, strlen(expected_outputs[i]));
|
||||
|
||||
ret = qcrypto_hash_digest(i,
|
||||
INPUT_TEXT,
|
||||
|
Loading…
Reference in New Issue
Block a user