File: print_tee_hash.py

package info (click to toggle)
optee-os 4.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 31,560 kB
  • sloc: ansic: 441,914; asm: 12,903; python: 3,719; makefile: 1,676; sh: 238
file content (81 lines) | stat: -rwxr-xr-x 2,360 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021, Huawei Technologies Co., Ltd
#

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection
import codecs
import sys

verbose = False


def dump(buf):
    print(codecs.encode(buf, 'hex').decode('utf-8'))


def resolve_symbol(elf, name):
    for section in elf.iter_sections():
        if isinstance(section, SymbolTableSection):
            for symbol in section.iter_symbols():
                if symbol.name == name:
                    return symbol.entry['st_value']
    raise RuntimeError(f'Symbol {name} not found')


def hash_range(h, elf, start, end):
    global verbose
    start_addr = resolve_symbol(elf, start)
    end_addr = resolve_symbol(elf, end)
    size = end_addr - start_addr
    if verbose:
        print(f'[{start}(0x{start_addr:x}), {end}(0x{end_addr:x})]: '
              f'{size} bytes')
    for segment in elf.iter_segments():
        if (segment['p_type'] == 'PT_LOAD' and
                segment['p_vaddr'] <= start_addr and
                end_addr <= segment['p_vaddr'] + segment['p_filesz']):
            begin_offs = start_addr - segment['p_vaddr']
            h.update(segment.data()[begin_offs:begin_offs + size])


def hash_section(h, elf, name):
    global verbose
    s = elf.get_section_by_name(name)
    if s is None:
        return
    d = s.data()
    if verbose:
        print(f'{name}: {len(d)} bytes')
    h.update(d)


def main():
    global verbose
    argc = len(sys.argv)
    if argc != 2 and argc != 3:
        print('Usage:', sys.argv[0], '<tee.elf>')
        return 1

    if argc == 3 and sys.argv[1] == '-v':
        verbose = True

    with open(sys.argv[argc - 1], 'rb') as f:
        elf = ELFFile(f)
        h = hashes.Hash(hashes.SHA256(), default_backend())
        hash_range(h, elf, '__text_start', '__text_data_start')
        hash_range(h, elf, '__text_data_end', '__text_end')
        hash_section(h, elf, '.text_init')
        hash_section(h, elf, '.text_pageable')
        hash_section(h, elf, '.rodata')
        hash_section(h, elf, '.rodata_init')
        hash_section(h, elf, '.rodata_pageable')
        dump(h.finalize())


if __name__ == "__main__":
    main()