Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f4219dd authored by Viresh Kumar's avatar Viresh Kumar Committed by Alex Elder
Browse files

greybus: Documentation: Document Authentication interfaces



This patch defined userspace interface of the CAP protocol.

Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: default avatarJun Li <li_jun@projectara.com>
Tested-by: default avatarJun Li <li_jun@projectara.com>
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
parent e3eda54d
Loading
Loading
Loading
Loading
+139 −0
Original line number Diff line number Diff line
/*
 * Sample code to test CAP protocol
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * Copyright(c) 2016 Google Inc. All rights reserved.
 * Copyright(c) 2016 Linaro Ltd. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details.
 *
 * BSD LICENSE
 *
 * Copyright(c) 2016 Google Inc. All rights reserved.
 * Copyright(c) 2016 Linaro Ltd. 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 name of Google Inc. or Linaro Ltd. 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 GOOGLE INC. OR
 * LINARO LTD. 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 <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "../../greybus_authentication.h"

struct cap_ioc_get_endpoint_uid uid;
struct cap_ioc_get_ims_certificate cert = {
	.certificate_class = 0,
	.certificate_id = 0,
};

struct cap_ioc_authenticate authenticate = {
	.auth_type = 0,
	.challenge = {0},
};

int main(int argc, char *argv[])
{
	unsigned int timeout = 10000;
	char *capdev;
	int fd, ret;

	/* Make sure arguments are correct */
	if (argc != 2) {
		printf("\nUsage: ./firmware <Path of the gb-cap-X dev>\n");
		return 0;
	}

	capdev = argv[1];

	printf("Opening %s authentication device\n", capdev);

	fd = open(capdev, O_RDWR);
	if (fd < 0) {
		printf("Failed to open: %s\n", capdev);
		return -1;
	}

	/* Get UID */
	printf("Get UID\n");

	ret = ioctl(fd, CAP_IOC_GET_ENDPOINT_UID, &uid);
	if (ret < 0) {
		printf("Failed to get UID: %s (%d)\n", capdev, ret);
		ret = -1;
		goto close_fd;
	}

	printf("UID received: 0x%llx\n", *(long long unsigned int *)(uid.uid));

	/* Get certificate */
	printf("Get IMS certificate\n");

	ret = ioctl(fd, CAP_IOC_GET_IMS_CERTIFICATE, &cert);
	if (ret < 0) {
		printf("Failed to get IMS certificate: %s (%d)\n", capdev, ret);
		ret = -1;
		goto close_fd;
	}

	printf("IMS Certificate size: %d\n", cert.cert_size);

	/* Authenticate */
	printf("Authenticate module\n");

	memcpy(authenticate.uid, uid.uid, 8);

	ret = ioctl(fd, CAP_IOC_AUTHENTICATE, &authenticate);
	if (ret < 0) {
		printf("Failed to authenticate module: %s (%d)\n", capdev, ret);
		ret = -1;
		goto close_fd;
	}

	printf("Authenticated, result (%02x), sig-size (%02x)\n",
		authenticate.result_code, authenticate.signature_size);

close_fd:
	close(fd);

	return ret;
}
+130 −4
Original line number Diff line number Diff line
@@ -40,8 +40,7 @@ may look like:
	; (Optional) Component Authentication Protocol (CAP) on CPort 4
	[cport-descriptor 4]
	bundle = 1
	protocol = 0xXX //TBD

	protocol = 0x19


Sysfs Interfaces - Firmware Management
@@ -164,6 +163,129 @@ struct fw_mgmt_ioc_backend_fw_update {
   allow mode-switch.


Sysfs Interfaces - Authentication
---------------------------------

The Component Authentication Protocol interacts with Userspace using the
character device interface. The character device will be present in /dev/
directory and will be named gb-authenticate-<N>. The number <N> is assigned at
runtime.

Identifying the Character Device
================================

There can be multiple devices present in /dev/ directory with name
gb-authenticate-N and user first needs to identify the character device used for
authentication a of particular interface.

The Authentication core creates a device of class 'gb_authenticate', which shall
be used by the user to identify the right character device for it. The class
device is created within the Bundle directory for a particular Interface.

For example this is how the class-device can be present:

/sys/bus/greybus/devices/1-1/1-1.1/1-1.1.1/gb_authenticate/gb-authenticate-0

The last name in this path: gb-authenticate-0 is precisely the name of the char
device and so the device in this case will be:

/dev/gb-authenticate-0.

Operations on the Char device
=============================

The Character device (/dev/gb-authenticate-0 in above example) can be opened by
the userspace application and it can perform various 'ioctl' operations on the
device. The device doesn't support any read/write operations.

Following are the IOCTLs and their data structures available to the user:

#define CAP_CERTIFICATE_MAX_SIZE	1600
#define CAP_SIGNATURE_MAX_SIZE		320

/* Certificate class types */
#define CAP_CERT_IMS_EAPC		0x00000001
#define CAP_CERT_IMS_EASC		0x00000002
#define CAP_CERT_IMS_EARC		0x00000003
#define CAP_CERT_IMS_IAPC		0x00000004
#define CAP_CERT_IMS_IASC		0x00000005
#define CAP_CERT_IMS_IARC		0x00000006

/* IMS Certificate response result codes */
#define CAP_IMS_RESULT_CERT_FOUND	0x00
#define CAP_IMS_RESULT_CERT_CLASS_INVAL	0x01
#define CAP_IMS_RESULT_CERT_CORRUPT	0x02
#define CAP_IMS_RESULT_CERT_NOT_FOUND	0x03

/* Authentication types */
#define CAP_AUTH_IMS_PRI		0x00000001
#define CAP_AUTH_IMS_SEC		0x00000002
#define CAP_AUTH_IMS_RSA		0x00000003

/* Authenticate response result codes */
#define CAP_AUTH_RESULT_CR_SUCCESS	0x00
#define CAP_AUTH_RESULT_CR_BAD_TYPE	0x01
#define CAP_AUTH_RESULT_CR_WRONG_EP	0x02
#define CAP_AUTH_RESULT_CR_NO_KEY	0x03
#define CAP_AUTH_RESULT_CR_SIG_FAIL	0x04


/* IOCTL support */
struct cap_ioc_get_endpoint_uid {
	__u8			uid[8];
} __attribute__ ((__packed__));

struct cap_ioc_get_ims_certificate {
	__u32			certificate_class;
	__u32			certificate_id;

	__u8			result_code;
	__u32			cert_size;
	__u8			certificate[CAP_CERTIFICATE_MAX_SIZE];
} __attribute__ ((__packed__));

struct cap_ioc_authenticate {
	__u32			auth_type;
	__u8			uid[8];
	__u8			challenge[32];

	__u8			result_code;
	__u8			response[64];
	__u32			signature_size;
	__u8			signature[CAP_SIGNATURE_MAX_SIZE];
} __attribute__ ((__packed__));

#define CAP_IOCTL_BASE			'C'
#define CAP_IOC_GET_ENDPOINT_UID	_IOR(CAP_IOCTL_BASE, 0, struct cap_ioc_get_endpoint_uid)
#define CAP_IOC_GET_IMS_CERTIFICATE	_IOWR(CAP_IOCTL_BASE, 1, struct cap_ioc_get_ims_certificate)
#define CAP_IOC_AUTHENTICATE		_IOWR(CAP_IOCTL_BASE, 2, struct cap_ioc_authenticate)


1. CAP_IOC_GET_ENDPOINT_UID:

   This ioctl shall be used the user to get the endpoint UID associated with the
   Interface.  All the fields of the 'struct cap_ioc_get_endpoint_uid' are
   filled by the kernel.

2. CAP_IOC_GET_IMS_CERTIFICATE:

   This ioctl shall be used the user to retrieve one of the available
   cryptographic certificates held by the Interface for use in Component
   Authentication. The user is required to fill the 'certificate_class' and
   'certificate_id' field of the 'struct cap_ioc_get_ims_certificate' in this
   case. The other fields will be set by the kernel in response. The first
   'cert_size' bytes of the 'certificate' shall be read by the user and others
   must be discarded.

3. CAP_IOC_AUTHENTICATE:

   This ioctl shall be used the user to authenticate the Module attached to an
   Interface.  The user needs to fill the 'auth_type', 'uid', and 'challenge'
   fields of the 'struct cap_ioc_authenticate'. The other fields will be set by
   the kernel in response.  The first 'signature_size' bytes of the 'signature'
   shall be read by the user and others must be discarded.


Sysfs Interfaces - Firmware Download
------------------------------------

@@ -182,9 +304,13 @@ $ ls /sys/bus/greybus/devices/1-1/1-1.1/1-1.1.1/spi_master/spi32766/spi32766.0/m
mtd0    mtd0ro


Sample Application
------------------
Sample Applications
-------------------

The current directory also provides a firmware.c test application, which can be
referenced while developing userspace application to talk to firmware-management
protocol.

The current directory also provides a authenticate.c test application, which can
be referenced while developing userspace application to talk to
component authentication protocol.