Get quote using Linux ConfigFS TSM interface (Linux 6.7+)
(report_data: &TdxReportData)
| 288 | |
| 289 | /// Get quote using Linux ConfigFS TSM interface (Linux 6.7+) |
| 290 | fn get_quote_via_configfs(report_data: &TdxReportData) -> Result<Vec<u8>> { |
| 291 | let configfs_path = prepare_configfs()?; |
| 292 | |
| 293 | let inblob_path = format!("{}/inblob", configfs_path); |
| 294 | let outblob_path = format!("{}/outblob", configfs_path); |
| 295 | let generation_path = format!("{}/generation", configfs_path); |
| 296 | |
| 297 | let lock_file = OpenOptions::new() |
| 298 | .write(true) |
| 299 | .open(&inblob_path) |
| 300 | .map_err(|e| TdxAttestError::Unexpected(format!("open {inblob_path}: {e}")))?; |
| 301 | |
| 302 | let ret = unsafe { libc::flock(lock_file.as_raw_fd(), libc::LOCK_EX) }; |
| 303 | if ret != 0 { |
| 304 | let err = std::io::Error::last_os_error(); |
| 305 | return Err(TdxAttestError::Unexpected(format!( |
| 306 | "flock {inblob_path}: {err}" |
| 307 | ))); |
| 308 | } |
| 309 | |
| 310 | let gen1 = read_generation(&generation_path)?; |
| 311 | write_inblob_with_retry(&inblob_path, report_data)?; |
| 312 | |
| 313 | let gen2 = wait_for_generation_change(&generation_path, gen1)?; |
| 314 | if gen2 != gen1 + 1 { |
| 315 | return Err(TdxAttestError::Busy); |
| 316 | } |
| 317 | |
| 318 | let quote = read_outblob_with_retry(&outblob_path)?; |
| 319 | |
| 320 | let gen3 = read_generation(&generation_path)?; |
| 321 | if gen3 != gen2 { |
| 322 | return Err(TdxAttestError::Busy); |
| 323 | } |
| 324 | |
| 325 | if quote.len() <= QUOTE_MIN_SIZE || quote.len() >= QUOTE_BUF_SIZE { |
| 326 | return Err(TdxAttestError::QuoteFailure(format!( |
| 327 | "invalid quote size: {}", |
| 328 | quote.len() |
| 329 | ))); |
| 330 | } |
| 331 | |
| 332 | Ok(quote) |
| 333 | } |
| 334 | |
| 335 | fn prepare_configfs() -> Result<String> { |
| 336 | if let Ok(path) = std::env::var(CONFIGFS_PATH_ENV) { |
no test coverage detected