1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Amazon Nitro Secure Module driver. 4 * 5 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 6 * 7 * The Nitro Secure Module implements commands via CBOR over virtio. 8 * This driver exposes a raw message ioctls on /dev/nsm that user 9 * space can use to issue these commands. 10 */ 11 12 #include <linux/file.h> 13 #include <linux/fs.h> 14 #include <linux/interrupt.h> 15 #include <linux/hw_random.h> 16 #include <linux/miscdevice.h> 17 #include <linux/module.h> 18 #include <linux/mutex.h> 19 #include <linux/slab.h> 20 #include <linux/string.h> 21 #include <linux/uaccess.h> 22 #include <linux/uio.h> 23 #include <linux/virtio_config.h> 24 #include <linux/virtio_ids.h> 25 #include <linux/virtio.h> 26 #include <linux/wait.h> 27 #include <uapi/linux/nsm.h> 28 29 /* Timeout for NSM virtqueue respose in milliseconds. */ 30 #define NSM_DEFAULT_TIMEOUT_MSECS (120000) /* 2 minutes */ 31 32 /* Maximum length input data */ 33 struct nsm_data_req { 34 u32 len; 35 u8 data[NSM_REQUEST_MAX_SIZE]; 36 }; 37 38 /* Maximum length output data */ 39 struct nsm_data_resp { 40 u32 len; 41 u8 data[NSM_RESPONSE_MAX_SIZE]; 42 }; 43 44 /* Full NSM request/response message */ 45 struct nsm_msg { 46 struct nsm_data_req req; 47 struct nsm_data_resp resp; 48 }; 49 50 struct nsm { 51 struct virtio_device *vdev; 52 struct virtqueue *vq; 53 struct mutex lock; 54 struct completion cmd_done; 55 struct miscdevice misc; 56 struct hwrng hwrng; 57 struct work_struct misc_init; 58 struct nsm_msg msg; 59 }; 60 61 /* NSM device ID */ 62 static const struct virtio_device_id id_table[] = { 63 { VIRTIO_ID_NITRO_SEC_MOD, VIRTIO_DEV_ANY_ID }, 64 { } 65 }; 66 67 static struct nsm *file_to_nsm(struct file *file) 68 { 69 return container_of(file->private_data, struct nsm, misc); 70 } 71 72 static struct nsm *hwrng_to_nsm(struct hwrng *rng) 73 { 74 return container_of(rng, struct nsm, hwrng); 75 } 76 77 #define CBOR_TYPE_MASK 0xE0 78 #define CBOR_TYPE_MAP 0xA0 79 #define CBOR_TYPE_TEXT 0x60 80 #define CBOR_TYPE_ARRAY 0x40 81 #define CBOR_HEADER_SIZE_SHORT 1 82 83 #define CBOR_SHORT_SIZE_MAX_VALUE 23 84 #define CBOR_LONG_SIZE_U8 24 85 #define CBOR_LONG_SIZE_U16 25 86 #define CBOR_LONG_SIZE_U32 26 87 #define CBOR_LONG_SIZE_U64 27 88 89 static bool cbor_object_is_array(const u8 *cbor_object, size_t cbor_object_size) 90 { 91 if (cbor_object_size == 0 || cbor_object == NULL) 92 return false; 93 94 return (cbor_object[0] & CBOR_TYPE_MASK) == CBOR_TYPE_ARRAY; 95 } 96 97 static int cbor_object_get_array(u8 *cbor_object, size_t cbor_object_size, u8 **cbor_array) 98 { 99 u8 cbor_short_size; 100 void *array_len_p; 101 u64 array_len; 102 u64 array_offset; 103 104 if (!cbor_object_is_array(cbor_object, cbor_object_size)) 105 return -EFAULT; 106 107 cbor_short_size = (cbor_object[0] & 0x1F); 108 109 /* Decoding byte array length */ 110 array_offset = CBOR_HEADER_SIZE_SHORT; 111 if (cbor_short_size >= CBOR_LONG_SIZE_U8) 112 array_offset += BIT(cbor_short_size - CBOR_LONG_SIZE_U8); 113 114 if (cbor_object_size < array_offset) 115 return -EFAULT; 116 117 array_len_p = &cbor_object[1]; 118 119 switch (cbor_short_size) { 120 case 0 ... CBOR_SHORT_SIZE_MAX_VALUE: /* short encoding */ 121 array_len = cbor_short_size; 122 break; 123 case CBOR_LONG_SIZE_U8: 124 array_len = *(u8 *)array_len_p; 125 break; 126 case CBOR_LONG_SIZE_U16: 127 array_len = be16_to_cpup((__be16 *)array_len_p); 128 break; 129 case CBOR_LONG_SIZE_U32: 130 array_len = be32_to_cpup((__be32 *)array_len_p); 131 break; 132 case CBOR_LONG_SIZE_U64: 133 array_len = be64_to_cpup((__be64 *)array_len_p); 134 break; 135 default: 136 return -EFAULT; 137 } 138 139 if (cbor_object_size < array_offset) 140 return -EFAULT; 141 142 if (cbor_object_size - array_offset < array_len) 143 return -EFAULT; 144 145 if (array_len > INT_MAX) 146 return -EFAULT; 147 148 *cbor_array = cbor_object + array_offset; 149 return array_len; 150 } 151 152 /* Copy the request of a raw message to kernel space */ 153 static int fill_req_raw(struct nsm *nsm, struct nsm_data_req *req, 154 struct nsm_raw *raw) 155 { 156 /* Verify the user input size. */ 157 if (raw->request.len > sizeof(req->data)) 158 return -EMSGSIZE; 159 160 /* Copy the request payload */ 161 if (copy_from_user(req->data, u64_to_user_ptr(raw->request.addr), 162 raw->request.len)) 163 return -EFAULT; 164 165 req->len = raw->request.len; 166 167 return 0; 168 } 169 170 /* Copy the response of a raw message back to user-space */ 171 static int parse_resp_raw(struct nsm *nsm, struct nsm_data_resp *resp, 172 struct nsm_raw *raw) 173 { 174 /* Truncate any message that does not fit. */ 175 raw->response.len = min_t(u64, raw->response.len, resp->len); 176 177 /* Copy the response content to user space */ 178 if (copy_to_user(u64_to_user_ptr(raw->response.addr), 179 resp->data, raw->response.len)) 180 return -EFAULT; 181 182 return 0; 183 } 184 185 /* Virtqueue interrupt handler */ 186 static void nsm_vq_callback(struct virtqueue *vq) 187 { 188 struct nsm *nsm = vq->vdev->priv; 189 190 complete(&nsm->cmd_done); 191 } 192 193 /* Forward a message to the NSM device and wait for the response from it */ 194 static int nsm_sendrecv_msg_locked(struct nsm *nsm) 195 { 196 struct device *dev = &nsm->vdev->dev; 197 struct scatterlist sg_in, sg_out; 198 struct nsm_msg *msg = &nsm->msg; 199 struct virtqueue *vq = nsm->vq; 200 unsigned int len; 201 void *queue_buf; 202 bool kicked; 203 int rc; 204 205 /* Initialize scatter-gather lists with request and response buffers. */ 206 sg_init_one(&sg_out, msg->req.data, msg->req.len); 207 sg_init_one(&sg_in, msg->resp.data, sizeof(msg->resp.data)); 208 209 init_completion(&nsm->cmd_done); 210 /* Add the request buffer (read by the device). */ 211 rc = virtqueue_add_outbuf(vq, &sg_out, 1, msg->req.data, GFP_KERNEL); 212 if (rc) 213 return rc; 214 215 /* Add the response buffer (written by the device). */ 216 rc = virtqueue_add_inbuf(vq, &sg_in, 1, msg->resp.data, GFP_KERNEL); 217 if (rc) 218 goto cleanup; 219 220 kicked = virtqueue_kick(vq); 221 if (!kicked) { 222 /* Cannot kick the virtqueue. */ 223 rc = -EIO; 224 goto cleanup; 225 } 226 227 /* If the kick succeeded, wait for the device's response. */ 228 if (!wait_for_completion_io_timeout(&nsm->cmd_done, 229 msecs_to_jiffies(NSM_DEFAULT_TIMEOUT_MSECS))) { 230 rc = -ETIMEDOUT; 231 goto cleanup; 232 } 233 234 queue_buf = virtqueue_get_buf(vq, &len); 235 if (!queue_buf || (queue_buf != msg->req.data)) { 236 dev_err(dev, "wrong request buffer."); 237 rc = -ENODATA; 238 goto cleanup; 239 } 240 241 queue_buf = virtqueue_get_buf(vq, &len); 242 if (!queue_buf || (queue_buf != msg->resp.data)) { 243 dev_err(dev, "wrong response buffer."); 244 rc = -ENODATA; 245 goto cleanup; 246 } 247 248 msg->resp.len = min_t(unsigned int, len, sizeof(msg->resp.data)); 249 250 rc = 0; 251 252 cleanup: 253 if (rc) { 254 /* Clean the virtqueue. */ 255 while (virtqueue_get_buf(vq, &len) != NULL) 256 ; 257 } 258 259 return rc; 260 } 261 262 static int fill_req_get_random(struct nsm *nsm, struct nsm_data_req *req) 263 { 264 /* 265 * 69 # text(9) 266 * 47657452616E646F6D # "GetRandom" 267 */ 268 const u8 request[] = { CBOR_TYPE_TEXT + strlen("GetRandom"), 269 'G', 'e', 't', 'R', 'a', 'n', 'd', 'o', 'm' }; 270 271 memcpy(req->data, request, sizeof(request)); 272 req->len = sizeof(request); 273 274 return 0; 275 } 276 277 static int parse_resp_get_random(struct nsm *nsm, struct nsm_data_resp *resp, 278 void *out, size_t max) 279 { 280 /* 281 * A1 # map(1) 282 * 69 # text(9) - Name of field 283 * 47657452616E646F6D # "GetRandom" 284 * A1 # map(1) - The field itself 285 * 66 # text(6) 286 * 72616E646F6D # "random" 287 * # The rest of the response is random data 288 */ 289 const u8 response[] = { CBOR_TYPE_MAP + 1, 290 CBOR_TYPE_TEXT + strlen("GetRandom"), 291 'G', 'e', 't', 'R', 'a', 'n', 'd', 'o', 'm', 292 CBOR_TYPE_MAP + 1, 293 CBOR_TYPE_TEXT + strlen("random"), 294 'r', 'a', 'n', 'd', 'o', 'm' }; 295 struct device *dev = &nsm->vdev->dev; 296 u8 *rand_data = NULL; 297 u8 *resp_ptr = resp->data; 298 u64 resp_len = resp->len; 299 int rc; 300 301 if ((resp->len < sizeof(response) + 1) || 302 (memcmp(resp_ptr, response, sizeof(response)) != 0)) { 303 dev_err(dev, "Invalid response for GetRandom"); 304 return -EFAULT; 305 } 306 307 resp_ptr += sizeof(response); 308 resp_len -= sizeof(response); 309 310 rc = cbor_object_get_array(resp_ptr, resp_len, &rand_data); 311 if (rc < 0) { 312 dev_err(dev, "GetRandom: Invalid CBOR encoding\n"); 313 return rc; 314 } 315 316 rc = min_t(size_t, rc, max); 317 memcpy(out, rand_data, rc); 318 319 return rc; 320 } 321 322 /* 323 * HwRNG implementation 324 */ 325 static int nsm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) 326 { 327 struct nsm *nsm = hwrng_to_nsm(rng); 328 struct device *dev = &nsm->vdev->dev; 329 int rc = 0; 330 331 /* NSM always needs to wait for a response */ 332 if (!wait) 333 return 0; 334 335 mutex_lock(&nsm->lock); 336 337 rc = fill_req_get_random(nsm, &nsm->msg.req); 338 if (rc != 0) 339 goto out; 340 341 rc = nsm_sendrecv_msg_locked(nsm); 342 if (rc != 0) 343 goto out; 344 345 rc = parse_resp_get_random(nsm, &nsm->msg.resp, data, max); 346 if (rc < 0) 347 goto out; 348 349 dev_dbg(dev, "RNG: returning rand bytes = %d", rc); 350 out: 351 mutex_unlock(&nsm->lock); 352 return rc; 353 } 354 355 static long nsm_dev_ioctl(struct file *file, unsigned int cmd, 356 unsigned long arg) 357 { 358 void __user *argp = u64_to_user_ptr((u64)arg); 359 struct nsm *nsm = file_to_nsm(file); 360 struct nsm_raw raw; 361 int r = 0; 362 363 if (cmd != NSM_IOCTL_RAW) 364 return -EINVAL; 365 366 if (_IOC_SIZE(cmd) != sizeof(raw)) 367 return -EINVAL; 368 369 /* Copy user argument struct to kernel argument struct */ 370 if (copy_from_user(&raw, argp, _IOC_SIZE(cmd))) 371 return -EFAULT; 372 373 mutex_lock(&nsm->lock); 374 375 /* Convert kernel argument struct to device request */ 376 r = fill_req_raw(nsm, &nsm->msg.req, &raw); 377 if (r) 378 goto out; 379 380 /* Send message to NSM and read reply */ 381 r = nsm_sendrecv_msg_locked(nsm); 382 if (r) 383 goto out; 384 385 /* Parse device response into kernel argument struct */ 386 r = parse_resp_raw(nsm, &nsm->msg.resp, &raw); 387 if (r) 388 goto out; 389 390 /* Copy kernel argument struct back to user argument struct */ 391 r = -EFAULT; 392 if (copy_to_user(argp, &raw, sizeof(raw))) 393 goto out; 394 395 r = 0; 396 397 out: 398 mutex_unlock(&nsm->lock); 399 return r; 400 } 401 402 static int nsm_device_init_vq(struct virtio_device *vdev) 403 { 404 struct virtqueue *vq = virtio_find_single_vq(vdev, 405 nsm_vq_callback, "nsm.vq.0"); 406 struct nsm *nsm = vdev->priv; 407 408 if (IS_ERR(vq)) 409 return PTR_ERR(vq); 410 411 nsm->vq = vq; 412 413 return 0; 414 } 415 416 static const struct file_operations nsm_dev_fops = { 417 .owner = THIS_MODULE, 418 .unlocked_ioctl = nsm_dev_ioctl, 419 .compat_ioctl = compat_ptr_ioctl, 420 }; 421 422 /* Handler for probing the NSM device */ 423 static int nsm_device_probe(struct virtio_device *vdev) 424 { 425 struct device *dev = &vdev->dev; 426 struct nsm *nsm; 427 int rc; 428 429 nsm = devm_kzalloc_obj(&vdev->dev, *nsm); 430 if (!nsm) 431 return -ENOMEM; 432 433 vdev->priv = nsm; 434 nsm->vdev = vdev; 435 436 rc = nsm_device_init_vq(vdev); 437 if (rc) { 438 dev_err(dev, "queue failed to initialize: %d.\n", rc); 439 goto err_init_vq; 440 } 441 442 mutex_init(&nsm->lock); 443 444 virtio_device_ready(vdev); 445 446 /* Register as hwrng provider */ 447 nsm->hwrng = (struct hwrng) { 448 .read = nsm_rng_read, 449 .name = "nsm-hwrng", 450 .quality = 1000, 451 }; 452 453 rc = hwrng_register(&nsm->hwrng); 454 if (rc) { 455 dev_err(dev, "RNG initialization error: %d.\n", rc); 456 goto err_hwrng; 457 } 458 459 /* Register /dev/nsm device node */ 460 nsm->misc = (struct miscdevice) { 461 .minor = MISC_DYNAMIC_MINOR, 462 .name = "nsm", 463 .fops = &nsm_dev_fops, 464 .mode = 0666, 465 }; 466 467 rc = misc_register(&nsm->misc); 468 if (rc) { 469 dev_err(dev, "misc device registration error: %d.\n", rc); 470 goto err_misc; 471 } 472 473 return 0; 474 475 err_misc: 476 hwrng_unregister(&nsm->hwrng); 477 err_hwrng: 478 virtio_reset_device(vdev); 479 vdev->config->del_vqs(vdev); 480 err_init_vq: 481 return rc; 482 } 483 484 /* Handler for removing the NSM device */ 485 static void nsm_device_remove(struct virtio_device *vdev) 486 { 487 struct nsm *nsm = vdev->priv; 488 489 hwrng_unregister(&nsm->hwrng); 490 491 vdev->config->del_vqs(vdev); 492 misc_deregister(&nsm->misc); 493 } 494 495 /* NSM device configuration structure */ 496 static struct virtio_driver virtio_nsm_driver = { 497 .feature_table = 0, 498 .feature_table_size = 0, 499 .feature_table_legacy = 0, 500 .feature_table_size_legacy = 0, 501 .driver.name = KBUILD_MODNAME, 502 .id_table = id_table, 503 .probe = nsm_device_probe, 504 .remove = nsm_device_remove, 505 }; 506 507 module_virtio_driver(virtio_nsm_driver); 508 MODULE_DEVICE_TABLE(virtio, id_table); 509 MODULE_DESCRIPTION("Virtio NSM driver"); 510 MODULE_LICENSE("GPL"); 511