Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/usb/backend/fido_backend/hid_utils.rs
5394 views
1
// Copyright 2024 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use std::fs::File;
6
use std::os::raw::c_int;
7
8
use base::handle_eintr_errno;
9
use base::ioctl_ior_nr;
10
11
use crate::usb::backend::fido_backend::constants;
12
use crate::usb::backend::fido_backend::error::Error;
13
use crate::usb::backend::fido_backend::error::Result;
14
15
#[repr(C)]
16
#[derive(Clone)]
17
pub struct HidrawReportDescriptor {
18
pub size: u32,
19
pub value: [u8; constants::HID_MAX_DESCRIPTOR_SIZE],
20
}
21
22
pub const HID_IO_TYPE: u32 = 'H' as u32;
23
24
ioctl_ior_nr!(HIDIOCGRDESCSIZE, HID_IO_TYPE, 0x01, c_int);
25
ioctl_ior_nr!(HIDIOCGRDESC, HID_IO_TYPE, 0x02, HidrawReportDescriptor);
26
27
/// Verifies that the given `hidraw` file handle is a valid FIDO device.
28
/// In case it is not, it returns an `InvalidHidrawDevice` erro.
29
pub fn verify_is_fido_device(hidraw: &File) -> Result<()> {
30
let mut desc_size: c_int = 0;
31
// SAFETY:
32
// Safe because:
33
// - We check the return value after the call.
34
// - ioctl(HIDIOCGRDDESCSIZE) does not hold the descriptor after the call.
35
unsafe {
36
let ret = handle_eintr_errno!(base::ioctl_with_mut_ref(
37
hidraw,
38
HIDIOCGRDESCSIZE,
39
&mut desc_size
40
));
41
if ret < 0 || (desc_size as usize) < constants::HID_REPORT_DESC_HEADER.len() {
42
return Err(Error::InvalidHidrawDevice);
43
}
44
}
45
46
let mut descriptor = HidrawReportDescriptor {
47
size: desc_size as u32,
48
value: [0; constants::HID_MAX_DESCRIPTOR_SIZE],
49
};
50
51
// SAFETY:
52
// Safe because:
53
// - We check the return value after the call.
54
// - ioctl(HIDIOCGRDESC) does not hold the descriptor after the call.
55
unsafe {
56
let ret = handle_eintr_errno!(base::ioctl_with_mut_ref(
57
hidraw,
58
HIDIOCGRDESC,
59
&mut descriptor
60
));
61
if ret < 0 {
62
return Err(Error::InvalidHidrawDevice);
63
}
64
}
65
66
if descriptor.value[..constants::HID_REPORT_DESC_HEADER.len()]
67
!= *constants::HID_REPORT_DESC_HEADER
68
{
69
return Err(Error::InvalidHidrawDevice);
70
}
71
Ok(())
72
}
73
74