Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for FIPS option #460

Merged
merged 4 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/audit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
pub(crate) mod commands;
mod error;

pub use self::error::{Error, ErrorKind};
pub use self::{
commands::{LogDigest, LogEntries, LogEntry},
error::{Error, ErrorKind},
};

use crate::command;
use serde::{de, ser, Deserialize, Serialize};
Expand Down Expand Up @@ -97,6 +100,7 @@ impl<'de> Deserialize<'de> for AuditOption {
pub(crate) enum AuditTag {
Force = 0x01,
Command = 0x03,
Fips = 0x05,
}

impl AuditTag {
Expand All @@ -105,6 +109,7 @@ impl AuditTag {
Ok(match byte {
0x01 => AuditTag::Force,
0x03 => AuditTag::Command,
0x05 => AuditTag::Fips,
_ => fail!(ErrorKind::TagInvalid, "invalid audit tag value: {}", byte),
})
}
Expand All @@ -129,7 +134,7 @@ impl<'de> Deserialize<'de> for AuditTag {
type Value = AuditTag;

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("an unsigned byte with values 0x01 or 0x03")
formatter.write_str("an unsigned byte with values 0x01, 0x03, or 0x05")
}

fn visit_u8<E: de::Error>(self, value: u8) -> Result<AuditTag, E> {
Expand Down
1 change: 1 addition & 0 deletions src/audit/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ mod get_option;
mod set_log_index;
mod set_option;

pub use self::get_log_entries::{LogDigest, LogEntries, LogEntry};
pub(crate) use self::{get_log_entries::*, get_option::*, set_log_index::*, set_option::*};
35 changes: 35 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,25 @@ impl Client {
.map_err(|e| format_err!(ErrorKind::ProtocolError, e).into())
}

/// Get the FIPS operation global option
///
/// <https://developers.yubico.com/YubiHSM2/Commands/Get_Option.html>
pub fn get_fips_option(&self) -> Result<AuditOption, Error> {
let response = self.send_command(GetOptionCommand {
tag: AuditTag::Fips,
})?;

ensure!(
response.0.len() == 1,
ErrorKind::ProtocolError,
"expected 1-byte response, got {}",
response.0.len()
);

AuditOption::from_u8(response.0[0])
.map_err(|e| format_err!(ErrorKind::ProtocolError, e).into())
}

/// Get some number of bytes of pseudo random data generated on the device.
///
/// <https://developers.yubico.com/YubiHSM2/Commands/Get_Pseudo_Random.html>
Expand Down Expand Up @@ -900,6 +919,22 @@ impl Client {
Ok(())
}

/// Put the FIPS global option: when enabled, it disables algorithms that are
/// not allowed by FIPS 140.
///
/// Options are `Off`, or `On`
///
/// <https://developers.yubico.com/YubiHSM2/Commands/Put_Option.html>
pub fn set_fips_option(&self, option: AuditOption) -> Result<(), Error> {
self.send_command(SetOptionCommand {
tag: AuditTag::Fips,
length: 1,
value: vec![option.to_u8()],
})?;

Ok(())
}

/// Set the index of the last consumed index of the HSM audit log.
///
/// <https://developers.yubico.com/YubiHSM2/Commands/Set_Log_Index.html>
Expand Down
5 changes: 5 additions & 0 deletions src/mockhsm/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ fn get_option(state: &State, cmd_data: &[u8]) -> response::Message {
let results = match command.tag {
AuditTag::Command => state.command_audit_options.serialize(),
AuditTag::Force => vec![state.force_audit.to_u8()],
AuditTag::Fips => vec![state.fips.to_u8()],
};

GetOptionResponse(results).serialize()
Expand Down Expand Up @@ -572,6 +573,10 @@ fn put_option(state: &mut State, cmd_data: &[u8]) -> response::Message {
.command_audit_options
.put(audit_cmd.command_type(), audit_cmd.audit_option());
}
AuditTag::Fips => {
assert_eq!(length, 1);
state.fips = AuditOption::from_u8(value[0]).unwrap()
}
}

PutOptionResponse {}.serialize()
Expand Down
4 changes: 4 additions & 0 deletions src/mockhsm/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub(crate) struct State {
/// via the `SetLogIndex` command.
pub(super) force_audit: AuditOption,

/// Fips mode
pub(super) fips: AuditOption,

/// Active sessions with the MockHsm
sessions: BTreeMap<session::Id, HsmSession>,

Expand All @@ -35,6 +38,7 @@ impl State {
Self {
command_audit_options: CommandAuditOptions::default(),
force_audit: AuditOption::Off,
fips: AuditOption::Off,
sessions: BTreeMap::new(),
objects: Objects::default(),
}
Expand Down
Loading