Remy S
Remy S

Reputation: 63

recompute ima-ng template hash

I am trying to recompute the template hash (ima-ng) in my IMA event log but it seems I am missing something. ima-doc-ima-mg-template

I have being trying the whole day, but really I don't see where I go wrong, I would greatly use some help over here. I have tried to extend the computed value with my previous PCR value (the template hash of the boot aggregate) with no luck.

azureuser@tdx24:~$ sudo cat /sys/kernel/security/ima/ascii_runtime_measurements
10 1ddcc863e454c492100cbcc76c62204b8db350c4 ima-ng sha256:4f9ffcc1525d34d6d029cfea50dfd7e830ad66f6e2d7d3e8a3209921721a0cd3 boot_aggregate
10 65a3a4458c5368168e6625e1ce7bde75c888d450 ima-ng sha256:bd23bde4dff524631fb25d73bb3df9d57a551303b9b4a2e990a6407ec74612b0 /usr/lib/modules/6.8.0-1020-azure/kernel/fs/autofs/autofs4.ko.zst
import hashlib
import struct
import re

def compute_template_hash(file_hash_hex, file_path):
    # Construct d-ng
    hash_alg = b"sha256:\x00"  # Fixed: Use bytes directly
    file_hash = bytes.fromhex(file_hash_hex)
    hash_length = len(hash_alg) + len(file_hash)
    d_ng = struct.pack(">I", hash_length) + hash_alg + file_hash
    
    # Debug d-ng (hex and bytes)
    print(f"d-ng (hex): {d_ng.hex()}")
    print(f"d-ng (bytes): {d_ng}")
    
    # Construct n-ng
    file_name_bytes = file_path.encode("utf-8") + b"\x00"  # Ensure null terminator is added
    file_name_length = len(file_name_bytes)
    
    # Debug file name
    print(f"File path (encoded): {file_name_bytes}")
    print(f"File path length (including null terminator): {file_name_length}")
    
    n_ng = struct.pack(">I", file_name_length) + file_name_bytes
    
    # Debug n-ng (hex and bytes)
    print(f"n-ng (hex): {n_ng.hex()}")
    print(f"n-ng (bytes): {n_ng}")
    
    # Combine d-ng and n-ng
    combined = d_ng + n_ng
    
    # Debug combined structure
    print(f"Combined (hex): {combined.hex()}")
    print(f"Combined (bytes): {combined}")
    
    # Compute SHA1
    computed_hash = hashlib.sha1(combined).hexdigest()
    return computed_hash

# Example log entry
log_entry = "10 65a3a4458c5368168e6625e1ce7bde75c888d450 ima-ng sha256:bd23bde4dff524631fb25d73bb3df9d57a551303b9b4a2e990a6407ec74612b0 /usr/lib/modules/6.8.0-1020-azure/kernel/fs/autofs/autofs4.ko.zst"

# Parse log entry
match = re.match(r"10\s+([a-f0-9]+)\s+ima-ng\s+(\w+):([a-f0-9]+)\s+(.+)$", log_entry)
if match:
    template_hash_expected = match.group(1)
    file_hash_hex = match.group(3)
    file_path = match.group(4)
    
    # Verify path length
    print(f"File path length: {len(file_path)} characters")
    
    # Compute template hash
    computed_hash = compute_template_hash(file_hash_hex, file_path)
    print(f"Expected: {template_hash_expected}")
    print(f"Computed: {computed_hash}")
else:
    print("Log entry format invalid")

File path length: 65 characters
d-ng (hex): 000000287368613235363a00bd23bde4dff524631fb25d73bb3df9d57a551303b9b4a2e990a6407ec74612b0
d-ng (bytes): b'\x00\x00\x00(sha256:\x00\xbd#\xbd\xe4\xdf\xf5$c\x1f\xb2]s\xbb=\xf9\xd5zU\x13\x03\xb9\xb4\xa2\xe9\x90\xa6@~\xc7F\x12\xb0'
File path (encoded): b'/usr/lib/modules/6.8.0-1020-azure/kernel/fs/autofs/autofs4.ko.zst\x00'
File path length (including null terminator): 66
n-ng (hex): 000000422f7573722f6c69622f6d6f64756c65732f362e382e302d313032302d617a7572652f6b65726e656c2f66732f6175746f66732f6175746f6673342e6b6f2e7a737400
n-ng (bytes): b'\x00\x00\x00B/usr/lib/modules/6.8.0-1020-azure/kernel/fs/autofs/autofs4.ko.zst\x00'
Combined (hex): 000000287368613235363a00bd23bde4dff524631fb25d73bb3df9d57a551303b9b4a2e990a6407ec74612b0000000422f7573722f6c69622f6d6f64756c65732f362e382e302d313032302d617a7572652f6b65726e656c2f66732f6175746f66732f6175746f6673342e6b6f2e7a737400
Combined (bytes): b'\x00\x00\x00(sha256:\x00\xbd#\xbd\xe4\xdf\xf5$c\x1f\xb2]s\xbb=\xf9\xd5zU\x13\x03\xb9\xb4\xa2\xe9\x90\xa6@~\xc7F\x12\xb0\x00\x00\x00B/usr/lib/modules/6.8.0-1020-azure/kernel/fs/autofs/autofs4.ko.zst\x00'
Expected: 65a3a4458c5368168e6625e1ce7bde75c888d450
Computed: 1ddae0b6c9e5a88aff55c9fab2b8f18ad0d58728


** Process exited - Return Code: 0 **
Press Enter to exit terminal

Upvotes: 1

Views: 18

Answers (1)

Remy S
Remy S

Reputation: 63

PCR index and lengths, are stored in little-endian byte order from TCG specs: [TCG][1]

d_ng = struct.pack("<I", hash_length) + hash_alg + file_hash
n_ng = struct.pack("<I", file_name_length) + file_name_bytes
Expected: 65a3a4458c5368168e6625e1ce7bde75c888d450
Computed: 65a3a4458c5368168e6625e1ce7bde75c888d450


** Process exited - Return Code: 0 **
Press Enter to exit terminal

Upvotes: 1

Related Questions