MCPcopy Create free account
hub / github.com/Dstack-TEE/dstack / authenticode_sha384_hash

Function authenticode_sha384_hash

dstack-mr/src/kernel.rs:11–116  ·  view source on GitHub ↗

Calculates the Authenticode hash of a PE/COFF file

(data: &[u8])

Source from the content-addressed store, hash-verified

9
10/// Calculates the Authenticode hash of a PE/COFF file
11fn authenticode_sha384_hash(data: &[u8]) -> Result<Vec<u8>> {
12 let lfanew_offset = 0x3c;
13 let lfanew: u32 = read_le(data, lfanew_offset, "DOS header")?;
14
15 let pe_sig_offset = lfanew as usize;
16 let pe_sig: u32 = read_le(data, pe_sig_offset, "PE signature offset")?;
17 if pe_sig != pe::IMAGE_NT_SIGNATURE {
18 bail!("Invalid PE signature");
19 }
20
21 let coff_header_offset = pe_sig_offset + 4;
22 let optional_header_size =
23 read_le::<u16>(data, coff_header_offset + 16, "COFF header size")? as usize;
24
25 let optional_header_offset = coff_header_offset + 20;
26 let magic: u16 = read_le(data, optional_header_offset, "header magic")?;
27
28 let is_pe32_plus = magic == 0x20b;
29
30 let checksum_offset = optional_header_offset + 64;
31 let checksum_end = checksum_offset + 4;
32
33 let data_dir_offset = optional_header_offset + if is_pe32_plus { 112 } else { 96 };
34 let cert_dir_offset = data_dir_offset + (pe::IMAGE_DIRECTORY_ENTRY_SECURITY * 8);
35 let cert_dir_end = cert_dir_offset + 8;
36
37 let size_of_headers_offset = optional_header_offset + 60;
38 let size_of_headers = read_le::<u32>(data, size_of_headers_offset, "size_of_headers")? as usize;
39
40 let mut hasher = Sha384::new();
41 hasher.update(&data[0..checksum_offset]);
42 hasher.update(&data[checksum_end..cert_dir_offset]);
43 hasher.update(&data[cert_dir_end..size_of_headers]);
44
45 let mut sum_of_bytes_hashed = size_of_headers;
46
47 let num_sections_offset = coff_header_offset + 2;
48 let num_sections = read_le::<u16>(data, num_sections_offset, "number of sections")? as usize;
49
50 let section_table_offset = optional_header_offset + optional_header_size;
51 let section_size = 40;
52
53 let mut sections = Vec::with_capacity(num_sections);
54 for i in 0..num_sections {
55 let section_offset = section_table_offset + (i * section_size);
56
57 let ptr_raw_data_offset = section_offset + 20;
58 let ptr_raw_data =
59 read_le::<u32>(data, ptr_raw_data_offset, "pointer_to_raw_data")? as usize;
60
61 let size_raw_data_offset = section_offset + 16;
62 let size_raw_data =
63 read_le::<u32>(data, size_raw_data_offset, "size_of_raw_data")? as usize;
64
65 if size_raw_data > 0 {
66 sections.push((ptr_raw_data, size_raw_data));
67 }
68 }

Callers 1

rtmr1_logFunction · 0.85

Calls 3

read_leFunction · 0.85
to_vecMethod · 0.80
lenMethod · 0.45

Tested by

no test coverage detected