earlgrey/
aes.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
5//! Support for the AES hardware block on OpenTitan
6//!
7//! <https://docs.opentitan.org/hw/ip/aes/doc/>
8
9use crate::registers::top_earlgrey::AES_BASE_ADDR;
10use core::cell::Cell;
11use kernel::deferred_call::{DeferredCall, DeferredCallClient};
12use kernel::hil;
13use kernel::hil::symmetric_encryption;
14use kernel::hil::symmetric_encryption::{AES128_BLOCK_SIZE, AES128_KEY_SIZE};
15use kernel::utilities::cells::{OptionalCell, TakeCell};
16use kernel::utilities::registers::interfaces::{Readable, Writeable};
17use kernel::utilities::registers::{
18    register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly,
19};
20use kernel::utilities::StaticRef;
21use kernel::ErrorCode;
22
23const MAX_LENGTH: usize = 128;
24
25register_structs! {
26    pub AesRegisters {
27        (0x00 => alert_test: WriteOnly<u32, ALERT_TEST::Register>),
28        (0x04 => key_share0_0: WriteOnly<u32>),
29        (0x08 => key_share0_1: WriteOnly<u32>),
30        (0x0C => key_share0_2: WriteOnly<u32>),
31        (0x10 => key_share0_3: WriteOnly<u32>),
32        (0x14 => key_share0_4: WriteOnly<u32>),
33        (0x18 => key_share0_5: WriteOnly<u32>),
34        (0x1C => key_share0_6: WriteOnly<u32>),
35        (0x20 => key_share0_7: WriteOnly<u32>),
36        (0x24 => key_share1_0: WriteOnly<u32>),
37        (0x28 => key_share1_1: WriteOnly<u32>),
38        (0x2C => key_share1_2: WriteOnly<u32>),
39        (0x30 => key_share1_3: WriteOnly<u32>),
40        (0x34 => key_share1_4: WriteOnly<u32>),
41        (0x38 => key_share1_5: WriteOnly<u32>),
42        (0x3C => key_share1_6: WriteOnly<u32>),
43        (0x40 => key_share1_7: WriteOnly<u32>),
44        (0x44 => iv_0: WriteOnly<u32>),
45        (0x48 => iv_1: WriteOnly<u32>),
46        (0x4C => iv_2: WriteOnly<u32>),
47        (0x50 => iv_3: WriteOnly<u32>),
48        (0x54 => data_in0: WriteOnly<u32>),
49        (0x58 => data_in1: WriteOnly<u32>),
50        (0x5C => data_in2: WriteOnly<u32>),
51        (0x60 => data_in3: WriteOnly<u32>),
52        (0x64 => data_out0: ReadOnly<u32>),
53        (0x68 => data_out1: ReadOnly<u32>),
54        (0x6C => data_out2: ReadOnly<u32>),
55        (0x70 => data_out3: ReadOnly<u32>),
56        (0x74 => ctrl: ReadWrite<u32, CTRL::Register>),
57        (0x78 => ctrl_aux: ReadWrite<u32>),
58        (0x7C => ctrl_aux_regwen: ReadWrite<u32>),
59        (0x80 => trigger: WriteOnly<u32, TRIGGER::Register>),
60        (0x84 => status: ReadOnly<u32, STATUS::Register>),
61        (0x88 => @END),
62    }
63}
64
65register_bitfields![u32,
66    ALERT_TEST [
67        RECOV_CTRL_UPDATE_ERR OFFSET(0) NUMBITS(1) [],
68        FATAL_FAULT OFFSET(1) NUMBITS(1) [],
69    ],
70    CTRL [
71        OPERATION OFFSET(0) NUMBITS(2) [
72            Encrypting = 1,
73            Decrypting = 2,
74        ],
75        MODE OFFSET(2) NUMBITS(6) [
76            AES_ECB = 1,
77            AES_CBC = 2,
78            AES_CFB = 4,
79            AES_OFB = 8,
80            AES_CTR = 16,
81            AES_NONE = 32,
82        ],
83        KEY_LEN OFFSET(8) NUMBITS(3) [
84            Key128 = 1,
85            Key192 = 2,
86            Key256 = 4,
87        ],
88        MANUAL_OPERATION OFFSET(15) NUMBITS(1) [],
89        FORCE_ZERO_MASKS OFFSET(16) NUMBITS(1) [],
90    ],
91    TRIGGER [
92        START OFFSET(0) NUMBITS(1) [],
93        KEY_IV_DATA_IN_CLEAR OFFSET(1) NUMBITS(1) [],
94        DATA_OUT_CLEAR OFFSET(2) NUMBITS(1) [],
95        PRNG_RESEED OFFSET(3) NUMBITS(1) [],
96    ],
97    STATUS [
98        IDLE OFFSET(0) NUMBITS(1) [],
99        STALL OFFSET(1) NUMBITS(1) [],
100        OUTPUT_LOST OFFSET(2) NUMBITS(1) [],
101        OUTPUT_VALID OFFSET(3) NUMBITS(1) [],
102        INPUT_READY OFFSET(4) NUMBITS(1) [],
103        ALERT_RECOV_CTRL_UPDATE_ERR OFFSET(5) NUMBITS(1) [],
104        ALERT_FATAL_FAULT OFFSET(6) NUMBITS(1) [],
105    ]
106];
107
108#[derive(Clone, Copy)]
109enum Mode {
110    IDLE,
111    AES128CTR,
112    AES128CBC,
113    AES128ECB,
114}
115
116// https://docs.opentitan.org/hw/top_earlgrey/doc/
117const AES_BASE: StaticRef<AesRegisters> =
118    unsafe { StaticRef::new(AES_BASE_ADDR as *const AesRegisters) };
119
120pub struct Aes<'a> {
121    registers: StaticRef<AesRegisters>,
122
123    client: OptionalCell<&'a dyn hil::symmetric_encryption::Client<'a>>,
124    source: TakeCell<'static, [u8]>,
125    dest: TakeCell<'static, [u8]>,
126    mode: Cell<Mode>,
127
128    deferred_call: DeferredCall,
129}
130
131impl<'a> Aes<'a> {
132    pub fn new() -> Aes<'a> {
133        Aes {
134            registers: AES_BASE,
135            client: OptionalCell::empty(),
136            source: TakeCell::empty(),
137            dest: TakeCell::empty(),
138            mode: Cell::new(Mode::IDLE),
139            deferred_call: DeferredCall::new(),
140        }
141    }
142
143    pub fn idle(&self) -> bool {
144        self.registers.status.is_set(STATUS::IDLE)
145    }
146
147    /// Must wait for IDLE, for trigger to set.
148    /// On reset, AES unit will first reseed the internal PRNGs
149    /// for register clearing and masking via EDN, and then
150    /// clear all key, IV and data registers with pseudo-random data.
151    /// Only after this sequence has finished, the unit becomes idle
152    ///
153    /// NOTE: This is needed for Verilator, and is suggested by documentation
154    ///       in general.
155    /// Refer: <https://docs.opentitan.org/hw/ip/aes/doc/#programmers-guide>
156    fn wait_on_idle_ready(&self) -> Result<(), ErrorCode> {
157        for _i in 0..10000 {
158            if self.idle() {
159                return Ok(());
160            }
161        }
162        // AES Busy
163        Err(ErrorCode::BUSY)
164    }
165
166    fn input_ready(&self) -> bool {
167        self.registers.status.is_set(STATUS::INPUT_READY)
168    }
169
170    /// Wait for the input to be ready, return an error if it takes too long
171    fn wait_for_input_ready(&self) -> Result<(), ErrorCode> {
172        let mut j = 0;
173
174        while !self.input_ready() {
175            j += 1;
176            if j > 10000 {
177                return Err(ErrorCode::FAIL);
178            }
179        }
180
181        Ok(())
182    }
183
184    fn output_valid(&self) -> bool {
185        self.registers.status.is_set(STATUS::OUTPUT_VALID)
186    }
187
188    /// Wait for the output to be valid, return an error if it takes too long
189    fn wait_for_output_valid(&self) -> Result<(), ErrorCode> {
190        let mut j = 0;
191
192        while !self.output_valid() {
193            j += 1;
194            if j > 10000 {
195                return Err(ErrorCode::FAIL);
196            }
197        }
198
199        Ok(())
200    }
201
202    fn read_block(&self, blocknum: usize) -> Result<(), ErrorCode> {
203        let blocknum = blocknum * AES128_BLOCK_SIZE;
204
205        self.dest.map_or(Err(ErrorCode::NOMEM), |dest| {
206            for i in 0..4 {
207                // we work off an array of u8 so we need to assemble those
208                // back into a u32
209                let mut v = 0;
210                match i {
211                    0 => v = self.registers.data_out0.get(),
212                    1 => v = self.registers.data_out1.get(),
213                    2 => v = self.registers.data_out2.get(),
214                    3 => v = self.registers.data_out3.get(),
215                    _ => {}
216                }
217                dest[blocknum + (i * 4) + 0] = (v >> 0) as u8;
218                dest[blocknum + (i * 4) + 1] = (v >> 8) as u8;
219                dest[blocknum + (i * 4) + 2] = (v >> 16) as u8;
220                dest[blocknum + (i * 4) + 3] = (v >> 24) as u8;
221            }
222            Ok(())
223        })
224    }
225
226    fn write_block(&self, blocknum: usize) -> Result<(), ErrorCode> {
227        self.source.map_or_else(
228            || {
229                // This is the case that dest = source
230                self.dest.map_or(Err(ErrorCode::NOMEM), |dest| {
231                    for i in 0..4 {
232                        let mut v = dest[blocknum + (i * 4) + 0] as usize;
233                        v |= (dest[blocknum + (i * 4) + 1] as usize) << 8;
234                        v |= (dest[blocknum + (i * 4) + 2] as usize) << 16;
235                        v |= (dest[blocknum + (i * 4) + 3] as usize) << 24;
236                        match i {
237                            0 => self.registers.data_in0.set(v as u32),
238                            1 => self.registers.data_in1.set(v as u32),
239                            2 => self.registers.data_in2.set(v as u32),
240                            3 => self.registers.data_in3.set(v as u32),
241                            _ => {}
242                        }
243                    }
244                    Ok(())
245                })
246            },
247            |source| {
248                for i in 0..4 {
249                    // we work off an array of u8 so we need to assemble
250                    // those back into a u32
251                    let mut v = source[blocknum + (i * 4) + 0] as usize;
252                    v |= (source[blocknum + (i * 4) + 1] as usize) << 8;
253                    v |= (source[blocknum + (i * 4) + 2] as usize) << 16;
254                    v |= (source[blocknum + (i * 4) + 3] as usize) << 24;
255                    match i {
256                        0 => self.registers.data_in0.set(v as u32),
257                        1 => self.registers.data_in1.set(v as u32),
258                        2 => self.registers.data_in2.set(v as u32),
259                        3 => self.registers.data_in3.set(v as u32),
260                        _ => {}
261                    }
262                }
263                Ok(())
264            },
265        )
266    }
267
268    fn do_crypt(
269        &self,
270        start_index: usize,
271        stop_index: usize,
272        mut write_block: usize,
273    ) -> Result<(), ErrorCode> {
274        let start_block = start_index / AES128_BLOCK_SIZE;
275        let end_block = stop_index / AES128_BLOCK_SIZE;
276
277        for i in start_block..end_block {
278            self.wait_for_input_ready()?;
279            self.write_block(write_block)?;
280
281            self.wait_for_output_valid()?;
282            self.read_block(i)?;
283            write_block += AES128_BLOCK_SIZE;
284        }
285
286        Ok(())
287    }
288}
289
290impl<'a> hil::symmetric_encryption::AES128<'a> for Aes<'a> {
291    fn enable(&self) {
292        self.registers.trigger.write(
293            TRIGGER::KEY_IV_DATA_IN_CLEAR::SET
294                + TRIGGER::DATA_OUT_CLEAR::SET
295                + TRIGGER::PRNG_RESEED::SET,
296        );
297    }
298
299    fn disable(&self) {
300        self.registers.ctrl.write(CTRL::MANUAL_OPERATION::SET);
301        self.registers.ctrl.write(CTRL::MANUAL_OPERATION::SET);
302
303        self.registers.ctrl.write(CTRL::MANUAL_OPERATION::CLEAR);
304        self.registers.ctrl.write(CTRL::MANUAL_OPERATION::CLEAR);
305    }
306
307    fn set_client(&'a self, client: &'a dyn symmetric_encryption::Client<'a>) {
308        self.client.set(client);
309    }
310
311    fn set_iv(&self, iv: &[u8]) -> Result<(), ErrorCode> {
312        self.wait_on_idle_ready()?;
313
314        if iv.len() != AES128_BLOCK_SIZE {
315            return Err(ErrorCode::INVAL);
316        }
317
318        for i in 0..(AES128_BLOCK_SIZE / 4) {
319            let mut k = iv[i * 4 + 0] as u32;
320            k |= (iv[i * 4 + 1] as u32) << 8;
321            k |= (iv[i * 4 + 2] as u32) << 16;
322            k |= (iv[i * 4 + 3] as u32) << 24;
323            match i {
324                0 => self.registers.iv_0.set(k),
325                1 => self.registers.iv_1.set(k),
326                2 => self.registers.iv_2.set(k),
327                3 => self.registers.iv_3.set(k),
328                _ => {
329                    unreachable!()
330                }
331            }
332        }
333
334        Ok(())
335    }
336
337    fn set_key(&self, key: &[u8]) -> Result<(), ErrorCode> {
338        self.wait_on_idle_ready()?;
339
340        if key.len() != AES128_KEY_SIZE {
341            return Err(ErrorCode::INVAL);
342        }
343
344        for i in 0..(AES128_KEY_SIZE / 4) {
345            let mut k = key[i * 4 + 0] as u32;
346            k |= (key[i * 4 + 1] as u32) << 8;
347            k |= (key[i * 4 + 2] as u32) << 16;
348            k |= (key[i * 4 + 3] as u32) << 24;
349            match i {
350                0 => {
351                    self.registers.key_share0_0.set(k);
352                    self.registers.key_share1_0.set(0);
353                }
354                1 => {
355                    self.registers.key_share0_1.set(k);
356                    self.registers.key_share1_1.set(0);
357                }
358                2 => {
359                    self.registers.key_share0_2.set(k);
360                    self.registers.key_share1_2.set(0);
361                }
362                3 => {
363                    self.registers.key_share0_3.set(k);
364                    self.registers.key_share1_3.set(0);
365                }
366                _ => {
367                    unreachable!()
368                }
369            }
370        }
371
372        // We must write the rest of the registers as well
373        // This should be written with random data, for now this will do
374        self.registers.key_share0_4.set(0x12);
375        self.registers.key_share0_5.set(0x34);
376        self.registers.key_share0_6.set(0x56);
377        self.registers.key_share0_7.set(0x78);
378
379        self.registers.key_share1_4.set(0xAB);
380        self.registers.key_share1_5.set(0xCD);
381        self.registers.key_share1_6.set(0xEF);
382        self.registers.key_share1_7.set(0x00);
383
384        Ok(())
385    }
386
387    fn start_message(&self) {}
388
389    fn crypt(
390        &self,
391        source: Option<&'static mut [u8]>,
392        dest: &'static mut [u8],
393        start_index: usize,
394        stop_index: usize,
395    ) -> Option<(
396        Result<(), ErrorCode>,
397        Option<&'static mut [u8]>,
398        &'static mut [u8],
399    )> {
400        match stop_index.checked_sub(start_index) {
401            None => return Some((Err(ErrorCode::INVAL), source, dest)),
402            Some(s) => {
403                if s > MAX_LENGTH {
404                    return Some((Err(ErrorCode::INVAL), source, dest));
405                }
406                if s % AES128_BLOCK_SIZE != 0 {
407                    return Some((Err(ErrorCode::INVAL), source, dest));
408                }
409            }
410        }
411
412        if self.deferred_call.is_pending() {
413            return Some((
414                Err(ErrorCode::BUSY),
415                self.source.take(),
416                self.dest.take().unwrap(),
417            ));
418        }
419
420        self.dest.replace(dest);
421        let ret = match source {
422            None => self.do_crypt(start_index, stop_index, start_index),
423            Some(src) => {
424                self.source.replace(src);
425                self.do_crypt(start_index, stop_index, 0)
426            }
427        };
428
429        if ret.is_ok() {
430            // Schedule a deferred call
431            self.deferred_call.set();
432            None
433        } else {
434            Some((ret, self.source.take(), self.dest.take().unwrap()))
435        }
436    }
437}
438
439impl kernel::hil::symmetric_encryption::AES128Ctr for Aes<'_> {
440    fn set_mode_aes128ctr(&self, encrypting: bool) -> Result<(), ErrorCode> {
441        self.wait_on_idle_ready()?;
442        self.mode.set(Mode::AES128CTR);
443
444        let mut ctrl = if encrypting {
445            CTRL::OPERATION::Encrypting
446        } else {
447            CTRL::OPERATION::Decrypting
448        };
449        ctrl += CTRL::MODE::AES_CTR;
450        // Tock only supports 128-bit keys
451        ctrl += CTRL::KEY_LEN::Key128;
452        ctrl += CTRL::MANUAL_OPERATION::CLEAR;
453
454        // We need to set the control register twice as it's shadowed
455        self.registers.ctrl.write(ctrl);
456        self.registers.ctrl.write(ctrl);
457
458        Ok(())
459    }
460}
461
462impl kernel::hil::symmetric_encryption::AES128ECB for Aes<'_> {
463    fn set_mode_aes128ecb(&self, encrypting: bool) -> Result<(), ErrorCode> {
464        self.wait_on_idle_ready()?;
465        self.mode.set(Mode::AES128ECB);
466
467        let mut ctrl = if encrypting {
468            CTRL::OPERATION::Encrypting
469        } else {
470            CTRL::OPERATION::Decrypting
471        };
472        ctrl += CTRL::MODE::AES_ECB;
473        // Tock only supports 128-bit keys
474        ctrl += CTRL::KEY_LEN::Key128;
475        ctrl += CTRL::MANUAL_OPERATION::CLEAR;
476
477        // We need to set the control register twice as it's shadowed
478        self.registers.ctrl.write(ctrl);
479        self.registers.ctrl.write(ctrl);
480
481        Ok(())
482    }
483}
484
485impl kernel::hil::symmetric_encryption::AES128CBC for Aes<'_> {
486    fn set_mode_aes128cbc(&self, encrypting: bool) -> Result<(), ErrorCode> {
487        self.wait_on_idle_ready()?;
488        self.mode.set(Mode::AES128CBC);
489
490        let mut ctrl = if encrypting {
491            CTRL::OPERATION::Encrypting
492        } else {
493            CTRL::OPERATION::Decrypting
494        };
495        ctrl += CTRL::MODE::AES_CBC;
496        // Tock only supports 128-bit keys
497        ctrl += CTRL::KEY_LEN::Key128;
498        ctrl += CTRL::MANUAL_OPERATION::CLEAR;
499
500        // We need to set the control register twice as it's shadowed
501        self.registers.ctrl.write(ctrl);
502        self.registers.ctrl.write(ctrl);
503
504        Ok(())
505    }
506}
507
508impl DeferredCallClient for Aes<'_> {
509    fn register(&'static self) {
510        self.deferred_call.register(self);
511    }
512
513    fn handle_deferred_call(&self) {
514        self.client.map(|client| {
515            client.crypt_done(self.source.take(), self.dest.take().unwrap());
516        });
517    }
518}