VirtualBox

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

Last change on this file since 108794 was 108794, checked in by vboxsync, 2 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 13.3 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 'armcap.c',
266 ]
267 for item in exclude:
268 if item in filename:
269 return False
270 return True
271
272def libcrypto_sources(cfg, asm = None):
273 """ Get source file list for libcrypto """
274 files = get_sources(cfg, 'libcrypto', asm)
275 files += get_sources(cfg, 'providers/libcommon.a', asm)
276 files = list(filter(sources_filter_fn, files))
277 return files
278
279def libssl_sources(cfg, asm = None):
280 """ Get source file list for libssl """
281 files = get_sources(cfg, 'libssl', asm)
282 files = list(filter(sources_filter_fn, files))
283 return files
284
285def update_inf(filename, sources, arch = None, defines = []):
286 """
287 Update inf file, replace source file list and build flags.
288 """
289 head = ''
290 tail = ''
291 state = 0
292
293 if arch:
294 section = f'Sources.{arch}'
295 flags = f'OPENSSL_FLAGS_{arch}'
296 else:
297 section = None
298 flags = f'OPENSSL_FLAGS_NOASM'
299 state = 1
300
301 # read and parse file
302 with open(filename, 'r') as f:
303 while True:
304 line = f.readline()
305 if line == '':
306 break
307 if state in [0, 1]:
308 if flags in line:
309 (keep, replace) = line.split('=')
310 args = map(lambda x: f'-D{x}', defines)
311 head += keep + '= ' + ' '.join(args)
312 head = head.rstrip() + '\r\n'
313 else:
314 head += line.rstrip() + '\r\n'
315 if state == 0 and section in line:
316 state = 1
317 if state == 1 and 'Autogenerated files list starts here' in line:
318 state = 2
319 if state == 2 and 'Autogenerated files list ends here' in line:
320 state = 3
321 if state == 3:
322 tail += line.rstrip() + '\r\n'
323
324 # write updated file
325 with open(filename, 'w') as f:
326 f.write(head)
327 for src in sources:
328 f.write(f' {src}\r\n')
329 f.write(tail)
330
331def update_MSFT_asm_format(asm, filelist):
332 """ rename MSFT asm files to .nasm """
333 if 'IA32-MSFT' in asm:
334 for file_index in range(len(filelist)):
335 filelist[file_index] = filelist[file_index].replace('.S', '.nasm')
336 elif 'X64-MSFT' in asm:
337 for file_index in range(len(filelist)):
338 filelist[file_index] = filelist[file_index].replace('.s', '.nasm')
339
340def main():
341 # prepare
342 os.chdir(os.path.dirname(os.path.abspath(__file__)))
343 openssldir = os.path.join(os.getcwd(), 'openssl')
344 opensslgendir = os.path.join(os.getcwd(), 'OpensslGen')
345
346 # asm accel configs (see UefiAsm.conf)
347 for ec in [True, False]:
348 if ec:
349 inf = 'OpensslLibFullAccel.inf'
350 hdr = 'configuration-ec.h'
351 else:
352 inf = 'OpensslLibAccel.inf'
353 hdr = 'configuration-noec.h'
354 sources = {}
355 defines = {}
356 for asm in [ 'UEFI-IA32-MSFT', 'UEFI-IA32-GCC',
357 'UEFI-X64-MSFT', 'UEFI-X64-GCC',
358 'UEFI-AARCH64-GCC']:
359 (uefi, arch, cc) = asm.split('-')
360 archcc = f'{arch}-{cc}'
361
362 openssl_configure(openssldir, asm, ec = ec);
363 cfg = get_configdata(openssldir)
364 generate_all_files(openssldir, opensslgendir, archcc, cfg)
365 shutil.move(os.path.join(opensslgendir, 'include', 'openssl', 'configuration.h'),
366 os.path.join(opensslgendir, 'include', 'openssl', hdr))
367 openssl_run_make(openssldir, 'distclean')
368
369 srclist = libcrypto_sources(cfg, archcc) + libssl_sources(cfg, archcc)
370 sources[archcc] = list(map(lambda x: f'{x} | {cc}', filter(is_asm, srclist)))
371 update_MSFT_asm_format(archcc, sources[archcc])
372 sources[arch] = list(filter(lambda x: not is_asm(x), srclist))
373 defines[arch] = cfg['unified_info']['defines']['libcrypto']
374 defines[arch] = list(filter(asm_filter_fn, defines[arch]))
375
376 ia32accel = sources['IA32'] + sources['IA32-MSFT'] + sources['IA32-GCC']
377 x64accel = sources['X64'] + sources['X64-MSFT'] + sources['X64-GCC']
378 update_inf(inf, ia32accel, 'IA32', defines['IA32'])
379 update_inf(inf, x64accel, 'X64', defines['X64'])
380 aarch64accel = sources['AARCH64'] + sources['AARCH64-GCC']
381 update_inf(inf, aarch64accel, 'AARCH64', defines['AARCH64'])
382
383 # noaccel - ec enabled
384 openssl_configure(openssldir, 'UEFI', ec = True);
385 cfg = get_configdata(openssldir)
386 generate_all_files(openssldir, opensslgendir, None, cfg)
387 openssl_run_make(openssldir, 'distclean')
388
389 defines = []
390 if 'libcrypto' in cfg['unified_info']['defines']:
391 defines = cfg['unified_info']['defines']['libcrypto']
392
393 update_inf('OpensslLibFull.inf',
394 libcrypto_sources(cfg) + libssl_sources(cfg),
395 defines)
396
397 # noaccel - ec disabled
398 openssl_configure(openssldir, 'UEFI', ec = False);
399 cfg = get_configdata(openssldir)
400 generate_all_files(openssldir, opensslgendir, None, cfg)
401 openssl_run_make(openssldir, 'distclean')
402
403 update_inf('OpensslLibCrypto.inf',
404 libcrypto_sources(cfg),
405 None, defines)
406 update_inf('OpensslLib.inf',
407 libcrypto_sources(cfg) + libssl_sources(cfg),
408 None, defines)
409
410 # wrap header file
411 confighdr = os.path.join(opensslgendir, 'include', 'openssl', 'configuration.h')
412 with open(confighdr, 'w') as f:
413 f.write('#ifdef EDK2_OPENSSL_NOEC\r\n'
414 '# include "configuration-noec.h"\r\n'
415 '#else\r\n'
416 '# include "configuration-ec.h"\r\n'
417 '#endif\r\n')
418
419if __name__ == '__main__':
420 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