diff --git a/Makefile b/Makefile
index 7873ad40..53ede052 100644
--- a/Makefile
+++ b/Makefile
@@ -218,7 +218,7 @@ qemu/config-host.h-timestamp:
./configure --cc="${CC}" --extra-cflags="$(UNICORN_CFLAGS)" --target-list="$(UNICORN_TARGETS)" ${UNICORN_QEMU_FLAGS}
printf "$(UNICORN_ARCHS)" > config.log
$(MAKE) -C qemu $(SMP_MFLAGS)
- $(eval UC_TARGET_OBJ += $$(wildcard qemu/util/*.o) $$(wildcard qemu/*.o) $$(wildcard qemu/qom/*.o) $$(wildcard qemu/hw/core/*.o) $$(wildcard qemu/qapi/*.o) $$(wildcard qemu/qobject/*.o))
+ $(eval UC_TARGET_OBJ += $$(wildcard qemu/util/*.o) $$(wildcard qemu/*.o) $$(wildcard qemu/crypto/*.o) $$(wildcard qemu/qom/*.o) $$(wildcard qemu/hw/core/*.o) $$(wildcard qemu/qapi/*.o) $$(wildcard qemu/qobject/*.o))
unicorn: $(LIBRARY) $(ARCHIVE)
diff --git a/msvc/unicorn/unicorn/unicorn.vcxproj b/msvc/unicorn/unicorn/unicorn.vcxproj
index d9f2adeb..76338e17 100644
--- a/msvc/unicorn/unicorn/unicorn.vcxproj
+++ b/msvc/unicorn/unicorn/unicorn.vcxproj
@@ -195,6 +195,8 @@ copy $(SolutionDir)..\include\unicorn\*.h $(SolutionDir)distro\include\unicorn\
+
+
@@ -285,6 +287,8 @@ copy $(SolutionDir)..\include\unicorn\*.h $(SolutionDir)distro\include\unicorn\
+
+
diff --git a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
index 9b05cb69..6c3aa890 100644
--- a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
+++ b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
@@ -22,6 +22,8 @@
+
+
@@ -98,6 +100,8 @@
+
+
diff --git a/qemu/Makefile.objs b/qemu/Makefile.objs
index e8d4dfa5..e23f884f 100644
--- a/qemu/Makefile.objs
+++ b/qemu/Makefile.objs
@@ -1,6 +1,7 @@
#######################################################################
# Common libraries for tools and emulators
util-obj-y = util/ qobject/ qapi/ qapi-types.o qapi-visit.o
+util-obj-y += crypto/
#######################################################################
# block-obj-y is code used by both qemu system emulation and qemu-img
diff --git a/qemu/aarch64.h b/qemu/aarch64.h
index ef3453cc..cbc777c9 100644
--- a/qemu/aarch64.h
+++ b/qemu/aarch64.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_aarch64
#define qbus_initfn qbus_initfn_aarch64
#define qbus_realize qbus_realize_aarch64
+#define qcrypto_hash_base64 qcrypto_hash_base64_aarch64
+#define qcrypto_hash_base64v qcrypto_hash_base64v_aarch64
+#define qcrypto_hash_bytes qcrypto_hash_bytes_aarch64
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_aarch64
+#define qcrypto_hash_digest qcrypto_hash_digest_aarch64
+#define qcrypto_hash_digestv qcrypto_hash_digestv_aarch64
+#define qcrypto_hash_supports qcrypto_hash_supports_aarch64
+#define qcrypto_init qcrypto_init_aarch64
#define qdev_create qdev_create_aarch64
#define qdev_get_type qdev_get_type_aarch64
#define qdev_register_types qdev_register_types_aarch64
diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h
index e3e491ca..2310c7f4 100644
--- a/qemu/aarch64eb.h
+++ b/qemu/aarch64eb.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_aarch64eb
#define qbus_initfn qbus_initfn_aarch64eb
#define qbus_realize qbus_realize_aarch64eb
+#define qcrypto_hash_base64 qcrypto_hash_base64_aarch64eb
+#define qcrypto_hash_base64v qcrypto_hash_base64v_aarch64eb
+#define qcrypto_hash_bytes qcrypto_hash_bytes_aarch64eb
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_aarch64eb
+#define qcrypto_hash_digest qcrypto_hash_digest_aarch64eb
+#define qcrypto_hash_digestv qcrypto_hash_digestv_aarch64eb
+#define qcrypto_hash_supports qcrypto_hash_supports_aarch64eb
+#define qcrypto_init qcrypto_init_aarch64eb
#define qdev_create qdev_create_aarch64eb
#define qdev_get_type qdev_get_type_aarch64eb
#define qdev_register_types qdev_register_types_aarch64eb
diff --git a/qemu/arm.h b/qemu/arm.h
index 3d30070c..cf8b9545 100644
--- a/qemu/arm.h
+++ b/qemu/arm.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_arm
#define qbus_initfn qbus_initfn_arm
#define qbus_realize qbus_realize_arm
+#define qcrypto_hash_base64 qcrypto_hash_base64_arm
+#define qcrypto_hash_base64v qcrypto_hash_base64v_arm
+#define qcrypto_hash_bytes qcrypto_hash_bytes_arm
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_arm
+#define qcrypto_hash_digest qcrypto_hash_digest_arm
+#define qcrypto_hash_digestv qcrypto_hash_digestv_arm
+#define qcrypto_hash_supports qcrypto_hash_supports_arm
+#define qcrypto_init qcrypto_init_arm
#define qdev_create qdev_create_arm
#define qdev_get_type qdev_get_type_arm
#define qdev_register_types qdev_register_types_arm
diff --git a/qemu/armeb.h b/qemu/armeb.h
index 5488361d..4496c15a 100644
--- a/qemu/armeb.h
+++ b/qemu/armeb.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_armeb
#define qbus_initfn qbus_initfn_armeb
#define qbus_realize qbus_realize_armeb
+#define qcrypto_hash_base64 qcrypto_hash_base64_armeb
+#define qcrypto_hash_base64v qcrypto_hash_base64v_armeb
+#define qcrypto_hash_bytes qcrypto_hash_bytes_armeb
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_armeb
+#define qcrypto_hash_digest qcrypto_hash_digest_armeb
+#define qcrypto_hash_digestv qcrypto_hash_digestv_armeb
+#define qcrypto_hash_supports qcrypto_hash_supports_armeb
+#define qcrypto_init qcrypto_init_armeb
#define qdev_create qdev_create_armeb
#define qdev_get_type qdev_get_type_armeb
#define qdev_register_types qdev_register_types_armeb
diff --git a/qemu/crypto/Makefile.objs b/qemu/crypto/Makefile.objs
new file mode 100644
index 00000000..3ac3dfa2
--- /dev/null
+++ b/qemu/crypto/Makefile.objs
@@ -0,0 +1,2 @@
+util-obj-y = init.o
+util-obj-y += hash.o
\ No newline at end of file
diff --git a/qemu/crypto/hash.c b/qemu/crypto/hash.c
new file mode 100644
index 00000000..e799ac55
--- /dev/null
+++ b/qemu/crypto/hash.c
@@ -0,0 +1,199 @@
+/*
+ * 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 .
+ *
+ */
+
+#include "crypto/hash.h"
+
+#ifdef CONFIG_GNUTLS_HASH
+#include
+#include
+
+static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG_LAST] = {
+ GNUTLS_DIG_MD5,
+ GNUTLS_DIG_SHA1,
+ GNUTLS_DIG_SHA256,
+};
+
+gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
+{
+ if (alg < (sizeof(qcrypto_hash_alg_map) / sizeof(qcrypto_hash_alg_map[0]))) {
+ return true;
+ }
+ return false;
+}
+
+int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
+ const struct iovec *iov,
+ size_t niov,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ int i, ret;
+ gnutls_hash_hd_t dig;
+
+ if (alg >= (sizeof(qcrypto_hash_alg_map) / sizeof(qcrypto_hash_alg_map[0]))) {
+ error_setg(errp,
+ "Unknown hash algorithm %d",
+ alg);
+ return -1;
+ }
+
+ ret = gnutls_hash_init(&dig, qcrypto_hash_alg_map[alg]);
+
+ if (ret < 0) {
+ error_setg(errp,
+ "Unable to initialize hash algorithm: %s",
+ gnutls_strerror(ret));
+ return -1;
+ }
+
+ for (i = 0; i < niov; i++) {
+ ret = gnutls_hash(dig, iov[i].iov_base, iov[i].iov_len);
+ if (ret < 0) {
+ error_setg(errp,
+ "Unable process hash data: %s",
+ gnutls_strerror(ret));
+ goto error;
+ }
+ }
+
+ ret = gnutls_hash_get_len(qcrypto_hash_alg_map[alg]);
+ if (ret <= 0) {
+ error_setg(errp,
+ "Unable to get hash length: %s",
+ gnutls_strerror(ret));
+ goto error;
+ }
+ if (*resultlen == 0) {
+ *resultlen = ret;
+ *result = g_new0(uint8_t, *resultlen);
+ } else if (*resultlen != ret) {
+ error_setg(errp,
+ "Result buffer size %zu is smaller than hash %d",
+ *resultlen, ret);
+ goto error;
+ }
+
+ gnutls_hash_deinit(dig, *result);
+ return 0;
+
+ error:
+ gnutls_hash_deinit(dig, NULL);
+ return -1;
+}
+
+#else /* ! CONFIG_GNUTLS_HASH */
+
+gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
+{
+ return false;
+}
+
+int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
+ const struct iovec *iov,
+ size_t niov,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ error_setg(errp,
+ "Hash algorithm %d not supported without GNUTLS",
+ alg);
+ return -1;
+}
+
+#endif /* ! CONFIG_GNUTLS_HASH */
+
+int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
+ const char *buf,
+ size_t len,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ struct iovec iov = { (char *)buf, len };
+ return qcrypto_hash_bytesv(alg, &iov, 1, result, resultlen, errp);
+}
+
+static const char hex[] = "0123456789abcdef";
+
+int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
+ const struct iovec *iov,
+ size_t niov,
+ char **digest,
+ Error **errp)
+{
+ uint8_t *result = NULL;
+ size_t resultlen = 0;
+ size_t i;
+
+ if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) {
+ return -1;
+ }
+
+ *digest = g_new0(char, (resultlen * 2) + 1);
+ for (i = 0 ; i < resultlen ; i++) {
+ (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
+ (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
+ }
+ (*digest)[resultlen * 2] = '\0';
+ g_free(result);
+ return 0;
+}
+
+int qcrypto_hash_digest(QCryptoHashAlgorithm alg,
+ const char *buf,
+ size_t len,
+ char **digest,
+ Error **errp)
+{
+ struct iovec iov = { (char *)buf, len };
+
+ return qcrypto_hash_digestv(alg, &iov, 1, digest, errp);
+}
+
+int qcrypto_hash_base64v(QCryptoHashAlgorithm alg,
+ const struct iovec *iov,
+ size_t niov,
+ char **base64,
+ Error **errp)
+{
+ uint8_t *result = NULL;
+ size_t resultlen = 0;
+
+ if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) {
+ return -1;
+ }
+
+ *base64 = g_base64_encode(result, resultlen);
+ g_free(result);
+ return 0;
+}
+
+int qcrypto_hash_base64(QCryptoHashAlgorithm alg,
+ const char *buf,
+ size_t len,
+ char **base64,
+ Error **errp)
+{
+ struct iovec iov = { (char *)buf, len };
+
+ return qcrypto_hash_base64v(alg, &iov, 1, base64, errp);
+}
diff --git a/qemu/crypto/init.c b/qemu/crypto/init.c
new file mode 100644
index 00000000..50d13e6e
--- /dev/null
+++ b/qemu/crypto/init.c
@@ -0,0 +1,60 @@
+/*
+ * 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 .
+ *
+ */
+
+#include "crypto/init.h"
+
+#ifdef CONFIG_GNUTLS
+#include
+#include
+
+/* #define DEBUG_GNUTLS */
+
+#ifdef DEBUG_GNUTLS
+static void qcrypto_gnutls_log(int level, const char *str)
+{
+ fprintf(stderr, "%d: %s", level, str);
+}
+#endif
+
+int qcrypto_init(Error **errp)
+{
+ int ret;
+ ret = gnutls_global_init();
+ if (ret < 0) {
+ error_setg(errp,
+ "Unable to initialize GNUTLS library: %s",
+ gnutls_strerror(ret));
+ return -1;
+ }
+#ifdef DEBUG_GNUTLS
+ gnutls_global_set_log_level(10);
+ gnutls_global_set_log_function(qcrypto_gnutls_log);
+#endif
+ return 0;
+}
+
+#else /* ! CONFIG_GNUTLS */
+
+int qcrypto_init(Error **errp)
+{
+ return 0;
+}
+
+#endif /* ! CONFIG_GNUTLS */
diff --git a/qemu/glib_compat.c b/qemu/glib_compat.c
index 13225524..3afa7fe5 100644
--- a/qemu/glib_compat.c
+++ b/qemu/glib_compat.c
@@ -1452,3 +1452,286 @@ gchar** g_strsplit (const gchar *string,
return str_array;
}
+
+static const char base64_alphabet[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static gsize g_base64_encode_step(const guchar *in, gsize len,
+ gboolean break_lines,
+ gchar *out, gint *state,
+ gint *save)
+{
+ char *outptr;
+ const guchar *inptr;
+
+ if (in == NULL || out == NULL || state == NULL || save == NULL) {
+ return 0;
+ }
+
+ if (len <= 0) {
+ return 0;
+ }
+
+ inptr = in;
+ outptr = out;
+
+ if (len + ((char *) save) [0] > 2)
+ {
+ const guchar *inend = in + len - 2;
+ int c1, c2, c3;
+ int already;
+
+ already = *state;
+
+ switch (((char *) save)[0])
+ {
+ case 1:
+ c1 = ((unsigned char *) save)[1];
+ goto skip1;
+ case 2:
+ c1 = ((unsigned char *) save)[1];
+ c2 = ((unsigned char *) save)[2];
+ goto skip2;
+ }
+
+ /*
+ * yes, we jump into the loop, no i'm not going to change it,
+ * it's beautiful!
+ */
+ while (inptr < inend)
+ {
+ c1 = *inptr++;
+ skip1:
+ c2 = *inptr++;
+ skip2:
+ c3 = *inptr++;
+ *outptr++ = base64_alphabet[c1 >> 2];
+ *outptr++ = base64_alphabet[c2 >> 4 | ((c1 & 0x3) << 4)];
+ *outptr++ = base64_alphabet[((c2 & 0x0f) << 2) | (c3 >> 6)];
+ *outptr++ = base64_alphabet[c3 & 0x3f];
+ /* this is a bit ugly ... */
+ if (break_lines && (++already) >= 19)
+ {
+ *outptr++ = '\n';
+ already = 0;
+ }
+ }
+
+ ((char *)save)[0] = 0;
+ len = 2 - (inptr - inend);
+ *state = already;
+ }
+
+ if (len > 0)
+ {
+ char *saveout;
+
+ /* points to the slot for the next char to save */
+ saveout = & (((char *)save)[1]) + ((char *)save)[0];
+
+ /* len can only be 0 1 or 2 */
+ switch (len)
+ {
+ case 2: *saveout++ = *inptr++;
+ case 1: *saveout++ = *inptr++;
+ }
+ ((char *) save)[0] += len;
+ }
+
+ return outptr - out;
+}
+
+gsize g_base64_encode_close(gboolean break_lines, gchar *out,
+ gint *state, gint *save)
+{
+ int c1, c2;
+ char *outptr = out;
+
+ if (out == NULL || state == NULL || save == NULL) {
+ return 0;
+ }
+
+ c1 = ((unsigned char *) save)[1];
+ c2 = ((unsigned char *) save)[2];
+
+ switch (((char *) save)[0])
+ {
+ case 2:
+ outptr[2] = base64_alphabet[((c2 &0x0f) << 2)];
+ g_assert(outptr[2] != 0);
+ goto skip;
+ case 1:
+ outptr[2] = '=';
+ c2 = 0; /* saved state here is not relevant */
+ skip:
+ outptr[0] = base64_alphabet[c1 >> 2 ];
+ outptr[1] = base64_alphabet[c2 >> 4 | ((c1 & 0x3) << 4)];
+ outptr[3] = '=';
+ outptr += 4;
+ break;
+ }
+ if (break_lines) {
+ *outptr++ = '\n';
+ }
+
+ *save = 0;
+ *state = 0;
+
+ return outptr - out;
+}
+
+gchar *g_base64_encode(const guchar *data, gsize len)
+{
+ gchar *out;
+ gint state = 0, outlen;
+ gint save = 0;
+
+ if (data == NULL && len != 0) {
+ return NULL;
+ }
+
+ /* We can use a smaller limit here, since we know the saved state is 0,
+ +1 is needed for trailing \0, also check for unlikely integer overflow */
+ if (len >= ((SIZE_MAX - 1) / 4 - 1) * 3) {
+ //g_error("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)",
+ // G_STRLOC, len);
+ return NULL;
+ }
+
+ out = g_malloc((len / 3 + 1) * 4 + 1);
+
+ outlen = g_base64_encode_step(data, len, FALSE, out, &state, &save);
+ outlen += g_base64_encode_close(FALSE, out + outlen, &state, &save);
+ out[outlen] = '\0';
+
+ return (gchar *) out;
+}
+
+static const unsigned char mime_base64_rank[256] = {
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+};
+
+static gsize g_base64_decode_step(const gchar *in, gsize len,
+ guchar *out, gint *state,
+ guint *save)
+{
+ const guchar *inptr;
+ guchar *outptr;
+ const guchar *inend;
+ guchar c, rank;
+ guchar last[2];
+ unsigned int v;
+ int i;
+
+ if (in == NULL || out == NULL || state == NULL || save == NULL) {
+ return 0;
+ }
+
+ if (len <= 0) {
+ return 0;
+ }
+
+ inend = (const guchar *)in+len;
+ outptr = out;
+
+ /* convert 4 base64 bytes to 3 normal bytes */
+ v = *save;
+ i = *state;
+
+ last[0] = last[1] = 0;
+
+ /* we use the sign in the state to determine if we got a padding character
+ in the previous sequence */
+ if (i < 0)
+ {
+ i = -i;
+ last[0] = '=';
+ }
+
+ inptr = (const guchar *)in;
+ while (inptr < inend)
+ {
+ c = *inptr++;
+ rank = mime_base64_rank[c];
+ if (rank != 0xff)
+ {
+ last[1] = last[0];
+ last[0] = c;
+ v = (v << 6) | rank;
+ i++;
+ if (i == 4)
+ {
+ *outptr++ = v >> 16;
+ if (last[1] != '=') {
+ *outptr++ = v >> 8;
+ }
+ if (last[0] != '=') {
+ *outptr++ = v;
+ }
+ i = 0;
+ }
+ }
+ }
+
+ *save = v;
+ *state = last[0] == '=' ? -i : i;
+
+ return outptr - out;
+}
+
+guchar *g_base64_decode(const gchar *text, gsize *out_len)
+{
+ guchar *ret;
+ gsize input_length;
+ gint state = 0;
+ guint save = 0;
+
+ if (text == NULL || out_len == NULL) {
+ return NULL;
+ }
+
+ input_length = strlen(text);
+
+ /* We can use a smaller limit here, since we know the saved state is 0,
+ +1 used to avoid calling g_malloc0(0), and hence returning NULL */
+ ret = g_malloc0((input_length / 4) * 3 + 1);
+
+ *out_len = g_base64_decode_step(text, input_length, ret, &state, &save);
+
+ return ret;
+}
+
+guchar *g_base64_decode_inplace(gchar *text, gsize *out_len)
+{
+ gint input_length, state = 0;
+ guint save = 0;
+
+ if (text == NULL || out_len == NULL) {
+ return NULL;
+ }
+
+ input_length = strlen(text);
+
+ if (input_length <= 1) {
+ return NULL;
+ }
+
+ *out_len = g_base64_decode_step(text, input_length, (guchar *) text, &state, &save);
+
+ return (guchar *) text;
+}
diff --git a/qemu/header_gen.py b/qemu/header_gen.py
index a0554aa6..11ac4729 100644
--- a/qemu/header_gen.py
+++ b/qemu/header_gen.py
@@ -2372,6 +2372,14 @@ symbols = (
'qbus_finalize',
'qbus_initfn',
'qbus_realize',
+ 'qcrypto_hash_base64',
+ 'qcrypto_hash_base64v',
+ 'qcrypto_hash_bytes',
+ 'qcrypto_hash_bytesv',
+ 'qcrypto_hash_digest',
+ 'qcrypto_hash_digestv',
+ 'qcrypto_hash_supports',
+ 'qcrypto_init',
'qdev_create',
'qdev_get_type',
'qdev_register_types',
diff --git a/qemu/include/crypto/hash.h b/qemu/include/crypto/hash.h
new file mode 100644
index 00000000..b5acbf63
--- /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 .
+ *
+ */
+
+#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 00000000..5fc510c4
--- /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 .
+ *
+ */
+
+#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__ */
diff --git a/qemu/include/glib_compat.h b/qemu/include/glib_compat.h
index 2d627ed2..6eb3827b 100644
--- a/qemu/include/glib_compat.h
+++ b/qemu/include/glib_compat.h
@@ -44,6 +44,7 @@ typedef uint32_t guint32;
typedef uint64_t guint64;
typedef unsigned int guint;
typedef char gchar;
+typedef unsigned char guchar;
typedef int gboolean;
typedef unsigned long gulong;
typedef unsigned long gsize;
@@ -128,6 +129,12 @@ gchar** g_strsplit (const gchar *string,
const gchar *delimiter,
gint max_tokens);
+/* replacement for base64 dependency */
+gsize g_base64_encode_close(gboolean break_lines, gchar *out,
+ gint *state, gint *save);
+gchar *g_base64_encode(const guchar *data, gsize len);
+guchar *g_base64_decode(const gchar *text, gsize *out_len);
+guchar *g_base64_decode_inplace(gchar *text, gsize *out_len);
#define g_new(struct_type, n_structs) ((struct_type*)g_new_(sizeof(struct_type), n_structs))
#define g_new0(struct_type, n_structs) ((struct_type*)g_new0_(sizeof(struct_type), n_structs))
diff --git a/qemu/include/qemu/osdep.h b/qemu/include/qemu/osdep.h
index 5387816d..5d00ecd6 100644
--- a/qemu/include/qemu/osdep.h
+++ b/qemu/include/qemu/osdep.h
@@ -116,6 +116,13 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#define FMT_pid "%d"
#endif
+#ifndef CONFIG_IOVEC
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+#endif
+
/**
* qemu_getauxval:
* @type: the auxiliary vector key to lookup
diff --git a/qemu/m68k.h b/qemu/m68k.h
index 4e785262..824020b0 100644
--- a/qemu/m68k.h
+++ b/qemu/m68k.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_m68k
#define qbus_initfn qbus_initfn_m68k
#define qbus_realize qbus_realize_m68k
+#define qcrypto_hash_base64 qcrypto_hash_base64_m68k
+#define qcrypto_hash_base64v qcrypto_hash_base64v_m68k
+#define qcrypto_hash_bytes qcrypto_hash_bytes_m68k
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_m68k
+#define qcrypto_hash_digest qcrypto_hash_digest_m68k
+#define qcrypto_hash_digestv qcrypto_hash_digestv_m68k
+#define qcrypto_hash_supports qcrypto_hash_supports_m68k
+#define qcrypto_init qcrypto_init_m68k
#define qdev_create qdev_create_m68k
#define qdev_get_type qdev_get_type_m68k
#define qdev_register_types qdev_register_types_m68k
diff --git a/qemu/mips.h b/qemu/mips.h
index 173d9520..f35c01ad 100644
--- a/qemu/mips.h
+++ b/qemu/mips.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_mips
#define qbus_initfn qbus_initfn_mips
#define qbus_realize qbus_realize_mips
+#define qcrypto_hash_base64 qcrypto_hash_base64_mips
+#define qcrypto_hash_base64v qcrypto_hash_base64v_mips
+#define qcrypto_hash_bytes qcrypto_hash_bytes_mips
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_mips
+#define qcrypto_hash_digest qcrypto_hash_digest_mips
+#define qcrypto_hash_digestv qcrypto_hash_digestv_mips
+#define qcrypto_hash_supports qcrypto_hash_supports_mips
+#define qcrypto_init qcrypto_init_mips
#define qdev_create qdev_create_mips
#define qdev_get_type qdev_get_type_mips
#define qdev_register_types qdev_register_types_mips
diff --git a/qemu/mips64.h b/qemu/mips64.h
index 5fd876ab..8a0c8c65 100644
--- a/qemu/mips64.h
+++ b/qemu/mips64.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_mips64
#define qbus_initfn qbus_initfn_mips64
#define qbus_realize qbus_realize_mips64
+#define qcrypto_hash_base64 qcrypto_hash_base64_mips64
+#define qcrypto_hash_base64v qcrypto_hash_base64v_mips64
+#define qcrypto_hash_bytes qcrypto_hash_bytes_mips64
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_mips64
+#define qcrypto_hash_digest qcrypto_hash_digest_mips64
+#define qcrypto_hash_digestv qcrypto_hash_digestv_mips64
+#define qcrypto_hash_supports qcrypto_hash_supports_mips64
+#define qcrypto_init qcrypto_init_mips64
#define qdev_create qdev_create_mips64
#define qdev_get_type qdev_get_type_mips64
#define qdev_register_types qdev_register_types_mips64
diff --git a/qemu/mips64el.h b/qemu/mips64el.h
index da89a17b..3e9d13a7 100644
--- a/qemu/mips64el.h
+++ b/qemu/mips64el.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_mips64el
#define qbus_initfn qbus_initfn_mips64el
#define qbus_realize qbus_realize_mips64el
+#define qcrypto_hash_base64 qcrypto_hash_base64_mips64el
+#define qcrypto_hash_base64v qcrypto_hash_base64v_mips64el
+#define qcrypto_hash_bytes qcrypto_hash_bytes_mips64el
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_mips64el
+#define qcrypto_hash_digest qcrypto_hash_digest_mips64el
+#define qcrypto_hash_digestv qcrypto_hash_digestv_mips64el
+#define qcrypto_hash_supports qcrypto_hash_supports_mips64el
+#define qcrypto_init qcrypto_init_mips64el
#define qdev_create qdev_create_mips64el
#define qdev_get_type qdev_get_type_mips64el
#define qdev_register_types qdev_register_types_mips64el
diff --git a/qemu/mipsel.h b/qemu/mipsel.h
index a8c575e4..ae03514c 100644
--- a/qemu/mipsel.h
+++ b/qemu/mipsel.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_mipsel
#define qbus_initfn qbus_initfn_mipsel
#define qbus_realize qbus_realize_mipsel
+#define qcrypto_hash_base64 qcrypto_hash_base64_mipsel
+#define qcrypto_hash_base64v qcrypto_hash_base64v_mipsel
+#define qcrypto_hash_bytes qcrypto_hash_bytes_mipsel
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_mipsel
+#define qcrypto_hash_digest qcrypto_hash_digest_mipsel
+#define qcrypto_hash_digestv qcrypto_hash_digestv_mipsel
+#define qcrypto_hash_supports qcrypto_hash_supports_mipsel
+#define qcrypto_init qcrypto_init_mipsel
#define qdev_create qdev_create_mipsel
#define qdev_get_type qdev_get_type_mipsel
#define qdev_register_types qdev_register_types_mipsel
diff --git a/qemu/powerpc.h b/qemu/powerpc.h
index a3716f05..c480478b 100644
--- a/qemu/powerpc.h
+++ b/qemu/powerpc.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_powerpc
#define qbus_initfn qbus_initfn_powerpc
#define qbus_realize qbus_realize_powerpc
+#define qcrypto_hash_base64 qcrypto_hash_base64_powerpc
+#define qcrypto_hash_base64v qcrypto_hash_base64v_powerpc
+#define qcrypto_hash_bytes qcrypto_hash_bytes_powerpc
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_powerpc
+#define qcrypto_hash_digest qcrypto_hash_digest_powerpc
+#define qcrypto_hash_digestv qcrypto_hash_digestv_powerpc
+#define qcrypto_hash_supports qcrypto_hash_supports_powerpc
+#define qcrypto_init qcrypto_init_powerpc
#define qdev_create qdev_create_powerpc
#define qdev_get_type qdev_get_type_powerpc
#define qdev_register_types qdev_register_types_powerpc
diff --git a/qemu/sparc.h b/qemu/sparc.h
index f83eefb8..c62cb60c 100644
--- a/qemu/sparc.h
+++ b/qemu/sparc.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_sparc
#define qbus_initfn qbus_initfn_sparc
#define qbus_realize qbus_realize_sparc
+#define qcrypto_hash_base64 qcrypto_hash_base64_sparc
+#define qcrypto_hash_base64v qcrypto_hash_base64v_sparc
+#define qcrypto_hash_bytes qcrypto_hash_bytes_sparc
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_sparc
+#define qcrypto_hash_digest qcrypto_hash_digest_sparc
+#define qcrypto_hash_digestv qcrypto_hash_digestv_sparc
+#define qcrypto_hash_supports qcrypto_hash_supports_sparc
+#define qcrypto_init qcrypto_init_sparc
#define qdev_create qdev_create_sparc
#define qdev_get_type qdev_get_type_sparc
#define qdev_register_types qdev_register_types_sparc
diff --git a/qemu/sparc64.h b/qemu/sparc64.h
index a96b632d..e7baf1be 100644
--- a/qemu/sparc64.h
+++ b/qemu/sparc64.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_sparc64
#define qbus_initfn qbus_initfn_sparc64
#define qbus_realize qbus_realize_sparc64
+#define qcrypto_hash_base64 qcrypto_hash_base64_sparc64
+#define qcrypto_hash_base64v qcrypto_hash_base64v_sparc64
+#define qcrypto_hash_bytes qcrypto_hash_bytes_sparc64
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_sparc64
+#define qcrypto_hash_digest qcrypto_hash_digest_sparc64
+#define qcrypto_hash_digestv qcrypto_hash_digestv_sparc64
+#define qcrypto_hash_supports qcrypto_hash_supports_sparc64
+#define qcrypto_init qcrypto_init_sparc64
#define qdev_create qdev_create_sparc64
#define qdev_get_type qdev_get_type_sparc64
#define qdev_register_types qdev_register_types_sparc64
diff --git a/qemu/vl.c b/qemu/vl.c
index f6c68b47..8e42985f 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -30,6 +30,7 @@
#include "sysemu/cpus.h"
#include "vl.h"
#include "uc_priv.h"
+#include "crypto/init.h"
#define DEFAULT_RAM_SIZE 128
@@ -80,6 +81,7 @@ int machine_initialize(struct uc_struct *uc)
{
MachineClass *machine_class;
MachineState *current_machine;
+ Error *err = NULL;
module_call_init(uc, MODULE_INIT_QOM);
register_types_object(uc);
@@ -88,6 +90,13 @@ int machine_initialize(struct uc_struct *uc)
cpu_register_types(uc);
qdev_register_types(uc);
+ // Init crypto
+ if (qcrypto_init(&err) < 0) {
+ //fprintf(stderr, "Cannot initialize crypto: %s\n",
+ // error_get_pretty(err));
+ return -1;
+ }
+
// Initialize arch specific.
uc->init_arch(uc);
diff --git a/qemu/x86_64.h b/qemu/x86_64.h
index 6ba2e52b..36bc833e 100644
--- a/qemu/x86_64.h
+++ b/qemu/x86_64.h
@@ -2366,6 +2366,14 @@
#define qbus_finalize qbus_finalize_x86_64
#define qbus_initfn qbus_initfn_x86_64
#define qbus_realize qbus_realize_x86_64
+#define qcrypto_hash_base64 qcrypto_hash_base64_x86_64
+#define qcrypto_hash_base64v qcrypto_hash_base64v_x86_64
+#define qcrypto_hash_bytes qcrypto_hash_bytes_x86_64
+#define qcrypto_hash_bytesv qcrypto_hash_bytesv_x86_64
+#define qcrypto_hash_digest qcrypto_hash_digest_x86_64
+#define qcrypto_hash_digestv qcrypto_hash_digestv_x86_64
+#define qcrypto_hash_supports qcrypto_hash_supports_x86_64
+#define qcrypto_init qcrypto_init_x86_64
#define qdev_create qdev_create_x86_64
#define qdev_get_type qdev_get_type_x86_64
#define qdev_register_types qdev_register_types_x86_64