-
Notifications
You must be signed in to change notification settings - Fork 792
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1. Allow loading the Entrust PQ crypto module from a shared library. 2. Add a command hierarchy of SPHINCS+ (aka `spx`) commands: - list: List keys - generate: Generate a key - export: Export the public portion of an SPX key. - import: Import a private SPX key. - sign: Sign a message with an SPX key. - verify: Verify a message with an SPX key. Signed-off-by: Chris Frantz <[email protected]> (cherry picked from commit 605a457)
- Loading branch information
Showing
12 changed files
with
417 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use anyhow::Result; | ||
use cryptoki::session::Session; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_annotate::Annotate; | ||
use std::any::Any; | ||
use std::path::PathBuf; | ||
use std::str::FromStr; | ||
|
||
use crate::commands::{BasicResult, Dispatch}; | ||
use crate::error::HsmError; | ||
use crate::module::Module; | ||
use acorn::Acorn; | ||
use sphincsplus::{EncodeKey, SphincsPlus, SpxPublicKey}; | ||
|
||
#[derive(clap::Args, Debug, Serialize, Deserialize)] | ||
pub struct Export { | ||
#[arg(short, long)] | ||
label: String, | ||
filename: PathBuf, | ||
} | ||
|
||
impl Export { | ||
fn export(&self, acorn: &Acorn) -> Result<()> { | ||
let key = acorn.get_key_info(&self.label)?; | ||
let algorithm = SphincsPlus::from_str(&key.algorithm)?; | ||
let pk = SpxPublicKey::from_bytes(algorithm, &key.public_key)?; | ||
pk.write_pem_file(&self.filename)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[typetag::serde(name = "spx-export")] | ||
impl Dispatch for Export { | ||
fn run( | ||
&self, | ||
_context: &dyn Any, | ||
hsm: &Module, | ||
_session: Option<&Session>, | ||
) -> Result<Box<dyn Annotate>> { | ||
let acorn = hsm.acorn.as_ref().ok_or(HsmError::AcornUnavailable)?; | ||
let _token = hsm.token.as_deref().ok_or(HsmError::SessionRequired)?; | ||
self.export(acorn)?; | ||
Ok(Box::<BasicResult>::default()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use anyhow::Result; | ||
use cryptoki::session::Session; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_annotate::Annotate; | ||
use std::any::Any; | ||
use std::path::PathBuf; | ||
|
||
use crate::commands::{BasicResult, Dispatch}; | ||
use crate::error::HsmError; | ||
use crate::module::Module; | ||
use crate::util::attribute::AttrData; | ||
use acorn::GenerateFlags; | ||
use sphincsplus::{EncodeKey, SphincsPlus, SpxSecretKey}; | ||
|
||
#[derive(clap::Args, Debug, Serialize, Deserialize)] | ||
pub struct Generate { | ||
#[arg(short, long)] | ||
label: String, | ||
#[arg(short, long, default_value = "SHA2-128s-simple")] | ||
algorithm: SphincsPlus, | ||
#[arg(short, long, help = "Overwrite an existing key with the same label")] | ||
overwrite: bool, | ||
#[arg(short, long, help = "Export the private key material to a file")] | ||
export: Option<PathBuf>, | ||
} | ||
|
||
#[typetag::serde(name = "spx-generate")] | ||
impl Dispatch for Generate { | ||
fn run( | ||
&self, | ||
_context: &dyn Any, | ||
hsm: &Module, | ||
_session: Option<&Session>, | ||
) -> Result<Box<dyn Annotate>> { | ||
let acorn = hsm.acorn.as_ref().ok_or(HsmError::AcornUnavailable)?; | ||
let token = hsm.token.as_deref().ok_or(HsmError::SessionRequired)?; | ||
|
||
#[rustfmt::skip] | ||
let flags = | ||
if self.overwrite { GenerateFlags::OVERWRITE } else { GenerateFlags::NONE } | ||
| if self.export.is_some() { GenerateFlags::EXPORT_PRIVATE } else { GenerateFlags::NONE }; | ||
|
||
let key = acorn.generate_key(&self.label, &self.algorithm.to_string(), token, flags)?; | ||
|
||
if let Some(path) = &self.export { | ||
let sk = SpxSecretKey::from_bytes(self.algorithm, &key.private_key)?; | ||
sk.write_pem_file(path)?; | ||
} | ||
|
||
Ok(Box::new(BasicResult { | ||
success: true, | ||
id: AttrData::Str(key.hash.expect("key hash")), | ||
label: AttrData::Str(key.alias), | ||
error: None, | ||
})) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use anyhow::Result; | ||
use cryptoki::session::Session; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_annotate::Annotate; | ||
use std::any::Any; | ||
use std::path::PathBuf; | ||
|
||
use crate::commands::{BasicResult, Dispatch}; | ||
use crate::error::HsmError; | ||
use crate::module::Module; | ||
use crate::util::attribute::AttrData; | ||
use sphincsplus::{DecodeKey, SpxPublicKey, SpxSecretKey}; | ||
|
||
#[derive(clap::Args, Debug, Serialize, Deserialize)] | ||
pub struct Import { | ||
#[arg(short, long)] | ||
label: String, | ||
#[arg(short, long, help = "Overwrite an existing key with the same label")] | ||
overwrite: bool, | ||
filename: PathBuf, | ||
} | ||
|
||
#[typetag::serde(name = "spx-import")] | ||
impl Dispatch for Import { | ||
fn run( | ||
&self, | ||
_context: &dyn Any, | ||
hsm: &Module, | ||
_session: Option<&Session>, | ||
) -> Result<Box<dyn Annotate>> { | ||
let acorn = hsm.acorn.as_ref().ok_or(HsmError::AcornUnavailable)?; | ||
let token = hsm.token.as_deref().ok_or(HsmError::SessionRequired)?; | ||
|
||
let sk = SpxSecretKey::read_pem_file(&self.filename)?; | ||
let pk = SpxPublicKey::from(&sk); | ||
|
||
let key = acorn.import_keypair( | ||
&self.label, | ||
&sk.algorithm().to_string(), | ||
token, | ||
self.overwrite, | ||
pk.as_bytes(), | ||
sk.as_bytes(), | ||
)?; | ||
Ok(Box::new(BasicResult { | ||
success: true, | ||
id: AttrData::Str(key.hash.expect("key hash")), | ||
label: AttrData::Str(key.alias), | ||
error: None, | ||
})) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use anyhow::Result; | ||
use cryptoki::session::Session; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_annotate::Annotate; | ||
use std::any::Any; | ||
|
||
use crate::commands::Dispatch; | ||
use crate::error::HsmError; | ||
use crate::module::Module; | ||
|
||
#[derive(clap::Args, Debug, Serialize, Deserialize)] | ||
pub struct List {} | ||
|
||
#[derive(Default, Debug, Serialize)] | ||
pub struct Key { | ||
pub id: String, | ||
pub label: String, | ||
pub algorithm: String, | ||
} | ||
|
||
#[derive(Default, Debug, Serialize)] | ||
pub struct ListResult { | ||
host_version: String, | ||
see_version: String, | ||
objects: Vec<Key>, | ||
} | ||
|
||
#[typetag::serde(name = "spx-list")] | ||
impl Dispatch for List { | ||
fn run( | ||
&self, | ||
_context: &dyn Any, | ||
hsm: &Module, | ||
_session: Option<&Session>, | ||
) -> Result<Box<dyn Annotate>> { | ||
let acorn = hsm.acorn.as_ref().ok_or(HsmError::AcornUnavailable)?; | ||
let _token = hsm.token.as_deref().ok_or(HsmError::SessionRequired)?; | ||
|
||
let mut result = Box::new(ListResult { | ||
host_version: acorn.get_version()?, | ||
see_version: acorn.get_see_version()?, | ||
..Default::default() | ||
}); | ||
let keys = acorn.list_keys()?; | ||
for key in keys { | ||
let info = acorn.get_key_info(&key.alias)?; | ||
result.objects.push(Key { | ||
id: info.hash, | ||
label: key.alias, | ||
algorithm: info.algorithm, | ||
}); | ||
} | ||
Ok(result) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use anyhow::Result; | ||
use cryptoki::session::Session; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_annotate::Annotate; | ||
use std::any::Any; | ||
|
||
use crate::commands::Dispatch; | ||
use crate::module::Module; | ||
|
||
pub mod export; | ||
pub mod generate; | ||
pub mod import; | ||
pub mod list; | ||
pub mod sign; | ||
pub mod verify; | ||
|
||
#[derive(clap::Subcommand, Debug, Serialize, Deserialize)] | ||
pub enum Spx { | ||
Generate(generate::Generate), | ||
Export(export::Export), | ||
Import(import::Import), | ||
List(list::List), | ||
Sign(sign::Sign), | ||
Verify(verify::Verify), | ||
} | ||
|
||
#[typetag::serde(name = "__spx__")] | ||
impl Dispatch for Spx { | ||
fn run( | ||
&self, | ||
context: &dyn Any, | ||
hsm: &Module, | ||
session: Option<&Session>, | ||
) -> Result<Box<dyn Annotate>> { | ||
match self { | ||
Spx::Generate(x) => x.run(context, hsm, session), | ||
Spx::Export(x) => x.run(context, hsm, session), | ||
Spx::Import(x) => x.run(context, hsm, session), | ||
Spx::List(x) => x.run(context, hsm, session), | ||
Spx::Sign(x) => x.run(context, hsm, session), | ||
Spx::Verify(x) => x.run(context, hsm, session), | ||
} | ||
} | ||
fn leaf(&self) -> &dyn Dispatch | ||
where | ||
Self: Sized, | ||
{ | ||
match self { | ||
Spx::Generate(x) => x.leaf(), | ||
Spx::Export(x) => x.leaf(), | ||
Spx::Import(x) => x.leaf(), | ||
Spx::List(x) => x.leaf(), | ||
Spx::Sign(x) => x.leaf(), | ||
Spx::Verify(x) => x.leaf(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use anyhow::Result; | ||
use cryptoki::session::Session; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_annotate::Annotate; | ||
use std::any::Any; | ||
use std::path::PathBuf; | ||
|
||
use crate::commands::{BasicResult, Dispatch}; | ||
use crate::error::HsmError; | ||
use crate::module::Module; | ||
use crate::util::helper; | ||
|
||
#[derive(clap::Args, Debug, Serialize, Deserialize)] | ||
pub struct Sign { | ||
#[arg(long)] | ||
id: Option<String>, | ||
#[arg(short, long)] | ||
label: Option<String>, | ||
#[arg(short, long)] | ||
output: PathBuf, | ||
input: PathBuf, | ||
} | ||
|
||
#[typetag::serde(name = "spx-sign")] | ||
impl Dispatch for Sign { | ||
fn run( | ||
&self, | ||
_context: &dyn Any, | ||
hsm: &Module, | ||
_session: Option<&Session>, | ||
) -> Result<Box<dyn Annotate>> { | ||
let acorn = hsm.acorn.as_ref().ok_or(HsmError::AcornUnavailable)?; | ||
let _token = hsm.token.as_deref().ok_or(HsmError::SessionRequired)?; | ||
|
||
let data = helper::read_file(&self.input)?; | ||
let result = acorn.sign(self.label.as_deref(), self.id.as_deref(), &data)?; | ||
helper::write_file(&self.output, &result)?; | ||
Ok(Box::<BasicResult>::default()) | ||
} | ||
} |
Oops, something went wrong.