Skip to main content

rhdl_ubft/crypto/
external.rs

1//! A scheme outside the replica (`define_replica!(Name, external SB)`).
2//!
3//! On a card, a replica that embeds its own signature service costs that
4//! service's area: about 400k LUT for DSig, so N replicas cannot share a
5//! chip. An external replica instead exports its crypto requests on
6//! `ReplicaOut.crypto_req` and takes the answers on `ReplicaIn.crypto_resp`.
7//! The card top wires replica `i` to signer port `i`, and the port number is
8//! the trusted identity. [`External`] is the placeholder that fills the
9//! scheme slot: it holds no crypto and only fixes `SHARE_BEATS`.
10
11use rhdl::prelude::*;
12
13use crate::ports::{Axis64, CryptoIn, CryptoOut, CryptoScheme, idle512, idle_read};
14
15/// No scheme inside; `SB` share beats on the outer ports.
16#[derive(Clone, Debug, Synchronous, SynchronousDQ)]
17pub struct External<const SB: usize> {
18    unused: rhdl_fpga::core::dff::DFF<bool>,
19}
20
21impl<const SB: usize> Default for External<SB> {
22    fn default() -> Self {
23        Self { unused: rhdl_fpga::core::dff::DFF::new(false) }
24    }
25}
26
27impl<const SB: usize> CryptoScheme for External<SB> {
28    const SHARE_BEATS: usize = SB;
29    const SCHEME: u8 = 0;
30}
31
32impl<const SB: usize> SynchronousIO for External<SB> {
33    type I = CryptoIn;
34    type O = CryptoOut;
35    type Kernel = external_kernel<SB>;
36}
37
38/// Answers nothing (the replica reads the outer port instead).
39#[kernel]
40pub fn external_kernel<const SB: usize>(_cr: ClockReset, _i: CryptoIn, q: ExternalQ<SB>) -> (CryptoOut, ExternalD<SB>) {
41    let o = CryptoOut {
42        ready: false,
43        msg: idle_read(),
44        sign_ready: false,
45        sig: idle512(),
46        verify_ready: false,
47        verdict: Axis64 { valid: false, data: b64(0) },
48        fault: false,
49        announce: idle512(),
50        cert_ready: false,
51    };
52    (o, ExternalD::<SB> { unused: q.unused })
53}