1#!/bin/bash
2set -eo pipefail
3
4help=$'Generate Tarball with PSU image and MANIFEST Script
5usage: generate-psu-tar [OPTION] <parameter>...
6Options:
7   --image        <file>          PSU FW image
8   --version      <version>       PSU FW version
9   --model        <model>         PSU FW model
10   --manufacture  <version>       PSU FW manufacture
11   --machineName  <machineName>   Optionally specify the target machine name of this image.
12   --outfile      <filename>      Outfile name
13		                  For example : -o psufw.tar
14                                  The default outfile name is image.tar,and
15                                  "image" is what you input.
16   --sign         <path>          Sign the image. The optional path argument specifies
17                                  the private key file. Defaults to the bash variable
18                                  PRIVATE_KEY_PATH if available, or else uses the
19                                  open-source private key in this script.
20   --help                         Display this help text and exit.
21'
22
23private_key=$'-----BEGIN PRIVATE KEY-----
24MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPvSDLu6slkP1gri
25PaeQXL9ysD69J/HjbBCIQ0RPfeWBb75US1tRTjPP0Ub8CtH8ExVf8iF1ulsZA78B
26zIjBYZVp9pyD6LbpZ/hjV7rIH6dTNhoVpdA+F8LzmQ7cyhHG8l2JMvdunwF2uX5k
27D4WDcZt/ITKZNQNavPtmIyD5HprdAgMBAAECgYEAuQkTSi5ZNpAoWz76xtGRFSwU
28zUT4wQi3Mz6tDtjKTYXasiQGa0dHC1M9F8fDu6BZ9W7W4Dc9hArRcdzEighuxoI/
29nZI/0uL89iUEywnDEIHuS6D5JlZaj86/nx9YvQnO8F/seM+MX0EAWVrd5wC7aAF1
30h6Fu7ykZB4ggUjQAWwECQQD+AUiDOEO+8btLJ135dQfSGc5VFcZiequnKWVm6uXt
31rX771hEYjYMjLqWGFg9G4gE3GuABM5chMINuQQUivy8tAkEA/cxfy19XkjtqcMgE
32x/UDt6Nr+Ky/tk+4Y65WxPRDas0uxFOPk/vEjgVmz1k/TAy9G4giisluTvtmltr5
33DCLocQJBAJnRHx9PiD7uVhRJz6/L/iNuOzPtTsi+Loq5F83+O6T15qsM1CeBMsOw
34cM5FN5UeMcwz+yjfHAsePMkcmMaU7jUCQHlg9+N8upXuIo7Dqj2zOU7nMmkgvSNE
355yuNImRZabC3ZolwaTdd7nf5r1y1Eyec5Ag5yENV6JKPe1Xkbb1XKJECQDngA0h4
366ATvfP1Vrx4CbP11eKXbCsZ9OGPHSgyvVjn68oY5ZP3uPsIattoN7dE2BRfuJm7m
37F0nIdUAhR0yTfKM=
38-----END PRIVATE KEY-----
39'
40
41do_sign=false
42private_key_path="${PRIVATE_KEY_PATH}"
43image=""
44outfile=""
45version=""
46model=""
47manufacture=""
48machineName=""
49declare -a partitions=()
50
51
52while [[ $# -gt 0 ]]; do
53  key="$1"
54  case $key in
55    --image)
56      image="$2"
57      shift 2
58      ;;
59    --version)
60      version="$2"
61      shift 2
62      ;;
63    --model)
64      model="$2"
65      shift 2
66      ;;
67    --manufacture)
68      manufacture="$2"
69      shift 2
70      ;;
71    --machineName)
72      machineName="$2"
73      shift 2
74      ;;
75    --outfile)
76      outfile="$2"
77      shift 2
78      ;;
79    --sign)
80      do_sign=true
81      if [[ ! -z "${2}"  && "${2}" != -* ]]; then
82        private_key_path="$2"
83        shift 2
84      else
85        shift 1
86      fi
87      ;;
88    --help)
89      echo "$help"
90      exit
91      ;;
92    *)
93      echo "Please enter the correct parameters."
94      echo "$help"
95      exit 1
96      ;;
97  esac
98done
99
100if [ ! -f "${image}" ]; then
101  echo "Please enter a valid PSU FW image file."
102  echo "$help"
103  exit 1
104fi
105
106if [  -z "${version}" ]; then
107  echo "Please enter a valid PSU FW image version."
108  echo "$help"
109  exit 1
110fi
111
112
113if [  -z "${model}" ]; then
114  echo "Please enter a valid PSU FW image model."
115  echo "$help"
116  exit 1
117fi
118
119if [  -z "${manufacture}" ]; then
120  echo "Please enter a valid PSU FW image manufacture."
121  echo "$help"
122  exit 1
123fi
124
125if [  -z "${outfile}" ]; then
126  outfile=`pwd`/$image.tar
127else
128  outfile=`pwd`/$outfile
129fi
130
131scratch_dir=`mktemp -d`
132trap "{ rm -r ${scratch_dir}; }" EXIT
133
134if [[ "${do_sign}" == true ]]; then
135  if [[ -z "${private_key_path}" ]]; then
136    private_key_path=${scratch_dir}/OpenBMC.priv
137    echo "${private_key}" > "${private_key_path}"
138    echo "Image is NOT secure!! Signing with the open private key!"
139  else
140    if [[ ! -f "${private_key_path}" ]]; then
141      echo "Couldn't find private key ${private_key_path}."
142      exit 1
143    fi
144
145    echo "Signing with ${private_key_path}."
146  fi
147
148  public_key_file=publickey
149  public_key_path=${scratch_dir}/$public_key_file
150  openssl pkey -in "${private_key_path}" -pubout -out "${public_key_path}"
151
152  cp ${private_key_path} ${scratch_dir}/private_key
153
154fi
155
156manifest_location="MANIFEST"
157files_to_sign="$manifest_location $public_key_file $image"
158
159cp ${image} ${scratch_dir}
160cd "${scratch_dir}"
161
162echo "Creating MANIFEST for the image"
163echo -e "purpose=xyz.openbmc_project.Software.Version.VersionPurpose.PSU\nversion=$version\n\
164extended_version=model=$model,manufacture=$manufacture" > $manifest_location
165
166if [[ ! -z "${machineName}" ]]; then
167    echo -e "MachineName=${machineName}" >> $manifest_location
168fi
169
170if [[ "${do_sign}" == true ]]; then
171  private_key_name=$(basename "${private_key_path}")
172  key_type="${private_key_name%.*}"
173  echo KeyType="${key_type}" >> $manifest_location
174  echo HashType="RSA-SHA256" >> $manifest_location
175
176  for file in $files_to_sign; do
177    openssl dgst -sha256 -sign private_key -out "${file}.sig" $file
178  done
179
180  additional_files="*.sig"
181fi
182
183tar -cvf $outfile $files_to_sign $additional_files
184echo "PSU FW tarball at $outfile"
185exit
186