From patchwork Mon Aug 24 11:48:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9sar_Belley?= X-Patchwork-Id: 275740 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAA45C433DF for ; Mon, 24 Aug 2020 11:51:00 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2E820206BE for ; Mon, 24 Aug 2020 11:51:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=lse.epita.fr header.i=@lse.epita.fr header.b="mpnVpbl+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2E820206BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lse.epita.fr Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38014 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kAB07-0005ck-3g for qemu-devel@archiver.kernel.org; Mon, 24 Aug 2020 07:50:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51340) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyR-0002UY-JK for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:15 -0400 Received: from gate-2.cri.epita.net ([163.5.55.20]:54788 helo=mail-2.srv.cri.epita.fr) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyP-0003cJ-Tw for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:15 -0400 Received: from MattGorko-Laptop.home (lfbn-idf1-1-1395-83.w90-79.abo.wanadoo.fr [90.79.87.83]) (Authenticated sender: cesar.belley) by mail-2.srv.cri.epita.fr (Postfix) with ESMTPSA id B5D363FB5A; Mon, 24 Aug 2020 13:49:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lse.epita.fr; s=cri; t=1598269752; bh=WDA0oI2Z69R2zXIfx2G23h1o+q5997g9l9qIdMw94RQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mpnVpbl+sRfYFZwdKLVT0THHPmpbPTKBgdNxF4BuVm+S+2xj6j7xKWvCcXlkywx86 hj9c4F2a39E3mmbV065lkUiM14tn+E+AErJepNbQOlOn83lqR6DfNM46fPvEu+QKc0 DU2/VoiG726/M2wY2ioN2ByJ0EFLAIkaNtdhyEI4= From: =?utf-8?q?C=C3=A9sar_Belley?= To: qemu-devel@nongnu.org Subject: [PATCH v2 01/13] hw/usb: Regroup USB HID protocol values Date: Mon, 24 Aug 2020 13:48:15 +0200 Message-Id: <20200824114827.81623-2-cesar.belley@lse.epita.fr> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200824114827.81623-1-cesar.belley@lse.epita.fr> References: <20200824114827.81623-1-cesar.belley@lse.epita.fr> MIME-Version: 1.0 Received-SPF: pass client-ip=163.5.55.20; envelope-from=srs0=45nv=cc=lse.epita.fr=cesar.belley@cri.epita.fr; helo=mail-2.srv.cri.epita.fr X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/24 07:49:04 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9sar_Belley?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Group some HID values that are used pretty much everywhere when dealing with HID devices. Signed-off-by: César Belley --- hw/usb/dev-hid.c | 26 +++++++------------------- hw/usb/dev-wacom.c | 12 +++--------- include/hw/usb/hid.h | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 28 deletions(-) create mode 100644 include/hw/usb/hid.h diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c index 89f63b698b..c73f7b2fe2 100644 --- a/hw/usb/dev-hid.c +++ b/hw/usb/dev-hid.c @@ -32,21 +32,9 @@ #include "qemu/module.h" #include "qemu/timer.h" #include "hw/input/hid.h" +#include "hw/usb/hid.h" #include "hw/qdev-properties.h" -/* HID interface requests */ -#define GET_REPORT 0xa101 -#define GET_IDLE 0xa102 -#define GET_PROTOCOL 0xa103 -#define SET_REPORT 0x2109 -#define SET_IDLE 0x210a -#define SET_PROTOCOL 0x210b - -/* HID descriptor types */ -#define USB_DT_HID 0x21 -#define USB_DT_REPORT 0x22 -#define USB_DT_PHY 0x23 - typedef struct USBHIDState { USBDevice dev; USBEndpoint *intr; @@ -618,38 +606,38 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p, goto fail; } break; - case GET_REPORT: + case HID_GET_REPORT: if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) { p->actual_length = hid_pointer_poll(hs, data, length); } else if (hs->kind == HID_KEYBOARD) { p->actual_length = hid_keyboard_poll(hs, data, length); } break; - case SET_REPORT: + case HID_SET_REPORT: if (hs->kind == HID_KEYBOARD) { p->actual_length = hid_keyboard_write(hs, data, length); } else { goto fail; } break; - case GET_PROTOCOL: + case HID_GET_PROTOCOL: if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) { goto fail; } data[0] = hs->protocol; p->actual_length = 1; break; - case SET_PROTOCOL: + case HID_SET_PROTOCOL: if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) { goto fail; } hs->protocol = value; break; - case GET_IDLE: + case HID_GET_IDLE: data[0] = hs->idle; p->actual_length = 1; break; - case SET_IDLE: + case HID_SET_IDLE: hs->idle = (uint8_t) (value >> 8); hid_set_next_idle(hs); if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) { diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c index 8aba44b8bc..76fc5a5dab 100644 --- a/hw/usb/dev-wacom.c +++ b/hw/usb/dev-wacom.c @@ -29,6 +29,7 @@ #include "qemu/osdep.h" #include "ui/console.h" #include "hw/usb.h" +#include "hw/usb/hid.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "desc.h" @@ -37,13 +38,6 @@ #define WACOM_GET_REPORT 0x2101 #define WACOM_SET_REPORT 0x2109 -/* HID interface requests */ -#define HID_GET_REPORT 0xa101 -#define HID_GET_IDLE 0xa102 -#define HID_GET_PROTOCOL 0xa103 -#define HID_SET_IDLE 0x210a -#define HID_SET_PROTOCOL 0x210b - typedef struct USBWacomState { USBDevice dev; USBEndpoint *intr; @@ -86,11 +80,11 @@ static const USBDescIface desc_iface_wacom = { /* HID descriptor */ .data = (uint8_t[]) { 0x09, /* u8 bLength */ - 0x21, /* u8 bDescriptorType */ + USB_DT_HID, /* u8 bDescriptorType */ 0x01, 0x10, /* u16 HID_class */ 0x00, /* u8 country_code */ 0x01, /* u8 num_descriptors */ - 0x22, /* u8 type: Report */ + USB_DT_REPORT, /* u8 type: Report */ 0x6e, 0, /* u16 len */ }, }, diff --git a/include/hw/usb/hid.h b/include/hw/usb/hid.h new file mode 100644 index 0000000000..1c142584ff --- /dev/null +++ b/include/hw/usb/hid.h @@ -0,0 +1,17 @@ +#ifndef HW_USB_HID_H +#define HW_USB_HID_H + +/* HID interface requests */ +#define HID_GET_REPORT 0xa101 +#define HID_GET_IDLE 0xa102 +#define HID_GET_PROTOCOL 0xa103 +#define HID_SET_REPORT 0x2109 +#define HID_SET_IDLE 0x210a +#define HID_SET_PROTOCOL 0x210b + +/* HID descriptor types */ +#define USB_DT_HID 0x21 +#define USB_DT_REPORT 0x22 +#define USB_DT_PHY 0x23 + +#endif From patchwork Mon Aug 24 11:48:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9sar_Belley?= X-Patchwork-Id: 275741 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69431C433DF for ; Mon, 24 Aug 2020 11:50:13 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 385B8206BE for ; Mon, 24 Aug 2020 11:50:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=lse.epita.fr header.i=@lse.epita.fr header.b="qCRkOn/o" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 385B8206BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lse.epita.fr Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:34176 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kAAzM-00046Z-Bc for qemu-devel@archiver.kernel.org; Mon, 24 Aug 2020 07:50:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51378) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyS-0002Uz-TG for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:16 -0400 Received: from gate-2.cri.epita.net ([163.5.55.20]:54792 helo=mail-2.srv.cri.epita.fr) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyQ-0003cP-P6 for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:16 -0400 Received: from MattGorko-Laptop.home (lfbn-idf1-1-1395-83.w90-79.abo.wanadoo.fr [90.79.87.83]) (Authenticated sender: cesar.belley) by mail-2.srv.cri.epita.fr (Postfix) with ESMTPSA id 4AB133FB60; Mon, 24 Aug 2020 13:49:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lse.epita.fr; s=cri; t=1598269753; bh=mXjkHDuBA2Pelp7FvLqsvotpGAVI+Oj+eqQ5xB79ZVs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qCRkOn/oVfrKaCwoaoVQKMGgBVr3LUZttmVQW239j2gC7RnwwI27Uv8pQ75lUh9jW c/8T7yqGbF/gIu1rNzSuVhOkcFGTnlivpvJhuQfAWGeA66SzKtnHlOtoK17UEisE6s tOOQ2+XJ2VjYvzlOPbsOsGB+ZQwrFxVTkzgWpW9M= From: =?utf-8?q?C=C3=A9sar_Belley?= To: qemu-devel@nongnu.org Subject: [PATCH v2 02/13] docs: Add USB U2F key device documentation Date: Mon, 24 Aug 2020 13:48:16 +0200 Message-Id: <20200824114827.81623-3-cesar.belley@lse.epita.fr> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200824114827.81623-1-cesar.belley@lse.epita.fr> References: <20200824114827.81623-1-cesar.belley@lse.epita.fr> MIME-Version: 1.0 Received-SPF: pass client-ip=163.5.55.20; envelope-from=srs0=45nv=cc=lse.epita.fr=cesar.belley@cri.epita.fr; helo=mail-2.srv.cri.epita.fr X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/24 07:49:04 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9sar_Belley?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add USB U2F key device documentation: - USB U2F key device - Building - Using u2f-emulated - Using u2f-passthru - Libu2f-emu Signed-off-by: César Belley --- docs/u2f.txt | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 docs/u2f.txt diff --git a/docs/u2f.txt b/docs/u2f.txt new file mode 100644 index 0000000000..f60052882e --- /dev/null +++ b/docs/u2f.txt @@ -0,0 +1,101 @@ +QEMU U2F Key Device Documentation. + +Contents +1. USB U2F key device +2. Building +3. Using u2f-emulated +4. Using u2f-passthru +5. Libu2f-emu + +1. USB U2F key device + +U2F is an open authentication standard that enables relying parties +exposed to the internet to offer a strong second factor option for end +user authentication. + +The standard brings many advantages to both parties, client and server, +allowing to reduce over-reliance on passwords, it increases authentication +security and simplifies passwords. + +The second factor is materialized by a device implementing the U2F +protocol. In case of a USB U2F security key, it is a USB HID device +that implements the U2F protocol. + +In Qemu, the USB U2F key device offers a dedicated support of U2F, allowing +guest USB FIDO/U2F security keys operating in two possible modes: +pass-through and emulated. + +The pass-through mode consists of passing all requests made from the guest +to the physical security key connected to the host machine and vice versa. +In addition, the dedicated pass-through allows to have a U2F security key +shared on several guests which is not possible with a simple host device +assignment pass-through. + +The emulated mode consists of completely emulating the behavior of an +U2F device through software part. Libu2f-emu is used for that. + + +2. Building + +To ensure the build of the u2f-emulated device variant which depends +on libu2f-emu: configuring and building: + + ./configure --enable-u2f && make + + +3. Using u2f-emulated + +To work, an emulated U2F device must have four elements: + * ec x509 certificate + * ec private key + * counter (four bytes value) + * 48 bytes of entropy (random bits) + +To use this type of device, this one has to be configured, and these +four elements must be passed one way or another. + +Assuming that you have a working libu2f-emu installed on the host. +There are three possible ways of configurations: + * ephemeral + * setup directory + * manual + +Ephemeral is the simplest way to configure, it lets the device generate +all the elements it needs for a single use of the lifetime of the device. + + qemu -usb -device u2f-emulated + +Setup directory allows to configure the device from a directory containing +four files: + * certificate.pem: ec x509 certificate + * private-key.pem: ec private key + * counter: counter value + * entropy: 48 bytes of entropy + + qemu -usb -device u2f-emulated,dir=$dir + +Manual allows to configure the device more finely by specifying each +of the elements necessary for the device: + * cert + * priv + * counter + * entropy + + qemu -usb -device u2f-emulated,cert=$DIR1/$FILE1,priv=$DIR2/$FILE2,counter=$DIR3/$FILE3,entropy=$DIR4/$FILE4 + + +4. Using u2f-passthru + +On the host specify the u2f-passthru device with a suitable hidraw: + + qemu -usb -device u2f-passthru,hidraw=/dev/hidraw0 + + +5. Libu2f-emu + +The u2f-emulated device uses libu2f-emu for the U2F key emulation. Libu2f-emu +implements completely the U2F protocol device part for all specified +transport given by the FIDO Alliance. + +For more information about libu2f-emu see this page: +https://github.com/MattGorko/libu2f-emu. From patchwork Mon Aug 24 11:48:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9sar_Belley?= X-Patchwork-Id: 275738 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3A0FC433E1 for ; Mon, 24 Aug 2020 11:52:18 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3F213206BE for ; Mon, 24 Aug 2020 11:52:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=lse.epita.fr header.i=@lse.epita.fr header.b="eLbQt3wB" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3F213206BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lse.epita.fr Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:46360 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kAB1N-0000e1-GX for qemu-devel@archiver.kernel.org; Mon, 24 Aug 2020 07:52:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51374) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyS-0002Uw-RO for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:16 -0400 Received: from gate-2.cri.epita.net ([163.5.55.20]:54798 helo=mail-2.srv.cri.epita.fr) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyQ-0003cX-Ur for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:16 -0400 Received: from MattGorko-Laptop.home (lfbn-idf1-1-1395-83.w90-79.abo.wanadoo.fr [90.79.87.83]) (Authenticated sender: cesar.belley) by mail-2.srv.cri.epita.fr (Postfix) with ESMTPSA id BC7103FAC7; Mon, 24 Aug 2020 13:49:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lse.epita.fr; s=cri; t=1598269753; bh=cvFDhlHRNc+dPkxjMum8CmWTe5nwcNjnFM+clGU5O+A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eLbQt3wBWd4JWa7a1huVhzJmTVPsv3A0g4CfP98WV56roIPGDpSVGmoHwkeekjLCN 2QQUyVh4+JDfplaDGzBwQefhpANhUMMKqY4kIZlCdiSYyuotuNx3m+YEG4xTX22Y8z cmKcSMk7fEr5qUBEtcrrh6MeDLnrIULuoXOBZZIM= From: =?utf-8?q?C=C3=A9sar_Belley?= To: qemu-devel@nongnu.org Subject: [PATCH v2 03/13] hw/usb: Add U2F key base class Date: Mon, 24 Aug 2020 13:48:17 +0200 Message-Id: <20200824114827.81623-4-cesar.belley@lse.epita.fr> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200824114827.81623-1-cesar.belley@lse.epita.fr> References: <20200824114827.81623-1-cesar.belley@lse.epita.fr> MIME-Version: 1.0 Received-SPF: pass client-ip=163.5.55.20; envelope-from=srs0=45nv=cc=lse.epita.fr=cesar.belley@cri.epita.fr; helo=mail-2.srv.cri.epita.fr X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/24 07:49:04 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9sar_Belley?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This patch adds the specification for the U2F key base class. Used to group the common characteristics, this device class will be inherited by its two variants, corresponding to the two modes: passthrough and emulated This prepares the U2F devices hierarchy which is as follow: USB device -> u2f-key -> {u2f-passthru, u2f-emulated}. Signed-off-by: César Belley --- hw/usb/u2f.h | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 hw/usb/u2f.h diff --git a/hw/usb/u2f.h b/hw/usb/u2f.h new file mode 100644 index 0000000000..db30f3586b --- /dev/null +++ b/hw/usb/u2f.h @@ -0,0 +1,92 @@ +/* + * U2F USB device. + * + * Copyright (c) 2020 César Belley + * Written by César Belley + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef U2F_H +#define U2F_H + +#include "hw/qdev-core.h" + +#define U2FHID_PACKET_SIZE 64 +#define U2FHID_PENDING_IN_NUM 32 + +typedef struct U2FKeyState U2FKeyState; +typedef struct U2FKeyInfo U2FKeyInfo; + +#define TYPE_U2F_KEY "u2f-key" +#define U2F_KEY(obj) \ + OBJECT_CHECK(U2FKeyState, (obj), TYPE_U2F_KEY) +#define U2F_KEY_CLASS(klass) \ + OBJECT_CLASS_CHECK(U2FKeyClass, (klass), TYPE_U2F_KEY) +#define U2F_KEY_GET_CLASS(obj) \ + OBJECT_GET_CLASS(U2FKeyClass, (obj), TYPE_U2F_KEY) + +/* + * Callbacks to be used by the U2F key base device (i.e. hw/u2f.c) + * to interact with its variants (i.e. hw/u2f-*.c) + */ +typedef struct U2FKeyClass { + /*< private >*/ + USBDeviceClass parent_class; + + /*< public >*/ + void (*recv_from_guest)(U2FKeyState *key, + const uint8_t packet[U2FHID_PACKET_SIZE]); + void (*realize)(U2FKeyState *key, Error **errp); + void (*unrealize)(U2FKeyState *key); +} U2FKeyClass; + +/* + * State of the U2F key base device (i.e. hw/u2f.c) + */ +typedef struct U2FKeyState { + USBDevice dev; + USBEndpoint *ep; + uint8_t idle; + + /* Pending packets to be send to the guest */ + uint8_t pending_in[U2FHID_PENDING_IN_NUM][U2FHID_PACKET_SIZE]; + uint8_t pending_in_start; + uint8_t pending_in_end; + uint8_t pending_in_num; +} U2FKeyState; + +/* + * API to be used by the U2F key device variants (i.e. hw/u2f-*.c) + * to interact with the the U2F key base device (i.e. hw/u2f.c) + */ +void u2f_send_to_guest(U2FKeyState *key, + const uint8_t packet[U2FHID_PACKET_SIZE]); + +extern const VMStateDescription vmstate_u2f_key; + +#define VMSTATE_U2F_KEY(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(U2FKeyState), \ + .vmsd = &vmstate_u2f_key, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, U2FKeyState), \ +} + +#endif /* U2F_H */ From patchwork Mon Aug 24 11:48:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9sar_Belley?= X-Patchwork-Id: 275739 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 217DBC433DF for ; Mon, 24 Aug 2020 11:51:43 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E65E4206BE for ; Mon, 24 Aug 2020 11:51:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=lse.epita.fr header.i=@lse.epita.fr header.b="Yaj+1N//" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E65E4206BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lse.epita.fr Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:42568 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kAB0o-0007YB-4D for qemu-devel@archiver.kernel.org; Mon, 24 Aug 2020 07:51:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51438) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyV-0002Yt-7H for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:19 -0400 Received: from gate-2.cri.epita.net ([163.5.55.20]:54822 helo=mail-2.srv.cri.epita.fr) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyS-0003cy-LF for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:18 -0400 Received: from MattGorko-Laptop.home (lfbn-idf1-1-1395-83.w90-79.abo.wanadoo.fr [90.79.87.83]) (Authenticated sender: cesar.belley) by mail-2.srv.cri.epita.fr (Postfix) with ESMTPSA id 73685412C9; Mon, 24 Aug 2020 13:49:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lse.epita.fr; s=cri; t=1598269755; bh=a+7ZXrsEm2NyNn+Qyc4H4Tfiz70E7/Z+HkEpxeMxp5s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Yaj+1N//azg7lXjhBL0DIrEmvGAnCGQL/99nKvAJNjv3qGzkte2P3Y88PjQDSkhPg HR9FYj0InPiHybQ+Z3t8cjHDRpv6SJTxER2NJVn+8/5xI4Nd8SREEK46+QZ/igG3EE dwOKBfYLnOJ9/hT0jBOVV10qZ23JQSOcp7mZhKSw= From: =?utf-8?q?C=C3=A9sar_Belley?= To: qemu-devel@nongnu.org Subject: [PATCH v2 07/13] hw/usb: Add U2F key build recipe Date: Mon, 24 Aug 2020 13:48:21 +0200 Message-Id: <20200824114827.81623-8-cesar.belley@lse.epita.fr> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200824114827.81623-1-cesar.belley@lse.epita.fr> References: <20200824114827.81623-1-cesar.belley@lse.epita.fr> MIME-Version: 1.0 Received-SPF: pass client-ip=163.5.55.20; envelope-from=srs0=45nv=cc=lse.epita.fr=cesar.belley@cri.epita.fr; helo=mail-2.srv.cri.epita.fr X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/24 07:49:04 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9sar_Belley?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: César Belley --- hw/usb/Kconfig | 5 +++++ hw/usb/meson.build | 5 +++++ meson.build | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig index 5e63dc75f8..3fc8fbe3c7 100644 --- a/hw/usb/Kconfig +++ b/hw/usb/Kconfig @@ -96,6 +96,11 @@ config USB_STORAGE_MTP default y depends on USB +config USB_U2F + bool + default y + depends on USB + config IMX_USBPHY bool default y diff --git a/hw/usb/meson.build b/hw/usb/meson.build index 3c44a1b069..cac7639924 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -50,6 +50,11 @@ if config_host.has_key('CONFIG_SMARTCARD') hw_usb_modules += {'smartcard': usbsmartcard_ss} endif +# U2F +softmmu_ss.add(when: 'CONFIG_USB_U2F', if_true: files('u2f.c')) +softmmu_ss.add(when: ['CONFIG_LINUX', 'CONFIG_USB_U2F'], if_true: files('u2f-passthru.c')) +softmmu_ss.add(when: ['CONFIG_U2F', 'CONFIG_USB_U2F'], if_true: [u2f, files('u2f-emulated.c')]) + # usb redirect if config_host.has_key('CONFIG_USB_REDIR') usbredir_ss = ss.source_set() diff --git a/meson.build b/meson.build index df5bf728b5..1e6c9c598f 100644 --- a/meson.build +++ b/meson.build @@ -360,6 +360,11 @@ if 'CONFIG_SMARTCARD' in config_host cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(), link_args: config_host['SMARTCARD_LIBS'].split()) endif +u2f = not_found +if 'CONFIG_U2F' in config_host + u2f = declare_dependency(compile_args: config_host['U2F_CFLAGS'].split(), + link_args: config_host['U2F_LIBS'].split()) +endif usbredir = not_found if 'CONFIG_USB_REDIR' in config_host usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(), @@ -1359,6 +1364,7 @@ summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')} summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')} summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')} summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')} +summary_info += {'U2F support': config_host.has_key('CONFIG_U2F')} summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')} summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')} summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')} From patchwork Mon Aug 24 11:48:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9sar_Belley?= X-Patchwork-Id: 275737 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8FE41C433DF for ; Mon, 24 Aug 2020 11:53:02 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5EB3E206BE for ; Mon, 24 Aug 2020 11:53:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=lse.epita.fr header.i=@lse.epita.fr header.b="oTDC3NIV" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5EB3E206BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lse.epita.fr Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50016 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kAB25-00025i-LU for qemu-devel@archiver.kernel.org; Mon, 24 Aug 2020 07:53:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51442) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyV-0002a8-Nk for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:19 -0400 Received: from gate-2.cri.epita.net ([163.5.55.20]:54826 helo=mail-2.srv.cri.epita.fr) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyS-0003d3-VL for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:19 -0400 Received: from MattGorko-Laptop.home (lfbn-idf1-1-1395-83.w90-79.abo.wanadoo.fr [90.79.87.83]) (Authenticated sender: cesar.belley) by mail-2.srv.cri.epita.fr (Postfix) with ESMTPSA id CB551412D2; Mon, 24 Aug 2020 13:49:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lse.epita.fr; s=cri; t=1598269755; bh=YJtgc+Umbt+HNWGt7tySLOgQt78fbDR8UyHC6rJlKIk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oTDC3NIVh6lhcVRM8AI0SaPnG2rVSlbJIdpYRmzefuWTmVRBHh2LDEBh5UeN6vw+6 gQhMJc527zljiGCHnEqcxlGFXGFIkFdMDR2uB5FYjYTdsfN85gHO7xqf5qD9swOT7m nMJK31cMq5g7+I641C7grEVM58WQC0DTOkI7VlUc= From: =?utf-8?q?C=C3=A9sar_Belley?= To: qemu-devel@nongnu.org Subject: [PATCH v2 08/13] configure: Add USB U2F key device Date: Mon, 24 Aug 2020 13:48:22 +0200 Message-Id: <20200824114827.81623-9-cesar.belley@lse.epita.fr> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200824114827.81623-1-cesar.belley@lse.epita.fr> References: <20200824114827.81623-1-cesar.belley@lse.epita.fr> MIME-Version: 1.0 Received-SPF: pass client-ip=163.5.55.20; envelope-from=srs0=45nv=cc=lse.epita.fr=cesar.belley@cri.epita.fr; helo=mail-2.srv.cri.epita.fr X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/24 07:49:04 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9sar_Belley?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: César Belley --- configure | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/configure b/configure index 67832e3bab..75d38e5411 100755 --- a/configure +++ b/configure @@ -495,6 +495,7 @@ trace_file="trace" spice="" rbd="" smartcard="" +u2f="" libusb="" usb_redir="" opengl="" @@ -1411,6 +1412,10 @@ for opt do ;; --enable-smartcard) smartcard="yes" ;; + --disable-u2f) u2f="no" + ;; + --enable-u2f) u2f="yes" + ;; --disable-libusb) libusb="no" ;; --enable-libusb) libusb="yes" @@ -1940,6 +1945,7 @@ disabled with --disable-FEATURE, default is enabled if available: libiscsi iscsi support libnfs nfs support smartcard smartcard support (libcacard) + u2f U2F support (u2f-emu) libusb libusb (for usb passthrough) live-block-migration Block migration in the main migration stream usb-redir usb network redirection support @@ -5119,6 +5125,20 @@ if test "$smartcard" != "no"; then fi fi +# check for u2f support +if test "$u2f" != "no"; then + if $pkg_config --atleast-version=0.0.0 u2f-emu; then + u2f_emu_cflags=$($pkg_config --cflags u2f-emu) + u2f_emu_libs=$($pkg_config --libs u2f-emu) + u2f="yes" + else + if test "$u2f" = "yes"; then + feature_not_found "u2f" "Install u2f-emu" + fi + u2f="no" + fi +fi + # check for libusb if test "$libusb" != "no" ; then if $pkg_config --atleast-version=1.0.13 libusb-1.0; then @@ -7166,6 +7186,12 @@ if test "$smartcard" = "yes" ; then echo "SMARTCARD_LIBS=$libcacard_libs" >> $config_host_mak fi +if test "$u2f" = "yes" ; then + echo "CONFIG_U2F=y" >> $config_host_mak + echo "U2F_CFLAGS=$u2f_emu_cflags" >> $config_host_mak + echo "U2F_LIBS=$u2f_emu_libs" >> $config_host_mak +fi + if test "$libusb" = "yes" ; then echo "CONFIG_USB_LIBUSB=y" >> $config_host_mak echo "LIBUSB_CFLAGS=$libusb_cflags" >> $config_host_mak From patchwork Mon Aug 24 11:48:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9sar_Belley?= X-Patchwork-Id: 275736 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4BC6C433E1 for ; Mon, 24 Aug 2020 11:54:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 38CE7206BE for ; Mon, 24 Aug 2020 11:54:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=lse.epita.fr header.i=@lse.epita.fr header.b="YeItsgd2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 38CE7206BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lse.epita.fr Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:55120 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kAB3M-00049Z-HS for qemu-devel@archiver.kernel.org; Mon, 24 Aug 2020 07:54:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51502) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyi-00032H-8t for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:32 -0400 Received: from gate-2.cri.epita.net ([163.5.55.20]:54846 helo=mail-2.srv.cri.epita.fr) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyg-0003dt-BR for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:31 -0400 Received: from MattGorko-Laptop.home (lfbn-idf1-1-1395-83.w90-79.abo.wanadoo.fr [90.79.87.83]) (Authenticated sender: cesar.belley) by mail-2.srv.cri.epita.fr (Postfix) with ESMTPSA id 1ABAA410E0; Mon, 24 Aug 2020 13:49:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lse.epita.fr; s=cri; t=1598269759; bh=WhUfeKytyuCUL59PtsGUkPGPstr2XF/LWbWzGaMaN3Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YeItsgd22twBRUg/HkerPoW2IZYPNuc4HQ5DCvjNP9tEBBR04LNpjvm1J0ILns4hu J8BTCeSe6u/KF1LN2mMG02bZbcQjBnwEKwveBB11J/DRO0hLNg7XgJKTNu6YnaboKZ QqP5Oe/7EyM6X/wYcHsC+d2JtYrvKssTD7+PjCoo= From: =?utf-8?q?C=C3=A9sar_Belley?= To: qemu-devel@nongnu.org Subject: [PATCH v2 11/13] scripts: Add u2f-setup-gen script Date: Mon, 24 Aug 2020 13:48:25 +0200 Message-Id: <20200824114827.81623-12-cesar.belley@lse.epita.fr> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200824114827.81623-1-cesar.belley@lse.epita.fr> References: <20200824114827.81623-1-cesar.belley@lse.epita.fr> MIME-Version: 1.0 Received-SPF: pass client-ip=163.5.55.20; envelope-from=srs0=45nv=cc=lse.epita.fr=cesar.belley@cri.epita.fr; helo=mail-2.srv.cri.epita.fr X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/24 07:49:04 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9sar_Belley?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This patch adds the script used to generate setup directories, needed for the device u2f-emulated configuration in directory mode: python u2f-setup-gen.py $DIR qemu -usb -device u2f-emulated,dir=$DIR Signed-off-by: César Belley --- scripts/u2f-setup-gen.py | 170 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100755 scripts/u2f-setup-gen.py diff --git a/scripts/u2f-setup-gen.py b/scripts/u2f-setup-gen.py new file mode 100755 index 0000000000..2122598fed --- /dev/null +++ b/scripts/u2f-setup-gen.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# +# Libu2f-emu setup directory generator for USB U2F key emulation. +# +# Copyright (c) 2020 César Belley +# Written by César Belley +# +# This work is licensed under the terms of the GNU GPL, version 2 +# or, at your option, any later version. See the COPYING file in +# the top-level directory. + +import sys +import os +from random import randint +from typing import Tuple + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.serialization import Encoding, \ + NoEncryption, PrivateFormat, PublicFormat +from OpenSSL import crypto + + +def write_setup_dir(dirpath: str, privkey_pem: bytes, cert_pem: bytes, + entropy: bytes, counter: int) -> None: + """ + Write the setup directory. + + Args: + dirpath: The directory path. + key_pem: The private key PEM. + cert_pem: The certificate PEM. + entropy: The 48 bytes of entropy. + counter: The counter value. + """ + # Directory + os.mkdir(dirpath) + + # Private key + with open(f'{dirpath}/private-key.pem', 'bw') as f: + f.write(privkey_pem) + + # Certificate + with open(f'{dirpath}/certificate.pem', 'bw') as f: + f.write(cert_pem) + + # Entropy + with open(f'{dirpath}/entropy', 'wb') as f: + f.write(entropy) + + # Counter + with open(f'{dirpath}/counter', 'w') as f: + f.write(f'{str(counter)}\n') + + +def generate_ec_key_pair() -> Tuple[str, str]: + """ + Generate an ec key pair. + + Returns: + The private and public key PEM. + """ + # Key generation + privkey = ec.generate_private_key(ec.SECP256R1, default_backend()) + pubkey = privkey.public_key() + + # PEM serialization + privkey_pem = privkey.private_bytes(encoding=Encoding.PEM, + format=PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=NoEncryption()) + pubkey_pem = pubkey.public_bytes(encoding=Encoding.PEM, + format=PublicFormat.SubjectPublicKeyInfo) + return privkey_pem, pubkey_pem + + +def generate_certificate(privkey_pem: str, pubkey_pem: str) -> str: + """ + Generate a x509 certificate from a key pair. + + Args: + privkey_pem: The private key PEM. + pubkey_pem: The public key PEM. + + Returns: + The certificate PEM. + """ + # Convert key pair + privkey = crypto.load_privatekey(crypto.FILETYPE_PEM, privkey_pem) + pubkey = crypto.load_publickey(crypto.FILETYPE_PEM, pubkey_pem) + + # New x509v3 certificate + cert = crypto.X509() + cert.set_version(0x2) + + # Serial number + cert.set_serial_number(randint(1, 2 ** 64)) + + # Before / After + cert.gmtime_adj_notBefore(0) + cert.gmtime_adj_notAfter(4 * (365 * 24 * 60 * 60)) + + # Public key + cert.set_pubkey(pubkey) + + # Subject name and issueer + cert.get_subject().CN = "U2F emulated" + cert.set_issuer(cert.get_subject()) + + # Extensions + cert.add_extensions([ + crypto.X509Extension(b"subjectKeyIdentifier", + False, b"hash", subject=cert), + ]) + cert.add_extensions([ + crypto.X509Extension(b"authorityKeyIdentifier", + False, b"keyid:always", issuer=cert), + ]) + cert.add_extensions([ + crypto.X509Extension(b"basicConstraints", True, b"CA:TRUE") + ]) + + # Signature + cert.sign(privkey, 'sha256') + + return crypto.dump_certificate(crypto.FILETYPE_PEM, cert) + + +def generate_setup_dir(dirpath: str) -> None: + """ + Generates the setup directory. + + Args: + dirpath: The directory path. + """ + # Key pair + privkey_pem, pubkey_pem = generate_ec_key_pair() + + # Certificate + certificate_pem = generate_certificate(privkey_pem, pubkey_pem) + + # Entropy + entropy = os.urandom(48) + + # Counter + counter = 0 + + # Write + write_setup_dir(dirpath, privkey_pem, certificate_pem, entropy, counter) + + +def main() -> None: + """ + Main function + """ + # Dir path + if len(sys.argv) != 2: + sys.stderr.write(f'Usage: {sys.argv[0]} \n') + exit(2) + dirpath = sys.argv[1] + + # Dir non existence + if os.path.exists(dirpath): + sys.stderr.write(f'Directory: {dirpath} already exists.\n') + exit(1) + + generate_setup_dir(dirpath) + + +if __name__ == '__main__': + main() From patchwork Mon Aug 24 11:48:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9sar_Belley?= X-Patchwork-Id: 275735 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 521F8C433DF for ; Mon, 24 Aug 2020 11:55:49 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 15BFF20706 for ; Mon, 24 Aug 2020 11:55:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=lse.epita.fr header.i=@lse.epita.fr header.b="DoKDykgc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 15BFF20706 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lse.epita.fr Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:59536 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kAB4m-0005zM-Bl for qemu-devel@archiver.kernel.org; Mon, 24 Aug 2020 07:55:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51522) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyj-00034n-V2 for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:33 -0400 Received: from gate-2.cri.epita.net ([163.5.55.20]:54860 helo=mail-2.srv.cri.epita.fr) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kAAyh-0003eF-H4 for qemu-devel@nongnu.org; Mon, 24 Aug 2020 07:49:33 -0400 Received: from MattGorko-Laptop.home (lfbn-idf1-1-1395-83.w90-79.abo.wanadoo.fr [90.79.87.83]) (Authenticated sender: cesar.belley) by mail-2.srv.cri.epita.fr (Postfix) with ESMTPSA id 3FEA53FAC7; Mon, 24 Aug 2020 13:49:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lse.epita.fr; s=cri; t=1598269760; bh=hKpGvvq0chDFquaLVg/SoDp2sQXaURAZyryEMSCPX1s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DoKDykgc0fzo8vagx/A3/0KCHvGmVGNK/HApubrJyHavgexBd6LYGfTQWRvOPc6VC GyE1wauhTPPj4QgGqML1191jV2bo+pf3MiDCyAuvnDyptGrYp0Jh3E2aFyK7YF9y6X HxzDWu3QvfNJvWwzqKz3gBNGlPRfhYvY1grCSpUU= From: =?utf-8?q?C=C3=A9sar_Belley?= To: qemu-devel@nongnu.org Subject: [PATCH v2 13/13] hw/usb: Add U2F device autoscan to passthru mode Date: Mon, 24 Aug 2020 13:48:27 +0200 Message-Id: <20200824114827.81623-14-cesar.belley@lse.epita.fr> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200824114827.81623-1-cesar.belley@lse.epita.fr> References: <20200824114827.81623-1-cesar.belley@lse.epita.fr> MIME-Version: 1.0 Received-SPF: pass client-ip=163.5.55.20; envelope-from=srs0=45nv=cc=lse.epita.fr=cesar.belley@cri.epita.fr; helo=mail-2.srv.cri.epita.fr X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/24 07:49:04 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9sar_Belley?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: César Belley --- docs/u2f.txt | 9 ++++ hw/usb/meson.build | 2 +- hw/usb/u2f-passthru.c | 113 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 110 insertions(+), 14 deletions(-) diff --git a/docs/u2f.txt b/docs/u2f.txt index f60052882e..8f44994818 100644 --- a/docs/u2f.txt +++ b/docs/u2f.txt @@ -42,6 +42,10 @@ on libu2f-emu: configuring and building: ./configure --enable-u2f && make +The pass-through mode is built by default on Linux. To take advantage +of the autoscan option it provides, make sure you have a working libudev +installed on the host. + 3. Using u2f-emulated @@ -90,6 +94,11 @@ On the host specify the u2f-passthru device with a suitable hidraw: qemu -usb -device u2f-passthru,hidraw=/dev/hidraw0 +Alternately, the u2f-passthru device can autoscan to take the first +U2F device it finds on the host (this requires a working libudev): + + qemu -usb -device u2f-passthru + 5. Libu2f-emu diff --git a/hw/usb/meson.build b/hw/usb/meson.build index cac7639924..40c283ceb5 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -52,7 +52,7 @@ endif # U2F softmmu_ss.add(when: 'CONFIG_USB_U2F', if_true: files('u2f.c')) -softmmu_ss.add(when: ['CONFIG_LINUX', 'CONFIG_USB_U2F'], if_true: files('u2f-passthru.c')) +softmmu_ss.add(when: ['CONFIG_LINUX', 'CONFIG_USB_U2F'], if_true: [libudev, files('u2f-passthru.c')]) softmmu_ss.add(when: ['CONFIG_U2F', 'CONFIG_USB_U2F'], if_true: [u2f, files('u2f-emulated.c')]) # usb redirect diff --git a/hw/usb/u2f-passthru.c b/hw/usb/u2f-passthru.c index f8771966c7..1311530ee5 100644 --- a/hw/usb/u2f-passthru.c +++ b/hw/usb/u2f-passthru.c @@ -378,6 +378,84 @@ static bool u2f_passthru_is_u2f_device(int fd) sizeof(u2f_hid_report_desc_header)) == 0; } +#ifdef CONFIG_LIBUDEV +static int u2f_passthru_open_from_device(struct udev_device *device) +{ + const char *devnode = udev_device_get_devnode(device); + + int fd = qemu_open(devnode, O_RDWR); + if (fd < 0) { + return -1; + } else if (!u2f_passthru_is_u2f_device(fd)) { + qemu_close(fd); + return -1; + } + return fd; +} + +static int u2f_passthru_open_from_enumerate(struct udev *udev, + struct udev_enumerate *enumerate) +{ + struct udev_list_entry *devices, *entry; + int ret, fd; + + ret = udev_enumerate_scan_devices(enumerate); + if (ret < 0) { + return -1; + } + + devices = udev_enumerate_get_list_entry(enumerate); + udev_list_entry_foreach(entry, devices) { + struct udev_device *device; + const char *syspath = udev_list_entry_get_name(entry); + + if (syspath == NULL) { + continue; + } + + device = udev_device_new_from_syspath(udev, syspath); + if (device == NULL) { + continue; + } + + fd = u2f_passthru_open_from_device(device); + udev_device_unref(device); + if (fd >= 0) { + return fd; + } + } + return -1; +} + +static int u2f_passthru_open_from_scan(void) +{ + struct udev *udev; + struct udev_enumerate *enumerate; + int ret, fd = -1; + + udev = udev_new(); + if (udev == NULL) { + return -1; + } + + enumerate = udev_enumerate_new(udev); + if (enumerate == NULL) { + udev_unref(udev); + return -1; + } + + ret = udev_enumerate_add_match_subsystem(enumerate, "hidraw"); + if (ret >= 0) { + fd = u2f_passthru_open_from_enumerate(udev, enumerate); + } + + udev_enumerate_unref(enumerate); + udev_unref(udev); + + return fd; +} +#endif + static void u2f_passthru_unrealize(U2FKeyState *base) { U2FPassthruState *key = PASSTHRU_U2F_KEY(base); @@ -392,22 +470,31 @@ static void u2f_passthru_realize(U2FKeyState *base, Error **errp) int fd; if (key->hidraw == NULL) { +#ifdef CONFIG_LIBUDEV + fd = u2f_passthru_open_from_scan(); + if (fd < 0) { + error_setg(errp, "%s: Failed to find a U2F USB device", + TYPE_U2F_PASSTHRU); + return; + } +#else error_setg(errp, "%s: Missing hidraw", TYPE_U2F_PASSTHRU); return; - } - - fd = qemu_open(key->hidraw, O_RDWR); - if (fd < 0) { - error_setg(errp, "%s: Failed to open %s", TYPE_U2F_PASSTHRU, - key->hidraw); - return; - } +#endif + } else { + fd = qemu_open(key->hidraw, O_RDWR); + if (fd < 0) { + error_setg(errp, "%s: Failed to open %s", TYPE_U2F_PASSTHRU, + key->hidraw); + return; + } - if (!u2f_passthru_is_u2f_device(fd)) { - qemu_close(fd); - error_setg(errp, "%s: Passed hidraw does not represent " - "a U2F HID device", TYPE_U2F_PASSTHRU); - return; + if (!u2f_passthru_is_u2f_device(fd)) { + qemu_close(fd); + error_setg(errp, "%s: Passed hidraw does not represent " + "a U2F HID device", TYPE_U2F_PASSTHRU); + return; + } } key->hidraw_fd = fd; u2f_passthru_reset(key);