blob: 9d7fd87fdb68ad22956e6e7dcf9fe7fadb4452ed (
plain)
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
|
#!/bin/bash
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Abort on error.
set -e -o pipefail
# Determine script directory.
SCRIPT_DIR=$(dirname "$0")
# Load common constants and variables.
. "${SCRIPT_DIR}/common.sh"
usage() {
cat <<EOF
Usage: ${PROG} <input_firmware> <key_dir> <output_firmware>
Signs <input_firmware> with keys in <key_dir>. Outputs signed firmware to
<output_firmware>. The <input_firmware> and <output_firmware> paths should not
be the same.
For detail, reference the AMD documentation titled "OEM PSP VERSTAGE
BL FW Signing Key Pair Generation and Certificate Request Process"
http://dr/corp/drive/folders/1ySJyDgbH73W1lqrhxMvM9UYl5TtJt_mw
EOF
if [[ $# -ne 0 ]]; then
echo "$*" >&2
exit 1
else
exit 0
fi
}
# Check the arguments to make sure we have the correct number.
if [[ $# -lt 3 ]]; then
usage "Error: Too few arguments"
fi
if [[ $# -gt 3 ]]; then
usage "Error: Too many arguments"
fi
read_byte() {
local position="$1"
local file="$2"
dd if="${file}" bs=1 count=1 skip="$((16#${position}))" status=none |
hexdump -e '/1 "%X"'
}
write_byte() {
local position="$1"
local value="$2"
local file="$3"
printf "\x${value}" |
dd of="${file}" bs=1 count=1 seek="${position}" conv=notrunc status=none
}
read_dword_le() {
local position
position=$(printf -- "%d" "$1")
local file="$2"
read_byte "${position}" "${file}"
read_byte $((position + 1)) "${file}"
read_byte $((position + 2)) "${file}"
read_byte $((position + 3))
}
write_dword_le() {
local position
position=$(printf -- "%d" "$1")
local value
value=$(printf -- "%08x" "$2")
local file="$3"
write_byte "${position}" "${value:6:2}" "$file"
write_byte $((position + 1)) "${value:4:2}" "$file"
write_byte $((position + 2)) "${value:2:2}" "$file"
write_byte $((position + 3)) "${value:0:2}" "$file"
}
filesize() {
local file="$1"
stat -c %s -- "${file}"
}
copy_key_id() {
local input_file="$1"
local input_offset
input_offset=$(printf -- "%d" "$2")
local output_file="$3"
local output_offset
output_offset=$(printf -- "%d" "$4")
local id_size=16
dd if="${input_file}" skip="${input_offset}" \
of="${output_file}" seek="${output_offset}" \
bs=1 count="${id_size}" conv=notrunc status=none
}
KEYNAME=psp_verstagebl_fw_signing
main() {
local input_firmware="$1"
local key_dir="$2"
local output_firmware="$3"
if [[ "${input_firmware}" == "${output_firmware}" ]]; then
usage "Error: input and output files must not be the same"
fi
local amd_key="${key_dir}/${KEYNAME}.stkn"
local hashtype
local sig_size
local temp_sig
local temp_fw
local fw_size
local image_size
temp_sig=$(make_temp_file)
temp_fw=$(make_temp_file)
# TODO: Differentiate sizes for Picasso vs later chips
hashtype="-sha256"
sig_size=256
fw_size="$(($(filesize "${input_firmware}")))"
fw_minus_header_size="$((fw_size - 256))"
image_size="$((fw_size + sig_size))"
cp "${input_firmware}" "${temp_fw}"
# Refer to Appendix D in the AMD BIOS Signing Key Pair and Certification
# Process document for what needs to be changed in the psp_verstage header.
write_dword_le "0x14" "${fw_minus_header_size}" "${temp_fw}"
write_dword_le "0x30" "1" "${temp_fw}"
write_dword_le "0x6c" "${image_size}" "${temp_fw}"
# TODO: Need the PSP verstage signing token from AMD to verify.
copy_key_id "${amd_key}" "0x04" "${temp_fw}" "0x38"
local cmd=(
openssl dgst
"${hashtype}"
-sign "${key_dir}/${KEYNAME}.pem"
-sigopt rsa_padding_mode:pss
-sigopt rsa_pss_saltlen:-1
-out "${temp_sig}"
)
"${cmd[@]}" "${temp_fw}"
cat "${temp_fw}" "${temp_sig}" >"${output_firmware}"
echo "Complete"
}
main "$@"
|