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