1 /* 2 * QEMU crypto secret support 3 * 4 * Copyright (c) 2015 Red Hat, Inc. 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 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_H 22 #define QCRYPTO_SECRET_H 23 24 #include "qom/object.h" 25 26 #define TYPE_QCRYPTO_SECRET "secret" 27 #define QCRYPTO_SECRET(obj) \ 28 OBJECT_CHECK(QCryptoSecret, (obj), TYPE_QCRYPTO_SECRET) 29 30 typedef struct QCryptoSecret QCryptoSecret; 31 typedef struct QCryptoSecretClass QCryptoSecretClass; 32 33 /** 34 * QCryptoSecret: 35 * 36 * The QCryptoSecret object provides storage of secrets, 37 * which may be user passwords, encryption keys or any 38 * other kind of sensitive data that is represented as 39 * a sequence of bytes. 40 * 41 * The sensitive data associated with the secret can 42 * be provided directly via the 'data' property, or 43 * indirectly via the 'file' property. In the latter 44 * case there is support for file descriptor passing 45 * via the usual /dev/fdset/NN syntax that QEMU uses. 46 * 47 * The data for a secret can be provided in two formats, 48 * either as a UTF-8 string (the default), or as base64 49 * encoded 8-bit binary data. The latter is appropriate 50 * for raw encryption keys, while the former is appropriate 51 * for user entered passwords. 52 * 53 * The data may be optionally encrypted with AES-256-CBC, 54 * and the decryption key provided by another 55 * QCryptoSecret instance identified by the 'keyid' 56 * property. When passing sensitive data directly 57 * via the 'data' property it is strongly recommended 58 * to use the AES encryption facility to prevent the 59 * sensitive data being exposed in the process listing 60 * or system log files. 61 * 62 * Providing data directly, insecurely (suitable for 63 * ad hoc developer testing only) 64 * 65 * $QEMU -object secret,id=sec0,data=letmein 66 * 67 * Providing data indirectly: 68 * 69 * # printf "letmein" > password.txt 70 * # $QEMU \ 71 * -object secret,id=sec0,file=password.txt 72 * 73 * Using a master encryption key with data. 74 * 75 * The master key needs to be created as 32 secure 76 * random bytes (optionally base64 encoded) 77 * 78 * # openssl rand -base64 32 > key.b64 79 * # KEY=$(base64 -d key.b64 | hexdump -v -e '/1 "%02X"') 80 * 81 * Each secret to be encrypted needs to have a random 82 * initialization vector generated. These do not need 83 * to be kept secret 84 * 85 * # openssl rand -base64 16 > iv.b64 86 * # IV=$(base64 -d iv.b64 | hexdump -v -e '/1 "%02X"') 87 * 88 * A secret to be defined can now be encrypted 89 * 90 * # SECRET=$(printf "letmein" | 91 * openssl enc -aes-256-cbc -a -K $KEY -iv $IV) 92 * 93 * When launching QEMU, create a master secret pointing 94 * to key.b64 and specify that to be used to decrypt 95 * the user password 96 * 97 * # $QEMU \ 98 * -object secret,id=secmaster0,format=base64,file=key.b64 \ 99 * -object secret,id=sec0,keyid=secmaster0,format=base64,\ 100 * data=$SECRET,iv=$(<iv.b64) 101 * 102 * When encrypting, the data can still be provided via an 103 * external file, in which case it is possible to use either 104 * raw binary data, or base64 encoded. This example uses 105 * raw format 106 * 107 * # printf "letmein" | 108 * openssl enc -aes-256-cbc -K $KEY -iv $IV -o pw.aes 109 * # $QEMU \ 110 * -object secret,id=secmaster0,format=base64,file=key.b64 \ 111 * -object secret,id=sec0,keyid=secmaster0,\ 112 * file=pw.aes,iv=$(<iv.b64) 113 * 114 * Note that the ciphertext can be in either raw or base64 115 * format, as indicated by the 'format' parameter, but the 116 * plaintext resulting from decryption is expected to always 117 * be in raw format. 118 */ 119 120 struct QCryptoSecret { 121 Object parent_obj; 122 uint8_t *rawdata; 123 size_t rawlen; 124 QCryptoSecretFormat format; 125 char *data; 126 char *file; 127 char *keyid; 128 char *iv; 129 }; 130 131 132 struct QCryptoSecretClass { 133 ObjectClass parent_class; 134 }; 135 136 137 extern int qcrypto_secret_lookup(const char *secretid, 138 uint8_t **data, 139 size_t *datalen, 140 Error **errp); 141 extern char *qcrypto_secret_lookup_as_utf8(const char *secretid, 142 Error **errp); 143 extern char *qcrypto_secret_lookup_as_base64(const char *secretid, 144 Error **errp); 145 146 #endif /* QCRYPTO_SECRET_H */ 147