UPSTREAM: ANDROID: binder: prevent transactions into own process.
[GitHub/LineageOS/android_kernel_samsung_universal7580.git] / scripts / fips_fmp_hmac.sh
CommitLineData
3c2a0909
S
1#!/bin/bash
2
3# fips_fmp_hmac.sh
4#
5# Author : Rohit Kothari (r.kothari@samsung.com)
6# Created on : 14 Feb 2014
7# Copyright (c) Samsung Electronics 2014
8
9# Given a vmlinux file and a System.map, this scripts finds bytes belonging to
10# Kernel Crypto within vmlinux file.(Under section .text, .init.text, .exit.text and .rodata)
11# After collecting all the bytes, it calculates a hmac(sha256) on those bytes.
12# Generated hmac is put back into a fmp rodata variable within vmlinux file itself.
13# This makes the build time hmac available at runtime, for integrity check.
14#
15# To find fmp bytes, this scripts heavily relies on output of arm-eabi-readelf.
16# If the output of arm-eabi-readelf changes in future, this script might need changes.
17#
18# Pre-conditions : $READELF, $HOSTCC variables are set.
19#
20#
21
22if test $# -ne 2; then
23 echo "Usage: $0 vmlinux System.map"
24 exit 1
25fi
26
27vmlinux_var=$1
28system_map_var=$2
29
30if [[ -z "$vmlinux_var" || -z "$system_map_var" || -z "$READELF" || -z "$HOSTCC" ]]; then
31 echo "$0 : variables not set"
32 exit 1
33fi
34
35if [[ ! -f $vmlinux_var || ! -f $system_map_var ]]; then
36 echo "$0 : files does not exist"
37 exit 1
38fi
39
40rm -f vmlinux.elf
41$READELF -S $vmlinux_var > vmlinux.elf
42
43retval=$?
44if [ $retval -ne 0 ]; then
45 echo "$0 : $READELF returned error"
46 exit 1
47fi
48
49declare -A array
50
51# FOR GENERIC CRYPTO FILES #awk fields to cut
52array[0]=".text first_fmp_text last_fmp_text \$5 \$6"
53array[1]=".rodata first_fmp_rodata last_fmp_rodata \$5 \$6"
54array[2]=".init.text first_fmp_init last_fmp_init \$4 \$5"
55array[3]=".exit.text first_fmp_exit last_fmp_exit \$4 \$5"
56
57rm -f offsets_sizes.txt
58
59#Addresses retrieved must be a valid hex
60reg='^[0-9A-Fa-f]+$'
61
62#Total bytes of all fmp sections scanned. Used later for error checking
63total_bytes=0;
64
65# For each type of Section :
66# first_addr = Address of first_fmp_text, first_fmp_rodata, etc.
67# last_addr = Address of last_fmp_text, last_fmp_rodata etc.
68# start_addr = Starting Address of a section within vmlinux
69# offset = Offset in vmlinux file where the section begins
70# file_offset = Offset in vmlinux file where the fmp bytes begins.
71# size = size of fmp bytes.
72
73# Output is offsets_sizes.txt, of the format
74# Section Name fmp_bytes_offse fmp_bytes_size
75# (in decimal) (in decimal)
76# .text 2531072 114576
77# .rodata 9289648 55388
78# : : :
79
80for i in "${array[@]}"; do
81
82 var1=var2=var3=var4=var5=""
83 first_addr=last_addr=start_addr=offset=file_offset=size=""
84 k=1
85 #This loop creates var1, var2 etc and set them to individual strings of a row in array
86 for j in $i; do
87 export var$k=$j
88 let k+=1
89 done
90
91 first_addr=`cat $system_map_var|grep -w $var2|awk '{print $1}'`
92 if [[ ! $first_addr =~ $reg ]]; then echo "$0 : first_addr invalid"; exit 1; fi
93
94 last_addr=`cat $system_map_var|grep -w $var3|awk '{print $1}'`
95 if [[ ! $last_addr =~ $reg ]]; then echo "$0 : last_addr invalid"; exit 1; fi
96
97 start_addr=`cat vmlinux.elf |grep -w "$var1 "|grep PROGBITS|awk '{print '$var4'}'`
98 if [[ ! $start_addr =~ $reg ]]; then echo "$0 : start_addr invalid"; exit 1; fi
99
100 offset=`cat vmlinux.elf |grep -w "$var1 "|grep PROGBITS|awk '{print '$var5'}'`
101 if [[ ! $offset =~ $reg ]]; then echo "$0 : offset invalid"; exit 1; fi
102
103 if [[ $((16#$first_addr)) -lt $((16#$start_addr)) ]]; then echo "$0 : first_addr < start_addr"; exit 1; fi
104
105 if [[ $((16#$last_addr)) -le $((16#$first_addr)) ]]; then echo "$0 : last_addr <= first_addr"; exit 1; fi
106
107 file_offset=`expr $((16#$offset)) + $((16#$first_addr)) - $((16#$start_addr))`
108 if [[ $file_offset -le 0 ]]; then echo "$0 : file_offset invalid"; exit 1; fi
109
110 size=`expr $((16#$last_addr)) - $((16#$first_addr))`
111 if [[ $size -le 0 ]]; then echo "$0 : fmp section size invalid"; exit 1; fi
112
113 echo "$var1 " $file_offset " " $size >> offsets_sizes.txt
114
115 let "total_bytes += `expr $((16#$last_addr)) - $((16#$first_addr))`"
116done
117
118if [[ ! -f offsets_sizes.txt ]]; then
119 echo "$0 : offset_sizes.txt does not exist"
120 exit 1
121fi
122
123rm -f fips_fmp_utils
124$HOSTCC -o fips_fmp_utils $srctree/scripts/fips_fmp_utils.c
125retval=$?
126if [ $retval -ne 0 ]; then
127 echo "$0 : $HOSTCC returned error"
128 exit 1
129fi
130
131rm -f builtime_bytes.txt #used for debugging
132rm -f builtime_bytes.bin #used for calculating hmac
133
134date_var=`date`
135echo "Created on : " $date_var > builtime_bytes.txt
136
137#Using offsets_sizes.txt, dump fmp bytes from vmlinux file into builtime_bytes.bin
138#Also gather printf's into builtime_bytes.txt, for debugging if required
139while read args; do
140 ./fips_fmp_utils -g $vmlinux_var $args builtime_bytes.bin >> builtime_bytes.txt
141 retval=$?
142 if [ $retval -ne 0 ]; then
143 echo "$0 : fips_fmp_utils : unable to gather fmp bytes from vmlinux"
144 exit 1
145 fi
146 echo "" >> builtime_bytes.txt
147done < offsets_sizes.txt # <================== offsets_sizes.txt
148
149if [[ ! -f builtime_bytes.bin ]]; then
150 echo "$0 : builtime_bytes.bin does not exist"
151 exit 1
152fi
153
154file_size=`cat builtime_bytes.bin| wc -c`
155
156# Make sure that file size of fmp_hmac.bin is as expected
157if [ $total_bytes -ne $file_size ]; then
158 echo "$0: Bytes mismatch"
159 exit 1
160fi
161
162key="The quick brown fox jumps over the lazy dog"
163
164# Now, generate the hmac.
165openssl dgst -sha256 -hmac "$key" -binary -out fmp_hmac.bin builtime_bytes.bin
166retval=$?
167if [ $retval -ne 0 ]; then
168 echo "$0 : openssl dgst command returned error"
169 exit 1
170fi
171
172# Just, for debugging, print the same hmac on console
173openssl dgst -sha256 -hmac "$key" builtime_bytes.bin
174retval=$?
175if [ $retval -ne 0 ]; then
176 echo "$0 : openssl dgst command returned error"
177 exit 1
178fi
179
180if [[ ! -f fmp_hmac.bin ]]; then
181 echo "$0 : fmp_hmac.bin does not exist"
182 exit 1
183fi
184
185file_size=`cat fmp_hmac.bin| wc -c`
186
187# hmac(sha256) produces 32 bytes of hmac
188if [ $file_size -ne 32 ]; then
189 echo "$0: Unexpected size of Hash file : " $file_size
190 exit 1
191fi
192
193
194# Now that we have the hmac, update this hmac into an rodata "builtime_fmp_hmac" varialble
195# in vmlinux file.
196# This variable has a place holder 32 bytes that will be over-written with generated hmac.
197# This way, this build time hmac, will be available as a read-only variable at run-time.
198
199first_addr=`cat $system_map_var|grep -w "builtime_fmp_hmac"|awk '{print $1}' `
200if [[ ! $first_addr =~ $reg ]]; then echo "$0 : first_addr of hmac variable invalid"; exit 1; fi
201
202start_addr=`cat vmlinux.elf |grep -w ".rodata"|grep PROGBITS|awk '{print $5}' `
203if [[ ! $start_addr =~ $reg ]]; then echo "$0 : start_addr of .rodata invalid"; exit 1; fi
204
205offset=`cat vmlinux.elf |grep -w ".rodata"|grep PROGBITS| awk '{print $6}' `
206if [[ ! $offset =~ $reg ]]; then echo "$0 : offset of .rodata invalid"; exit 1; fi
207
208if [[ $((16#$first_addr)) -le $((16#$start_addr)) ]]; then echo "$0 : hmac var first_addr <= start_addr"; exit 1; fi
209
210hmac_offset=`expr $((16#$offset)) + $((16#$first_addr)) - $((16#$start_addr))`
211if [[ $hmac_offset -le 0 ]]; then echo "$0 : hmac_offset invalid"; exit 1; fi
212
213# This does the actual update of hmac into vmlinux file, at given offset
214./fips_fmp_utils -u $vmlinux_var fmp_hmac.bin $hmac_offset
215retval=$?
216if [ $retval -ne 0 ]; then
217 echo "$0 : fips_fmp_utils : unable to update hmac in vmlinux"
218 exit 1
219fi
220
221# rm -f fmp_hmac.bin
222# rm -f builtime_bytes.txt
223# rm -f builtime_bytes.bin
224# rm -f fips_fmp_utils
225# rm -f vmlinux.elf
226# rm -f offsets_sizes.txt
227
228# And we are done...