Coverage Report

Created: 2021-07-20 18:14

/libfido2/src/hid.c
Line
Count
Source (jump to first uncovered line)
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
 */
6
7
#include "fido.h"
8
9
static int
10
get_key_len(uint8_t tag, uint8_t *key, size_t *key_len)
11
322k
{
12
322k
        *key = tag & 0xfc;
13
322k
        if ((*key & 0xf0) == 0xf0) {
14
6.34k
                fido_log_debug("%s: *key=0x%02x", __func__, *key);
15
6.34k
                return (-1);
16
6.34k
        }
17
316k
18
316k
        *key_len = tag & 0x3;
19
316k
        if (*key_len == 3) {
20
17.0k
                *key_len = 4;
21
17.0k
        }
22
316k
23
316k
        return (0);
24
316k
}
25
26
static int
27
get_key_val(const void *body, size_t key_len, uint32_t *val)
28
296k
{
29
296k
        const uint8_t *ptr = body;
30
296k
31
296k
        switch (key_len) {
32
177k
        case 0:
33
177k
                *val = 0;
34
177k
                break;
35
11.7k
        case 1:
36
11.7k
                *val = ptr[0];
37
11.7k
                break;
38
100k
        case 2:
39
100k
                *val = (uint32_t)((ptr[1] << 8) | ptr[0]);
40
100k
                break;
41
6.75k
        default:
42
6.75k
                fido_log_debug("%s: key_len=%zu", __func__, key_len);
43
6.75k
                return (-1);
44
289k
        }
45
289k
46
289k
        return (0);
47
289k
}
48
49
int
50
fido_hid_get_usage(const uint8_t *report_ptr, size_t report_len,
51
    uint32_t *usage_page)
52
140k
{
53
140k
        const uint8_t   *ptr = report_ptr;
54
140k
        size_t           len = report_len;
55
140k
56
427k
        while (len > 0) {
57
320k
                const uint8_t tag = ptr[0];
58
320k
                ptr++;
59
320k
                len--;
60
320k
61
320k
                uint8_t  key;
62
320k
                size_t   key_len;
63
320k
                uint32_t key_val;
64
320k
65
320k
                if (get_key_len(tag, &key, &key_len) < 0 || key_len > len ||
66
320k
                    get_key_val(ptr, key_len, &key_val) < 0) {
67
32.8k
                        return (-1);
68
32.8k
                }
69
287k
70
287k
                if (key == 0x4) {
71
94.5k
                        *usage_page = key_val;
72
94.5k
                }
73
287k
74
287k
                ptr += key_len;
75
287k
                len -= key_len;
76
287k
        }
77
140k
78
140k
        return (0);
79
140k
}
80
81
int
82
fido_hid_get_report_len(const uint8_t *report_ptr, size_t report_len,
83
    size_t *report_in_len, size_t *report_out_len)
84
367
{
85
367
        const uint8_t   *ptr = report_ptr;
86
367
        size_t           len = report_len;
87
367
        uint32_t         report_size = 0;
88
367
89
2.20k
        while (len > 0) {
90
1.96k
                const uint8_t tag = ptr[0];
91
1.96k
                ptr++;
92
1.96k
                len--;
93
1.96k
94
1.96k
                uint8_t  key;
95
1.96k
                size_t   key_len;
96
1.96k
                uint32_t key_val;
97
1.96k
98
1.96k
                if (get_key_len(tag, &key, &key_len) < 0 || key_len > len ||
99
1.96k
                    get_key_val(ptr, key_len, &key_val) < 0) {
100
136
                        return (-1);
101
136
                }
102
1.83k
103
1.83k
                if (key == 0x94) {
104
252
                        report_size = key_val;
105
1.58k
                } else if (key == 0x80) {
106
202
                        *report_in_len = (size_t)report_size;
107
1.37k
                } else if (key == 0x90) {
108
206
                        *report_out_len = (size_t)report_size;
109
206
                }
110
1.83k
111
1.83k
                ptr += key_len;
112
1.83k
                len -= key_len;
113
1.83k
        }
114
367
115
367
        return (0);
116
367
}
117
118
fido_dev_info_t *
119
fido_dev_info_new(size_t n)
120
367
{
121
367
        return (calloc(n, sizeof(fido_dev_info_t)));
122
367
}
123
124
void
125
fido_dev_info_free(fido_dev_info_t **devlist_p, size_t n)
126
367
{
127
367
        fido_dev_info_t *devlist;
128
367
129
367
        if (devlist_p == NULL || (devlist = *devlist_p) == NULL)
130
367
                return;
131
365
132
14.9k
        for (size_t i = 0; i < n; i++) {
133
14.5k
                const fido_dev_info_t *di;
134
14.5k
                di = &devlist[i];
135
14.5k
                free(di->path);
136
14.5k
                free(di->manufacturer);
137
14.5k
                free(di->product);
138
14.5k
        }
139
365
140
365
        free(devlist);
141
365
142
365
        *devlist_p = NULL;
143
365
}
144
145
const fido_dev_info_t *
146
fido_dev_info_ptr(const fido_dev_info_t *devlist, size_t i)
147
9.38k
{
148
9.38k
        return (&devlist[i]);
149
9.38k
}
150
151
const char *
152
fido_dev_info_path(const fido_dev_info_t *di)
153
9.38k
{
154
9.38k
        return (di->path);
155
9.38k
}
156
157
int16_t
158
fido_dev_info_vendor(const fido_dev_info_t *di)
159
9.38k
{
160
9.38k
        return (di->vendor_id);
161
9.38k
}
162
163
int16_t
164
fido_dev_info_product(const fido_dev_info_t *di)
165
9.38k
{
166
9.38k
        return (di->product_id);
167
9.38k
}
168
169
const char *
170
fido_dev_info_manufacturer_string(const fido_dev_info_t *di)
171
9.38k
{
172
9.38k
        return (di->manufacturer);
173
9.38k
}
174
175
const char *
176
fido_dev_info_product_string(const fido_dev_info_t *di)
177
9.38k
{
178
9.38k
        return (di->product);
179
9.38k
}