1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <stdint.h> 8 #include <threads.h> 9 10 #include <crypto/cipher.h> 11 #include <lib/zx/port.h> 12 #include <zircon/syscalls/port.h> 13 #include <zircon/types.h> 14 #include <zxcrypt/volume.h> 15 16 #include "extra.h" 17 18 namespace zxcrypt { 19 20 class Device; 21 22 // |zxcrypt::Worker| represents a thread performing cryptographic transformations on block I/O data. 23 // Since these operations may have significant and asymmetric costs between encrypting and 24 // decrypting, they are performed asynchronously on separate threads. The |zxcrypt::Device| may 25 // spin up multiple workers pulling from a shared queues to optimize the throughput. 26 class Worker final { 27 public: 28 Worker(); 29 ~Worker(); 30 31 // Opcodes for requests that can be sent to workers. 32 static constexpr uint64_t kBlockRequest = 0x1; 33 static constexpr uint64_t kStopRequest = 0x2; 34 35 // Configure the given |packet| to be an |op| request, with an optional |arg|. 36 static void MakeRequest(zx_port_packet_t* packet, uint64_t op, void* arg = nullptr); 37 38 // Starts the worker, which will service requests sent from the given |device| on the given 39 // |port|. Cryptographic operations will use the key material from the given |volume|. 40 zx_status_t Start(Device* device, const Volume& volume, zx::port&& port); 41 42 // Asks the worker to stop. This call blocks until the worker has finished processing the 43 // currently queued operations and exits. 44 zx_status_t Stop(); 45 46 private: 47 DISALLOW_COPY_ASSIGN_AND_MOVE(Worker); 48 49 // Loop thread. Reads an I/O request from the |port_| and dispatches it between |EncryptWrite| 50 // and |DecryptRead|. WorkerRun(void * arg)51 static int WorkerRun(void* arg) { return static_cast<Worker*>(arg)->Run(); } 52 zx_status_t Run(); 53 54 // Copies the plaintext data to be written to the write buffer location given in |block|'s extra 55 // information, and encrypts it before sending it to the parent device. 56 zx_status_t EncryptWrite(block_op_t* block); 57 58 // Maps the ciphertext data in |block|, and decrypts it in place before completing the block op. 59 zx_status_t DecryptRead(block_op_t* block); 60 61 // The cipher objects used to perform cryptographic. See notes on "random access" in 62 // crypto/cipher.h. 63 crypto::Cipher encrypt_; 64 crypto::Cipher decrypt_; 65 66 // The device associated with this worker. 67 Device* device_; 68 69 // The port to wait for I/O request on, as given by the device. 70 zx::port port_; 71 72 // The executing thread for this worker 73 thrd_t thrd_; 74 }; 75 76 } // namespace zxcrypt 77