Skip to main content

Crate suit_validator

Crate suit_validator 

Source
Expand description

§SUIT Validator - CBOR Manifest Parser

A NO Std Rust implementation of the SUIT (Software Updates for Internet of Things) manifest format as defined in draft-ietf-suit-manifest.

This implementation targets draft-ietf-suit-manifest-34 of the SUIT manifest specification.

§Overview

This library provides a safe, efficient CBOR decoder for SUIT manifests for IoT firmware updates and trusted invocation scenarios. It implements complete manifest structure parsing with cryptographic signature verification.

Platform Support:

  • no_std Compatible: Designed for embedded systems and constrained devices
  • alloc feature: Optional, for enhanced debugging only

§Core Components

  • Manifest Decoder: Parses CBOR-encoded SUIT structures (see suit_decode())
  • Multiple Handlers: Process decoded components with custom logic via handler
  • Manifest Types: SUIT data structures defined in suit_manifest
  • Error Handling: Comprehensive error types in SuitError

§Quick Start (with default_crypto enabled)

Process a SUIT manifest with GenericStartHandler using closures:

use suit_validator::handler::GenericStartHandler;
use cose_minicbor::cose_keys::{CoseKey, CoseKeySetBuilder, KeyType, CoseAlg};
use suit_validator::crypto::CoseCrypto;

// Build trusted keys (CBOR-encoded COSE KeySet)
let mut keys_builder: CoseKeySetBuilder<1> = CoseKeySetBuilder::try_new()?;
let mut key = CoseKey::new(KeyType::Ec2);
key.alg(CoseAlg::ES256P256);
key.x(x_bytes)?;
key.y(y_bytes)?;
keys_builder.push_key(key)?;
let keys = keys_builder.into_bytes()?;
let mut crypto = CoseCrypto::new(&keys);

// Decode and process
let data = vec![/* CBOR manifest */];
let mut handler = GenericStartHandler {
    on_envelope: |env| println!("Sequence: {}", env.manifest.sequence_number),
    on_manifest: |_| {},
};
suit_validator::suit_decode(&data, &mut handler, &mut crypto)?;

§Backend Cryptography

By default, this library uses the cose_minicbor crate as its cryptographic backend. The default enabled features include:

  • "hmac" — HMAC-based signatures
  • "decrypt" — COSE decryption support
  • "es256" — ECDSA P-256 signatures (ES256)
  • "sha256" — SHA-256 digest computation

The backend is automatically used when creating a CoseCrypto instance:

use suit_validator::crypto::CoseCrypto;

// `keys` is a CBOR-encoded array of COSE keys
let mut crypto = CoseCrypto::new(&keys);

If you need to override the default cryptography implementation, implement the crypto::SuitCrypto trait and pass your instance to suit_decode(). This allows using custom algorithms, hardware security modules (HSMs), or platform-specific crypto engines.

§Custom Handler Implementation

Implement handler::SuitStartHandler, handler::SuitCommandHandler or handler::SuitSharedSequenceHandler to inspect manifests directly. All iterators contain flat_seq::PairView objects for lazy decoding:

use suit_validator::handler::SuitCommandHandler;
use suit_validator::suit_manifest::SuitCondition;
use suit_validator::SuitError;
use suit_validator::flat_seq::PairView;

struct Inspector;

impl SuitCommandHandler for Inspector {
    fn on_conditions<'a>(
        &mut self,
        conditions: impl Iterator<Item = PairView<'a, SuitCondition>>,
    ) -> Result<(), SuitError> {
        for pair in conditions {
            // pair.key = command code (no decode cost)
            // pair.get() = decode only if needed
            if pair.key == 3 {
                if let Ok(cond) = pair.get() {
                    println!("Image match condition");
                }
            }
        }
        Ok(())
    }
    // ... implement other methods
}

Benefits: Selective decoding, early filtering, error resilience, performance. This is the recommended pattern for manifest processing.

§Security Considerations

This library enforces critical security requirements from RFC 9124:

  • Signature Verification: All manifests are cryptographically signed (Section 6.2)
  • TOCTOU Protection: Digest is verified before cryptographic operations (Section 8.3)
  • Rollback Protection: Sequence numbers prevent downgrade attacks
  • Compatibility Checking: Vendor/class IDs must match device

See SuitError for possible error conditions.

§Handler Reference

All handlers are trait-based for flexibility, with convenient generic implementations for closure-based processing:

HandlerPurposeClosure Fields
handler::SuitStartHandlerProcess top-level envelope or bare manifestN/A (implement trait)
handler::GenericStartHandlerClosure wrapper for start handlingon_envelope, on_manifest
handler::SuitCommandHandlerProcess command sequences (fetch, install, etc.)N/A (implement trait)
handler::GenericCommandHandlerClosure wrapper for command sequenceson_cond, on_dir, on_custom
handler::SuitSharedSequenceHandlerProcess shared sequence metadataN/A (implement trait)
handler::GenericSharedSequenceHandlerClosure wrapper for shared sequenceson_cond, on_com

Choose:

  • Trait implementation for complex stateful processing with PairView inspection
  • Generic handlers for simple closure-based callbacks

§References

Modules§

crypto
This module defines the crypto trait handler for the suit manifest processing. You can either use your own crypto backend supplying the two
handler
suit_manifest
SUIT Manifest Data Structures

Structs§

SuitError

Functions§

suit_decode
Decodes a SUIT manifest from CBOR bytes and dispatches to a handler.