cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

tls-cipher-suites.c (3925B)


      1/*
      2 * QEMU TLS Cipher Suites
      3 *
      4 * Copyright (c) 2018-2020 Red Hat, Inc.
      5 *
      6 * Author: Philippe Mathieu-Daudé <philmd@redhat.com>
      7 *
      8 * SPDX-License-Identifier: GPL-2.0-or-later
      9 */
     10
     11#include "qemu/osdep.h"
     12#include "qapi/error.h"
     13#include "qom/object_interfaces.h"
     14#include "crypto/tlscreds.h"
     15#include "crypto/tls-cipher-suites.h"
     16#include "hw/nvram/fw_cfg.h"
     17#include "tlscredspriv.h"
     18#include "trace.h"
     19
     20struct QCryptoTLSCipherSuites {
     21    /* <private> */
     22    QCryptoTLSCreds parent_obj;
     23    /* <public> */
     24};
     25
     26/*
     27 * IANA registered TLS ciphers:
     28 * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
     29 */
     30typedef struct {
     31    uint8_t data[2];
     32} QEMU_PACKED IANA_TLS_CIPHER;
     33
     34GByteArray *qcrypto_tls_cipher_suites_get_data(QCryptoTLSCipherSuites *obj,
     35                                               Error **errp)
     36{
     37    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
     38    gnutls_priority_t pcache;
     39    GByteArray *byte_array;
     40    const char *err;
     41    size_t i;
     42    int ret;
     43
     44    trace_qcrypto_tls_cipher_suite_priority(creds->priority);
     45    ret = gnutls_priority_init(&pcache, creds->priority, &err);
     46    if (ret < 0) {
     47        error_setg(errp, "Syntax error using priority '%s': %s",
     48                   creds->priority, gnutls_strerror(ret));
     49        return NULL;
     50    }
     51
     52    byte_array = g_byte_array_new();
     53
     54    for (i = 0;; i++) {
     55        int ret;
     56        unsigned idx;
     57        const char *name;
     58        IANA_TLS_CIPHER cipher;
     59        gnutls_protocol_t protocol;
     60        const char *version;
     61
     62        ret = gnutls_priority_get_cipher_suite_index(pcache, i, &idx);
     63        if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     64            break;
     65        }
     66        if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) {
     67            continue;
     68        }
     69
     70        name = gnutls_cipher_suite_info(idx, (unsigned char *)&cipher,
     71                                        NULL, NULL, NULL, &protocol);
     72        if (name == NULL) {
     73            continue;
     74        }
     75
     76        version = gnutls_protocol_get_name(protocol);
     77        g_byte_array_append(byte_array, cipher.data, 2);
     78        trace_qcrypto_tls_cipher_suite_info(cipher.data[0],
     79                                            cipher.data[1],
     80                                            version, name);
     81    }
     82    trace_qcrypto_tls_cipher_suite_count(byte_array->len);
     83    gnutls_priority_deinit(pcache);
     84
     85    return byte_array;
     86}
     87
     88static void qcrypto_tls_cipher_suites_complete(UserCreatable *uc,
     89                                               Error **errp)
     90{
     91    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(uc);
     92
     93    if (!creds->priority) {
     94        error_setg(errp, "'priority' property is not set");
     95        return;
     96    }
     97}
     98
     99static GByteArray *qcrypto_tls_cipher_suites_fw_cfg_gen_data(Object *obj,
    100                                                             Error **errp)
    101{
    102    return qcrypto_tls_cipher_suites_get_data(QCRYPTO_TLS_CIPHER_SUITES(obj),
    103                                              errp);
    104}
    105
    106static void qcrypto_tls_cipher_suites_class_init(ObjectClass *oc, void *data)
    107{
    108    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    109    FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(oc);
    110
    111    ucc->complete = qcrypto_tls_cipher_suites_complete;
    112    fwgc->get_data = qcrypto_tls_cipher_suites_fw_cfg_gen_data;
    113}
    114
    115static const TypeInfo qcrypto_tls_cipher_suites_info = {
    116    .parent = TYPE_QCRYPTO_TLS_CREDS,
    117    .name = TYPE_QCRYPTO_TLS_CIPHER_SUITES,
    118    .instance_size = sizeof(QCryptoTLSCipherSuites),
    119    .class_size = sizeof(QCryptoTLSCredsClass),
    120    .class_init = qcrypto_tls_cipher_suites_class_init,
    121    .interfaces = (InterfaceInfo[]) {
    122        { TYPE_USER_CREATABLE },
    123        { TYPE_FW_CFG_DATA_GENERATOR_INTERFACE },
    124        { }
    125    }
    126};
    127
    128static void qcrypto_tls_cipher_suites_register_types(void)
    129{
    130    type_register_static(&qcrypto_tls_cipher_suites_info);
    131}
    132
    133type_init(qcrypto_tls_cipher_suites_register_types);