Commit 879c26fb authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/berrange/tags/pull-qcrypto-2016-03-17-3' into staging



Merge QCrypto 2016/03/17 v3

# gpg: Signature made Thu 17 Mar 2016 16:51:32 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-qcrypto-2016-03-17-3:
  crypto: implement the LUKS block encryption format
  crypto: add block encryption framework
  crypto: wire up XTS mode for cipher APIs
  crypto: refactor code for dealing with AES cipher
  crypto: import an implementation of the XTS cipher mode
  crypto: add support for the twofish cipher algorithm
  crypto: add support for the serpent cipher algorithm
  crypto: add support for the cast5-128 cipher algorithm
  crypto: skip testing of unsupported cipher algorithms
  crypto: add support for anti-forensic split algorithm
  crypto: add support for generating initialization vectors
  crypto: add support for PBKDF2 algorithm
  crypto: add cryptographic random byte source

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 6741d38a 3e308f20
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
#######################################################################
# Common libraries for tools and emulators
stub-obj-y = stubs/
stub-obj-y = stubs/ crypto/
util-obj-y = util/ qobject/ qapi/
util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o

+32 −0
Original line number Diff line number Diff line
@@ -306,8 +306,10 @@ gtkabi=""
gtk_gl="no"
gnutls=""
gnutls_hash=""
gnutls_rnd=""
nettle=""
gcrypt=""
gcrypt_kdf="no"
vte=""
virglrenderer=""
tpm="yes"
@@ -2201,6 +2203,13 @@ if test "$gnutls" != "no"; then
	    gnutls_hash="no"
	fi

	# gnutls_rnd requires >= 2.11.0
	if $pkg_config --exists "gnutls >= 2.11.0"; then
	    gnutls_rnd="yes"
	else
	    gnutls_rnd="no"
	fi

	if $pkg_config --exists 'gnutls >= 3.0'; then
	    gnutls_gcrypt=no
	    gnutls_nettle=yes
@@ -2228,9 +2237,11 @@ if test "$gnutls" != "no"; then
    else
        gnutls="no"
        gnutls_hash="no"
        gnutls_rnd="no"
    fi
else
    gnutls_hash="no"
    gnutls_rnd="no"
fi


@@ -2292,6 +2303,19 @@ if test "$gcrypt" != "no"; then
        if test -z "$nettle"; then
           nettle="no"
        fi

        cat > $TMPC << EOF
#include <gcrypt.h>
int main(void) {
  gcry_kdf_derive(NULL, 0, GCRY_KDF_PBKDF2,
                  GCRY_MD_SHA256,
                  NULL, 0, 0, 0, NULL);
 return 0;
}
EOF
        if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
            gcrypt_kdf=yes
        fi
    else
        if test "$gcrypt" = "yes"; then
            feature_not_found "gcrypt" "Install gcrypt devel"
@@ -4714,7 +4738,9 @@ echo "GTK support $gtk"
echo "GTK GL support    $gtk_gl"
echo "GNUTLS support    $gnutls"
echo "GNUTLS hash       $gnutls_hash"
echo "GNUTLS rnd        $gnutls_rnd"
echo "libgcrypt         $gcrypt"
echo "libgcrypt kdf     $gcrypt_kdf"
if test "$nettle" = "yes"; then
    echo "nettle            $nettle ($nettle_version)"
else
@@ -5092,8 +5118,14 @@ fi
if test "$gnutls_hash" = "yes" ; then
  echo "CONFIG_GNUTLS_HASH=y" >> $config_host_mak
fi
if test "$gnutls_rnd" = "yes" ; then
  echo "CONFIG_GNUTLS_RND=y" >> $config_host_mak
fi
if test "$gcrypt" = "yes" ; then
  echo "CONFIG_GCRYPT=y" >> $config_host_mak
  if test "$gcrypt_kdf" = "yes" ; then
    echo "CONFIG_GCRYPT_KDF=y" >> $config_host_mak
  fi
fi
if test "$nettle" = "yes" ; then
  echo "CONFIG_NETTLE=y" >> $config_host_mak
+17 −0
Original line number Diff line number Diff line
@@ -8,6 +8,23 @@ crypto-obj-y += tlscredsanon.o
crypto-obj-y += tlscredsx509.o
crypto-obj-y += tlssession.o
crypto-obj-y += secret.o
crypto-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS_RND)) += random-gnutls.o
crypto-obj-y += pbkdf.o
crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.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
crypto-obj-y += afsplit.o
crypto-obj-y += xts.o
crypto-obj-y += block.o
crypto-obj-y += block-qcow.o
crypto-obj-y += block-luks.o

# Let the userspace emulators avoid linking gnutls/etc
crypto-aes-obj-y = aes.o

stub-obj-y += random-stub.o
stub-obj-y += pbkdf-stub.o

crypto/afsplit.c

0 → 100644
+158 −0
Original line number Diff line number Diff line
/*
 * QEMU Crypto anti forensic information splitter
 *
 * Copyright (c) 2015-2016 Red Hat, Inc.
 *
 * Derived from cryptsetup package lib/luks1/af.c
 *
 * Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
 * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU 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/afsplit.h"
#include "crypto/random.h"


static void qcrypto_afsplit_xor(size_t blocklen,
                                const uint8_t *in1,
                                const uint8_t *in2,
                                uint8_t *out)
{
    size_t i;
    for (i = 0; i < blocklen; i++) {
        out[i] = in1[i] ^ in2[i];
    }
}


static int qcrypto_afsplit_hash(QCryptoHashAlgorithm hash,
                                size_t blocklen,
                                uint8_t *block,
                                Error **errp)
{
    size_t digestlen = qcrypto_hash_digest_len(hash);

    size_t hashcount = blocklen / digestlen;
    size_t finallen = blocklen % digestlen;
    uint32_t i;

    if (finallen) {
        hashcount++;
    } else {
        finallen = digestlen;
    }

    for (i = 0; i < hashcount; i++) {
        uint8_t *out = NULL;
        size_t outlen = 0;
        uint32_t iv = cpu_to_be32(i);
        struct iovec in[] = {
            { .iov_base = &iv,
              .iov_len = sizeof(iv) },
            { .iov_base = block + (i * digestlen),
              .iov_len = (i == (hashcount - 1)) ? finallen : digestlen },
        };

        if (qcrypto_hash_bytesv(hash,
                                in,
                                G_N_ELEMENTS(in),
                                &out, &outlen,
                                errp) < 0) {
            return -1;
        }

        assert(outlen == digestlen);
        memcpy(block + (i * digestlen), out,
               (i == (hashcount - 1)) ? finallen : digestlen);
        g_free(out);
    }

    return 0;
}


int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash,
                           size_t blocklen,
                           uint32_t stripes,
                           const uint8_t *in,
                           uint8_t *out,
                           Error **errp)
{
    uint8_t *block = g_new0(uint8_t, blocklen);
    size_t i;
    int ret = -1;

    for (i = 0; i < (stripes - 1); i++) {
        if (qcrypto_random_bytes(out + (i * blocklen), blocklen, errp) < 0) {
            goto cleanup;
        }

        qcrypto_afsplit_xor(blocklen,
                            out + (i * blocklen),
                            block,
                            block);
        if (qcrypto_afsplit_hash(hash, blocklen, block,
                                 errp) < 0) {
            goto cleanup;
        }
    }
    qcrypto_afsplit_xor(blocklen,
                        in,
                        block,
                        out + (i * blocklen));
    ret = 0;

 cleanup:
    g_free(block);
    return ret;
}


int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash,
                           size_t blocklen,
                           uint32_t stripes,
                           const uint8_t *in,
                           uint8_t *out,
                           Error **errp)
{
    uint8_t *block = g_new0(uint8_t, blocklen);
    size_t i;
    int ret = -1;

    for (i = 0; i < (stripes - 1); i++) {
        qcrypto_afsplit_xor(blocklen,
                            in + (i * blocklen),
                            block,
                            block);
        if (qcrypto_afsplit_hash(hash, blocklen, block,
                                 errp) < 0) {
            goto cleanup;
        }
    }

    qcrypto_afsplit_xor(blocklen,
                        in + (i * blocklen),
                        block,
                        out);

    ret = 0;

 cleanup:
    g_free(block);
    return ret;
}

crypto/block-luks.c

0 → 100644
+1328 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading