From patchwork Thu Jan 5 00:49:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Longpeng (Mike, Cloud Infrastructure Service Product Dept.)" X-Patchwork-Id: 711183 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tv8K80tVXz9sxS for ; Thu, 5 Jan 2017 11:52:12 +1100 (AEDT) Received: from localhost ([::1]:43051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cOwHp-0003dG-SH for incoming@patchwork.ozlabs.org; Wed, 04 Jan 2017 19:52:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60078) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cOwGF-00024w-4T for qemu-devel@nongnu.org; Wed, 04 Jan 2017 19:50:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cOwGB-0008MO-Lw for qemu-devel@nongnu.org; Wed, 04 Jan 2017 19:50:31 -0500 Received: from szxga02-in.huawei.com ([119.145.14.65]:41906) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1cOwGA-0008Gj-Hx for qemu-devel@nongnu.org; Wed, 04 Jan 2017 19:50:27 -0500 Received: from 172.24.1.137 (EHLO szxeml430-hub.china.huawei.com) ([172.24.1.137]) by szxrg02-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DSZ81161; Thu, 05 Jan 2017 08:50:15 +0800 (CST) Received: from localhost (10.177.246.209) by szxeml430-hub.china.huawei.com (10.82.67.185) with Microsoft SMTP Server id 14.3.235.1; Thu, 5 Jan 2017 08:50:09 +0800 From: "Longpeng(Mike)" To: Date: Thu, 5 Jan 2017 08:49:37 +0800 Message-ID: <1483577381-38088-3-git-send-email-longpeng2@huawei.com> X-Mailer: git-send-email 1.8.4.msysgit.0 In-Reply-To: <1483577381-38088-1-git-send-email-longpeng2@huawei.com> References: <1483577381-38088-1-git-send-email-longpeng2@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.246.209] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020203.586D9848.0002, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 326829e8c1c278b4d22794e9bf80ddf6 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] [fuzzy] X-Received-From: 119.145.14.65 Subject: [Qemu-devel] [PATCH RESEND 2/6] crypto: add AEAD algorithms framework X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Longpeng\(Mike\)" , arei.gonglei@huawei.com, qemu-devel@nongnu.org, wu.wubin@huawei.com, jianjay.zhou@huawei.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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) --- 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) + * + * 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 + +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) + * + * 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 +#include +#include + +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) + * + * 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']} ##