From nobody Thu May 16 06:20:40 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1592217468; cv=none; d=zohomail.com; s=zohoarc; b=mlOLVRGO+TxyCJZPwG2Oyf3LPgppcoK/6v8jjo6CAViqXpSRvxbUnldfcrKu6kLPuDYNOr3LKTwAlZY6b9lr4AdMO40LNOVm4gJgxP6f23mXXuCzN3gwNq5onImHU4rXWlslyJzsIEbandRSDMjUzBbMFRnqaR/Ts0mWsahUboc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592217468; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=DcbBSo5vE0YFfV2gRVV5Ik/OnmR1K71bEatWoKpYXhs=; b=BP9P8LUOFMkoKQbai9su9szM1rMEX+lUzibGd7jKTEsDJY/KFETpQgaHIZ1xXk9b8A7nVgke9B1TD3ehxNsidkBszROq3KxiuHCbwZIKjgjVla1LQPmGgROXqAThUWih3AfhjLePk83crO6JzFuH51/I5SWLPAZ3f53zvVQKiZU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1592217468770711.7208000661519; Mon, 15 Jun 2020 03:37:48 -0700 (PDT) Received: from localhost ([::1]:56604 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jkmUt-0002Ok-Cx for importer@patchew.org; Mon, 15 Jun 2020 06:37:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52482) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkmTs-0000ft-Et for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:36:44 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:57523 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jkmTq-0007Rn-HA for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:36:44 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-395-w3jN1ibtM3CcjVe4FauUZw-1; Mon, 15 Jun 2020 06:36:37 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E29B9835B48; Mon, 15 Jun 2020 10:36:36 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id ED8985D9CD; Mon, 15 Jun 2020 10:36:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1592217401; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DcbBSo5vE0YFfV2gRVV5Ik/OnmR1K71bEatWoKpYXhs=; b=ZslIfXtEe10bTpsZoMPZ+oBqdDTzDgdRexVFEA1zWJs21ACuHJExLZOwUMle3cylqbvacP 2FCb7d2dYFaILeDb+n1gNWtmMdVA4dOshw6EPGpEY9uSIUdLjgLcCMVPRjpWI2YlJcKv7a SdylRmdsvHPoBQeIoDD0u+aGNijU+cY= X-MC-Unique: w3jN1ibtM3CcjVe4FauUZw-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PULL 1/5] crypto: add "none" random provider Date: Mon, 15 Jun 2020 11:36:29 +0100 Message-Id: <20200615103633.300208-2-berrange@redhat.com> In-Reply-To: <20200615103633.300208-1-berrange@redhat.com> References: <20200615103633.300208-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=207.211.31.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/15 01:17:36 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @redhat.com) From: Marek Marczykowski-G=C3=B3recki In case of not using random-number needing feature, it makes sense to skip RNG init too. This is especially helpful when QEMU is sandboxed in Stubdomain under Xen, where there is very little entropy so initial getrandom() call delays the startup several seconds. In that setup, no random bytes are needed at all. Signed-off-by: Marek Marczykowski-G=C3=B3recki Signed-off-by: Daniel P. Berrang=C3=A9 --- configure | 11 +++++++++++ crypto/Makefile.objs | 3 ++- crypto/random-none.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 crypto/random-none.c diff --git a/configure b/configure index bb7fd12612..997284e094 100755 --- a/configure +++ b/configure @@ -509,6 +509,7 @@ libpmem=3D"" default_devices=3D"yes" plugins=3D"no" fuzzing=3D"no" +rng_none=3D"no" =20 supported_cpu=3D"no" supported_os=3D"no" @@ -1601,6 +1602,10 @@ for opt do ;; --gdb=3D*) gdb_bin=3D"$optarg" ;; + --enable-rng-none) rng_none=3Dyes + ;; + --disable-rng-none) rng_none=3Dno + ;; *) echo "ERROR: unknown option $opt" echo "Try '$0 --help' for more information" @@ -1898,6 +1903,7 @@ disabled with --disable-FEATURE, default is enabled i= f available: debug-mutex mutex debugging support libpmem libpmem support xkbcommon xkbcommon support + rng-none dummy RNG, avoid using /dev/(u)random and getrandom() =20 NOTE: The object files are built at the place where configure is launched EOF @@ -6767,6 +6773,7 @@ echo "default devices $default_devices" echo "plugin support $plugins" echo "fuzzing support $fuzzing" echo "gdb $gdb_bin" +echo "rng-none $rng_none" =20 if test "$supported_cpu" =3D "no"; then echo @@ -7744,6 +7751,10 @@ if test "$edk2_blobs" =3D "yes" ; then echo "DECOMPRESS_EDK2_BLOBS=3Dy" >> $config_host_mak fi =20 +if test "$rng_none" =3D "yes"; then + echo "CONFIG_RNG_NONE=3Dy" >> $config_host_mak +fi + # use included Linux headers if test "$linux" =3D "yes" ; then mkdir -p linux-headers diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs index c2a371b0b4..cdee92b4e5 100644 --- a/crypto/Makefile.objs +++ b/crypto/Makefile.objs @@ -35,5 +35,6 @@ crypto-obj-y +=3D block-luks.o =20 util-obj-$(CONFIG_GCRYPT) +=3D random-gcrypt.o util-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) +=3D random-gnutls.o -util-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) +=3D random-p= latform.o +util-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,$(CONFIG_RNG_NONE= ))) +=3D random-none.o +util-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,$(if $(CONFIG_RNG= _NONE),n,y))) +=3D random-platform.o util-obj-y +=3D aes.o init.o diff --git a/crypto/random-none.c b/crypto/random-none.c new file mode 100644 index 0000000000..102f8a4dce --- /dev/null +++ b/crypto/random-none.c @@ -0,0 +1,38 @@ +/* + * QEMU Crypto "none" random number provider + * + * Copyright (c) 2020 Marek Marczykowski-G=C3=B3recki + * + * + * 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.1 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 "qemu/osdep.h" + +#include "crypto/random.h" +#include "qapi/error.h" + +int qcrypto_random_init(Error **errp) +{ + return 0; +} + +int qcrypto_random_bytes(void *buf, + size_t buflen, + Error **errp) +{ + error_setg(errp, "Random bytes not available with \"none\" rng"); + return -1; +} --=20 2.26.2 From nobody Thu May 16 06:20:40 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1592217783; cv=none; d=zohomail.com; s=zohoarc; b=Qk+YWwU9dqDS2WM2Z2EkLFv1xIGz2vrZaFdXazmbHnezWaLamqKhFE359OO1vxcXRukuJxE+EuAETkURwWhImboU4VC8kA5sg8wBwruxlj7YiwuJnNqPu/ly9bdV8En0LKMJR/SmYE0mIh0d3+EnLmALwpPw1J0ymUwp/2JZ+hU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592217783; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=uSy78qr6Oe6o0jCPl0NKq4EI77Wz8aKk46+Qn6KdhTY=; b=ZJZCYCPT1DbHlRkgjU35Y7t65EW78wSGADSKus7BM8o2AfCxEBOSeWVYQV1MxRDsoQlw1CV3DQPaX9NejTl765G4NzOxr4QcpWnvgZl553NHahM51tT75jL4w6COko21FsRNKJodEzpU2ndzZbYhcK+rt/oI5yBa8ynlgKlI/Ks= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1592217783457943.5716369513616; Mon, 15 Jun 2020 03:43:03 -0700 (PDT) Received: from localhost ([::1]:43576 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jkmZx-0000UN-U3 for importer@patchew.org; Mon, 15 Jun 2020 06:43:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52534) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkmU2-00013J-AC for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:36:54 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:23053 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jkmTz-0007Sf-Be for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:36:53 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-41-OzvPZbZrMJGkXzv8GPjGqg-1; Mon, 15 Jun 2020 06:36:42 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3948E18585AA; Mon, 15 Jun 2020 10:36:41 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5120A5D9CC; Mon, 15 Jun 2020 10:36:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1592217410; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uSy78qr6Oe6o0jCPl0NKq4EI77Wz8aKk46+Qn6KdhTY=; b=hXOfvp8Ma6+RAl59/yU7D5kAeCn0sxbXw/6KLR6je/BYsNRG9Ibrtkq3fs+Cf7+RcywVau ZKCZXzqDNHzUHbfR9c3H461xIF7sw1UPkO5vwcHZEfgqLJv6ZMrDBlb8wen0ABcMQ09iSj hpEn+ngyOqS2vNjdVvagW/xna1uExm8= X-MC-Unique: OzvPZbZrMJGkXzv8GPjGqg-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PULL 2/5] crypto/secret: move main logic from 'secret' to 'secret_common'. Date: Mon, 15 Jun 2020 11:36:30 +0100 Message-Id: <20200615103633.300208-3-berrange@redhat.com> In-Reply-To: <20200615103633.300208-1-berrange@redhat.com> References: <20200615103633.300208-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=207.211.31.81; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/15 01:43:27 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Krasikov , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) From: Alexey Krasikov Create base class 'common secret'. Move common data and logic from 'secret' to 'common_secret' class. This allowed adding abstraction layer for easier adding new 'secret' objects in future. Convert 'secret' class to child from basic 'secret_common' with 'data' and 'file' properties. Signed-off-by: Alexey Krasikov Signed-off-by: Daniel P. Berrang=C3=A9 --- crypto/Makefile.objs | 1 + crypto/secret.c | 347 +--------------------------- crypto/secret_common.c | 403 +++++++++++++++++++++++++++++++++ include/crypto/secret.h | 20 +- include/crypto/secret_common.h | 68 ++++++ 5 files changed, 482 insertions(+), 357 deletions(-) create mode 100644 crypto/secret_common.c create mode 100644 include/crypto/secret_common.h diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs index cdee92b4e5..110dec1b87 100644 --- a/crypto/Makefile.objs +++ b/crypto/Makefile.objs @@ -18,6 +18,7 @@ crypto-obj-y +=3D tlscredsanon.o crypto-obj-y +=3D tlscredspsk.o crypto-obj-y +=3D tlscredsx509.o crypto-obj-y +=3D tlssession.o +crypto-obj-y +=3D secret_common.o crypto-obj-y +=3D secret.o crypto-obj-y +=3D pbkdf.o crypto-obj-$(CONFIG_NETTLE) +=3D pbkdf-nettle.o diff --git a/crypto/secret.c b/crypto/secret.c index 3107aecb47..3447e2f64b 100644 --- a/crypto/secret.c +++ b/crypto/secret.c @@ -20,16 +20,14 @@ =20 #include "qemu/osdep.h" #include "crypto/secret.h" -#include "crypto/cipher.h" #include "qapi/error.h" #include "qom/object_interfaces.h" -#include "qemu/base64.h" #include "qemu/module.h" #include "trace.h" =20 =20 static void -qcrypto_secret_load_data(QCryptoSecret *secret, +qcrypto_secret_load_data(QCryptoSecretCommon *sec_common, uint8_t **output, size_t *outputlen, Error **errp) @@ -38,6 +36,8 @@ qcrypto_secret_load_data(QCryptoSecret *secret, size_t length =3D 0; GError *gerr =3D NULL; =20 + QCryptoSecret *secret =3D QCRYPTO_SECRET(sec_common); + *output =3D NULL; *outputlen =3D 0; =20 @@ -65,198 +65,6 @@ qcrypto_secret_load_data(QCryptoSecret *secret, } =20 =20 -static void qcrypto_secret_decrypt(QCryptoSecret *secret, - const uint8_t *input, - size_t inputlen, - uint8_t **output, - size_t *outputlen, - Error **errp) -{ - g_autofree uint8_t *key =3D NULL; - g_autofree uint8_t *ciphertext =3D NULL; - g_autofree uint8_t *iv =3D NULL; - size_t keylen, ciphertextlen, ivlen; - g_autoptr(QCryptoCipher) aes =3D NULL; - g_autofree uint8_t *plaintext =3D NULL; - - *output =3D NULL; - *outputlen =3D 0; - - if (qcrypto_secret_lookup(secret->keyid, - &key, &keylen, - errp) < 0) { - return; - } - - if (keylen !=3D 32) { - error_setg(errp, "Key should be 32 bytes in length"); - return; - } - - if (!secret->iv) { - error_setg(errp, "IV is required to decrypt secret"); - return; - } - - iv =3D qbase64_decode(secret->iv, -1, &ivlen, errp); - if (!iv) { - return; - } - if (ivlen !=3D 16) { - error_setg(errp, "IV should be 16 bytes in length not %zu", - ivlen); - return; - } - - aes =3D qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256, - QCRYPTO_CIPHER_MODE_CBC, - key, keylen, - errp); - if (!aes) { - return; - } - - if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) { - return; - } - - if (secret->format =3D=3D QCRYPTO_SECRET_FORMAT_BASE64) { - ciphertext =3D qbase64_decode((const gchar*)input, - inputlen, - &ciphertextlen, - errp); - if (!ciphertext) { - return; - } - plaintext =3D g_new0(uint8_t, ciphertextlen + 1); - } else { - ciphertextlen =3D inputlen; - plaintext =3D g_new0(uint8_t, inputlen + 1); - } - if (qcrypto_cipher_decrypt(aes, - ciphertext ? ciphertext : input, - plaintext, - ciphertextlen, - errp) < 0) { - return; - } - - if (plaintext[ciphertextlen - 1] > 16 || - plaintext[ciphertextlen - 1] > ciphertextlen) { - error_setg(errp, "Incorrect number of padding bytes (%d) " - "found on decrypted data", - (int)plaintext[ciphertextlen - 1]); - return; - } - - /* Even though plaintext may contain arbitrary NUL - * ensure it is explicitly NUL terminated. - */ - ciphertextlen -=3D plaintext[ciphertextlen - 1]; - plaintext[ciphertextlen] =3D '\0'; - - *output =3D g_steal_pointer(&plaintext); - *outputlen =3D ciphertextlen; -} - - -static void qcrypto_secret_decode(const uint8_t *input, - size_t inputlen, - uint8_t **output, - size_t *outputlen, - Error **errp) -{ - *output =3D qbase64_decode((const gchar*)input, - inputlen, - outputlen, - errp); -} - - -static void -qcrypto_secret_prop_set_loaded(Object *obj, - bool value, - Error **errp) -{ - QCryptoSecret *secret =3D QCRYPTO_SECRET(obj); - - if (value) { - Error *local_err =3D NULL; - uint8_t *input =3D NULL; - size_t inputlen =3D 0; - uint8_t *output =3D NULL; - size_t outputlen =3D 0; - - qcrypto_secret_load_data(secret, &input, &inputlen, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - - if (secret->keyid) { - qcrypto_secret_decrypt(secret, input, inputlen, - &output, &outputlen, &local_err); - g_free(input); - if (local_err) { - error_propagate(errp, local_err); - return; - } - input =3D output; - inputlen =3D outputlen; - } else { - if (secret->format =3D=3D QCRYPTO_SECRET_FORMAT_BASE64) { - qcrypto_secret_decode(input, inputlen, - &output, &outputlen, &local_err); - g_free(input); - if (local_err) { - error_propagate(errp, local_err); - return; - } - input =3D output; - inputlen =3D outputlen; - } - } - - secret->rawdata =3D input; - secret->rawlen =3D inputlen; - } else { - g_free(secret->rawdata); - secret->rawdata =3D NULL; - secret->rawlen =3D 0; - } -} - - -static bool -qcrypto_secret_prop_get_loaded(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoSecret *secret =3D QCRYPTO_SECRET(obj); - return secret->rawdata !=3D NULL; -} - - -static void -qcrypto_secret_prop_set_format(Object *obj, - int value, - Error **errp G_GNUC_UNUSED) -{ - QCryptoSecret *creds =3D QCRYPTO_SECRET(obj); - - creds->format =3D value; -} - - -static int -qcrypto_secret_prop_get_format(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoSecret *creds =3D QCRYPTO_SECRET(obj); - - return creds->format; -} - - static void qcrypto_secret_prop_set_data(Object *obj, const char *value, @@ -299,48 +107,6 @@ qcrypto_secret_prop_get_file(Object *obj, } =20 =20 -static void -qcrypto_secret_prop_set_iv(Object *obj, - const char *value, - Error **errp) -{ - QCryptoSecret *secret =3D QCRYPTO_SECRET(obj); - - g_free(secret->iv); - secret->iv =3D g_strdup(value); -} - - -static char * -qcrypto_secret_prop_get_iv(Object *obj, - Error **errp) -{ - QCryptoSecret *secret =3D QCRYPTO_SECRET(obj); - return g_strdup(secret->iv); -} - - -static void -qcrypto_secret_prop_set_keyid(Object *obj, - const char *value, - Error **errp) -{ - QCryptoSecret *secret =3D QCRYPTO_SECRET(obj); - - g_free(secret->keyid); - secret->keyid =3D g_strdup(value); -} - - -static char * -qcrypto_secret_prop_get_keyid(Object *obj, - Error **errp) -{ - QCryptoSecret *secret =3D QCRYPTO_SECRET(obj); - return g_strdup(secret->keyid); -} - - static void qcrypto_secret_complete(UserCreatable *uc, Error **errp) { @@ -353,129 +119,30 @@ qcrypto_secret_finalize(Object *obj) { QCryptoSecret *secret =3D QCRYPTO_SECRET(obj); =20 - g_free(secret->iv); g_free(secret->file); - g_free(secret->keyid); - g_free(secret->rawdata); g_free(secret->data); } =20 static void qcrypto_secret_class_init(ObjectClass *oc, void *data) { - UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(oc); + QCryptoSecretCommonClass *sic =3D QCRYPTO_SECRET_COMMON_CLASS(oc); + sic->load_data =3D qcrypto_secret_load_data; =20 + UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(oc); ucc->complete =3D qcrypto_secret_complete; =20 - object_class_property_add_bool(oc, "loaded", - qcrypto_secret_prop_get_loaded, - qcrypto_secret_prop_set_loaded); - object_class_property_add_enum(oc, "format", - "QCryptoSecretFormat", - &QCryptoSecretFormat_lookup, - qcrypto_secret_prop_get_format, - qcrypto_secret_prop_set_format); object_class_property_add_str(oc, "data", qcrypto_secret_prop_get_data, qcrypto_secret_prop_set_data); object_class_property_add_str(oc, "file", qcrypto_secret_prop_get_file, qcrypto_secret_prop_set_file); - object_class_property_add_str(oc, "keyid", - qcrypto_secret_prop_get_keyid, - qcrypto_secret_prop_set_keyid); - object_class_property_add_str(oc, "iv", - qcrypto_secret_prop_get_iv, - qcrypto_secret_prop_set_iv); -} - - -int qcrypto_secret_lookup(const char *secretid, - uint8_t **data, - size_t *datalen, - Error **errp) -{ - Object *obj; - QCryptoSecret *secret; - - obj =3D object_resolve_path_component( - object_get_objects_root(), secretid); - if (!obj) { - error_setg(errp, "No secret with id '%s'", secretid); - return -1; - } - - secret =3D (QCryptoSecret *) - object_dynamic_cast(obj, - TYPE_QCRYPTO_SECRET); - if (!secret) { - error_setg(errp, "Object with id '%s' is not a secret", - secretid); - return -1; - } - - if (!secret->rawdata) { - error_setg(errp, "Secret with id '%s' has no data", - secretid); - return -1; - } - - *data =3D g_new0(uint8_t, secret->rawlen + 1); - memcpy(*data, secret->rawdata, secret->rawlen); - (*data)[secret->rawlen] =3D '\0'; - *datalen =3D secret->rawlen; - - return 0; -} - - -char *qcrypto_secret_lookup_as_utf8(const char *secretid, - Error **errp) -{ - uint8_t *data; - size_t datalen; - - if (qcrypto_secret_lookup(secretid, - &data, - &datalen, - errp) < 0) { - return NULL; - } - - if (!g_utf8_validate((const gchar*)data, datalen, NULL)) { - error_setg(errp, - "Data from secret %s is not valid UTF-8", - secretid); - g_free(data); - return NULL; - } - - return (char *)data; -} - - -char *qcrypto_secret_lookup_as_base64(const char *secretid, - Error **errp) -{ - uint8_t *data; - size_t datalen; - char *ret; - - if (qcrypto_secret_lookup(secretid, - &data, - &datalen, - errp) < 0) { - return NULL; - } - - ret =3D g_base64_encode(data, datalen); - g_free(data); - return ret; } =20 =20 static const TypeInfo qcrypto_secret_info =3D { - .parent =3D TYPE_OBJECT, + .parent =3D TYPE_QCRYPTO_SECRET_COMMON, .name =3D TYPE_QCRYPTO_SECRET, .instance_size =3D sizeof(QCryptoSecret), .instance_finalize =3D qcrypto_secret_finalize, diff --git a/crypto/secret_common.c b/crypto/secret_common.c new file mode 100644 index 0000000000..b03d530867 --- /dev/null +++ b/crypto/secret_common.c @@ -0,0 +1,403 @@ +/* + * QEMU crypto secret support + * + * 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.1 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 "qemu/osdep.h" +#include "crypto/secret_common.h" +#include "crypto/cipher.h" +#include "qapi/error.h" +#include "qom/object_interfaces.h" +#include "qemu/base64.h" +#include "qemu/module.h" +#include "trace.h" + + +static void qcrypto_secret_decrypt(QCryptoSecretCommon *secret, + const uint8_t *input, + size_t inputlen, + uint8_t **output, + size_t *outputlen, + Error **errp) +{ + g_autofree uint8_t *iv =3D NULL; + g_autofree uint8_t *key =3D NULL; + g_autofree uint8_t *ciphertext =3D NULL; + size_t keylen, ciphertextlen, ivlen; + g_autoptr(QCryptoCipher) aes =3D NULL; + g_autofree uint8_t *plaintext =3D NULL; + + *output =3D NULL; + *outputlen =3D 0; + + if (qcrypto_secret_lookup(secret->keyid, + &key, &keylen, + errp) < 0) { + return; + } + + if (keylen !=3D 32) { + error_setg(errp, "Key should be 32 bytes in length"); + return; + } + + if (!secret->iv) { + error_setg(errp, "IV is required to decrypt secret"); + return; + } + + iv =3D qbase64_decode(secret->iv, -1, &ivlen, errp); + if (!iv) { + return; + } + if (ivlen !=3D 16) { + error_setg(errp, "IV should be 16 bytes in length not %zu", + ivlen); + return; + } + + aes =3D qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256, + QCRYPTO_CIPHER_MODE_CBC, + key, keylen, + errp); + if (!aes) { + return; + } + + if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) { + return; + } + + if (secret->format =3D=3D QCRYPTO_SECRET_FORMAT_BASE64) { + ciphertext =3D qbase64_decode((const gchar *)input, + inputlen, + &ciphertextlen, + errp); + if (!ciphertext) { + return; + } + plaintext =3D g_new0(uint8_t, ciphertextlen + 1); + } else { + ciphertextlen =3D inputlen; + plaintext =3D g_new0(uint8_t, inputlen + 1); + } + if (qcrypto_cipher_decrypt(aes, + ciphertext ? ciphertext : input, + plaintext, + ciphertextlen, + errp) < 0) { + return; + } + + if (plaintext[ciphertextlen - 1] > 16 || + plaintext[ciphertextlen - 1] > ciphertextlen) { + error_setg(errp, "Incorrect number of padding bytes (%d) " + "found on decrypted data", + (int)plaintext[ciphertextlen - 1]); + return; + } + + /* + * Even though plaintext may contain arbitrary NUL + * ensure it is explicitly NUL terminated. + */ + ciphertextlen -=3D plaintext[ciphertextlen - 1]; + plaintext[ciphertextlen] =3D '\0'; + + *output =3D g_steal_pointer(&plaintext); + *outputlen =3D ciphertextlen; +} + + +static void qcrypto_secret_decode(const uint8_t *input, + size_t inputlen, + uint8_t **output, + size_t *outputlen, + Error **errp) +{ + *output =3D qbase64_decode((const gchar *)input, + inputlen, + outputlen, + errp); +} + + +static void +qcrypto_secret_prop_set_loaded(Object *obj, + bool value, + Error **errp) +{ + QCryptoSecretCommon *secret =3D QCRYPTO_SECRET_COMMON(obj); + QCryptoSecretCommonClass *sec_class + =3D QCRYPTO_SECRET_COMMON_GET_CLASS(obj); + + if (value) { + Error *local_err =3D NULL; + uint8_t *input =3D NULL; + size_t inputlen =3D 0; + uint8_t *output =3D NULL; + size_t outputlen =3D 0; + + if (sec_class->load_data) { + sec_class->load_data(secret, &input, &inputlen, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } else { + error_setg(errp, "%s provides no 'load_data' method'", + object_get_typename(obj)); + return; + } + + if (secret->keyid) { + qcrypto_secret_decrypt(secret, input, inputlen, + &output, &outputlen, &local_err); + g_free(input); + if (local_err) { + error_propagate(errp, local_err); + return; + } + input =3D output; + inputlen =3D outputlen; + } else { + if (secret->format =3D=3D QCRYPTO_SECRET_FORMAT_BASE64) { + qcrypto_secret_decode(input, inputlen, + &output, &outputlen, &local_err); + g_free(input); + if (local_err) { + error_propagate(errp, local_err); + return; + } + input =3D output; + inputlen =3D outputlen; + } + } + + secret->rawdata =3D input; + secret->rawlen =3D inputlen; + } else { + g_free(secret->rawdata); + secret->rawlen =3D 0; + } +} + + +static bool +qcrypto_secret_prop_get_loaded(Object *obj, + Error **errp G_GNUC_UNUSED) +{ + QCryptoSecretCommon *secret =3D QCRYPTO_SECRET_COMMON(obj); + return secret->rawdata !=3D NULL; +} + + +static void +qcrypto_secret_prop_set_format(Object *obj, + int value, + Error **errp G_GNUC_UNUSED) +{ + QCryptoSecretCommon *creds =3D QCRYPTO_SECRET_COMMON(obj); + creds->format =3D value; +} + + +static int +qcrypto_secret_prop_get_format(Object *obj, + Error **errp G_GNUC_UNUSED) +{ + QCryptoSecretCommon *creds =3D QCRYPTO_SECRET_COMMON(obj); + return creds->format; +} + + +static void +qcrypto_secret_prop_set_iv(Object *obj, + const char *value, + Error **errp) +{ + QCryptoSecretCommon *secret =3D QCRYPTO_SECRET_COMMON(obj); + + g_free(secret->iv); + secret->iv =3D g_strdup(value); +} + + +static char * +qcrypto_secret_prop_get_iv(Object *obj, + Error **errp) +{ + QCryptoSecretCommon *secret =3D QCRYPTO_SECRET_COMMON(obj); + return g_strdup(secret->iv); +} + + +static void +qcrypto_secret_prop_set_keyid(Object *obj, + const char *value, + Error **errp) +{ + QCryptoSecretCommon *secret =3D QCRYPTO_SECRET_COMMON(obj); + + g_free(secret->keyid); + secret->keyid =3D g_strdup(value); +} + + +static char * +qcrypto_secret_prop_get_keyid(Object *obj, + Error **errp) +{ + QCryptoSecretCommon *secret =3D QCRYPTO_SECRET_COMMON(obj); + return g_strdup(secret->keyid); +} + + +static void +qcrypto_secret_finalize(Object *obj) +{ + QCryptoSecretCommon *secret =3D QCRYPTO_SECRET_COMMON(obj); + + g_free(secret->iv); + g_free(secret->keyid); + g_free(secret->rawdata); +} + +static void +qcrypto_secret_class_init(ObjectClass *oc, void *data) +{ + object_class_property_add_bool(oc, "loaded", + qcrypto_secret_prop_get_loaded, + qcrypto_secret_prop_set_loaded); + object_class_property_add_enum(oc, "format", + "QCryptoSecretFormat", + &QCryptoSecretFormat_lookup, + qcrypto_secret_prop_get_format, + qcrypto_secret_prop_set_format); + object_class_property_add_str(oc, "keyid", + qcrypto_secret_prop_get_keyid, + qcrypto_secret_prop_set_keyid); + object_class_property_add_str(oc, "iv", + qcrypto_secret_prop_get_iv, + qcrypto_secret_prop_set_iv); +} + + +int qcrypto_secret_lookup(const char *secretid, + uint8_t **data, + size_t *datalen, + Error **errp) +{ + Object *obj; + QCryptoSecretCommon *secret; + + obj =3D object_resolve_path_component( + object_get_objects_root(), secretid); + if (!obj) { + error_setg(errp, "No secret with id '%s'", secretid); + return -1; + } + + secret =3D (QCryptoSecretCommon *) + object_dynamic_cast(obj, + TYPE_QCRYPTO_SECRET_COMMON); + if (!secret) { + error_setg(errp, "Object with id '%s' is not a secret", + secretid); + return -1; + } + + if (!secret->rawdata) { + error_setg(errp, "Secret with id '%s' has no data", + secretid); + return -1; + } + + *data =3D g_new0(uint8_t, secret->rawlen + 1); + memcpy(*data, secret->rawdata, secret->rawlen); + (*data)[secret->rawlen] =3D '\0'; + *datalen =3D secret->rawlen; + + return 0; +} + + +char *qcrypto_secret_lookup_as_utf8(const char *secretid, + Error **errp) +{ + uint8_t *data; + size_t datalen; + + if (qcrypto_secret_lookup(secretid, + &data, + &datalen, + errp) < 0) { + return NULL; + } + + if (!g_utf8_validate((const gchar *)data, datalen, NULL)) { + error_setg(errp, + "Data from secret %s is not valid UTF-8", + secretid); + g_free(data); + return NULL; + } + + return (char *)data; +} + + +char *qcrypto_secret_lookup_as_base64(const char *secretid, + Error **errp) +{ + uint8_t *data; + size_t datalen; + char *ret; + + if (qcrypto_secret_lookup(secretid, + &data, + &datalen, + errp) < 0) { + return NULL; + } + + ret =3D g_base64_encode(data, datalen); + g_free(data); + return ret; +} + + +static const TypeInfo qcrypto_secret_info =3D { + .parent =3D TYPE_OBJECT, + .name =3D TYPE_QCRYPTO_SECRET_COMMON, + .instance_size =3D sizeof(QCryptoSecretCommon), + .instance_finalize =3D qcrypto_secret_finalize, + .class_size =3D sizeof(QCryptoSecretCommonClass), + .class_init =3D qcrypto_secret_class_init, + .abstract =3D true, +}; + + +static void +qcrypto_secret_register_types(void) +{ + type_register_static(&qcrypto_secret_info); +} + + +type_init(qcrypto_secret_register_types); diff --git a/include/crypto/secret.h b/include/crypto/secret.h index 5e07e29bae..2deb461d2f 100644 --- a/include/crypto/secret.h +++ b/include/crypto/secret.h @@ -23,6 +23,7 @@ =20 #include "qapi/qapi-types-crypto.h" #include "qom/object.h" +#include "crypto/secret_common.h" =20 #define TYPE_QCRYPTO_SECRET "secret" #define QCRYPTO_SECRET(obj) \ @@ -119,29 +120,14 @@ typedef struct QCryptoSecretClass QCryptoSecretClass; */ =20 struct QCryptoSecret { - Object parent_obj; - uint8_t *rawdata; - size_t rawlen; - QCryptoSecretFormat format; + QCryptoSecretCommon parent_obj; char *data; char *file; - char *keyid; - char *iv; }; =20 =20 struct QCryptoSecretClass { - ObjectClass parent_class; + QCryptoSecretCommonClass parent_class; }; =20 - -extern int qcrypto_secret_lookup(const char *secretid, - uint8_t **data, - size_t *datalen, - Error **errp); -extern char *qcrypto_secret_lookup_as_utf8(const char *secretid, - Error **errp); -extern char *qcrypto_secret_lookup_as_base64(const char *secretid, - Error **errp); - #endif /* QCRYPTO_SECRET_H */ diff --git a/include/crypto/secret_common.h b/include/crypto/secret_common.h new file mode 100644 index 0000000000..980c02ab71 --- /dev/null +++ b/include/crypto/secret_common.h @@ -0,0 +1,68 @@ +/* + * QEMU crypto secret support + * + * 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.1 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_SECRET_COMMON_H +#define QCRYPTO_SECRET_COMMON_H + +#include "qapi/qapi-types-crypto.h" +#include "qom/object.h" + +#define TYPE_QCRYPTO_SECRET_COMMON "secret_common" +#define QCRYPTO_SECRET_COMMON(obj) \ + OBJECT_CHECK(QCryptoSecretCommon, (obj), TYPE_QCRYPTO_SECRET_COMMON) +#define QCRYPTO_SECRET_COMMON_CLASS(class) \ + OBJECT_CLASS_CHECK(QCryptoSecretCommonClass, \ + (class), TYPE_QCRYPTO_SECRET_COMMON) +#define QCRYPTO_SECRET_COMMON_GET_CLASS(obj) \ + OBJECT_GET_CLASS(QCryptoSecretCommonClass, \ + (obj), TYPE_QCRYPTO_SECRET_COMMON) + +typedef struct QCryptoSecretCommon QCryptoSecretCommon; +typedef struct QCryptoSecretCommonClass QCryptoSecretCommonClass; + +struct QCryptoSecretCommon { + Object parent_obj; + uint8_t *rawdata; + size_t rawlen; + QCryptoSecretFormat format; + char *keyid; + char *iv; +}; + + +struct QCryptoSecretCommonClass { + ObjectClass parent_class; + void (*load_data)(QCryptoSecretCommon *secret, + uint8_t **output, + size_t *outputlen, + Error **errp); +}; + + +extern int qcrypto_secret_lookup(const char *secretid, + uint8_t **data, + size_t *datalen, + Error **errp); +extern char *qcrypto_secret_lookup_as_utf8(const char *secretid, + Error **errp); +extern char *qcrypto_secret_lookup_as_base64(const char *secretid, + Error **errp); + +#endif /* QCRYPTO_SECRET_COMMON_H */ --=20 2.26.2 From nobody Thu May 16 06:20:40 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1592217800; cv=none; d=zohomail.com; s=zohoarc; b=bjwLmK2dGue7BG05YEoCFCa8yzFibgJuNz4hJOObgKL6DodtZBk1P1Z2uTLWr0kmjUuJ1LJoXZt74I2N2IdIOlwerGqbBndNqf6kbCNjD9hI3MxVqxKuUK011XyCZLHs6IR2PhhsNJIWS6SRlId7T3TGAx7wHFCq8Edubrqw3zg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592217800; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0+3p+JNLyczyeCJ2gmwnKj1a+SQ2zoOfi5OnnPEnnG8=; b=CGtDrVRkWYguz3SQ4GZO2QlLO+W2gUcr3VXRLhRRNXE5X3bzQ3O6B+JkiTRL9Mw/y/EzzSIR06JTMQf370eDf6K1p4zvaWrBj9C3FQPuEaGiF8BgBjSyYq7H6YwI1ZCQJ5UGKZqZzYVBMTwidDaohIy0voL54LbmyoVls64wcMw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15922178001361017.8842591401769; Mon, 15 Jun 2020 03:43:20 -0700 (PDT) Received: from localhost ([::1]:44602 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jkmaE-0000vt-RH for importer@patchew.org; Mon, 15 Jun 2020 06:43:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52548) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkmU8-0001I8-FR for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:37:00 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:46222 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jkmU6-0007T5-6N for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:37:00 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-49-oBI3u6txNi-AeRzdBld7ig-1; Mon, 15 Jun 2020 06:36:43 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AB94480F5CC; Mon, 15 Jun 2020 10:36:42 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9BD815D9CC; Mon, 15 Jun 2020 10:36:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1592217417; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0+3p+JNLyczyeCJ2gmwnKj1a+SQ2zoOfi5OnnPEnnG8=; b=XLXEtXa5dQO4u4wCw4+g8JIJW08GLbRJ8B/dKEFaqTI50Zqc8XGisJYjBNcDUUuZCUbi39 jRsAWTy+kGtXA6uGZjqZ9zgXTo15im33rOx2WDzHP+uidYlyWdwmKjXqma7KgeszAqdVrk +gq7C76blAIV8MxlsqyxUdUSJfCH+zQ= X-MC-Unique: oBI3u6txNi-AeRzdBld7ig-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PULL 3/5] crypto/linux_keyring: add 'secret_keyring' secret object. Date: Mon, 15 Jun 2020 11:36:31 +0100 Message-Id: <20200615103633.300208-4-berrange@redhat.com> In-Reply-To: <20200615103633.300208-1-berrange@redhat.com> References: <20200615103633.300208-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=207.211.31.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/15 01:17:36 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Krasikov , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) From: Alexey Krasikov Add the ability for the secret object to obtain secret data from the Linux in-kernel key managment and retention facility, as an extra option to the existing ones: reading from a file or passing directly as a string. The secret is identified by the key serial number. The upper layers need to instantiate the key and make sure the QEMU process has access permissions to read it. Signed-off-by: Alexey Krasikov - Fixed up detection logic default behaviour in configure Signed-off-by: Daniel P. Berrang=C3=A9 --- configure | 45 ++++++++++ crypto/Makefile.objs | 1 + crypto/secret_keyring.c | 148 ++++++++++++++++++++++++++++++++ include/crypto/secret_keyring.h | 52 +++++++++++ 4 files changed, 246 insertions(+) create mode 100644 crypto/secret_keyring.c create mode 100644 include/crypto/secret_keyring.h diff --git a/configure b/configure index 997284e094..3fbb61905a 100755 --- a/configure +++ b/configure @@ -510,6 +510,7 @@ default_devices=3D"yes" plugins=3D"no" fuzzing=3D"no" rng_none=3D"no" +secret_keyring=3D"" =20 supported_cpu=3D"no" supported_os=3D"no" @@ -1606,6 +1607,10 @@ for opt do ;; --disable-rng-none) rng_none=3Dno ;; + --enable-keyring) secret_keyring=3D"yes" + ;; + --disable-keyring) secret_keyring=3D"no" + ;; *) echo "ERROR: unknown option $opt" echo "Try '$0 --help' for more information" @@ -6290,6 +6295,41 @@ case "$slirp" in ;; esac =20 +########################################## +# check for usable __NR_keyctl syscall + +if test "$linux" =3D "yes" ; then + + have_keyring=3Dno + cat > $TMPC << EOF +#include +#include +#include +#include +int main(void) { + return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); +} +EOF + if compile_prog "" "" ; then + have_keyring=3Dyes + fi +fi +if test "$secret_keyring" !=3D "no" +then + if test "$have_keyring" =3D=3D "yes" + then + secret_keyring=3Dyes + else + if test "$secret_keyring" =3D "yes" + then + error_exit "syscall __NR_keyctl requested, \ +but not implemented on your system" + else + secret_keyring=3Dno + fi + fi +fi + =20 ########################################## # End of CC checks @@ -6774,6 +6814,7 @@ echo "plugin support $plugins" echo "fuzzing support $fuzzing" echo "gdb $gdb_bin" echo "rng-none $rng_none" +echo "Linux keyring $secret_keyring" =20 if test "$supported_cpu" =3D "no"; then echo @@ -7659,6 +7700,10 @@ if test -n "$gdb_bin" ; then echo "HAVE_GDB_BIN=3D$gdb_bin" >> $config_host_mak fi =20 +if test "$secret_keyring" =3D "yes" ; then + echo "CONFIG_SECRET_KEYRING=3Dy" >> $config_host_mak +fi + if test "$tcg_interpreter" =3D "yes"; then QEMU_INCLUDES=3D"-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES" elif test "$ARCH" =3D "sparc64" ; then diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs index 110dec1b87..707c02ad37 100644 --- a/crypto/Makefile.objs +++ b/crypto/Makefile.objs @@ -20,6 +20,7 @@ crypto-obj-y +=3D tlscredsx509.o crypto-obj-y +=3D tlssession.o crypto-obj-y +=3D secret_common.o crypto-obj-y +=3D secret.o +crypto-obj-$(CONFIG_SECRET_KEYRING) +=3D secret_keyring.o crypto-obj-y +=3D pbkdf.o crypto-obj-$(CONFIG_NETTLE) +=3D pbkdf-nettle.o crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) +=3D pbkdf-gcrypt.o diff --git a/crypto/secret_keyring.c b/crypto/secret_keyring.c new file mode 100644 index 0000000000..4f132d6370 --- /dev/null +++ b/crypto/secret_keyring.c @@ -0,0 +1,148 @@ +/* + * QEMU crypto secret support + * + * Copyright 2020 Yandex N.V. + * + * 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.1 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 "qemu/osdep.h" +#include +#include +#include "qapi/error.h" +#include "qom/object_interfaces.h" +#include "trace.h" +#include "crypto/secret_keyring.h" + + +static inline +long keyctl_read(int32_t key, uint8_t *buffer, size_t buflen) +{ + return syscall(__NR_keyctl, KEYCTL_READ, key, buffer, buflen, 0); +} + + +static void +qcrypto_secret_keyring_load_data(QCryptoSecretCommon *sec_common, + uint8_t **output, + size_t *outputlen, + Error **errp) +{ + QCryptoSecretKeyring *secret =3D QCRYPTO_SECRET_KEYRING(sec_common); + uint8_t *buffer =3D NULL; + long retcode; + + *output =3D NULL; + *outputlen =3D 0; + + if (!secret->serial) { + error_setg(errp, "'serial' parameter must be provided"); + return; + } + + retcode =3D keyctl_read(secret->serial, NULL, 0); + if (retcode <=3D 0) { + goto keyctl_error; + } + + buffer =3D g_new0(uint8_t, retcode); + + retcode =3D keyctl_read(secret->serial, buffer, retcode); + if (retcode < 0) { + g_free(buffer); + goto keyctl_error; + } + + *outputlen =3D retcode; + *output =3D buffer; + return; + +keyctl_error: + error_setg_errno(errp, errno, + "Unable to read serial key %08x", + secret->serial); +} + + +static void +qcrypto_secret_prop_set_key(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + QCryptoSecretKeyring *secret =3D QCRYPTO_SECRET_KEYRING(obj); + int32_t value; + visit_type_int32(v, name, &value, errp); + if (!value) { + error_setg(errp, "'serial' should not be equal to 0"); + } + secret->serial =3D value; +} + + +static void +qcrypto_secret_prop_get_key(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + QCryptoSecretKeyring *secret =3D QCRYPTO_SECRET_KEYRING(obj); + int32_t value =3D secret->serial; + visit_type_int32(v, name, &value, errp); +} + + +static void +qcrypto_secret_keyring_complete(UserCreatable *uc, Error **errp) +{ + object_property_set_bool(OBJECT(uc), true, "loaded", errp); +} + + +static void +qcrypto_secret_keyring_class_init(ObjectClass *oc, void *data) +{ + QCryptoSecretCommonClass *sic =3D QCRYPTO_SECRET_COMMON_CLASS(oc); + sic->load_data =3D qcrypto_secret_keyring_load_data; + + UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(oc); + ucc->complete =3D qcrypto_secret_keyring_complete; + + object_class_property_add(oc, "serial", "int32_t", + qcrypto_secret_prop_get_key, + qcrypto_secret_prop_set_key, + NULL, NULL); +} + + +static const TypeInfo qcrypto_secret_info =3D { + .parent =3D TYPE_QCRYPTO_SECRET_COMMON, + .name =3D TYPE_QCRYPTO_SECRET_KEYRING, + .instance_size =3D sizeof(QCryptoSecretKeyring), + .class_size =3D sizeof(QCryptoSecretKeyringClass), + .class_init =3D qcrypto_secret_keyring_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + + +static void +qcrypto_secret_register_types(void) +{ + type_register_static(&qcrypto_secret_info); +} + + +type_init(qcrypto_secret_register_types); diff --git a/include/crypto/secret_keyring.h b/include/crypto/secret_keyrin= g.h new file mode 100644 index 0000000000..9f371ad251 --- /dev/null +++ b/include/crypto/secret_keyring.h @@ -0,0 +1,52 @@ +/* + * QEMU crypto secret support + * + * Copyright 2020 Yandex N.V. + * + * 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.1 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_SECRET_KEYRING_H +#define QCRYPTO_SECRET_KEYRING_H + +#include "qapi/qapi-types-crypto.h" +#include "qom/object.h" +#include "crypto/secret_common.h" + +#define TYPE_QCRYPTO_SECRET_KEYRING "secret_keyring" +#define QCRYPTO_SECRET_KEYRING(obj) \ + OBJECT_CHECK(QCryptoSecretKeyring, (obj), \ + TYPE_QCRYPTO_SECRET_KEYRING) +#define QCRYPTO_SECRET_KEYRING_CLASS(class) \ + OBJECT_CLASS_CHECK(QCryptoSecretKeyringClass, \ + (class), TYPE_QCRYPTO_SECRET_KEYRING) +#define QCRYPTO_SECRET_KEYRING_GET_CLASS(class) \ + OBJECT_GET_CLASS(QCryptoSecretKeyringClass, \ + (class), TYPE_QCRYPTO_SECRET_KEYRING) + +typedef struct QCryptoSecretKeyring QCryptoSecretKeyring; +typedef struct QCryptoSecretKeyringClass QCryptoSecretKeyringClass; + +typedef struct QCryptoSecretKeyring { + QCryptoSecretCommon parent; + int32_t serial; +} QCryptoSecretKeyring; + + +typedef struct QCryptoSecretKeyringClass { + QCryptoSecretCommonClass parent; +} QCryptoSecretKeyringClass; + +#endif /* QCRYPTO_SECRET_KEYRING_H */ --=20 2.26.2 From nobody Thu May 16 06:20:40 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1592217688; cv=none; d=zohomail.com; s=zohoarc; b=HSm0zM2Okb4VhsQomttI24NKuKoK7adp5//dLRNkMFhyhSGOdhJ0zRpZ1NnoF1HV1hSXPaU9U22QGWKw8Fp1PEyfCI+ppwdhLhIsJGrimNk+ko9xQefAAbN+In6EQb84LH8k0nW53FKjUC1OQw8Po5J8+s/tHybnGO97+QVs+RQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592217688; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=wILdVeQQePVjwaoswacZyVPQPAG30iuleWLwrAprDyM=; b=UHI0qMMcpmDLqYDKdR297BEHBjIqzhYlPxxwlv0HwVqzdlYupAhetq8EYaPSsR1wPcU8ngj+YG+wVnitHzTn30KH/51FZMzWM7xK7lWgIPVs4IvYT7pmMJ1QS7Oe9/bN5B73JInbleQ0qEG+qwf+cReiD7kdUtAyaWxNVr22vw0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 159221768848971.98407744316148; Mon, 15 Jun 2020 03:41:28 -0700 (PDT) Received: from localhost ([::1]:40340 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jkmYR-0007W6-77 for importer@patchew.org; Mon, 15 Jun 2020 06:41:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52524) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkmU0-0000xz-8m for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:36:52 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:42157 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jkmTy-0007SS-4o for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:36:51 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-143-o-XHveDwMa-HcPuYlgeCsg-1; Mon, 15 Jun 2020 06:36:45 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 44001106B243; Mon, 15 Jun 2020 10:36:44 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 155135D9CC; Mon, 15 Jun 2020 10:36:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1592217409; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wILdVeQQePVjwaoswacZyVPQPAG30iuleWLwrAprDyM=; b=jUu8QqovjmfwgJi8z5zvBurlCnErpQE7V4ijhm9oPTZc41H2BcpZ1Z0fWzkTPyqvNpvE9Z 2QU/ZTIAVOOKXmD+77ZATcV5hB3wMgHenMDJHQBaOQd7yJ1aT7jlj7i0fweu6Y8/+9dzpg 0iW7l8vLt6HHBVATwJ9XLjpqCyhKPIw= X-MC-Unique: o-XHveDwMa-HcPuYlgeCsg-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PULL 4/5] test-crypto-secret: add 'secret_keyring' object tests. Date: Mon, 15 Jun 2020 11:36:32 +0100 Message-Id: <20200615103633.300208-5-berrange@redhat.com> In-Reply-To: <20200615103633.300208-1-berrange@redhat.com> References: <20200615103633.300208-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=207.211.31.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/15 01:17:36 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Krasikov , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) From: Alexey Krasikov Add tests: test_secret_keyring_good; test_secret_keyring_revoked_key; test_secret_keyring_expired_key; test_secret_keyring_bad_serial_key; test_secret_keyring_bad_key_access_right; Added tests require libkeyutils. The absence of this library is not critical, because these tests will be skipped in this case. Signed-off-by: Alexey Krasikov Signed-off-by: Daniel P. Berrang=C3=A9 --- configure | 24 ++++++ tests/Makefile.include | 4 + tests/test-crypto-secret.c | 158 +++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) diff --git a/configure b/configure index 3fbb61905a..07202acb9e 100755 --- a/configure +++ b/configure @@ -6330,6 +6330,27 @@ but not implemented on your system" fi fi =20 +########################################## +# check for usable keyutils.h + +if test "$linux" =3D "yes" ; then + + have_keyutils=3Dno + cat > $TMPC << EOF +#include +#include +#include +#include +#include +int main(void) { + return request_key("user", NULL, NULL, 0); +} +EOF + if compile_prog "" "-lkeyutils"; then + have_keyutils=3Dyes + fi +fi + =20 ########################################## # End of CC checks @@ -7702,6 +7723,9 @@ fi =20 if test "$secret_keyring" =3D "yes" ; then echo "CONFIG_SECRET_KEYRING=3Dy" >> $config_host_mak + if test "$have_keyutils" =3D "yes" ; then + echo "CONFIG_TEST_SECRET_KEYRING=3Dy" >> $config_host_mak + fi fi =20 if test "$tcg_interpreter" =3D "yes"; then diff --git a/tests/Makefile.include b/tests/Makefile.include index c2397de8ed..5607c7290d 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -540,6 +540,10 @@ tests/benchmark-crypto-cipher$(EXESUF): tests/benchmar= k-crypto-cipher.o $(test-c tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypt= o-obj-y) tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-= y) =20 +ifeq ($(CONFIG_TEST_SECRET_KEYRING),y) +tests/test-crypto-secret.o-libs :=3D -lkeyutils +endif + tests/crypto-tls-x509-helpers.o-cflags :=3D $(TASN1_CFLAGS) tests/crypto-tls-x509-helpers.o-libs :=3D $(TASN1_LIBS) tests/pkix_asn1_tab.o-cflags :=3D $(TASN1_CFLAGS) diff --git a/tests/test-crypto-secret.c b/tests/test-crypto-secret.c index 13fc6c4c75..603a093f10 100644 --- a/tests/test-crypto-secret.c +++ b/tests/test-crypto-secret.c @@ -24,6 +24,10 @@ #include "crypto/secret.h" #include "qapi/error.h" #include "qemu/module.h" +#ifdef CONFIG_TEST_SECRET_KEYRING +#include "crypto/secret_keyring.h" +#include +#endif =20 static void test_secret_direct(void) { @@ -124,6 +128,147 @@ static void test_secret_indirect_emptyfile(void) g_free(fname); } =20 +#ifdef CONFIG_TEST_SECRET_KEYRING + +#define DESCRIPTION "qemu_test_secret" +#define PAYLOAD "Test Payload" + + +static void test_secret_keyring_good(void) +{ + char key_str[16]; + Object *sec; + int32_t key =3D add_key("user", DESCRIPTION, PAYLOAD, + strlen(PAYLOAD), KEY_SPEC_PROCESS_KEYRING); + + g_assert(key >=3D 0); + + snprintf(key_str, sizeof(key_str), "0x%08x", key); + sec =3D object_new_with_props( + TYPE_QCRYPTO_SECRET_KEYRING, + object_get_objects_root(), + "sec0", + &error_abort, + "serial", key_str, + NULL); + + assert(0 <=3D keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING)); + char *pw =3D qcrypto_secret_lookup_as_utf8("sec0", + &error_abort); + g_assert_cmpstr(pw, =3D=3D, PAYLOAD); + + object_unparent(sec); + g_free(pw); +} + + +static void test_secret_keyring_revoked_key(void) +{ + char key_str[16]; + Object *sec; + int32_t key =3D add_key("user", DESCRIPTION, PAYLOAD, + strlen(PAYLOAD), KEY_SPEC_PROCESS_KEYRING); + g_assert(key >=3D 0); + g_assert_false(keyctl_revoke(key)); + + snprintf(key_str, sizeof(key_str), "0x%08x", key); + sec =3D object_new_with_props( + TYPE_QCRYPTO_SECRET_KEYRING, + object_get_objects_root(), + "sec0", + NULL, + "serial", key_str, + NULL); + + g_assert(errno =3D=3D EKEYREVOKED); + g_assert(sec =3D=3D NULL); + + keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING); +} + + +static void test_secret_keyring_expired_key(void) +{ + char key_str[16]; + Object *sec; + int32_t key =3D add_key("user", DESCRIPTION, PAYLOAD, + strlen(PAYLOAD), KEY_SPEC_PROCESS_KEYRING); + g_assert(key >=3D 0); + g_assert_false(keyctl_set_timeout(key, 1)); + sleep(1); + + snprintf(key_str, sizeof(key_str), "0x%08x", key); + sec =3D object_new_with_props( + TYPE_QCRYPTO_SECRET_KEYRING, + object_get_objects_root(), + "sec0", + NULL, + "serial", key_str, + NULL); + + g_assert(errno =3D=3D EKEYEXPIRED); + g_assert(sec =3D=3D NULL); + + keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING); +} + + +static void test_secret_keyring_bad_serial_key(void) +{ + Object *sec; + + sec =3D object_new_with_props( + TYPE_QCRYPTO_SECRET_KEYRING, + object_get_objects_root(), + "sec0", + NULL, + "serial", "1", + NULL); + + g_assert(errno =3D=3D ENOKEY); + g_assert(sec =3D=3D NULL); +} + +/* + * TODO + * test_secret_keyring_bad_key_access_right() is not working yet. + * We don't know yet if this due a bug in the Linux kernel or + * whether it's normal syscall behavior. + * We've requested information from kernel maintainers. + * See: + * Thread: 'security/keys: remove possessor verify after key permission ch= eck' + */ + +static void test_secret_keyring_bad_key_access_right(void) +{ + char key_str[16]; + Object *sec; + + g_test_skip("TODO: Need responce from Linux kernel maintainers"); + return; + + int32_t key =3D add_key("user", DESCRIPTION, PAYLOAD, + strlen(PAYLOAD), KEY_SPEC_PROCESS_KEYRING); + g_assert(key >=3D 0); + g_assert_false(keyctl_setperm(key, KEY_POS_ALL & (~KEY_POS_READ))); + + snprintf(key_str, sizeof(key_str), "0x%08x", key); + + sec =3D object_new_with_props( + TYPE_QCRYPTO_SECRET_KEYRING, + object_get_objects_root(), + "sec0", + NULL, + "serial", key_str, + NULL); + + g_assert(errno =3D=3D EACCES); + g_assert(sec =3D=3D NULL); + + keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING); +} + +#endif /* CONFIG_TEST_SECRET_KEYRING */ =20 static void test_secret_noconv_base64_good(void) { @@ -426,6 +571,19 @@ int main(int argc, char **argv) g_test_add_func("/crypto/secret/indirect/emptyfile", test_secret_indirect_emptyfile); =20 +#ifdef CONFIG_TEST_SECRET_KEYRING + g_test_add_func("/crypto/secret/keyring/good", + test_secret_keyring_good); + g_test_add_func("/crypto/secret/keyring/revoked_key", + test_secret_keyring_revoked_key); + g_test_add_func("/crypto/secret/keyring/expired_key", + test_secret_keyring_expired_key); + g_test_add_func("/crypto/secret/keyring/bad_serial_key", + test_secret_keyring_bad_serial_key); + g_test_add_func("/crypto/secret/keyring/bad_key_access_right", + test_secret_keyring_bad_key_access_right); +#endif /* CONFIG_TEST_SECRET_KEYRING */ + g_test_add_func("/crypto/secret/noconv/base64/good", test_secret_noconv_base64_good); g_test_add_func("/crypto/secret/noconv/base64/bad", --=20 2.26.2 From nobody Thu May 16 06:20:40 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1592217670; cv=none; d=zohomail.com; s=zohoarc; b=EgMAEFDXBj+RH5EV/GZAnuDvn6djPgi5f+0rUDKONe7qWzpWU6o27Oo8t3TtjyQyv4oUI7DC/Ol0tDVl7Bs/h3m4vzIJeJ8rXku6P+upCOxkyUS7YmA2FxjU/FTSS9D/KL/m6UzBRadcZ72ApCZlyCKuwY0dsyq92qqJOi6Jrt4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592217670; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=lDPcbbQN9/45I+316wizP19u8fb11YOlZCffXtV4MRg=; b=Qo6Bs2k9M+eWY9ijP7edr5IlMaV45hDMUDj37Z6V7yjea5/HNQKwRjb/A9P3OKEEe7/763zkWN2xbHgOr//Bn6tKsYta2QqbIG87W7H/vy5ykVcsvqdIiq+bpEO8zCA8H4SmBjOVW5DS7/FS7LHUra07QfNXKD5pug7Lt56tAcg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15922176701331006.7937427929181; Mon, 15 Jun 2020 03:41:10 -0700 (PDT) Received: from localhost ([::1]:39252 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jkmY8-00072v-E4 for importer@patchew.org; Mon, 15 Jun 2020 06:41:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52512) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkmTy-0000uR-Os for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:36:50 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:45533 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jkmTw-0007SI-TS for qemu-devel@nongnu.org; Mon, 15 Jun 2020 06:36:50 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-353-0c7d3AguP-e9_NppyrpyMg-1; Mon, 15 Jun 2020 06:36:46 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 85A0A1009441 for ; Mon, 15 Jun 2020 10:36:45 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 90A3D5D9CC; Mon, 15 Jun 2020 10:36:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1592217408; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lDPcbbQN9/45I+316wizP19u8fb11YOlZCffXtV4MRg=; b=I1T3rv+x34sOJwFGe+fjhuxj6olKjoMBfVLFFi4S1DCzgxSb0zxHXZhj5hPR1Y7ca8O8KO GpLn8NUB87wmgTcTEOrKbo5+6DNEo7vMeJA55GtjqQF3/jv5Gg8AwnU9tkA2bKvNNrpejT UYFJSuBDv+GvKLtHn8Tvp22PYZzJQ2M= X-MC-Unique: 0c7d3AguP-e9_NppyrpyMg-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: qemu-devel@nongnu.org Subject: [PULL 5/5] crypto: Remove use of GCRYPT_VERSION macro. Date: Mon, 15 Jun 2020 11:36:33 +0100 Message-Id: <20200615103633.300208-6-berrange@redhat.com> In-Reply-To: <20200615103633.300208-1-berrange@redhat.com> References: <20200615103633.300208-1-berrange@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=207.211.31.120; envelope-from=berrange@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/15 01:17:36 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , "Richard W.M. Jones" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @redhat.com) From: "Richard W.M. Jones" According to the gcrypt documentation it's intended that gcry_check_version() is called with the minimum version of gcrypt needed by the program, not the version from the header file that happened to be installed when qemu was compiled. Indeed the gcrypt.h header says that you shouldn't use the GCRYPT_VERSION macro. This causes the following failure: qemu-img: Unable to initialize gcrypt if a slightly older version of libgcrypt is installed with a newer qemu, even though the slightly older version works fine. This can happen with RPM packaging which uses symbol versioning to determine automatically which libgcrypt is required by qemu, which caused the following bug in RHEL 8: https://bugzilla.redhat.com/show_bug.cgi?id=3D1840485 qemu actually requires libgcrypt >=3D 1.5.0, so we might put the string "1.5.0" here. However since 1.5.0 was released in 2011, it hardly seems we need to check that. So I replaced GCRYPT_VERSION with NULL. Perhaps in future if we move to requiring a newer version of gcrypt we could put a literal string here. Signed-off-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrang=C3=A9 --- crypto/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/init.c b/crypto/init.c index b305381ec5..ea233b9192 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -122,7 +122,7 @@ int qcrypto_init(Error **errp) #endif =20 #ifdef CONFIG_GCRYPT - if (!gcry_check_version(GCRYPT_VERSION)) { + if (!gcry_check_version(NULL)) { error_setg(errp, "Unable to initialize gcrypt"); return -1; } --=20 2.26.2