diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2020-07-09 20:01:43 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2020-07-09 20:01:43 +0100 |
| commit | aecdfcc3f8499b34a90e5b21159b4d245bc833c2 (patch) | |
| tree | c248c244f80abd1c03176094442741b835a6ab38 /crypto/tls-cipher-suites.c | |
| parent | aff2caf6b3fbab1062e117a47b66d27f7fd2f272 (diff) | |
| parent | 69699f3055a59e24f1153c329ae6eff4b9a343e0 (diff) | |
| download | focaccia-qemu-aecdfcc3f8499b34a90e5b21159b4d245bc833c2.tar.gz focaccia-qemu-aecdfcc3f8499b34a90e5b21159b4d245bc833c2.zip | |
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/fw_cfg-20200704' into staging
firmware (and crypto) patches - add the tls-cipher-suites object, - add the ability to QOM objects to produce data consumable by the fw_cfg device, - let the tls-cipher-suites object implement the FW_CFG_DATA_GENERATOR interface. This is required by EDK2 'HTTPS Boot' feature of OVMF to tell the guest which TLS ciphers it can use. CI jobs results: https://travis-ci.org/github/philmd/qemu/builds/704724619 https://gitlab.com/philmd/qemu/-/pipelines/162938106 https://cirrus-ci.com/build/4682977303068672 # gpg: Signature made Sat 04 Jul 2020 17:37:08 BST # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * remotes/philmd-gitlab/tags/fw_cfg-20200704: crypto/tls-cipher-suites: Produce fw_cfg consumable blob softmmu/vl: Allow -fw_cfg 'gen_id' option to use the 'etc/' namespace softmmu/vl: Let -fw_cfg option take a 'gen_id' argument hw/nvram/fw_cfg: Add the FW_CFG_DATA_GENERATOR interface crypto: Add tls-cipher-suites object Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'crypto/tls-cipher-suites.c')
| -rw-r--r-- | crypto/tls-cipher-suites.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/crypto/tls-cipher-suites.c b/crypto/tls-cipher-suites.c new file mode 100644 index 0000000000..0d305b684b --- /dev/null +++ b/crypto/tls-cipher-suites.c @@ -0,0 +1,126 @@ +/* + * QEMU TLS Cipher Suites + * + * Copyright (c) 2018-2020 Red Hat, Inc. + * + * Author: Philippe Mathieu-Daudé <philmd@redhat.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qom/object_interfaces.h" +#include "crypto/tlscreds.h" +#include "crypto/tls-cipher-suites.h" +#include "hw/nvram/fw_cfg.h" +#include "trace.h" + +/* + * IANA registered TLS ciphers: + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4 + */ +typedef struct { + uint8_t data[2]; +} QEMU_PACKED IANA_TLS_CIPHER; + +GByteArray *qcrypto_tls_cipher_suites_get_data(QCryptoTLSCipherSuites *obj, + Error **errp) +{ + QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); + gnutls_priority_t pcache; + GByteArray *byte_array; + const char *err; + size_t i; + int ret; + + trace_qcrypto_tls_cipher_suite_priority(creds->priority); + ret = gnutls_priority_init(&pcache, creds->priority, &err); + if (ret < 0) { + error_setg(errp, "Syntax error using priority '%s': %s", + creds->priority, gnutls_strerror(ret)); + return NULL; + } + + byte_array = g_byte_array_new(); + + for (i = 0;; i++) { + int ret; + unsigned idx; + const char *name; + IANA_TLS_CIPHER cipher; + gnutls_protocol_t protocol; + const char *version; + + ret = gnutls_priority_get_cipher_suite_index(pcache, i, &idx); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { + break; + } + if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) { + continue; + } + + name = gnutls_cipher_suite_info(idx, (unsigned char *)&cipher, + NULL, NULL, NULL, &protocol); + if (name == NULL) { + continue; + } + + version = gnutls_protocol_get_name(protocol); + g_byte_array_append(byte_array, cipher.data, 2); + trace_qcrypto_tls_cipher_suite_info(cipher.data[0], + cipher.data[1], + version, name); + } + trace_qcrypto_tls_cipher_suite_count(byte_array->len); + gnutls_priority_deinit(pcache); + + return byte_array; +} + +static void qcrypto_tls_cipher_suites_complete(UserCreatable *uc, + Error **errp) +{ + QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(uc); + + if (!creds->priority) { + error_setg(errp, "'priority' property is not set"); + return; + } +} + +static GByteArray *qcrypto_tls_cipher_suites_fw_cfg_gen_data(Object *obj, + Error **errp) +{ + return qcrypto_tls_cipher_suites_get_data(QCRYPTO_TLS_CIPHER_SUITES(obj), + errp); +} + +static void qcrypto_tls_cipher_suites_class_init(ObjectClass *oc, void *data) +{ + UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); + FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(oc); + + ucc->complete = qcrypto_tls_cipher_suites_complete; + fwgc->get_data = qcrypto_tls_cipher_suites_fw_cfg_gen_data; +} + +static const TypeInfo qcrypto_tls_cipher_suites_info = { + .parent = TYPE_QCRYPTO_TLS_CREDS, + .name = TYPE_QCRYPTO_TLS_CIPHER_SUITES, + .instance_size = sizeof(QCryptoTLSCreds), + .class_size = sizeof(QCryptoTLSCredsClass), + .class_init = qcrypto_tls_cipher_suites_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { TYPE_FW_CFG_DATA_GENERATOR_INTERFACE }, + { } + } +}; + +static void qcrypto_tls_cipher_suites_register_types(void) +{ + type_register_static(&qcrypto_tls_cipher_suites_info); +} + +type_init(qcrypto_tls_cipher_suites_register_types); |