1#!/usr/bin/env python3 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2021, Huawei Technologies Co., Ltd 5# 6 7from cryptography.hazmat.backends import default_backend 8from cryptography.hazmat.primitives import hashes 9from elftools.elf.elffile import ELFFile 10from elftools.elf.sections import SymbolTableSection 11import codecs 12import sys 13 14verbose = False 15 16 17def dump(buf): 18 print(codecs.encode(buf, 'hex').decode('utf-8')) 19 20 21def resolve_symbol(elf, name): 22 for section in elf.iter_sections(): 23 if isinstance(section, SymbolTableSection): 24 for symbol in section.iter_symbols(): 25 if symbol.name == name: 26 return symbol.entry['st_value'] 27 raise RuntimeError(f'Symbol {name} not found') 28 29 30def hash_range(h, elf, start, end): 31 global verbose 32 start_addr = resolve_symbol(elf, start) 33 end_addr = resolve_symbol(elf, end) 34 size = end_addr - start_addr 35 if verbose: 36 print(f'[{start}(0x{start_addr:x}), {end}(0x{end_addr:x})]: ' 37 f'{size} bytes') 38 for segment in elf.iter_segments(): 39 if (segment['p_type'] == 'PT_LOAD' and 40 segment['p_vaddr'] <= start_addr and 41 end_addr <= segment['p_vaddr'] + segment['p_filesz']): 42 begin_offs = start_addr - segment['p_vaddr'] 43 h.update(segment.data()[begin_offs:begin_offs + size]) 44 45 46def hash_section(h, elf, name): 47 global verbose 48 s = elf.get_section_by_name(name) 49 if s is None: 50 return 51 d = s.data() 52 if verbose: 53 print(f'{name}: {len(d)} bytes') 54 h.update(d) 55 56 57def main(): 58 global verbose 59 argc = len(sys.argv) 60 if argc != 2 and argc != 3: 61 print('Usage:', sys.argv[0], '<tee.elf>') 62 return 1 63 64 if argc == 3 and sys.argv[1] == '-v': 65 verbose = True 66 67 with open(sys.argv[argc - 1], 'rb') as f: 68 elf = ELFFile(f) 69 h = hashes.Hash(hashes.SHA256(), default_backend()) 70 hash_range(h, elf, '__text_start', '__text_data_start') 71 hash_range(h, elf, '__text_data_end', '__text_end') 72 hash_section(h, elf, '.text_init') 73 hash_section(h, elf, '.text_pageable') 74 hash_section(h, elf, '.rodata') 75 hash_section(h, elf, '.rodata_init') 76 hash_section(h, elf, '.rodata_pageable') 77 dump(h.finalize()) 78 79 80if __name__ == "__main__": 81 main() 82