Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

greybus: Add Component Authentication Protocol support

This patch adds Component Authentication Protocol support in greybus.
The purpose of the CAP protocol is to authenticate the Module hardware,
and it can only be used when it is present as part of the
firmware-management bundle, on a separate CPort.

Compile tested only.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Jun Li <li_jun@projectara.com>
Tested-by: Jun Li <li_jun@projectara.com>
Signed-off-by: Alex Elder <elder@linaro.org>

authored by

Viresh Kumar and committed by
Alex Elder
e3eda54d 80b3982b

+650 -4
+1 -1
drivers/staging/greybus/Makefile
··· 33 33 gb-audio-manager-y += audio_manager_module.o 34 34 gb-bootrom-y := bootrom.o 35 35 gb-camera-y := camera.o 36 - gb-firmware-y := fw-core.o fw-download.o fw-management.o 36 + gb-firmware-y := fw-core.o fw-download.o fw-management.o authentication.o 37 37 gb-spilib-y := spilib.o 38 38 gb-sdio-y := sdio.o 39 39 gb-uart-y := uart.o
+437
drivers/staging/greybus/authentication.c
··· 1 + /* 2 + * Greybus Component Authentication Protocol (CAP) Driver. 3 + * 4 + * Copyright 2016 Google Inc. 5 + * Copyright 2016 Linaro Ltd. 6 + * 7 + * Released under the GPLv2 only. 8 + */ 9 + 10 + #include "greybus.h" 11 + 12 + #include <linux/cdev.h> 13 + #include <linux/fs.h> 14 + #include <linux/ioctl.h> 15 + #include <linux/uaccess.h> 16 + 17 + #include "greybus_authentication.h" 18 + #include "firmware.h" 19 + #include "greybus.h" 20 + 21 + #define CAP_TIMEOUT_MS 1000 22 + 23 + /* 24 + * Number of minor devices this driver supports. 25 + * There will be exactly one required per Interface. 26 + */ 27 + #define NUM_MINORS U8_MAX 28 + 29 + struct gb_cap { 30 + struct device *parent; 31 + struct gb_connection *connection; 32 + struct kref kref; 33 + struct list_head node; 34 + bool disabled; /* connection getting disabled */ 35 + 36 + struct mutex mutex; 37 + struct cdev cdev; 38 + struct device *class_device; 39 + dev_t dev_num; 40 + }; 41 + 42 + static struct class *cap_class; 43 + static dev_t cap_dev_num; 44 + static DEFINE_IDA(cap_minors_map); 45 + static LIST_HEAD(cap_list); 46 + static DEFINE_MUTEX(list_mutex); 47 + 48 + static void cap_kref_release(struct kref *kref) 49 + { 50 + struct gb_cap *cap = container_of(kref, struct gb_cap, kref); 51 + 52 + kfree(cap); 53 + } 54 + 55 + /* 56 + * All users of cap take a reference (from within list_mutex lock), before 57 + * they get a pointer to play with. And the structure will be freed only after 58 + * the last user has put the reference to it. 59 + */ 60 + static void put_cap(struct gb_cap *cap) 61 + { 62 + kref_put(&cap->kref, cap_kref_release); 63 + } 64 + 65 + /* Caller must call put_cap() after using struct gb_cap */ 66 + static struct gb_cap *get_cap(struct cdev *cdev) 67 + { 68 + struct gb_cap *cap; 69 + 70 + mutex_lock(&list_mutex); 71 + 72 + list_for_each_entry(cap, &cap_list, node) { 73 + if (&cap->cdev == cdev) { 74 + kref_get(&cap->kref); 75 + goto unlock; 76 + } 77 + } 78 + 79 + cap = NULL; 80 + 81 + unlock: 82 + mutex_unlock(&list_mutex); 83 + 84 + return cap; 85 + } 86 + 87 + static int cap_get_endpoint_uid(struct gb_cap *cap, u8 *euid) 88 + { 89 + struct gb_connection *connection = cap->connection; 90 + struct gb_cap_get_endpoint_uid_response response; 91 + int ret; 92 + 93 + ret = gb_operation_sync(connection, GB_CAP_TYPE_GET_ENDPOINT_UID, NULL, 94 + 0, &response, sizeof(response)); 95 + if (ret) { 96 + dev_err(cap->parent, "failed to get endpoint uid (%d)\n", ret); 97 + return ret; 98 + } 99 + 100 + memcpy(euid, response.uid, sizeof(response.uid)); 101 + 102 + return 0; 103 + } 104 + 105 + static int cap_get_ims_certificate(struct gb_cap *cap, u32 class, u32 id, 106 + u8 *certificate, u32 *size, u8 *result) 107 + { 108 + struct gb_connection *connection = cap->connection; 109 + struct gb_cap_get_ims_certificate_request *request; 110 + struct gb_cap_get_ims_certificate_response *response; 111 + size_t max_size = gb_operation_get_payload_size_max(connection); 112 + struct gb_operation *op; 113 + int ret; 114 + 115 + op = gb_operation_create_flags(connection, 116 + GB_CAP_TYPE_GET_IMS_CERTIFICATE, 117 + sizeof(*request), max_size, 118 + GB_OPERATION_FLAG_SHORT_RESPONSE, 119 + GFP_KERNEL); 120 + if (!op) 121 + return -ENOMEM; 122 + 123 + request = op->request->payload; 124 + request->certificate_class = cpu_to_le32(class); 125 + request->certificate_id = cpu_to_le32(id); 126 + 127 + ret = gb_operation_request_send_sync(op); 128 + if (ret) { 129 + dev_err(cap->parent, "failed to get certificate (%d)\n", ret); 130 + goto done; 131 + } 132 + 133 + response = op->response->payload; 134 + *result = response->result_code; 135 + *size = op->response->payload_size - sizeof(*response); 136 + memcpy(certificate, response->certificate, *size); 137 + 138 + done: 139 + gb_operation_put(op); 140 + return ret; 141 + } 142 + 143 + static int cap_authenticate(struct gb_cap *cap, u32 auth_type, u8 *uid, 144 + u8 *challenge, u8 *result, u8 *auth_response, 145 + u32 *signature_size, u8 *signature) 146 + { 147 + struct gb_connection *connection = cap->connection; 148 + struct gb_cap_authenticate_request *request; 149 + struct gb_cap_authenticate_response *response; 150 + size_t max_size = gb_operation_get_payload_size_max(connection); 151 + struct gb_operation *op; 152 + int ret; 153 + 154 + op = gb_operation_create_flags(connection, GB_CAP_TYPE_AUTHENTICATE, 155 + sizeof(*request), max_size, 156 + GB_OPERATION_FLAG_SHORT_RESPONSE, 157 + GFP_KERNEL); 158 + if (!op) 159 + return -ENOMEM; 160 + 161 + request = op->request->payload; 162 + request->auth_type = cpu_to_le32(auth_type); 163 + memcpy(request->uid, uid, sizeof(request->uid)); 164 + memcpy(request->challenge, challenge, sizeof(request->challenge)); 165 + 166 + ret = gb_operation_request_send_sync(op); 167 + if (ret) { 168 + dev_err(cap->parent, "failed to authenticate (%d)\n", ret); 169 + goto done; 170 + } 171 + 172 + response = op->response->payload; 173 + *result = response->result_code; 174 + *signature_size = op->response->payload_size - sizeof(*response); 175 + memcpy(auth_response, response->response, sizeof(response->response)); 176 + memcpy(signature, response->signature, *signature_size); 177 + 178 + done: 179 + gb_operation_put(op); 180 + return ret; 181 + } 182 + 183 + /* Char device fops */ 184 + 185 + static int cap_open(struct inode *inode, struct file *file) 186 + { 187 + struct gb_cap *cap = get_cap(inode->i_cdev); 188 + 189 + /* cap structure can't get freed until file descriptor is closed */ 190 + if (cap) { 191 + file->private_data = cap; 192 + return 0; 193 + } 194 + 195 + return -ENODEV; 196 + } 197 + 198 + static int cap_release(struct inode *inode, struct file *file) 199 + { 200 + struct gb_cap *cap = file->private_data; 201 + 202 + put_cap(cap); 203 + return 0; 204 + } 205 + 206 + static int cap_ioctl(struct gb_cap *cap, unsigned int cmd, 207 + void __user *buf) 208 + { 209 + struct cap_ioc_get_endpoint_uid endpoint_uid; 210 + struct cap_ioc_get_ims_certificate *ims_cert; 211 + struct cap_ioc_authenticate *authenticate; 212 + int ret; 213 + 214 + switch (cmd) { 215 + case CAP_IOC_GET_ENDPOINT_UID: 216 + ret = cap_get_endpoint_uid(cap, endpoint_uid.uid); 217 + if (ret) 218 + return ret; 219 + 220 + if (copy_to_user(buf, &endpoint_uid, sizeof(endpoint_uid))) 221 + return -EFAULT; 222 + 223 + return 0; 224 + case CAP_IOC_GET_IMS_CERTIFICATE: 225 + ims_cert = kzalloc(sizeof(*ims_cert), GFP_KERNEL); 226 + if (!ims_cert) 227 + return -ENOMEM; 228 + 229 + if (copy_from_user(ims_cert, buf, sizeof(*ims_cert))) { 230 + ret = -EFAULT; 231 + goto free_ims_cert; 232 + } 233 + 234 + ret = cap_get_ims_certificate(cap, ims_cert->certificate_class, 235 + ims_cert->certificate_id, 236 + ims_cert->certificate, 237 + &ims_cert->cert_size, 238 + &ims_cert->result_code); 239 + if (ret) 240 + goto free_ims_cert; 241 + 242 + if (copy_to_user(buf, ims_cert, sizeof(*ims_cert))) 243 + ret = -EFAULT; 244 + 245 + free_ims_cert: 246 + kfree(ims_cert); 247 + return ret; 248 + case CAP_IOC_AUTHENTICATE: 249 + authenticate = kzalloc(sizeof(*authenticate), GFP_KERNEL); 250 + if (!authenticate) 251 + return -ENOMEM; 252 + 253 + if (copy_from_user(authenticate, buf, sizeof(*authenticate))) { 254 + ret = -EFAULT; 255 + goto free_authenticate; 256 + } 257 + 258 + ret = cap_authenticate(cap, authenticate->auth_type, 259 + authenticate->uid, 260 + authenticate->challenge, 261 + &authenticate->result_code, 262 + authenticate->response, 263 + &authenticate->signature_size, 264 + authenticate->signature); 265 + if (ret) 266 + goto free_authenticate; 267 + 268 + if (copy_to_user(buf, authenticate, sizeof(*authenticate))) 269 + ret = -EFAULT; 270 + free_authenticate: 271 + kfree(authenticate); 272 + return ret; 273 + default: 274 + return -ENOTTY; 275 + } 276 + } 277 + 278 + static long cap_ioctl_unlocked(struct file *file, unsigned int cmd, 279 + unsigned long arg) 280 + { 281 + struct gb_cap *cap = file->private_data; 282 + int ret = -ENODEV; 283 + 284 + /* 285 + * Serialize ioctls. 286 + * 287 + * We don't want the user to do multiple authentication operations in 288 + * parallel. 289 + * 290 + * This is also used to protect ->disabled, which is used to check if 291 + * the connection is getting disconnected, so that we don't start any 292 + * new operations. 293 + */ 294 + mutex_lock(&cap->mutex); 295 + if (!cap->disabled) 296 + ret = cap_ioctl(cap, cmd, (void __user *)arg); 297 + mutex_unlock(&cap->mutex); 298 + 299 + return ret; 300 + } 301 + 302 + static const struct file_operations cap_fops = { 303 + .owner = THIS_MODULE, 304 + .open = cap_open, 305 + .release = cap_release, 306 + .unlocked_ioctl = cap_ioctl_unlocked, 307 + }; 308 + 309 + int gb_cap_connection_init(struct gb_connection *connection) 310 + { 311 + struct gb_cap *cap; 312 + int ret, minor; 313 + 314 + if (!connection) 315 + return 0; 316 + 317 + cap = kzalloc(sizeof(*cap), GFP_KERNEL); 318 + if (!cap) 319 + return -ENOMEM; 320 + 321 + cap->parent = &connection->bundle->dev; 322 + cap->connection = connection; 323 + mutex_init(&cap->mutex); 324 + gb_connection_set_data(connection, cap); 325 + kref_init(&cap->kref); 326 + 327 + mutex_lock(&list_mutex); 328 + list_add(&cap->node, &cap_list); 329 + mutex_unlock(&list_mutex); 330 + 331 + ret = gb_connection_enable(connection); 332 + if (ret) 333 + goto err_list_del; 334 + 335 + minor = ida_simple_get(&cap_minors_map, 0, NUM_MINORS, GFP_KERNEL); 336 + if (minor < 0) { 337 + ret = minor; 338 + goto err_connection_disable; 339 + } 340 + 341 + /* Add a char device to allow userspace to interact with cap */ 342 + cap->dev_num = MKDEV(MAJOR(cap_dev_num), minor); 343 + cdev_init(&cap->cdev, &cap_fops); 344 + 345 + ret = cdev_add(&cap->cdev, cap->dev_num, 1); 346 + if (ret) 347 + goto err_remove_ida; 348 + 349 + /* Add a soft link to the previously added char-dev within the bundle */ 350 + cap->class_device = device_create(cap_class, cap->parent, cap->dev_num, 351 + NULL, "gb-authenticate-%d", minor); 352 + if (IS_ERR(cap->class_device)) { 353 + ret = PTR_ERR(cap->class_device); 354 + goto err_del_cdev; 355 + } 356 + 357 + return 0; 358 + 359 + err_del_cdev: 360 + cdev_del(&cap->cdev); 361 + err_remove_ida: 362 + ida_simple_remove(&cap_minors_map, minor); 363 + err_connection_disable: 364 + gb_connection_disable(connection); 365 + err_list_del: 366 + mutex_lock(&list_mutex); 367 + list_del(&cap->node); 368 + mutex_unlock(&list_mutex); 369 + 370 + put_cap(cap); 371 + 372 + return ret; 373 + } 374 + 375 + void gb_cap_connection_exit(struct gb_connection *connection) 376 + { 377 + struct gb_cap *cap; 378 + 379 + if (!connection) 380 + return; 381 + 382 + cap = gb_connection_get_data(connection); 383 + 384 + device_destroy(cap_class, cap->dev_num); 385 + cdev_del(&cap->cdev); 386 + ida_simple_remove(&cap_minors_map, MINOR(cap->dev_num)); 387 + 388 + /* 389 + * Disallow any new ioctl operations on the char device and wait for 390 + * existing ones to finish. 391 + */ 392 + mutex_lock(&cap->mutex); 393 + cap->disabled = true; 394 + mutex_unlock(&cap->mutex); 395 + 396 + /* All pending greybus operations should have finished by now */ 397 + gb_connection_disable(cap->connection); 398 + 399 + /* Disallow new users to get access to the cap structure */ 400 + mutex_lock(&list_mutex); 401 + list_del(&cap->node); 402 + mutex_unlock(&list_mutex); 403 + 404 + /* 405 + * All current users of cap would have taken a reference to it by 406 + * now, we can drop our reference and wait the last user will get 407 + * cap freed. 408 + */ 409 + put_cap(cap); 410 + } 411 + 412 + int cap_init(void) 413 + { 414 + int ret; 415 + 416 + cap_class = class_create(THIS_MODULE, "gb_authenticate"); 417 + if (IS_ERR(cap_class)) 418 + return PTR_ERR(cap_class); 419 + 420 + ret = alloc_chrdev_region(&cap_dev_num, 0, NUM_MINORS, 421 + "gb_authenticate"); 422 + if (ret) 423 + goto err_remove_class; 424 + 425 + return 0; 426 + 427 + err_remove_class: 428 + class_destroy(cap_class); 429 + return ret; 430 + } 431 + 432 + void cap_exit(void) 433 + { 434 + unregister_chrdev_region(cap_dev_num, NUM_MINORS); 435 + class_destroy(cap_class); 436 + ida_destroy(&cap_minors_map); 437 + }
+6
drivers/staging/greybus/firmware.h
··· 25 25 int gb_fw_download_connection_init(struct gb_connection *connection); 26 26 void gb_fw_download_connection_exit(struct gb_connection *connection); 27 27 28 + /* CAP Protocol specific functions */ 29 + int cap_init(void); 30 + void cap_exit(void); 31 + int gb_cap_connection_init(struct gb_connection *connection); 32 + void gb_cap_connection_exit(struct gb_connection *connection); 33 + 28 34 #endif /* __FIRMWARE_H */
+48 -3
drivers/staging/greybus/fw-core.c
··· 17 17 struct gb_connection *download_connection; 18 18 struct gb_connection *mgmt_connection; 19 19 struct gb_connection *spi_connection; 20 + struct gb_connection *cap_connection; 20 21 }; 21 22 22 23 struct gb_connection *to_fw_mgmt_connection(struct device *dev) ··· 136 135 } 137 136 138 137 break; 138 + case GREYBUS_PROTOCOL_AUTHENTICATION: 139 + /* Disallow multiple CAP CPorts */ 140 + if (fw_core->cap_connection) { 141 + dev_err(&bundle->dev, "multiple Authentication CPorts found\n"); 142 + ret = -EINVAL; 143 + goto err_destroy_connections; 144 + } 145 + 146 + connection = gb_connection_create(bundle, cport_id, 147 + NULL); 148 + if (IS_ERR(connection)) { 149 + dev_err(&bundle->dev, "failed to create Authentication connection (%ld)\n", 150 + PTR_ERR(connection)); 151 + } else { 152 + fw_core->cap_connection = connection; 153 + } 154 + 155 + break; 139 156 default: 140 157 dev_err(&bundle->dev, "invalid protocol id (0x%02x)\n", 141 158 protocol_id); ··· 187 168 fw_core->spi_connection = NULL; 188 169 } 189 170 171 + ret = gb_cap_connection_init(fw_core->cap_connection); 172 + if (ret) { 173 + /* We may still be able to work with the Interface */ 174 + dev_err(&bundle->dev, "failed to initialize CAP connection, disable it (%d)\n", 175 + ret); 176 + gb_connection_destroy(fw_core->cap_connection); 177 + fw_core->cap_connection = NULL; 178 + } 179 + 190 180 ret = gb_fw_mgmt_connection_init(fw_core->mgmt_connection); 191 181 if (ret) { 192 182 /* We may still be able to work with the Interface */ ··· 209 181 return 0; 210 182 211 183 err_exit_connections: 184 + gb_cap_connection_exit(fw_core->cap_connection); 212 185 gb_fw_spi_connection_exit(fw_core->spi_connection); 213 186 gb_fw_download_connection_exit(fw_core->download_connection); 214 187 err_destroy_connections: 215 188 gb_connection_destroy(fw_core->mgmt_connection); 189 + gb_connection_destroy(fw_core->cap_connection); 216 190 gb_connection_destroy(fw_core->spi_connection); 217 191 gb_connection_destroy(fw_core->download_connection); 218 192 kfree(fw_core); ··· 227 197 struct gb_fw_core *fw_core = greybus_get_drvdata(bundle); 228 198 229 199 gb_fw_mgmt_connection_exit(fw_core->mgmt_connection); 200 + gb_cap_connection_exit(fw_core->cap_connection); 230 201 gb_fw_spi_connection_exit(fw_core->spi_connection); 231 202 gb_fw_download_connection_exit(fw_core->download_connection); 232 203 233 204 gb_connection_destroy(fw_core->mgmt_connection); 205 + gb_connection_destroy(fw_core->cap_connection); 234 206 gb_connection_destroy(fw_core->spi_connection); 235 207 gb_connection_destroy(fw_core->download_connection); 236 208 ··· 261 229 return ret; 262 230 } 263 231 264 - ret = greybus_register(&gb_fw_core_driver); 232 + ret = cap_init(); 265 233 if (ret) { 266 - fw_mgmt_exit(); 267 - return ret; 234 + pr_err("Failed to initialize component authentication core (%d)\n", 235 + ret); 236 + goto fw_mgmt_exit; 268 237 } 269 238 239 + ret = greybus_register(&gb_fw_core_driver); 240 + if (ret) 241 + goto cap_exit; 242 + 270 243 return 0; 244 + 245 + cap_exit: 246 + cap_exit(); 247 + fw_mgmt_exit: 248 + fw_mgmt_exit(); 249 + 250 + return ret; 271 251 } 272 252 module_init(fw_core_init); 273 253 274 254 static void __exit fw_core_exit(void) 275 255 { 276 256 greybus_deregister(&gb_fw_core_driver); 257 + cap_exit(); 277 258 fw_mgmt_exit(); 278 259 } 279 260 module_exit(fw_core_exit);
+120
drivers/staging/greybus/greybus_authentication.h
··· 1 + /* 2 + * Greybus Component Authentication User Header 3 + * 4 + * This file is provided under a dual BSD/GPLv2 license. When using or 5 + * redistributing this file, you may do so under either license. 6 + * 7 + * GPL LICENSE SUMMARY 8 + * 9 + * Copyright(c) 2016 Google Inc. All rights reserved. 10 + * Copyright(c) 2016 Linaro Ltd. All rights reserved. 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of version 2 of the GNU General Public License as 14 + * published by the Free Software Foundation. 15 + * 16 + * This program is distributed in the hope that it will be useful, but 17 + * WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 + * General Public License version 2 for more details. 20 + * 21 + * BSD LICENSE 22 + * 23 + * Copyright(c) 2016 Google Inc. All rights reserved. 24 + * Copyright(c) 2016 Linaro Ltd. All rights reserved. 25 + * 26 + * Redistribution and use in source and binary forms, with or without 27 + * modification, are permitted provided that the following conditions 28 + * are met: 29 + * 30 + * * Redistributions of source code must retain the above copyright 31 + * notice, this list of conditions and the following disclaimer. 32 + * * Redistributions in binary form must reproduce the above copyright 33 + * notice, this list of conditions and the following disclaimer in 34 + * the documentation and/or other materials provided with the 35 + * distribution. 36 + * * Neither the name of Google Inc. or Linaro Ltd. nor the names of 37 + * its contributors may be used to endorse or promote products 38 + * derived from this software without specific prior written 39 + * permission. 40 + * 41 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 42 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 43 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 44 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR 45 + * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 46 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 47 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 48 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 49 + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 50 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 51 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 + */ 53 + 54 + #ifndef __GREYBUS_AUTHENTICATION_USER_H 55 + #define __GREYBUS_AUTHENTICATION_USER_H 56 + 57 + #include <linux/ioctl.h> 58 + #include <linux/types.h> 59 + 60 + #define CAP_CERTIFICATE_MAX_SIZE 1600 61 + #define CAP_SIGNATURE_MAX_SIZE 320 62 + 63 + /* Certificate class types */ 64 + #define CAP_CERT_IMS_EAPC 0x00000001 65 + #define CAP_CERT_IMS_EASC 0x00000002 66 + #define CAP_CERT_IMS_EARC 0x00000003 67 + #define CAP_CERT_IMS_IAPC 0x00000004 68 + #define CAP_CERT_IMS_IASC 0x00000005 69 + #define CAP_CERT_IMS_IARC 0x00000006 70 + 71 + /* IMS Certificate response result codes */ 72 + #define CAP_IMS_RESULT_CERT_FOUND 0x00 73 + #define CAP_IMS_RESULT_CERT_CLASS_INVAL 0x01 74 + #define CAP_IMS_RESULT_CERT_CORRUPT 0x02 75 + #define CAP_IMS_RESULT_CERT_NOT_FOUND 0x03 76 + 77 + /* Authentication types */ 78 + #define CAP_AUTH_IMS_PRI 0x00000001 79 + #define CAP_AUTH_IMS_SEC 0x00000002 80 + #define CAP_AUTH_IMS_RSA 0x00000003 81 + 82 + /* Authenticate response result codes */ 83 + #define CAP_AUTH_RESULT_CR_SUCCESS 0x00 84 + #define CAP_AUTH_RESULT_CR_BAD_TYPE 0x01 85 + #define CAP_AUTH_RESULT_CR_WRONG_EP 0x02 86 + #define CAP_AUTH_RESULT_CR_NO_KEY 0x03 87 + #define CAP_AUTH_RESULT_CR_SIG_FAIL 0x04 88 + 89 + 90 + /* IOCTL support */ 91 + struct cap_ioc_get_endpoint_uid { 92 + __u8 uid[8]; 93 + } __attribute__ ((__packed__)); 94 + 95 + struct cap_ioc_get_ims_certificate { 96 + __u32 certificate_class; 97 + __u32 certificate_id; 98 + 99 + __u8 result_code; 100 + __u32 cert_size; 101 + __u8 certificate[CAP_CERTIFICATE_MAX_SIZE]; 102 + } __attribute__ ((__packed__)); 103 + 104 + struct cap_ioc_authenticate { 105 + __u32 auth_type; 106 + __u8 uid[8]; 107 + __u8 challenge[32]; 108 + 109 + __u8 result_code; 110 + __u8 response[64]; 111 + __u32 signature_size; 112 + __u8 signature[CAP_SIGNATURE_MAX_SIZE]; 113 + } __attribute__ ((__packed__)); 114 + 115 + #define CAP_IOCTL_BASE 'C' 116 + #define CAP_IOC_GET_ENDPOINT_UID _IOR(CAP_IOCTL_BASE, 0, struct cap_ioc_get_endpoint_uid) 117 + #define CAP_IOC_GET_IMS_CERTIFICATE _IOWR(CAP_IOCTL_BASE, 1, struct cap_ioc_get_ims_certificate) 118 + #define CAP_IOC_AUTHENTICATE _IOWR(CAP_IOCTL_BASE, 2, struct cap_ioc_authenticate) 119 + 120 + #endif /* __GREYBUS_AUTHENTICATION_USER_H */
+1
drivers/staging/greybus/greybus_manifest.h
··· 47 47 GREYBUS_PROTOCOL_CAMERA_DATA = 0x16, 48 48 GREYBUS_PROTOCOL_FW_DOWNLOAD = 0x17, 49 49 GREYBUS_PROTOCOL_FW_MANAGEMENT = 0x18, 50 + GREYBUS_PROTOCOL_AUTHENTICATION = 0x19, 50 51 GREYBUS_PROTOCOL_LOG = 0x1a, 51 52 /* ... */ 52 53 GREYBUS_PROTOCOL_RAW = 0xfe,
+37
drivers/staging/greybus/greybus_protocols.h
··· 345 345 /* firmware management backend firmware updated response has no payload */ 346 346 347 347 348 + /* Component Authentication Protocol (CAP) */ 349 + 350 + /* Request Types */ 351 + #define GB_CAP_TYPE_GET_ENDPOINT_UID 0x01 352 + #define GB_CAP_TYPE_GET_IMS_CERTIFICATE 0x02 353 + #define GB_CAP_TYPE_AUTHENTICATE 0x03 354 + 355 + /* CAP get endpoint uid request has no payload */ 356 + struct gb_cap_get_endpoint_uid_response { 357 + __u8 uid[8]; 358 + } __packed; 359 + 360 + /* CAP get endpoint ims certificate request/response */ 361 + struct gb_cap_get_ims_certificate_request { 362 + __le32 certificate_class; 363 + __le32 certificate_id; 364 + } __packed; 365 + 366 + struct gb_cap_get_ims_certificate_response { 367 + __u8 result_code; 368 + __u8 certificate[0]; 369 + } __packed; 370 + 371 + /* CAP authenticate request/response */ 372 + struct gb_cap_authenticate_request { 373 + __le32 auth_type; 374 + __u8 uid[8]; 375 + __u8 challenge[32]; 376 + } __packed; 377 + 378 + struct gb_cap_authenticate_response { 379 + __u8 result_code; 380 + __u8 response[64]; 381 + __u8 signature[0]; 382 + } __packed; 383 + 384 + 348 385 /* Bootrom Protocol */ 349 386 350 387 /* Version of the Greybus bootrom protocol we support */