esp-hal icon indicating copy to clipboard operation
esp-hal copied to clipboard

`esp32` - issue with `RSA` peripheral

Open playfulFence opened this issue 2 years ago • 4 comments

Encountered a problem during implementing https://github.com/esp-rs/esp-hal/pull/790 : Program run hangs in this or similar blocks -> seems to be stuck in non-idle mode.

One idea where the problem is: Every other chip (except of esp32) has a separate register for handling IDLE state (RSA_IDLE_REG for esp32sX or RSA_QUERY_IDLE for esp32cX), but on esp32 it's checked through the interrupt register on which async functionality depends -> conflict

playfulFence avatar Sep 27 '23 08:09 playfulFence

This one is still valid though. Made some tests on this code:

#[main]
async fn main(spawner: Spawner) -> ! {
    let peripherals = Peripherals::take();
    let system = SystemControl::new(peripherals.SYSTEM);
    let clocks = ClockControl::boot_defaults(system.clock_control).freeze();

    let mut rsa = Rsa::new_async(peripherals.RSA);

    test_modular_exponentiation(rsa).await;
    // test_modular_multiplication(rsa);
    // test_multiplication(rsa);

    loop {
    }
}

const fn compute_r(modulus: &U512) -> U512 {
    let mut d = [0_u32; U512::LIMBS * 2 + 1];
    d[d.len() - 1] = 1;
    let d = Uint::from_words(d);
    d.const_rem(&modulus.resize()).0.resize()
}

const fn compute_mprime(modulus: &U512) -> u32 {
    let m_inv = modulus.inv_mod2k(32).to_words()[0];
    (-1 * m_inv as i64 % 4294967296) as u32
}

async fn test_modular_exponentiation(mut rsa: Rsa<'static, Async>) {
    const EXPECTED_OUTPUT: [u32; U512::LIMBS] = [
        1601059419, 3994655875, 2600857657, 1530060852, 64828275, 4221878473, 2751381085,
        1938128086, 625895085, 2087010412, 2133352910, 101578249, 3798099415, 3357588690,
        2065243474, 330914193,
    ];

    #[cfg(not(feature = "esp32"))]
    {
        rsa.enable_disable_constant_time_acceleration(true);
        rsa.enable_disable_search_acceleration(true);
    }
    let mut outbuf = [0_u32; U512::LIMBS];
    let mut mod_exp = RsaModularExponentiation::<operand_sizes::Op512, esp_hal::Async>::new(
        &mut rsa,
        BIGNUM_2.as_words(),
        BIGNUM_3.as_words(),
        compute_mprime(&BIGNUM_3),
    );
    let r = compute_r(&BIGNUM_3);
    let base = &BIGNUM_1.as_words();
    mod_exp.exponentiation(&base, r.as_words(), &mut outbuf).await;
    assert_eq!(EXPECTED_OUTPUT, outbuf);
    esp_println::println!("Yep");
}

Output on esp32c6: image

On esp32: image

playfulFence avatar Jul 02 '24 14:07 playfulFence

I don't see any "clean" way out of here. The whole async functionality depends on INTERRUPT register in RSA peripheral, which at the same time signalizes about the IDLE state of peripheral.

Maybe there's any option to add some simple "arbitration" (flag) like what event provoked the change of this reg. Just thoughts out loud anyways 😄

playfulFence avatar Jul 02 '24 14:07 playfulFence

This is very low priority so I would not spend too much effort on it right now.

jessebraham avatar Jul 02 '24 15:07 jessebraham

This is very low priority so I would not spend too much effort on it right now.

Yeah, for sure. I've only checked if this issue is still valid at all

playfulFence avatar Jul 02 '24 15:07 playfulFence