xref: /openbmc/qemu/docs/system/devices/canokey.rst (revision ed3a06b1)
1.. _canokey:
2
3CanoKey QEMU
4------------
5
6CanoKey [1]_ is an open-source secure key with supports of
7
8* U2F / FIDO2 with Ed25519 and HMAC-secret
9* OpenPGP Card V3.4 with RSA4096, Ed25519 and more [2]_
10* PIV (NIST SP 800-73-4)
11* HOTP / TOTP
12* NDEF
13
14All these platform-independent features are in canokey-core [3]_.
15
16For different platforms, CanoKey has different implementations,
17including both hardware implementions and virtual cards:
18
19* CanoKey STM32 [4]_
20* CanoKey Pigeon [5]_
21* (virt-card) CanoKey USB/IP
22* (virt-card) CanoKey FunctionFS
23
24In QEMU, yet another CanoKey virt-card is implemented.
25CanoKey QEMU exposes itself as a USB device to the guest OS.
26
27With the same software configuration as a hardware key,
28the guest OS can use all the functionalities of a secure key as if
29there was actually an hardware key plugged in.
30
31CanoKey QEMU provides much convenience for debuging:
32
33* libcanokey-qemu supports debuging output thus developers can
34  inspect what happens inside a secure key
35* CanoKey QEMU supports trace event thus event
36* QEMU USB stack supports pcap thus USB packet between the guest
37  and key can be captured and analysed
38
39Then for developers:
40
41* For developers on software with secure key support (e.g. FIDO2, OpenPGP),
42  they can see what happens inside the secure key
43* For secure key developers, USB packets between guest OS and CanoKey
44  can be easily captured and analysed
45
46Also since this is a virtual card, it can be easily used in CI for testing
47on code coping with secure key.
48
49Building
50========
51
52libcanokey-qemu is required to use CanoKey QEMU.
53
54.. code-block:: shell
55
56    git clone https://github.com/canokeys/canokey-qemu
57    mkdir canokey-qemu/build
58    pushd canokey-qemu/build
59
60If you want to install libcanokey-qemu in a different place,
61add ``-DCMAKE_INSTALL_PREFIX=/path/to/your/place`` to cmake below.
62
63.. code-block:: shell
64
65    cmake ..
66    make
67    make install # may need sudo
68    popd
69
70Then configuring and building:
71
72.. code-block:: shell
73
74    # depending on your env, lib/pkgconfig can be lib64/pkgconfig
75    export PKG_CONFIG_PATH=/path/to/your/place/lib/pkgconfig:$PKG_CONFIG_PATH
76    ./configure --enable-canokey && make
77
78Using CanoKey QEMU
79==================
80
81CanoKey QEMU stores all its data on a file of the host specified by the argument
82when invoking qemu.
83
84.. parsed-literal::
85
86    |qemu_system| -usb -device canokey,file=$HOME/.canokey-file
87
88Note: you should keep this file carefully as it may contain your private key!
89
90The first time when the file is used, it is created and initialized by CanoKey,
91afterwards CanoKey QEMU would just read this file.
92
93After the guest OS boots, you can check that there is a USB device.
94
95For example, If the guest OS is an Linux machine. You may invoke lsusb
96and find CanoKey QEMU there:
97
98.. code-block:: shell
99
100    $ lsusb
101    Bus 001 Device 002: ID 20a0:42d4 Clay Logic CanoKey QEMU
102
103You may setup the key as guided in [6]_. The console for the key is at [7]_.
104
105Debuging
106========
107
108CanoKey QEMU consists of two parts, ``libcanokey-qemu.so`` and ``canokey.c``,
109the latter of which resides in QEMU. The former provides core functionality
110of a secure key while the latter provides platform-dependent functions:
111USB packet handling.
112
113If you want to trace what happens inside the secure key, when compiling
114libcanokey-qemu, you should add ``-DQEMU_DEBUG_OUTPUT=ON`` in cmake command
115line:
116
117.. code-block:: shell
118
119    cmake .. -DQEMU_DEBUG_OUTPUT=ON
120
121If you want to trace events happened in canokey.c, use
122
123.. parsed-literal::
124
125    |qemu_system| --trace "canokey_*" \\
126        -usb -device canokey,file=$HOME/.canokey-file
127
128If you want to capture USB packets between the guest and the host, you can:
129
130.. parsed-literal::
131
132    |qemu_system| -usb -device canokey,file=$HOME/.canokey-file,pcap=key.pcap
133
134Limitations
135===========
136
137Currently libcanokey-qemu.so has dozens of global variables as it was originally
138designed for embedded systems. Thus one qemu instance can not have
139multiple CanoKey QEMU running, namely you can not
140
141.. parsed-literal::
142
143    |qemu_system| -usb -device canokey,file=$HOME/.canokey-file \\
144         -device canokey,file=$HOME/.canokey-file2
145
146Also, there is no lock on canokey-file, thus two CanoKey QEMU instance
147can not read one canokey-file at the same time.
148
149Another limitation is that this device is not compatible with ``qemu-xhci``,
150in that this device would hang when there are FIDO2 packets (traffic on
151interrupt endpoints). If you do not use FIDO2 then it works as intended,
152but for full functionality you should use old uhci/ehci bus and attach canokey
153to it, for example
154
155.. parsed-literal::
156
157   |qemu_system| -device piix3-usb-uhci,id=uhci -device canokey,bus=uhci.0
158
159References
160==========
161
162.. [1] `<https://canokeys.org>`_
163.. [2] `<https://docs.canokeys.org/userguide/openpgp/#supported-algorithm>`_
164.. [3] `<https://github.com/canokeys/canokey-core>`_
165.. [4] `<https://github.com/canokeys/canokey-stm32>`_
166.. [5] `<https://github.com/canokeys/canokey-pigeon>`_
167.. [6] `<https://docs.canokeys.org/>`_
168.. [7] `<https://console.canokeys.org/>`_
169