Skip to content

Commit

Permalink
trying to verify rsa signed apps
Browse files Browse the repository at this point in the history
  • Loading branch information
bradjc committed May 23, 2023
1 parent c927128 commit 2284ef8
Show file tree
Hide file tree
Showing 14 changed files with 507 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ members = [
"boards/weact_f401ccu6/",
"capsules/core",
"capsules/extra",
"capsules/rsa_sw",
"chips/apollo3",
"chips/arty_e21_chip",
"chips/e310_g002",
Expand Down
1 change: 0 additions & 1 deletion boards/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ CARGO_FLAGS ?=
# https://github.com/tock/tock/pull/2847 for more details.
CARGO_FLAGS_TOCK ?= \
$(VERBOSE_FLAGS) \
-Z build-std=core,compiler_builtins \
--target=$(TARGET) \
--package $(PLATFORM) \
--target-dir=$(TARGET_DIRECTORY) $(CARGO_FLAGS)
Expand Down
2 changes: 2 additions & 0 deletions boards/hail/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ sam4l = { path = "../../chips/sam4l" }

capsules-core = { path = "../../capsules/core" }
capsules-extra = { path = "../../capsules/extra" }
rsa-sw = { path = "../../capsules/rsa_sw" }
emballoc = "0.1.2"
4 changes: 2 additions & 2 deletions boards/hail/chip_layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* Bootloader is at address 0x00000000 */
MEMORY
{
rom (rx) : ORIGIN = 0x00010000, LENGTH = 0x00020000
prog (rx) : ORIGIN = 0x00030000, LENGTH = 0x00040000
rom (rx) : ORIGIN = 0x00010000, LENGTH = 0x00030000
prog (rx) : ORIGIN = 0x00040000, LENGTH = 0x00030000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
}
44 changes: 34 additions & 10 deletions boards/hail/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ mod custom_fault_policy;

use kernel::capabilities;
use kernel::component::Component;
use kernel::deferred_call::DeferredCallClient;
use kernel::hil;
use kernel::hil::digest::Digest;
use kernel::hil::led::LedLow;
use kernel::hil::public_key_crypto::signature::SignatureVerify;
use kernel::hil::Controller;
use kernel::platform::{KernelResources, SyscallDriverLookup};
use kernel::process_checker::basic::AppCheckerSha256;
use kernel::scheduler::round_robin::RoundRobinSched;
#[allow(unused_imports)]
use kernel::{create_capability, debug, debug_gpio, static_init};
Expand Down Expand Up @@ -50,7 +51,12 @@ static mut PROCESS_PRINTER: Option<&'static kernel::process::ProcessPrinterText>
/// Dummy buffer that causes the linker to reserve enough space for the stack.
#[no_mangle]
#[link_section = ".stack_buffer"]
pub static mut STACK_MEMORY: [u8; 0x1200] = [0; 0x1200];
pub static mut STACK_MEMORY: [u8; 0x1400] = [0; 0x1400];

#[global_allocator]
static ALLOCATOR: emballoc::Allocator<16000> = emballoc::Allocator::new();

extern crate alloc;

// Function for the process console to use to reboot the board
fn reset() -> ! {
Expand Down Expand Up @@ -100,7 +106,7 @@ struct Hail {
scheduler: &'static RoundRobinSched<'static>,
systick: cortexm4::systick::SysTick,
fault_policy: &'static custom_fault_policy::CredentialedFaultPolicy,
credentials_checking_policy: &'static AppCheckerSha256,
credentials_checking_policy: &'static kernel::process_checker::rsa::AppCheckerRsa2048,
}

/// Mapping of integer syscalls to objects that implement syscalls.
Expand Down Expand Up @@ -141,7 +147,7 @@ impl KernelResources<sam4l::chip::Sam4l<Sam4lDefaultPeripherals>> for Hail {
type SyscallFilter = ();
type ProcessFault = ();
type ProcessFaultPolicy = custom_fault_policy::CredentialedFaultPolicy;
type CredentialsCheckingPolicy = AppCheckerSha256;
type CredentialsCheckingPolicy = kernel::process_checker::rsa::AppCheckerRsa2048;
type Scheduler = RoundRobinSched<'static>;
type SchedulerTimer = cortexm4::systick::SysTick;
type WatchDog = ();
Expand Down Expand Up @@ -508,18 +514,36 @@ pub unsafe fn main() {
custom_fault_policy::CredentialedFaultPolicy::new()
);

let sha256_checker_buf = static_init!([u8; 32], [0; 32]);
let sha = static_init!(
///////
// App Credential Checker
///////

let sha256_hash_buf = static_init!([u8; 32], [0; 32]);
let rsa2048_signature_buf = static_init!([u8; 256], [0; 256]);

let sha256 = static_init!(
capsules_extra::sha256::Sha256Software<'static>,
capsules_extra::sha256::Sha256Software::new()
);
kernel::deferred_call::DeferredCallClient::register(sha);
sha256.register();

let rsa2048verifier = static_init!(
rsa_sw::verifier::RsaSignatureVerifier<'static, 32, 256>,
rsa_sw::verifier::RsaSignatureVerifier::new()
);
rsa2048verifier.register();

let checker = static_init!(
AppCheckerSha256,
AppCheckerSha256::new(sha, sha256_checker_buf, false)
kernel::process_checker::rsa::AppCheckerRsa2048,
kernel::process_checker::rsa::AppCheckerRsa2048::new(
sha256,
rsa2048verifier,
sha256_hash_buf,
rsa2048_signature_buf
)
);
sha.set_client(checker);
sha256.set_client(checker);
rsa2048verifier.set_verify_client(checker);

let scheduler = components::sched::round_robin::RoundRobinComponent::new(&PROCESSES)
.finalize(components::round_robin_component_static!(NUM_PROCS));
Expand Down
14 changes: 14 additions & 0 deletions capsules/rsa_sw/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2023.

[package]
name = "rsa-sw"
version.workspace = true
authors.workspace = true
edition.workspace = true

[dependencies]
kernel = { path = "../../kernel" }
rsa = { version = "0.9.2", default-features = false, features = ["sha2"] }

78 changes: 78 additions & 0 deletions capsules/rsa_sw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
RSA Software Implementation
===========================

This crate provides a software-based implementation of RSA algorithms using
the RustCrypto RSA crate.

Dependency Tree
---------------

```
rsa-sw v0.1.0 (/Users/bradjc/git/tock/capsules/rsa_sw)
├── kernel v0.1.0 (/Users/bradjc/git/tock/kernel)
│ ├── tock-cells v0.1.0 (/Users/bradjc/git/tock/libraries/tock-cells)
│ ├── tock-registers v0.8.1 (/Users/bradjc/git/tock/libraries/tock-register-interface)
│ └── tock-tbf v0.1.0 (/Users/bradjc/git/tock/libraries/tock-tbf)
└── rsa v0.9.2
├── byteorder v1.4.3
├── const-oid v0.9.2
├── digest v0.10.7
│ ├── block-buffer v0.10.4
│ │ └── generic-array v0.14.7
│ │ └── typenum v1.16.0
│ │ [build-dependencies]
│ │ └── version_check v0.9.4
│ ├── const-oid v0.9.2
│ └── crypto-common v0.1.6
│ ├── generic-array v0.14.7 (*)
│ └── typenum v1.16.0
├── num-bigint-dig v0.8.2
│ ├── byteorder v1.4.3
│ ├── lazy_static v1.4.0
│ │ └── spin v0.5.2
│ ├── libm v0.2.7
│ ├── num-integer v0.1.45
│ │ └── num-traits v0.2.15
│ │ └── libm v0.2.7
│ │ [build-dependencies]
│ │ └── autocfg v1.1.0
│ │ [build-dependencies]
│ │ └── autocfg v1.1.0
│ ├── num-iter v0.1.43
│ │ ├── num-integer v0.1.45 (*)
│ │ └── num-traits v0.2.15 (*)
│ │ [build-dependencies]
│ │ └── autocfg v1.1.0
│ ├── num-traits v0.2.15 (*)
│ ├── rand v0.8.5
│ │ ├── rand_chacha v0.3.1
│ │ │ ├── ppv-lite86 v0.2.17
│ │ │ └── rand_core v0.6.4
│ │ └── rand_core v0.6.4
│ ├── smallvec v1.10.0
│ └── zeroize v1.6.0
├── num-integer v0.1.45 (*)
├── num-iter v0.1.43 (*)
├── num-traits v0.2.15 (*)
├── pkcs1 v0.7.5
│ ├── der v0.7.6
│ │ ├── const-oid v0.9.2
│ │ └── zeroize v1.6.0
│ ├── pkcs8 v0.10.2
│ │ ├── der v0.7.6 (*)
│ │ └── spki v0.7.2
│ │ └── der v0.7.6 (*)
│ └── spki v0.7.2 (*)
├── pkcs8 v0.10.2 (*)
├── rand_core v0.6.4
├── sha2 v0.10.6
│ ├── cfg-if v1.0.0
│ ├── cpufeatures v0.2.7
│ └── digest v0.10.7 (*)
├── signature v2.1.0
│ ├── digest v0.10.7 (*)
│ └── rand_core v0.6.4
├── spki v0.7.2 (*)
├── subtle v2.5.0
└── zeroize v1.6.0
```
4 changes: 4 additions & 0 deletions capsules/rsa_sw/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#![forbid(unsafe_code)]
#![no_std]

pub mod verifier;
106 changes: 106 additions & 0 deletions capsules/rsa_sw/src/verifier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2023.

//! RSA Signature Verifier for SHA256 hashes and RSA2048 keys.
use core::cell::Cell;
use kernel::hil;
use kernel::utilities::cells::{MapCell, OptionalCell, TakeCell};

pub struct RsaSignatureVerifier<'a, const H: usize, const S: usize> {
verified: Cell<bool>,
client: OptionalCell<&'a dyn hil::public_key_crypto::signature::ClientVerify<H, S>>,
rsa_public_key: MapCell<rsa::RsaPublicKey>,
hash_storage: TakeCell<'static, [u8; 32]>,
signature_storage: TakeCell<'static, [u8; 256]>,

deferred_call: kernel::deferred_call::DeferredCall,
}

impl<'a, const H: usize, const S: usize> RsaSignatureVerifier<'a, H, S> {
pub fn new() -> Self {
// my ACTUAL public key
let n = rsa::BigUint::parse_bytes(b"24207257266404723702480416527933364039116773666417951609465570931679686940076207109293072612569267113256147168695608811123741758650429326896362330556657608406060222154960934834802893052320574456334624928389491520892685313371199210386475223296696579831840058897720325126562243770933238678183073031561719244791265232863605896837907058881808599654200582034457810596804897754743492491685117186551986141408292570229581725243489406524879436825146596246620952685529114397828868686804212048259156058108264250596765840612650253797791010731257875056647324896013942698591287080293236802963873491363585251097167389150803020633481", 10).unwrap();
let e = rsa::BigUint::parse_bytes(b"65537", 10).unwrap();

// Incorrect public key for testing
// let n = rsa::BigUint::parse_bytes(b"34207257266404723702480416527933364039116773666417951609465570931679686940076207109293072612569267113256147168695608811123741758650429326896362330556657608406060222154960934834802893052320574456334624928389491520892685313371199210386475223296696579831840058897720325126562243770933238678183073031561719244791265232863605896837907058881808599654200582034457810596804897754743492491685117186551986141408292570229581725243489406524879436825146596246620952685529114397828868686804212048259156058108264250596765840612650253797791010731257875056647324896013942698591287080293236802963873491363585251097167389150803020633481", 10).unwrap();
// let e = rsa::BigUint::parse_bytes(b"65537", 10).unwrap();

let pub_key =
rsa::RsaPublicKey::new(n, e).map_or_else(|_e| MapCell::empty(), |v| MapCell::new(v));

Self {
verified: Cell::new(false),
client: OptionalCell::empty(),
rsa_public_key: pub_key,
hash_storage: TakeCell::empty(),
signature_storage: TakeCell::empty(),

deferred_call: kernel::deferred_call::DeferredCall::new(),
}
}
}

impl<'a> hil::public_key_crypto::signature::SignatureVerify<'a, 32, 256>
for RsaSignatureVerifier<'a, 32, 256>
{
fn set_verify_client(
&'a self,
client: &'a dyn hil::public_key_crypto::signature::ClientVerify<32, 256>,
) {
self.client.replace(client);
}

fn verify(
&'a self,
hash: &'static mut [u8; 32],
signature: &'static mut [u8; 256],
) -> Result<
(),
(
kernel::ErrorCode,
&'static mut [u8; 32],
&'static mut [u8; 256],
),
> {
if self.rsa_public_key.is_some() {
self.rsa_public_key
.map(|pub_key| {
self.verified.set(
pub_key
.verify(
rsa::Pkcs1v15Sign::new::<rsa::sha2::Sha256>(),
hash,
signature,
)
.is_ok(),
);
self.hash_storage.replace(hash);
self.signature_storage.replace(signature);
self.deferred_call.set();
Ok(())
})
.unwrap()
} else {
Err((kernel::ErrorCode::FAIL, hash, signature))
}
}
}

impl<'a> kernel::deferred_call::DeferredCallClient for RsaSignatureVerifier<'a, 32, 256> {
fn handle_deferred_call(&self) {
self.client.map(|client| {
self.hash_storage.take().map(|h| {
self.signature_storage.take().map(|s| {
client.verification_done(Ok(self.verified.get()), h, s);
});
});
});
}

fn register(&'static self) {
self.deferred_call.register(self);
}
}
1 change: 1 addition & 0 deletions kernel/src/hil/public_key_crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
pub mod keys;
pub mod rsa_math;
pub mod signature;
35 changes: 35 additions & 0 deletions kernel/src/hil/public_key_crypto/signature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

//! Interface for verifying signatures.
use crate::ErrorCode;

/// This trait provides callbacks for when the verification has completed.
pub trait ClientVerify<const H: usize, const S: usize> {
fn verification_done(
&self,
result: Result<bool, ErrorCode>,
hash: &'static mut [u8; H],
signature: &'static mut [u8; S],
);
}

/// Verify a signature.
///
/// - `H`: The length in bytes of the hash.
/// - `S`: The length in bytes of the signature.
pub trait SignatureVerify<'a, const H: usize, const S: usize> {
/// Set the client instance which will receive the `verification_done()`
/// callback.
#[allow(unused_variables)]
fn set_verify_client(&'a self, client: &'a dyn ClientVerify<H, S>) {}

// Verify the signature. Returns `Ok(())` if the signature matches.
fn verify(
&'a self,
hash: &'static mut [u8; H],
signature: &'static mut [u8; S],
) -> Result<(), (ErrorCode, &'static mut [u8; H], &'static mut [u8; S])>;
}
1 change: 1 addition & 0 deletions kernel/src/process_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//| the [AppID TRD](../../doc/reference/trd-appid.md).

pub mod basic;
pub mod rsa;

use crate::config;
use crate::debug;
Expand Down
Loading

0 comments on commit 2284ef8

Please sign in to comment.