capsules_extra/tutorials/
encryption_oracle_chkpt3.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use kernel::grant::{AllowRoCount, AllowRwCount, Grant, UpcallCount};
6use kernel::hil::symmetric_encryption::{AES128Ctr, AES128};
7use kernel::syscall::{CommandReturn, SyscallDriver};
8use kernel::utilities::cells::OptionalCell;
9use kernel::ErrorCode;
10use kernel::ProcessId;
11
12pub const DRIVER_NUM: usize = 0x99999;
13
14pub static KEY: &[u8; kernel::hil::symmetric_encryption::AES128_KEY_SIZE] = b"InsecureAESKey12";
15
16#[derive(Default)]
17pub struct ProcessState {
18    request_pending: bool,
19}
20
21pub struct EncryptionOracleDriver<'a, A: AES128<'a> + AES128Ctr> {
22    aes: &'a A,
23    process_grants: Grant<ProcessState, UpcallCount<0>, AllowRoCount<0>, AllowRwCount<0>>,
24    current_process: OptionalCell<ProcessId>,
25}
26
27impl<'a, A: AES128<'a> + AES128Ctr> EncryptionOracleDriver<'a, A> {
28    /// Create a new instance of our encryption oracle userspace driver:
29    pub fn new(
30        aes: &'a A,
31        _source_buffer: &'static mut [u8],
32        _dest_buffer: &'static mut [u8],
33        process_grants: Grant<ProcessState, UpcallCount<0>, AllowRoCount<0>, AllowRwCount<0>>,
34    ) -> Self {
35        EncryptionOracleDriver {
36            process_grants,
37            aes,
38            current_process: OptionalCell::empty(),
39        }
40    }
41
42    /// Return a `ProcessId` which has `request_pending` set, if there is some:
43    fn next_pending(&self) -> Option<ProcessId> {
44        for process_grant in self.process_grants.iter() {
45            let processid = process_grant.processid();
46            if process_grant.enter(|grant, _| grant.request_pending) {
47                // The process to which `process_grant` belongs
48                // has a request pending, return its id:
49                return Some(processid);
50            }
51        }
52
53        // No process with `request_pending` found:
54        None
55    }
56}
57
58impl<'a, A: AES128<'a> + AES128Ctr> SyscallDriver for EncryptionOracleDriver<'a, A> {
59    fn command(
60        &self,
61        command_num: usize,
62        _data1: usize,
63        _data2: usize,
64        processid: ProcessId,
65    ) -> CommandReturn {
66        match command_num {
67            // Check whether the driver is present:
68            0 => CommandReturn::success(),
69
70            // Request the decryption operation:
71            1 => self
72                .process_grants
73                .enter(processid, |grant, _kernel_data| {
74                    grant.request_pending = true;
75                    CommandReturn::success()
76                })
77                .unwrap_or_else(|err| err.into()),
78
79            // Unknown command number, return a NOSUPPORT error
80            _ => CommandReturn::failure(ErrorCode::NOSUPPORT),
81        }
82    }
83
84    fn allocate_grant(&self, processid: ProcessId) -> Result<(), kernel::process::Error> {
85        self.process_grants.enter(processid, |_, _| {})
86    }
87}