VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/CryptoPkg/Library/OpensslLib/configure.py@ 108793

Last change on this file since 108793 was 101291, checked in by vboxsync, 19 months ago

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 13.1 KB
Line 
1#!/usr/bin/python3
2# SPDX-License-Identifier: BSD-2-Clause-Patent
3import os
4import sys
5import json
6import shutil
7import pprint
8import argparse
9import subprocess
10
11def openssl_configure(openssldir, target, ec = True):
12 """ Run openssl Configure script. """
13 cmdline = [
14 'perl',
15 'Configure',
16 '--config=../UefiAsm.conf',
17 '--api=1.1.1',
18 '--with-rand-seed=none',
19 target,
20 'no-afalgeng',
21 'no-aria',
22 'no-async',
23 'no-autoerrinit',
24 'no-autoload-config',
25 'no-bf',
26 'no-blake2',
27 'no-camellia',
28 'no-capieng',
29 'no-cast',
30 'no-chacha',
31 'no-cmac',
32 'no-cmp',
33 'no-cms',
34 'no-ct',
35 'no-deprecated',
36 'no-des',
37 'no-dgram',
38 'no-dsa',
39 'no-dso',
40 'no-dtls',
41 'no-dtls1-method',
42 'no-dtls1_2-method',
43 'no-dynamic-engine',
44 'no-ec2m',
45 'no-engine',
46 'no-err',
47 'no-filenames',
48 'no-gost',
49 'no-hw',
50 'no-idea',
51 'no-ktls',
52 'no-makedepend',
53 'no-module',
54 'no-md4',
55 'no-mdc2',
56 'no-multiblock',
57 'no-nextprotoneg',
58 'no-pic',
59 'no-psk',
60 'no-ocb',
61 'no-ocsp',
62 'no-padlockeng',
63 'no-poly1305',
64 'no-posix-io',
65 'no-rc2',
66 'no-rc4',
67 'no-rc5',
68 'no-rfc3779',
69 'no-rmd160',
70 'no-scrypt',
71 'no-seed',
72 'no-shared',
73 'no-siphash',
74 'no-siv',
75 'no-sm2',
76 'no-sm4',
77 'no-sock',
78 'no-srp',
79 'no-srtp',
80 'no-ssl',
81 'no-ssl3-method',
82 'no-ssl-trace',
83 'no-static-engine',
84 'no-stdio',
85 'no-threads',
86 'no-tls1_3',
87 'no-ts',
88 'no-ui-console',
89 'no-whirlpool',
90 'disable-legacy',
91 ]
92 if not ec:
93 cmdline += [ 'no-ec', ]
94 print('')
95 print(f'# -*- configure openssl for {target} (ec={ec}) -*-')
96 rc = subprocess.run(cmdline, cwd = openssldir,
97 stdout = subprocess.PIPE,
98 stderr = subprocess.PIPE)
99 if rc.returncode:
100 print(rc.stdout)
101 print(rc.stderr)
102 sys.exit(rc.returncode)
103
104def openssl_run_make(openssldir, target):
105 """
106 Run make utility to generate files or cleanup.
107 Target can be either a string or a list of strings.
108 """
109 cmdline = [ 'make', '--silent' ]
110 if isinstance(target, list):
111 cmdline += target
112 else:
113 cmdline += [ target, ]
114 rc = subprocess.run(cmdline, cwd = openssldir)
115 rc.check_returncode()
116
117def get_configdata(openssldir):
118 """
119 Slurp openssl config data as JSON,
120 using a little perl helper script.
121 """
122 cmdline = [
123 'perl',
124 'perl2json.pl',
125 openssldir,
126 ]
127 rc = subprocess.run(cmdline, stdout = subprocess.PIPE)
128 rc.check_returncode()
129 return json.loads(rc.stdout)
130
131def is_asm(filename):
132 """ Check whenevr the passed file is an assembler file """
133 if filename.endswith('.s') or filename.endswith('.S'):
134 return True
135 return False
136
137def copy_generated_file(src, dst):
138 src_file = []
139 with open(src, 'r') as fsrc:
140 src_file = fsrc.readlines()
141 with open(dst, 'w') as fdst:
142 for lines in range(len(src_file)):
143 s = src_file[lines]
144 s = s.rstrip() + "\r\n"
145 fdst.write(s.expandtabs())
146
147def generate_files(openssldir, opensslgendir, asm, filelist):
148 """
149 Generate files, using make, and copy over the results to the
150 directory tree for generated openssl files. Creates
151 subdirectories as needed.
152 """
153 openssl_run_make(openssldir, filelist)
154 for filename in filelist:
155 src = os.path.join(openssldir, filename)
156 if is_asm(filename):
157 """ rename MSFT asm files to .nasm """
158 if 'IA32-MSFT' in asm:
159 filename = filename.replace('.S', '.nasm')
160 elif 'X64-MSFT' in asm:
161 filename = filename.replace('.s', '.nasm')
162 dst = os.path.join(opensslgendir, asm, filename)
163 else:
164 dst = os.path.join(opensslgendir, filename)
165 os.makedirs(os.path.dirname(dst), exist_ok = True)
166 copy_generated_file(src, dst)
167
168def generate_include_files(openssldir, opensslgendir, asm, cfg):
169 """ Generate openssl include files """
170 print('# generate include files')
171 filelist = cfg['unified_info']['generate'].keys()
172 filelist = list(filter(lambda f: 'include' in f, filelist))
173 generate_files(openssldir, opensslgendir, asm, filelist)
174
175def generate_library_files(openssldir, opensslgendir, asm, cfg, obj):
176 """
177 Generate openssl source files for a given library. Handles
178 mostly assembler files, but a few C sources are generated too.
179 """
180 filelist = get_source_list(cfg, obj, True)
181 if filelist:
182 print(f'# generate source files for {obj}')
183 generate_files(openssldir, opensslgendir, asm, filelist)
184
185def generate_all_files(openssldir, opensslgendir, asm, cfg):
186 """ Generate all files needed. """
187 generate_include_files(openssldir, opensslgendir, asm, cfg)
188 generate_library_files(openssldir, opensslgendir, asm, cfg, 'libcrypto')
189 generate_library_files(openssldir, opensslgendir, asm, cfg, 'providers/libcommon.a')
190 generate_library_files(openssldir, opensslgendir, asm, cfg, 'libssl')
191
192def get_source_list(cfg, obj, gen):
193 """
194 Gets the list of source files needed to create a specific object.
195 * If 'gen' is True the function returns the list of generated
196 files.
197 * If 'gen' is False the function returns the list of files not
198 generated (which are used from the submodule directly).
199 Note: Will call itself recursively to resolve nested dependencies.
200 """
201 sources = cfg['unified_info']['sources']
202 generate = cfg['unified_info']['generate']
203 srclist = []
204 if sources.get(obj):
205 for item in sources.get(obj):
206 srclist += get_source_list(cfg, item, gen)
207 else:
208 is_generated = generate.get(obj) is not None
209 if is_generated == gen:
210 srclist += [ obj, ]
211 return srclist
212
213def asm_filter_fn(filename):
214 """
215 Filter asm source and define lists. Drops files we don't want include.
216 """
217 exclude = [
218 '/bn/',
219 'OPENSSL_BN_ASM',
220 'OPENSSL_IA32_SSE2',
221 '/ec/',
222 'ECP_NISTZ256_ASM',
223 'X25519_ASM',
224 ]
225 for item in exclude:
226 if item in filename:
227 return False
228 return True
229
230def get_sources(cfg, obj, asm):
231 """
232 Get the list of all sources files. Will fetch both generated
233 and not generated file lists and update the paths accordingly, so
234 the openssl submodule or the sub-tree for generated files is
235 referenced as needed.
236 """
237 srclist = get_source_list(cfg, obj, False)
238 genlist = get_source_list(cfg, obj, True)
239 srclist = list(map(lambda x: f'$(OPENSSL_PATH)/{x}', srclist))
240 c_list = list(map(lambda x: f'$(OPENSSL_GEN_PATH)/{x}',
241 filter(lambda x: not is_asm(x), genlist)))
242 asm_list = list(map(lambda x: f'$(OPENSSL_GEN_PATH)/{asm}/{x}',
243 filter(is_asm, genlist)))
244 asm_list = list(filter(asm_filter_fn, asm_list))
245 return srclist + c_list + asm_list
246
247def sources_filter_fn(filename):
248 """
249 Filter source lists. Drops files we don't want include or
250 need replace with our own uefi-specific version.
251 """
252 exclude = [
253 'randfile.c',
254 '/store/',
255 '/storemgmt/',
256 '/encode_decode/encode',
257 '/pkcs12/',
258 'statem_srvr.c',
259 'extensions_srvr.c',
260 'defltprov.c',
261 'baseprov.c',
262 'provider_predefined.c',
263 'ecp_nistz256.c',
264 'x86_64-gcc.c',
265 ]
266 for item in exclude:
267 if item in filename:
268 return False
269 return True
270
271def libcrypto_sources(cfg, asm = None):
272 """ Get source file list for libcrypto """
273 files = get_sources(cfg, 'libcrypto', asm)
274 files += get_sources(cfg, 'providers/libcommon.a', asm)
275 files = list(filter(sources_filter_fn, files))
276 return files
277
278def libssl_sources(cfg, asm = None):
279 """ Get source file list for libssl """
280 files = get_sources(cfg, 'libssl', asm)
281 files = list(filter(sources_filter_fn, files))
282 return files
283
284def update_inf(filename, sources, arch = None, defines = []):
285 """
286 Update inf file, replace source file list and build flags.
287 """
288 head = ''
289 tail = ''
290 state = 0
291
292 if arch:
293 section = f'Sources.{arch}'
294 flags = f'OPENSSL_FLAGS_{arch}'
295 else:
296 section = None
297 flags = f'OPENSSL_FLAGS_NOASM'
298 state = 1
299
300 # read and parse file
301 with open(filename, 'r') as f:
302 while True:
303 line = f.readline()
304 if line == '':
305 break
306 if state in [0, 1]:
307 if flags in line:
308 (keep, replace) = line.split('=')
309 args = map(lambda x: f'-D{x}', defines)
310 head += keep + '= ' + ' '.join(args)
311 head = head.rstrip() + '\r\n'
312 else:
313 head += line.rstrip() + '\r\n'
314 if state == 0 and section in line:
315 state = 1
316 if state == 1 and 'Autogenerated files list starts here' in line:
317 state = 2
318 if state == 2 and 'Autogenerated files list ends here' in line:
319 state = 3
320 if state == 3:
321 tail += line.rstrip() + '\r\n'
322
323 # write updated file
324 with open(filename, 'w') as f:
325 f.write(head)
326 for src in sources:
327 f.write(f' {src}\r\n')
328 f.write(tail)
329
330def update_MSFT_asm_format(asm, filelist):
331 """ rename MSFT asm files to .nasm """
332 if 'IA32-MSFT' in asm:
333 for file_index in range(len(filelist)):
334 filelist[file_index] = filelist[file_index].replace('.S', '.nasm')
335 elif 'X64-MSFT' in asm:
336 for file_index in range(len(filelist)):
337 filelist[file_index] = filelist[file_index].replace('.s', '.nasm')
338
339def main():
340 # prepare
341 os.chdir(os.path.dirname(os.path.abspath(__file__)))
342 openssldir = os.path.join(os.getcwd(), 'openssl')
343 opensslgendir = os.path.join(os.getcwd(), 'OpensslGen')
344
345 # asm accel configs (see UefiAsm.conf)
346 for ec in [True, False]:
347 if ec:
348 inf = 'OpensslLibFullAccel.inf'
349 hdr = 'configuration-ec.h'
350 else:
351 inf = 'OpensslLibAccel.inf'
352 hdr = 'configuration-noec.h'
353 sources = {}
354 defines = {}
355 for asm in [ 'UEFI-IA32-MSFT', 'UEFI-IA32-GCC',
356 'UEFI-X64-MSFT', 'UEFI-X64-GCC']:
357 (uefi, arch, cc) = asm.split('-')
358 archcc = f'{arch}-{cc}'
359
360 openssl_configure(openssldir, asm, ec = ec);
361 cfg = get_configdata(openssldir)
362 generate_all_files(openssldir, opensslgendir, archcc, cfg)
363 shutil.move(os.path.join(opensslgendir, 'include', 'openssl', 'configuration.h'),
364 os.path.join(opensslgendir, 'include', 'openssl', hdr))
365 openssl_run_make(openssldir, 'distclean')
366
367 srclist = libcrypto_sources(cfg, archcc) + libssl_sources(cfg, archcc)
368 sources[archcc] = list(map(lambda x: f'{x} | {cc}', filter(is_asm, srclist)))
369 update_MSFT_asm_format(archcc, sources[archcc])
370 sources[arch] = list(filter(lambda x: not is_asm(x), srclist))
371 defines[arch] = cfg['unified_info']['defines']['libcrypto']
372 defines[arch] = list(filter(asm_filter_fn, defines[arch]))
373
374 ia32accel = sources['IA32'] + sources['IA32-MSFT'] + sources['IA32-GCC']
375 x64accel = sources['X64'] + sources['X64-MSFT'] + sources['X64-GCC']
376 update_inf(inf, ia32accel, 'IA32', defines['IA32'])
377 update_inf(inf, x64accel, 'X64', defines['X64'])
378
379 # noaccel - ec enabled
380 openssl_configure(openssldir, 'UEFI', ec = True);
381 cfg = get_configdata(openssldir)
382 generate_all_files(openssldir, opensslgendir, None, cfg)
383 openssl_run_make(openssldir, 'distclean')
384
385 defines = []
386 if 'libcrypto' in cfg['unified_info']['defines']:
387 defines = cfg['unified_info']['defines']['libcrypto']
388
389 update_inf('OpensslLibFull.inf',
390 libcrypto_sources(cfg) + libssl_sources(cfg),
391 defines)
392
393 # noaccel - ec disabled
394 openssl_configure(openssldir, 'UEFI', ec = False);
395 cfg = get_configdata(openssldir)
396 generate_all_files(openssldir, opensslgendir, None, cfg)
397 openssl_run_make(openssldir, 'distclean')
398
399 update_inf('OpensslLibCrypto.inf',
400 libcrypto_sources(cfg),
401 None, defines)
402 update_inf('OpensslLib.inf',
403 libcrypto_sources(cfg) + libssl_sources(cfg),
404 None, defines)
405
406 # wrap header file
407 confighdr = os.path.join(opensslgendir, 'include', 'openssl', 'configuration.h')
408 with open(confighdr, 'w') as f:
409 f.write('#ifdef EDK2_OPENSSL_NOEC\r\n'
410 '# include "configuration-noec.h"\r\n'
411 '#else\r\n'
412 '# include "configuration-ec.h"\r\n'
413 '#endif\r\n')
414
415if __name__ == '__main__':
416 sys.exit(main())
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette