Skip to content

Commit

Permalink
Merge pull request #8 from ChocolateLoverRaj/fp-set-context
Browse files Browse the repository at this point in the history
Fp set context
  • Loading branch information
lleyton authored Dec 20, 2024
2 parents 4d56452 + 48726d6 commit d7d124b
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 67 additions & 0 deletions crosec/src/commands/fp_set_context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use std::{os::fd::AsRawFd, thread::sleep, time::Duration};

use bytemuck::{Pod, Zeroable};
use num::ToPrimitive;
use num_derive::ToPrimitive;

use crate::{ec_command::ec_command_bytemuck, EcCmdResult};

use super::CrosEcCmd;

pub type UserId = [u8; 32];

/* Version 1 of the command is "asynchronous". */
#[repr(C, align(4))]
#[derive(Pod, Zeroable, Clone, Copy, Debug)]
struct EcParamsFpContextV1 {
/**< enum fp_context_action */
action: u8,
reserved: [u8; 3],
user_id: UserId,
}

#[repr(u8)]
#[derive(ToPrimitive)]
enum FpContextAction {
Async = 0,
GetResult = 1,
}

/// Make sure that the fp mode is Reset before setting the context
/// Related: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/biod/cros_fp_device.cc#660
pub fn fp_set_context<File: AsRawFd>(file: &mut File, user_id: UserId) -> EcCmdResult<()> {
// From testing, it seems that this can be anything besides all zeroes, but we're going to use these numbers in honor of CoolStar - https://github.com/coolstar/crosfingerprint/blob/5e77307d7542218e173f24eb657b426565ed361a/fingerprint_adapter/eccmd.cpp#L140
ec_command_bytemuck(
CrosEcCmd::FpContext,
1,
&EcParamsFpContextV1 {
action: FpContextAction::Async.to_u8().unwrap(),
reserved: Default::default(),
user_id,
},
file.as_raw_fd(),
)?;
let mut tries = 20;
let delay = Duration::from_millis(100);
loop {
sleep(delay);
let result = ec_command_bytemuck(
CrosEcCmd::FpContext,
1,
&EcParamsFpContextV1 {
action: FpContextAction::GetResult.to_u8().unwrap(),
reserved: Default::default(),
user_id,
},
file.as_raw_fd(),
);
if result.is_ok() {
break result;
} else {
tries -= 1;
if tries == 0 {
break result;
}
}
}
}
2 changes: 2 additions & 0 deletions crosec/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum CrosEcCmd {
FpInfo = 0x0403,
FpFrame = 0x0404,
FpTemplate = 0x0405,
FpContext = 0x0406,
FpStats = 0x0407,
FpSetSeed = 0x0408,
FpGetEncryptionStatus = 0x0409,
Expand All @@ -36,6 +37,7 @@ pub mod fp_download;
pub mod fp_get_encryption_status;
pub mod fp_info;
pub mod fp_mode;
pub mod fp_set_context;
pub mod fp_set_seed;
pub mod fp_stats;
pub mod fp_upload_template;
Expand Down
1 change: 1 addition & 0 deletions ectool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ num-traits = "0.2.19"
image = "0.25.1"
strum = "0.26.3"
uom = "0.36.0"
hex = "0.4.3"
7 changes: 7 additions & 0 deletions ectool/src/check_user_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use crosec::commands::fp_set_context::UserId;

pub fn check_user_id(user_id_str: &str) -> Result<UserId, String> {
let mut user_id = UserId::default();
hex::decode_to_slice(user_id_str.as_bytes(), &mut user_id).map_err(|e| e.to_string())?;
Ok(user_id)
}
11 changes: 11 additions & 0 deletions ectool/src/fp_set_context_command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use crosec::commands::fp_set_context::{fp_set_context, UserId};
use crosec::CROS_FP_PATH;
use std::fs::File;

pub fn fp_context_command(user_id: UserId) -> color_eyre::Result<()> {
let mut file = File::open(CROS_FP_PATH)?;
fp_set_context(&mut file, user_id)?;
let user_id_str = hex::encode(user_id);
println!("Set FP context to user id: 0x{user_id_str}");
Ok(())
}
11 changes: 11 additions & 0 deletions ectool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ use std::fs::File;
use charge_control_subcommand::{charge_control_subcommand, ChargeControlSubcommand};
use charge_current_limit_subcommand::charge_current_limit_subcommand;
use check_seed::check_seed;
use check_user_id::check_user_id;
use clap::{Parser, Subcommand, ValueEnum};
use color_eyre::eyre::Result;
use crosec::commands::fp_info::fp_info;
use crosec::commands::fp_mode::{fp_mode, FpMode};
use crosec::commands::fp_set_context::UserId;
use crosec::commands::fp_set_seed::{fp_set_seed, FP_CONTEXT_TPM_BYTES};
use crosec::commands::fp_stats::fp_stats;
use crosec::commands::get_protocol_info::get_protocol_info;
use crosec::wait_event::{event::EcMkbpEventType, wait_event_sync};
use fp_download_subcommand::{fp_download_subcommand, FpDownloadSubcommand};
use fp_set_context_command::fp_context_command;
use fp_upload_template_command::fp_upload_template_command;
use get_uptime_info_command::get_uptime_info_commnad;
use num_traits::cast::FromPrimitive;
Expand Down Expand Up @@ -43,8 +46,10 @@ use crosec::{
mod charge_control_subcommand;
mod charge_current_limit_subcommand;
mod check_seed;
mod check_user_id;
mod fp_download_subcommand;
mod fp_get_encryption_status_command;
mod fp_set_context_command;
mod fp_upload_template_command;
mod get_uptime_info_command;

Expand Down Expand Up @@ -145,6 +150,11 @@ enum Commands {
#[arg()]
limit: u32,
},
FpSetContext {
/// A 32 byte hex string
#[arg(value_parser = check_user_id)]
user_id: UserId,
},
}

fn main() -> Result<()> {
Expand Down Expand Up @@ -348,6 +358,7 @@ fn main() -> Result<()> {
Commands::FpGetEncryptionStatus => fp_get_encryption_status_command()?,
Commands::GetUptimeInfo { device } => get_uptime_info_commnad(device)?,
Commands::ChargeCurrentLimit { limit } => charge_current_limit_subcommand(limit)?,
Commands::FpSetContext { user_id } => fp_context_command(user_id)?,
}

Ok(())
Expand Down

0 comments on commit d7d124b

Please sign in to comment.