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