use std::collections::BTreeSet;
use aws_nitro_enclaves_nsm_api as nsm;
use nsm::api::{Digest, ErrorCode, Request, Response};
#[derive(Debug, borsh::BorshSerialize, borsh::BorshDeserialize, PartialEq, Eq, Clone)]
pub enum NsmErrorCode {
Success,
InvalidArgument,
InvalidIndex,
InvalidResponse,
ReadOnlyIndex,
InvalidOperation,
BufferTooSmall,
InputTooLarge,
InternalError,
}
impl From<ErrorCode> for NsmErrorCode {
fn from(e: ErrorCode) -> Self {
use ErrorCode as E;
match e {
E::Success => Self::Success,
E::InvalidArgument => Self::InvalidArgument,
E::InvalidIndex => Self::InvalidIndex,
E::InvalidResponse => Self::InvalidResponse,
E::ReadOnlyIndex => Self::ReadOnlyIndex,
E::InvalidOperation => Self::InvalidOperation,
E::BufferTooSmall => Self::BufferTooSmall,
E::InputTooLarge => Self::InputTooLarge,
E::InternalError => Self::InternalError,
}
}
}
impl From<NsmErrorCode> for ErrorCode {
fn from(e: NsmErrorCode) -> Self {
use NsmErrorCode as E;
match e {
E::Success => Self::Success,
E::InvalidArgument => Self::InvalidArgument,
E::InvalidIndex => Self::InvalidIndex,
E::InvalidResponse => Self::InvalidResponse,
E::ReadOnlyIndex => Self::ReadOnlyIndex,
E::InvalidOperation => Self::InvalidOperation,
E::BufferTooSmall => Self::BufferTooSmall,
E::InputTooLarge => Self::InputTooLarge,
E::InternalError => Self::InternalError,
}
}
}
#[derive(Debug, borsh::BorshSerialize, borsh::BorshDeserialize, Copy, Clone, PartialEq, Eq)]
pub enum NsmDigest {
SHA256,
SHA384,
SHA512,
}
impl From<Digest> for NsmDigest {
fn from(d: Digest) -> Self {
use Digest as D;
match d {
D::SHA256 => Self::SHA256,
D::SHA384 => Self::SHA384,
D::SHA512 => Self::SHA512,
}
}
}
impl From<NsmDigest> for Digest {
fn from(d: NsmDigest) -> Self {
use NsmDigest as D;
match d {
D::SHA256 => Self::SHA256,
D::SHA384 => Self::SHA384,
D::SHA512 => Self::SHA512,
}
}
}
#[derive(Debug, borsh::BorshSerialize, borsh::BorshDeserialize, PartialEq, Eq, Clone)]
pub enum NsmRequest {
DescribePCR {
index: u16,
},
ExtendPCR {
index: u16,
data: Vec<u8>,
},
LockPCR {
index: u16,
},
LockPCRs {
range: u16,
},
DescribeNSM,
Attestation {
user_data: Option<Vec<u8>>,
nonce: Option<Vec<u8>>,
public_key: Option<Vec<u8>>,
},
GetRandom,
}
impl From<Request> for NsmRequest {
fn from(req: Request) -> Self {
use Request as R;
match req {
R::DescribePCR { index } => Self::DescribePCR { index },
R::ExtendPCR { index, data } => Self::ExtendPCR { index, data },
R::LockPCR { index } => Self::LockPCR { index },
R::LockPCRs { range } => Self::LockPCRs { range },
R::DescribeNSM => Self::DescribeNSM,
R::Attestation {
user_data,
nonce,
public_key,
} => Self::Attestation {
user_data: user_data.map(|u| u.to_vec()),
nonce: nonce.map(|n| n.to_vec()),
public_key: public_key.map(|p| p.to_vec()),
},
R::GetRandom => Self::GetRandom,
_ => panic!("Un-recognized aws-nsm Request"),
}
}
}
impl From<NsmRequest> for Request {
fn from(req: NsmRequest) -> Self {
use serde_bytes::ByteBuf;
use NsmRequest as R;
match req {
R::DescribePCR { index } => Self::DescribePCR { index },
R::ExtendPCR { index, data } => Self::ExtendPCR { index, data },
R::LockPCR { index } => Self::LockPCR { index },
R::LockPCRs { range } => Self::LockPCRs { range },
R::DescribeNSM => Self::DescribeNSM,
R::Attestation {
user_data,
nonce,
public_key,
} => Self::Attestation {
user_data: user_data.map(ByteBuf::from),
nonce: nonce.map(ByteBuf::from),
public_key: public_key.map(ByteBuf::from),
},
R::GetRandom => Self::GetRandom,
}
}
}
#[derive(Debug, borsh::BorshSerialize, borsh::BorshDeserialize, PartialEq, Eq, Clone)]
pub enum NsmResponse {
DescribePCR {
lock: bool,
data: Vec<u8>,
},
ExtendPCR {
data: Vec<u8>,
},
LockPCR,
LockPCRs,
DescribeNSM {
version_major: u16,
version_minor: u16,
version_patch: u16,
module_id: String,
max_pcrs: u16,
locked_pcrs: BTreeSet<u16>,
digest: NsmDigest,
},
Attestation {
document: Vec<u8>,
},
GetRandom {
random: Vec<u8>,
},
Error(NsmErrorCode),
}
impl From<Response> for NsmResponse {
fn from(req: Response) -> Self {
use Response as R;
match req {
R::DescribePCR { lock, data } => Self::DescribePCR { lock, data },
R::ExtendPCR { data } => Self::ExtendPCR { data },
R::LockPCR => Self::LockPCR,
R::LockPCRs => Self::LockPCRs,
R::DescribeNSM {
version_major,
version_minor,
version_patch,
module_id,
max_pcrs,
locked_pcrs,
digest,
} => Self::DescribeNSM {
version_major,
version_minor,
version_patch,
module_id,
max_pcrs,
locked_pcrs,
digest: digest.into(),
},
R::Attestation { document } => Self::Attestation { document },
R::GetRandom { random } => Self::GetRandom { random },
R::Error(e) => Self::Error(e.into()),
_ => Self::Error(ErrorCode::InternalError.into()),
}
}
}
impl From<NsmResponse> for nsm::api::Response {
fn from(req: NsmResponse) -> Self {
use NsmResponse as R;
match req {
R::DescribePCR { lock, data } => Self::DescribePCR { lock, data },
R::ExtendPCR { data } => Self::ExtendPCR { data },
R::LockPCR => Self::LockPCR,
R::LockPCRs => Self::LockPCRs,
R::DescribeNSM {
version_major,
version_minor,
version_patch,
module_id,
max_pcrs,
locked_pcrs,
digest,
} => Self::DescribeNSM {
version_major,
version_minor,
version_patch,
module_id,
max_pcrs,
locked_pcrs,
digest: digest.into(),
},
R::Attestation { document } => Self::Attestation { document },
R::GetRandom { random } => Self::GetRandom { random },
R::Error(e) => Self::Error(e.into()),
}
}
}