| /* | |
| * 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 <http://www.gnu.org/licenses/>. | |
| * | |
| */ | |
| #ifndef QCRYPTO_SECRET_H | |
| #define QCRYPTO_SECRET_H | |
| #include "qapi/qapi-types-crypto.h" | |
| #include "qom/object.h" | |
| #include "crypto/secret_common.h" | |
| #define TYPE_QCRYPTO_SECRET "secret" | |
| typedef struct QCryptoSecret QCryptoSecret; | |
| DECLARE_INSTANCE_CHECKER(QCryptoSecret, QCRYPTO_SECRET, | |
| TYPE_QCRYPTO_SECRET) | |
| typedef struct QCryptoSecretClass QCryptoSecretClass; | |
| /** | |
| * QCryptoSecret: | |
| * | |
| * The QCryptoSecret object provides storage of secrets, | |
| * which may be user passwords, encryption keys or any | |
| * other kind of sensitive data that is represented as | |
| * a sequence of bytes. | |
| * | |
| * The sensitive data associated with the secret can | |
| * be provided directly via the 'data' property, or | |
| * indirectly via the 'file' property. In the latter | |
| * case there is support for file descriptor passing | |
| * via the usual /dev/fdset/NN syntax that QEMU uses. | |
| * | |
| * The data for a secret can be provided in two formats, | |
| * either as a UTF-8 string (the default), or as base64 | |
| * encoded 8-bit binary data. The latter is appropriate | |
| * for raw encryption keys, while the former is appropriate | |
| * for user entered passwords. | |
| * | |
| * The data may be optionally encrypted with AES-256-CBC, | |
| * and the decryption key provided by another | |
| * QCryptoSecret instance identified by the 'keyid' | |
| * property. When passing sensitive data directly | |
| * via the 'data' property it is strongly recommended | |
| * to use the AES encryption facility to prevent the | |
| * sensitive data being exposed in the process listing | |
| * or system log files. | |
| * | |
| * Providing data directly, insecurely (suitable for | |
| * ad hoc developer testing only) | |
| * | |
| * $QEMU -object secret,id=sec0,data=letmein | |
| * | |
| * Providing data indirectly: | |
| * | |
| * # printf "letmein" > password.txt | |
| * # $QEMU \ | |
| * -object secret,id=sec0,file=password.txt | |
| * | |
| * Using a master encryption key with data. | |
| * | |
| * The master key needs to be created as 32 secure | |
| * random bytes (optionally base64 encoded) | |
| * | |
| * # openssl rand -base64 32 > key.b64 | |
| * # KEY=$(base64 -d key.b64 | hexdump -v -e '/1 "%02X"') | |
| * | |
| * Each secret to be encrypted needs to have a random | |
| * initialization vector generated. These do not need | |
| * to be kept secret | |
| * | |
| * # openssl rand -base64 16 > iv.b64 | |
| * # IV=$(base64 -d iv.b64 | hexdump -v -e '/1 "%02X"') | |
| * | |
| * A secret to be defined can now be encrypted | |
| * | |
| * # SECRET=$(printf "letmein" | | |
| * openssl enc -aes-256-cbc -a -K $KEY -iv $IV) | |
| * | |
| * When launching QEMU, create a master secret pointing | |
| * to key.b64 and specify that to be used to decrypt | |
| * the user password | |
| * | |
| * # $QEMU \ | |
| * -object secret,id=secmaster0,format=base64,file=key.b64 \ | |
| * -object secret,id=sec0,keyid=secmaster0,format=base64,\ | |
| * data=$SECRET,iv=$(<iv.b64) | |
| * | |
| * When encrypting, the data can still be provided via an | |
| * external file, in which case it is possible to use either | |
| * raw binary data, or base64 encoded. This example uses | |
| * raw format | |
| * | |
| * # printf "letmein" | | |
| * openssl enc -aes-256-cbc -K $KEY -iv $IV -o pw.aes | |
| * # $QEMU \ | |
| * -object secret,id=secmaster0,format=base64,file=key.b64 \ | |
| * -object secret,id=sec0,keyid=secmaster0,\ | |
| * file=pw.aes,iv=$(<iv.b64) | |
| * | |
| * Note that the ciphertext can be in either raw or base64 | |
| * format, as indicated by the 'format' parameter, but the | |
| * plaintext resulting from decryption is expected to always | |
| * be in raw format. | |
| */ | |
| struct QCryptoSecret { | |
| QCryptoSecretCommon parent_obj; | |
| char *data; | |
| char *file; | |
| }; | |
| struct QCryptoSecretClass { | |
| QCryptoSecretCommonClass parent_class; | |
| }; | |
| #endif /* QCRYPTO_SECRET_H */ |