* [Qemu-devel] [PATCH 0/6] add AEAD algorithms support
@ 2017-01-03 0:33 Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 1/6] configure: add CONFIG_GCRYPT/NETTLE_AEAD item Longpeng(Mike)
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Longpeng(Mike) @ 2017-01-03 0:33 UTC (permalink / raw)
To: berrange; +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
Since QEMU has been supported cryptodev, so it is necessary to support
more crypto algorithms(i.e. hmac,aead) in QEMU backend.
We have already added HMAC support, and this patchset adds AEAD algos
support.
Longpeng(Mike) (6):
configure: add CONFIG_GCRYPT/NETTLE_AEAD item
crypto: add AEAD algorithms framework
crypto: implement nettle-backed AEAD algorithms
crypto: implement gcrypt-backed AEAD algorithms
crypto: implement other common funcs for AEAD algorithms
crypto: add AEAD algorithms testcases
configure | 36 +++++
crypto/Makefile.objs | 3 +
crypto/aead-gcrypt.c | 231 ++++++++++++++++++++++++++++++
crypto/aead-nettle.c | 232 ++++++++++++++++++++++++++++++
crypto/aead.c | 124 ++++++++++++++++
crypto/aead.h | 180 ++++++++++++++++++++++++
qapi/crypto.json | 4 +-
tests/Makefile.include | 2 +
tests/test-crypto-aead.c | 357 +++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 1168 insertions(+), 1 deletion(-)
create mode 100644 crypto/aead-gcrypt.c
create mode 100644 crypto/aead-nettle.c
create mode 100644 crypto/aead.c
create mode 100644 crypto/aead.h
create mode 100644 tests/test-crypto-aead.c
--
2.9.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 1/6] configure: add CONFIG_GCRYPT/NETTLE_AEAD item
2017-01-03 0:33 [Qemu-devel] [PATCH 0/6] add AEAD algorithms support Longpeng(Mike)
@ 2017-01-03 0:33 ` Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 2/6] crypto: add AEAD algorithms framework Longpeng(Mike)
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Longpeng(Mike) @ 2017-01-03 0:33 UTC (permalink / raw)
To: berrange; +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This item will be used for gcrypt/nettle backed AEAD algorithms.
It's hardly to decide which version of gcrypt/nettle started
supporting AEAD algorithms, but it's easily for us to making
a test in configure to know whether current gcrypt/nettle
support AEAD.
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
configure | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/configure b/configure
index 218df87..14f558c 100755
--- a/configure
+++ b/configure
@@ -309,8 +309,10 @@ tls_priority="NORMAL"
gnutls=""
gnutls_rnd=""
nettle=""
+nettle_aead="no"
nettle_kdf="no"
gcrypt=""
+gcrypt_aead="no"
gcrypt_hmac="no"
gcrypt_kdf="no"
vte=""
@@ -2429,6 +2431,19 @@ EOF
if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
gcrypt_hmac=yes
fi
+
+ cat > $TMPC << EOF
+#include <gcrypt.h>
+int main(void) {
+ gcry_cipher_hd_t handle;
+ gcry_cipher_open(&handle, 0, 0, 0);
+ gcry_cipher_authenticate(handle, NULL, 0);
+ return 0;
+}
+EOF
+ if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
+ gcrypt_aead=yes
+ fi
else
if test "$gcrypt" = "yes"; then
feature_not_found "gcrypt" "Install gcrypt devel"
@@ -2460,6 +2475,21 @@ EOF
if compile_prog "$nettle_cflags" "$nettle_libs" ; then
nettle_kdf=yes
fi
+
+ cat > $TMPC << EOF
+#include <stddef.h>
+#include <nettle/aes.h>
+#include <nettle/ccm.h>
+#include <nettle/gcm.h>
+int main(void) {
+ ccm_aes128_encrypt(NULL, 0, NULL, NULL);
+ gcm_aes128_encrypt(NULL, 0, NULL, NULL);
+ return 0;
+}
+EOF
+ if compile_prog "$nettle_cflags" "$nettle_libs" ; then
+ nettle_aead=yes
+ fi
else
if test "$nettle" = "yes"; then
feature_not_found "nettle" "Install nettle devel"
@@ -5399,6 +5429,9 @@ if test "$gnutls_rnd" = "yes" ; then
fi
if test "$gcrypt" = "yes" ; then
echo "CONFIG_GCRYPT=y" >> $config_host_mak
+ if test "$gcrypt_aead" = "yes" ; then
+ echo "CONFIG_GCRYPT_AEAD=y" >> $config_host_mak
+ fi
if test "$gcrypt_hmac" = "yes" ; then
echo "CONFIG_GCRYPT_HMAC=y" >> $config_host_mak
fi
@@ -5409,6 +5442,9 @@ fi
if test "$nettle" = "yes" ; then
echo "CONFIG_NETTLE=y" >> $config_host_mak
echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
+ if test "$nettle_aead" = "yes" ; then
+ echo "CONFIG_NETTLE_AEAD=y" >> $config_host_mak
+ fi
if test "$nettle_kdf" = "yes" ; then
echo "CONFIG_NETTLE_KDF=y" >> $config_host_mak
fi
--
2.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 2/6] crypto: add AEAD algorithms framework
2017-01-03 0:33 [Qemu-devel] [PATCH 0/6] add AEAD algorithms support Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 1/6] configure: add CONFIG_GCRYPT/NETTLE_AEAD item Longpeng(Mike)
@ 2017-01-03 0:33 ` Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 3/6] crypto: implement nettle-backed AEAD algorithms Longpeng(Mike)
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Longpeng(Mike) @ 2017-01-03 0:33 UTC (permalink / raw)
To: berrange; +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch introduce AEAD algorithms framework.
We currently plan to support six basic AEAD algorithms,
ccm(aes128/192/256) and gcm(aes128/192/256), so we need
to add ccm/gcm mode in qapi/crypto.json simultaneously.
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
crypto/Makefile.objs | 3 +
crypto/aead-gcrypt.c | 70 ++++++++++++++++++++
crypto/aead-nettle.c | 72 +++++++++++++++++++++
crypto/aead.c | 84 ++++++++++++++++++++++++
crypto/aead.h | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++
qapi/crypto.json | 4 +-
6 files changed, 412 insertions(+), 1 deletion(-)
create mode 100644 crypto/aead-gcrypt.c
create mode 100644 crypto/aead-nettle.c
create mode 100644 crypto/aead.c
create mode 100644 crypto/aead.h
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 1f749f2..2c5243d 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -3,6 +3,9 @@ crypto-obj-y += hash.o
crypto-obj-$(CONFIG_NETTLE) += hash-nettle.o
crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += hash-gcrypt.o
crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += hash-glib.o
+crypto-obj-y += aead.o
+crypto-obj-$(CONFIG_NETTLE_AEAD) += aead-nettle.o
+crypto-obj-$(if $(CONFIG_NETTLE_AEAD),n,$(CONFIG_GCRYPT_AEAD)) += aead-gcrypt.o
crypto-obj-y += hmac.o
crypto-obj-$(CONFIG_NETTLE) += hmac-nettle.o
crypto-obj-$(CONFIG_GCRYPT_HMAC) += hmac-gcrypt.o
diff --git a/crypto/aead-gcrypt.c b/crypto/aead-gcrypt.c
new file mode 100644
index 0000000..9465518
--- /dev/null
+++ b/crypto/aead-gcrypt.c
@@ -0,0 +1,70 @@
+/*
+ * QEMU Crypto aead algorithms (based on libgcrypt)
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/aead.h"
+#include <gcrypt.h>
+
+QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key, size_t nkey,
+ Error **errp)
+{
+ return NULL;
+}
+
+void qcrypto_aead_free(QCryptoAead *aead)
+{
+ return;
+}
+
+int qcrypto_aead_set_nonce(QCryptoAead *aead,
+ const uint8_t *nonce, size_t nonce_len,
+ size_t aad_len, size_t in_len,
+ size_t tag_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_authenticate(QCryptoAead *aead,
+ const uint8_t *aad, size_t aad_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_encrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_decrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_get_tag(QCryptoAead *aead,
+ uint8_t *tag, size_t tag_len,
+ Error **errp)
+{
+ return -1;
+}
diff --git a/crypto/aead-nettle.c b/crypto/aead-nettle.c
new file mode 100644
index 0000000..cfb9d33
--- /dev/null
+++ b/crypto/aead-nettle.c
@@ -0,0 +1,72 @@
+/*
+ * QEMU Crypto aead algorithms (based on nettle)
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/aead.h"
+#include <nettle/aes.h>
+#include <nettle/ccm.h>
+#include <nettle/gcm.h>
+
+QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key, size_t nkey,
+ Error **errp)
+{
+ return NULL;
+}
+
+void qcrypto_aead_free(QCryptoAead *aead)
+{
+ return;
+}
+
+int qcrypto_aead_set_nonce(QCryptoAead *aead,
+ const uint8_t *nonce, size_t nonce_len,
+ size_t aad_len, size_t in_len,
+ size_t tag_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_authenticate(QCryptoAead *aead,
+ const uint8_t *aad, size_t aad_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_encrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_decrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_get_tag(QCryptoAead *aead,
+ uint8_t *tag, size_t tag_len,
+ Error **errp)
+{
+ return -1;
+}
diff --git a/crypto/aead.c b/crypto/aead.c
new file mode 100644
index 0000000..47639b7
--- /dev/null
+++ b/crypto/aead.c
@@ -0,0 +1,84 @@
+/*
+ * QEMU Crypto aead algorithms
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/aead.h"
+
+bool qcrypto_aead_supports(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode)
+{
+ return false;
+}
+
+size_t qcrypto_aead_get_key_len(QCryptoCipherAlgorithm alg)
+{
+ return -1;
+}
+
+#if !defined(CONFIG_NETTLE_AEAD) && !defined(CONFIG_GCRYPT_AEAD)
+
+QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key, size_t nkey,
+ Error **errp)
+{
+ return NULL;
+}
+
+void qcrypto_aead_free(QCryptoAead *aead)
+{
+ return;
+}
+
+int qcrypto_aead_set_nonce(QCryptoAead *aead,
+ const uint8_t *nonce, size_t nonce_len,
+ size_t aad_len, size_t in_len,
+ size_t tag_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_authenticate(QCryptoAead *aead,
+ const uint8_t *aad, size_t aad_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_encrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_decrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp)
+{
+ return -1;
+}
+
+int qcrypto_aead_get_tag(QCryptoAead *aead,
+ uint8_t *tag, size_t tag_len,
+ Error **errp)
+{
+ return -1;
+}
+
+#endif
diff --git a/crypto/aead.h b/crypto/aead.h
new file mode 100644
index 0000000..a868d0a
--- /dev/null
+++ b/crypto/aead.h
@@ -0,0 +1,180 @@
+/*
+ * QEMU Crypto aead algorithms
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#ifndef QCRYPTO_AEAD_H
+#define QCRYPTO_AEAD_H
+
+#include "qapi-types.h"
+
+/**
+ * We currently only support six basic aead algorithms,
+ * ccm(aes128/192/256) and gcm(aes128/192/256), so for
+ * some global arrays, like qcrypto_aead_alg_map, we use
+ * AEAD_ALG__MAX/AEAD_MODE__MAX as their size instead of
+ * CIPHER_ALG__MAX/CIPHER_MODE__MAX, in order to save memory.
+ *
+ * Note: this means that we must make sure ccm,gcm,ecb at
+ * the first three places in QCryptoCipherMode, and aes128,
+ * aes192,aes256,des-rfb at the first four places in
+ * QCryptoCipherAlgorithm.
+ */
+#define QCRYPTO_AEAD_ALG__MAX QCRYPTO_CIPHER_ALG_DES_RFB
+#define QCRYPTO_AEAD_MODE__MAX QCRYPTO_CIPHER_MODE_ECB
+
+typedef struct QCryptoAead QCryptoAead;
+struct QCryptoAead {
+ QCryptoCipherAlgorithm alg;
+ QCryptoCipherMode mode;
+ void *opaque;
+};
+
+/**
+ * qcrypto_aead_supports:
+ * @alg: the cipher algorithm
+ * @mode: the cipher mode
+ *
+ * Determine if @alg hmac algorithm is supported by
+ * the current configured build
+ *
+ * Returns:
+ * true if the algorithm is supported, false otherwise
+ */
+bool qcrypto_aead_supports(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode);
+
+/**
+ * qcrypto_aead_get_key_len:
+ * @alg: the cipher algorithm
+ *
+ * Get the required key size in bytes
+ *
+ * Returns: the key size in bytes
+ */
+size_t qcrypto_aead_get_key_len(QCryptoCipherAlgorithm alg);
+
+/**
+ * qcrypto_aead_new:
+ * @alg: the cipher algorithm
+ * @mode: the cipher usage mode
+ * @key: the private key bytes
+ * @nkey: the length of @key
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Creates a new aead object for encrypting/decrypting
+ * data with the algorithm @alg in the usage mode @mode.
+ *
+ * The returned aead object must be released with
+ * qcrypto_aead_free() when no longer required
+ *
+ * Returns:
+ * a new aead object, or NULL on error
+ */
+QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key, size_t nkey,
+ Error **errp);
+
+/**
+ * qcrypto_aead_free:
+ * @aead: the aead object
+ *
+ * Release the memory associated with @aead that
+ * was previously allocated by qcrypto_aead_new()
+ */
+void qcrypto_aead_free(QCryptoAead *aead);
+
+/**
+ * qcrypto_aead_set_nonce:
+ * @aead: the aead object
+ * @nonce: the nonce/iv data
+ * @nonce_len: the length of @nonce
+ * @aad_len: the length of associated data
+ * @in_len: the length of plain data
+ * @tag_len: the length of authentication tag
+ *
+ * Set the aead object's nonce/iv
+ *
+ * Returns:
+ * 0 if success, or -1 on error
+ */
+int qcrypto_aead_set_nonce(QCryptoAead *aead,
+ const uint8_t *nonce, size_t nonce_len,
+ size_t aad_len, size_t in_len,
+ size_t tag_len,
+ Error **errp);
+
+/**
+ * qcrypto_aead_authenticate:
+ * @aead: the aead object
+ * @aad: associated data
+ * @aad_len: the length of @add
+ *
+ * Set associated data to be authenticated
+ *
+ * Returns:
+ * 0 if success, or -1 on error
+ */
+int qcrypto_aead_authenticate(QCryptoAead *aead,
+ const uint8_t *aad, size_t aad_len,
+ Error **errp);
+
+/**
+ * qcrypto_aead_encrypt:
+ * @aead: the aead object
+ * @in: the plain data
+ * @in_len: the length of @in
+ * @out: the cipher data buffer
+ * @out_len: the length of @out
+ *
+ * Encrypts the input data
+ *
+ * Returns:
+ * 0 if success, or -1 on error
+ */
+int qcrypto_aead_encrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp);
+
+/**
+ * qcrypto_aead_decrypt:
+ * @aead: the aead object
+ * @in: the cipher data
+ * @in_len: the length of @in
+ * @out: the plain data buffer
+ * @out_len: the length of @out
+ *
+ * Decrypts the input data
+ *
+ * Returns:
+ * 0 if success, or -1 on error
+ */
+int qcrypto_aead_decrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp);
+
+/**
+ * qcrypto_aead_get_tag:
+ * @aead: the aead object
+ * @tag: the tag buffer
+ * @tag_len: the length of @tag
+ *
+ * Extracts the authentication tag
+ *
+ * Returns:
+ * 0 if success, or -1 on error
+ */
+int qcrypto_aead_get_tag(QCryptoAead *aead,
+ uint8_t *tag, size_t tag_len,
+ Error **errp);
+
+#endif
diff --git a/qapi/crypto.json b/qapi/crypto.json
index f4fd93b..edb2962 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -87,6 +87,8 @@
#
# The supported modes for content encryption ciphers
#
+# @ccm: Counter with CBC-MAC Mode (Since 2.9)
+# @gcm: Galois Counter Mode (Since 2.9)
# @ecb: Electronic Code Book
# @cbc: Cipher Block Chaining
# @xts: XEX with tweaked code book and ciphertext stealing
@@ -95,7 +97,7 @@
##
{ 'enum': 'QCryptoCipherMode',
'prefix': 'QCRYPTO_CIPHER_MODE',
- 'data': ['ecb', 'cbc', 'xts', 'ctr']}
+ 'data': ['ccm', 'gcm', 'ecb', 'cbc', 'xts', 'ctr']}
##
--
2.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 3/6] crypto: implement nettle-backed AEAD algorithms
2017-01-03 0:33 [Qemu-devel] [PATCH 0/6] add AEAD algorithms support Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 1/6] configure: add CONFIG_GCRYPT/NETTLE_AEAD item Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 2/6] crypto: add AEAD algorithms framework Longpeng(Mike)
@ 2017-01-03 0:33 ` Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 4/6] crypto: implement gcrypt-backed " Longpeng(Mike)
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Longpeng(Mike) @ 2017-01-03 0:33 UTC (permalink / raw)
To: berrange; +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch add nettle-backed AEAD algorithms
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
crypto/aead-nettle.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 167 insertions(+), 7 deletions(-)
diff --git a/crypto/aead-nettle.c b/crypto/aead-nettle.c
index cfb9d33..7a2296d 100644
--- a/crypto/aead-nettle.c
+++ b/crypto/aead-nettle.c
@@ -19,17 +19,124 @@
#include <nettle/ccm.h>
#include <nettle/gcm.h>
+typedef void (*qcrypto_nettle_aead_setkey)(void *ctx,
+ const uint8_t *key);
+
+typedef void (*qcrypto_nettle_aead_setiv)(void *ctx,
+ size_t length, const uint8_t *iv);
+
+typedef void (*qcrypto_nettle_aead_setnonce)(void *ctx,
+ size_t length, const uint8_t *nonce,
+ size_t authlen, size_t msglen, size_t taglen);
+
+typedef void (*qcrypto_nettle_aead_update)(void *ctx,
+ size_t length, const uint8_t *data);
+
+typedef void (*qcrypto_nettle_aead_encrypt)(void *ctx,
+ size_t length, uint8_t *dst, const uint8_t *src);
+
+typedef void (*qcrypto_nettle_aead_decrypt)(void *ctx,
+ size_t length, uint8_t *dst, const uint8_t *src);
+
+typedef void (*qcrypto_nettle_aead_digest)(void *ctx,
+ size_t length, uint8_t *digest);
+
+#define NETTLE_AEAD_SET_CCM_FN(alg) { \
+ .setkey = (qcrypto_nettle_aead_setkey)ccm_##alg##_set_key, \
+ .u_op.setnonce = (qcrypto_nettle_aead_setnonce)ccm_##alg##_set_nonce, \
+ .update = (qcrypto_nettle_aead_update)ccm_##alg##_update, \
+ .encrypt = (qcrypto_nettle_aead_encrypt)ccm_##alg##_encrypt, \
+ .decrypt = (qcrypto_nettle_aead_decrypt)ccm_##alg##_decrypt, \
+ .digest = (qcrypto_nettle_aead_digest)ccm_##alg##_digest, \
+}
+
+#define NETTLE_AEAD_SET_GCM_FN(alg) { \
+ .setkey = (qcrypto_nettle_aead_setkey)gcm_##alg##_set_key, \
+ .u_op.setiv = (qcrypto_nettle_aead_setiv)gcm_##alg##_set_iv, \
+ .update = (qcrypto_nettle_aead_update)gcm_##alg##_update, \
+ .encrypt = (qcrypto_nettle_aead_encrypt)gcm_##alg##_encrypt, \
+ .decrypt = (qcrypto_nettle_aead_decrypt)gcm_##alg##_decrypt, \
+ .digest = (qcrypto_nettle_aead_digest)gcm_##alg##_digest, \
+}
+
+static struct qcrypto_nettle_aead_alg {
+ qcrypto_nettle_aead_setkey setkey;
+ union {
+ qcrypto_nettle_aead_setnonce setnonce;
+ qcrypto_nettle_aead_setiv setiv;
+ } u_op;
+ qcrypto_nettle_aead_update update;
+ qcrypto_nettle_aead_encrypt encrypt;
+ qcrypto_nettle_aead_decrypt decrypt;
+ qcrypto_nettle_aead_digest digest;
+} qcrypto_aead_alg_map[][QCRYPTO_AEAD_ALG__MAX] = {
+ {
+ [QCRYPTO_CIPHER_ALG_AES_128] = NETTLE_AEAD_SET_CCM_FN(aes128),
+ [QCRYPTO_CIPHER_ALG_AES_192] = NETTLE_AEAD_SET_CCM_FN(aes192),
+ [QCRYPTO_CIPHER_ALG_AES_256] = NETTLE_AEAD_SET_CCM_FN(aes256),
+ },
+ {
+ [QCRYPTO_CIPHER_ALG_AES_128] = NETTLE_AEAD_SET_GCM_FN(aes128),
+ [QCRYPTO_CIPHER_ALG_AES_192] = NETTLE_AEAD_SET_GCM_FN(aes192),
+ [QCRYPTO_CIPHER_ALG_AES_256] = NETTLE_AEAD_SET_GCM_FN(aes256),
+ }
+};
+
+typedef struct QCryptoAeadNettle QCryptoAeadNettle;
+struct QCryptoAeadNettle {
+ union qcrypto_nettle_aead_ctx {
+ struct ccm_aes128_ctx c_aes128_ctx;
+ struct ccm_aes192_ctx c_aes192_ctx;
+ struct ccm_aes256_ctx c_aes256_ctx;
+ struct gcm_aes128_ctx g_aes128_ctx;
+ struct gcm_aes192_ctx g_aes192_ctx;
+ struct gcm_aes256_ctx g_aes256_ctx;
+ } u;
+};
+
QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key, size_t nkey,
Error **errp)
{
- return NULL;
+ QCryptoAead *aead;
+ QCryptoAeadNettle *ctx;
+
+ if (!qcrypto_aead_supports(alg, mode)) {
+ return NULL;
+ }
+
+ if (nkey != qcrypto_aead_get_key_len(alg)) {
+ error_setg(errp, "Cipher key length %zu is invalid",
+ nkey);
+ return NULL;
+ }
+
+ aead = g_new0(QCryptoAead, 1);
+ aead->alg = alg;
+ aead->mode = mode;
+
+ ctx = g_new0(QCryptoAeadNettle, 1);
+
+ qcrypto_aead_alg_map[mode][alg].setkey(&ctx->u, key);
+
+ aead->opaque = ctx;
+
+ return aead;
}
void qcrypto_aead_free(QCryptoAead *aead)
{
- return;
+ QCryptoAeadNettle *ctx;
+
+ if (!aead) {
+ return;
+ }
+
+ ctx = aead->opaque;
+
+ g_free(ctx);
+ g_free(aead);
}
int qcrypto_aead_set_nonce(QCryptoAead *aead,
@@ -38,14 +145,43 @@ int qcrypto_aead_set_nonce(QCryptoAead *aead,
size_t tag_len,
Error **errp)
{
- return -1;
+ QCryptoAeadNettle *ctx;
+ struct qcrypto_nettle_aead_alg *aead_ops;
+
+ ctx = (QCryptoAeadNettle *)aead->opaque;
+
+ switch (aead->mode) {
+ case QCRYPTO_CIPHER_MODE_CCM:
+ aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg];
+ aead_ops->u_op.setnonce(&ctx->u, nonce_len, nonce, aad_len,
+ in_len, tag_len);
+ break;
+ case QCRYPTO_CIPHER_MODE_GCM:
+ aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg];
+ aead_ops->u_op.setiv(&ctx->u, nonce_len, nonce);
+ break;
+ default:
+ error_setg(errp, "Unsupported AEAD mode: %d",
+ aead->mode);
+ return -1;
+ }
+
+ return 0;
}
int qcrypto_aead_authenticate(QCryptoAead *aead,
const uint8_t *aad, size_t aad_len,
Error **errp)
{
- return -1;
+ QCryptoAeadNettle *ctx;
+ struct qcrypto_nettle_aead_alg *aead_ops;
+
+ ctx = (QCryptoAeadNettle *)aead->opaque;
+ aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg];
+
+ aead_ops->update(&ctx->u, aad_len, aad);
+
+ return 0;
}
int qcrypto_aead_encrypt(QCryptoAead *aead,
@@ -53,7 +189,15 @@ int qcrypto_aead_encrypt(QCryptoAead *aead,
uint8_t *out, size_t out_len,
Error **errp)
{
- return -1;
+ QCryptoAeadNettle *ctx;
+ struct qcrypto_nettle_aead_alg *aead_ops;
+
+ ctx = (QCryptoAeadNettle *)aead->opaque;
+ aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg];
+
+ aead_ops->encrypt(&ctx->u, in_len, out, in);
+
+ return 0;
}
int qcrypto_aead_decrypt(QCryptoAead *aead,
@@ -61,12 +205,28 @@ int qcrypto_aead_decrypt(QCryptoAead *aead,
uint8_t *out, size_t out_len,
Error **errp)
{
- return -1;
+ QCryptoAeadNettle *ctx;
+ struct qcrypto_nettle_aead_alg *aead_ops;
+
+ ctx = (QCryptoAeadNettle *)aead->opaque;
+ aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg];
+
+ aead_ops->decrypt(&ctx->u, in_len, out, in);
+
+ return 0;
}
int qcrypto_aead_get_tag(QCryptoAead *aead,
uint8_t *tag, size_t tag_len,
Error **errp)
{
- return -1;
+ QCryptoAeadNettle *ctx;
+ struct qcrypto_nettle_aead_alg *aead_ops;
+
+ ctx = (QCryptoAeadNettle *)aead->opaque;
+ aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg];
+
+ aead_ops->digest(&ctx->u, tag_len, tag);
+
+ return 0;
}
--
2.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 4/6] crypto: implement gcrypt-backed AEAD algorithms
2017-01-03 0:33 [Qemu-devel] [PATCH 0/6] add AEAD algorithms support Longpeng(Mike)
` (2 preceding siblings ...)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 3/6] crypto: implement nettle-backed AEAD algorithms Longpeng(Mike)
@ 2017-01-03 0:33 ` Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 5/6] crypto: implement other common funcs for " Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 6/6] crypto: add AEAD algorithms testcases Longpeng(Mike)
5 siblings, 0 replies; 7+ messages in thread
From: Longpeng(Mike) @ 2017-01-03 0:33 UTC (permalink / raw)
To: berrange; +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch add gcrypt-backed AEAD algorithms support
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
crypto/aead-gcrypt.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 167 insertions(+), 6 deletions(-)
diff --git a/crypto/aead-gcrypt.c b/crypto/aead-gcrypt.c
index 9465518..9892e3b 100644
--- a/crypto/aead-gcrypt.c
+++ b/crypto/aead-gcrypt.c
@@ -17,17 +17,100 @@
#include "crypto/aead.h"
#include <gcrypt.h>
+typedef struct QCryptoAeadGcrypt QCryptoAeadGcrypt;
+struct QCryptoAeadGcrypt {
+ gcry_cipher_hd_t handle;
+};
+
QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key, size_t nkey,
Error **errp)
{
+ QCryptoAead *aead;
+ QCryptoAeadGcrypt *ctx;
+ gcry_error_t err;
+ int gcryalg, gcrymode;
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_CCM:
+ gcrymode = GCRY_CIPHER_MODE_CCM;
+ break;
+ case QCRYPTO_CIPHER_MODE_GCM:
+ gcrymode = GCRY_CIPHER_MODE_GCM;
+ break;
+ default:
+ error_setg(errp, "Unsupported AEAD mode %s",
+ QCryptoCipherMode_lookup[mode]);
+ return NULL;
+ }
+
+ if (nkey != qcrypto_aead_get_key_len(alg)) {
+ error_setg(errp, "Cipher key length %zu is invalid",
+ nkey);
+ return NULL;
+ }
+
+ switch (alg) {
+ case QCRYPTO_CIPHER_ALG_AES_128:
+ gcryalg = GCRY_CIPHER_AES128;
+ break;
+ case QCRYPTO_CIPHER_ALG_AES_192:
+ gcryalg = GCRY_CIPHER_AES192;
+ break;
+ case QCRYPTO_CIPHER_ALG_AES_256:
+ gcryalg = GCRY_CIPHER_AES256;
+ break;
+ default:
+ error_setg(errp, "Unsupported AEAD algorithm %s",
+ QCryptoCipherAlgorithm_lookup[alg]);
+ return NULL;
+ }
+
+ aead = g_new0(QCryptoAead, 1);
+ aead->alg = alg;
+ aead->mode = mode;
+
+ ctx = g_new0(QCryptoAeadGcrypt, 1);
+
+ err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
+ if (err) {
+ error_setg(errp, "Cannot initialize aead: %s",
+ gcry_strerror(err));
+ goto error;
+ }
+
+ err = gcry_cipher_setkey(ctx->handle, key, nkey);
+ if (err) {
+ error_setg(errp, "Cannot set key: %s",
+ gcry_strerror(err));
+ goto error;
+ }
+
+ aead->opaque = ctx;
+
+ return aead;
+
+error:
+ gcry_cipher_close(ctx->handle);
+ g_free(ctx);
+ g_free(aead);
return NULL;
}
void qcrypto_aead_free(QCryptoAead *aead)
{
- return;
+ QCryptoAeadGcrypt *ctx;
+
+ if (!aead) {
+ return;
+ }
+
+ ctx = aead->opaque;
+
+ gcry_cipher_close(ctx->handle);
+ g_free(ctx);
+ g_free(aead);
}
int qcrypto_aead_set_nonce(QCryptoAead *aead,
@@ -36,14 +119,54 @@ int qcrypto_aead_set_nonce(QCryptoAead *aead,
size_t tag_len,
Error **errp)
{
- return -1;
+ QCryptoAeadGcrypt *ctx;
+ gcry_error_t err;
+
+ ctx = aead->opaque;
+
+ err = gcry_cipher_setiv(ctx->handle, nonce, nonce_len);
+ if (err) {
+ error_setg(errp, "Cannot set iv/nonce: %s",
+ gcry_strerror(err));
+ return -1;
+ }
+
+ if (aead->mode == QCRYPTO_CIPHER_MODE_CCM) {
+ size_t ctl_para[3];
+
+ ctl_para[0] = in_len;
+ ctl_para[1] = aad_len;
+ ctl_para[2] = tag_len;
+
+ err = gcry_cipher_ctl(ctx->handle, GCRYCTL_SET_CCM_LENGTHS,
+ ctl_para, sizeof(ctl_para));
+ if (err) {
+ error_setg(errp, "Cannot set lengths: %s",
+ gcry_strerror(err));
+ return -1;
+ }
+ }
+
+ return 0;
}
int qcrypto_aead_authenticate(QCryptoAead *aead,
const uint8_t *aad, size_t aad_len,
Error **errp)
{
- return -1;
+ QCryptoAeadGcrypt *ctx;
+ gcry_error_t err;
+
+ ctx = aead->opaque;
+
+ err = gcry_cipher_authenticate(ctx->handle, aad, aad_len);
+ if (err) {
+ error_setg(errp, "Cannot set associated data: %s",
+ gcry_strerror(err));
+ return -1;
+ }
+
+ return 0;
}
int qcrypto_aead_encrypt(QCryptoAead *aead,
@@ -51,7 +174,20 @@ int qcrypto_aead_encrypt(QCryptoAead *aead,
uint8_t *out, size_t out_len,
Error **errp)
{
- return -1;
+ QCryptoAeadGcrypt *ctx;
+ gcry_error_t err;
+
+ ctx = aead->opaque;
+
+ err = gcry_cipher_encrypt(ctx->handle, out, out_len,
+ in, in_len);
+ if (err) {
+ error_setg(errp, "Cannot encrypt data: %s",
+ gcry_strerror(err));
+ return -1;
+ }
+
+ return 0;
}
int qcrypto_aead_decrypt(QCryptoAead *aead,
@@ -59,12 +195,37 @@ int qcrypto_aead_decrypt(QCryptoAead *aead,
uint8_t *out, size_t out_len,
Error **errp)
{
- return -1;
+ QCryptoAeadGcrypt *ctx;
+ gcry_error_t err;
+
+ ctx = aead->opaque;
+
+ err = gcry_cipher_decrypt(ctx->handle, out, out_len,
+ in, in_len);
+ if (err) {
+ error_setg(errp, "Cannot decrypt data: %s",
+ gcry_strerror(err));
+ return -1;
+ }
+
+ return 0;
}
int qcrypto_aead_get_tag(QCryptoAead *aead,
uint8_t *tag, size_t tag_len,
Error **errp)
{
- return -1;
+ QCryptoAeadGcrypt *ctx;
+ gcry_error_t err;
+
+ ctx = aead->opaque;
+
+ err = gcry_cipher_gettag(ctx->handle, tag, tag_len);
+ if (err) {
+ error_setg(errp, "Cannot get tag: %s",
+ gcry_strerror(err));
+ return -1;
+ }
+
+ return 0;
}
--
2.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 5/6] crypto: implement other common funcs for AEAD algorithms
2017-01-03 0:33 [Qemu-devel] [PATCH 0/6] add AEAD algorithms support Longpeng(Mike)
` (3 preceding siblings ...)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 4/6] crypto: implement gcrypt-backed " Longpeng(Mike)
@ 2017-01-03 0:33 ` Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 6/6] crypto: add AEAD algorithms testcases Longpeng(Mike)
5 siblings, 0 replies; 7+ messages in thread
From: Longpeng(Mike) @ 2017-01-03 0:33 UTC (permalink / raw)
To: berrange; +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
If currently gcrypt/nettle doesn't support AEAD alg, then
we should implement some no-op funcs.
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
crypto/aead.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 42 insertions(+), 2 deletions(-)
diff --git a/crypto/aead.c b/crypto/aead.c
index 47639b7..effe45e 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -16,18 +16,58 @@
#include "qapi/error.h"
#include "crypto/aead.h"
+#if defined(CONFIG_NETTLE_AEAD) || defined(CONFIG_GCRYPT_AEAD)
+
+static size_t alg_key_len[QCRYPTO_AEAD_ALG__MAX] = {
+ [QCRYPTO_CIPHER_ALG_AES_128] = 16,
+ [QCRYPTO_CIPHER_ALG_AES_192] = 24,
+ [QCRYPTO_CIPHER_ALG_AES_256] = 32,
+};
+
bool qcrypto_aead_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
+ switch (alg) {
+ case QCRYPTO_CIPHER_ALG_AES_128:
+ case QCRYPTO_CIPHER_ALG_AES_192:
+ case QCRYPTO_CIPHER_ALG_AES_256:
+ break;
+ default:
+ return false;
+ }
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_CCM:
+ case QCRYPTO_CIPHER_MODE_GCM:
+ return true;
+ default:
+ break;
+ }
+
return false;
}
size_t qcrypto_aead_get_key_len(QCryptoCipherAlgorithm alg)
{
- return -1;
+ if (alg > G_N_ELEMENTS(alg_key_len)) {
+ return 0;
+ }
+
+ return alg_key_len[alg];
}
-#if !defined(CONFIG_NETTLE_AEAD) && !defined(CONFIG_GCRYPT_AEAD)
+#else
+
+bool qcrypto_aead_supports(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode)
+{
+ return false;
+}
+
+size_t qcrypto_aead_get_key_len(QCryptoCipherAlgorithm alg)
+{
+ return -1;
+}
QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
--
2.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 6/6] crypto: add AEAD algorithms testcases
2017-01-03 0:33 [Qemu-devel] [PATCH 0/6] add AEAD algorithms support Longpeng(Mike)
` (4 preceding siblings ...)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 5/6] crypto: implement other common funcs for " Longpeng(Mike)
@ 2017-01-03 0:33 ` Longpeng(Mike)
5 siblings, 0 replies; 7+ messages in thread
From: Longpeng(Mike) @ 2017-01-03 0:33 UTC (permalink / raw)
To: berrange; +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch add some AEAD algorithms testcases
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
tests/Makefile.include | 2 +
tests/test-crypto-aead.c | 357 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 359 insertions(+)
create mode 100644 tests/test-crypto-aead.c
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 4841d58..686ba30 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -93,6 +93,7 @@ gcov-files-test-write-threshold-y = block/write-threshold.c
check-unit-y += tests/test-crypto-hash$(EXESUF)
check-unit-y += tests/test-crypto-hmac$(EXESUF)
check-unit-y += tests/test-crypto-cipher$(EXESUF)
+check-unit-y += tests/test-crypto-aead$(EXESUF)
check-unit-y += tests/test-crypto-secret$(EXESUF)
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF)
@@ -574,6 +575,7 @@ 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-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
+tests/test-crypto-aead$(EXESUF): tests/test-crypto-aead.o $(test-crypto-obj-y)
tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y)
tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-y)
diff --git a/tests/test-crypto-aead.c b/tests/test-crypto-aead.c
new file mode 100644
index 0000000..c757be3
--- /dev/null
+++ b/tests/test-crypto-aead.c
@@ -0,0 +1,357 @@
+/*
+ * QEMU Crypto aead algorithms testcase
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "crypto/init.h"
+#include "crypto/aead.h"
+#include "qapi/error.h"
+
+typedef struct QCryptoAeadTestData QCryptoAeadTestData;
+struct QCryptoAeadTestData {
+ const char *path;
+ QCryptoCipherAlgorithm alg;
+ QCryptoCipherMode mode;
+ const char *hex_key;
+ const char *hex_nonce;
+ const char *hex_aad;
+ const char *hex_plain;
+ const char *hex_cipher;
+ const char *hex_tag;
+};
+
+static QCryptoAeadTestData test_data[] = {
+ {
+ /* Borrowed from libgcrypt */
+ .path = "/crypto/aead/gcm-aes-128",
+ .alg = QCRYPTO_CIPHER_ALG_AES_128,
+ .mode = QCRYPTO_CIPHER_MODE_GCM,
+ .hex_key = "0000000000000000"
+ "0000000000000000",
+ .hex_nonce = "0000000000000000"
+ "00000000",
+ .hex_aad = "",
+ .hex_plain = "0000000000000000"
+ "0000000000000000",
+ .hex_cipher = "0388dace60b6a392"
+ "f328c2b971b2fe78",
+ .hex_tag = "ab6e47d42cec13bd"
+ "f53a67b21257bddf",
+ },
+ {
+ /* Borrowed from libgcrypt */
+ .path = "/crypto/aead/gcm-aes-192",
+ .alg = QCRYPTO_CIPHER_ALG_AES_192,
+ .mode = QCRYPTO_CIPHER_MODE_GCM,
+ .hex_key = "feffe9928665731c"
+ "6d6a8f9467308308"
+ "feffe9928665731c",
+ .hex_nonce = "9313225df88406e5"
+ "55909c5aff5269aa"
+ "6a7a9538534f7da1"
+ "e4c303d2a318a728"
+ "c3c0c95156809539"
+ "fcf0e2429a6b5254"
+ "16aedbf5a0de6a57"
+ "a637b39b",
+ .hex_aad = "feedfacedeadbeef"
+ "feedfacedeadbeef"
+ "abaddad2",
+ .hex_plain = "d9313225f88406e5"
+ "a55909c5aff5269a"
+ "86a7a9531534f7da"
+ "2e4c303d8a318a72"
+ "1c3c0c9595680953"
+ "2fcf0e2449a6b525"
+ "b16aedf5aa0de657"
+ "ba637b39",
+ .hex_cipher = "d27e88681ce3243c"
+ "4830165a8fdcf9ff"
+ "1de9a1d8e6b447ef"
+ "6ef7b79828666e45"
+ "81e79012af34ddd9"
+ "e2f037589b292db3"
+ "e67c036745fa22e7"
+ "e9b7373b",
+ .hex_tag = "dcf566ff291c25bb"
+ "b8568fc3d376a6d9",
+ },
+ {
+ /* Borrowed from libgcrypt */
+ .path = "/crypto/aead/gcm-aes-256",
+ .alg = QCRYPTO_CIPHER_ALG_AES_256,
+ .mode = QCRYPTO_CIPHER_MODE_GCM,
+ .hex_key = "feffe9928665731c"
+ "6d6a8f9467308308"
+ "feffe9928665731c"
+ "6d6a8f9467308308",
+ .hex_nonce = "9313225df88406e5"
+ "55909c5aff5269aa"
+ "6a7a9538534f7da1"
+ "e4c303d2a318a728"
+ "c3c0c95156809539"
+ "fcf0e2429a6b5254"
+ "16aedbf5a0de6a57"
+ "a637b39b",
+ .hex_aad = "feedfacedeadbeef"
+ "feedfacedeadbeef"
+ "abaddad2",
+ .hex_plain = "d9313225f88406e5"
+ "a55909c5aff5269a"
+ "86a7a9531534f7da"
+ "2e4c303d8a318a72"
+ "1c3c0c9595680953"
+ "2fcf0e2449a6b525"
+ "b16aedf5aa0de657"
+ "ba637b39",
+ .hex_cipher = "5a8def2f0c9e53f1"
+ "f75d7853659e2a20"
+ "eeb2b22aafde6419"
+ "a058ab4f6f746bf4"
+ "0fc0c3b780f24445"
+ "2da3ebf1c5d82cde"
+ "a2418997200ef82e"
+ "44ae7e3f",
+ .hex_tag = "a44a8266ee1c8eb0"
+ "c8b5d4cf5ae9f19a",
+ },
+ {
+ /* Borrowed from libgcrypt */
+ .path = "/crypto/aead/ccm-aes-128",
+ .alg = QCRYPTO_CIPHER_ALG_AES_128,
+ .mode = QCRYPTO_CIPHER_MODE_CCM,
+ .hex_key = "c0c1c2c3c4c5c6c7"
+ "c8c9cacbcccdcecf",
+ .hex_nonce = "00000003020100a0"
+ "a1a2a3a4a5",
+ .hex_aad = "0001020304050607",
+ .hex_plain = "08090a0b0c0d0e0f"
+ "1011121314151617"
+ "18191a1b1c1d1e",
+ .hex_cipher = "588c979a61c663d2"
+ "f066d0c2c0f98980"
+ "6d5f6b61dac384",
+ .hex_tag = "17e8d12cfdf926e0",
+ },
+ {
+ .path = "/crypto/aead/ccm-aes-192",
+ .alg = QCRYPTO_CIPHER_ALG_AES_192,
+ .mode = QCRYPTO_CIPHER_MODE_CCM,
+ .hex_key = "56df5c8f263f0e42"
+ "ef7ad3cefc846062"
+ "cab440af5fc9c901",
+ .hex_nonce = "03d63c8c8684b6cd"
+ "ef092e94",
+ .hex_aad = "0265783ce9213091"
+ "b1b9da769a786d95"
+ "f28832a3f250cb4c"
+ "e300736984698779",
+ .hex_plain = "9fd2024b5249313c"
+ "43693a2d8e70ad7e"
+ "e0e54609808913b2"
+ "8c8bd93f86fbb56b",
+ .hex_cipher = "00161ecf83e37c91"
+ "ce8bdb138370e37a"
+ "d638efed5e3a8aed"
+ "1841db9f8654251d",
+ .hex_tag = "18219f9396f03723"
+ "c185f9781ec0a6ad",
+ },
+ {
+ /* Borrowed from nettle*/
+ .path = "/crypto/aead/ccm-aes-256",
+ .alg = QCRYPTO_CIPHER_ALG_AES_256,
+ .mode = QCRYPTO_CIPHER_MODE_CCM,
+ .hex_key = "4041424344454647"
+ "48494a4b4c4d4e4f"
+ "5051525354555657"
+ "58595a5b5c5d5e5f",
+ .hex_nonce = "1011121314151617"
+ "18191a1b",
+ .hex_aad = "0001020304050607"
+ "08090a0b0c0d0e0f"
+ "10111213",
+ .hex_plain = "2021222324252627"
+ "28292a2b2c2d2e2f"
+ "3031323334353637",
+ .hex_cipher = "04f883aeb3bd0730"
+ "eaf50bb6de4fa221"
+ "2034e4e41b0e75e5",
+ .hex_tag = "9bba3f3a107f3239"
+ "bd63902923f80371",
+ },
+};
+
+static inline int unhex(char c)
+{
+ if (c >= 'a' && c <= 'f') {
+ return 10 + (c - 'a');
+ }
+ if (c >= 'A' && c <= 'F') {
+ return 10 + (c - 'A');
+ }
+ return c - '0';
+}
+
+static inline char hex(int i)
+{
+ if (i < 10) {
+ return '0' + i;
+ }
+ return 'a' + (i - 10);
+}
+
+static size_t unhex_string(const char *hexstr,
+ uint8_t **data)
+{
+ size_t len;
+ size_t i;
+
+ if (!hexstr) {
+ *data = NULL;
+ return 0;
+ }
+
+ len = strlen(hexstr);
+ *data = g_new0(uint8_t, len / 2);
+
+ for (i = 0; i < len; i += 2) {
+ (*data)[i / 2] = (unhex(hexstr[i]) << 4)
+ | unhex(hexstr[i + 1]);
+ }
+ return len / 2;
+}
+
+static char *hex_string(const uint8_t *bytes,
+ size_t len)
+{
+ char *hexstr = g_new0(char, len * 2 + 1);
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ hexstr[i * 2] = hex((bytes[i] >> 4) & 0xf);
+ hexstr[i * 2 + 1] = hex(bytes[i] & 0xf);
+ }
+ hexstr[len * 2] = '\0';
+
+ return hexstr;
+}
+
+static void _test_aead(const QCryptoAeadTestData *data,
+ bool encrypt)
+{
+ QCryptoAead *aead;
+
+ uint8_t *key = NULL, *nonce = NULL;
+ uint8_t *aad = NULL, *in = NULL;
+ size_t key_len = 0, nonce_len = 0, aad_len = 0;
+ size_t in_len = 0, tag_len = 0;
+ uint8_t *hex_tmp = NULL;
+ uint8_t *out = NULL;
+ uint8_t out_len = 0;
+ Error *err = NULL;
+ int ret;
+
+ key_len = unhex_string(data->hex_key, &key);
+ nonce_len = unhex_string(data->hex_nonce, &nonce);
+ aad_len = unhex_string(data->hex_aad, &aad);
+ if (encrypt) {
+ in_len = unhex_string(data->hex_plain, &in);
+ } else {
+ in_len = unhex_string(data->hex_cipher, &in);
+ }
+
+ tag_len = strlen(data->hex_tag) / 2;
+ out_len = in_len + tag_len;
+ out = g_new0(uint8_t, out_len);
+
+ aead = qcrypto_aead_new(data->alg, data->mode,
+ key, key_len, &err);
+ g_assert(aead != NULL);
+
+ ret = qcrypto_aead_set_nonce(aead, nonce, nonce_len,
+ aad_len, in_len, tag_len,
+ &err);
+ g_assert(ret == 0);
+
+ ret = qcrypto_aead_authenticate(aead, aad, aad_len,
+ &err);
+ g_assert(ret == 0);
+
+ if (encrypt) {
+ ret = qcrypto_aead_encrypt(aead, in, in_len,
+ out, in_len, &err);
+ g_assert(ret == 0);
+
+ hex_tmp = (uint8_t *)hex_string(out, in_len);
+ g_assert_cmpstr((char *)hex_tmp, ==,
+ (char *)data->hex_cipher);
+ g_free(hex_tmp);
+ } else {
+ ret = qcrypto_aead_decrypt(aead, in, in_len,
+ out, in_len, &err);
+ g_assert(ret == 0);
+
+ hex_tmp = (uint8_t *)hex_string(out, in_len);
+ g_assert_cmpstr((char *)hex_tmp, ==,
+ (char *)data->hex_plain);
+ g_free(hex_tmp);
+ }
+
+ ret = qcrypto_aead_get_tag(aead, out + in_len,
+ tag_len, &err);
+ g_assert(ret == 0);
+
+ hex_tmp = (uint8_t *)hex_string(out + in_len,
+ tag_len);
+ g_assert_cmpstr((char *)hex_tmp, ==,
+ (char *)data->hex_tag);
+ g_free(hex_tmp);
+
+ g_free(out);
+ g_free(in);
+ g_free(aad);
+ g_free(nonce);
+ g_free(key);
+ qcrypto_aead_free(aead);
+}
+
+static void test_aead(const void *opaque)
+{
+ const QCryptoAeadTestData *data = opaque;
+
+ /* test encrypt */
+ _test_aead(data, 1);
+
+ /* test decrypt */
+ _test_aead(data, 0);
+}
+
+int main(int argc, char **argv)
+{
+ size_t i;
+
+ g_test_init(&argc, &argv, NULL);
+
+ g_assert(qcrypto_init(NULL) == 0);
+
+ for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
+ if (qcrypto_aead_supports(test_data[i].alg,
+ test_data[i].mode)) {
+ g_test_add_data_func(test_data[i].path,
+ &test_data[i], test_aead);
+ }
+ }
+
+ return g_test_run();
+}
--
2.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-01-03 0:34 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-01-03 0:33 [Qemu-devel] [PATCH 0/6] add AEAD algorithms support Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 1/6] configure: add CONFIG_GCRYPT/NETTLE_AEAD item Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 2/6] crypto: add AEAD algorithms framework Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 3/6] crypto: implement nettle-backed AEAD algorithms Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 4/6] crypto: implement gcrypt-backed " Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 5/6] crypto: implement other common funcs for " Longpeng(Mike)
2017-01-03 0:33 ` [Qemu-devel] [PATCH 6/6] crypto: add AEAD algorithms testcases Longpeng(Mike)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).