Project

General

Profile

Flashing » History » Version 8

xilokar, 05/07/2022 06:59 AM

1 1 tsaitgaist
h1. Flashing
2
3
There are several way to flash partitions (e.g. updating) manually:
4
* using @/usr/sbin/ubiupdatevol@:
5
<pre>
6
ubiupdatevol version 1.2 - a tool to write data to UBI volumes.
7
8
Usage: ubiupdatevol <UBI volume node file name> [-t] [-s <size>] [-h] [-V] [--truncate]
9
			[--size=<size>] [--help] [--version] <image file>
10
11
Example 1: ubiupdatevol /dev/ubi0_1 fs.img - write file "fs.img" to UBI volume /dev/ubi0_1
12
Example 2: ubiupdatevol /dev/ubi0_1 -t - wipe out UBI volume /dev/ubi0_1
13
14
-t, --truncate             truncate volume (wipe it out)
15
-s, --size=<bytes>         bytes in input, if not reading from file
16
-h, --help                 print help message
17
-V, --version              print program version
18
</pre>
19
* using @/APP/dev_only/swupd.sh@
20
<pre>
21
swupd.sh - update flash partitions on the target
22
23
Easy mode:
24
   using NFS: swupd.sh -i<IP> -p<PATH>
25
   where:
26
   <IP>   = IP address of your VM (defaults to 192.168.16.18)
27
   <PATH> = path of NFS directory (defaults to /home/femto/ftpdata)
28
29
   using wget: swupd.sh -w<URL>
30
   where:
31
   <URL>  = URL to fetch images from (e.g. ftp://user:pass@host/path)
32
33
Expert mode: (stay away from them!)
34
   -k update kernel
35
   -r update root fs
36
   -a update application partition
37
   -u update unitdata partition
38
   -c update caldata partition
39
   -x toggle banks
40
   -z don't reboot after successful update
41
42
   -o<str> Pass option string <str> to wget
43
</pre>
44
45 2 tsaitgaist
@/etc/init.d/flash_update@ takes care of flashing all partitions at once (also done during boot in @/etc/init.d/rcS@).
46 1 tsaitgaist
47
Lastly the operator can also flash images remotely through @/APP/bin/oam_start@.
48 2 tsaitgaist
49
h1. Secure boot
50
51
h2. System
52
53
The partition signatures (kernel, rootfs, data) are stored in @/dev/mtdblock2/bootdata.ini@ (the only file in the @bootdata@ partition).
54
While @bootdata@ is not signed itself, it only contains the signatures.
55
You can also see the content using @/APP/dev_only/cat_bootdata.sh@
56
The corresponding public key seems to be burned in the OTP section of the CPU, providing secure boot (this has not been verified).
57 1 tsaitgaist
58
@bootdata.ini@ also defines which system will be booted (A or B).
59
The file is updated using @/APP/dev_only/write_bootdata.sh@
60 3 tsaitgaist
61
For the [[Bootlog]] the femtocell seems to use "secure boot":
62
# the Percello bootrom verifies the Percello bootloader:
63
<pre>
64
Percello bootrom version 1.2.8
65
...
66
Board: Secure mode
67
...
68
Secured device - OTP2: verification ...PASSED
69
Secured device - OTP3: verification ...PASSED
70
Running Percello bootloader
71
PASSED
72
</pre>
73
# the Percello bootloader loader the Sagemcom FM-loader
74
<pre>
75
Nand execute: load_addr: 3fe0000
76
77
Percello bootloader version 0.6 (from NAND)
78
</pre>
79
# the Sagemcom FM-loader verifies the signatures of the kernel, rootfs, and app partitions
80
<pre>
81
Sagemcom FM-loader v2.0.4-11
82
Boot 1 (cold) into main system, secured
83
...
84
Unit key found and verified
85
TrustStor signature check passed
86
Group A signature check passed
87
Kernel A signature check passed
88
Root file system A signature check passed
89
Application file system A signature check passed
90
</pre>
91
92
You can check if secure boot has been activated using @cat /proc/prc6000/otp_data/boot/secured@ but it is unclear how the signatures are verified.
93 2 tsaitgaist
94 5 xilokar
h2. Unlocking bootloader
95
96
*Do this at your own risk*
97
98
First grab a copy of the current bootloader
99
<pre>
100
# dd if=/dev/mtdblock0 of=/tmp/boot.bin
101
</pre>
102
Following instructions/patches are valid for this bootloader:
103
<pre>
104
$ md5sum boot.bin 
105
ae00a5f7dab5ab8f82c4d7ba5169d713  boot.bin
106
</pre>
107
extract header and first stage
108
<pre>
109
$ dd if=boot.bin bs=1  count=$((0x5500)) of=percello.bin
110
</pre>
111 6 xilokar
patch it with attachment:percello.bspatch
112 5 xilokar
<pre>
113
bspatch percello.bin percello-patched.bin percello.bspatch
114
</pre>
115
extract fm-loader
116
<pre>
117
$ dd if=boot.bin bs=1 skip=$((0x5508))  count=$((0x85af)) of=fm.bin.gz
118
$ gunzip fm.bin.gz
119
</pre>
120 6 xilokar
patch fm.bin with attachment:fm.bspatch
121 5 xilokar
<pre>
122
$ bspatch fm.bin fm-patched.bin fm.bspatch
123
</pre>
124
Then
125
<pre>
126
$ gzip fm-patched.bin
127
</pre>
128
get the size of fm-patched.bin.gz
129
write fm-header
130
<pre>
131
$ echo "00 00 00 00 xx xx xx xx" | xxd -r -p > fm-block.bin
132
</pre>
133
where xx xx xx xx being the hex size of fm-patched.bin.gz, little endian
134
135
append fm-patched.bin.gz
136
<pre>
137
$ cat fm-patched.bin.gz >> fm-block.bin
138
</pre>
139
pack header, first stage and fm
140
<pre>
141 8 xilokar
$ cat percello-patched.bin fm-block.bin > patched-bootloader.bin
142 5 xilokar
</pre>
143
pad it to 0x1c000 where we will put the stack smasher signature
144
<pre>
145
$ truncate -s $((0x1c000)) patched-bootloader.bin
146
</pre>
147 6 xilokar
append stack-smasher attachment:stacksmash-padded.bin
148 5 xilokar
<pre>
149
$ cat stacksmash-padded.bin >> patched-bootloader.bin
150
</pre>
151
The resulting binary size should be 128k
152
153
write the patched bootloader
154
<pre>
155
# dd if=patched-bootloader.bin of=/dev/mtdblock0
156
</pre>
157 7 xilokar
158
h3. tune your firmware
159
160
grab the kernel, rootfs and app paritions in use.
161
162
tune rootfs and app
163
<pre>
164
fakeroot
165
fsck.crmafs --extract=dir
166
# patch (eg: remove firewall, change shadow...)
167
mkfs.cramfs dir out.img
168
</pre>
169
170
and flash it:
171
put it on a web server with this filenames:
172
<pre>
173
$ ls femtoplug
174
appA.img, rfsA.img, uImageA
175
</pre>
176
and update it
177
<pre>
178
/APP/dev_only/swupd.sh -k -r -a -w http://xx.xx.xx.xx/femtoplug -z -x
179
</pre>
180
181 2 tsaitgaist
h2. Operator
182
183
The @unidata@ (mtd3) signature is checked in @/etc/init.d/flash_update@ (called by @/etc/init.d/rcS@) using @/boot/bc_cli -u${PARTNUM_UNITDATA} -q@ (with PARTNUM_UNITDATA=3):
184
* hash is sha1sum of 0x2000 (8192) first bytes
185
* signature is at 0x2000 (after the cramfs indicated size)
186
* public key is first 256 bytes of @/caldata/unitkey.bin@
187
188
It the signature check fails, @unidata_backup@ is used.
189
If this signature check fails too, it enters recovery mode
190
191 4 tsaitgaist
@caldata@ in mounted without check (in @/etc/init.d/flash_update@).
192
This allows to flash your own operator data:
193
# create your own key pair
194
<pre>
195
# generate 2048-bit RSA key pair
196
openssl genrsa -out key.pem 2048
197
# export public key
198
openssl rsa -in key.pem -pubout -out pubkey.pem
199
# export public key as raw bytes
200
openssl rsa -in key.pem -pubout -text 2>&1 | grep -A18 "modulus" | tail -n +2 | sed "s/[^0-9a-f]//g" | sed "s/^00//" | xxd -r -p > pubkey.bin
201
</pre>
202
# prepare the @unitdata@
203
<pre>
204
# create cramfs image
205
mkfs.cramfs unitdata_folder unitdata.bin
206
# sign partition
207
openssl dgst -sha1 -sign key.pem -out unitdata.sig unitdata.bin
208
# verify signature
209
openssl dgst -sha1 -verify pubkey.pem -signature unitdata.sig unitdata.bin
210
# append signature to image (read out by bc_cli)
211
cat unitdata.sig >> unitdata.bin
212
</pre>
213
# transfer data
214
<pre>
215
# transfer unidata image
216
scp -i /tmp/femto_id_rsa -o KexAlgorithms=diffie-hellman-group1-sha1 unitdata.bin root@192.168.23.200:/tmp/
217
# transfer public key
218
scp -i /tmp/femto_id_rsa -o KexAlgorithms=diffie-hellman-group1-sha1 pubkey.bin root@192.168.23.200:/tmp/
219
</pre>
220
# install images on femtocell (once logged in as root)
221
<pre>
222
# copy original caldata files
223
cp -r /caldata /tmp/caldata
224
# backup original keys (only do this the first time you flash caldata)
225
mv /tmp/caldata/unitkey.bin /tmp/caldata/unitkey.bin.bak
226
# write public key to unitkey.bin (used by bc_cli to verify unitdata partition)
227
cp /tmp/pubkey.bin /tmp/caldata/unitkey.bin
228
# append rest of data (not sure what it is used for)
229
dd if=/tmp/caldata/unitkey.bin.bak bs=1 skip=256 >> /tmp/caldata/unitkey.bin
230
# create caldata cramfs image
231
mkfs.cramfs /tmp/caldata /tmp/caldata.bin
232
# flash new caldata image
233
umount /caldata
234
source /etc/init.d/partnum.sh
235
ubiupdatevol /dev/ubi0_$(($PARTNUM_CALDATA-$PARTNUM_UBI_OFFS)) /tmp/caldata.bin
236
sync
237
# flash new unitdata image
238
umount /unitdata
239
ubiupdatevol /dev/ubi0_$(($PARTNUM_UNITDATA-$PARTNUM_UBI_OFFS)) /tmp/unitdata.bin
240
sync
241
# enjoy
242
reboot
243
</pre>
Add picture from clipboard (Maximum size: 48.8 MB)