forked from keepkey/python-keepkey
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_bootloader.py
More file actions
160 lines (114 loc) · 5.99 KB
/
Copy pathtest_bootloader.py
File metadata and controls
160 lines (114 loc) · 5.99 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# This file is part of the TREZOR project.
#
# Copyright (C) 2012-2016 Marek Palatinus <slush@satoshilabs.com>
# Copyright (C) 2012-2016 Pavol Rusnak <stick@satoshilabs.com>
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
#
# The script has been modified for KeepKey Device.
import time
import unittest
import common
import hashlib
import binascii
import struct
from keepkeylib import messages_pb2 as proto
from keepkeylib import types_pb2 as proto_types
class TestBootloader(common.KeepKeyBootloaderTest):
def test_firmware_update_mode(self):
self.client.init_device()
self.assertEquals(self.client.features.bootloader_mode, True)
def test_signed_firmware_upload(self):
self.client.debug.fill_config()
# get storage hash so we can compare it after upload
original_flashed_firmware_hash, storage_hash = self.client.debug.read_memory_hashes()
data = open('firmware_images/signed_firmware_correct.bin', 'r').read()
firmware_hash = hashlib.sha256(data)
# erase firmware
ret = self.client.call(proto.FirmwareErase())
self.assertIsInstance(ret, proto.Success)
# upload firmware
ret = self.client.call_raw(proto.FirmwareUpload(payload_hash=firmware_hash.digest(), payload=data))
self.assertIsInstance(ret, proto.Success)
self.reconnect()
# get flashed hashes
flashed_firmware_hash, storage_hash_after = self.client.debug.read_memory_hashes()
# check that firmware hash is the same as we calculated client side
self.assertEquals(firmware_hash.hexdigest(), binascii.hexlify(flashed_firmware_hash))
# make sure config flash got copied over
self.assertEquals(storage_hash, storage_hash_after)
def test_signed_wrong_firmware_upload(self):
self.client.debug.fill_config()
# get storage hash so we can compare it after upload
original_flashed_firmware_hash, storage_hash = self.client.debug.read_memory_hashes()
data = open('firmware_images/signed_firmware_wrong.bin', 'r').read()
firmware_hash = hashlib.sha256(data)
# erase firmware
ret = self.client.call(proto.FirmwareErase())
self.assertIsInstance(ret, proto.Success)
# upload firmware
ret = self.client.call_raw(proto.FirmwareUpload(payload_hash=firmware_hash.digest(), payload=data))
self.assertIsInstance(ret, proto.Success)
self.reconnect()
# get flased hashes
flashed_firmware_hash, storage_hash_after = self.client.debug.read_memory_hashes()
# check that the flashed hash is the same as we calculated client side
self.assertEquals(firmware_hash.hexdigest(), binascii.hexlify(flashed_firmware_hash))
# make sure config flash did not get copied over
self.assertNotEquals(storage_hash, storage_hash_after)
def test_unsigned_firmware_upload(self):
# get storage hash so we can compare it after upload
original_flashed_firmware_hash, storage_hash = self.client.debug.read_memory_hashes()
data = open('firmware_images/firmware_no_magic.bin', 'r').read()
firmware_hash = hashlib.sha256(data)
# erase firmware
ret = self.client.call(proto.FirmwareErase())
self.assertIsInstance(ret, proto.Success)
# upload firmware
ret = self.client.call_raw(proto.FirmwareUpload(payload_hash=firmware_hash.digest(), payload=data))
self.assertIsInstance(ret, proto.Failure)
self.assertEquals(ret.message, 'Not valid firmware')
def test_signed_firmware_too_large_upload(self):
# get storage hash so we can compare it after upload
original_flashed_firmware_hash, storage_hash = self.client.debug.read_memory_hashes()
data = open('firmware_images/signed_firmware_correct_too_large.bin', 'r').read()
firmware_hash = hashlib.sha256(data)
# erase firmware
ret = self.client.call(proto.FirmwareErase())
self.assertIsInstance(ret, proto.Success)
# upload firmware
ret = self.client.call_raw(proto.FirmwareUpload(payload_hash=firmware_hash.digest(), payload=data))
self.assertIsInstance(ret, proto.Failure)
self.assertEquals(ret.message, 'Firmware too large')
def test_signed_firmware_corrupted_upload(self):
self.client.debug.fill_config()
# get storage hash so we can compare it after upload
original_flashed_firmware_hash, storage_hash = self.client.debug.read_memory_hashes()
data = open('firmware_images/signed_firmware_correct_corrupted.bin', 'r').read()
firmware_hash = hashlib.sha256(data)
# erase firmware
ret = self.client.call(proto.FirmwareErase())
self.assertIsInstance(ret, proto.Success)
# upload firmware
ret = self.client.call_raw(proto.FirmwareUpload(payload_hash=firmware_hash.digest(), payload=data))
self.assertIsInstance(ret, proto.Success)
self.reconnect()
# get flashed hashes
flashed_firmware_hash, storage_hash_after = self.client.debug.read_memory_hashes()
# check firmware hash written to flash is the same as we calculated client side
self.assertEquals(firmware_hash.hexdigest(), binascii.hexlify(flashed_firmware_hash))
# make sure config flash did not get copied over
self.assertNotEquals(storage_hash, storage_hash_after)
if __name__ == '__main__':
unittest.main()