Merge qcrypto-fixes 2015/10/22
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJWKSUBAAoJEL6G67QVEE/f7cgQAJQPIFv/tq6tvAnN+vZQDS5V xVhahx3FoOCty3LkdPnSya+C+jvJe9/JwF4VyJHIP/IrWrtJOyWkjg18R86YhWjo QjycP8usYFZ4YiF5IVOpeKBhM2rff9q9U+5i+aZ8GIJKjpkd2/Ij4itlmDSEQkX9 umZ5AIpY0yHjn+HobJOdQaouKn6/OLiNSEBmO1/G43xipwlQeXRUDKDKTt58ebEA cNjgICBr41J0Dvol8trZjJDTbs/g1mw6N2NK/kauLcidgw5dT/MvyPD0d67Oo2rb ZbsnfX8ZKljT5ZsNPItBJqFuQmfJA6ssPYkqdLpQU7HjBQUU5fW84MK2Uoc7hhgF f/SmDLcCJ49fNew6MDwN5OgkO/7UnEASfLaQltdVmI7IvGvxVy58mLoJzdbS+Fh/ ZLUbPYMj9lXtsQYjkrdzhedV8rLpWVi35pQ+7kKoIzt3hcclKoJJUJJ09+nenxNo h9o83He+AbqhCQM9YCwM3OLtgyxHn1H2DzlQZrma3tRZTz8RE6KBKhKAiF50iMOS KouHV0kON1yVXJS2Ro+KpU0ja3Ck4YF89gR9ty2aPfPMJvkTNPqIl0gJxP+haOBB FII6PATfh6cpfnSa/FJ01tHzfyUcA4sTsJVex13LurYTuVAzXYxg8iKMY0stbZ6y I4dJ9WFvyG4aVNz5KKLC =5byU -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/berrange/tags/qcrypto-fixes-pull-20151022-2' into staging Merge qcrypto-fixes 2015/10/22 # gpg: Signature made Thu 22 Oct 2015 19:03:45 BST 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/qcrypto-fixes-pull-20151022-2: configure: avoid polluting global CFLAGS with tasn1 flags crypto: add sanity checking of plaintext/ciphertext length crypto: don't let builtin aes crash if no IV is provided crypto: allow use of nettle/gcrypt to be selected explicitly Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
431429a5b8
|
@ -331,6 +331,8 @@ gtkabi=""
|
|||
gtk_gl="no"
|
||||
gnutls=""
|
||||
gnutls_hash=""
|
||||
nettle=""
|
||||
gcrypt=""
|
||||
vte=""
|
||||
virglrenderer=""
|
||||
tpm="yes"
|
||||
|
@ -417,9 +419,6 @@ if test "$debug_info" = "yes"; then
|
|||
LDFLAGS="-g $LDFLAGS"
|
||||
fi
|
||||
|
||||
test_cflags=""
|
||||
test_libs=""
|
||||
|
||||
# make source path absolute
|
||||
source_path=`cd "$source_path"; pwd`
|
||||
|
||||
|
@ -1114,6 +1113,14 @@ for opt do
|
|||
;;
|
||||
--enable-gnutls) gnutls="yes"
|
||||
;;
|
||||
--disable-nettle) nettle="no"
|
||||
;;
|
||||
--enable-nettle) nettle="yes"
|
||||
;;
|
||||
--disable-gcrypt) gcrypt="no"
|
||||
;;
|
||||
--enable-gcrypt) gcrypt="yes"
|
||||
;;
|
||||
--enable-rdma) rdma="yes"
|
||||
;;
|
||||
--disable-rdma) rdma="no"
|
||||
|
@ -1324,6 +1331,8 @@ disabled with --disable-FEATURE, default is enabled if available:
|
|||
sparse sparse checker
|
||||
|
||||
gnutls GNUTLS cryptography support
|
||||
nettle nettle cryptography support
|
||||
gcrypt libgcrypt cryptography support
|
||||
sdl SDL UI
|
||||
--with-sdlabi select preferred SDL ABI 1.2 or 2.0
|
||||
gtk gtk UI
|
||||
|
@ -2254,20 +2263,76 @@ else
|
|||
gnutls_hash="no"
|
||||
fi
|
||||
|
||||
if test "$gnutls_gcrypt" != "no"; then
|
||||
if has "libgcrypt-config"; then
|
||||
|
||||
# If user didn't give a --disable/enable-gcrypt flag,
|
||||
# then mark as disabled if user requested nettle
|
||||
# explicitly, or if gnutls links to nettle
|
||||
if test -z "$gcrypt"
|
||||
then
|
||||
if test "$nettle" = "yes" || test "$gnutls_nettle" = "yes"
|
||||
then
|
||||
gcrypt="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If user didn't give a --disable/enable-nettle flag,
|
||||
# then mark as disabled if user requested gcrypt
|
||||
# explicitly, or if gnutls links to gcrypt
|
||||
if test -z "$nettle"
|
||||
then
|
||||
if test "$gcrypt" = "yes" || test "$gnutls_gcrypt" = "yes"
|
||||
then
|
||||
nettle="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
has_libgcrypt_config() {
|
||||
if ! has "libgcrypt-config"
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if test -n "$cross_prefix"
|
||||
then
|
||||
host=`libgcrypt-config --host`
|
||||
if test "$host-" != $cross_prefix
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
if test "$gcrypt" != "no"; then
|
||||
if has_libgcrypt_config; then
|
||||
gcrypt_cflags=`libgcrypt-config --cflags`
|
||||
gcrypt_libs=`libgcrypt-config --libs`
|
||||
# Debian has remove -lgpg-error from libgcrypt-config
|
||||
# as it "spreads unnecessary dependencies" which in
|
||||
# turn breaks static builds...
|
||||
if test "$static" = "yes"
|
||||
then
|
||||
gcrypt_libs="$gcrypt_libs -lgpg-error"
|
||||
fi
|
||||
libs_softmmu="$gcrypt_libs $libs_softmmu"
|
||||
libs_tools="$gcrypt_libs $libs_tools"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
|
||||
gcrypt="yes"
|
||||
if test -z "$nettle"; then
|
||||
nettle="no"
|
||||
fi
|
||||
else
|
||||
feature_not_found "gcrypt" "Install gcrypt devel"
|
||||
if test "$gcrypt" = "yes"; then
|
||||
feature_not_found "gcrypt" "Install gcrypt devel"
|
||||
else
|
||||
gcrypt="no"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if test "$gnutls_nettle" != "no"; then
|
||||
if test "$nettle" != "no"; then
|
||||
if $pkg_config --exists "nettle"; then
|
||||
nettle_cflags=`$pkg_config --cflags nettle`
|
||||
nettle_libs=`$pkg_config --libs nettle`
|
||||
|
@ -2275,20 +2340,30 @@ if test "$gnutls_nettle" != "no"; then
|
|||
libs_softmmu="$nettle_libs $libs_softmmu"
|
||||
libs_tools="$nettle_libs $libs_tools"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
|
||||
nettle="yes"
|
||||
else
|
||||
feature_not_found "nettle" "Install nettle devel"
|
||||
if test "$nettle" = "yes"; then
|
||||
feature_not_found "nettle" "Install nettle devel"
|
||||
else
|
||||
nettle="no"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$gcrypt" = "yes" && test "$nettle" = "yes"
|
||||
then
|
||||
error_exit "Only one of gcrypt & nettle can be enabled"
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# libtasn1 - only for the TLS creds/session test suite
|
||||
|
||||
tasn1=yes
|
||||
tasn1_cflags=""
|
||||
tasn1_libs=""
|
||||
if $pkg_config --exists "libtasn1"; then
|
||||
tasn1_cflags=`$pkg_config --cflags libtasn1`
|
||||
tasn1_libs=`$pkg_config --libs libtasn1`
|
||||
test_cflags="$test_cflags $tasn1_cflags"
|
||||
test_libs="$test_libs $tasn1_libs"
|
||||
else
|
||||
tasn1=no
|
||||
fi
|
||||
|
@ -4621,8 +4696,8 @@ echo "GTK support $gtk"
|
|||
echo "GTK GL support $gtk_gl"
|
||||
echo "GNUTLS support $gnutls"
|
||||
echo "GNUTLS hash $gnutls_hash"
|
||||
echo "GNUTLS gcrypt $gnutls_gcrypt"
|
||||
echo "GNUTLS nettle $gnutls_nettle ${gnutls_nettle+($nettle_version)}"
|
||||
echo "libgcrypt $gcrypt"
|
||||
echo "nettle $nettle ${nettle+($nettle_version)}"
|
||||
echo "libtasn1 $tasn1"
|
||||
echo "VTE support $vte"
|
||||
echo "curses support $curses"
|
||||
|
@ -4991,11 +5066,11 @@ fi
|
|||
if test "$gnutls_hash" = "yes" ; then
|
||||
echo "CONFIG_GNUTLS_HASH=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$gnutls_gcrypt" = "yes" ; then
|
||||
echo "CONFIG_GNUTLS_GCRYPT=y" >> $config_host_mak
|
||||
if test "$gcrypt" = "yes" ; then
|
||||
echo "CONFIG_GCRYPT=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$gnutls_nettle" = "yes" ; then
|
||||
echo "CONFIG_GNUTLS_NETTLE=y" >> $config_host_mak
|
||||
if test "$nettle" = "yes" ; then
|
||||
echo "CONFIG_NETTLE=y" >> $config_host_mak
|
||||
echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
|
||||
fi
|
||||
if test "$tasn1" = "yes" ; then
|
||||
|
@ -5330,8 +5405,8 @@ echo "EXESUF=$EXESUF" >> $config_host_mak
|
|||
echo "DSOSUF=$DSOSUF" >> $config_host_mak
|
||||
echo "LDFLAGS_SHARED=$LDFLAGS_SHARED" >> $config_host_mak
|
||||
echo "LIBS_QGA+=$libs_qga" >> $config_host_mak
|
||||
echo "TEST_LIBS=$test_libs" >> $config_host_mak
|
||||
echo "TEST_CFLAGS=$test_cflags" >> $config_host_mak
|
||||
echo "TASN1_LIBS=$tasn1_libs" >> $config_host_mak
|
||||
echo "TASN1_CFLAGS=$tasn1_cflags" >> $config_host_mak
|
||||
echo "POD2MAN=$POD2MAN" >> $config_host_mak
|
||||
echo "TRANSLATE_OPT_CFLAGS=$TRANSLATE_OPT_CFLAGS" >> $config_host_mak
|
||||
if test "$gcov" = "yes" ; then
|
||||
|
|
|
@ -25,8 +25,7 @@ typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
|
|||
struct QCryptoCipherBuiltinAES {
|
||||
AES_KEY encrypt_key;
|
||||
AES_KEY decrypt_key;
|
||||
uint8_t *iv;
|
||||
size_t niv;
|
||||
uint8_t iv[AES_BLOCK_SIZE];
|
||||
};
|
||||
typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
|
||||
struct QCryptoCipherBuiltinDESRFB {
|
||||
|
@ -40,6 +39,7 @@ struct QCryptoCipherBuiltin {
|
|||
QCryptoCipherBuiltinAES aes;
|
||||
QCryptoCipherBuiltinDESRFB desrfb;
|
||||
} state;
|
||||
size_t blocksize;
|
||||
void (*free)(QCryptoCipher *cipher);
|
||||
int (*setiv)(QCryptoCipher *cipher,
|
||||
const uint8_t *iv, size_t niv,
|
||||
|
@ -61,7 +61,6 @@ static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
|
|||
{
|
||||
QCryptoCipherBuiltin *ctxt = cipher->opaque;
|
||||
|
||||
g_free(ctxt->state.aes.iv);
|
||||
g_free(ctxt);
|
||||
cipher->opaque = NULL;
|
||||
}
|
||||
|
@ -145,15 +144,13 @@ static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
|
|||
Error **errp)
|
||||
{
|
||||
QCryptoCipherBuiltin *ctxt = cipher->opaque;
|
||||
if (niv != 16) {
|
||||
error_setg(errp, "IV must be 16 bytes not %zu", niv);
|
||||
if (niv != AES_BLOCK_SIZE) {
|
||||
error_setg(errp, "IV must be %d bytes not %zu",
|
||||
AES_BLOCK_SIZE, niv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_free(ctxt->state.aes.iv);
|
||||
ctxt->state.aes.iv = g_new0(uint8_t, niv);
|
||||
memcpy(ctxt->state.aes.iv, iv, niv);
|
||||
ctxt->state.aes.niv = niv;
|
||||
memcpy(ctxt->state.aes.iv, iv, AES_BLOCK_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -185,6 +182,7 @@ static int qcrypto_cipher_init_aes(QCryptoCipher *cipher,
|
|||
goto error;
|
||||
}
|
||||
|
||||
ctxt->blocksize = AES_BLOCK_SIZE;
|
||||
ctxt->free = qcrypto_cipher_free_aes;
|
||||
ctxt->setiv = qcrypto_cipher_setiv_aes;
|
||||
ctxt->encrypt = qcrypto_cipher_encrypt_aes;
|
||||
|
@ -286,6 +284,7 @@ static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,
|
|||
memcpy(ctxt->state.desrfb.key, key, nkey);
|
||||
ctxt->state.desrfb.nkey = nkey;
|
||||
|
||||
ctxt->blocksize = 8;
|
||||
ctxt->free = qcrypto_cipher_free_des_rfb;
|
||||
ctxt->setiv = qcrypto_cipher_setiv_des_rfb;
|
||||
ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
|
||||
|
@ -374,6 +373,12 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
|
|||
{
|
||||
QCryptoCipherBuiltin *ctxt = cipher->opaque;
|
||||
|
||||
if (len % ctxt->blocksize) {
|
||||
error_setg(errp, "Length %zu must be a multiple of block size %zu",
|
||||
len, ctxt->blocksize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ctxt->encrypt(cipher, in, out, len, errp);
|
||||
}
|
||||
|
||||
|
@ -386,6 +391,12 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
|
|||
{
|
||||
QCryptoCipherBuiltin *ctxt = cipher->opaque;
|
||||
|
||||
if (len % ctxt->blocksize) {
|
||||
error_setg(errp, "Length %zu must be a multiple of block size %zu",
|
||||
len, ctxt->blocksize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ctxt->decrypt(cipher, in, out, len, errp);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,11 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct QCryptoCipherGcrypt QCryptoCipherGcrypt;
|
||||
struct QCryptoCipherGcrypt {
|
||||
gcry_cipher_hd_t handle;
|
||||
size_t blocksize;
|
||||
};
|
||||
|
||||
QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
||||
QCryptoCipherMode mode,
|
||||
|
@ -41,7 +46,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
|||
Error **errp)
|
||||
{
|
||||
QCryptoCipher *cipher;
|
||||
gcry_cipher_hd_t handle;
|
||||
QCryptoCipherGcrypt *ctx;
|
||||
gcry_error_t err;
|
||||
int gcryalg, gcrymode;
|
||||
|
||||
|
@ -87,7 +92,9 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
|||
cipher->alg = alg;
|
||||
cipher->mode = mode;
|
||||
|
||||
err = gcry_cipher_open(&handle, gcryalg, gcrymode, 0);
|
||||
ctx = g_new0(QCryptoCipherGcrypt, 1);
|
||||
|
||||
err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
|
||||
if (err != 0) {
|
||||
error_setg(errp, "Cannot initialize cipher: %s",
|
||||
gcry_strerror(err));
|
||||
|
@ -100,10 +107,12 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
|||
* bizarre RFB variant of DES :-)
|
||||
*/
|
||||
uint8_t *rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
|
||||
err = gcry_cipher_setkey(handle, rfbkey, nkey);
|
||||
err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
|
||||
g_free(rfbkey);
|
||||
ctx->blocksize = 8;
|
||||
} else {
|
||||
err = gcry_cipher_setkey(handle, key, nkey);
|
||||
err = gcry_cipher_setkey(ctx->handle, key, nkey);
|
||||
ctx->blocksize = 16;
|
||||
}
|
||||
if (err != 0) {
|
||||
error_setg(errp, "Cannot set key: %s",
|
||||
|
@ -111,11 +120,12 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
|||
goto error;
|
||||
}
|
||||
|
||||
cipher->opaque = handle;
|
||||
cipher->opaque = ctx;
|
||||
return cipher;
|
||||
|
||||
error:
|
||||
gcry_cipher_close(handle);
|
||||
gcry_cipher_close(ctx->handle);
|
||||
g_free(ctx);
|
||||
g_free(cipher);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -123,12 +133,13 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
|||
|
||||
void qcrypto_cipher_free(QCryptoCipher *cipher)
|
||||
{
|
||||
gcry_cipher_hd_t handle;
|
||||
QCryptoCipherGcrypt *ctx;
|
||||
if (!cipher) {
|
||||
return;
|
||||
}
|
||||
handle = cipher->opaque;
|
||||
gcry_cipher_close(handle);
|
||||
ctx = cipher->opaque;
|
||||
gcry_cipher_close(ctx->handle);
|
||||
g_free(ctx);
|
||||
g_free(cipher);
|
||||
}
|
||||
|
||||
|
@ -139,10 +150,16 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
|
|||
size_t len,
|
||||
Error **errp)
|
||||
{
|
||||
gcry_cipher_hd_t handle = cipher->opaque;
|
||||
QCryptoCipherGcrypt *ctx = cipher->opaque;
|
||||
gcry_error_t err;
|
||||
|
||||
err = gcry_cipher_encrypt(handle,
|
||||
if (len % ctx->blocksize) {
|
||||
error_setg(errp, "Length %zu must be a multiple of block size %zu",
|
||||
len, ctx->blocksize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = gcry_cipher_encrypt(ctx->handle,
|
||||
out, len,
|
||||
in, len);
|
||||
if (err != 0) {
|
||||
|
@ -161,10 +178,16 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
|
|||
size_t len,
|
||||
Error **errp)
|
||||
{
|
||||
gcry_cipher_hd_t handle = cipher->opaque;
|
||||
QCryptoCipherGcrypt *ctx = cipher->opaque;
|
||||
gcry_error_t err;
|
||||
|
||||
err = gcry_cipher_decrypt(handle,
|
||||
if (len % ctx->blocksize) {
|
||||
error_setg(errp, "Length %zu must be a multiple of block size %zu",
|
||||
len, ctx->blocksize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = gcry_cipher_decrypt(ctx->handle,
|
||||
out, len,
|
||||
in, len);
|
||||
if (err != 0) {
|
||||
|
@ -180,11 +203,17 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
|
|||
const uint8_t *iv, size_t niv,
|
||||
Error **errp)
|
||||
{
|
||||
gcry_cipher_hd_t handle = cipher->opaque;
|
||||
QCryptoCipherGcrypt *ctx = cipher->opaque;
|
||||
gcry_error_t err;
|
||||
|
||||
gcry_cipher_reset(handle);
|
||||
err = gcry_cipher_setiv(handle, iv, niv);
|
||||
if (niv != ctx->blocksize) {
|
||||
error_setg(errp, "Expected IV size %zu not %zu",
|
||||
ctx->blocksize, niv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gcry_cipher_reset(ctx->handle);
|
||||
err = gcry_cipher_setiv(ctx->handle, iv, niv);
|
||||
if (err != 0) {
|
||||
error_setg(errp, "Cannot set IV: %s",
|
||||
gcry_strerror(err));
|
||||
|
|
|
@ -69,7 +69,7 @@ struct QCryptoCipherNettle {
|
|||
nettle_cipher_func *alg_encrypt;
|
||||
nettle_cipher_func *alg_decrypt;
|
||||
uint8_t *iv;
|
||||
size_t niv;
|
||||
size_t blocksize;
|
||||
};
|
||||
|
||||
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
|
||||
|
@ -125,7 +125,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
|||
ctx->alg_encrypt = des_encrypt_wrapper;
|
||||
ctx->alg_decrypt = des_decrypt_wrapper;
|
||||
|
||||
ctx->niv = DES_BLOCK_SIZE;
|
||||
ctx->blocksize = DES_BLOCK_SIZE;
|
||||
break;
|
||||
|
||||
case QCRYPTO_CIPHER_ALG_AES_128:
|
||||
|
@ -140,14 +140,14 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
|||
ctx->alg_encrypt = aes_encrypt_wrapper;
|
||||
ctx->alg_decrypt = aes_decrypt_wrapper;
|
||||
|
||||
ctx->niv = AES_BLOCK_SIZE;
|
||||
ctx->blocksize = AES_BLOCK_SIZE;
|
||||
break;
|
||||
default:
|
||||
error_setg(errp, "Unsupported cipher algorithm %d", alg);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ctx->iv = g_new0(uint8_t, ctx->niv);
|
||||
ctx->iv = g_new0(uint8_t, ctx->blocksize);
|
||||
cipher->opaque = ctx;
|
||||
|
||||
return cipher;
|
||||
|
@ -184,6 +184,12 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
|
|||
{
|
||||
QCryptoCipherNettle *ctx = cipher->opaque;
|
||||
|
||||
if (len % ctx->blocksize) {
|
||||
error_setg(errp, "Length %zu must be a multiple of block size %zu",
|
||||
len, ctx->blocksize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (cipher->mode) {
|
||||
case QCRYPTO_CIPHER_MODE_ECB:
|
||||
ctx->alg_encrypt(ctx->ctx_encrypt, len, out, in);
|
||||
|
@ -191,7 +197,7 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
|
|||
|
||||
case QCRYPTO_CIPHER_MODE_CBC:
|
||||
cbc_encrypt(ctx->ctx_encrypt, ctx->alg_encrypt,
|
||||
ctx->niv, ctx->iv,
|
||||
ctx->blocksize, ctx->iv,
|
||||
len, out, in);
|
||||
break;
|
||||
default:
|
||||
|
@ -211,6 +217,12 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
|
|||
{
|
||||
QCryptoCipherNettle *ctx = cipher->opaque;
|
||||
|
||||
if (len % ctx->blocksize) {
|
||||
error_setg(errp, "Length %zu must be a multiple of block size %zu",
|
||||
len, ctx->blocksize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (cipher->mode) {
|
||||
case QCRYPTO_CIPHER_MODE_ECB:
|
||||
ctx->alg_decrypt(ctx->ctx_decrypt ? ctx->ctx_decrypt : ctx->ctx_encrypt,
|
||||
|
@ -219,7 +231,7 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
|
|||
|
||||
case QCRYPTO_CIPHER_MODE_CBC:
|
||||
cbc_decrypt(ctx->ctx_decrypt ? ctx->ctx_decrypt : ctx->ctx_encrypt,
|
||||
ctx->alg_decrypt, ctx->niv, ctx->iv,
|
||||
ctx->alg_decrypt, ctx->blocksize, ctx->iv,
|
||||
len, out, in);
|
||||
break;
|
||||
default:
|
||||
|
@ -235,9 +247,9 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
|
|||
Error **errp)
|
||||
{
|
||||
QCryptoCipherNettle *ctx = cipher->opaque;
|
||||
if (niv != ctx->niv) {
|
||||
if (niv != ctx->blocksize) {
|
||||
error_setg(errp, "Expected IV size %zu not %zu",
|
||||
ctx->niv, niv);
|
||||
ctx->blocksize, niv);
|
||||
return -1;
|
||||
}
|
||||
memcpy(ctx->iv, iv, niv);
|
||||
|
|
|
@ -47,7 +47,7 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_GNUTLS_GCRYPT) || defined(CONFIG_GNUTLS_NETTLE)
|
||||
#if defined(CONFIG_GCRYPT) || defined(CONFIG_NETTLE)
|
||||
static uint8_t *
|
||||
qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
|
||||
size_t nkey)
|
||||
|
@ -63,11 +63,11 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_GNUTLS_GCRYPT || CONFIG_GNUTLS_NETTLE */
|
||||
#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
|
||||
|
||||
#ifdef CONFIG_GNUTLS_GCRYPT
|
||||
#ifdef CONFIG_GCRYPT
|
||||
#include "crypto/cipher-gcrypt.c"
|
||||
#elif defined CONFIG_GNUTLS_NETTLE
|
||||
#elif defined CONFIG_NETTLE
|
||||
#include "crypto/cipher-nettle.c"
|
||||
#else
|
||||
#include "crypto/cipher-builtin.c"
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
#ifdef CONFIG_GNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GNUTLS_GCRYPT
|
||||
#ifdef CONFIG_GCRYPT
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
|
@ -37,6 +38,7 @@
|
|||
* - When GNUTLS >= 2.12, we must not initialize gcrypt threading
|
||||
* because GNUTLS will do that itself
|
||||
* - When GNUTLS < 2.12 we must always initialize gcrypt threading
|
||||
* - When GNUTLS is disabled we must always initialize gcrypt threading
|
||||
*
|
||||
* But....
|
||||
*
|
||||
|
@ -47,12 +49,15 @@
|
|||
*
|
||||
* - gcrypt < 1.6.0
|
||||
* AND
|
||||
* - gnutls < 2.12
|
||||
* - gnutls < 2.12
|
||||
* OR
|
||||
* - gnutls is disabled
|
||||
*
|
||||
*/
|
||||
|
||||
#if (defined(CONFIG_GNUTLS_GCRYPT) && \
|
||||
(!defined(GNUTLS_VERSION_NUMBER) || \
|
||||
#if (defined(CONFIG_GCRYPT) && \
|
||||
(!defined(CONFIG_GNUTLS) || \
|
||||
!defined(GNUTLS_VERSION_NUMBER) || \
|
||||
(GNUTLS_VERSION_NUMBER < 0x020c00)) && \
|
||||
(!defined(GCRYPT_VERSION_NUMBER) || \
|
||||
(GCRYPT_VERSION_NUMBER < 0x010600)))
|
||||
|
@ -113,6 +118,7 @@ static struct gcry_thread_cbs qcrypto_gcrypt_thread_impl = {
|
|||
|
||||
int qcrypto_init(Error **errp)
|
||||
{
|
||||
#ifdef CONFIG_GNUTLS
|
||||
int ret;
|
||||
ret = gnutls_global_init();
|
||||
if (ret < 0) {
|
||||
|
@ -125,8 +131,9 @@ int qcrypto_init(Error **errp)
|
|||
gnutls_global_set_log_level(10);
|
||||
gnutls_global_set_log_function(qcrypto_gnutls_log);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GNUTLS_GCRYPT
|
||||
#ifdef CONFIG_GCRYPT
|
||||
if (!gcry_check_version(GCRYPT_VERSION)) {
|
||||
error_setg(errp, "Unable to initialize gcrypt");
|
||||
return -1;
|
||||
|
@ -139,12 +146,3 @@ int qcrypto_init(Error **errp)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* ! CONFIG_GNUTLS */
|
||||
|
||||
int qcrypto_init(Error **errp G_GNUC_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ! CONFIG_GNUTLS */
|
||||
|
|
|
@ -444,8 +444,16 @@ tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y)
|
|||
tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y)
|
||||
tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
|
||||
tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
|
||||
|
||||
tests/crypto-tls-x509-helpers.o-cflags := $(TASN1_CFLAGS)
|
||||
tests/crypto-tls-x509-helpers.o-libs := $(TASN1_LIBS)
|
||||
tests/pkix_asn1_tab.o-cflags := $(TASN1_CFLAGS)
|
||||
|
||||
tests/test-crypto-tlscredsx509.o-cflags := $(TASN1_CFLAGS)
|
||||
tests/test-crypto-tlscredsx509$(EXESUF): tests/test-crypto-tlscredsx509.o \
|
||||
tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y)
|
||||
|
||||
tests/test-crypto-tlssession.o-cflags := $(TASN1_CFLAGS)
|
||||
tests/test-crypto-tlssession$(EXESUF): tests/test-crypto-tlssession.o \
|
||||
tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y)
|
||||
|
||||
|
@ -518,8 +526,6 @@ tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
|
|||
ifeq ($(CONFIG_POSIX),y)
|
||||
LIBS += -lutil
|
||||
endif
|
||||
LIBS += $(TEST_LIBS)
|
||||
CFLAGS += $(TEST_CFLAGS)
|
||||
|
||||
# QTest rules
|
||||
|
||||
|
|
|
@ -287,6 +287,79 @@ static void test_cipher(const void *opaque)
|
|||
qcrypto_cipher_free(cipher);
|
||||
}
|
||||
|
||||
|
||||
static void test_cipher_null_iv(void)
|
||||
{
|
||||
QCryptoCipher *cipher;
|
||||
uint8_t key[32] = { 0 };
|
||||
uint8_t plaintext[32] = { 0 };
|
||||
uint8_t ciphertext[32] = { 0 };
|
||||
|
||||
cipher = qcrypto_cipher_new(
|
||||
QCRYPTO_CIPHER_ALG_AES_256,
|
||||
QCRYPTO_CIPHER_MODE_CBC,
|
||||
key, sizeof(key),
|
||||
&error_abort);
|
||||
g_assert(cipher != NULL);
|
||||
|
||||
/* Don't call qcrypto_cipher_setiv */
|
||||
|
||||
qcrypto_cipher_encrypt(cipher,
|
||||
plaintext,
|
||||
ciphertext,
|
||||
sizeof(plaintext),
|
||||
&error_abort);
|
||||
|
||||
qcrypto_cipher_free(cipher);
|
||||
}
|
||||
|
||||
static void test_cipher_short_plaintext(void)
|
||||
{
|
||||
Error *err = NULL;
|
||||
QCryptoCipher *cipher;
|
||||
uint8_t key[32] = { 0 };
|
||||
uint8_t plaintext1[20] = { 0 };
|
||||
uint8_t ciphertext1[20] = { 0 };
|
||||
uint8_t plaintext2[40] = { 0 };
|
||||
uint8_t ciphertext2[40] = { 0 };
|
||||
int ret;
|
||||
|
||||
cipher = qcrypto_cipher_new(
|
||||
QCRYPTO_CIPHER_ALG_AES_256,
|
||||
QCRYPTO_CIPHER_MODE_CBC,
|
||||
key, sizeof(key),
|
||||
&error_abort);
|
||||
g_assert(cipher != NULL);
|
||||
|
||||
/* Should report an error as plaintext is shorter
|
||||
* than block size
|
||||
*/
|
||||
ret = qcrypto_cipher_encrypt(cipher,
|
||||
plaintext1,
|
||||
ciphertext1,
|
||||
sizeof(plaintext1),
|
||||
&err);
|
||||
g_assert(ret == -1);
|
||||
g_assert(err != NULL);
|
||||
|
||||
error_free(err);
|
||||
err = NULL;
|
||||
|
||||
/* Should report an error as plaintext is larger than
|
||||
* block size, but not a multiple of block size
|
||||
*/
|
||||
ret = qcrypto_cipher_encrypt(cipher,
|
||||
plaintext2,
|
||||
ciphertext2,
|
||||
sizeof(plaintext2),
|
||||
&err);
|
||||
g_assert(ret == -1);
|
||||
g_assert(err != NULL);
|
||||
|
||||
error_free(err);
|
||||
qcrypto_cipher_free(cipher);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -298,5 +371,12 @@ int main(int argc, char **argv)
|
|||
for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
|
||||
g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
|
||||
}
|
||||
|
||||
g_test_add_func("/crypto/cipher/null-iv",
|
||||
test_cipher_null_iv);
|
||||
|
||||
g_test_add_func("/crypto/cipher/short-plaintext",
|
||||
test_cipher_short_plaintext);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue