From patchwork Thu Jan 14 16:01:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Berger X-Patchwork-Id: 8033871 Return-Path: X-Original-To: patchwork-tpmdd-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 915E0BEEE5 for ; Thu, 14 Jan 2016 16:02:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 78B1120457 for ; Thu, 14 Jan 2016 16:02:32 +0000 (UTC) Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6F31A2042B for ; Thu, 14 Jan 2016 16:02:28 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=sfs-ml-4.v29.ch3.sourceforge.com) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1aJkLw-0001Fk-Kj; Thu, 14 Jan 2016 16:02:24 +0000 Received: from sog-mx-2.v43.ch3.sourceforge.com ([172.29.43.192] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1aJkLv-0001Fe-7A for tpmdd-devel@lists.sourceforge.net; Thu, 14 Jan 2016 16:02:23 +0000 Received-SPF: pass (sog-mx-2.v43.ch3.sourceforge.com: domain of us.ibm.com designates 32.97.110.149 as permitted sender) client-ip=32.97.110.149; envelope-from=stefanb@us.ibm.com; helo=e31.co.us.ibm.com; Received: from e31.co.us.ibm.com ([32.97.110.149]) by sog-mx-2.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1aJkLt-0003Qs-RD for tpmdd-devel@lists.sourceforge.net; Thu, 14 Jan 2016 16:02:23 +0000 Received: from localhost by e31.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 14 Jan 2016 09:02:15 -0700 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) by e31.co.us.ibm.com (192.168.1.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 14 Jan 2016 09:02:13 -0700 X-IBM-Helo: d03dlp03.boulder.ibm.com X-IBM-MailFrom: stefanb@us.ibm.com X-IBM-RcptTo: tpmdd-devel@lists.sourceforge.net Received: from b01cxnp22033.gho.pok.ibm.com (b01cxnp22033.gho.pok.ibm.com [9.57.198.23]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id 5058D19D804E for ; Thu, 14 Jan 2016 08:50:14 -0700 (MST) Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u0EG2Cf928639276 for ; Thu, 14 Jan 2016 16:02:12 GMT Received: from d01av01.pok.ibm.com (localhost [127.0.0.1]) by d01av01.pok.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u0EG2BZU013264 for ; Thu, 14 Jan 2016 11:02:12 -0500 Received: from sbct-3.watson.ibm.com (sbct-3.watson.ibm.com [9.2.141.158]) by d01av01.pok.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u0EG21A3011081; Thu, 14 Jan 2016 11:02:02 -0500 From: Stefan Berger To: tpmdd-devel@lists.sourceforge.net Date: Thu, 14 Jan 2016 11:01:58 -0500 Message-Id: <1452787318-29610-5-git-send-email-stefanb@us.ibm.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1452787318-29610-1-git-send-email-stefanb@us.ibm.com> References: <1452787318-29610-1-git-send-email-stefanb@us.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16011416-8236-0000-0000-0000152E708B X-Spam-Score: -1.5 (-) X-Headers-End: 1aJkLt-0003Qs-RD Cc: dhowells@redhat.com, dwmw2@infradead.org Subject: [tpmdd-devel] [RFC PATCH 4/4] A test program for vTPM device creation X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: tpmdd-devel-bounces@lists.sourceforge.net X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, HK_RANDOM_ENVFROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stefan Berger This provides a test program for testing the creation of vTPM device pairs. Build it using the following commands: make headers_install ARCH=x86_64 INSTALL_HDR_PATH=/usr gcc vtpmctrl.c -o vtpmctrl To use it: # to create a device pair: ./vtpmctrl create # to find the name of the other device give the name of one device ./vtpmctrl find /dev/vtpms0 # to destroy a device pair given one device name ./vtpmctrl destroy /dev/vtpms0 Signed-off-by: Stefan Berger --- vtpmctrl.c | 369 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 vtpmctrl.c diff --git a/vtpmctrl.c b/vtpmctrl.c new file mode 100644 index 0000000..883df72 --- /dev/null +++ b/vtpmctrl.c @@ -0,0 +1,369 @@ +/* + * vtpmctrl.c -- Linux vTPM driver control program + * + * (c) Copyright IBM Corporation 2015. + * + * Author: Stefan Berger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the names of the IBM Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void vtpmctrl_create_usage(const char *prgname) +{ + fprintf(stderr, +"Usage: %s create [options]\n" +"\n" +"Create a client server device pair." +"\n" +"The following options are supported\n" +"\n" +"-k|--keep : Keep the device pair after the vTPM closes access to the\n" +" device; by default the device is closed.\n" +"-h|--help : Display this help screen and exit.\n" +"\n", prgname); +} + +int vtpmctrl_create(int argc, char *argv[], const char *prgname) +{ + int fd, n; + struct vtpm_new_pair vtpm_new_pair = { + .flags = 0, + }; + char tpmdev[VTPM_DEVNAME_MAX + 5]; + char vtpmdev[VTPM_DEVNAME_MAX + 5]; + const struct option longOpts[] = { + {"keep", no_argument, NULL, 'k'}, + {"help", no_argument, NULL, 'h'}, + {NULL , 0, 0, 0 }, + }; + int option, li; + + while ((option = getopt_long(argc, argv, "kh", longOpts, &li)) >= 0) { + switch (option) { + case 'k': + vtpm_new_pair.flags |= VTPM_FLAG_KEEP_DEVPAIR; + break; + case 'h': + vtpmctrl_create_usage(prgname); + return 0; + default: + vtpmctrl_create_usage(prgname); + return 1; + } + } + + fd = open("/dev/vtpmx", O_RDWR); + if (fd < 0) { + perror("Could not open /dev/vtpmx"); + return 1; + } + + n = ioctl(fd, VTPM_NEW_DEV, &vtpm_new_pair); + if (n != 0) { + perror("ioctl to create dev pair failed"); + close(fd); + return 1; + } + + snprintf(tpmdev, sizeof(tpmdev), "/dev/" VTPM_DEV_PREFIX_CLIENT"%u", + vtpm_new_pair.tpm_dev_num); + snprintf(vtpmdev, sizeof(vtpmdev), "/dev/" VTPM_DEV_PREFIX_SERVER"%u", + vtpm_new_pair.vtpm_dev_num); + + printf("Created TPM device %s and vTPM device %s.\n", + tpmdev, vtpmdev); + + close(fd); + + return 0; +} + +int copy_devname(char *dest, size_t size, const char *devname) +{ + int n; + + n = snprintf(dest, size, "%s", devname); + if (n >= size) { + fprintf(stderr, "Device name %s is too long.\n", devname); + return 1; + } + + return 0; +} + +void vtpmctrl_destroy_usage(const char *prgname) +{ + fprintf(stderr, +"Usage: %s destroy [options]\n" +"\n" +"Destroy a client server device pair by providing the name of one of\n" +"the devices.\n" +"\n" +"The following options are supported\n" +"\n" +"-h|--help : Display this help screen and exit.\n" +"\n", prgname); +} + +int fill_vtpm_pair(struct vtpm_pair *vtpm_pair, const char *devname) +{ + unsigned int offset = 0, num; + int n; + + if (!strncmp("/dev/", devname, 5)) + offset = 5; + + if (!strncmp(&devname[offset], VTPM_DEV_PREFIX_SERVER, + strlen(VTPM_DEV_PREFIX_SERVER))) { + offset += strlen(VTPM_DEV_PREFIX_SERVER); + if (sscanf(&devname[offset], "%u", &num) != 1) { + fprintf(stderr, "Could not parse %s as vTPM " + "device.\n", devname); + return -1; + } + vtpm_pair->tpm_dev_num = VTPM_DEV_NUM_INVALID; + vtpm_pair->vtpm_dev_num = num; + return 0; + } else if (!strncmp(&devname[offset], VTPM_DEV_PREFIX_CLIENT, + strlen(VTPM_DEV_PREFIX_CLIENT))) { + offset += strlen(VTPM_DEV_PREFIX_CLIENT); + if (sscanf(&devname[offset], "%u", &num) != 1) { + fprintf(stderr, "Could not parse %s as vTPM " + "device.\n", devname); + return -1; + } + vtpm_pair->tpm_dev_num = num; + vtpm_pair->vtpm_dev_num = VTPM_DEV_NUM_INVALID; + return 0; + } + fprintf(stderr , "Could not parse %s.\n", devname); + + return -1; +} + +int vtpmctrl_destroy(int argc, char *argv[], const char *prgname) +{ + int fd = -1, n; + struct vtpm_pair vtpm_pair; + const char *devname; + unsigned offset = 0; + size_t size; + const struct option longOpts[] = { + {"help", no_argument, NULL, 'h'}, + {NULL , 0, 0, 0 }, + }; + int option, li; + + while ((option = getopt_long(argc, argv, "h", longOpts, &li)) >= 0) { + switch (option) { + case 'h': + vtpmctrl_destroy_usage(prgname); + return 0; + default: + vtpmctrl_destroy_usage(prgname); + return 1; + } + } + + if (argc < 2) { + fprintf(stderr, "Missing device name parameter.\n"); + vtpmctrl_destroy_usage(prgname); + goto err_exit; + } + + devname = argv[1]; + + fd = open("/dev/vtpmx", O_RDWR); + if (fd < 0) { + perror("Could not open /dev/vtpmx"); + goto err_exit; + } + + if (fill_vtpm_pair(&vtpm_pair, devname) < 0) + goto err_exit; + + n = ioctl(fd, VTPM_DEL_DEV, &vtpm_pair); + if (n != 0) { + fprintf(stderr, "Could not delete device pair.\n"); + goto err_exit; + } + + fprintf(stdout, "Successfully deleted device pair.\n"); + + close(fd); + + return 0; + +err_exit: + if (fd >= 0) + close(fd); + return 1; +} + +void vtpmctrl_find_usage(const char *prgname) +{ + fprintf(stderr, +"Usage: %s find [options]\n" +"\n" +"Given one device name, determine the name of the other one.\n" +"\n" +"The following options are supported\n" +"\n" +"-h|--help : Display this help screen and exit.\n" +"\n", prgname); +} + +int vtpmctrl_find(int argc, char *argv[], const char *prgname) +{ + int fd = -1, n; + struct vtpm_pair vtpm_pair; + const char *devname; + unsigned offset = 0; + size_t size; + const struct option longOpts[] = { + {"help", no_argument, NULL, 'h'}, + {NULL , 0, 0, 0 }, + }; + int option, li; + char tpmdev[VTPM_DEVNAME_MAX + 5]; + + while ((option = getopt_long(argc, argv, "h", longOpts, &li)) >= 0) { + switch (option) { + case 'h': + vtpmctrl_find_usage(prgname); + return 0; + + default: + vtpmctrl_find_usage(prgname); + return 1; + } + } + + if (argc < 2) { + fprintf(stderr, "Missing device name parameter.\n"); + vtpmctrl_destroy_usage(prgname); + goto err_exit; + } + + devname = argv[1]; + + fd = open("/dev/vtpmx", O_RDWR); + if (fd < 0) { + perror("Could not open /dev/vtpmx"); + goto err_exit; + } + + if (fill_vtpm_pair(&vtpm_pair, devname) < 0) + goto err_exit; + + if (vtpm_pair.tpm_dev_num != VTPM_DEV_NUM_INVALID) { + n = ioctl(fd, VTPM_GET_VTPMDEV, &vtpm_pair); + if (n != 0) { + fprintf(stderr, "Could not find the other device of the device pair.\n"); + goto err_exit; + } else { + snprintf(tpmdev, sizeof(tpmdev), "/dev/"VTPM_DEV_PREFIX_SERVER"%u", + vtpm_pair.vtpm_dev_num); + fprintf(stdout, "The name of the vTPM device is: %s\n", tpmdev); + } + } else { + n = ioctl(fd, VTPM_GET_TPMDEV, &vtpm_pair); + if (n != 0) { + fprintf(stderr, "Could not find the other device of the device pair.\n"); + goto err_exit; + } else { + snprintf(tpmdev, sizeof(tpmdev), "/dev/"VTPM_DEV_PREFIX_CLIENT"%u", + vtpm_pair.tpm_dev_num); + fprintf(stdout, "The name of the TPM device is: %s\n", tpmdev); + } + } + + + close(fd); + + return 0; + +err_exit: + if (fd >= 0) + close(fd); + return 1; +} + +void main_usage(const char *prgname) +{ + fprintf(stdout, +"Usage: %s [command] [options]\n" +"\n" +"Control vTPM devices.\n" +"\n" +"The following commands are supported.\n" +"\n" +"create : Create device pairs\n" +"destroy : Destroy device pairs\n" +"find : Find the names of device pairs\n" +"\n" +"Consult the help screens of the individual commands for supported options.\n" +"\n" +, prgname); +} + +int main(int argc, char *argv[]) +{ + + if (argc < 2) { + fprintf(stderr, "Missing command parameter.\n"); + return 1; + } + + if (!strcmp(argv[1], "create")) { + return vtpmctrl_create(argc - 1, &argv[1], argv[0]); + } else if (!strcmp(argv[1], "destroy")) { + return vtpmctrl_destroy(argc - 1, &argv[1], argv[0]); + } else if (!strcmp(argv[1], "find")) { + return vtpmctrl_find(argc - 1, &argv[1], argv[0]); + } else { + fprintf(stderr, "Unsupported command.\n\n"); + main_usage(argv[0]); + return 1; + } +}