cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
admin_sig.py
Go to the documentation of this file.
1 # /*******************************************************************************
2 # * Copyright 2016 -- 2022 IBM Corporation
3 # *
4 # * Licensed under the Apache License, Version 2.0 (the "License");
5 # * you may not use this file except in compliance with the License.
6 # * You may obtain a copy of the License at
7 # *
8 # * http://www.apache.org/licenses/LICENSE-2.0
9 # *
10 # * Unless required by applicable law or agreed to in writing, software
11 # * distributed under the License is distributed on an "AS IS" BASIS,
12 # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # * See the License for the specific language governing permissions and
14 # * limitations under the License.
15 # *******************************************************************************/
16 
17 # *
18 # * cloudFPGA
19 # * =============================================
20 # * Created: Nov 2021
21 # * Authors: FAB, WEI, NGL, DID
22 # *
23 # * Description:
24 # * Python script to create build signature file for new platform logics
25 # *
26 
27 import sys
28 import os
29 import json
30 import hashlib
31 
32 # 'hardcoded' version strings
33 # __THIS_FILE_VERSION_NUMBER__ = 3
34 # __THIS_FILE_VERSION_STRING__ = "0.0.3"
35 __THIS_FILE_ALGORITHM_VERSION = 'hc1' # hash concat version 1
36 
37 __cfp_json_path__ = '/../cFp.json'
38 __shell_type_key__ = 'cFpSRAtype'
39 __mod_type_key__ = 'cFpMOD'
40 __dcps_folder_name__ = '/dcps/'
41 __sig_file_ending__ = 'sig'
42 __admin_sig_file_name__ = 'admin'
43 
44 
45 def get_file_hash(file_path):
46  # # check right version
47  # assert __THIS_FILE_ALGORITHM_VERSION == 'hc1'
48  sha256_hash = hashlib.sha256()
49  with open(file_path, 'rb') as f:
50  # Read and update hash string value in blocks of 4K
51  for byte_block in iter(lambda: f.read(4096), b""):
52  sha256_hash.update(byte_block)
53  return sha256_hash.hexdigest()
54 
55 
56 def get_string_hash(inp_string):
57  # # check right version
58  # assert __THIS_FILE_ALGORITHM_VERSION == 'hc1'
59  sha256_hash = hashlib.sha256(inp_string.encode('utf-8'))
60  return sha256_hash.hexdigest()
61 
62 
63 def get_admin_sig_string(dcp_hash, mcs_hash, bit_hash, rpt_hash, debugging_flow=None):
64  # # check right version
65  # assert __THIS_FILE_ALGORITHM_VERSION == 'hc1'
66  new_cert_string = 'new_pl:' + str(dcp_hash) + str(mcs_hash) + str(bit_hash) + str(rpt_hash)
67  cert = hashlib.sha384(new_cert_string.encode('utf-8')).hexdigest()
68  if debugging_flow is not None:
69  print("\tnew_cert_string: {}".format(new_cert_string))
70  return cert
71 
72 
73 def main(new_mcs_file_name, new_bit_file_name, pr_verify_rpt_file_name):
74  # we print only on error
75  me_abs_dir = os.path.dirname(os.path.realpath(__file__))
76  me_abs_file = os.path.abspath(os.path.realpath(__file__))
77  cfp_json_file = me_abs_dir + __cfp_json_path__
78  debugging_flow = os.environ.get('CFP_DEBUGGING')
79  if debugging_flow is not None:
80  cfp_json_file = me_abs_dir + debugging_flow + '/cFp.json'
81  with open(cfp_json_file, 'r') as json_file:
82  cFp_data = json.load(json_file)
83 
84  # 1. check folders and file names
85  root_abs = os.path.realpath(me_abs_dir+"/../")
86  if debugging_flow is not None:
87  root_abs = os.path.realpath(me_abs_dir + debugging_flow + "/env/" + "/../")
88  cFp_data['abs_path'] = root_abs
89  dcps_folder = root_abs + __dcps_folder_name__
90  # folder should exist...
91  dcp_file_name = "3_top{}_STATIC.dcp".format(cFp_data[__mod_type_key__])
92  target_file_name = os.path.abspath(dcps_folder + "/" + dcp_file_name)
93  # meta_file_name = "3_top{}_STATIC.json".format(cFp_data[__mod_type_key__])
94  # target_meta_name = os.path.abspath(dcps_folder + "/" + meta_file_name)
95 
96  new_mcs_file_path = os.path.abspath(dcps_folder + '/' + new_mcs_file_name)
97  if not os.path.isfile(new_mcs_file_path):
98  print("[cFBuild] ERROR: {} is not a file. STOP.".format(new_mcs_file_path))
99  exit(1)
100 
101  new_bit_file_path = os.path.abspath(dcps_folder + '/' + new_bit_file_name)
102  if not os.path.isfile(new_bit_file_path):
103  print("[cFBuild] ERROR: {} is not a file. STOP.".format(new_bit_file_path))
104  exit(1)
105 
106  pr_verify_rpt_file_path = os.path.abspath(dcps_folder + '/' + pr_verify_rpt_file_name)
107  if not os.path.isfile(pr_verify_rpt_file_path):
108  print("[cFBuild] ERROR: {} is not a file. STOP.".format(pr_verify_rpt_file_path))
109  exit(1)
110  rpt_file_lines = []
111  with open(pr_verify_rpt_file_path) as rpt_in:
112  for line in rpt_in:
113  rpt_file_lines.append(line.rstrip())
114  pr_verify_str = ''.join(rpt_file_lines)
115 
116  sig_file_path = os.path.abspath(dcps_folder + '/' + __admin_sig_file_name__ + '.' + __sig_file_ending__)
117  # to have all the expected keys
118  new_sig = {'build_id': __admin_sig_file_name__, 'algorithm': __admin_sig_file_name__,
119  'file': __admin_sig_file_name__, 'pl_id': 'new_pl', 'hash': 'ignore'}
120 
121  # with open(target_meta_name, 'r') as meta_file:
122  # cur_meta = json.load(meta_file)
123  # current_cl_cert = cur_meta['cert']
124  # pl_id = cur_meta['id']
125  # for Mantles
126  # if 'pl_id' in cur_meta:
127  # pl_id = cur_meta['pl_id']
128  # new_sig['pl_id'] = pl_id
129 
130  # crete new cert
131  dcp_hash = get_file_hash(target_file_name)
132  # my_hash = get_file_hash(me_abs_file)
133  mcs_hash = get_file_hash(new_mcs_file_path)
134  bit_hash = get_file_hash(new_bit_file_path)
135  # rpt_hash = get_file_hash(pr_verify_rpt_file_path) # not file!
136  rpt_hash = get_string_hash(pr_verify_str)
137 
138  if debugging_flow is not None:
139  print("\tdcp hash: {}".format(dcp_hash))
140  print("\trpt hash: {}".format(rpt_hash))
141  print("\tbit hash: {}".format(bit_hash))
142  print("\tmcs hash: {}".format(mcs_hash))
143  # print("\tmy hash: {}".format(my_hash))
144 
145  new_sig['sig'] = get_admin_sig_string(dcp_hash, mcs_hash, bit_hash, rpt_hash, debugging_flow=debugging_flow)
146  new_sig['dcp_hash'] = dcp_hash # to check for transport errors first?
147  new_sig['mcs_hash'] = mcs_hash
148  new_sig['bit_hash'] = bit_hash
149  new_sig['rpt_hash'] = rpt_hash
150 
151  rpt_sum_line = rpt_file_lines[-1]
152  new_sig['verify_rpt'] = rpt_sum_line
153  if dcp_file_name in rpt_sum_line:
154  new_sig['verify'] = 'OK'
155  else:
156  new_sig['verify'] = 'NOK'
157 
158  with open(sig_file_path, 'w') as outfile:
159  json.dump(new_sig, outfile)
160 
161  return 0
162 
163 
164 if __name__ == '__main__':
165  # we print only on error
166  if len(sys.argv) != 4:
167  print('ERROR: Usage is {} <new-mcs-file-name> <new-bit-file-name> <pr-verify-rpt-file-name>. STOP'
168  .format(sys.argv[0]))
169  exit(1)
170  main(sys.argv[1], sys.argv[2], sys.argv[3])
171  exit(0)
172 
def get_string_hash(inp_string)
Definition: admin_sig.py:56
def main(new_mcs_file_name, new_bit_file_name, pr_verify_rpt_file_name)
Definition: admin_sig.py:73
def get_admin_sig_string(dcp_hash, mcs_hash, bit_hash, rpt_hash, debugging_flow=None)
Definition: admin_sig.py:63
def get_file_hash(file_path)
Definition: admin_sig.py:45