summaryrefslogtreecommitdiff
path: root/BIOS/gen-bios-tarball
blob: 9160451da8f7d9e33e055fcf2d36b924b1d0db05 (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
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
#!/bin/bash
set -eo pipefail

help=$'Generate Tarball with Bios image and MANIFEST Script

Generates a Bios image tarball from given file as input.
Creates a MANIFEST for image verification and recreation
Packages the image and MANIFEST together in a tarball

usage: gen-bios-tarball [OPTION] <Bios FILE>...

Options:
   -o, --out <file>                Specify destination file. Defaults to
                                   `pwd`/obmc-bios.tar.gz if unspecified.
   -s, --sign <path>               Sign the image. The optional path argument specifies
                                   the private key file. Defaults to the bash variable
                                   PRIVATE_KEY_PATH if available, or else uses the
                                   open-source private key in this script.
   -m, --machine <name>            Optionally specify the target machine name of this
                                   image.
   -v, --version <name>            Specify the version of bios image file.
   -e, --extended-version <name>   Specify the Extended Version of bios image file
   -c, --compatible-name <name>    Specify the name of bios image in tarball.
                                   Default: 'image-hostfw'.
   -h, --help                      Display this help text and exit.
'

#################################################################
# It's the OpenBMC "public" private key (currently under
# meta-phosphor/recipes-phosphor/flash/files/OpenBMC.priv):
# https://gerrit.openbmc-project.xyz/c/openbmc/openbmc/+/8949/15/
# meta-phosphor/common/recipes-phosphor/flash/files/OpenBMC.priv
#
#################################################################
private_key=$'-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPvSDLu6slkP1gri
PaeQXL9ysD69J/HjbBCIQ0RPfeWBb75US1tRTjPP0Ub8CtH8ExVf8iF1ulsZA78B
zIjBYZVp9pyD6LbpZ/hjV7rIH6dTNhoVpdA+F8LzmQ7cyhHG8l2JMvdunwF2uX5k
D4WDcZt/ITKZNQNavPtmIyD5HprdAgMBAAECgYEAuQkTSi5ZNpAoWz76xtGRFSwU
zUT4wQi3Mz6tDtjKTYXasiQGa0dHC1M9F8fDu6BZ9W7W4Dc9hArRcdzEighuxoI/
nZI/0uL89iUEywnDEIHuS6D5JlZaj86/nx9YvQnO8F/seM+MX0EAWVrd5wC7aAF1
h6Fu7ykZB4ggUjQAWwECQQD+AUiDOEO+8btLJ135dQfSGc5VFcZiequnKWVm6uXt
rX771hEYjYMjLqWGFg9G4gE3GuABM5chMINuQQUivy8tAkEA/cxfy19XkjtqcMgE
x/UDt6Nr+Ky/tk+4Y65WxPRDas0uxFOPk/vEjgVmz1k/TAy9G4giisluTvtmltr5
DCLocQJBAJnRHx9PiD7uVhRJz6/L/iNuOzPtTsi+Loq5F83+O6T15qsM1CeBMsOw
cM5FN5UeMcwz+yjfHAsePMkcmMaU7jUCQHlg9+N8upXuIo7Dqj2zOU7nMmkgvSNE
5yuNImRZabC3ZolwaTdd7nf5r1y1Eyec5Ag5yENV6JKPe1Xkbb1XKJECQDngA0h4
6ATvfP1Vrx4CbP11eKXbCsZ9OGPHSgyvVjn68oY5ZP3uPsIattoN7dE2BRfuJm7m
F0nIdUAhR0yTfKM=
-----END PRIVATE KEY-----

'

do_sign=true
PRIVATE_KEY_PATH=${PRIVATE_KEY_PATH:-}
private_key_path="${PRIVATE_KEY_PATH}"
outfile=""
machine=""
version=""
extended_version=""
compatible_name="image-hostfw"

while [[ $# -gt 0 ]]; do
  key="$1"
  case $key in
    -o|--out)
      outfile="$2"
      shift 2
      ;;
    -s|--sign)
      do_sign=true
      if [[ -n "${2}"  && "${2}" != -* ]]; then
        private_key_path="$2"
        shift 2
      else
        shift 1
      fi
      ;;
    -m|--machine)
      machine="$2"
      shift 2
      ;;
    -v|--version)
      version="$2"
      shift 2
      ;;
    -e|--extended-version)
      extended_version="$2"
      shift 2
      ;;
    -c|--compatible-name)
      compatible_name="$2"
      shift 2
      ;;
    -h|--help)
      echo "$help"
      exit
      ;;
    -*)
      echo "Unrecognised option $1"
      echo "$help"
      exit
      ;;
    *)
      file="$1"
      shift 1
      ;;
  esac
done

if [ ! -f "${file}" ]; then
  echo "${file} not found, Please enter a valid Bios image file"
  echo "$help"
  exit 1
fi

if [[ -z $version ]]; then
  echo "Please provide version of image with -v option"
  exit 1
fi

if [[ -z $outfile ]]; then
  outfile=$(pwd)/obmc-bios.tar.gz
else
  if [[ $outfile != /* ]]; then
    outfile=$(pwd)/$outfile
  fi
fi

scratch_dir=$(mktemp -d)
# Remove the temp directory on exit.
# The files in the temp directory may contain read-only files, so add
# --interactive=never to skip the prompt.
trap '{ rm -r --interactive=never ${scratch_dir}; }' EXIT

if [[ "${do_sign}" == true ]]; then
  if [[ -z "${private_key_path}" ]]; then
    private_key_path=${scratch_dir}/OpenBMC.priv
    echo "${private_key}" > "${private_key_path}"
    echo "Image is NOT secure!! Signing with the open private key!"
  else
    if [[ ! -f "${private_key_path}" ]]; then
      echo "Couldn't find private key ${private_key_path}."
      exit 1
    fi

    echo "Signing with ${private_key_path}."
  fi

  public_key_file=publickey
  public_key_path=${scratch_dir}/$public_key_file
  openssl pkey -in "${private_key_path}" -pubout -out "${public_key_path}"
fi

manifest_location="MANIFEST"
files_to_sign="$manifest_location $public_key_file"

# Go to scratch_dir
cp "${file}" "${scratch_dir}/${compatible_name}"
cd "${scratch_dir}"
files_to_sign+=" ${compatible_name}"

echo "Creating MANIFEST for the image"
echo -e "purpose=xyz.openbmc_project.Software.Version.VersionPurpose.Host\n\
version=$version" > $manifest_location

echo "ExtendedVersion=${extended_version}" >> $manifest_location
echo "CompatibleName=${compatible_name}" >> $manifest_location

if [[ -n "${machine}" ]]; then
    echo -e "MachineName=${machine}" >> $manifest_location
fi

if [[ "${do_sign}" == true ]]; then
  signature_files=
  private_key_name=$(basename "${private_key_path}")
  key_type="${private_key_name%.*}"
  echo KeyType="${key_type}" >> $manifest_location
  echo HashType="RSA-SHA256" >> $manifest_location

  for file in $files_to_sign; do
    openssl dgst -sha256 -sign "${private_key_path}" -out "${file}.sig" "$file"
    signature_files="${signature_files} ${file}.sig"
  done

  if [ -n "$signature_files" ]; then
    sort_signature_files=`echo "$signature_files" | tr ' ' '\n' | sort | tr '\n' ' '`
    cat $sort_signature_files > image-full
    openssl dgst -sha256 -sign ${private_key_path} -out image-full.sig image-full
    signature_files="${signature_files} image-full.sig"
  fi

  additional_files="${signature_files}"
fi

tar -czvf $outfile $files_to_sign $additional_files
echo "Bios image tarball is at $outfile"