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