hc
2025-02-14 bbb9540dc49f70f6b703d1c8d1b85fa5f602d86e
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/bin/bash
 
set -e
 
KEYS=avb_keys
PRODUCT_ID=0123456789ABCDE
SCRIPTS=scripts
OUT=out
 
usage()
{
   echo "$0 [ -n/f/s/d/l/u/h or --su_pswd]"
   echo "    n    < Product id > #16 bytes"
   echo "        Generate new AVB keys"
   echo "    f    < /path/to/secureboot/private/key >"
   echo "        Config efuse device"
   echo "        Must generated keys [-n] firstly"
   echo "    s    Sign file"
   echo "        [ -b < /path/to/boot.img > ]: Sign boot.img"
   echo "        [ -r < /path/to/recovery.img > ]: Sign recovery.img"
   echo "    d    Download permanent_attributes.bin to OTP or RPMB"
   echo "    l    Lock device"
   echo "    u    Unlock device"
   echo "    h    Show this context"
   echo "    --su_pswd    Set super user password for fastboot"
}
 
Generate_keys()
{
   # generate config file
   touch $KEYS/temp.bin
   echo -n $PRODUCT_ID > $KEYS/product_id.bin
   # generate test keys
   openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM -out $KEYS/testkey_prk.pem
   openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM -out $KEYS/testkey_psk.pem
   openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM -out $KEYS/testkey_pik.pem
   openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM -out $KEYS/testkey_puk.pem
 
   # generate certificate.bin and metadata
   python $SCRIPTS/avbtool make_atx_certificate --output=avb_keys/pik_certificate.bin --subject=avb_keys/temp.bin --subject_key=avb_keys/testkey_pik.pem --subject_is_intermediate_authority --subject_key_version 42 --authority_key=avb_keys/testkey_prk.pem
   python $SCRIPTS/avbtool make_atx_certificate --output=avb_keys/psk_certificate.bin --subject=avb_keys/product_id.bin --subject_key=avb_keys/testkey_psk.pem --subject_key_version 42 --authority_key=avb_keys/testkey_pik.pem
   python $SCRIPTS/avbtool make_atx_certificate --output=avb_keys/puk_certificate.bin --subject=avb_keys/product_id.bin --subject_key=avb_keys/testkey_puk.pem --usage=com.google.android.things.vboot.unlock --subject_key_version 42 --authority_key=avb_keys/testkey_pik.pem
   python $SCRIPTS/avbtool make_atx_metadata --output=avb_keys/metadata.bin --intermediate_key_certificate=avb_keys/pik_certificate.bin --product_key_certificate=avb_keys/psk_certificate.bin
 
   # Generate permanent_attributes.bin
   python $SCRIPTS/avbtool make_atx_permanent_attributes --output=avb_keys/permanent_attributes.bin --product_id=avb_keys/product_id.bin --root_authority_key=avb_keys/testkey_prk.pem
   echo "Generate AVB Keys Done!!!"
}
 
signed_image()
{
   IMAGE=$1
   echo "Sign ${IMAGE}"
   SIZE=`ls $OUT/${IMAGE}.img -l | awk '{printf $5}'`
   echo "image size is ${SIZE}"
   # At least 68K greater than origin file
   # Source code (scripts/avbtool)
   # reserve some memory for (footer + vbmeta struct)
   # - MAX_VBMETA_SIZE = 64 * 1024
   # - MAX_FOOTER_SIZE = 4096
   SIZE=$[(SIZE / 4096 + 18) * 4096]
   echo "set size to ${SIZE}"
   python $SCRIPTS/avbtool add_hash_footer --image $OUT/${IMAGE}.img --partition_size ${SIZE} --partition_name ${IMAGE} --key avb_keys/testkey_psk.pem --algorithm SHA512_RSA4096
   echo "Sign $IMAGE Done"
}
 
Sign_file()
{
   while [ $# -gt 1 ]
   do
       FILE=$2
       case $1 in
           -b)
               cp $2 $OUT/boot.img
               signed_image boot
               VBMETA_CMD="${VBMETA_CMD} --include_descriptors_from_image $OUT/boot.img"
               ;;
           -r)
               cp $2 $OUT/recovery.img
               signed_image recovery
               VBMETA_CMD="${VBMETA_CMD} --include_descriptors_from_image $OUT/recovery.img"
               ;;
           *)
               echo "unknown file type"
               exit -1
               ;;
       esac
       shift 2
   done
 
   echo "Generate vbmeta.img"
   python $SCRIPTS/avbtool make_vbmeta_image --public_key_metadata $KEYS/metadata.bin ${VBMETA_CMD} --algorithm SHA256_RSA4096 --rollback_index 0 --key $KEYS/testkey_psk.pem  --output $OUT/vbmeta.img
   echo "Genrate vbmeta.img Done"
}
 
Expect_cmd_fastboot()
{
       test -z ${SU_PSWD} && exit -1
 
/usr/bin/expect << EOF
       set timeout 2
       spawn sudo ./${SCRIPTS}/fastboot $1
       expect {
           "* password for *" {send "${SU_PSWD}\r"; exp_continue;}
           "OKAY *" {send "fastboot succeed\r"}
           "rebooting...*" {send "fastboot succeed\r"}
           default {send_error "expect_timeout 2\n"; exit 1}
       }
       expect eof
EOF
}
 
Make_unlock()
{
   python $SCRIPTS/avb-challenge-verify.py raw_unlock_challenge.bin $KEYS/product_id.bin # Generate unlock_challenge.bin
   python $SCRIPTS/avbtool make_atx_unlock_credential --output=unlock_credential.bin --intermediate_key_certificate=$KEYS/pik_certificate.bin --unlock_key_certificate=$KEYS/puk_certificate.bin --challenge=unlock_challenge.bin --unlock_key=$KEYS/testkey_puk.pem
}
 
load_su_pswd()
{
   if [ ! -e $SCRIPTS/.su_pswd ]; then
       echo "Please set super user password with --su_pswd first"
       exit
   fi
 
   SU_PSWD=$(cat $SCRIPTS/.su_pswd)
}
 
case $1 in
   -n)
       if [ ${#2} != 16 ]; then
           echo "please input 16 bytes product_id behind -n !"
           exit
       fi
       PRODUCT_ID=$2
       test -d $KEYS && rm $KEYS -rf
       mkdir $KEYS
       Generate_keys
       ;;
   -f)
       if [ $# -lt 2 ]; then
           usage
           exit -1
       fi
 
       openssl dgst -sha256 -out $KEYS/permanent_attributes_cer.bin -sign $2 $KEYS/permanent_attributes.bin
 
       test -e .setting || touch .setting
       sed -i "/type=/d" .setting
       echo "type=efuse" >> .setting
       ;;
   -s)
       if [ $# -lt 3 ]; then
           usage
           exit
       fi
 
       shift 1
       test -d $OUT || mkdir $OUT
       Sign_file $@
       ;;
   --su_pswd)
       if [ $# -lt 2 ]; then
           usage
       fi
       echo -n "$2" > $SCRIPTS/.su_pswd
       ;;
   -d)
       load_su_pswd
       test -e .setting && source .setting || echo "no .setting"
       Expect_cmd_fastboot "stage ${KEYS}/permanent_attributes.bin"
       Expect_cmd_fastboot "oem fuse at-perm-attr"
       if [ "$type" = "efuse" ]; then
           Expect_cmd_fastboot "stage ${KEYS}/permanent_attributes_cer.bin"
           Expect_cmd_fastboot "oem fuse at-rsa-perm-attr"
       fi
       ;;
   -l)
       load_su_pswd
       Expect_cmd_fastboot "oem at-lock-vboot"
       Expect_cmd_fastboot "reboot"
       ;;
   -u)
       load_su_pswd
       Expect_cmd_fastboot "oem at-get-vboot-unlock-challenge"
       Expect_cmd_fastboot "get_staged raw_unlock_challenge.bin"
       Make_unlock
       Expect_cmd_fastboot "stage unlock_credential.bin"
       Expect_cmd_fastboot "oem at-unlock-vboot"
       rm raw_unlock_challenge.bin -f
       rm unlock_challenge.bin -f
       rm unlock_credential.bin -f
       Expect_cmd_fastboot "reboot"
       ;;
   *)
       usage
       ;;
esac