## Coverage Report

#### Created: 2025-03-01 02:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /libfido2/src/hid.c

    Line
    Count
    Source
    1
    /*
    2
     * Copyright (c) 2018 Yubico AB. All rights reserved.
    3
     * Use of this source code is governed by a BSD-style
    4
     * license that can be found in the LICENSE file.
    5
     * SPDX-License-Identifier: BSD-2-Clause
    6
     */
    7
    8
    #include "fido.h"
    9
    10
    static int
    11
    get_key_len(uint8_t tag, uint8_t *key, size_t *key_len)
    12
    7.06M
    {
    13
    7.06M
            *key = tag & 0xfc;
    14
    7.06M
            if ((*key & 0xf0) == 0xf0) {
    15
    112k
                    fido_log_debug("%s: *key=0x%02x", __func__, *key);
    16
    112k
                    return (-1);
    17
    112k
            }
    18
    19
    6.95M
            *key_len = tag & 0x3;
    20
    6.95M
            if (*key_len == 3) {
    21
    327k
                    *key_len = 4;
    22
    327k
            }
    23
    24
    6.95M
            return (0);
    25
    7.06M
    }
    26
    27
    static int
    28
    get_key_val(const void *body, size_t key_len, uint32_t *val)
    29
    5.83M
    {
    30
    5.83M
            const uint8_t *ptr = body;
    31
    32
    5.83M
            switch (key_len) {
    33
    3.56M
            case 0:
    34
    3.56M
                    *val = 0;
    35
    3.56M
                    break;
    36
    797k
            case 1:
    37
    797k
                    *val = ptr[0];
    38
    797k
                    break;
    39
    1.44M
            case 2:
    40
    1.44M
                    *val = (uint32_t)((ptr[1] << 8) | ptr[0]);
    41
    1.44M
                    break;
    42
    29.6k
            default:
    43
    29.6k
                    fido_log_debug("%s: key_len=%zu", __func__, key_len);
    44
    29.6k
                    return (-1);
    45
    5.83M
            }
    46
    47
    5.80M
            return (0);
    48
    5.83M
    }
    49
    50
    int
    51
    fido_hid_get_usage(const uint8_t *report_ptr, size_t report_len,
    52
        uint32_t *usage_page)
    53
    2.48M
    {
    54
    2.48M
            const uint8_t   *ptr = report_ptr;
    55
    2.48M
            size_t           len = report_len;
    56
    57
    8.26M
            while (len > 0) {
    58
    7.05M
                    const uint8_t tag = ptr[0];
    59
    7.05M
                    ptr++;
    60
    7.05M
                    len--;
    61
    62
    7.05M
                    uint8_t  key;
    63
    7.05M
                    size_t   key_len;
    64
    7.05M
                    uint32_t key_val;
    65
    66
    7.05M
                    if (get_key_len(tag, &key, &key_len) < 0 || key_len > len ||
    67
    7.05M
                        get_key_val(ptr, key_len, &key_val) < 0) {
    68
    1.26M
                            return (-1);
    69
    1.26M
                    }
    70
    71
    5.78M
                    if (key == 0x4) {
    72
    476k
                            *usage_page = key_val;
    73
    476k
                    }
    74
    75
    5.78M
                    ptr += key_len;
    76
    5.78M
                    len -= key_len;
    77
    5.78M
            }
    78
    79
    1.21M
            return (0);
    80
    2.48M
    }
    81
    82
    int
    83
    fido_hid_get_report_len(const uint8_t *report_ptr, size_t report_len,
    84
        size_t *report_in_len, size_t *report_out_len)
    85
    6.02k
    {
    86
    6.02k
            const uint8_t   *ptr = report_ptr;
    87
    6.02k
            size_t           len = report_len;
    88
    6.02k
            uint32_t         report_size = 0;
    89
    90
    19.2k
            while (len > 0) {
    91
    16.4k
                    const uint8_t tag = ptr[0];
    92
    16.4k
                    ptr++;
    93
    16.4k
                    len--;
    94
    95
    16.4k
                    uint8_t  key;
    96
    16.4k
                    size_t   key_len;
    97
    16.4k
                    uint32_t key_val;
    98
    99
    16.4k
                    if (get_key_len(tag, &key, &key_len) < 0 || key_len > len ||
    100
    16.4k
                        get_key_val(ptr, key_len, &key_val) < 0) {
    101
    3.22k
                            return (-1);
    102
    3.22k
                    }
    103
    104
    13.2k
                    if (key == 0x94) {
    105
    1.31k
                            report_size = key_val;
    106
    11.9k
                    } else if (key == 0x80) {
    107
    1.04k
                            *report_in_len = (size_t)report_size;
    108
    10.8k
                    } else if (key == 0x90) {
    109
    979
                            *report_out_len = (size_t)report_size;
    110
    979
                    }
    111
    112
    13.2k
                    ptr += key_len;
    113
    13.2k
                    len -= key_len;
    114
    13.2k
            }
    115
    116
    2.79k
            return (0);
    117
    6.02k
    }
    118
    119
    fido_dev_info_t *
    120
    fido_dev_info_new(size_t n)
    121
    17.9k
    {
    122
    17.9k
            return (calloc(n, sizeof(fido_dev_info_t)));
    123
    17.9k
    }
    124
    125
    static void
    126
    fido_dev_info_reset(fido_dev_info_t *di)
    127
    409k
    {
    128
    409k
            free(di->path);
    129
    409k
            free(di->manufacturer);
    130
    409k
            free(di->product);
    131
    409k
            memset(di, 0, sizeof(*di));
    132
    409k
    }
    133
    134
    void
    135
    fido_dev_info_free(fido_dev_info_t **devlist_p, size_t n)
    136
    17.9k
    {
    137
    17.9k
            fido_dev_info_t *devlist;
    138
    139
    17.9k
            if (devlist_p == NULL || (devlist = *devlist_p) == NULL)
    140
    97
                    return;
    141
    142
    418k
            for (size_t i = 0; i < n; i++)
    143
    400k
                    fido_dev_info_reset(&devlist[i]);
    144
    145
    17.8k
            free(devlist);
    146
    147
    17.8k
            *devlist_p = NULL;
    148
    17.8k
    }
    149
    150
    const fido_dev_info_t *
    151
    fido_dev_info_ptr(const fido_dev_info_t *devlist, size_t i)
    152
    9.61k
    {
    153
    9.61k
            return (&devlist[i]);
    154
    9.61k
    }
    155
    156
    int
    157
    fido_dev_info_set(fido_dev_info_t *devlist, size_t i,
    158
        const char *path, const char *manufacturer, const char *product,
    159
        const fido_dev_io_t *io, const fido_dev_transport_t *transport)
    160
    8.64k
    {
    161
    8.64k
            char *path_copy = NULL, *manu_copy = NULL, *prod_copy = NULL;
    162
    8.64k
            int r;
    163
    164
    8.64k
            if (path == NULL || manufacturer == NULL || product == NULL ||
    165
    8.64k
                io == NULL) {
    166
    0
                    r = FIDO_ERR_INVALID_ARGUMENT;
    167
    0
                    goto out;
    168
    0
            }
    169
    170
    8.64k
            if ((path_copy = strdup(path)) == NULL ||
    171
    8.64k
                (manu_copy = strdup(manufacturer)) == NULL ||
    172
    8.64k
                (prod_copy = strdup(product)) == NULL) {
    173
    200
                    r = FIDO_ERR_INTERNAL;
    174
    200
                    goto out;
    175
    200
            }
    176
    177
    8.44k
            fido_dev_info_reset(&devlist[i]);
    178
    8.44k
            devlist[i].path = path_copy;
    179
    8.44k
            devlist[i].manufacturer = manu_copy;
    180
    8.44k
            devlist[i].product = prod_copy;
    181
    8.44k
            devlist[i].io = *io;
    182
    8.44k
            if (transport)
    183
    8.44k
                    devlist[i].transport = *transport;
    184
    8.44k
            r = FIDO_OK;
    185
    8.64k
    out:
    186
    8.64k
            if (r != FIDO_OK) {
    187
    200
                    free(prod_copy);
    188
    200
                    free(manu_copy);
    189
    200
                    free(path_copy);
    190
    200
            }
    191
    8.64k
            return (r);
    192
    8.44k
    }
    193
    194
    const char *
    195
    fido_dev_info_path(const fido_dev_info_t *di)
    196
    18.2k
    {
    197
    18.2k
            return (di->path);
    198
    18.2k
    }
    199
    200
    int16_t
    201
    fido_dev_info_vendor(const fido_dev_info_t *di)
    202
    9.61k
    {
    203
    9.61k
            return (di->vendor_id);
    204
    9.61k
    }
    205
    206
    int16_t
    207
    fido_dev_info_product(const fido_dev_info_t *di)
    208
    9.61k
    {
    209
    9.61k
            return (di->product_id);
    210
    9.61k
    }
    211
    212
    const char *
    213
    fido_dev_info_manufacturer_string(const fido_dev_info_t *di)
    214
    18.2k
    {
    215
    18.2k
            return (di->manufacturer);
    216
    18.2k
    }
    217
    218
    const char *
    219
    fido_dev_info_product_string(const fido_dev_info_t *di)
    220
    18.2k
    {
    221
    18.2k
            return (di->product);
    222
    18.2k
    }