embassy-rs/embassy · critical

PKA error

Error message

PKA error: {:?}

What it means

The PKA arithmetic driver validates every value crossing its boundary, so the underlying engine can only return Err on a hardware fault that cannot be expressed through the elliptic-curve driver traits. expect() converts that result into a panic with the debug-formatted PKA error. This is an internal invariant, not something the caller can cause with bad input.

Solutions

  1. Inspect the Debug-formatted error to identify which PKA operation failed and check the chip errata sheet for that PKA error code.
  2. Reset and reinitialize the PKA peripheral, then retry the operation.
  3. Report the case to embassy-stm32 as a driver/hardware-fault issue; there is no user-side configuration fix.
Defensive patterns

Strategy: try-catch

Try / catch

// Hardware fault surfaced as panic; no caller-side catch. Handle at fault level:
// log the Debug error payload, reset the PKA peripheral, retry once.
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| curve.mul(p, k))) {
    Ok(r) => r,
    Err(_) => { /* reset PKA, retry or abort */ unreachable_in_prod() }
} // only if unwinding is enabled; on embedded defaults, treat as fatal

Prevention

When it happens

Trigger: Calling is_on_curve(), mul(), or add() on a Pka-based elliptic-curve implementation while the PKA engine reports an Error (hardware fault, RAM corruption, or unexpected IP behavior).

Common situations: Silicon errata / PKA IP misbehavior on a given chip revision; memory corruption of PKA RAM; running the PKA without the clock/enable the HAL assumed it had set up.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/288041ebf288dadb. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/src/pka/driver.rs:108

impl<const N: usize> Aff<N> {
    fn from_ecc_point(p: &EccPoint) -> Self {
        Self {
            x: p.x[..N].try_into().unwrap(),
            y: p.y[..N].try_into().unwrap(),
        }
    }
}

/// The arithmetic driver's point: affine coordinates, or `None` for the point at infinity.
type Pt<const N: usize> = Option<Aff<N>>;

/// Every value crossing the arithmetic driver boundary is valid, so the engine can only fail
/// on a hardware fault, which there is no way to report through the driver traits.
fn expect<T>(r: Result<T, Error>) -> T {
    match r {
        Ok(v) => v,
        Err(e) => panic!("PKA error: {:?}", e),
    }
}

fn is_zero(v: &[u8]) -> bool {
    v.iter().all(|&b| b == 0)
}

/// Returns whether `v < limit`, both big-endian and of the same length.
fn less_than(v: &[u8], limit: &[u8]) -> bool {
    for (a, b) in v.iter().zip(limit) {
        if a != b {
            return a < b;
        }
    }
    false
}

/// Returns whether `v` is zero, in constant time.

View on GitHub (pinned to 463a07b963)