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