crypto: add support for generating initialization vectors
There are a number of different algorithms that can be used to generate initialization vectors for disk encryption. This introduces a simple internal QCryptoBlockIV object to provide a consistent internal API to the different algorithms. The initially implemented algorithms are 'plain', 'plain64' and 'essiv', each matching the same named algorithm provided by the Linux kernel dm-crypt driver. Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
37788f253a
commit
cb730894ae
@ -13,6 +13,10 @@ crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS_RND)) += random-gnutls.o
|
|||||||
crypto-obj-y += pbkdf.o
|
crypto-obj-y += pbkdf.o
|
||||||
crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o
|
crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o
|
||||||
crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT_KDF)) += pbkdf-gcrypt.o
|
crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT_KDF)) += pbkdf-gcrypt.o
|
||||||
|
crypto-obj-y += ivgen.o
|
||||||
|
crypto-obj-y += ivgen-essiv.o
|
||||||
|
crypto-obj-y += ivgen-plain.o
|
||||||
|
crypto-obj-y += ivgen-plain64.o
|
||||||
|
|
||||||
# Let the userspace emulators avoid linking gnutls/etc
|
# Let the userspace emulators avoid linking gnutls/etc
|
||||||
crypto-aes-obj-y = aes.o
|
crypto-aes-obj-y = aes.o
|
||||||
|
118
crypto/ivgen-essiv.c
Normal file
118
crypto/ivgen-essiv.c
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator - essiv
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "crypto/ivgen-essiv.h"
|
||||||
|
|
||||||
|
typedef struct QCryptoIVGenESSIV QCryptoIVGenESSIV;
|
||||||
|
struct QCryptoIVGenESSIV {
|
||||||
|
QCryptoCipher *cipher;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int qcrypto_ivgen_essiv_init(QCryptoIVGen *ivgen,
|
||||||
|
const uint8_t *key, size_t nkey,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
uint8_t *salt;
|
||||||
|
size_t nhash;
|
||||||
|
size_t nsalt;
|
||||||
|
QCryptoIVGenESSIV *essiv = g_new0(QCryptoIVGenESSIV, 1);
|
||||||
|
|
||||||
|
/* Not necessarily the same as nkey */
|
||||||
|
nsalt = qcrypto_cipher_get_key_len(ivgen->cipher);
|
||||||
|
|
||||||
|
nhash = qcrypto_hash_digest_len(ivgen->hash);
|
||||||
|
/* Salt must be larger of hash size or key size */
|
||||||
|
salt = g_new0(uint8_t, MAX(nhash, nsalt));
|
||||||
|
|
||||||
|
if (qcrypto_hash_bytes(ivgen->hash, (const gchar *)key, nkey,
|
||||||
|
&salt, &nhash,
|
||||||
|
errp) < 0) {
|
||||||
|
g_free(essiv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now potentially truncate salt to match cipher key len */
|
||||||
|
essiv->cipher = qcrypto_cipher_new(ivgen->cipher,
|
||||||
|
QCRYPTO_CIPHER_MODE_ECB,
|
||||||
|
salt, MIN(nhash, nsalt),
|
||||||
|
errp);
|
||||||
|
if (!essiv->cipher) {
|
||||||
|
g_free(essiv);
|
||||||
|
g_free(salt);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(salt);
|
||||||
|
ivgen->private = essiv;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qcrypto_ivgen_essiv_calculate(QCryptoIVGen *ivgen,
|
||||||
|
uint64_t sector,
|
||||||
|
uint8_t *iv, size_t niv,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
QCryptoIVGenESSIV *essiv = ivgen->private;
|
||||||
|
size_t ndata = qcrypto_cipher_get_block_len(ivgen->cipher);
|
||||||
|
uint8_t *data = g_new(uint8_t, ndata);
|
||||||
|
|
||||||
|
sector = cpu_to_le64(sector);
|
||||||
|
memcpy(data, (uint8_t *)§or, ndata);
|
||||||
|
if (sizeof(sector) < ndata) {
|
||||||
|
memset(data + sizeof(sector), 0, ndata - sizeof(sector));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qcrypto_cipher_encrypt(essiv->cipher,
|
||||||
|
data,
|
||||||
|
data,
|
||||||
|
ndata,
|
||||||
|
errp) < 0) {
|
||||||
|
g_free(data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ndata > niv) {
|
||||||
|
ndata = niv;
|
||||||
|
}
|
||||||
|
memcpy(iv, data, ndata);
|
||||||
|
if (ndata < niv) {
|
||||||
|
memset(iv + ndata, 0, niv - ndata);
|
||||||
|
}
|
||||||
|
g_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qcrypto_ivgen_essiv_cleanup(QCryptoIVGen *ivgen)
|
||||||
|
{
|
||||||
|
QCryptoIVGenESSIV *essiv = ivgen->private;
|
||||||
|
|
||||||
|
qcrypto_cipher_free(essiv->cipher);
|
||||||
|
g_free(essiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct QCryptoIVGenDriver qcrypto_ivgen_essiv = {
|
||||||
|
.init = qcrypto_ivgen_essiv_init,
|
||||||
|
.calculate = qcrypto_ivgen_essiv_calculate,
|
||||||
|
.cleanup = qcrypto_ivgen_essiv_cleanup,
|
||||||
|
};
|
||||||
|
|
28
crypto/ivgen-essiv.h
Normal file
28
crypto/ivgen-essiv.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator - essiv
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "crypto/ivgenpriv.h"
|
||||||
|
|
||||||
|
#ifndef QCRYPTO_IVGEN_ESSIV_H__
|
||||||
|
#define QCRYPTO_IVGEN_ESSIV_H__
|
||||||
|
|
||||||
|
extern struct QCryptoIVGenDriver qcrypto_ivgen_essiv;
|
||||||
|
|
||||||
|
#endif /* QCRYPTO_IVGEN_ESSIV_H__ */
|
59
crypto/ivgen-plain.c
Normal file
59
crypto/ivgen-plain.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator - plain
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "crypto/ivgen-plain.h"
|
||||||
|
|
||||||
|
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
|
||||||
|
const uint8_t *key, size_t nkey,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qcrypto_ivgen_plain_calculate(QCryptoIVGen *ivgen,
|
||||||
|
uint64_t sector,
|
||||||
|
uint8_t *iv, size_t niv,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
size_t ivprefix;
|
||||||
|
uint32_t shortsector = cpu_to_le32((sector & 0xffffffff));
|
||||||
|
ivprefix = sizeof(shortsector);
|
||||||
|
if (ivprefix > niv) {
|
||||||
|
ivprefix = niv;
|
||||||
|
}
|
||||||
|
memcpy(iv, &shortsector, ivprefix);
|
||||||
|
if (ivprefix < niv) {
|
||||||
|
memset(iv + ivprefix, 0, niv - ivprefix);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qcrypto_ivgen_plain_cleanup(QCryptoIVGen *ivgen)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct QCryptoIVGenDriver qcrypto_ivgen_plain = {
|
||||||
|
.init = qcrypto_ivgen_plain_init,
|
||||||
|
.calculate = qcrypto_ivgen_plain_calculate,
|
||||||
|
.cleanup = qcrypto_ivgen_plain_cleanup,
|
||||||
|
};
|
||||||
|
|
28
crypto/ivgen-plain.h
Normal file
28
crypto/ivgen-plain.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator - plain
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "crypto/ivgenpriv.h"
|
||||||
|
|
||||||
|
#ifndef QCRYPTO_IVGEN_PLAIN_H__
|
||||||
|
#define QCRYPTO_IVGEN_PLAIN_H__
|
||||||
|
|
||||||
|
extern struct QCryptoIVGenDriver qcrypto_ivgen_plain;
|
||||||
|
|
||||||
|
#endif /* QCRYPTO_IVGEN_PLAIN_H__ */
|
59
crypto/ivgen-plain64.c
Normal file
59
crypto/ivgen-plain64.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator - plain
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "crypto/ivgen-plain.h"
|
||||||
|
|
||||||
|
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
|
||||||
|
const uint8_t *key, size_t nkey,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qcrypto_ivgen_plain_calculate(QCryptoIVGen *ivgen,
|
||||||
|
uint64_t sector,
|
||||||
|
uint8_t *iv, size_t niv,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
size_t ivprefix;
|
||||||
|
ivprefix = sizeof(sector);
|
||||||
|
sector = cpu_to_le64(sector);
|
||||||
|
if (ivprefix > niv) {
|
||||||
|
ivprefix = niv;
|
||||||
|
}
|
||||||
|
memcpy(iv, §or, ivprefix);
|
||||||
|
if (ivprefix < niv) {
|
||||||
|
memset(iv + ivprefix, 0, niv - ivprefix);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qcrypto_ivgen_plain_cleanup(QCryptoIVGen *ivgen)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct QCryptoIVGenDriver qcrypto_ivgen_plain64 = {
|
||||||
|
.init = qcrypto_ivgen_plain_init,
|
||||||
|
.calculate = qcrypto_ivgen_plain_calculate,
|
||||||
|
.cleanup = qcrypto_ivgen_plain_cleanup,
|
||||||
|
};
|
||||||
|
|
28
crypto/ivgen-plain64.h
Normal file
28
crypto/ivgen-plain64.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator - plain64
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "crypto/ivgenpriv.h"
|
||||||
|
|
||||||
|
#ifndef QCRYPTO_IVGEN_PLAIN64_H__
|
||||||
|
#define QCRYPTO_IVGEN_PLAIN64_H__
|
||||||
|
|
||||||
|
extern struct QCryptoIVGenDriver qcrypto_ivgen_plain64;
|
||||||
|
|
||||||
|
#endif /* QCRYPTO_IVGEN_PLAIN64_H__ */
|
99
crypto/ivgen.c
Normal file
99
crypto/ivgen.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "crypto/ivgenpriv.h"
|
||||||
|
#include "crypto/ivgen-plain.h"
|
||||||
|
#include "crypto/ivgen-plain64.h"
|
||||||
|
#include "crypto/ivgen-essiv.h"
|
||||||
|
|
||||||
|
|
||||||
|
QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg,
|
||||||
|
QCryptoCipherAlgorithm cipheralg,
|
||||||
|
QCryptoHashAlgorithm hash,
|
||||||
|
const uint8_t *key, size_t nkey,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
QCryptoIVGen *ivgen = g_new0(QCryptoIVGen, 1);
|
||||||
|
|
||||||
|
ivgen->algorithm = alg;
|
||||||
|
ivgen->cipher = cipheralg;
|
||||||
|
ivgen->hash = hash;
|
||||||
|
|
||||||
|
switch (alg) {
|
||||||
|
case QCRYPTO_IVGEN_ALG_PLAIN:
|
||||||
|
ivgen->driver = &qcrypto_ivgen_plain;
|
||||||
|
break;
|
||||||
|
case QCRYPTO_IVGEN_ALG_PLAIN64:
|
||||||
|
ivgen->driver = &qcrypto_ivgen_plain64;
|
||||||
|
break;
|
||||||
|
case QCRYPTO_IVGEN_ALG_ESSIV:
|
||||||
|
ivgen->driver = &qcrypto_ivgen_essiv;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error_setg(errp, "Unknown block IV generator algorithm %d", alg);
|
||||||
|
g_free(ivgen);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ivgen->driver->init(ivgen, key, nkey, errp) < 0) {
|
||||||
|
g_free(ivgen);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ivgen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen,
|
||||||
|
uint64_t sector,
|
||||||
|
uint8_t *iv, size_t niv,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
return ivgen->driver->calculate(ivgen, sector, iv, niv, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen)
|
||||||
|
{
|
||||||
|
return ivgen->algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen)
|
||||||
|
{
|
||||||
|
return ivgen->cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen)
|
||||||
|
{
|
||||||
|
return ivgen->hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void qcrypto_ivgen_free(QCryptoIVGen *ivgen)
|
||||||
|
{
|
||||||
|
if (!ivgen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ivgen->driver->cleanup(ivgen);
|
||||||
|
g_free(ivgen);
|
||||||
|
}
|
49
crypto/ivgenpriv.h
Normal file
49
crypto/ivgenpriv.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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_IVGEN_PRIV_H__
|
||||||
|
#define QCRYPTO_IVGEN_PRIV_H__
|
||||||
|
|
||||||
|
#include "crypto/ivgen.h"
|
||||||
|
|
||||||
|
typedef struct QCryptoIVGenDriver QCryptoIVGenDriver;
|
||||||
|
|
||||||
|
struct QCryptoIVGenDriver {
|
||||||
|
int (*init)(QCryptoIVGen *ivgen,
|
||||||
|
const uint8_t *key, size_t nkey,
|
||||||
|
Error **errp);
|
||||||
|
int (*calculate)(QCryptoIVGen *ivgen,
|
||||||
|
uint64_t sector,
|
||||||
|
uint8_t *iv, size_t niv,
|
||||||
|
Error **errp);
|
||||||
|
void (*cleanup)(QCryptoIVGen *ivgen);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QCryptoIVGen {
|
||||||
|
QCryptoIVGenDriver *driver;
|
||||||
|
void *private;
|
||||||
|
|
||||||
|
QCryptoIVGenAlgorithm algorithm;
|
||||||
|
QCryptoCipherAlgorithm cipher;
|
||||||
|
QCryptoHashAlgorithm hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* QCRYPTO_IVGEN_PRIV_H__ */
|
206
include/crypto/ivgen.h
Normal file
206
include/crypto/ivgen.h
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto block IV generator
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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_IVGEN_H__
|
||||||
|
#define QCRYPTO_IVGEN_H__
|
||||||
|
|
||||||
|
#include "crypto/cipher.h"
|
||||||
|
#include "crypto/hash.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module provides a framework for generating initialization
|
||||||
|
* vectors for block encryption schemes using chained cipher modes
|
||||||
|
* CBC. The principle is that each disk sector is assigned a unique
|
||||||
|
* initialization vector for use for encryption of data in that
|
||||||
|
* sector.
|
||||||
|
*
|
||||||
|
* <example>
|
||||||
|
* <title>Encrypting block data with initialiation vectors</title>
|
||||||
|
* <programlisting>
|
||||||
|
* uint8_t *data = ....data to encrypt...
|
||||||
|
* size_t ndata = XXX;
|
||||||
|
* uint8_t *key = ....some encryption key...
|
||||||
|
* size_t nkey = XXX;
|
||||||
|
* uint8_t *iv;
|
||||||
|
* size_t niv;
|
||||||
|
* size_t sector = 0;
|
||||||
|
*
|
||||||
|
* g_assert((ndata % 512) == 0);
|
||||||
|
*
|
||||||
|
* QCryptoIVGen *ivgen = qcrypto_ivgen_new(QCRYPTO_IVGEN_ALG_ESSIV,
|
||||||
|
* QCRYPTO_CIPHER_ALG_AES_128,
|
||||||
|
* QCRYPTO_HASH_ALG_SHA256,
|
||||||
|
* key, nkey, errp);
|
||||||
|
* if (!ivgen) {
|
||||||
|
* return -1;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* QCryptoCipher *cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
|
||||||
|
* QCRYPTO_CIPHER_MODE_CBC,
|
||||||
|
* key, nkey, errp);
|
||||||
|
* if (!cipher) {
|
||||||
|
* goto error;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128,
|
||||||
|
* QCRYPTO_CIPHER_MODE_CBC);
|
||||||
|
* iv = g_new0(uint8_t, niv);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* while (ndata) {
|
||||||
|
* if (qcrypto_ivgen_calculate(ivgen, sector, iv, niv, errp) < 0) {
|
||||||
|
* goto error;
|
||||||
|
* }
|
||||||
|
* if (qcrypto_cipher_setiv(cipher, iv, niv, errp) < 0) {
|
||||||
|
* goto error;
|
||||||
|
* }
|
||||||
|
* if (qcrypto_cipher_encrypt(cipher,
|
||||||
|
* data + (sector * 512),
|
||||||
|
* data + (sector * 512),
|
||||||
|
* 512, errp) < 0) {
|
||||||
|
* goto error;
|
||||||
|
* }
|
||||||
|
* sector++;
|
||||||
|
* ndata -= 512;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* g_free(iv);
|
||||||
|
* qcrypto_ivgen_free(ivgen);
|
||||||
|
* qcrypto_cipher_free(cipher);
|
||||||
|
* return 0;
|
||||||
|
*
|
||||||
|
*error:
|
||||||
|
* g_free(iv);
|
||||||
|
* qcrypto_ivgen_free(ivgen);
|
||||||
|
* qcrypto_cipher_free(cipher);
|
||||||
|
* return -1;
|
||||||
|
* </programlisting>
|
||||||
|
* </example>
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct QCryptoIVGen QCryptoIVGen;
|
||||||
|
|
||||||
|
/* See also QCryptoIVGenAlgorithm enum in qapi/crypto.json */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcrypto_ivgen_new:
|
||||||
|
* @alg: the initialization vector generation algorithm
|
||||||
|
* @cipheralg: the cipher algorithm or 0
|
||||||
|
* @hash: the hash algorithm or 0
|
||||||
|
* @key: the encryption key or NULL
|
||||||
|
* @nkey: the size of @key in bytes
|
||||||
|
*
|
||||||
|
* Create a new initialization vector generator that uses
|
||||||
|
* the algorithm @alg. Whether the remaining parameters
|
||||||
|
* are required or not depends on the choice of @alg
|
||||||
|
* requested.
|
||||||
|
*
|
||||||
|
* - QCRYPTO_IVGEN_ALG_PLAIN
|
||||||
|
*
|
||||||
|
* The IVs are generated by the 32-bit truncated sector
|
||||||
|
* number. This should never be used for block devices
|
||||||
|
* that are larger than 2^32 sectors in size.
|
||||||
|
* All the other parameters are unused.
|
||||||
|
*
|
||||||
|
* - QCRYPTO_IVGEN_ALG_PLAIN64
|
||||||
|
*
|
||||||
|
* The IVs are generated by the 64-bit sector number.
|
||||||
|
* All the other parameters are unused.
|
||||||
|
*
|
||||||
|
* - QCRYPTO_IVGEN_ALG_ESSIV:
|
||||||
|
*
|
||||||
|
* The IVs are generated by encrypting the 64-bit sector
|
||||||
|
* number with a hash of an encryption key. The @cipheralg,
|
||||||
|
* @hash, @key and @nkey parameters are all required.
|
||||||
|
*
|
||||||
|
* Returns: a new IV generator, or NULL on error
|
||||||
|
*/
|
||||||
|
QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg,
|
||||||
|
QCryptoCipherAlgorithm cipheralg,
|
||||||
|
QCryptoHashAlgorithm hash,
|
||||||
|
const uint8_t *key, size_t nkey,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcrypto_ivgen_calculate:
|
||||||
|
* @ivgen: the IV generator object
|
||||||
|
* @sector: the 64-bit sector number
|
||||||
|
* @iv: a pre-allocated buffer to hold the generated IV
|
||||||
|
* @niv: the number of bytes in @iv
|
||||||
|
* @errp: pointer to a NULL-initialized error object
|
||||||
|
*
|
||||||
|
* Calculate a new initialiation vector for the data
|
||||||
|
* to be stored in sector @sector. The IV will be
|
||||||
|
* written into the buffer @iv of size @niv.
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen,
|
||||||
|
uint64_t sector,
|
||||||
|
uint8_t *iv, size_t niv,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcrypto_ivgen_get_algorithm:
|
||||||
|
* @ivgen: the IV generator object
|
||||||
|
*
|
||||||
|
* Get the algorithm used by this IV generator
|
||||||
|
*
|
||||||
|
* Returns: the IV generator algorithm
|
||||||
|
*/
|
||||||
|
QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcrypto_ivgen_get_cipher:
|
||||||
|
* @ivgen: the IV generator object
|
||||||
|
*
|
||||||
|
* Get the cipher algorithm used by this IV generator (if
|
||||||
|
* applicable)
|
||||||
|
*
|
||||||
|
* Returns: the cipher algorithm
|
||||||
|
*/
|
||||||
|
QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcrypto_ivgen_get_hash:
|
||||||
|
* @ivgen: the IV generator object
|
||||||
|
*
|
||||||
|
* Get the hash algorithm used by this IV generator (if
|
||||||
|
* applicable)
|
||||||
|
*
|
||||||
|
* Returns: the hash algorithm
|
||||||
|
*/
|
||||||
|
QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcrypto_ivgen_free:
|
||||||
|
* @ivgen: the IV generator object
|
||||||
|
*
|
||||||
|
* Release all resources associated with @ivgen, or a no-op
|
||||||
|
* if @ivgen is NULL
|
||||||
|
*/
|
||||||
|
void qcrypto_ivgen_free(QCryptoIVGen *ivgen);
|
||||||
|
|
||||||
|
#endif /* QCRYPTO_IVGEN_H__ */
|
@ -78,3 +78,22 @@
|
|||||||
{ 'enum': 'QCryptoCipherMode',
|
{ 'enum': 'QCryptoCipherMode',
|
||||||
'prefix': 'QCRYPTO_CIPHER_MODE',
|
'prefix': 'QCRYPTO_CIPHER_MODE',
|
||||||
'data': ['ecb', 'cbc']}
|
'data': ['ecb', 'cbc']}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# QCryptoIVGenAlgorithm:
|
||||||
|
#
|
||||||
|
# The supported algorithms for generating initialization
|
||||||
|
# vectors for full disk encryption. The 'plain' generator
|
||||||
|
# should not be used for disks with sector numbers larger
|
||||||
|
# than 2^32, except where compatibility with pre-existing
|
||||||
|
# Linux dm-crypt volumes is required.
|
||||||
|
#
|
||||||
|
# @plain: 64-bit sector number truncated to 32-bits
|
||||||
|
# @plain64: 64-bit sector number
|
||||||
|
# @essiv: 64-bit sector number encrypted with a hash of the encryption key
|
||||||
|
# Since: 2.6
|
||||||
|
##
|
||||||
|
{ 'enum': 'QCryptoIVGenAlgorithm',
|
||||||
|
'prefix': 'QCRYPTO_IVGEN_ALG',
|
||||||
|
'data': ['plain', 'plain64', 'essiv']}
|
||||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -14,6 +14,7 @@ test-blockjob-txn
|
|||||||
test-coroutine
|
test-coroutine
|
||||||
test-crypto-cipher
|
test-crypto-cipher
|
||||||
test-crypto-hash
|
test-crypto-hash
|
||||||
|
test-crypto-ivgen
|
||||||
test-crypto-pbkdf
|
test-crypto-pbkdf
|
||||||
test-crypto-secret
|
test-crypto-secret
|
||||||
test-crypto-tlscredsx509
|
test-crypto-tlscredsx509
|
||||||
|
@ -93,6 +93,7 @@ check-unit-y += tests/test-io-channel-command$(EXESUF)
|
|||||||
check-unit-y += tests/test-io-channel-buffer$(EXESUF)
|
check-unit-y += tests/test-io-channel-buffer$(EXESUF)
|
||||||
check-unit-y += tests/test-base64$(EXESUF)
|
check-unit-y += tests/test-base64$(EXESUF)
|
||||||
check-unit-$(if $(CONFIG_NETTLE),y,$(CONFIG_GCRYPT_KDF)) += tests/test-crypto-pbkdf$(EXESUF)
|
check-unit-$(if $(CONFIG_NETTLE),y,$(CONFIG_GCRYPT_KDF)) += tests/test-crypto-pbkdf$(EXESUF)
|
||||||
|
check-unit-y += tests/test-crypto-ivgen$(EXESUF)
|
||||||
|
|
||||||
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
|
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
|
||||||
|
|
||||||
@ -498,6 +499,7 @@ tests/test-io-channel-command$(EXESUF): tests/test-io-channel-command.o \
|
|||||||
tests/test-io-channel-buffer$(EXESUF): tests/test-io-channel-buffer.o \
|
tests/test-io-channel-buffer$(EXESUF): tests/test-io-channel-buffer.o \
|
||||||
tests/io-channel-helpers.o $(test-io-obj-y)
|
tests/io-channel-helpers.o $(test-io-obj-y)
|
||||||
tests/test-crypto-pbkdf$(EXESUF): tests/test-crypto-pbkdf.o $(test-crypto-obj-y)
|
tests/test-crypto-pbkdf$(EXESUF): tests/test-crypto-pbkdf.o $(test-crypto-obj-y)
|
||||||
|
tests/test-crypto-ivgen$(EXESUF): tests/test-crypto-ivgen.o $(test-crypto-obj-y)
|
||||||
|
|
||||||
libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
|
libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
|
||||||
libqos-obj-y += tests/libqos/i2c.o tests/libqos/libqos.o
|
libqos-obj-y += tests/libqos/i2c.o tests/libqos/libqos.o
|
||||||
|
173
tests/test-crypto-ivgen.c
Normal file
173
tests/test-crypto-ivgen.c
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
* QEMU Crypto IV generator algorithms
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "crypto/ivgen.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct QCryptoIVGenTestData {
|
||||||
|
const char *path;
|
||||||
|
uint64_t sector;
|
||||||
|
QCryptoIVGenAlgorithm ivalg;
|
||||||
|
QCryptoHashAlgorithm hashalg;
|
||||||
|
QCryptoCipherAlgorithm cipheralg;
|
||||||
|
const uint8_t *key;
|
||||||
|
size_t nkey;
|
||||||
|
const uint8_t *iv;
|
||||||
|
size_t niv;
|
||||||
|
} test_data[] = {
|
||||||
|
/* Small */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/plain/1",
|
||||||
|
.sector = 0x1,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_PLAIN,
|
||||||
|
.iv = (const uint8_t *)"\x01\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
/* Big ! */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/plain/1f2e3d4c",
|
||||||
|
.sector = 0x1f2e3d4cULL,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_PLAIN,
|
||||||
|
.iv = (const uint8_t *)"\x4c\x3d\x2e\x1f\x00\x00\x00\x00"
|
||||||
|
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
/* Truncation */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/plain/1f2e3d4c5b6a7988",
|
||||||
|
.sector = 0x1f2e3d4c5b6a7988ULL,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_PLAIN,
|
||||||
|
.iv = (const uint8_t *)"\x88\x79\x6a\x5b\x00\x00\x00\x00"
|
||||||
|
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
/* Small */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/plain64/1",
|
||||||
|
.sector = 0x1,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_PLAIN64,
|
||||||
|
.iv = (const uint8_t *)"\x01\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
/* Big ! */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/plain64/1f2e3d4c",
|
||||||
|
.sector = 0x1f2e3d4cULL,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_PLAIN64,
|
||||||
|
.iv = (const uint8_t *)"\x4c\x3d\x2e\x1f\x00\x00\x00\x00"
|
||||||
|
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
/* No Truncation */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/plain64/1f2e3d4c5b6a7988",
|
||||||
|
.sector = 0x1f2e3d4c5b6a7988ULL,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_PLAIN64,
|
||||||
|
.iv = (const uint8_t *)"\x88\x79\x6a\x5b\x4c\x3d\x2e\x1f"
|
||||||
|
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
/* Small */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/essiv/1",
|
||||||
|
.sector = 0x1,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_ESSIV,
|
||||||
|
.cipheralg = QCRYPTO_CIPHER_ALG_AES_128,
|
||||||
|
.hashalg = QCRYPTO_HASH_ALG_SHA256,
|
||||||
|
.key = (const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
.nkey = 16,
|
||||||
|
.iv = (const uint8_t *)"\xd4\x83\x71\xb2\xa1\x94\x53\x88"
|
||||||
|
"\x1c\x7a\x2d\06\x2d\x0b\x65\x46",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
/* Big ! */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/essiv/1f2e3d4c",
|
||||||
|
.sector = 0x1f2e3d4cULL,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_ESSIV,
|
||||||
|
.cipheralg = QCRYPTO_CIPHER_ALG_AES_128,
|
||||||
|
.hashalg = QCRYPTO_HASH_ALG_SHA256,
|
||||||
|
.key = (const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
.nkey = 16,
|
||||||
|
.iv = (const uint8_t *)"\x5d\x36\x09\x5d\xc6\x9e\x5e\xe9"
|
||||||
|
"\xe3\x02\x8d\xd8\x7a\x3d\xe7\x8f",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
/* No Truncation */
|
||||||
|
{
|
||||||
|
"/crypto/ivgen/essiv/1f2e3d4c5b6a7988",
|
||||||
|
.sector = 0x1f2e3d4c5b6a7988ULL,
|
||||||
|
.ivalg = QCRYPTO_IVGEN_ALG_ESSIV,
|
||||||
|
.cipheralg = QCRYPTO_CIPHER_ALG_AES_128,
|
||||||
|
.hashalg = QCRYPTO_HASH_ALG_SHA256,
|
||||||
|
.key = (const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
|
||||||
|
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
|
||||||
|
.nkey = 16,
|
||||||
|
.iv = (const uint8_t *)"\x58\xbb\x81\x94\x51\x83\x23\x23"
|
||||||
|
"\x7a\x08\x93\xa9\xdc\xd2\xd9\xab",
|
||||||
|
.niv = 16,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void test_ivgen(const void *opaque)
|
||||||
|
{
|
||||||
|
const struct QCryptoIVGenTestData *data = opaque;
|
||||||
|
uint8_t *iv = g_new0(uint8_t, data->niv);
|
||||||
|
QCryptoIVGen *ivgen = qcrypto_ivgen_new(
|
||||||
|
data->ivalg,
|
||||||
|
data->cipheralg,
|
||||||
|
data->hashalg,
|
||||||
|
data->key,
|
||||||
|
data->nkey,
|
||||||
|
&error_abort);
|
||||||
|
|
||||||
|
qcrypto_ivgen_calculate(ivgen,
|
||||||
|
data->sector,
|
||||||
|
iv,
|
||||||
|
data->niv,
|
||||||
|
&error_abort);
|
||||||
|
|
||||||
|
g_assert(memcmp(iv, data->iv, data->niv) == 0);
|
||||||
|
|
||||||
|
qcrypto_ivgen_free(ivgen);
|
||||||
|
g_free(iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
g_test_init(&argc, &argv, NULL);
|
||||||
|
for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
|
||||||
|
if (test_data[i].ivalg == QCRYPTO_IVGEN_ALG_ESSIV &&
|
||||||
|
!qcrypto_hash_supports(test_data[i].hashalg)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
g_test_add_data_func(test_data[i].path,
|
||||||
|
&(test_data[i]),
|
||||||
|
test_ivgen);
|
||||||
|
}
|
||||||
|
return g_test_run();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user