qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

crypto/linux_keyring: add 'secret_keyring' secret object.

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 <alex-krasikov@yandex-team.ru>

- Fixed up detection logic default behaviour in configure

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>

authored by

Alexey Krasikov and committed by
Daniel P. Berrangé
54e7aac0 4862bd3c

+246
+45
configure
··· 510 510 plugins="no" 511 511 fuzzing="no" 512 512 rng_none="no" 513 + secret_keyring="" 513 514 514 515 supported_cpu="no" 515 516 supported_os="no" ··· 1605 1606 --enable-rng-none) rng_none=yes 1606 1607 ;; 1607 1608 --disable-rng-none) rng_none=no 1609 + ;; 1610 + --enable-keyring) secret_keyring="yes" 1611 + ;; 1612 + --disable-keyring) secret_keyring="no" 1608 1613 ;; 1609 1614 *) 1610 1615 echo "ERROR: unknown option $opt" ··· 6290 6295 ;; 6291 6296 esac 6292 6297 6298 + ########################################## 6299 + # check for usable __NR_keyctl syscall 6300 + 6301 + if test "$linux" = "yes" ; then 6302 + 6303 + have_keyring=no 6304 + cat > $TMPC << EOF 6305 + #include <errno.h> 6306 + #include <asm/unistd.h> 6307 + #include <linux/keyctl.h> 6308 + #include <unistd.h> 6309 + int main(void) { 6310 + return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); 6311 + } 6312 + EOF 6313 + if compile_prog "" "" ; then 6314 + have_keyring=yes 6315 + fi 6316 + fi 6317 + if test "$secret_keyring" != "no" 6318 + then 6319 + if test "$have_keyring" == "yes" 6320 + then 6321 + secret_keyring=yes 6322 + else 6323 + if test "$secret_keyring" = "yes" 6324 + then 6325 + error_exit "syscall __NR_keyctl requested, \ 6326 + but not implemented on your system" 6327 + else 6328 + secret_keyring=no 6329 + fi 6330 + fi 6331 + fi 6332 + 6293 6333 6294 6334 ########################################## 6295 6335 # End of CC checks ··· 6774 6814 echo "fuzzing support $fuzzing" 6775 6815 echo "gdb $gdb_bin" 6776 6816 echo "rng-none $rng_none" 6817 + echo "Linux keyring $secret_keyring" 6777 6818 6778 6819 if test "$supported_cpu" = "no"; then 6779 6820 echo ··· 7657 7698 7658 7699 if test -n "$gdb_bin" ; then 7659 7700 echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak 7701 + fi 7702 + 7703 + if test "$secret_keyring" = "yes" ; then 7704 + echo "CONFIG_SECRET_KEYRING=y" >> $config_host_mak 7660 7705 fi 7661 7706 7662 7707 if test "$tcg_interpreter" = "yes"; then
+1
crypto/Makefile.objs
··· 20 20 crypto-obj-y += tlssession.o 21 21 crypto-obj-y += secret_common.o 22 22 crypto-obj-y += secret.o 23 + crypto-obj-$(CONFIG_SECRET_KEYRING) += secret_keyring.o 23 24 crypto-obj-y += pbkdf.o 24 25 crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o 25 26 crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += pbkdf-gcrypt.o
+148
crypto/secret_keyring.c
··· 1 + /* 2 + * QEMU crypto secret support 3 + * 4 + * Copyright 2020 Yandex N.V. 5 + * 6 + * This library is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU Lesser General Public 8 + * License as published by the Free Software Foundation; either 9 + * version 2.1 of the License, or (at your option) any later version. 10 + * 11 + * This library is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * Lesser General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU Lesser General Public 17 + * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 + * 19 + */ 20 + 21 + #include "qemu/osdep.h" 22 + #include <asm/unistd.h> 23 + #include <linux/keyctl.h> 24 + #include "qapi/error.h" 25 + #include "qom/object_interfaces.h" 26 + #include "trace.h" 27 + #include "crypto/secret_keyring.h" 28 + 29 + 30 + static inline 31 + long keyctl_read(int32_t key, uint8_t *buffer, size_t buflen) 32 + { 33 + return syscall(__NR_keyctl, KEYCTL_READ, key, buffer, buflen, 0); 34 + } 35 + 36 + 37 + static void 38 + qcrypto_secret_keyring_load_data(QCryptoSecretCommon *sec_common, 39 + uint8_t **output, 40 + size_t *outputlen, 41 + Error **errp) 42 + { 43 + QCryptoSecretKeyring *secret = QCRYPTO_SECRET_KEYRING(sec_common); 44 + uint8_t *buffer = NULL; 45 + long retcode; 46 + 47 + *output = NULL; 48 + *outputlen = 0; 49 + 50 + if (!secret->serial) { 51 + error_setg(errp, "'serial' parameter must be provided"); 52 + return; 53 + } 54 + 55 + retcode = keyctl_read(secret->serial, NULL, 0); 56 + if (retcode <= 0) { 57 + goto keyctl_error; 58 + } 59 + 60 + buffer = g_new0(uint8_t, retcode); 61 + 62 + retcode = keyctl_read(secret->serial, buffer, retcode); 63 + if (retcode < 0) { 64 + g_free(buffer); 65 + goto keyctl_error; 66 + } 67 + 68 + *outputlen = retcode; 69 + *output = buffer; 70 + return; 71 + 72 + keyctl_error: 73 + error_setg_errno(errp, errno, 74 + "Unable to read serial key %08x", 75 + secret->serial); 76 + } 77 + 78 + 79 + static void 80 + qcrypto_secret_prop_set_key(Object *obj, Visitor *v, 81 + const char *name, void *opaque, 82 + Error **errp) 83 + { 84 + QCryptoSecretKeyring *secret = QCRYPTO_SECRET_KEYRING(obj); 85 + int32_t value; 86 + visit_type_int32(v, name, &value, errp); 87 + if (!value) { 88 + error_setg(errp, "'serial' should not be equal to 0"); 89 + } 90 + secret->serial = value; 91 + } 92 + 93 + 94 + static void 95 + qcrypto_secret_prop_get_key(Object *obj, Visitor *v, 96 + const char *name, void *opaque, 97 + Error **errp) 98 + { 99 + QCryptoSecretKeyring *secret = QCRYPTO_SECRET_KEYRING(obj); 100 + int32_t value = secret->serial; 101 + visit_type_int32(v, name, &value, errp); 102 + } 103 + 104 + 105 + static void 106 + qcrypto_secret_keyring_complete(UserCreatable *uc, Error **errp) 107 + { 108 + object_property_set_bool(OBJECT(uc), true, "loaded", errp); 109 + } 110 + 111 + 112 + static void 113 + qcrypto_secret_keyring_class_init(ObjectClass *oc, void *data) 114 + { 115 + QCryptoSecretCommonClass *sic = QCRYPTO_SECRET_COMMON_CLASS(oc); 116 + sic->load_data = qcrypto_secret_keyring_load_data; 117 + 118 + UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); 119 + ucc->complete = qcrypto_secret_keyring_complete; 120 + 121 + object_class_property_add(oc, "serial", "int32_t", 122 + qcrypto_secret_prop_get_key, 123 + qcrypto_secret_prop_set_key, 124 + NULL, NULL); 125 + } 126 + 127 + 128 + static const TypeInfo qcrypto_secret_info = { 129 + .parent = TYPE_QCRYPTO_SECRET_COMMON, 130 + .name = TYPE_QCRYPTO_SECRET_KEYRING, 131 + .instance_size = sizeof(QCryptoSecretKeyring), 132 + .class_size = sizeof(QCryptoSecretKeyringClass), 133 + .class_init = qcrypto_secret_keyring_class_init, 134 + .interfaces = (InterfaceInfo[]) { 135 + { TYPE_USER_CREATABLE }, 136 + { } 137 + } 138 + }; 139 + 140 + 141 + static void 142 + qcrypto_secret_register_types(void) 143 + { 144 + type_register_static(&qcrypto_secret_info); 145 + } 146 + 147 + 148 + type_init(qcrypto_secret_register_types);
+52
include/crypto/secret_keyring.h
··· 1 + /* 2 + * QEMU crypto secret support 3 + * 4 + * Copyright 2020 Yandex N.V. 5 + * 6 + * This library is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU Lesser General Public 8 + * License as published by the Free Software Foundation; either 9 + * version 2.1 of the License, or (at your option) any later version. 10 + * 11 + * This library is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * Lesser General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU Lesser General Public 17 + * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 + * 19 + */ 20 + 21 + #ifndef QCRYPTO_SECRET_KEYRING_H 22 + #define QCRYPTO_SECRET_KEYRING_H 23 + 24 + #include "qapi/qapi-types-crypto.h" 25 + #include "qom/object.h" 26 + #include "crypto/secret_common.h" 27 + 28 + #define TYPE_QCRYPTO_SECRET_KEYRING "secret_keyring" 29 + #define QCRYPTO_SECRET_KEYRING(obj) \ 30 + OBJECT_CHECK(QCryptoSecretKeyring, (obj), \ 31 + TYPE_QCRYPTO_SECRET_KEYRING) 32 + #define QCRYPTO_SECRET_KEYRING_CLASS(class) \ 33 + OBJECT_CLASS_CHECK(QCryptoSecretKeyringClass, \ 34 + (class), TYPE_QCRYPTO_SECRET_KEYRING) 35 + #define QCRYPTO_SECRET_KEYRING_GET_CLASS(class) \ 36 + OBJECT_GET_CLASS(QCryptoSecretKeyringClass, \ 37 + (class), TYPE_QCRYPTO_SECRET_KEYRING) 38 + 39 + typedef struct QCryptoSecretKeyring QCryptoSecretKeyring; 40 + typedef struct QCryptoSecretKeyringClass QCryptoSecretKeyringClass; 41 + 42 + typedef struct QCryptoSecretKeyring { 43 + QCryptoSecretCommon parent; 44 + int32_t serial; 45 + } QCryptoSecretKeyring; 46 + 47 + 48 + typedef struct QCryptoSecretKeyringClass { 49 + QCryptoSecretCommonClass parent; 50 + } QCryptoSecretKeyringClass; 51 + 52 + #endif /* QCRYPTO_SECRET_KEYRING_H */