1207753Smm// Copyright 2018 The Fuchsia Authors. All rights reserved. 2207753Smm// Use of this source code is governed by a BSD-style license that can be 3207753Smm// found in the LICENSE file. 4207753Smm 5207753Smm#pragma once 6207753Smm 7207753Smm#include <stdint.h> 8207753Smm#include <threads.h> 9207753Smm 10207753Smm#include <crypto/cipher.h> 11207753Smm#include <lib/zx/port.h> 12207753Smm#include <zircon/syscalls/port.h> 13207753Smm#include <zircon/types.h> 14207753Smm#include <zxcrypt/volume.h> 15207753Smm 16207753Smm#include "extra.h" 17207753Smm 18207753Smmnamespace zxcrypt { 19207753Smm 20207753Smmclass Device; 21207753Smm 22207753Smm// |zxcrypt::Worker| represents a thread performing cryptographic transformations on block I/O data. 23207753Smm// Since these operations may have significant and asymmetric costs between encrypting and 24207753Smm// 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. 26class Worker final { 27public: 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 46private: 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|. 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