mirror of https://github.com/ipxe/ipxe.git
Merge branch 'master' into feature/tpm-info
commit
6577252e18
|
@ -47,22 +47,21 @@ datastack = [
|
|||
]
|
||||
stack = []
|
||||
while stack or not decoder.eof():
|
||||
if decoder.eof():
|
||||
tag = decoder.peek()
|
||||
if tag is None:
|
||||
encoder.leave()
|
||||
decoder.leave()
|
||||
stack.pop()
|
||||
elif tag.typ == asn1.Types.Constructed:
|
||||
encoder.enter(nr=tag.nr, cls=tag.cls)
|
||||
decoder.enter()
|
||||
stack.append(tag.nr)
|
||||
else:
|
||||
tag = decoder.peek()
|
||||
if tag.typ == asn1.Types.Constructed:
|
||||
encoder.enter(nr=tag.nr, cls=tag.cls)
|
||||
decoder.enter()
|
||||
stack.append(tag.nr)
|
||||
(tag, value) = decoder.read()
|
||||
if stack == datastack and tag.nr == 0:
|
||||
data = value
|
||||
else:
|
||||
(tag, value) = decoder.read()
|
||||
if stack == datastack and tag.nr == 0:
|
||||
data = value
|
||||
else:
|
||||
encoder.write(value, nr=tag.nr, cls=tag.cls)
|
||||
encoder.write(value, nr=tag.nr, cls=tag.cls)
|
||||
envelope = encoder.output()
|
||||
if data is None:
|
||||
parser.error("Input file does not contain any encrypted data")
|
||||
|
|
|
@ -25,12 +25,12 @@ plugin_ctrl: unmapped=1, biosdev=1, speaker=1, e1000=1, parallel=1, serial=1
|
|||
# allows you to change all the settings that control Bochs's behavior.
|
||||
# Depending on the platform there are up to 3 choices of configuration
|
||||
# interface: a text mode version called "textconfig" and two graphical versions
|
||||
# called "win32config" and "wx". The text mode version uses stdin/stdout and
|
||||
# is always compiled in, unless Bochs is compiled for wx only. The choice
|
||||
# "win32config" is only available on win32 and it is the default there.
|
||||
# The choice "wx" is only available when you use "--with-wx" on the configure
|
||||
# command. If you do not write a config_interface line, Bochs will
|
||||
# choose a default for you.
|
||||
# called "win32config" and "wx". The text mode version uses stdin/stdout or
|
||||
# gui console (if available / runtime config) and is always compiled in, unless
|
||||
# Bochs is compiled for wx only. The choice "win32config" is only available on
|
||||
# win32/win64 and it is the default on these platforms. The choice "wx" is only
|
||||
# available when Bochs is compiled with wxWidgets support. If you do not write
|
||||
# a config_interface line, Bochs will choose a default for you.
|
||||
#
|
||||
# NOTE: if you use the "wx" configuration interface, you must also use
|
||||
# the "wx" display library.
|
||||
|
@ -73,12 +73,14 @@ plugin_ctrl: unmapped=1, biosdev=1, speaker=1, e1000=1, parallel=1, serial=1
|
|||
# "cmdmode" - call a headerbar button handler after pressing F7 (sdl, sdl2,
|
||||
# win32, x)
|
||||
# "fullscreen" - startup in fullscreen mode (sdl, sdl2)
|
||||
# "gui_debug" - use GTK debugger gui (sdl, sdl2, x) / Win32 debugger gui (sdl,
|
||||
# sdl2, win32)
|
||||
# "hideIPS" - disable IPS output in status bar (rfb, sdl, sdl2, term, vncsrv,
|
||||
# win32, wx, x)
|
||||
# "nokeyrepeat" - turn off host keyboard repeat (sdl, sdl2, win32, x)
|
||||
# "no_gui_console" - use system console instead of builtin gui console
|
||||
# (rfb, sdl, sdl2, vncsrv, x)
|
||||
# "timeout" - time (in seconds) to wait for client (rfb, vncsrv)
|
||||
# "gui_debug" - This option is DEPRECATED, use command line option '-dbg_gui'
|
||||
# instead. It also supports the 'globalini' extension
|
||||
#
|
||||
# See the examples below for other currently supported options.
|
||||
# Setting up options without specifying display library is also supported.
|
||||
|
@ -113,9 +115,12 @@ plugin_ctrl: unmapped=1, biosdev=1, speaker=1, e1000=1, parallel=1, serial=1
|
|||
#
|
||||
# CPU configurations that can be selected:
|
||||
# -----------------------------------------------------------------
|
||||
# i386 Intel 386SX
|
||||
# i486dx4 Intel 486DX4
|
||||
# pentium Intel Pentium (P54C)
|
||||
# pentium_mmx Intel Pentium MMX
|
||||
# amd_k6_2_chomper AMD-K6(tm) 3D processor (Chomper)
|
||||
# athlon_xp AMD Athlon(tm) XP Processor
|
||||
# p2_klamath Intel Pentium II (Klamath)
|
||||
# p3_katmai Intel Pentium III (Katmai)
|
||||
# p4_willamette Intel(R) Pentium(R) 4 (Willamette)
|
||||
|
@ -136,6 +141,26 @@ plugin_ctrl: unmapped=1, biosdev=1, speaker=1, e1000=1, parallel=1, serial=1
|
|||
# corei7_ivy_bridge_3770k Intel(R) Core(TM) i7-3770K CPU (Ivy Bridge)
|
||||
# corei7_haswell_4770 Intel(R) Core(TM) i7-4770 CPU (Haswell)
|
||||
# broadwell_ult Intel(R) Processor 5Y70 CPU (Broadwell)
|
||||
# corei7_skylake_x Intel(R) Core(TM) i7-7800X CPU (Skylake)
|
||||
# corei3_cnl Intel(R) Core(TM) i3-8121U CPU (Cannonlake)
|
||||
# corei7_icelake_u QuadCore Intel Core i7-1065G7 (IceLake)
|
||||
# tigerlake 11th Gen Intel(R) Core(TM) i5-1135G7 (TigerLake)
|
||||
# sapphire_rapids Intel(R) Xeon(R) w9-3475X (Sappire Rapids)
|
||||
# arrow_lake 15th Gen Intel(R) Core(TM) Ultra 5 245K (ArrowLake)
|
||||
#
|
||||
# ADD_FEATURES:
|
||||
# Enable one of more CPU feature in the CPU configuration selected by MODEL.
|
||||
# Could be useful for testing CPU with newer imaginary configurations by
|
||||
# adding a specific feature or set of features to existing MODEL. The list
|
||||
# of features to add supplied through space or comma separated string.
|
||||
#
|
||||
# EXCLUDE_FEATURES:
|
||||
# Disable one of more CPU feature from CPU configuration selected by MODEL.
|
||||
# Could be useful for testing CPU without a specific feature or set of
|
||||
# features. When experiening issues booting a modern OS it could be useful
|
||||
# to disable CPU features(s) to see if they responsible for the failures.
|
||||
# The list of features to exclude supplied through space or comma separated
|
||||
# string.
|
||||
#
|
||||
# COUNT:
|
||||
# Set the number of processors:cores per processor:threads per core when
|
||||
|
@ -196,151 +221,6 @@ plugin_ctrl: unmapped=1, biosdev=1, speaker=1, e1000=1, parallel=1, serial=1
|
|||
cpu: model=core2_penryn_t9600, count=1, ips=50000000, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="msrs.def"
|
||||
cpu: cpuid_limit_winnt=0
|
||||
|
||||
#=======================================================================
|
||||
# CPUID:
|
||||
#
|
||||
# This defines features and functionality supported by Bochs emulated CPU.
|
||||
# The option has no offect if CPU model was selected in CPU option.
|
||||
#
|
||||
# MMX:
|
||||
# Select MMX instruction set support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5.
|
||||
#
|
||||
# APIC:
|
||||
# Select APIC configuration (LEGACY/XAPIC/XAPIC_EXT/X2APIC).
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5.
|
||||
#
|
||||
# SEP:
|
||||
# Select SYSENTER/SYSEXIT instruction set support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# SIMD:
|
||||
# Select SIMD instructions support.
|
||||
# Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2/AVX/AVX2/AVX512
|
||||
# could be selected.
|
||||
#
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
# The AVX choises exists only if Bochs compiled with --enable-avx option.
|
||||
#
|
||||
# SSE4A:
|
||||
# Select AMD SSE4A instructions support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# MISALIGNED_SSE:
|
||||
# Select AMD Misaligned SSE mode support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# AES:
|
||||
# Select AES instruction set support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# SHA:
|
||||
# Select SHA instruction set support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# MOVBE:
|
||||
# Select MOVBE Intel(R) Atom instruction support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# ADX:
|
||||
# Select ADCX/ADOX instructions support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# XSAVE:
|
||||
# Select XSAVE extensions support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# XSAVEOPT:
|
||||
# Select XSAVEOPT instruction support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# AVX_F16C:
|
||||
# Select AVX float16 convert instructions support.
|
||||
# This option exists only if Bochs compiled with --enable-avx option.
|
||||
#
|
||||
# AVX_FMA:
|
||||
# Select AVX fused multiply add (FMA) instructions support.
|
||||
# This option exists only if Bochs compiled with --enable-avx option.
|
||||
#
|
||||
# BMI:
|
||||
# Select BMI1/BMI2 instructions support.
|
||||
# This option exists only if Bochs compiled with --enable-avx option.
|
||||
#
|
||||
# XOP:
|
||||
# Select AMD XOP instructions support.
|
||||
# This option exists only if Bochs compiled with --enable-avx option.
|
||||
#
|
||||
# FMA4:
|
||||
# Select AMD four operand FMA instructions support.
|
||||
# This option exists only if Bochs compiled with --enable-avx option.
|
||||
#
|
||||
# TBM:
|
||||
# Select AMD Trailing Bit Manipulation (TBM) instructions support.
|
||||
# This option exists only if Bochs compiled with --enable-avx option.
|
||||
#
|
||||
# X86-64:
|
||||
# Enable x86-64 and long mode support.
|
||||
# This option exists only if Bochs compiled with x86-64 support.
|
||||
#
|
||||
# 1G_PAGES:
|
||||
# Enable 1G page size support in long mode.
|
||||
# This option exists only if Bochs compiled with x86-64 support.
|
||||
#
|
||||
# PCID:
|
||||
# Enable Process-Context Identifiers (PCID) support in long mode.
|
||||
# This option exists only if Bochs compiled with x86-64 support.
|
||||
#
|
||||
# FSGSBASE:
|
||||
# Enable GS/GS BASE access instructions support in long mode.
|
||||
# This option exists only if Bochs compiled with x86-64 support.
|
||||
#
|
||||
# SMEP:
|
||||
# Enable Supervisor Mode Execution Protection (SMEP) support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# SMAP:
|
||||
# Enable Supervisor Mode Access Prevention (SMAP) support.
|
||||
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
|
||||
#
|
||||
# MWAIT:
|
||||
# Select MONITOR/MWAIT instructions support.
|
||||
# This option exists only if Bochs compiled with --enable-monitor-mwait.
|
||||
#
|
||||
# VMX:
|
||||
# Select VMX extensions emulation support.
|
||||
# This option exists only if Bochs compiled with --enable-vmx option.
|
||||
#
|
||||
# SVM:
|
||||
# Select AMD SVM (Secure Virtual Machine) extensions emulation support.
|
||||
# This option exists only if Bochs compiled with --enable-svm option.
|
||||
#
|
||||
# VENDOR_STRING:
|
||||
# Set the CPUID vendor string returned by CPUID(0x0). This should be a
|
||||
# twelve-character ASCII string.
|
||||
#
|
||||
# BRAND_STRING:
|
||||
# Set the CPUID vendor string returned by CPUID(0x80000002 .. 0x80000004).
|
||||
# This should be at most a forty-eight-character ASCII string.
|
||||
#
|
||||
# LEVEL:
|
||||
# Set emulated CPU level information returned by CPUID. Default value is
|
||||
# determined by configure option --enable-cpu-level. Currently supported
|
||||
# values are 5 (for Pentium and similar processors) and 6 (for P6 and
|
||||
# later processors).
|
||||
#
|
||||
# FAMILY:
|
||||
# Set model information returned by CPUID. Default family value determined
|
||||
# by configure option --enable-cpu-level.
|
||||
#
|
||||
# MODEL:
|
||||
# Set model information returned by CPUID. Default model value is 3.
|
||||
#
|
||||
# STEPPING:
|
||||
# Set stepping information returned by CPUID. Default stepping value is 3.
|
||||
#=======================================================================
|
||||
#cpuid: x86_64=1, mmx=1, sep=1, simd=sse4_2, apic=xapic, aes=1, movbe=1, xsave=1
|
||||
#cpuid: family=6, model=0x1a, stepping=5
|
||||
|
||||
#=======================================================================
|
||||
# MEMORY
|
||||
# Set the amount of physical memory you want to emulate.
|
||||
|
@ -357,8 +237,14 @@ cpu: cpuid_limit_winnt=0
|
|||
# memory pool. You will be warned (by FATAL PANIC) in case guest already
|
||||
# used all allocated host memory and wants more.
|
||||
#
|
||||
# BLOCK_SIZE:
|
||||
# Memory block size select granularity of host memory allocation. Very
|
||||
# large memory configurations might requre larger memory blocks which
|
||||
# configurations with small memory might want memory block smaller.
|
||||
# Default memory block size is 128K.
|
||||
#
|
||||
#=======================================================================
|
||||
memory: guest=512, host=256
|
||||
memory: guest=512, host=256, block_size=512
|
||||
|
||||
#=======================================================================
|
||||
# ROMIMAGE:
|
||||
|
@ -368,28 +254,50 @@ memory: guest=512, host=256
|
|||
# starting at address 0xfffe0000, and it is exactly 128k long. The legacy
|
||||
# version of the Bochs BIOS is usually loaded starting at address 0xffff0000,
|
||||
# and it is exactly 64k long.
|
||||
# You can use the environment variable $BXSHARE to specify the location
|
||||
# of the BIOS.
|
||||
# The usage of external large BIOS images (up to 512k) at memory top is
|
||||
# now supported, but we still recommend to use the BIOS distributed with Bochs.
|
||||
# The start address is optional, since it can be calculated from image size.
|
||||
# The Bochs BIOS currently supports only the option "fastboot" to skip the
|
||||
# boot menu delay.
|
||||
#
|
||||
# FILE
|
||||
# Name of the BIOS image file. You can use the environment variable $BXSHARE
|
||||
# to specify the location of the BIOS.
|
||||
#
|
||||
# ADDRESS
|
||||
# The start address is optional, since it can be calculated from image size.
|
||||
#
|
||||
# OPTIONS
|
||||
# The Bochs BIOS currently only supports the option "fastboot" to skip the
|
||||
# boot menu delay.
|
||||
#
|
||||
# FLASH_DATA
|
||||
# This parameter defines the file name for the flash BIOS config space loaded
|
||||
# at startup if existing and saved on exit if modified. The Bochs BIOS doesn't
|
||||
# use this feature yet.
|
||||
#
|
||||
# Please note that if you use the BIOS-bochs-legacy romimage BIOS option,
|
||||
# you cannot use a PCI enabled VGA ROM BIOS.
|
||||
# Please note that if you use a SeaBIOS binary in romimage BIOS option,
|
||||
# you must use a PCI enabled VGA ROM BIOS.
|
||||
#=======================================================================
|
||||
#romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot
|
||||
#romimage: file=$BXSHARE/BIOS-bochs-legacy
|
||||
#romimage: file=$BXSHARE/bios.bin-1.13.0 # http://www.seabios.org/SeaBIOS
|
||||
#romimage: file=$BXSHARE/i440fx.bin, flash_data=escd.bin
|
||||
#romimage: file=asus_p6np5.bin, flash_data=escd.bin
|
||||
#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top
|
||||
romimage: file=bochs/bios/BIOS-bochs-latest
|
||||
|
||||
#=======================================================================
|
||||
# VGAROMIMAGE
|
||||
# You now need to load a VGA ROM BIOS into C0000.
|
||||
# Please note that if you use the BIOS-bochs-legacy romimage BIOS option,
|
||||
# you cannot use a PCI enabled VGA ROM BIOS option such as the cirrus
|
||||
# option shown below.
|
||||
#=======================================================================
|
||||
#vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
|
||||
#vgaromimage: file=bios/VGABIOS-lgpl-latest-cirrus
|
||||
#vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest.bin
|
||||
#vgaromimage: file=bios/VGABIOS-lgpl-latest-cirrus.bin
|
||||
#vgaromimage: file=$BXSHARE/vgabios-cirrus.bin-1.13.0 # http://www.seabios.org/SeaVGABIOS
|
||||
#vgaromimage: file=bios/VGABIOS-elpin-2.40
|
||||
vgaromimage: file=bochs/bios/VGABIOS-lgpl-latest
|
||||
vgaromimage: file=bochs/bios/VGABIOS-lgpl-latest.bin
|
||||
|
||||
#=======================================================================
|
||||
# OPTROMIMAGE[1-4]:
|
||||
|
@ -406,7 +314,7 @@ vgaromimage: file=bochs/bios/VGABIOS-lgpl-latest
|
|||
#optromimage2: file=optionalrom.bin, address=0xd1000
|
||||
#optromimage3: file=optionalrom.bin, address=0xd2000
|
||||
#optromimage4: file=optionalrom.bin, address=0xd3000
|
||||
optromimage1: file=../../src/bin/intel.rom, address=0xcb000
|
||||
optromimage1: file=../../src/bin/intel.rom, address=0xc8000
|
||||
|
||||
#optramimage1: file=/path/file1.img, address=0x0010000
|
||||
#optramimage2: file=/path/file2.img, address=0x0020000
|
||||
|
@ -426,7 +334,9 @@ optromimage1: file=../../src/bin/intel.rom, address=0xcb000
|
|||
# UPDATE_FREQ
|
||||
# This parameter specifies the number of display updates per second.
|
||||
# The VGA update timer by default uses the realtime engine with a value
|
||||
# of 5. This parameter can be changed at runtime.
|
||||
# of 10 (valid: 1 to 75). This parameter can be changed at runtime.
|
||||
# The special value 0 enables support for using the frame rate of the
|
||||
# emulated graphics device.
|
||||
#
|
||||
# REALTIME
|
||||
# If set to 1 (default), the VGA timer is based on realtime, otherwise it
|
||||
|
@ -440,6 +350,10 @@ optromimage1: file=../../src/bin/intel.rom, address=0xcb000
|
|||
# the monitor EDID data. By default the 'builtin' values for 'Bochs Screen'
|
||||
# are used. Other choices are 'disabled' (no DDC emulation) and 'file'
|
||||
# (read monitor EDID from file / path name separated with a colon).
|
||||
#
|
||||
# VBE_MEMSIZE
|
||||
# With this parameter the size of the memory for the Bochs VBE extension
|
||||
# can be defined. Valid values are 4, 8, 16 and 32 MB (default is 16 MB).
|
||||
# Examples:
|
||||
# vga: extension=cirrus, update_freq=10, ddc=builtin
|
||||
#=======================================================================
|
||||
|
@ -488,6 +402,8 @@ optromimage1: file=../../src/bin/intel.rom, address=0xcb000
|
|||
# KEYMAP:
|
||||
# This enables a remap of a physical localized keyboard to a
|
||||
# virtualized us keyboard, as the PC architecture expects.
|
||||
# Using a language specifier instead of a file name is also supported.
|
||||
# A keymap is also required by the paste feature.
|
||||
#
|
||||
# USER_SHORTCUT:
|
||||
# This defines the keyboard shortcut to be sent when you press the "user"
|
||||
|
@ -504,7 +420,7 @@ optromimage1: file=../../src/bin/intel.rom, address=0xcb000
|
|||
# keyboard: keymap=gui/keymaps/x11-pc-de.map
|
||||
# keyboard: user_shortcut=ctrl-alt-del
|
||||
#=======================================================================
|
||||
#keyboard: type=mf, serial_delay=250
|
||||
#keyboard: type=mf, serial_delay=150
|
||||
|
||||
#=======================================================================
|
||||
# MOUSE:
|
||||
|
@ -529,8 +445,8 @@ optromimage1: file=../../src/bin/intel.rom, address=0xcb000
|
|||
# TOGGLE:
|
||||
# The default method to toggle the mouse capture at runtime is to press the
|
||||
# CTRL key and the middle mouse button ('ctrl+mbutton'). This option allows
|
||||
# to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (like QEMU)
|
||||
# or 'f12'.
|
||||
# to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (legacy QEMU),
|
||||
# 'ctrl+alt+g' (QEMU current) or 'f12'.
|
||||
#
|
||||
# Examples:
|
||||
# mouse: enabled=1
|
||||
|
@ -567,7 +483,8 @@ mouse: enabled=0
|
|||
# PCI chipset. These options can be specified as comma-separated values.
|
||||
# By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but
|
||||
# original i440FX doesn't support them. The options 'noacpi' and 'nohpet' make
|
||||
# it possible to disable them.
|
||||
# it possible to disable them. The option 'noagp' disables the incomplete AGP
|
||||
# subsystem of the i440BX chipset.
|
||||
#
|
||||
# Example:
|
||||
# pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi
|
||||
|
@ -772,10 +689,11 @@ ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9
|
|||
# This defines the boot sequence. Now you can specify up to 3 boot drives,
|
||||
# which can be 'floppy', 'disk', 'cdrom' or 'network' (boot ROM).
|
||||
# Legacy 'a' and 'c' are also supported.
|
||||
# The new boot choice 'usb' is only supported by the i440fx.bin BIOS.
|
||||
# Examples:
|
||||
# boot: floppy
|
||||
# boot: cdrom, disk
|
||||
# boot: network, disk
|
||||
# boot: network, usb, disk
|
||||
# boot: cdrom, floppy, disk
|
||||
#=======================================================================
|
||||
#boot: floppy
|
||||
|
@ -929,15 +847,15 @@ parport1: enabled=1, file="parport.out"
|
|||
# waveoutdrv:
|
||||
# This defines the driver to be used for the waveout feature.
|
||||
# Possible values are 'file' (all wave data sent to file), 'dummy' (no
|
||||
# output) and the platform-dependant drivers 'alsa', 'oss', 'osx', 'sdl'
|
||||
# and 'win'.
|
||||
# output), 'pulse', 'sdl' (both cross-platform) and the platform-dependant
|
||||
# drivers 'alsa', 'oss', 'osx' and 'win'.
|
||||
# waveout:
|
||||
# This defines the device to be used for wave output (if necessary) or
|
||||
# the output file for the 'file' driver.
|
||||
# waveindrv:
|
||||
# This defines the driver to be used for the wavein feature.
|
||||
# Possible values are 'dummy' (recording silence) and platform-dependent
|
||||
# drivers 'alsa', 'oss', 'sdl' and 'win'.
|
||||
# Possible values are 'dummy' (recording silence), 'pulse', 'sdl' (both
|
||||
# cross-platform) and platform-dependent drivers 'alsa', 'oss' and 'win'.
|
||||
# wavein:
|
||||
# This defines the device to be used for wave input (if necessary).
|
||||
# midioutdrv:
|
||||
|
@ -967,6 +885,7 @@ parport1: enabled=1, file="parport.out"
|
|||
# the Beep() function. The 'gui' mode forwards the beep to the related
|
||||
# gui methods (currently only used by the Carbon gui).
|
||||
#=======================================================================
|
||||
#speaker: enabled=1, mode=sound, volume=15
|
||||
speaker: enabled=1, mode=system
|
||||
|
||||
#=======================================================================
|
||||
|
@ -1000,14 +919,15 @@ speaker: enabled=1, mode=system
|
|||
# log: The file to write the sb16 emulator messages to.
|
||||
# dmatimer:
|
||||
# microseconds per second for a DMA cycle. Make it smaller to fix
|
||||
# non-continuous sound. 750000 is usually a good value. This needs a
|
||||
# reasonably correct setting for the IPS parameter of the CPU option.
|
||||
# non-continuous sound. 1000000 is usually a good value. This needs a
|
||||
# reasonably correct setting for the IPS parameter of the CPU option
|
||||
# and also depends on the clock sync setting.
|
||||
#
|
||||
# Examples for output modes:
|
||||
# sb16: midimode=2, midifile="output.mid", wavemode=1 # MIDI to file
|
||||
# sb16: midimode=1, wavemode=3, wavefile="output.wav" # wave to file and device
|
||||
#=======================================================================
|
||||
#sb16: midimode=1, wavemode=1, loglevel=2, log=sb16.log, dmatimer=600000
|
||||
#sb16: midimode=1, wavemode=1, loglevel=2, log=sb16.log, dmatimer=900000
|
||||
|
||||
#=======================================================================
|
||||
# ES1370:
|
||||
|
@ -1069,7 +989,8 @@ speaker: enabled=1, mode=system
|
|||
#
|
||||
# BOOTROM: The bootrom value is optional, and is the name of the ROM image
|
||||
# to load. Note that this feature is only implemented for the PCI version of
|
||||
# the NE2000.
|
||||
# the NE2000. For the ISA version using one of the 'optromimage[1-4]' options
|
||||
# must be used instead of this one.
|
||||
#
|
||||
# If you don't want to make connections to any physical networks,
|
||||
# you can use the following 'ethmod's to simulate a virtual network.
|
||||
|
@ -1137,34 +1058,40 @@ e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=tuntap, ethdev=/dev/net/tun:tap0
|
|||
# the numeric keypad to the USB device instead of the PS/2 keyboard. If the
|
||||
# keyboard is selected, all key events are sent to the USB device.
|
||||
#
|
||||
# To connect a 'flat' mode image as a USB hardisk you can use the 'disk' device
|
||||
# with the path to the image separated with a colon. To use other disk image modes
|
||||
# similar to ATA disks the syntax 'disk:mode:filename' must be used (see below).
|
||||
# To connect a disk image as a USB hardisk you can use the 'disk' device. Use
|
||||
# the 'path' option in the optionsX parameter to specify the path to the image
|
||||
# separated with a colon. To use other disk image modes similar to ATA disks
|
||||
# the syntax 'path:mode:filename' must be used (see below).
|
||||
#
|
||||
# To emulate a USB cdrom you can use the 'cdrom' device name and the path to
|
||||
# an ISO image or raw device name also separated with a colon. An option to
|
||||
# insert/eject media is available in the runtime configuration.
|
||||
# To emulate a USB cdrom you can use the 'cdrom' device and the path to an
|
||||
# ISO image or raw device name can be set with the 'path' option in the
|
||||
# optionsX parameter also separated with a colon. An option to insert/eject
|
||||
# media is available in the runtime configuration.
|
||||
#
|
||||
# To emulate a USB floppy you can use the 'floppy' device with the path to the
|
||||
# image separated with a colon. To use the VVFAT image mode similar to the
|
||||
# legacy floppy the syntax 'floppy:vvfat:directory' must be used (see below).
|
||||
# To emulate a USB floppy you can use the 'floppy' device and the path to a
|
||||
# floppy image can be set with the 'path' option in the optionsX parameter
|
||||
# separated with a colon. To use the VVFAT image mode similar to the legacy
|
||||
# floppy the syntax 'path:vvfat:directory' must be used (see below).
|
||||
# An option to insert/eject media is available in the runtime configuration.
|
||||
#
|
||||
# The device name 'hub' connects an external hub with max. 8 ports (default: 4)
|
||||
# to the root hub. To specify the number of ports you have to add the value
|
||||
# separated with a colon. Connecting devices to the external hub ports is only
|
||||
# available in the runtime configuration.
|
||||
# to the root hub. To specify the number of ports you have to use the 'ports'
|
||||
# option in the optionsX parameter with the value separated with a colon.
|
||||
# Connecting devices to the external hub ports is only available in the runtime
|
||||
# configuration.
|
||||
#
|
||||
# The device 'printer' emulates the HP Deskjet 920C printer. The PCL data is
|
||||
# sent to a file specified in bochsrc.txt. The current code appends the PCL
|
||||
# code to the file if the file already existed. The output file can be
|
||||
# changed at runtime.
|
||||
# sent to a file specified in the 'file' option with the optionsX parameter.
|
||||
# The current code appends the PCL code to the file if the file already existed.
|
||||
# The output file can be changed at runtime.
|
||||
#
|
||||
# The optionsX parameter can be used to assign specific options to the device
|
||||
# connected to the corresponding USB port. Currently this feature is used to
|
||||
# set the speed reported by device ('low', 'full', 'high' or 'super'). The
|
||||
# available speed choices depend on both HC and device. The option 'debug' turns
|
||||
# on debug output for the device at connection time.
|
||||
# connected to the corresponding USB port. The option 'speed' can be used to set
|
||||
# the speed reported by device ('low', 'full', 'high' or 'super'). The available
|
||||
# speed choices depend on both HC and device. The option 'debug' turns on debug
|
||||
# output for the device at connection time. The option 'pcap' turns on packet
|
||||
# logging in PCAP format.
|
||||
#
|
||||
# For the USB 'disk' device the optionsX parameter can be used to specify an
|
||||
# alternative redolog file (journal) of some image modes. For 'vvfat' mode USB
|
||||
# disks the optionsX parameter can be used to specify the disk size (range
|
||||
|
@ -1174,15 +1101,23 @@ e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=tuntap, ethdev=/dev/net/tun:tap0
|
|||
# supported (can fix hw detection in some guest OS). The USB floppy also
|
||||
# accepts the parameter "write_protected" with valid values 0 and 1 to select
|
||||
# the access mode (default is 0).
|
||||
#
|
||||
# For a high- or super-speed USB 'disk' device the optionsX parameter can include
|
||||
# the 'proto:bbb' or 'proto:uasp' parameter specifying to use either the bulk-only
|
||||
# Protocol (default) or the USB Attached SCSI Protocol. If no such parameter
|
||||
# is given, the 'bbb' protocol is used. A Guest that doesn't support UASP
|
||||
# should revert to bbb even if the 'uasp' attribute is given. See the usb_ehci:
|
||||
# or usb_xhci: section below for an example. (Only 1 LUN is available at this time)
|
||||
#=======================================================================
|
||||
#usb_uhci: enabled=1
|
||||
#usb_uhci: enabled=1, port1=mouse, port2=disk:usbstick.img
|
||||
#usb_uhci: enabled=1, port1=hub:7, port2=disk:growing:usbdisk.img
|
||||
#usb_uhci: enabled=1, port2=disk:undoable:usbdisk.img, options2=journal:redo.log
|
||||
#usb_uhci: enabled=1, port2=disk:usbdisk2.img, options2=sect_size:1024
|
||||
#usb_uhci: enabled=1, port2=disk:vvfat:vvfat, options2="debug,speed:full"
|
||||
#usb_uhci: enabled=1, port1=printer:printdata.bin, port2=cdrom:image.iso
|
||||
#usb_uhci: enabled=1, port2=floppy:vvfat:diskette, options2="model:teac"
|
||||
#usb_uhci: port1=mouse, port2=disk, options2="path:usbstick.img"
|
||||
#usb_uhci: port1=hub, options1="ports:6, pcap:outfile.pcap"
|
||||
#usb_uhci: port2=disk, options2="path:undoable:usbdisk.img, journal:u.redolog"
|
||||
#usb_uhci: port2=disk, options2=""path:usbdisk2.img, sect_size:1024"
|
||||
#usb_uhci: port2=disk, options2="path:vvfat:vvfat, debug, speed:full"
|
||||
#usb_uhci: port2=cdrom, options2="path:image.iso"
|
||||
#usb_uhci: port1=printer, options1="file:printdata.bin"
|
||||
#usb_uhci: port2=floppy, options2="path:vvfat:diskette, model:teac"
|
||||
|
||||
#=======================================================================
|
||||
# USB_OHCI:
|
||||
|
@ -1200,19 +1135,61 @@ e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=tuntap, ethdev=/dev/net/tun:tap0
|
|||
# 6-port hub. The portX parameter accepts the same device types with the
|
||||
# same syntax as the UHCI controller (see above). The optionsX parameter is
|
||||
# also available on EHCI.
|
||||
# The HC will default to three UHCI companion controllers, but you can specify
|
||||
# either UHCI or OHCI. Each companion controller will be evenly divided
|
||||
# with 2 ports each, the first 2 on the first companion, and so on.
|
||||
#=======================================================================
|
||||
#usb_ehci: enabled=1
|
||||
#usb_ehci: enabled=1, companion=uhci
|
||||
#usb_ehci: enabled=1, companion=ohci
|
||||
#usb_ehci: port1=disk, options1="speed:high, path:hdd.img, proto:bbb"
|
||||
#usb_ehci: port1=disk, options1="speed:high, path:hdd.img, proto:uasp"
|
||||
|
||||
#=======================================================================
|
||||
# USB_XHCI:
|
||||
# This option controls the presence of the USB xHCI host controller with a
|
||||
# 4-port hub. The portX parameter accepts the same device types with the
|
||||
# same syntax as the UHCI controller (see above). The optionsX parameter is
|
||||
# also available on xHCI. NOTE: port 1 and 2 are USB3 and only support
|
||||
# super-speed devices, but port 3 and 4 are USB2 and support speed settings
|
||||
# low, full and high.
|
||||
# default 4-port hub. The portX parameter accepts the same device types
|
||||
# with the same syntax as the UHCI controller (see above). The optionsX
|
||||
# parameter is also available on xHCI.
|
||||
#
|
||||
# The xHCI emulation allows you to set the number of ports used with a range
|
||||
# of 2 to 10, requiring an even numbered count.
|
||||
#
|
||||
# NOTE: The first half of the ports, (ports 1 and 2 on a 4-port hub) are
|
||||
# USB3 only and support super-speed devices. The second half ports (ports
|
||||
# 3 and 4) are USB2 and support speed settings of low, full, or high.
|
||||
# The xHCI also allows for different host controllers using the model=
|
||||
# parameter. Currently, the two allowed options are "uPD720202" and
|
||||
# "uPD720201". The first defaults to 2 sockets (4 ports) and the later
|
||||
# defaults to 4 sockets (8 ports).
|
||||
#=======================================================================
|
||||
#usb_xhci: enabled=1
|
||||
#usb_xhci: enabled=1 # defaults to the uPD720202 w/4 ports
|
||||
#usb_xhci: enabled=1, n_ports=6 # defaults to the uPD720202 w/6 ports
|
||||
#usb_xhci: enabled=1, model=uPD720202 # defaults to 4 ports
|
||||
#usb_xhci: enabled=1, model=uPD720202, n_ports=6 # change to 6 ports
|
||||
#usb_xhci: enabled=1, model=uPD720201 # defaults to 8 ports
|
||||
#usb_xhci: enabled=1, model=uPD720201, n_ports=10 # change to 10 ports
|
||||
#usb_xhci: port1=disk, options1="speed:super, path:hdd.img, proto:bbb"
|
||||
#usb_xhci: port1=disk, options1="speed:super, path:hdd.img, proto:uasp"
|
||||
#usb_xhci: port3=disk, options3="speed:high, path:hdd.img, proto:uasp"
|
||||
|
||||
#=======================================================================
|
||||
# USB Debugger:
|
||||
# This is the experimental USB Debugger for the Windows Platform.
|
||||
# Specify a type (none, uhci, ohci, ehci, xhci) and one or more triggers.
|
||||
# (Currently, only xhci is supported, with some uhci in the process)
|
||||
# Triggers:
|
||||
# reset: will break and load the debugger on a port reset
|
||||
# enable: will break and load the debugger on a port enable
|
||||
# doorbell: will break and load the debugger a xHCI Command Ring addition
|
||||
# event: will break and load the debugger on a xHCI Event Ring addition
|
||||
# data: will break and load the debugger on a xHCI Data Ring addition
|
||||
# start_frame: will break and load the debugger on start of frame
|
||||
# (this is different for each controller type)
|
||||
# non_exist: will break and load the debugger on a non-existant port access
|
||||
# (experimental and is under development)
|
||||
#=======================================================================
|
||||
#usb_debug: type=xhci, reset=1, enable=1, start_frame=1, doorbell=1, event=1, data=1, non_exist=1
|
||||
|
||||
#=======================================================================
|
||||
# PCIDEV:
|
||||
|
@ -1232,11 +1209,20 @@ e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=tuntap, ethdev=/dev/net/tun:tap0
|
|||
#=======================================================================
|
||||
# MAGIC_BREAK:
|
||||
# This enables the "magic breakpoint" feature when using the debugger.
|
||||
# The useless cpu instruction XCHG BX, BX causes Bochs to enter the
|
||||
# The useless cpu instructions XCHG %REGW, %REGW causes Bochs to enter the
|
||||
# debugger mode. This might be useful for software development.
|
||||
#
|
||||
# Example:
|
||||
# You can specify multiple at once:
|
||||
#
|
||||
# cx dx bx sp bp si di
|
||||
#
|
||||
# Example for breaking on "XCHGW %DI, %DI" or "XCHG %SP, %SP" execution
|
||||
# magic_break: enabled=1 di sp
|
||||
#
|
||||
# If nothing is specified, the default will be used: XCHGW %BX, %BX
|
||||
# magic_break: enabled=1
|
||||
#
|
||||
# Note: Windows XP ntldr can cause problems with XCHGW %BX, %BX
|
||||
#=======================================================================
|
||||
magic_break: enabled=1
|
||||
|
||||
|
@ -1262,12 +1248,27 @@ magic_break: enabled=1
|
|||
# very early when writing BIOS or OS code for example, without having to
|
||||
# bother with setting up a serial port or etc. Reading from port 0xE9 will
|
||||
# will return 0xe9 to let you know if the feature is available.
|
||||
# Leave this 0 unless you have a reason to use it.
|
||||
# Leave this 0 unless you have a reason to use it. By enabling the
|
||||
# 'all_rings' option, you can utilize the port e9 hack from ring3.
|
||||
#
|
||||
# Example:
|
||||
# port_e9_hack: enabled=1
|
||||
# port_e9_hack: enabled=1, all_rings=1
|
||||
#=======================================================================
|
||||
port_e9_hack: enabled=1
|
||||
port_e9_hack: enabled=1, all_rings=1
|
||||
|
||||
#=======================================================================
|
||||
# IODEBUG:
|
||||
# I/O Interface to Bochs Debugger plugin allows the code running inside
|
||||
# Bochs to monitor memory ranges, trace individual instructions, and
|
||||
# observe register values during execution. By enabling the 'all_rings'
|
||||
# option, you can utilize the iodebug ports from ring3. For more
|
||||
# information, refer to "Advanced debugger usage" documentation.
|
||||
#
|
||||
# Example:
|
||||
# iodebug: all_rings=1
|
||||
#=======================================================================
|
||||
#iodebug: all_rings=1
|
||||
|
||||
#=======================================================================
|
||||
# fullscreen: ONLY IMPLEMENTED ON AMIGA
|
||||
|
|
|
@ -484,6 +484,7 @@ CFLAGS += $(WORKAROUND_CFLAGS) $(EXTRA_CFLAGS)
|
|||
ASFLAGS += $(WORKAROUND_ASFLAGS) $(EXTRA_ASFLAGS)
|
||||
LDFLAGS += $(WORKAROUND_LDFLAGS) $(EXTRA_LDFLAGS)
|
||||
HOST_CFLAGS += -O2 -g
|
||||
HOST_EFI_CFLAGS += -fshort-wchar
|
||||
|
||||
# Inhibit -Werror if NO_WERROR is specified on make command line
|
||||
#
|
||||
|
@ -1449,22 +1450,22 @@ CLEANUP += $(ZBIN)
|
|||
|
||||
$(ELF2EFI32) : util/elf2efi.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [HOSTCC] $@"
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -DEFI_TARGET32 $< -o $@
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) $(HOST_EFI_CFLAGS) -idirafter include -DEFI_TARGET32 $< -o $@
|
||||
CLEANUP += $(ELF2EFI32)
|
||||
|
||||
$(ELF2EFI64) : util/elf2efi.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [HOSTCC] $@"
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -DEFI_TARGET64 $< -o $@
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) $(HOST_EFI_CFLAGS) -idirafter include -DEFI_TARGET64 $< -o $@
|
||||
CLEANUP += $(ELF2EFI64)
|
||||
|
||||
$(EFIROM) : util/efirom.c util/eficompress.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [HOSTCC] $@"
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -o $@ $<
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) $(HOST_EFI_CFLAGS) -idirafter include -o $@ $<
|
||||
CLEANUP += $(EFIROM)
|
||||
|
||||
$(EFIFATBIN) : util/efifatbin.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [HOSTCC] $@"
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -o $@ $<
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) $(HOST_EFI_CFLAGS) -idirafter include -o $@ $<
|
||||
CLEANUP += $(EFIFATBIN)
|
||||
|
||||
###############################################################################
|
||||
|
|
|
@ -123,16 +123,18 @@ bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shl_raw ( uint32_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint32_t *discard_value;
|
||||
uint32_t *discard_end;
|
||||
uint32_t discard_value_i;
|
||||
int carry;
|
||||
|
||||
__asm__ __volatile__ ( "adds %1, %0, %5, lsl #2\n\t" /* clear CF */
|
||||
__asm__ __volatile__ ( "adds %1, %0, %1, lsl #2\n\t" /* clear CF */
|
||||
"\n1:\n\t"
|
||||
"ldr %2, [%0]\n\t"
|
||||
"adcs %2, %2\n\t"
|
||||
|
@ -142,9 +144,10 @@ bigint_shl_raw ( uint32_t *value0, unsigned int size ) {
|
|||
: "=l" ( discard_value ),
|
||||
"=l" ( discard_end ),
|
||||
"=l" ( discard_value_i ),
|
||||
"=@cccs" ( carry ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 ), "1" ( size )
|
||||
: "cc" );
|
||||
: "0" ( value0 ), "1" ( size ) );
|
||||
return carry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,16 +155,18 @@ bigint_shl_raw ( uint32_t *value0, unsigned int size ) {
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shr_raw ( uint32_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint32_t *discard_value;
|
||||
uint32_t *discard_end;
|
||||
uint32_t discard_value_i;
|
||||
int carry;
|
||||
|
||||
__asm__ __volatile__ ( "adds %1, %0, %5, lsl #2\n\t" /* clear CF */
|
||||
__asm__ __volatile__ ( "adds %1, %0, %1, lsl #2\n\t" /* clear CF */
|
||||
"\n1:\n\t"
|
||||
"ldmdb %1!, {%2}\n\t"
|
||||
"rrxs %2, %2\n\t"
|
||||
|
@ -171,9 +176,10 @@ bigint_shr_raw ( uint32_t *value0, unsigned int size ) {
|
|||
: "=l" ( discard_value ),
|
||||
"=l" ( discard_end ),
|
||||
"=l" ( discard_value_i ),
|
||||
"=@cccs" ( carry ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 ), "1" ( size )
|
||||
: "cc" );
|
||||
: "0" ( value0 ), "1" ( size ) );
|
||||
return carry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -122,14 +122,16 @@ bigint_subtract_raw ( const uint64_t *subtrahend0, uint64_t *value0,
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shl_raw ( uint64_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
unsigned int discard_size;
|
||||
int carry;
|
||||
|
||||
__asm__ __volatile__ ( "cmn xzr, xzr\n\t" /* clear CF */
|
||||
"\n1:\n\t"
|
||||
|
@ -141,9 +143,10 @@ bigint_shl_raw ( uint64_t *value0, unsigned int size ) {
|
|||
: "=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=@cccs" ( carry ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 ), "1" ( size )
|
||||
: "cc" );
|
||||
: "0" ( value0 ), "1" ( size ) );
|
||||
return carry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,30 +154,32 @@ bigint_shl_raw ( uint64_t *value0, unsigned int size ) {
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shr_raw ( uint64_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_value_j;
|
||||
uint64_t discard_high;
|
||||
unsigned int discard_size;
|
||||
uint64_t low;
|
||||
|
||||
__asm__ __volatile__ ( "mov %3, #0\n\t"
|
||||
__asm__ __volatile__ ( "mov %2, #0\n\t"
|
||||
"\n1:\n\t"
|
||||
"sub %w1, %w1, #1\n\t"
|
||||
"ldr %2, [%0, %1, lsl #3]\n\t"
|
||||
"extr %3, %3, %2, #1\n\t"
|
||||
"str %3, [%0, %1, lsl #3]\n\t"
|
||||
"mov %3, %2\n\t"
|
||||
"ldr %3, [%0, %1, lsl #3]\n\t"
|
||||
"extr %2, %2, %3, #1\n\t"
|
||||
"str %2, [%0, %1, lsl #3]\n\t"
|
||||
"mov %2, %3\n\t"
|
||||
"cbnz %w1, 1b\n\t"
|
||||
: "=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_value_j ),
|
||||
"=r" ( discard_high ),
|
||||
"=r" ( low ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 ), "1" ( size ) );
|
||||
return ( low & 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -144,26 +144,27 @@ bigint_subtract_raw ( const uint64_t *subtrahend0, uint64_t *value0,
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shl_raw ( uint64_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
uint64_t carry;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load value[i] */
|
||||
"ld.d %2, %0, 0\n\t"
|
||||
/* Shift left */
|
||||
"rotri.d %2, %2, 63\n\t"
|
||||
"andi %4, %2, 1\n\t"
|
||||
"xor %2, %2, %4\n\t"
|
||||
"or %2, %2, %3\n\t"
|
||||
"move %3, %4\n\t"
|
||||
"andi %3, %2, 1\n\t"
|
||||
"xor %2, %2, %3\n\t"
|
||||
"or %2, %2, %4\n\t"
|
||||
"move %4, %3\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %2, %0, 0\n\t"
|
||||
/* Loop */
|
||||
|
@ -173,11 +174,12 @@ bigint_shl_raw ( uint64_t *value0, unsigned int size ) {
|
|||
: "=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"=r" ( carry ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 ), "1" ( size ), "3" ( 0 )
|
||||
: "0" ( value0 ), "1" ( size ), "4" ( 0 )
|
||||
: "cc" );
|
||||
return ( carry & 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,25 +187,26 @@ bigint_shl_raw ( uint64_t *value0, unsigned int size ) {
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shr_raw ( uint64_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
uint64_t carry;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load value[i] */
|
||||
"ld.d %2, %0, -8\n\t"
|
||||
/* Shift right */
|
||||
"andi %4, %2, 1\n\t"
|
||||
"xor %2, %2, %4\n\t"
|
||||
"or %2, %2, %3\n\t"
|
||||
"move %3, %4\n\t"
|
||||
"andi %3, %2, 1\n\t"
|
||||
"xor %2, %2, %3\n\t"
|
||||
"or %2, %2, %4\n\t"
|
||||
"move %4, %3\n\t"
|
||||
"rotri.d %2, %2, 1\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %2, %0, -8\n\t"
|
||||
|
@ -214,11 +217,12 @@ bigint_shr_raw ( uint64_t *value0, unsigned int size ) {
|
|||
: "=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"=r" ( carry ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 + size ), "1" ( size ), "3" ( 0 )
|
||||
: "0" ( value0 + size ), "1" ( size ), "4" ( 0 )
|
||||
: "cc" );
|
||||
return ( carry & 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,38 +143,40 @@ bigint_subtract_raw ( const unsigned long *subtrahend0, unsigned long *value0,
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shl_raw ( unsigned long *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
unsigned long *valueN = ( value0 + size );
|
||||
unsigned long *discard_value;
|
||||
unsigned long discard_value_i;
|
||||
unsigned long discard_carry;
|
||||
unsigned long discard_temp;
|
||||
unsigned long carry;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load value[i] */
|
||||
LOADN " %1, (%0)\n\t"
|
||||
/* Shift left */
|
||||
"slli %3, %1, 1\n\t"
|
||||
"or %3, %3, %2\n\t"
|
||||
"srli %2, %1, %7\n\t"
|
||||
"slli %2, %1, 1\n\t"
|
||||
"or %2, %2, %3\n\t"
|
||||
"srli %3, %1, %7\n\t"
|
||||
/* Store value[i] */
|
||||
STOREN " %3, (%0)\n\t"
|
||||
STOREN " %2, (%0)\n\t"
|
||||
/* Loop */
|
||||
"addi %0, %0, %6\n\t"
|
||||
"bne %0, %5, 1b\n\t"
|
||||
: "=&r" ( discard_value ),
|
||||
"=&r" ( discard_value_i ),
|
||||
"=&r" ( discard_carry ),
|
||||
"=&r" ( discard_temp ),
|
||||
"=&r" ( carry ),
|
||||
"+m" ( *value )
|
||||
: "r" ( valueN ),
|
||||
"i" ( sizeof ( unsigned long ) ),
|
||||
"i" ( ( 8 * sizeof ( unsigned long ) - 1 ) ),
|
||||
"0" ( value0 ), "2" ( 0 ) );
|
||||
"0" ( value0 ), "3" ( 0 ) );
|
||||
return carry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -182,38 +184,40 @@ bigint_shl_raw ( unsigned long *value0, unsigned int size ) {
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shr_raw ( unsigned long *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
unsigned long *valueN = ( value0 + size );
|
||||
unsigned long *discard_value;
|
||||
unsigned long discard_value_i;
|
||||
unsigned long discard_carry;
|
||||
unsigned long discard_temp;
|
||||
unsigned long carry;
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load value[i] */
|
||||
LOADN " %1, %6(%0)\n\t"
|
||||
/* Shift right */
|
||||
"srli %3, %1, 1\n\t"
|
||||
"or %3, %3, %2\n\t"
|
||||
"slli %2, %1, %7\n\t"
|
||||
"srli %2, %1, 1\n\t"
|
||||
"or %2, %2, %3\n\t"
|
||||
"slli %3, %1, %7\n\t"
|
||||
/* Store value[i] */
|
||||
STOREN " %3, %6(%0)\n\t"
|
||||
STOREN " %2, %6(%0)\n\t"
|
||||
/* Loop */
|
||||
"addi %0, %0, %6\n\t"
|
||||
"bne %0, %5, 1b\n\t"
|
||||
: "=&r" ( discard_value ),
|
||||
"=&r" ( discard_value_i ),
|
||||
"=&r" ( discard_carry ),
|
||||
"=&r" ( discard_temp ),
|
||||
"=&r" ( carry ),
|
||||
"+m" ( *value )
|
||||
: "r" ( value0 ),
|
||||
"i" ( -( sizeof ( unsigned long ) ) ),
|
||||
"i" ( ( 8 * sizeof ( unsigned long ) - 1 ) ),
|
||||
"0" ( valueN ), "2" ( 0 ) );
|
||||
"0" ( valueN ), "3" ( 0 ) );
|
||||
return ( !! carry );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -353,24 +353,35 @@ static size_t bzimage_load_initrd ( struct image *image,
|
|||
const char *filename = cpio_name ( initrd );
|
||||
struct cpio_header cpio;
|
||||
size_t offset;
|
||||
size_t cpio_len;
|
||||
size_t pad_len;
|
||||
size_t len;
|
||||
unsigned int i;
|
||||
|
||||
/* Skip hidden images */
|
||||
if ( initrd->flags & IMAGE_HIDDEN )
|
||||
return 0;
|
||||
|
||||
/* Create cpio header for non-prebuilt images */
|
||||
offset = cpio_header ( initrd, &cpio );
|
||||
/* Determine length of cpio headers for non-prebuilt images */
|
||||
len = 0;
|
||||
for ( i = 0 ; ( cpio_len = cpio_header ( initrd, i, &cpio ) ) ; i++ )
|
||||
len += ( cpio_len + cpio_pad_len ( cpio_len ) );
|
||||
|
||||
/* Copy in initrd image body (and cpio header if applicable) */
|
||||
/* Copy in initrd image body and construct any cpio headers */
|
||||
if ( address ) {
|
||||
memmove_user ( address, offset, initrd->data, 0, initrd->len );
|
||||
if ( offset ) {
|
||||
memset_user ( address, 0, 0, offset );
|
||||
copy_to_user ( address, 0, &cpio, sizeof ( cpio ) );
|
||||
copy_to_user ( address, sizeof ( cpio ), filename,
|
||||
cpio_name_len ( initrd ) );
|
||||
memmove_user ( address, len, initrd->data, 0, initrd->len );
|
||||
memset_user ( address, 0, 0, len );
|
||||
offset = 0;
|
||||
for ( i = 0 ; ( cpio_len = cpio_header ( initrd, i, &cpio ) ) ;
|
||||
i++ ) {
|
||||
copy_to_user ( address, offset, &cpio,
|
||||
sizeof ( cpio ) );
|
||||
copy_to_user ( address, ( offset + sizeof ( cpio ) ),
|
||||
filename,
|
||||
( cpio_len - sizeof ( cpio ) ) );
|
||||
offset += ( cpio_len + cpio_pad_len ( cpio_len ) );
|
||||
}
|
||||
assert ( offset == len );
|
||||
DBGC ( image, "bzImage %p initrd %p [%#08lx,%#08lx,%#08lx)"
|
||||
"%s%s\n", image, initrd, user_to_phys ( address, 0 ),
|
||||
user_to_phys ( address, offset ),
|
||||
|
@ -379,14 +390,14 @@ static size_t bzimage_load_initrd ( struct image *image,
|
|||
DBGC2_MD5A ( image, user_to_phys ( address, offset ),
|
||||
user_to_virt ( address, offset ), initrd->len );
|
||||
}
|
||||
offset += initrd->len;
|
||||
len += initrd->len;
|
||||
|
||||
/* Zero-pad to next INITRD_ALIGN boundary */
|
||||
pad_len = ( ( -offset ) & ( INITRD_ALIGN - 1 ) );
|
||||
pad_len = ( ( -len ) & ( INITRD_ALIGN - 1 ) );
|
||||
if ( address )
|
||||
memset_user ( address, offset, 0, pad_len );
|
||||
memset_user ( address, len, 0, pad_len );
|
||||
|
||||
return offset;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,22 +116,25 @@ bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shl_raw ( uint32_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
long index;
|
||||
long discard_c;
|
||||
int out;
|
||||
|
||||
__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
|
||||
"\n1:\n\t"
|
||||
"rcll $1, (%3,%0,4)\n\t"
|
||||
"rcll $1, (%4,%0,4)\n\t"
|
||||
"inc %0\n\t" /* Does not affect CF */
|
||||
"loop 1b\n\t"
|
||||
: "=&r" ( index ), "=&c" ( discard_c ),
|
||||
"+m" ( *value )
|
||||
"=@ccc" ( out ), "+m" ( *value )
|
||||
: "r" ( value0 ), "1" ( size ) );
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,19 +142,23 @@ bigint_shl_raw ( uint32_t *value0, unsigned int size ) {
|
|||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_shr_raw ( uint32_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
long discard_c;
|
||||
int out;
|
||||
|
||||
__asm__ __volatile__ ( "clc\n\t"
|
||||
"\n1:\n\t"
|
||||
"rcrl $1, -4(%2,%0,4)\n\t"
|
||||
"rcrl $1, -4(%3,%0,4)\n\t"
|
||||
"loop 1b\n\t"
|
||||
: "=&c" ( discard_c ), "+m" ( *value )
|
||||
: "=&c" ( discard_c ), "=@ccc" ( out ),
|
||||
"+m" ( *value )
|
||||
: "r" ( value0 ), "0" ( size ) );
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,9 +47,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
/* Macros to enable/disable IRQs */
|
||||
#define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR )
|
||||
#define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) )
|
||||
#define irq_enabled(x) ( ( inb ( IMR_REG(x) ) & IMR_BIT(x) ) == 0 )
|
||||
#define enable_irq(x) outb ( inb( IMR_REG(x) ) & ~IMR_BIT(x), IMR_REG(x) )
|
||||
#define disable_irq(x) outb ( inb( IMR_REG(x) ) | IMR_BIT(x), IMR_REG(x) )
|
||||
|
||||
/* Macros for acknowledging IRQs */
|
||||
#define ICR_REG( irq ) ( (irq) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR )
|
||||
|
@ -63,6 +60,50 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define IRQ_MAX 15
|
||||
#define IRQ_NONE -1U
|
||||
|
||||
/**
|
||||
* Check if interrupt is enabled
|
||||
*
|
||||
* @v irq Interrupt number
|
||||
* @ret enabled Interrupt is currently enabled
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
irq_enabled ( unsigned int irq ) {
|
||||
int imr = inb ( IMR_REG ( irq ) );
|
||||
int mask = IMR_BIT ( irq );
|
||||
|
||||
return ( ( imr & mask ) == 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable interrupt
|
||||
*
|
||||
* @v irq Interrupt number
|
||||
* @ret enabled Interrupt was previously enabled
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
enable_irq ( unsigned int irq ) {
|
||||
int imr = inb ( IMR_REG ( irq ) );
|
||||
int mask = IMR_BIT ( irq );
|
||||
|
||||
outb ( ( imr & ~mask ), IMR_REG ( irq ) );
|
||||
return ( ( imr & mask ) == 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable interrupt
|
||||
*
|
||||
* @v irq Interrupt number
|
||||
* @ret enabled Interrupt was previously enabled
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
disable_irq ( unsigned int irq ) {
|
||||
int imr = inb ( IMR_REG ( irq ) );
|
||||
int mask = IMR_BIT ( irq );
|
||||
|
||||
outb ( ( imr | mask ), IMR_REG ( irq ) );
|
||||
return ( ( imr & mask ) == 0 );
|
||||
}
|
||||
|
||||
/* Function prototypes
|
||||
*/
|
||||
void send_eoi ( unsigned int irq );
|
||||
|
|
|
@ -53,6 +53,12 @@ extern void rtc_isr ( void );
|
|||
/** Previous RTC interrupt handler */
|
||||
static struct segoff rtc_old_handler;
|
||||
|
||||
/** Previous RTC interrupt enabled state */
|
||||
static uint8_t rtc_irq_enabled;
|
||||
|
||||
/** Previous RTC periodic interrupt enabled state */
|
||||
static uint8_t rtc_int_enabled;
|
||||
|
||||
/** Flag set by RTC interrupt handler */
|
||||
extern volatile uint8_t __text16 ( rtc_flag );
|
||||
#define rtc_flag __use_text16 ( rtc_flag )
|
||||
|
@ -107,8 +113,9 @@ static void rtc_unhook_isr ( void ) {
|
|||
/**
|
||||
* Enable RTC interrupts
|
||||
*
|
||||
* @ret enabled Periodic interrupt was previously enabled
|
||||
*/
|
||||
static void rtc_enable_int ( void ) {
|
||||
static int rtc_enable_int ( void ) {
|
||||
uint8_t status_b;
|
||||
|
||||
/* Clear any stale pending interrupts via status register C */
|
||||
|
@ -124,6 +131,9 @@ static void rtc_enable_int ( void ) {
|
|||
/* Re-enable NMI and reset to default address */
|
||||
outb ( CMOS_DEFAULT_ADDRESS, CMOS_ADDRESS );
|
||||
inb ( CMOS_DATA ); /* Discard; may be needed on some platforms */
|
||||
|
||||
/* Return previous state */
|
||||
return ( status_b & RTC_STATUS_B_PIE );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,8 +208,11 @@ static int rtc_entropy_enable ( void ) {
|
|||
|
||||
/* Hook ISR and enable RTC interrupts */
|
||||
rtc_hook_isr();
|
||||
enable_irq ( RTC_IRQ );
|
||||
rtc_enable_int();
|
||||
rtc_irq_enabled = enable_irq ( RTC_IRQ );
|
||||
rtc_int_enabled = rtc_enable_int();
|
||||
DBGC ( &rtc_flag, "RTC had IRQ%d %sabled, interrupt %sabled\n",
|
||||
RTC_IRQ, ( rtc_irq_enabled ? "en" : "dis" ),
|
||||
( rtc_int_enabled ? "en" : "dis" ) );
|
||||
|
||||
/* Check that RTC interrupts are working */
|
||||
if ( ( rc = rtc_entropy_check() ) != 0 )
|
||||
|
@ -223,8 +236,10 @@ static int rtc_entropy_enable ( void ) {
|
|||
return 0;
|
||||
|
||||
err_check:
|
||||
rtc_disable_int();
|
||||
disable_irq ( RTC_IRQ );
|
||||
if ( ! rtc_int_enabled )
|
||||
rtc_disable_int();
|
||||
if ( ! rtc_irq_enabled )
|
||||
disable_irq ( RTC_IRQ );
|
||||
rtc_unhook_isr();
|
||||
err_no_tsc:
|
||||
return rc;
|
||||
|
@ -236,9 +251,11 @@ static int rtc_entropy_enable ( void ) {
|
|||
*/
|
||||
static void rtc_entropy_disable ( void ) {
|
||||
|
||||
/* Disable RTC interrupts and unhook ISR */
|
||||
rtc_disable_int();
|
||||
disable_irq ( RTC_IRQ );
|
||||
/* Restore RTC interrupt state and unhook ISR */
|
||||
if ( ! rtc_int_enabled )
|
||||
rtc_disable_int();
|
||||
if ( ! rtc_irq_enabled )
|
||||
disable_irq ( RTC_IRQ );
|
||||
rtc_unhook_isr();
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ hardware_subarch:
|
|||
hardware_subarch_data:
|
||||
.byte 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
.section ".prefix.data", "aw", @progbits
|
||||
version_string:
|
||||
.asciz VERSION
|
||||
|
||||
|
@ -113,6 +114,7 @@ version_string:
|
|||
*
|
||||
*/
|
||||
|
||||
.section ".prefix", "ax", @progbits
|
||||
setup:
|
||||
/* Fix up code segment */
|
||||
pushw %ds
|
||||
|
|
|
@ -37,3 +37,6 @@ REQUIRE_OBJECT ( der );
|
|||
#ifdef IMAGE_PEM
|
||||
REQUIRE_OBJECT ( pem );
|
||||
#endif
|
||||
#ifdef IMAGE_EFISIG
|
||||
REQUIRE_OBJECT ( efi_siglist );
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <config/general.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Certificate source configuration
|
||||
*
|
||||
*/
|
||||
|
||||
PROVIDE_REQUIRING_SYMBOL();
|
||||
|
||||
#ifdef CERTS_EFI
|
||||
REQUIRE_OBJECT ( efi_cacert );
|
||||
#endif
|
|
@ -88,6 +88,16 @@ REQUIRE_OBJECT ( oid_sha512_256 );
|
|||
REQUIRE_OBJECT ( oid_x25519 );
|
||||
#endif
|
||||
|
||||
/* P-256 */
|
||||
#if defined ( CRYPTO_CURVE_P256 )
|
||||
REQUIRE_OBJECT ( oid_p256 );
|
||||
#endif
|
||||
|
||||
/* P-384 */
|
||||
#if defined ( CRYPTO_CURVE_P384 )
|
||||
REQUIRE_OBJECT ( oid_p384 );
|
||||
#endif
|
||||
|
||||
/* AES-CBC */
|
||||
#if defined ( CRYPTO_CIPHER_AES_CBC )
|
||||
REQUIRE_OBJECT ( oid_aes_cbc );
|
||||
|
|
|
@ -60,6 +60,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
/** X25519 elliptic curve */
|
||||
#define CRYPTO_CURVE_X25519
|
||||
|
||||
/** P-256 elliptic curve */
|
||||
#define CRYPTO_CURVE_P256
|
||||
|
||||
/** P-384 elliptic curve */
|
||||
#define CRYPTO_CURVE_P384
|
||||
|
||||
/** Margin of error (in seconds) allowed in signed timestamps
|
||||
*
|
||||
* We default to allowing a reasonable margin of error: 12 hours to
|
||||
|
|
|
@ -35,6 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
#define IMAGE_EFI /* EFI image support */
|
||||
#define IMAGE_SCRIPT /* iPXE script image support */
|
||||
#define IMAGE_EFISIG /* EFI signature list support */
|
||||
|
||||
#define SANBOOT_PROTO_ISCSI /* iSCSI protocol */
|
||||
#define SANBOOT_PROTO_AOE /* AoE protocol */
|
||||
|
@ -53,6 +54,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define EFI_SETTINGS /* EFI variable settings */
|
||||
|
||||
#define TPM_SETTINGS /* EFI TPM settings */
|
||||
#define CERTS_EFI /* EFI certificate sources */
|
||||
|
||||
#if defined ( __i386__ ) || defined ( __x86_64__ )
|
||||
#define IOAPI_X86
|
||||
|
|
|
@ -125,6 +125,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define IMAGE_PNG /* PNG image support */
|
||||
#define IMAGE_DER /* DER image support */
|
||||
#define IMAGE_PEM /* PEM image support */
|
||||
//#define IMAGE_EFISIG /* EFI signature list image support */
|
||||
//#define IMAGE_ZLIB /* ZLIB image support */
|
||||
//#define IMAGE_GZIP /* GZIP image support */
|
||||
//#define IMAGE_UCODE /* Microcode update image support */
|
||||
|
@ -173,6 +174,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define SHIM_CMD /* EFI shim command (or dummy command) */
|
||||
//#define USB_CMD /* USB commands */
|
||||
|
||||
/*
|
||||
* Certificate sources
|
||||
*
|
||||
*/
|
||||
//#undef CERTS_EFI /* EFI certificate sources */
|
||||
|
||||
/*
|
||||
* ROM-specific options
|
||||
*
|
||||
|
|
|
@ -13,6 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
#define PCI_SETTINGS /* PCI device settings */
|
||||
#define USB_SETTINGS /* USB device settings */
|
||||
#define EFI_SETTINGS /* EFI settings */
|
||||
//#define CPUID_SETTINGS /* CPUID settings */
|
||||
//#define MEMMAP_SETTINGS /* Memory map settings */
|
||||
//#define VMWARE_SETTINGS /* VMware GuestInfo settings */
|
||||
|
|
138
src/core/cpio.c
138
src/core/cpio.c
|
@ -34,13 +34,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <string.h>
|
||||
#include <ipxe/cpio.h>
|
||||
|
||||
/** CPIO default file mode */
|
||||
#define CPIO_DEFAULT_MODE 0644
|
||||
|
||||
/** CPIO directory mode */
|
||||
#define CPIO_DEFAULT_DIR_MODE 0755
|
||||
|
||||
/**
|
||||
* Set field within a CPIO header
|
||||
*
|
||||
* @v field Field within CPIO header
|
||||
* @v value Value to set
|
||||
*/
|
||||
void cpio_set_field ( char *field, unsigned long value ) {
|
||||
static void cpio_set_field ( char *field, unsigned long value ) {
|
||||
char buf[9];
|
||||
|
||||
snprintf ( buf, sizeof ( buf ), "%08lx", value );
|
||||
|
@ -48,23 +54,53 @@ void cpio_set_field ( char *field, unsigned long value ) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get CPIO image filename
|
||||
* Get maximum number of CPIO headers (i.e. number of path components)
|
||||
*
|
||||
* @v image Image
|
||||
* @ret len CPIO filename length (0 for no filename)
|
||||
* @ret max Maximum number of CPIO headers
|
||||
*/
|
||||
size_t cpio_name_len ( struct image *image ) {
|
||||
static unsigned int cpio_max ( struct image *image ) {
|
||||
const char *name = cpio_name ( image );
|
||||
char *sep;
|
||||
size_t len;
|
||||
unsigned int max = 0;
|
||||
char c;
|
||||
char p;
|
||||
|
||||
/* Check for existence of CPIO filename */
|
||||
if ( ! name )
|
||||
return 0;
|
||||
|
||||
/* Locate separator (if any) */
|
||||
sep = strchr ( name, ' ' );
|
||||
len = ( sep ? ( ( size_t ) ( sep - name ) ) : strlen ( name ) );
|
||||
/* Count number of path components */
|
||||
for ( p = '/' ; ( ( ( c = *(name++) ) ) && ( c != ' ' ) ) ; p = c ) {
|
||||
if ( ( p == '/' ) && ( c != '/' ) )
|
||||
max++;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CPIO image filename
|
||||
*
|
||||
* @v image Image
|
||||
* @v depth Path depth
|
||||
* @ret len Filename length
|
||||
*/
|
||||
static size_t cpio_name_len ( struct image *image, unsigned int depth ) {
|
||||
const char *name = cpio_name ( image );
|
||||
size_t len;
|
||||
char c;
|
||||
char p;
|
||||
|
||||
/* Sanity checks */
|
||||
assert ( name != NULL );
|
||||
assert ( depth > 0 );
|
||||
|
||||
/* Calculate length up to specified path depth */
|
||||
for ( len = 0, p = '/' ; ( ( ( c = name[len] ) ) && ( c != ' ' ) ) ;
|
||||
len++, p = c ) {
|
||||
if ( ( c == '/' ) && ( p != '/' ) && ( --depth == 0 ) )
|
||||
break;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
@ -73,55 +109,99 @@ size_t cpio_name_len ( struct image *image ) {
|
|||
* Parse CPIO image parameters
|
||||
*
|
||||
* @v image Image
|
||||
* @v cpio CPIO header to fill in
|
||||
* @v mode Mode to fill in
|
||||
* @v count Number of CPIO headers to fill in
|
||||
*/
|
||||
static void cpio_parse_cmdline ( struct image *image,
|
||||
struct cpio_header *cpio ) {
|
||||
static void cpio_parse_cmdline ( struct image *image, unsigned int *mode,
|
||||
unsigned int *count ) {
|
||||
const char *arg;
|
||||
char *end;
|
||||
unsigned int mode;
|
||||
|
||||
/* Look for "mode=" */
|
||||
/* Set default values */
|
||||
*mode = CPIO_DEFAULT_MODE;
|
||||
*count = 1;
|
||||
|
||||
/* Parse "mode=...", if present */
|
||||
if ( ( arg = image_argument ( image, "mode=" ) ) ) {
|
||||
mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
|
||||
*mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
|
||||
if ( *end && ( *end != ' ' ) ) {
|
||||
DBGC ( image, "CPIO %p strange \"mode=\" "
|
||||
"terminator '%c'\n", image, *end );
|
||||
}
|
||||
cpio_set_field ( cpio->c_mode, ( 0100000 | mode ) );
|
||||
}
|
||||
|
||||
/* Parse "mkdir=...", if present */
|
||||
if ( ( arg = image_argument ( image, "mkdir=" ) ) ) {
|
||||
*count += strtoul ( arg, &end, 10 );
|
||||
if ( *end && ( *end != ' ' ) ) {
|
||||
DBGC ( image, "CPIO %p strange \"mkdir=\" "
|
||||
"terminator '%c'\n", image, *end );
|
||||
}
|
||||
}
|
||||
|
||||
/* Allow "mkdir=-1" to request creation of full directory tree */
|
||||
if ( ! *count )
|
||||
*count = -1U;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct CPIO header for image, if applicable
|
||||
*
|
||||
* @v image Image
|
||||
* @v index CPIO header index
|
||||
* @v cpio CPIO header to fill in
|
||||
* @ret len Length of magic CPIO header (including filename)
|
||||
* @ret len Length of CPIO header (including name, excluding NUL)
|
||||
*/
|
||||
size_t cpio_header ( struct image *image, struct cpio_header *cpio ) {
|
||||
size_t cpio_header ( struct image *image, unsigned int index,
|
||||
struct cpio_header *cpio ) {
|
||||
const char *name = cpio_name ( image );
|
||||
unsigned int mode;
|
||||
unsigned int count;
|
||||
unsigned int max;
|
||||
unsigned int depth;
|
||||
unsigned int i;
|
||||
size_t name_len;
|
||||
size_t len;
|
||||
|
||||
/* Get filename length */
|
||||
name_len = cpio_name_len ( image );
|
||||
/* Parse command line arguments */
|
||||
cpio_parse_cmdline ( image, &mode, &count );
|
||||
|
||||
/* Images with no filename are assumed to already be CPIO archives */
|
||||
if ( ! name_len )
|
||||
/* Determine number of CPIO headers to be constructed */
|
||||
max = cpio_max ( image );
|
||||
if ( count > max )
|
||||
count = max;
|
||||
|
||||
/* Determine path depth of this CPIO header */
|
||||
if ( index >= count )
|
||||
return 0;
|
||||
depth = ( max - count + index + 1 );
|
||||
|
||||
/* Get filename length */
|
||||
name_len = cpio_name_len ( image, depth );
|
||||
|
||||
/* Set directory mode or file mode as appropriate */
|
||||
if ( name[name_len] == '/' ) {
|
||||
mode = ( CPIO_MODE_DIR | CPIO_DEFAULT_DIR_MODE );
|
||||
} else {
|
||||
mode |= CPIO_MODE_FILE;
|
||||
}
|
||||
|
||||
/* Set length on final header */
|
||||
len = ( ( depth < max ) ? 0 : image->len );
|
||||
|
||||
/* Construct CPIO header */
|
||||
memset ( cpio, '0', sizeof ( *cpio ) );
|
||||
memcpy ( cpio->c_magic, CPIO_MAGIC, sizeof ( cpio->c_magic ) );
|
||||
cpio_set_field ( cpio->c_mode, 0100644 );
|
||||
cpio_set_field ( cpio->c_mode, mode );
|
||||
cpio_set_field ( cpio->c_nlink, 1 );
|
||||
cpio_set_field ( cpio->c_filesize, image->len );
|
||||
cpio_set_field ( cpio->c_filesize, len );
|
||||
cpio_set_field ( cpio->c_namesize, ( name_len + 1 /* NUL */ ) );
|
||||
cpio_parse_cmdline ( image, cpio );
|
||||
DBGC ( image, "CPIO %s %d/%d \"", image->name, depth, max );
|
||||
for ( i = 0 ; i < name_len ; i++ )
|
||||
DBGC ( image, "%c", name[i] );
|
||||
DBGC ( image, "\"\n" );
|
||||
DBGC2_HDA ( image, 0, cpio, sizeof ( *cpio ) );
|
||||
|
||||
/* Calculate total length */
|
||||
len = ( ( sizeof ( *cpio ) + name_len + 1 /* NUL */ + CPIO_ALIGN - 1 )
|
||||
& ~( CPIO_ALIGN - 1 ) );
|
||||
|
||||
return len;
|
||||
return ( sizeof ( *cpio ) + name_len );
|
||||
}
|
||||
|
|
|
@ -59,7 +59,8 @@ struct memory_block {
|
|||
struct list_head list;
|
||||
};
|
||||
|
||||
#define MIN_MEMBLOCK_SIZE \
|
||||
/** Physical address alignment maintained for free blocks of memory */
|
||||
#define MEMBLOCK_ALIGN \
|
||||
( ( size_t ) ( 1 << ( fls ( sizeof ( struct memory_block ) - 1 ) ) ) )
|
||||
|
||||
/** A block of allocated memory complete with size information */
|
||||
|
@ -107,7 +108,7 @@ size_t maxusedmem;
|
|||
#define HEAP_SIZE ( 512 * 1024 )
|
||||
|
||||
/** The heap itself */
|
||||
static char heap[HEAP_SIZE] __attribute__ (( aligned ( __alignof__(void *) )));
|
||||
static char heap[HEAP_SIZE];
|
||||
|
||||
/**
|
||||
* Mark all blocks in free list as defined
|
||||
|
@ -211,12 +212,16 @@ static inline void check_blocks ( void ) {
|
|||
|
||||
list_for_each_entry ( block, &free_blocks, list ) {
|
||||
|
||||
/* Check alignment */
|
||||
assert ( ( virt_to_phys ( block ) &
|
||||
( MEMBLOCK_ALIGN - 1 ) ) == 0 );
|
||||
|
||||
/* Check that list structure is intact */
|
||||
list_check ( &block->list );
|
||||
|
||||
/* Check that block size is not too small */
|
||||
assert ( block->size >= sizeof ( *block ) );
|
||||
assert ( block->size >= MIN_MEMBLOCK_SIZE );
|
||||
assert ( block->size >= MEMBLOCK_ALIGN );
|
||||
|
||||
/* Check that block does not wrap beyond end of address space */
|
||||
assert ( ( ( void * ) block + block->size ) >
|
||||
|
@ -278,6 +283,7 @@ static void discard_all_cache ( void ) {
|
|||
*/
|
||||
void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
|
||||
struct memory_block *block;
|
||||
size_t actual_offset;
|
||||
size_t align_mask;
|
||||
size_t actual_size;
|
||||
size_t pre_size;
|
||||
|
@ -293,11 +299,13 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
|
|||
valgrind_make_blocks_defined();
|
||||
check_blocks();
|
||||
|
||||
/* Round up size to multiple of MIN_MEMBLOCK_SIZE and
|
||||
* calculate alignment mask.
|
||||
*/
|
||||
actual_size = ( ( size + MIN_MEMBLOCK_SIZE - 1 ) &
|
||||
~( MIN_MEMBLOCK_SIZE - 1 ) );
|
||||
/* Calculate offset of memory block */
|
||||
actual_offset = ( offset & ~( MEMBLOCK_ALIGN - 1 ) );
|
||||
assert ( actual_offset <= offset );
|
||||
|
||||
/* Calculate size of memory block */
|
||||
actual_size = ( ( size + offset - actual_offset + MEMBLOCK_ALIGN - 1 )
|
||||
& ~( MEMBLOCK_ALIGN - 1 ) );
|
||||
if ( ! actual_size ) {
|
||||
/* The requested size is not permitted to be zero. A
|
||||
* zero result at this point indicates that either the
|
||||
|
@ -308,14 +316,16 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
|
|||
goto done;
|
||||
}
|
||||
assert ( actual_size >= size );
|
||||
align_mask = ( ( align - 1 ) | ( MIN_MEMBLOCK_SIZE - 1 ) );
|
||||
|
||||
DBGC2 ( &heap, "Allocating %#zx (aligned %#zx+%zx)\n",
|
||||
/* Calculate alignment mask */
|
||||
align_mask = ( ( align - 1 ) | ( MEMBLOCK_ALIGN - 1 ) );
|
||||
|
||||
DBGC2 ( &heap, "HEAP allocating %#zx (aligned %#zx+%zx)\n",
|
||||
size, align, offset );
|
||||
while ( 1 ) {
|
||||
/* Search through blocks for the first one with enough space */
|
||||
list_for_each_entry ( block, &free_blocks, list ) {
|
||||
pre_size = ( ( offset - virt_to_phys ( block ) )
|
||||
pre_size = ( ( actual_offset - virt_to_phys ( block ) )
|
||||
& align_mask );
|
||||
if ( ( block->size < pre_size ) ||
|
||||
( ( block->size - pre_size ) < actual_size ) )
|
||||
|
@ -329,15 +339,15 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
|
|||
pre = block;
|
||||
block = ( ( ( void * ) pre ) + pre_size );
|
||||
post = ( ( ( void * ) block ) + actual_size );
|
||||
DBGC2 ( &heap, "[%p,%p) -> [%p,%p) + [%p,%p)\n", pre,
|
||||
DBGC2 ( &heap, "HEAP splitting [%p,%p) -> [%p,%p) "
|
||||
"+ [%p,%p)\n", pre,
|
||||
( ( ( void * ) pre ) + pre->size ), pre, block,
|
||||
post, ( ( ( void * ) pre ) + pre->size ) );
|
||||
/* If there is a "post" block, add it in to
|
||||
* the free list. Leak it if it is too small
|
||||
* (which can happen only at the very end of
|
||||
* the heap).
|
||||
* the free list.
|
||||
*/
|
||||
if ( post_size >= MIN_MEMBLOCK_SIZE ) {
|
||||
if ( post_size ) {
|
||||
assert ( post_size >= MEMBLOCK_ALIGN );
|
||||
VALGRIND_MAKE_MEM_UNDEFINED ( post,
|
||||
sizeof ( *post ));
|
||||
post->size = post_size;
|
||||
|
@ -349,14 +359,14 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
|
|||
*/
|
||||
pre->size = pre_size;
|
||||
/* If there is no "pre" block, remove it from
|
||||
* the list. Also remove it (i.e. leak it) if
|
||||
* it is too small, which can happen only at
|
||||
* the very start of the heap.
|
||||
* the list.
|
||||
*/
|
||||
if ( pre_size < MIN_MEMBLOCK_SIZE ) {
|
||||
if ( ! pre_size ) {
|
||||
list_del ( &pre->list );
|
||||
VALGRIND_MAKE_MEM_NOACCESS ( pre,
|
||||
sizeof ( *pre ) );
|
||||
} else {
|
||||
assert ( pre_size >= MEMBLOCK_ALIGN );
|
||||
}
|
||||
/* Update memory usage statistics */
|
||||
freemem -= actual_size;
|
||||
|
@ -364,23 +374,25 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
|
|||
if ( usedmem > maxusedmem )
|
||||
maxusedmem = usedmem;
|
||||
/* Return allocated block */
|
||||
DBGC2 ( &heap, "Allocated [%p,%p)\n", block,
|
||||
( ( ( void * ) block ) + size ) );
|
||||
ptr = block;
|
||||
ptr = ( ( ( void * ) block ) + offset - actual_offset );
|
||||
DBGC2 ( &heap, "HEAP allocated [%p,%p) within "
|
||||
"[%p,%p)\n", ptr, ( ptr + size ), block,
|
||||
( ( ( void * ) block ) + actual_size ) );
|
||||
VALGRIND_MAKE_MEM_UNDEFINED ( ptr, size );
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Try discarding some cached data to free up memory */
|
||||
DBGC ( &heap, "Attempting discard for %#zx (aligned %#zx+%zx), "
|
||||
"used %zdkB\n", size, align, offset, ( usedmem >> 10 ) );
|
||||
DBGC ( &heap, "HEAP attempting discard for %#zx (aligned "
|
||||
"%#zx+%zx), used %zdkB\n", size, align, offset,
|
||||
( usedmem >> 10 ) );
|
||||
valgrind_make_blocks_noaccess();
|
||||
discarded = discard_cache();
|
||||
valgrind_make_blocks_defined();
|
||||
check_blocks();
|
||||
if ( ! discarded ) {
|
||||
/* Nothing available to discard */
|
||||
DBGC ( &heap, "Failed to allocate %#zx (aligned "
|
||||
DBGC ( &heap, "HEAP failed to allocate %#zx (aligned "
|
||||
"%#zx)\n", size, align );
|
||||
ptr = NULL;
|
||||
goto done;
|
||||
|
@ -405,6 +417,7 @@ void free_memblock ( void *ptr, size_t size ) {
|
|||
struct memory_block *freeing;
|
||||
struct memory_block *block;
|
||||
struct memory_block *tmp;
|
||||
size_t sub_offset;
|
||||
size_t actual_size;
|
||||
ssize_t gap_before;
|
||||
ssize_t gap_after = -1;
|
||||
|
@ -418,16 +431,18 @@ void free_memblock ( void *ptr, size_t size ) {
|
|||
valgrind_make_blocks_defined();
|
||||
check_blocks();
|
||||
|
||||
/* Round up size to match actual size that alloc_memblock()
|
||||
* would have used.
|
||||
/* Round up to match actual block that alloc_memblock() would
|
||||
* have allocated.
|
||||
*/
|
||||
assert ( size != 0 );
|
||||
actual_size = ( ( size + MIN_MEMBLOCK_SIZE - 1 ) &
|
||||
~( MIN_MEMBLOCK_SIZE - 1 ) );
|
||||
freeing = ptr;
|
||||
sub_offset = ( virt_to_phys ( ptr ) & ( MEMBLOCK_ALIGN - 1) );
|
||||
freeing = ( ptr - sub_offset );
|
||||
actual_size = ( ( size + sub_offset + MEMBLOCK_ALIGN - 1 ) &
|
||||
~( MEMBLOCK_ALIGN - 1 ) );
|
||||
DBGC2 ( &heap, "HEAP freeing [%p,%p) within [%p,%p)\n",
|
||||
ptr, ( ptr + size ), freeing,
|
||||
( ( ( void * ) freeing ) + actual_size ) );
|
||||
VALGRIND_MAKE_MEM_UNDEFINED ( freeing, sizeof ( *freeing ) );
|
||||
DBGC2 ( &heap, "Freeing [%p,%p)\n",
|
||||
freeing, ( ( ( void * ) freeing ) + size ) );
|
||||
|
||||
/* Check that this block does not overlap the free list */
|
||||
if ( ASSERTING ) {
|
||||
|
@ -437,7 +452,7 @@ void free_memblock ( void *ptr, size_t size ) {
|
|||
( ( void * ) freeing <
|
||||
( ( void * ) block + block->size ) ) ) {
|
||||
assert ( 0 );
|
||||
DBGC ( &heap, "Double free of [%p,%p) "
|
||||
DBGC ( &heap, "HEAP double free of [%p,%p) "
|
||||
"overlapping [%p,%p) detected from %p\n",
|
||||
freeing,
|
||||
( ( ( void * ) freeing ) + size ), block,
|
||||
|
@ -457,7 +472,8 @@ void free_memblock ( void *ptr, size_t size ) {
|
|||
( ( ( void * ) freeing ) + freeing->size ) );
|
||||
/* Merge with immediately preceding block, if possible */
|
||||
if ( gap_before == 0 ) {
|
||||
DBGC2 ( &heap, "[%p,%p) + [%p,%p) -> [%p,%p)\n", block,
|
||||
DBGC2 ( &heap, "HEAP merging [%p,%p) + [%p,%p) -> "
|
||||
"[%p,%p)\n", block,
|
||||
( ( ( void * ) block ) + block->size ), freeing,
|
||||
( ( ( void * ) freeing ) + freeing->size ),
|
||||
block,
|
||||
|
@ -477,13 +493,13 @@ void free_memblock ( void *ptr, size_t size ) {
|
|||
* possible, merge the following block into the "freeing"
|
||||
* block.
|
||||
*/
|
||||
DBGC2 ( &heap, "[%p,%p)\n",
|
||||
DBGC2 ( &heap, "HEAP freed [%p,%p)\n",
|
||||
freeing, ( ( ( void * ) freeing ) + freeing->size ) );
|
||||
list_add_tail ( &freeing->list, &block->list );
|
||||
if ( gap_after == 0 ) {
|
||||
DBGC2 ( &heap, "[%p,%p) + [%p,%p) -> [%p,%p)\n", freeing,
|
||||
( ( ( void * ) freeing ) + freeing->size ), block,
|
||||
( ( ( void * ) block ) + block->size ), freeing,
|
||||
DBGC2 ( &heap, "HEAP merging [%p,%p) + [%p,%p) -> [%p,%p)\n",
|
||||
freeing, ( ( ( void * ) freeing ) + freeing->size ),
|
||||
block, ( ( ( void * ) block ) + block->size ), freeing,
|
||||
( ( ( void * ) block ) + block->size ) );
|
||||
freeing->size += block->size;
|
||||
list_del ( &block->list );
|
||||
|
@ -543,7 +559,7 @@ void * realloc ( void *old_ptr, size_t new_size ) {
|
|||
new_ptr = &new_block->data;
|
||||
VALGRIND_MALLOCLIKE_BLOCK ( new_ptr, new_size, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
/* Copy across relevant part of the old data region (if any),
|
||||
* then free it. Note that at this point either (a) new_ptr
|
||||
* is valid, or (b) new_size is 0; either way, the memcpy() is
|
||||
|
@ -565,8 +581,8 @@ void * realloc ( void *old_ptr, size_t new_size ) {
|
|||
}
|
||||
|
||||
if ( ASSERTED ) {
|
||||
DBGC ( &heap, "Possible memory corruption detected from %p\n",
|
||||
__builtin_return_address ( 0 ) );
|
||||
DBGC ( &heap, "HEAP detected possible memory corruption "
|
||||
"from %p\n", __builtin_return_address ( 0 ) );
|
||||
}
|
||||
return new_ptr;
|
||||
}
|
||||
|
@ -585,8 +601,8 @@ void * malloc ( size_t size ) {
|
|||
|
||||
ptr = realloc ( NULL, size );
|
||||
if ( ASSERTED ) {
|
||||
DBGC ( &heap, "Possible memory corruption detected from %p\n",
|
||||
__builtin_return_address ( 0 ) );
|
||||
DBGC ( &heap, "HEAP detected possible memory corruption "
|
||||
"from %p\n", __builtin_return_address ( 0 ) );
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
@ -605,8 +621,8 @@ void free ( void *ptr ) {
|
|||
|
||||
realloc ( ptr, 0 );
|
||||
if ( ASSERTED ) {
|
||||
DBGC ( &heap, "Possible memory corruption detected from %p\n",
|
||||
__builtin_return_address ( 0 ) );
|
||||
DBGC ( &heap, "HEAP detected possible memory corruption "
|
||||
"from %p\n", __builtin_return_address ( 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,8 +644,8 @@ void * zalloc ( size_t size ) {
|
|||
if ( data )
|
||||
memset ( data, 0, size );
|
||||
if ( ASSERTED ) {
|
||||
DBGC ( &heap, "Possible memory corruption detected from %p\n",
|
||||
__builtin_return_address ( 0 ) );
|
||||
DBGC ( &heap, "HEAP detected possible memory corruption "
|
||||
"from %p\n", __builtin_return_address ( 0 ) );
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
@ -638,19 +654,25 @@ void * zalloc ( size_t size ) {
|
|||
* Add memory to allocation pool
|
||||
*
|
||||
* @v start Start address
|
||||
* @v end End address
|
||||
* @v len Length of memory
|
||||
*
|
||||
* Adds a block of memory [start,end) to the allocation pool. This is
|
||||
* a one-way operation; there is no way to reclaim this memory.
|
||||
*
|
||||
* @c start must be aligned to at least a multiple of sizeof(void*).
|
||||
* Adds a block of memory to the allocation pool. This is a one-way
|
||||
* operation; there is no way to reclaim this memory.
|
||||
*/
|
||||
void mpopulate ( void *start, size_t len ) {
|
||||
static void mpopulate ( void *start, size_t len ) {
|
||||
size_t skip;
|
||||
|
||||
/* Prevent free_memblock() from rounding up len beyond the end
|
||||
* of what we were actually given...
|
||||
*/
|
||||
len &= ~( MIN_MEMBLOCK_SIZE - 1 );
|
||||
/* Align start of block */
|
||||
skip = ( ( -virt_to_phys ( start ) ) & ( MEMBLOCK_ALIGN - 1 ) );
|
||||
if ( skip > len )
|
||||
return;
|
||||
start += skip;
|
||||
len -= skip;
|
||||
|
||||
/* Align end of block */
|
||||
len &= ~( MEMBLOCK_ALIGN - 1 );
|
||||
if ( ! len )
|
||||
return;
|
||||
|
||||
/* Add to allocation pool */
|
||||
free_memblock ( start, len );
|
||||
|
@ -680,7 +702,7 @@ struct init_fn heap_init_fn __init_fn ( INIT_EARLY ) = {
|
|||
*/
|
||||
static void shutdown_cache ( int booting __unused ) {
|
||||
discard_all_cache();
|
||||
DBGC ( &heap, "Maximum heap usage %zdkB\n", ( maxusedmem >> 10 ) );
|
||||
DBGC ( &heap, "HEAP maximum usage %zdkB\n", ( maxusedmem >> 10 ) );
|
||||
}
|
||||
|
||||
/** Memory allocator shutdown function */
|
||||
|
@ -689,19 +711,17 @@ struct startup_fn heap_startup_fn __startup_fn ( STARTUP_EARLY ) = {
|
|||
.shutdown = shutdown_cache,
|
||||
};
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
/**
|
||||
* Dump free block list
|
||||
* Dump free block list (for debugging)
|
||||
*
|
||||
*/
|
||||
void mdumpfree ( void ) {
|
||||
struct memory_block *block;
|
||||
|
||||
printf ( "Free block list:\n" );
|
||||
dbg_printf ( "HEAP free block list:\n" );
|
||||
list_for_each_entry ( block, &free_blocks, list ) {
|
||||
printf ( "[%p,%p] (size %#zx)\n", block,
|
||||
( ( ( void * ) block ) + block->size ), block->size );
|
||||
dbg_printf ( "...[%p,%p] (size %#zx)\n", block,
|
||||
( ( ( void * ) block ) + block->size ),
|
||||
block->size );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,7 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ipxe/profile.h>
|
||||
#include <stdio.h>
|
||||
#include <ipxe/bigint.h>
|
||||
|
||||
/** @file
|
||||
|
@ -34,9 +34,51 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
* Big integer support
|
||||
*/
|
||||
|
||||
/** Modular direct reduction profiler */
|
||||
static struct profiler bigint_mod_profiler __profiler =
|
||||
{ .name = "bigint_mod" };
|
||||
/** Minimum number of least significant bytes included in transcription */
|
||||
#define BIGINT_NTOA_LSB_MIN 16
|
||||
|
||||
/**
|
||||
* Transcribe big integer (for debugging)
|
||||
*
|
||||
* @v value0 Element 0 of big integer to be transcribed
|
||||
* @v size Number of elements
|
||||
* @ret string Big integer in string form (may be abbreviated)
|
||||
*/
|
||||
const char * bigint_ntoa_raw ( const bigint_element_t *value0,
|
||||
unsigned int size ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*value = ( ( const void * ) value0 );
|
||||
bigint_element_t element;
|
||||
static char buf[256];
|
||||
unsigned int count;
|
||||
int threshold;
|
||||
uint8_t byte;
|
||||
char *tmp;
|
||||
int i;
|
||||
|
||||
/* Calculate abbreviation threshold, if any */
|
||||
count = ( size * sizeof ( element ) );
|
||||
threshold = count;
|
||||
if ( count >= ( ( sizeof ( buf ) - 1 /* NUL */ ) / 2 /* "xx" */ ) ) {
|
||||
threshold -= ( ( sizeof ( buf ) - 3 /* "..." */
|
||||
- ( BIGINT_NTOA_LSB_MIN * 2 /* "xx" */ )
|
||||
- 1 /* NUL */ ) / 2 /* "xx" */ );
|
||||
}
|
||||
|
||||
/* Transcribe bytes, abbreviating with "..." if necessary */
|
||||
for ( tmp = buf, i = ( count - 1 ) ; i >= 0 ; i-- ) {
|
||||
element = value->element[ i / sizeof ( element ) ];
|
||||
byte = ( element >> ( 8 * ( i % sizeof ( element ) ) ) );
|
||||
tmp += sprintf ( tmp, "%02x", byte );
|
||||
if ( i == threshold ) {
|
||||
tmp += sprintf ( tmp, "..." );
|
||||
i = BIGINT_NTOA_LSB_MIN;
|
||||
}
|
||||
}
|
||||
assert ( tmp < ( buf + sizeof ( buf ) ) );
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally swap big integers (in constant time)
|
||||
|
@ -133,148 +175,136 @@ void bigint_multiply_raw ( const bigint_element_t *multiplicand0,
|
|||
}
|
||||
|
||||
/**
|
||||
* Reduce big integer
|
||||
* Reduce big integer R^2 modulo N
|
||||
*
|
||||
* @v modulus0 Element 0 of big integer modulus
|
||||
* @v value0 Element 0 of big integer to be reduced
|
||||
* @v size Number of elements in modulus and value
|
||||
* @v result0 Element 0 of big integer to hold result
|
||||
* @v size Number of elements in modulus and result
|
||||
*
|
||||
* Reduce the value R^2 modulo N, where R=2^n and n is the number of
|
||||
* bits in the representation of the modulus N, including any leading
|
||||
* zero bits.
|
||||
*/
|
||||
void bigint_reduce_raw ( bigint_element_t *modulus0, bigint_element_t *value0,
|
||||
unsigned int size ) {
|
||||
void bigint_reduce_raw ( const bigint_element_t *modulus0,
|
||||
bigint_element_t *result0, unsigned int size ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*modulus = ( ( const void * ) modulus0 );
|
||||
bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*modulus = ( ( void * ) modulus0 );
|
||||
bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*value = ( ( void * ) value0 );
|
||||
*result = ( ( void * ) result0 );
|
||||
const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
|
||||
bigint_element_t *element;
|
||||
unsigned int modulus_max;
|
||||
unsigned int value_max;
|
||||
unsigned int subshift;
|
||||
int offset;
|
||||
int shift;
|
||||
unsigned int shift;
|
||||
int max;
|
||||
int sign;
|
||||
int msb;
|
||||
int i;
|
||||
int carry;
|
||||
|
||||
/* Start profiling */
|
||||
profile_start ( &bigint_mod_profiler );
|
||||
|
||||
/* Normalise the modulus
|
||||
/* We have the constants:
|
||||
*
|
||||
* Scale the modulus by shifting left such that both modulus
|
||||
* "m" and value "x" have the same most significant set bit.
|
||||
* (If this is not possible, then the value is already less
|
||||
* than the modulus, and we may therefore skip reduction
|
||||
* completely.)
|
||||
* N = modulus
|
||||
*
|
||||
* n = number of bits in the modulus (including any leading zeros)
|
||||
*
|
||||
* R = 2^n
|
||||
*
|
||||
* Let r be the extension of the n-bit result register by a
|
||||
* separate two's complement sign bit, such that -R <= r < R,
|
||||
* and define:
|
||||
*
|
||||
* x = r * 2^k
|
||||
*
|
||||
* as the value being reduced modulo N, where k is a
|
||||
* non-negative integer bit shift.
|
||||
*
|
||||
* We want to reduce the initial value R^2=2^(2n), which we
|
||||
* may trivially represent using r=1 and k=2n.
|
||||
*
|
||||
* We then iterate over decrementing k, maintaining the loop
|
||||
* invariant:
|
||||
*
|
||||
* -N <= r < N
|
||||
*
|
||||
* On each iteration we must first double r, to compensate for
|
||||
* having decremented k:
|
||||
*
|
||||
* k' = k - 1
|
||||
*
|
||||
* r' = 2r
|
||||
*
|
||||
* x = r * 2^k = 2r * 2^(k-1) = r' * 2^k'
|
||||
*
|
||||
* Note that doubling the n-bit result register will create a
|
||||
* value of n+1 bits: this extra bit needs to be handled
|
||||
* separately during the calculation.
|
||||
*
|
||||
* We then subtract N (if r is currently non-negative) or add
|
||||
* N (if r is currently negative) to restore the loop
|
||||
* invariant:
|
||||
*
|
||||
* 0 <= r < N => r" = 2r - N => -N <= r" < N
|
||||
* -N <= r < 0 => r" = 2r + N => -N <= r" < N
|
||||
*
|
||||
* Note that since N may use all n bits, the most significant
|
||||
* bit of the n-bit result register is not a valid two's
|
||||
* complement sign bit for r: the extra sign bit therefore
|
||||
* also needs to be handled separately.
|
||||
*
|
||||
* Once we reach k=0, we have x=r and therefore:
|
||||
*
|
||||
* -N <= x < N
|
||||
*
|
||||
* After this last loop iteration (with k=0), we may need to
|
||||
* add a single multiple of N to ensure that x is positive,
|
||||
* i.e. lies within the range 0 <= x < N.
|
||||
*
|
||||
* Since neither the modulus nor the value R^2 are secret, we
|
||||
* may elide approximately half of the total number of
|
||||
* iterations by constructing the initial representation of
|
||||
* R^2 as r=2^m and k=2n-m (for some m such that 2^m < N).
|
||||
*/
|
||||
value_max = bigint_max_set_bit ( value );
|
||||
modulus_max = bigint_max_set_bit ( modulus );
|
||||
shift = ( value_max - modulus_max );
|
||||
if ( shift < 0 )
|
||||
goto skip;
|
||||
subshift = ( shift & ( width - 1 ) );
|
||||
offset = ( shift / width );
|
||||
element = modulus->element;
|
||||
for ( i = ( ( value_max - 1 ) / width ) ; ; i-- ) {
|
||||
element[i] = ( element[ i - offset ] << subshift );
|
||||
if ( i <= offset )
|
||||
break;
|
||||
if ( subshift ) {
|
||||
element[i] |= ( element[ i - offset - 1 ]
|
||||
>> ( width - subshift ) );
|
||||
}
|
||||
|
||||
/* Initialise x=R^2 */
|
||||
memset ( result, 0, sizeof ( *result ) );
|
||||
max = ( bigint_max_set_bit ( modulus ) - 2 );
|
||||
if ( max < 0 ) {
|
||||
/* Degenerate case of N=0 or N=1: return a zero result */
|
||||
return;
|
||||
}
|
||||
for ( i-- ; i >= 0 ; i-- )
|
||||
element[i] = 0;
|
||||
bigint_set_bit ( result, max );
|
||||
shift = ( ( 2 * size * width ) - max );
|
||||
sign = 0;
|
||||
|
||||
/* Reduce the value "x" by iteratively adding or subtracting
|
||||
* the scaled modulus "m".
|
||||
*
|
||||
* On each loop iteration, we maintain the invariant:
|
||||
*
|
||||
* -2m <= x < 2m
|
||||
*
|
||||
* If x is positive, we obtain the new value x' by
|
||||
* subtracting m, otherwise we add m:
|
||||
*
|
||||
* 0 <= x < 2m => x' := x - m => -m <= x' < m
|
||||
* -2m <= x < 0 => x' := x + m => -m <= x' < m
|
||||
*
|
||||
* and then halve the modulus (by shifting right):
|
||||
*
|
||||
* m' = m/2
|
||||
*
|
||||
* We therefore end up with:
|
||||
*
|
||||
* -m <= x' < m => -2m' <= x' < 2m'
|
||||
*
|
||||
* i.e. we have preseved the invariant while reducing the
|
||||
* bounds on x' by one power of two.
|
||||
*
|
||||
* The issue remains of how to determine on each iteration
|
||||
* whether or not x is currently positive, given that both
|
||||
* input values are unsigned big integers that may use all
|
||||
* available bits (including the MSB).
|
||||
*
|
||||
* On the first loop iteration, we may simply assume that x is
|
||||
* positive, since it is unmodified from the input value and
|
||||
* so is positive by definition (even if the MSB is set). We
|
||||
* therefore unconditionally perform a subtraction on the
|
||||
* first loop iteration.
|
||||
*
|
||||
* Let k be the MSB after normalisation. We then have:
|
||||
*
|
||||
* 2^k <= m < 2^(k+1)
|
||||
* 2^k <= x < 2^(k+1)
|
||||
*
|
||||
* On the first loop iteration, we therefore have:
|
||||
*
|
||||
* x' = (x - m)
|
||||
* < 2^(k+1) - 2^k
|
||||
* < 2^k
|
||||
*
|
||||
* Any positive value of x' therefore has its MSB set to zero,
|
||||
* and so we may validly treat the MSB of x' as a sign bit at
|
||||
* the end of the first loop iteration.
|
||||
*
|
||||
* On all subsequent loop iterations, the starting value m is
|
||||
* guaranteed to have its MSB set to zero (since it has
|
||||
* already been shifted right at least once). Since we know
|
||||
* from above that we preserve the loop invariant:
|
||||
*
|
||||
* -m <= x' < m
|
||||
*
|
||||
* we immediately know that any positive value of x' also has
|
||||
* its MSB set to zero, and so we may validly treat the MSB of
|
||||
* x' as a sign bit at the end of all subsequent loop
|
||||
* iterations.
|
||||
*
|
||||
* After the last loop iteration (when m' has been shifted
|
||||
* back down to the original value of the modulus), we may
|
||||
* need to add a single multiple of m' to ensure that x' is
|
||||
* positive, i.e. lies within the range 0 <= x' < m'. To
|
||||
* allow for reusing the (inlined) expansion of
|
||||
* bigint_subtract(), we achieve this via a potential
|
||||
* additional loop iteration that performs the addition and is
|
||||
* then guaranteed to terminate (since the result will be
|
||||
* positive).
|
||||
*/
|
||||
for ( msb = 0 ; ( msb || ( shift >= 0 ) ) ; shift-- ) {
|
||||
if ( msb ) {
|
||||
bigint_add ( modulus, value );
|
||||
/* Iterate as described above */
|
||||
while ( shift-- ) {
|
||||
|
||||
/* Calculate 2r, storing extra bit separately */
|
||||
msb = bigint_shl ( result );
|
||||
|
||||
/* Add or subtract N according to current sign */
|
||||
if ( sign ) {
|
||||
carry = bigint_add ( modulus, result );
|
||||
} else {
|
||||
bigint_subtract ( modulus, value );
|
||||
carry = bigint_subtract ( modulus, result );
|
||||
}
|
||||
msb = bigint_msb_is_set ( value );
|
||||
if ( shift > 0 )
|
||||
bigint_shr ( modulus );
|
||||
|
||||
/* Calculate new sign of result
|
||||
*
|
||||
* We know the result lies in the range -N <= r < N
|
||||
* and so the tuple (old sign, msb, carry) cannot ever
|
||||
* take the values (0, 1, 0) or (1, 0, 0). We can
|
||||
* therefore treat these as don't-care inputs, which
|
||||
* allows us to simplify the boolean expression by
|
||||
* ignoring the old sign completely.
|
||||
*/
|
||||
assert ( ( sign == msb ) || carry );
|
||||
sign = ( msb ^ carry );
|
||||
}
|
||||
|
||||
skip:
|
||||
/* Sanity check */
|
||||
assert ( ! bigint_is_geq ( value, modulus ) );
|
||||
/* Add N to make result positive if necessary */
|
||||
if ( sign )
|
||||
bigint_add ( modulus, result );
|
||||
|
||||
/* Stop profiling */
|
||||
profile_stop ( &bigint_mod_profiler );
|
||||
/* Sanity check */
|
||||
assert ( ! bigint_is_geq ( result, modulus ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -351,82 +381,362 @@ void bigint_mod_invert_raw ( const bigint_element_t *invertend0,
|
|||
}
|
||||
|
||||
/**
|
||||
* Perform Montgomery reduction (REDC) of a big integer product
|
||||
* Perform relaxed Montgomery reduction (REDC) of a big integer
|
||||
*
|
||||
* @v modulus0 Element 0 of big integer modulus
|
||||
* @v modinv0 Element 0 of the inverse of the modulus modulo 2^k
|
||||
* @v mont0 Element 0 of big integer Montgomery product
|
||||
* @v modulus0 Element 0 of big integer odd modulus
|
||||
* @v value0 Element 0 of big integer to be reduced
|
||||
* @v result0 Element 0 of big integer to hold result
|
||||
* @v size Number of elements in modulus and result
|
||||
* @ret carry Carry out
|
||||
*
|
||||
* Note that only the least significant element of the inverse modulo
|
||||
* 2^k is required, and that the Montgomery product will be
|
||||
* overwritten.
|
||||
* The value to be reduced will be made divisible by the size of the
|
||||
* modulus while retaining its residue class (i.e. multiples of the
|
||||
* modulus will be added until the low half of the value is zero).
|
||||
*
|
||||
* The result may be expressed as
|
||||
*
|
||||
* tR = x + mN
|
||||
*
|
||||
* where x is the input value, N is the modulus, R=2^n (where n is the
|
||||
* number of bits in the representation of the modulus, including any
|
||||
* leading zero bits), and m is the number of multiples of the modulus
|
||||
* added to make the result tR divisible by R.
|
||||
*
|
||||
* The maximum addend is mN <= (R-1)*N (and such an m can be proven to
|
||||
* exist since N is limited to being odd and therefore coprime to R).
|
||||
*
|
||||
* Since the result of this addition is one bit larger than the input
|
||||
* value, a carry out bit is also returned. The caller may be able to
|
||||
* prove that the carry out is always zero, in which case it may be
|
||||
* safely ignored.
|
||||
*
|
||||
* The upper half of the output value (i.e. t) will also be copied to
|
||||
* the result pointer. It is permissible for the result pointer to
|
||||
* overlap the lower half of the input value.
|
||||
*
|
||||
* External knowledge of constraints on the modulus and the input
|
||||
* value may be used to prove constraints on the result. The
|
||||
* constraint on the modulus may be generally expressed as
|
||||
*
|
||||
* R > kN
|
||||
*
|
||||
* for some positive integer k. The value k=1 is allowed, and simply
|
||||
* expresses that the modulus fits within the number of bits in its
|
||||
* own representation.
|
||||
*
|
||||
* For classic Montgomery reduction, we have k=1, i.e. R > N and a
|
||||
* separate constraint that the input value is in the range x < RN.
|
||||
* This gives the result constraint
|
||||
*
|
||||
* tR < RN + (R-1)N
|
||||
* < 2RN - N
|
||||
* < 2RN
|
||||
* t < 2N
|
||||
*
|
||||
* A single subtraction of the modulus may therefore be required to
|
||||
* bring it into the range t < N.
|
||||
*
|
||||
* When the input value is known to be a product of two integers A and
|
||||
* B, with A < aN and B < bN, we get the result constraint
|
||||
*
|
||||
* tR < abN^2 + (R-1)N
|
||||
* < (ab/k)RN + RN - N
|
||||
* < (1 + ab/k)RN
|
||||
* t < (1 + ab/k)N
|
||||
*
|
||||
* If we have k=a=b=1, i.e. R > N with A < N and B < N, then the
|
||||
* result is in the range t < 2N and may require a single subtraction
|
||||
* of the modulus to bring it into the range t < N so that it may be
|
||||
* used as an input on a subsequent iteration.
|
||||
*
|
||||
* If we have k=4 and a=b=2, i.e. R > 4N with A < 2N and B < 2N, then
|
||||
* the result is in the range t < 2N and may immediately be used as an
|
||||
* input on a subsequent iteration, without requiring a subtraction.
|
||||
*
|
||||
* Larger values of k may be used to allow for larger values of a and
|
||||
* b, which can be useful to elide intermediate reductions in a
|
||||
* calculation chain that involves additions and subtractions between
|
||||
* multiplications (as used in elliptic curve point addition, for
|
||||
* example). As a general rule: each intermediate addition or
|
||||
* subtraction will require k to be doubled.
|
||||
*
|
||||
* When the input value is known to be a single integer A, with A < aN
|
||||
* (as used when converting out of Montgomery form), we get the result
|
||||
* constraint
|
||||
*
|
||||
* tR < aN + (R-1)N
|
||||
* < RN + (a-1)N
|
||||
*
|
||||
* If we have a=1, i.e. A < N, then the constraint becomes
|
||||
*
|
||||
* tR < RN
|
||||
* t < N
|
||||
*
|
||||
* and so the result is immediately in the range t < N with no
|
||||
* subtraction of the modulus required.
|
||||
*
|
||||
* For any larger value of a, the result value t=N becomes possible.
|
||||
* Additional external knowledge may potentially be used to prove that
|
||||
* t=N cannot occur. For example: if the caller is performing modular
|
||||
* exponentiation with a prime modulus (or, more generally, a modulus
|
||||
* that is coprime to the base), then there is no way for a non-zero
|
||||
* base value to end up producing an exact multiple of the modulus.
|
||||
* If t=N cannot be disproved, then conversion out of Montgomery form
|
||||
* may require an additional subtraction of the modulus.
|
||||
*/
|
||||
void bigint_montgomery_raw ( const bigint_element_t *modulus0,
|
||||
const bigint_element_t *modinv0,
|
||||
bigint_element_t *mont0,
|
||||
bigint_element_t *result0, unsigned int size ) {
|
||||
int bigint_montgomery_relaxed_raw ( const bigint_element_t *modulus0,
|
||||
bigint_element_t *value0,
|
||||
bigint_element_t *result0,
|
||||
unsigned int size ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*modulus = ( ( const void * ) modulus0 );
|
||||
const bigint_t ( 1 ) __attribute__ (( may_alias ))
|
||||
*modinv = ( ( const void * ) modinv0 );
|
||||
union {
|
||||
bigint_t ( size * 2 ) full;
|
||||
struct {
|
||||
bigint_t ( size ) low;
|
||||
bigint_t ( size ) high;
|
||||
} __attribute__ (( packed ));
|
||||
} __attribute__ (( may_alias )) *mont = ( ( void * ) mont0 );
|
||||
} __attribute__ (( may_alias )) *value = ( ( void * ) value0 );
|
||||
bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
bigint_element_t negmodinv = -modinv->element[0];
|
||||
static bigint_t ( 1 ) cached;
|
||||
static bigint_t ( 1 ) negmodinv;
|
||||
bigint_element_t multiple;
|
||||
bigint_element_t carry;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
int overflow;
|
||||
int underflow;
|
||||
|
||||
/* Sanity checks */
|
||||
assert ( bigint_bit_is_set ( modulus, 0 ) );
|
||||
|
||||
/* Calculate inverse (or use cached version) */
|
||||
if ( cached.element[0] != modulus->element[0] ) {
|
||||
bigint_mod_invert ( modulus, &negmodinv );
|
||||
negmodinv.element[0] = -negmodinv.element[0];
|
||||
cached.element[0] = modulus->element[0];
|
||||
}
|
||||
|
||||
/* Perform multiprecision Montgomery reduction */
|
||||
for ( i = 0 ; i < size ; i++ ) {
|
||||
|
||||
/* Determine scalar multiple for this round */
|
||||
multiple = ( mont->low.element[i] * negmodinv );
|
||||
multiple = ( value->low.element[i] * negmodinv.element[0] );
|
||||
|
||||
/* Multiply value to make it divisible by 2^(width*i) */
|
||||
carry = 0;
|
||||
for ( j = 0 ; j < size ; j++ ) {
|
||||
bigint_multiply_one ( multiple, modulus->element[j],
|
||||
&mont->full.element[ i + j ],
|
||||
&value->full.element[ i + j ],
|
||||
&carry );
|
||||
}
|
||||
|
||||
/* Since value is now divisible by 2^(width*i), we
|
||||
* know that the current low element must have been
|
||||
* zeroed. We can store the multiplication carry out
|
||||
* in this element, avoiding the need to immediately
|
||||
* propagate the carry through the remaining elements.
|
||||
* zeroed.
|
||||
*/
|
||||
assert ( mont->low.element[i] == 0 );
|
||||
mont->low.element[i] = carry;
|
||||
assert ( value->low.element[i] == 0 );
|
||||
|
||||
/* Store the multiplication carry out in the result,
|
||||
* avoiding the need to immediately propagate the
|
||||
* carry through the remaining elements.
|
||||
*/
|
||||
result->element[i] = carry;
|
||||
}
|
||||
|
||||
/* Add the accumulated carries */
|
||||
overflow = bigint_add ( &mont->low, &mont->high );
|
||||
overflow = bigint_add ( result, &value->high );
|
||||
|
||||
/* Copy to result buffer */
|
||||
bigint_copy ( &value->high, result );
|
||||
|
||||
return overflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform classic Montgomery reduction (REDC) of a big integer
|
||||
*
|
||||
* @v modulus0 Element 0 of big integer odd modulus
|
||||
* @v value0 Element 0 of big integer to be reduced
|
||||
* @v result0 Element 0 of big integer to hold result
|
||||
* @v size Number of elements in modulus and result
|
||||
*/
|
||||
void bigint_montgomery_raw ( const bigint_element_t *modulus0,
|
||||
bigint_element_t *value0,
|
||||
bigint_element_t *result0,
|
||||
unsigned int size ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*modulus = ( ( const void * ) modulus0 );
|
||||
union {
|
||||
bigint_t ( size * 2 ) full;
|
||||
struct {
|
||||
bigint_t ( size ) low;
|
||||
bigint_t ( size ) high;
|
||||
} __attribute__ (( packed ));
|
||||
} __attribute__ (( may_alias )) *value = ( ( void * ) value0 );
|
||||
bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
int overflow;
|
||||
int underflow;
|
||||
|
||||
/* Sanity check */
|
||||
assert ( ! bigint_is_geq ( &value->high, modulus ) );
|
||||
|
||||
/* Perform relaxed Montgomery reduction */
|
||||
overflow = bigint_montgomery_relaxed ( modulus, &value->full, result );
|
||||
|
||||
/* Conditionally subtract the modulus once */
|
||||
memcpy ( result, &mont->high, sizeof ( *result ) );
|
||||
underflow = bigint_subtract ( modulus, result );
|
||||
bigint_swap ( result, &mont->high, ( underflow & ~overflow ) );
|
||||
bigint_swap ( result, &value->high, ( underflow & ~overflow ) );
|
||||
|
||||
/* Sanity check */
|
||||
assert ( ! bigint_is_geq ( result, modulus ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform generalised exponentiation via a Montgomery ladder
|
||||
*
|
||||
* @v result0 Element 0 of result (initialised to identity element)
|
||||
* @v multiple0 Element 0 of multiple (initialised to generator)
|
||||
* @v size Number of elements in result and multiple
|
||||
* @v exponent0 Element 0 of exponent
|
||||
* @v exponent_size Number of elements in exponent
|
||||
* @v op Montgomery ladder commutative operation
|
||||
* @v ctx Operation context (if needed)
|
||||
* @v tmp Temporary working space (if needed)
|
||||
*
|
||||
* The Montgomery ladder may be used to perform any operation that is
|
||||
* isomorphic to exponentiation, i.e. to compute the result
|
||||
*
|
||||
* r = g^e = g * g * g * g * .... * g
|
||||
*
|
||||
* for an arbitrary commutative operation "*", generator "g" and
|
||||
* exponent "e".
|
||||
*
|
||||
* The result "r" is computed in constant time (assuming that the
|
||||
* underlying operation is constant time) in k steps, where k is the
|
||||
* number of bits in the big integer representation of the exponent.
|
||||
*
|
||||
* The result "r" must be initialised to the operation's identity
|
||||
* element, and the multiple must be initialised to the generator "g".
|
||||
* On exit, the multiple will contain
|
||||
*
|
||||
* m = r * g = g^(e+1)
|
||||
*
|
||||
* Note that the terminology used here refers to exponentiation
|
||||
* defined as repeated multiplication, but that the ladder may equally
|
||||
* well be used to perform any isomorphic operation (such as
|
||||
* multiplication defined as repeated addition).
|
||||
*/
|
||||
void bigint_ladder_raw ( bigint_element_t *result0,
|
||||
bigint_element_t *multiple0, unsigned int size,
|
||||
const bigint_element_t *exponent0,
|
||||
unsigned int exponent_size, bigint_ladder_op_t *op,
|
||||
const void *ctx, void *tmp ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*multiple = ( ( void * ) multiple0 );
|
||||
const bigint_t ( exponent_size ) __attribute__ (( may_alias ))
|
||||
*exponent = ( ( const void * ) exponent0 );
|
||||
const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
|
||||
unsigned int bit = ( exponent_size * width );
|
||||
int toggle = 0;
|
||||
int previous;
|
||||
|
||||
/* We have two physical storage locations: Rres (the "result"
|
||||
* register) and Rmul (the "multiple" register).
|
||||
*
|
||||
* On entry we have:
|
||||
*
|
||||
* Rres = g^0 = 1 (the identity element)
|
||||
* Rmul = g (the generator)
|
||||
*
|
||||
* For calculation purposes, define two virtual registers R[0]
|
||||
* and R[1], mapped to the underlying physical storage
|
||||
* locations via a boolean toggle state "t":
|
||||
*
|
||||
* R[t] -> Rres
|
||||
* R[~t] -> Rmul
|
||||
*
|
||||
* Define the initial toggle state to be t=0, so that we have:
|
||||
*
|
||||
* R[0] = g^0 = 1 (the identity element)
|
||||
* R[1] = g (the generator)
|
||||
*
|
||||
* The Montgomery ladder then iterates over each bit "b" of
|
||||
* the exponent "e" (from MSB down to LSB), computing:
|
||||
*
|
||||
* R[1] := R[0] * R[1], R[0] := R[0] * R[0] (if b=0)
|
||||
* R[0] := R[1] * R[0], R[1] := R[1] * R[1] (if b=1)
|
||||
*
|
||||
* i.e.
|
||||
*
|
||||
* R[~b] := R[b] * R[~b], R[b] := R[b] * R[b]
|
||||
*
|
||||
* To avoid data-dependent memory access patterns, we
|
||||
* implement this as:
|
||||
*
|
||||
* Rmul := Rres * Rmul
|
||||
* Rres := Rres * Rres
|
||||
*
|
||||
* and update the toggle state "t" (via constant-time
|
||||
* conditional swaps) as needed to ensure that R[b] always
|
||||
* maps to Rres and R[~b] always maps to Rmul.
|
||||
*/
|
||||
while ( bit-- ) {
|
||||
|
||||
/* Update toggle state t := b
|
||||
*
|
||||
* If the new toggle state is not equal to the old
|
||||
* toggle state, then we must swap R[0] and R[1] (in
|
||||
* constant time).
|
||||
*/
|
||||
previous = toggle;
|
||||
toggle = bigint_bit_is_set ( exponent, bit );
|
||||
bigint_swap ( result, multiple, ( toggle ^ previous ) );
|
||||
|
||||
/* Calculate Rmul = R[~b] := R[b] * R[~b] = Rres * Rmul */
|
||||
op ( result->element, multiple->element, size, ctx, tmp );
|
||||
|
||||
/* Calculate Rres = R[b] := R[b] * R[b] = Rres * Rres */
|
||||
op ( result->element, result->element, size, ctx, tmp );
|
||||
}
|
||||
|
||||
/* Reset toggle state to zero */
|
||||
bigint_swap ( result, multiple, toggle );
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform modular multiplication as part of a Montgomery ladder
|
||||
*
|
||||
* @v operand Element 0 of first input operand (may overlap result)
|
||||
* @v result Element 0 of second input operand and result
|
||||
* @v size Number of elements in operands and result
|
||||
* @v ctx Operation context (odd modulus, or NULL)
|
||||
* @v tmp Temporary working space
|
||||
*/
|
||||
void bigint_mod_exp_ladder ( const bigint_element_t *multiplier0,
|
||||
bigint_element_t *result0, unsigned int size,
|
||||
const void *ctx, void *tmp ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*multiplier = ( ( const void * ) multiplier0 );
|
||||
bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*modulus = ( ( const void * ) ctx );
|
||||
bigint_t ( size * 2 ) __attribute__ (( may_alias ))
|
||||
*product = ( ( void * ) tmp );
|
||||
|
||||
/* Multiply and reduce */
|
||||
bigint_multiply ( result, multiplier, product );
|
||||
if ( modulus ) {
|
||||
bigint_montgomery ( modulus, product, result );
|
||||
} else {
|
||||
bigint_shrink ( product, result );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform modular exponentiation of big integers
|
||||
*
|
||||
|
@ -454,12 +764,9 @@ void bigint_mod_exp_raw ( const bigint_element_t *base0,
|
|||
( ( void * ) result0 );
|
||||
const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
|
||||
struct {
|
||||
union {
|
||||
bigint_t ( 2 * size ) padded_modulus;
|
||||
struct {
|
||||
bigint_t ( size ) modulus;
|
||||
bigint_t ( size ) stash;
|
||||
};
|
||||
struct {
|
||||
bigint_t ( size ) modulus;
|
||||
bigint_t ( size ) stash;
|
||||
};
|
||||
union {
|
||||
bigint_t ( 2 * size ) full;
|
||||
|
@ -467,12 +774,10 @@ void bigint_mod_exp_raw ( const bigint_element_t *base0,
|
|||
} product;
|
||||
} *temp = tmp;
|
||||
const uint8_t one[1] = { 1 };
|
||||
bigint_t ( 1 ) modinv;
|
||||
bigint_element_t submask;
|
||||
unsigned int subsize;
|
||||
unsigned int scale;
|
||||
unsigned int max;
|
||||
unsigned int bit;
|
||||
unsigned int i;
|
||||
|
||||
/* Sanity check */
|
||||
assert ( sizeof ( *temp ) == bigint_mod_exp_tmp_len ( modulus ) );
|
||||
|
@ -484,7 +789,7 @@ void bigint_mod_exp_raw ( const bigint_element_t *base0,
|
|||
}
|
||||
|
||||
/* Factor modulus as (N * 2^scale) where N is odd */
|
||||
bigint_grow ( modulus, &temp->padded_modulus );
|
||||
bigint_copy ( modulus, &temp->modulus );
|
||||
for ( scale = 0 ; ( ! bigint_bit_is_set ( &temp->modulus, 0 ) ) ;
|
||||
scale++ ) {
|
||||
bigint_shr ( &temp->modulus );
|
||||
|
@ -494,47 +799,26 @@ void bigint_mod_exp_raw ( const bigint_element_t *base0,
|
|||
if ( ! submask )
|
||||
submask = ~submask;
|
||||
|
||||
/* Calculate inverse of (scaled) modulus N modulo element size */
|
||||
bigint_mod_invert ( &temp->modulus, &modinv );
|
||||
|
||||
/* Calculate (R^2 mod N) via direct reduction of (R^2 - N) */
|
||||
memset ( &temp->product.full, 0, sizeof ( temp->product.full ) );
|
||||
bigint_subtract ( &temp->padded_modulus, &temp->product.full );
|
||||
bigint_reduce ( &temp->padded_modulus, &temp->product.full );
|
||||
bigint_copy ( &temp->product.low, &temp->stash );
|
||||
/* Calculate (R^2 mod N) */
|
||||
bigint_reduce ( &temp->modulus, &temp->stash );
|
||||
|
||||
/* Initialise result = Montgomery(1, R^2 mod N) */
|
||||
bigint_montgomery ( &temp->modulus, &modinv,
|
||||
&temp->product.full, result );
|
||||
bigint_grow ( &temp->stash, &temp->product.full );
|
||||
bigint_montgomery ( &temp->modulus, &temp->product.full, result );
|
||||
|
||||
/* Convert base into Montgomery form */
|
||||
bigint_multiply ( base, &temp->stash, &temp->product.full );
|
||||
bigint_montgomery ( &temp->modulus, &modinv, &temp->product.full,
|
||||
bigint_montgomery ( &temp->modulus, &temp->product.full,
|
||||
&temp->stash );
|
||||
|
||||
/* Calculate x1 = base^exponent modulo N */
|
||||
max = bigint_max_set_bit ( exponent );
|
||||
for ( bit = 1 ; bit <= max ; bit++ ) {
|
||||
|
||||
/* Square (and reduce) */
|
||||
bigint_multiply ( result, result, &temp->product.full );
|
||||
bigint_montgomery ( &temp->modulus, &modinv,
|
||||
&temp->product.full, result );
|
||||
|
||||
/* Multiply (and reduce) */
|
||||
bigint_multiply ( &temp->stash, result, &temp->product.full );
|
||||
bigint_montgomery ( &temp->modulus, &modinv,
|
||||
&temp->product.full, &temp->product.low );
|
||||
|
||||
/* Conditionally swap the multiplied result */
|
||||
bigint_swap ( result, &temp->product.low,
|
||||
bigint_bit_is_set ( exponent, ( max - bit ) ) );
|
||||
}
|
||||
bigint_ladder ( result, &temp->stash, exponent, bigint_mod_exp_ladder,
|
||||
&temp->modulus, &temp->product );
|
||||
|
||||
/* Convert back out of Montgomery form */
|
||||
bigint_grow ( result, &temp->product.full );
|
||||
bigint_montgomery ( &temp->modulus, &modinv, &temp->product.full,
|
||||
result );
|
||||
bigint_montgomery_relaxed ( &temp->modulus, &temp->product.full,
|
||||
result );
|
||||
|
||||
/* Handle even moduli via Garner's algorithm */
|
||||
if ( subsize ) {
|
||||
|
@ -554,22 +838,14 @@ void bigint_mod_exp_raw ( const bigint_element_t *base0,
|
|||
|
||||
/* Calculate x2 = base^exponent modulo 2^k */
|
||||
bigint_init ( substash, one, sizeof ( one ) );
|
||||
for ( bit = 1 ; bit <= max ; bit++ ) {
|
||||
bigint_copy ( subbase, submodulus );
|
||||
bigint_ladder ( substash, submodulus, exponent,
|
||||
bigint_mod_exp_ladder, NULL, subproduct );
|
||||
|
||||
/* Square (and reduce) */
|
||||
bigint_multiply ( substash, substash,
|
||||
&subproduct->full );
|
||||
bigint_copy ( &subproduct->low, substash );
|
||||
|
||||
/* Multiply (and reduce) */
|
||||
bigint_multiply ( subbase, substash,
|
||||
&subproduct->full );
|
||||
|
||||
/* Conditionally swap the multiplied result */
|
||||
bigint_swap ( substash, &subproduct->low,
|
||||
bigint_bit_is_set ( exponent,
|
||||
( max - bit ) ) );
|
||||
}
|
||||
/* Reconstruct N */
|
||||
bigint_copy ( modulus, &temp->modulus );
|
||||
for ( i = 0 ; i < scale ; i++ )
|
||||
bigint_shr ( &temp->modulus );
|
||||
|
||||
/* Calculate N^-1 modulo 2^k */
|
||||
bigint_mod_invert ( submodulus, &subproduct->low );
|
||||
|
|
|
@ -266,3 +266,9 @@ static int certstore_apply_settings ( void ) {
|
|||
struct settings_applicator certstore_applicator __settings_applicator = {
|
||||
.apply = certstore_apply_settings,
|
||||
};
|
||||
|
||||
/* Drag in objects via certificate store */
|
||||
REQUIRING_SYMBOL ( certstore );
|
||||
|
||||
/* Drag in alternative certificate sources */
|
||||
REQUIRE_OBJECT ( config_certs );
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Elliptic Curve Ephemeral Diffie-Hellman (ECDHE) key exchange
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <ipxe/ecdhe.h>
|
||||
|
||||
/**
|
||||
* Calculate ECDHE key
|
||||
*
|
||||
* @v curve Elliptic curve
|
||||
* @v partner Partner public curve point
|
||||
* @v private Private key
|
||||
* @v public Public curve point to fill in (may overlap partner key)
|
||||
* @v shared Shared secret curve point to fill in
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ecdhe_key ( struct elliptic_curve *curve, const void *partner,
|
||||
const void *private, void *public, void *shared ) {
|
||||
int rc;
|
||||
|
||||
/* Construct shared key */
|
||||
if ( ( rc = elliptic_multiply ( curve, partner, private,
|
||||
shared ) ) != 0 ) {
|
||||
DBGC ( curve, "CURVE %s could not generate shared key: %s\n",
|
||||
curve->name, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Construct public key */
|
||||
if ( ( rc = elliptic_multiply ( curve, NULL, private,
|
||||
public ) ) != 0 ) {
|
||||
DBGC ( curve, "CURVE %s could not generate public key: %s\n",
|
||||
curve->name, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/p256.h>
|
||||
#include <ipxe/asn1.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** "prime256v1" object identifier */
|
||||
static uint8_t oid_prime256v1[] = { ASN1_OID_PRIME256V1 };
|
||||
|
||||
/** "prime256v1" OID-identified algorithm */
|
||||
struct asn1_algorithm prime256v1_algorithm __asn1_algorithm = {
|
||||
.name = "prime256v1",
|
||||
.curve = &p256_curve,
|
||||
.oid = ASN1_CURSOR ( oid_prime256v1 ),
|
||||
};
|
||||
|
||||
/** P-256 named curve */
|
||||
struct tls_named_curve tls_secp256r1_named_curve __tls_named_curve ( 01 ) = {
|
||||
.curve = &p256_curve,
|
||||
.code = htons ( TLS_NAMED_CURVE_SECP256R1 ),
|
||||
.format = TLS_POINT_FORMAT_UNCOMPRESSED,
|
||||
.pre_master_secret_len = P256_LEN,
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/p384.h>
|
||||
#include <ipxe/asn1.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** "secp384r1" object identifier */
|
||||
static uint8_t oid_secp384r1[] = { ASN1_OID_SECP384R1 };
|
||||
|
||||
/** "secp384r1" OID-identified algorithm */
|
||||
struct asn1_algorithm secp384r1_algorithm __asn1_algorithm = {
|
||||
.name = "secp384r1",
|
||||
.curve = &p384_curve,
|
||||
.oid = ASN1_CURSOR ( oid_secp384r1 ),
|
||||
};
|
||||
|
||||
/** P-384 named curve */
|
||||
struct tls_named_curve tls_secp384r1_named_curve __tls_named_curve ( 01 ) = {
|
||||
.curve = &p384_curve,
|
||||
.code = htons ( TLS_NAMED_CURVE_SECP384R1 ),
|
||||
.format = TLS_POINT_FORMAT_UNCOMPRESSED,
|
||||
.pre_master_secret_len = P384_LEN,
|
||||
};
|
|
@ -42,4 +42,5 @@ struct asn1_algorithm x25519_algorithm __asn1_algorithm = {
|
|||
struct tls_named_curve tls_x25519_named_curve __tls_named_curve ( 01 ) = {
|
||||
.curve = &x25519_curve,
|
||||
.code = htons ( TLS_NAMED_CURVE_X25519 ),
|
||||
.pre_master_secret_len = sizeof ( struct x25519_value ),
|
||||
};
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* NIST P-256 elliptic curve
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ipxe/p256.h>
|
||||
|
||||
/** P-256 field prime */
|
||||
static const uint8_t p256_prime[P256_LEN] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
/** P-256 constant "a" */
|
||||
static const uint8_t p256_a[P256_LEN] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc
|
||||
};
|
||||
|
||||
/** P-256 constant "b" */
|
||||
static const uint8_t p256_b[P256_LEN] = {
|
||||
0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
|
||||
0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
|
||||
0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
|
||||
};
|
||||
|
||||
/** P-256 base point */
|
||||
static const uint8_t p256_base[ P256_LEN * 2 ] = {
|
||||
0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
|
||||
0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
|
||||
0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f,
|
||||
0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
|
||||
0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e,
|
||||
0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
|
||||
};
|
||||
|
||||
/** P-256 elliptic curve */
|
||||
WEIERSTRASS_CURVE ( p256, p256_curve, P256_LEN,
|
||||
p256_prime, p256_a, p256_b, p256_base );
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* NIST P-384 elliptic curve
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ipxe/p384.h>
|
||||
|
||||
/** P-384 field prime */
|
||||
static const uint8_t p384_prime[P384_LEN] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
/** P-384 constant "a" */
|
||||
static const uint8_t p384_a[P384_LEN] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xfc
|
||||
};
|
||||
|
||||
/** P-384 constant "b" */
|
||||
static const uint8_t p384_b[P384_LEN] = {
|
||||
0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05,
|
||||
0x6b, 0xe3, 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81,
|
||||
0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a, 0xc6,
|
||||
0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed,
|
||||
0xd3, 0xec, 0x2a, 0xef
|
||||
};
|
||||
|
||||
/** P-384 base point */
|
||||
static const uint8_t p384_base[ P384_LEN * 2 ] = {
|
||||
0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7,
|
||||
0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7,
|
||||
0x9b, 0x98, 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55,
|
||||
0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e, 0x38,
|
||||
0x72, 0x76, 0x0a, 0xb7, 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c,
|
||||
0x6f, 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4,
|
||||
0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5,
|
||||
0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
|
||||
0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f
|
||||
};
|
||||
|
||||
/** P-384 elliptic curve */
|
||||
WEIERSTRASS_CURVE ( p384, p384_curve, P384_LEN,
|
||||
p384_prime, p384_a, p384_b, p384_base );
|
|
@ -75,6 +75,9 @@ static int rbg_startup ( void ) {
|
|||
int len;
|
||||
int rc;
|
||||
|
||||
/* Record that startup has been attempted (even if unsuccessful) */
|
||||
rbg.started = 1;
|
||||
|
||||
/* Try to obtain system UUID for use as personalisation
|
||||
* string, in accordance with ANS X9.82 Part 3-2007 Section
|
||||
* 8.5.2. If no UUID is available, proceed without a
|
||||
|
@ -97,6 +100,33 @@ static int rbg_startup ( void ) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate bits using RBG
|
||||
*
|
||||
* @v additional Additional input
|
||||
* @v additional_len Length of additional input
|
||||
* @v prediction_resist Prediction resistance is required
|
||||
* @v data Output buffer
|
||||
* @v len Length of output buffer
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This is the RBG_Generate function defined in ANS X9.82 Part 4
|
||||
* (April 2011 Draft) Section 9.1.2.2.
|
||||
*/
|
||||
int rbg_generate ( const void *additional, size_t additional_len,
|
||||
int prediction_resist, void *data, size_t len ) {
|
||||
|
||||
/* Attempt startup, if not already attempted */
|
||||
if ( ! rbg.started )
|
||||
rbg_startup();
|
||||
|
||||
/* Generate bits. The DRBG will itself return an error if it
|
||||
* is not valid (e.g. due to an instantiation failure).
|
||||
*/
|
||||
return drbg_generate ( &rbg.state, additional, additional_len,
|
||||
prediction_resist, data, len );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down RBG
|
||||
*
|
||||
|
@ -105,16 +135,21 @@ static void rbg_shutdown ( void ) {
|
|||
|
||||
/* Uninstantiate DRBG */
|
||||
drbg_uninstantiate ( &rbg.state );
|
||||
|
||||
/* Clear startup attempted flag */
|
||||
rbg.started = 0;
|
||||
}
|
||||
|
||||
/** RBG startup function */
|
||||
static void rbg_startup_fn ( void ) {
|
||||
|
||||
/* Start up RBG. There is no way to report an error at this
|
||||
* stage, but a failed startup will result in an invalid DRBG
|
||||
* that refuses to generate bits.
|
||||
/* Start up RBG (if not already started on demand). There is
|
||||
* no way to report an error at this stage, but a failed
|
||||
* startup will result in an invalid DRBG that refuses to
|
||||
* generate bits.
|
||||
*/
|
||||
rbg_startup();
|
||||
if ( ! rbg.started )
|
||||
rbg_startup();
|
||||
}
|
||||
|
||||
/** RBG shutdown function */
|
||||
|
|
|
@ -58,6 +58,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
0xed, 0x1a,
|
||||
#endif
|
||||
|
||||
/** Flag indicating if root of trust may be overridden at runtime */
|
||||
const int allow_trust_override = ALLOW_TRUST_OVERRIDE;
|
||||
|
||||
/** Root certificate fingerprints */
|
||||
static const uint8_t fingerprints[] = { TRUSTED };
|
||||
|
||||
|
|
|
@ -0,0 +1,866 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Weierstrass elliptic curves
|
||||
*
|
||||
* The implementation is based upon Algorithm 1 from "Complete
|
||||
* addition formulas for prime order elliptic curves" (Joost Renes,
|
||||
* Craig Costello, and Lejla Batina), available from
|
||||
*
|
||||
* https://www.microsoft.com/en-us/research/wp-content/uploads/2016/06/complete-2.pdf
|
||||
*
|
||||
* The steps within the algorithm have been reordered and temporary
|
||||
* variables shuffled to reduce stack usage, and calculations are
|
||||
* carried out modulo small multiples of the field prime in order to
|
||||
* elide reductions after intermediate addition and subtraction
|
||||
* operations.
|
||||
*
|
||||
* The algorithm is encoded using a bytecode representation, since
|
||||
* this substantially reduces the code size compared to direct
|
||||
* implementation of the big integer operations.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ipxe/weierstrass.h>
|
||||
|
||||
/** Big integer register names */
|
||||
enum weierstrass_register {
|
||||
|
||||
/*
|
||||
* Read-only registers
|
||||
*/
|
||||
|
||||
/* Curve constant "a" (for multiply), zero (for add/subtract) */
|
||||
WEIERSTRASS_a = 0,
|
||||
/* Curve constant "3b" */
|
||||
WEIERSTRASS_3b,
|
||||
/* Augend (x,y,z) co-ordinates */
|
||||
WEIERSTRASS_x1,
|
||||
WEIERSTRASS_y1,
|
||||
WEIERSTRASS_z1,
|
||||
/* Addend (x,y,z) co-ordinates */
|
||||
WEIERSTRASS_x2,
|
||||
WEIERSTRASS_y2,
|
||||
WEIERSTRASS_z2,
|
||||
|
||||
/*
|
||||
* Read-write registers
|
||||
*/
|
||||
|
||||
/* Temporary working registers */
|
||||
WEIERSTRASS_Wt,
|
||||
WEIERSTRASS_Wxy,
|
||||
WEIERSTRASS_Wyz,
|
||||
WEIERSTRASS_Wzx,
|
||||
/* Low half of multiplication product */
|
||||
WEIERSTRASS_Wp,
|
||||
/* Result (x,y,z) co-ordinates */
|
||||
WEIERSTRASS_x3,
|
||||
WEIERSTRASS_y3,
|
||||
WEIERSTRASS_z3,
|
||||
|
||||
/* Number of registers */
|
||||
WEIERSTRASS_NUM_REGISTERS = 16
|
||||
};
|
||||
|
||||
/** Zero register (for add/subtract operations */
|
||||
#define WEIERSTRASS_zero WEIERSTRASS_a
|
||||
|
||||
/** Construct big integer register index */
|
||||
#define WEIERSTRASS_REGISTER( name ) _C2 ( WEIERSTRASS_, name )
|
||||
|
||||
/** Bytecode operation codes */
|
||||
enum weierstrass_opcode {
|
||||
/** Subtract big integers (and add nothing)*/
|
||||
WEIERSTRASS_OP_SUB_0N = 0,
|
||||
/** Subtract big integers (and add 2N) */
|
||||
WEIERSTRASS_OP_SUB_2N = WEIERSTRASS_2N,
|
||||
/** Subtract big integers (and add 4N) */
|
||||
WEIERSTRASS_OP_SUB_4N = WEIERSTRASS_4N,
|
||||
/** Add big integers */
|
||||
WEIERSTRASS_OP_ADD,
|
||||
/** Multiply big integers (and perform Montgomery reduction) */
|
||||
WEIERSTRASS_OP_MUL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Define a bytecode operation
|
||||
*
|
||||
* @v opcode Operation code
|
||||
* @v dest Destination big integer register name
|
||||
* @v left Left source big integer register name
|
||||
* @v right Right source big integer register name
|
||||
*/
|
||||
#define WEIERSTRASS_OP( opcode, dest, left, right ) \
|
||||
( ( (opcode) << 12 ) | \
|
||||
( WEIERSTRASS_REGISTER ( dest ) << 8 ) | \
|
||||
( WEIERSTRASS_REGISTER ( left ) << 4 ) | \
|
||||
( WEIERSTRASS_REGISTER ( right ) << 0 ) )
|
||||
|
||||
/** Extract bytecode operation code */
|
||||
#define WEIERSTRASS_OPCODE( op ) ( ( (op) >> 12 ) & 0xf )
|
||||
|
||||
/** Extract destination big integer register */
|
||||
#define WEIERSTRASS_DEST( op ) ( ( (op) >> 8 ) & 0xf )
|
||||
|
||||
/** Extract left source big integer register */
|
||||
#define WEIERSTRASS_LEFT( op ) ( ( (op) >> 4 ) & 0xf )
|
||||
|
||||
/** Extract right source big integer register */
|
||||
#define WEIERSTRASS_RIGHT( op ) ( ( (op) >> 0 ) & 0xf )
|
||||
|
||||
/** Define a three-argument addition operation */
|
||||
#define WEIERSTRASS_ADD3( dest, augend, addend ) \
|
||||
WEIERSTRASS_OP ( WEIERSTRASS_OP_ADD, dest, augend, addend )
|
||||
|
||||
/** Define a two-argument addition operation */
|
||||
#define WEIERSTRASS_ADD2( augend, addend ) \
|
||||
WEIERSTRASS_ADD3 ( augend, augend, addend )
|
||||
|
||||
/** Define a move operation */
|
||||
#define WEIERSTRASS_MOV( dest, source ) \
|
||||
WEIERSTRASS_ADD3( dest, source, zero )
|
||||
|
||||
/** Define a three-argument subtraction operation */
|
||||
#define WEIERSTRASS_SUB3( dest, minuend, subtrahend, multiple ) \
|
||||
WEIERSTRASS_OP ( _C2 ( WEIERSTRASS_OP_SUB_, multiple ), \
|
||||
dest, minuend, subtrahend )
|
||||
|
||||
/** Define a two-argument subtraction operation */
|
||||
#define WEIERSTRASS_SUB2( minuend, subtrahend, multiple ) \
|
||||
WEIERSTRASS_SUB3 ( minuend, minuend, subtrahend, multiple )
|
||||
|
||||
/** Define a stop operation */
|
||||
#define WEIERSTRASS_STOP WEIERSTRASS_SUB2 ( zero, zero, 0N )
|
||||
|
||||
/** Define a three-argument multiplication operation */
|
||||
#define WEIERSTRASS_MUL3( dest, multiplicand, multiplier ) \
|
||||
WEIERSTRASS_OP ( WEIERSTRASS_OP_MUL, dest, multiplicand, multiplier )
|
||||
|
||||
/** Define a two-argument multiplication operation */
|
||||
#define WEIERSTRASS_MUL2( multiplicand, multiplier ) \
|
||||
WEIERSTRASS_MUL3 ( multiplicand, multiplicand, multiplier )
|
||||
|
||||
/**
|
||||
* Initialise curve
|
||||
*
|
||||
* @v curve Weierstrass curve
|
||||
*/
|
||||
static void weierstrass_init ( struct weierstrass_curve *curve ) {
|
||||
unsigned int size = curve->size;
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *prime =
|
||||
( ( void * ) curve->prime[0] );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
|
||||
( ( void * ) curve->fermat );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *square =
|
||||
( ( void * ) curve->square );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *one =
|
||||
( ( void * ) curve->one );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *a =
|
||||
( ( void * ) curve->a );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *b3 =
|
||||
( ( void * ) curve->b3 );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *mont =
|
||||
( ( void * ) curve->mont[0] );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *temp =
|
||||
( ( void * ) curve->prime[1] );
|
||||
bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
|
||||
( ( void * ) temp );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *two =
|
||||
( ( void * ) temp );
|
||||
static const uint8_t one_raw[] = { 1 };
|
||||
static const uint8_t two_raw[] = { 2 };
|
||||
size_t len = curve->len;
|
||||
unsigned int i;
|
||||
|
||||
/* Initialise field prime */
|
||||
bigint_init ( prime, curve->prime_raw, len );
|
||||
DBGC ( curve, "WEIERSTRASS %s N = %s\n",
|
||||
curve->name, bigint_ntoa ( prime ) );
|
||||
|
||||
/* Calculate Montgomery constant R^2 mod N */
|
||||
bigint_reduce ( prime, square );
|
||||
DBGC ( curve, "WEIERSTRASS %s R^2 = %s mod N\n",
|
||||
curve->name, bigint_ntoa ( square ) );
|
||||
|
||||
/* Calculate constant "3b" */
|
||||
bigint_init ( b3, curve->b_raw, len );
|
||||
DBGC ( curve, "WEIERSTRASS %s b = %s\n",
|
||||
curve->name, bigint_ntoa ( b3 ) );
|
||||
bigint_copy ( b3, a );
|
||||
bigint_add ( b3, b3 );
|
||||
bigint_add ( a, b3 );
|
||||
|
||||
/* Initialise "a" */
|
||||
bigint_init ( a, curve->a_raw, len );
|
||||
DBGC ( curve, "WEIERSTRASS %s a = %s\n",
|
||||
curve->name, bigint_ntoa ( a ) );
|
||||
|
||||
/* Initialise "1" */
|
||||
bigint_init ( one, one_raw, sizeof ( one_raw ) );
|
||||
|
||||
/* Convert relevant constants to Montgomery form
|
||||
*
|
||||
* We rely on the fact that the prime multiples have not yet
|
||||
* been calculated, and so can be used as a temporary buffer.
|
||||
*/
|
||||
for ( i = 0 ; i < WEIERSTRASS_NUM_MONT ; i++ ) {
|
||||
static const char *names[] = { " ", " a", "3b" };
|
||||
bigint_multiply ( &mont[i], square, product );
|
||||
bigint_montgomery ( prime, product, &mont[i] );
|
||||
DBGC ( curve, "WEIERSTRASS %s %sR = %s mod N\n",
|
||||
curve->name, names[i], bigint_ntoa ( &mont[i] ) );
|
||||
}
|
||||
|
||||
/* Calculate constant "N-2"
|
||||
*
|
||||
* We rely on the fact that the prime multiples have not yet
|
||||
* been calculated, and so can be used as a temporary buffer.
|
||||
*/
|
||||
bigint_copy ( prime, fermat );
|
||||
bigint_init ( two, two_raw, sizeof ( two_raw ) );
|
||||
bigint_subtract ( two, fermat );
|
||||
DBGC ( curve, "WEIERSTRASS %s N-2 = %s\n",
|
||||
curve->name, bigint_ntoa ( fermat ) );
|
||||
|
||||
/* Calculate multiples of field prime */
|
||||
for ( i = 1 ; i < WEIERSTRASS_NUM_MULTIPLES ; i++ ) {
|
||||
bigint_copy ( &prime[ i - 1 ], &prime[i] );
|
||||
bigint_add ( &prime[i], &prime[i] );
|
||||
DBGC ( curve, "WEIERSTRASS %s %dN = %s\n",
|
||||
curve->name, ( 1 << i ), bigint_ntoa ( &prime[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute bytecode instruction
|
||||
*
|
||||
* @v curve Weierstrass curve
|
||||
* @v regs Registers
|
||||
* @v size Big integer size
|
||||
* @v op Operation
|
||||
*/
|
||||
static void weierstrass_exec ( const struct weierstrass_curve *curve,
|
||||
void **regs, unsigned int size,
|
||||
unsigned int op ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*prime = ( ( const void * ) curve->prime[0] );
|
||||
bigint_t ( size * 2 ) __attribute__ (( may_alias ))
|
||||
*product = regs[WEIERSTRASS_Wp];
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *dest;
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *left;
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *right;
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *addend;
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *subtrahend;
|
||||
unsigned int op_code;
|
||||
unsigned int op_dest;
|
||||
unsigned int op_left;
|
||||
unsigned int op_right;
|
||||
|
||||
/* Decode instruction */
|
||||
op_code = WEIERSTRASS_OPCODE ( op );
|
||||
op_dest = WEIERSTRASS_DEST ( op );
|
||||
op_left = WEIERSTRASS_LEFT ( op );
|
||||
op_right = WEIERSTRASS_RIGHT ( op );
|
||||
dest = regs[op_dest];
|
||||
left = regs[op_left];
|
||||
right = regs[op_right];
|
||||
|
||||
/* Check destination is a writable register */
|
||||
assert ( op_dest >= WEIERSTRASS_Wt );
|
||||
|
||||
/* Handle multiplications */
|
||||
if ( op_code == WEIERSTRASS_OP_MUL ) {
|
||||
assert ( op_left != WEIERSTRASS_Wp );
|
||||
assert ( op_right != WEIERSTRASS_Wp );
|
||||
bigint_multiply ( left, right, product );
|
||||
bigint_montgomery_relaxed ( prime, product, dest );
|
||||
DBGCP ( curve, "WEIERSTRASS %s R%d := R%d x R%d = %s\n",
|
||||
curve->name, op_dest, op_left, op_right,
|
||||
bigint_ntoa ( dest ) );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy left source, if required */
|
||||
if ( op_dest != op_left )
|
||||
bigint_copy ( left, dest );
|
||||
|
||||
/* Do nothing more if addend/subtrahend is zero */
|
||||
if ( ! op_right ) {
|
||||
DBGCP ( curve, "WEIERSTRASS %s R%d := R%d = %s\n",
|
||||
curve->name, op_dest, op_left, bigint_ntoa ( dest ) );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Determine addend and subtrahend */
|
||||
addend = NULL;
|
||||
subtrahend = NULL;
|
||||
if ( op_code == WEIERSTRASS_OP_ADD ) {
|
||||
DBGCP ( curve, "WEIERSTRASS %s R%d := R%d + R%d = ",
|
||||
curve->name, op_dest, op_left, op_right );
|
||||
addend = ( ( const void * ) right );
|
||||
} else {
|
||||
subtrahend = ( ( const void * ) right );
|
||||
if ( op_code > WEIERSTRASS_OP_SUB_0N ) {
|
||||
DBGCP ( curve, "WEIERSTRASS %s R%d := R%d - R%d + "
|
||||
"%dN = ", curve->name, op_dest, op_left,
|
||||
op_right, ( 1 << op_code ) );
|
||||
addend = ( ( const void * ) curve->prime[op_code] );
|
||||
} else {
|
||||
DBGCP ( curve, "WEIERSTRASS %s R%d := R%d - R%d = ",
|
||||
curve->name, op_dest, op_left, op_right );
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform addition and subtraction */
|
||||
if ( addend )
|
||||
bigint_add ( addend, dest );
|
||||
if ( subtrahend )
|
||||
bigint_subtract ( subtrahend, dest );
|
||||
DBGCP ( curve, "%s\n", bigint_ntoa ( dest ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add points on curve
|
||||
*
|
||||
* @v curve Weierstrass curve
|
||||
* @v augend0 Element 0 of point (x1,y1,z1) to be added
|
||||
* @v addend0 Element 0 of point (x2,y2,z2) to be added
|
||||
* @v result0 Element 0 of point (x3,y3,z3) to hold result
|
||||
*
|
||||
* Points are represented in projective coordinates, with all values
|
||||
* in Montgomery form and in the range [0,4N) where N is the field
|
||||
* prime.
|
||||
*
|
||||
* The augend may have the same value as the addend (i.e. this routine
|
||||
* may be used to perform point doubling as well as point addition),
|
||||
* and either or both may be the point at infinity.
|
||||
*
|
||||
* The result may overlap either input, since the inputs are fully
|
||||
* consumed before the result is written.
|
||||
*/
|
||||
static void weierstrass_add_raw ( const struct weierstrass_curve *curve,
|
||||
const bigint_element_t *augend0,
|
||||
const bigint_element_t *addend0,
|
||||
bigint_element_t *result0 ) {
|
||||
unsigned int size = curve->size;
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*prime = ( ( const void * ) curve->prime[0] );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*a = ( ( const void * ) curve->a );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*b3 = ( ( const void * ) curve->b3 );
|
||||
const weierstrass_t ( size ) __attribute__ (( may_alias ))
|
||||
*augend = ( ( const void * ) augend0 );
|
||||
const weierstrass_t ( size ) __attribute__ (( may_alias ))
|
||||
*addend = ( ( const void * ) addend0 );
|
||||
weierstrass_t ( size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
struct {
|
||||
bigint_t ( size ) Wt;
|
||||
bigint_t ( size ) Wxy;
|
||||
bigint_t ( size ) Wyz;
|
||||
bigint_t ( size ) Wzx;
|
||||
bigint_t ( size * 2 ) Wp;
|
||||
} temp;
|
||||
void *regs[WEIERSTRASS_NUM_REGISTERS];
|
||||
unsigned int schedule;
|
||||
const uint16_t *op;
|
||||
unsigned int i;
|
||||
|
||||
/* On entry, we assume that x1, x2, y1, y2, z1, z2 are all in
|
||||
* the range [0,4N). Additions will extend the range.
|
||||
* Subtractions will extend the range (and require an addition
|
||||
* of a suitable multiple of the modulus to ensure that the
|
||||
* result is a positive value). Relaxed Montgomery
|
||||
* multiplications will reduce the range to [0,2N). The
|
||||
* outputs x3, y3, z3 will be in the range [0,4N) and
|
||||
* therefore usable as subsequent inputs.
|
||||
*/
|
||||
static const uint16_t ops[] = {
|
||||
/* [Wxy] Qxy = (x1+y1)*(x2+y2) (mod 2N) */
|
||||
WEIERSTRASS_ADD3 ( Wt, x1, y1 ),
|
||||
WEIERSTRASS_ADD3 ( Wxy, x2, y2 ),
|
||||
WEIERSTRASS_MUL2 ( Wxy, Wt ),
|
||||
/* [Wyz] Qyz = (y1+z1)*(y2+z2) (mod 2N) */
|
||||
WEIERSTRASS_ADD3 ( Wt, y1, z1 ),
|
||||
WEIERSTRASS_ADD3 ( Wyz, y2, z2 ),
|
||||
WEIERSTRASS_MUL2 ( Wyz, Wt ),
|
||||
/* [Wzx] Qzx = (z1+x1)*(z2+x2) (mod 2N) */
|
||||
WEIERSTRASS_ADD3 ( Wt, z1, x1 ),
|
||||
WEIERSTRASS_ADD3 ( Wzx, z2, x2 ),
|
||||
WEIERSTRASS_MUL2 ( Wzx, Wt ),
|
||||
/* [x3] Px = x1*x2 (mod 2N) */
|
||||
WEIERSTRASS_MUL3 ( x3, x1, x2 ),
|
||||
/* [y3] Py = y1*y2 (mod 2N) */
|
||||
WEIERSTRASS_MUL3 ( y3, y1, y2 ),
|
||||
/* [z3] Pz = z1*z2 (mod 2N) */
|
||||
WEIERSTRASS_MUL3 ( z3, z1, z2 ),
|
||||
/* [Wxy] Rxy = Qxy - Px - Py (mod 6N)
|
||||
* = (x1+y1)*(x2+y2) - x1*x2 - y1*y2 (mod 6N)
|
||||
* = x1*y2 + x2*y1 (mod 6N)
|
||||
*/
|
||||
WEIERSTRASS_SUB2 ( Wxy, x3, 0N ),
|
||||
WEIERSTRASS_SUB2 ( Wxy, y3, 4N ),
|
||||
/* [Wyz] Ryz = Qyz - Py - Pz (mod 6N)
|
||||
* = (y1+z1)*(y2+z2) - y1*y2 - z1*z2 (mod 6N)
|
||||
* = y1*z2 + y2*z1 (mod 6N)
|
||||
*/
|
||||
WEIERSTRASS_SUB2 ( Wyz, y3, 0N ),
|
||||
WEIERSTRASS_SUB2 ( Wyz, z3, 4N ),
|
||||
/* [Wzx] Rzx = Qzx - Pz - Px (mod 6N)
|
||||
* = (z1+x1)*(z2+x2) - z1*z2 - x1*x2 (mod 6N)
|
||||
* = x1*z2 + x2*z1 (mod 6N)
|
||||
*/
|
||||
WEIERSTRASS_SUB2 ( Wzx, z3, 0N ),
|
||||
WEIERSTRASS_SUB2 ( Wzx, x3, 4N ),
|
||||
/* [Wt] aRzx = a * Rzx (mod 2N)
|
||||
* = a * (x1*z2 + x2*z1) (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL3 ( Wt, a, Wzx ),
|
||||
/* [Wp] 3bPz = 3b * Pz (mod 2N)
|
||||
* = 3b*z1*z2 (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL3 ( Wp, 3b, z3 ),
|
||||
/* [Wp] Sy = aRzx + 3bPz (mod 4N)
|
||||
* = a*(x1*z2 + x2*z1) + 3b*z1*z2 (mod 4N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( Wp, Wt ),
|
||||
/* [Wt] Syz = Py + Sy (mod 6N)
|
||||
* = y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2 (mod 6N)
|
||||
*/
|
||||
WEIERSTRASS_ADD3 ( Wt, y3, Wp ),
|
||||
/* [y3] Sxy = Py - Sy (mod 6N)
|
||||
* = y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2 (mod 6N)
|
||||
*/
|
||||
WEIERSTRASS_SUB2 ( y3, Wp, 4N ),
|
||||
/* [z3] aPz = a * Pz (mod 2N)
|
||||
* = a * z1*z2 (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL2 ( z3, a ),
|
||||
/* [Wzx] 3bRzx = 3b * Rzx (mod 2N)
|
||||
* = 3b * (x1*z2 + x2*z1) (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL2 ( Wzx, 3b ),
|
||||
/* [x3] aPzx' = Px - aPz (mod 4N)
|
||||
* = x1*x2 - a*z1*z2 (mod 4N)
|
||||
*/
|
||||
WEIERSTRASS_SUB2 ( x3, z3, 2N ),
|
||||
/* [Wp] Szx = a * aPzx' (mod 2N)
|
||||
* = a * (x1*x2 - a*z1*z2) (mod 2N)
|
||||
* = a*x1*x2 - (a^2)*z1*z2 (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL3 ( Wp, a, x3 ),
|
||||
/* [x3] Px = aPzx' + aPz (mod 6N)
|
||||
* = x1*x2 - a*z1*z2 + a*z1*z2 (mod 6N)
|
||||
* = x1*x2 (mod 6N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( x3, z3 ),
|
||||
/* [Wzx] Tzx = 3bRzx + Szx (mod 4N)
|
||||
* = a*x1*x2 + 3b*(x1*z2 + x2*z1) -
|
||||
* (a^2)*z1*z2 (mod 4N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( Wzx, Wp ),
|
||||
/* [z3] aPzx = Px + aPz (mod 8N)
|
||||
* = x1*x2 + a*z1*z2 (mod 8N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( z3, x3 ),
|
||||
/* [x3] 2Px = Px + Px (mod 12N)
|
||||
* = 2*x1*x2 (mod 12N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( x3, x3 ),
|
||||
/* [x3] Tyz = 2Px + aPzx (mod 20N)
|
||||
* = 2*x1*x2 + x1*x2 + a*z1*z2 (mod 20N)
|
||||
* = 3*x1*x2 + a*z1*z2 (mod 20N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( x3, z3 ),
|
||||
/* [z3] Syz = Syz (mod 6N)
|
||||
* = y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2 (mod 6N)
|
||||
*/
|
||||
WEIERSTRASS_MOV ( z3, Wt ),
|
||||
/* [Wt] Tyz = Tyz (mod 20N)
|
||||
* = 3*x1*x2 + a*z1*z2 (mod 20N)
|
||||
*/
|
||||
WEIERSTRASS_MOV ( Wt, x3 ),
|
||||
/* [x3] Ux = Rxy * Sxy (mod 2N)
|
||||
* = (x1*y2 + x2*y1) *
|
||||
* (y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2) (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL3 ( x3, Wxy, y3 ),
|
||||
/* [y3] Uy = Syz * Sxy (mod 2N)
|
||||
* = (y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2) *
|
||||
* (y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2) (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL2 ( y3, z3 ),
|
||||
/* [z3] Uz = Ryz * Syz (mod 2N)
|
||||
* = (y1*z2 + y2*z1) *
|
||||
* (y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2) (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL2 ( z3, Wyz ),
|
||||
/* [Wp] Vx = Ryz * Tzx (mod 2N)
|
||||
* = (y1*z2 + y2*z1) *
|
||||
* (a*x1*x2 + 3b*(x1*z2 + x2*z1) - (a^2)*z1*z2)
|
||||
* (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL3 ( Wp, Wyz, Wzx ),
|
||||
/* [x3] x3 = Ux - Vx (mod 4N)
|
||||
* = ((x1*y2 + x2*y1) *
|
||||
* (y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2)) -
|
||||
* ((y1*z2 + y2*z1) *
|
||||
* (a*x1*x2 + 3b*(x1*z2 + x2*z1) - (a^2)*z1*z2))
|
||||
* (mod 4N)
|
||||
*/
|
||||
WEIERSTRASS_SUB2 ( x3, Wp, 2N ),
|
||||
/* [Wp] Vy = Tyz * Tzx (mod 2N)
|
||||
* = (3*x1*x2 + a*z1*z2) *
|
||||
* (a*x1*x2 + 3b*(x1*z2 + x2*z1) - (a^2)*z1*z2)
|
||||
* (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL3 ( Wp, Wt, Wzx ),
|
||||
/* [y3] y3 = Vy + Uy (mod 4N)
|
||||
* = ((3*x1*x2 + a*z1*z2) *
|
||||
* (a*x1*x2 + 3b*(x1*z2 + x2*z1) - (a^2)*z1*z2)) +
|
||||
* ((y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2) *
|
||||
* (y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2))
|
||||
* (mod 4N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( y3, Wp ),
|
||||
/* [Wp] Vz = Rxy * Tyz (mod 2N)
|
||||
* = (x1*y2 + x2*y1) * (3*x1*x2 + a*z1*z2) (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL3 ( Wp, Wxy, Wt ),
|
||||
/* [z3] z3 = Uz + Vz (mod 4N)
|
||||
* = ((y1*z2 + y2*z1) *
|
||||
* (y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2)) +
|
||||
* ((x1*y2 + x2*y1) * (3*x1*x2 + a*z1*z2))
|
||||
* (mod 4N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( z3, Wp ),
|
||||
/* Stop */
|
||||
WEIERSTRASS_STOP
|
||||
};
|
||||
|
||||
/* Initialise register list */
|
||||
regs[WEIERSTRASS_a] = ( ( void * ) a );
|
||||
regs[WEIERSTRASS_3b] = ( ( void * ) b3 );
|
||||
regs[WEIERSTRASS_x1] = ( ( void * ) &augend->x );
|
||||
regs[WEIERSTRASS_x2] = ( ( void * ) &addend->x );
|
||||
regs[WEIERSTRASS_x3] = ( ( void * ) &result->x );
|
||||
regs[WEIERSTRASS_Wt] = &temp;
|
||||
schedule = ( ( ( 1 << WEIERSTRASS_NUM_REGISTERS ) - 1 )
|
||||
- ( 1 << WEIERSTRASS_a )
|
||||
- ( 1 << WEIERSTRASS_3b )
|
||||
- ( 1 << WEIERSTRASS_x1 )
|
||||
- ( 1 << WEIERSTRASS_x2 )
|
||||
- ( 1 << WEIERSTRASS_x3 )
|
||||
- ( 1 << WEIERSTRASS_Wt ) );
|
||||
for ( i = 0 ; schedule ; i++, schedule >>= 1 ) {
|
||||
if ( schedule & 1 )
|
||||
regs[i] = ( regs[ i - 1 ] + sizeof ( *prime ) );
|
||||
}
|
||||
DBGC2 ( curve, "WEIERSTRASS %s augend (%s,",
|
||||
curve->name, bigint_ntoa ( &augend->x ) );
|
||||
DBGC2 ( curve, "%s,", bigint_ntoa ( &augend->y ) );
|
||||
DBGC2 ( curve, "%s)\n", bigint_ntoa ( &augend->z ) );
|
||||
DBGC2 ( curve, "WEIERSTRASS %s addend (%s,",
|
||||
curve->name, bigint_ntoa ( &addend->x ) );
|
||||
DBGC2 ( curve, "%s,", bigint_ntoa ( &addend->y ) );
|
||||
DBGC2 ( curve, "%s)\n", bigint_ntoa ( &addend->z ) );
|
||||
|
||||
/* Sanity checks */
|
||||
assert ( regs[WEIERSTRASS_a] == a );
|
||||
assert ( regs[WEIERSTRASS_3b] == b3 );
|
||||
assert ( regs[WEIERSTRASS_x1] == &augend->x );
|
||||
assert ( regs[WEIERSTRASS_y1] == &augend->y );
|
||||
assert ( regs[WEIERSTRASS_z1] == &augend->z );
|
||||
assert ( regs[WEIERSTRASS_x2] == &addend->x );
|
||||
assert ( regs[WEIERSTRASS_y2] == &addend->y );
|
||||
assert ( regs[WEIERSTRASS_z2] == &addend->z );
|
||||
assert ( regs[WEIERSTRASS_x3] == &result->x );
|
||||
assert ( regs[WEIERSTRASS_y3] == &result->y );
|
||||
assert ( regs[WEIERSTRASS_z3] == &result->z );
|
||||
assert ( regs[WEIERSTRASS_Wt] == &temp.Wt );
|
||||
assert ( regs[WEIERSTRASS_Wxy] == &temp.Wxy );
|
||||
assert ( regs[WEIERSTRASS_Wyz] == &temp.Wyz );
|
||||
assert ( regs[WEIERSTRASS_Wzx] == &temp.Wzx );
|
||||
assert ( regs[WEIERSTRASS_Wp] == &temp.Wp );
|
||||
|
||||
/* Execute bytecode instruction sequence */
|
||||
for ( op = ops ; *op != WEIERSTRASS_STOP ; op++ )
|
||||
weierstrass_exec ( curve, regs, size, *op );
|
||||
DBGC2 ( curve, "WEIERSTRASS %s result (%s,",
|
||||
curve->name, bigint_ntoa ( &result->x ) );
|
||||
DBGC2 ( curve, "%s,", bigint_ntoa ( &result->y ) );
|
||||
DBGC2 ( curve, "%s)\n", bigint_ntoa ( &result->z ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add points on curve
|
||||
*
|
||||
* @v curve Weierstrass curve
|
||||
* @v augend Point (x1,y1,z1) to be added
|
||||
* @v addend Point (x2,y2,z2) to be added
|
||||
* @v result0 Point (x3,y3,z3) to hold result
|
||||
*/
|
||||
#define weierstrass_add( curve, augend, addend, result ) do { \
|
||||
weierstrass_add_raw ( (curve), (augend)->all.element, \
|
||||
(addend)->all.element, \
|
||||
(result)->all.element ); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* Add points on curve as part of a Montgomery ladder
|
||||
*
|
||||
* @v operand Element 0 of first input operand (may overlap result)
|
||||
* @v result Element 0 of second input operand and result
|
||||
* @v size Number of elements in operands and result
|
||||
* @v ctx Operation context
|
||||
* @v tmp Temporary working space (not used)
|
||||
*/
|
||||
static void weierstrass_add_ladder ( const bigint_element_t *operand0,
|
||||
bigint_element_t *result0,
|
||||
unsigned int size, const void *ctx,
|
||||
void *tmp __unused ) {
|
||||
const struct weierstrass_curve *curve = ctx;
|
||||
const weierstrass_t ( curve->size ) __attribute__ (( may_alias ))
|
||||
*operand = ( ( const void * ) operand0 );
|
||||
weierstrass_t ( curve->size ) __attribute__ (( may_alias ))
|
||||
*result = ( ( void * ) result0 );
|
||||
|
||||
/* Add curve points */
|
||||
assert ( size == bigint_size ( &operand->all ) );
|
||||
assert ( size == bigint_size ( &result->all ) );
|
||||
weierstrass_add ( curve, operand, result, result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify point is on curve
|
||||
*
|
||||
* @v curve Weierstrass curve
|
||||
* @v point0 Element 0 of point (x,y,z) to be verified
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* As with point addition, points are represented in projective
|
||||
* coordinates, with all values in Montgomery form and in the range
|
||||
* [0,4N) where N is the field prime.
|
||||
*/
|
||||
static int weierstrass_verify_raw ( const struct weierstrass_curve *curve,
|
||||
const bigint_element_t *point0 ) {
|
||||
unsigned int size = curve->size;
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*prime = ( ( const void * ) curve->prime[0] );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*a = ( ( const void * ) curve->a );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias ))
|
||||
*b3 = ( ( const void * ) curve->b3 );
|
||||
const weierstrass_t ( size ) __attribute__ (( may_alias ))
|
||||
*point = ( ( const void * ) point0 );
|
||||
struct {
|
||||
bigint_t ( size ) Wt;
|
||||
bigint_t ( size * 2 ) Wp;
|
||||
} temp;
|
||||
void *regs[WEIERSTRASS_NUM_REGISTERS];
|
||||
const uint16_t *op;
|
||||
|
||||
/* Calculate 3*(x^3 + a*x + b - y^2) */
|
||||
static const uint16_t ops[] = {
|
||||
/* [Wt] Tx = x^2 (mod 2N) */
|
||||
WEIERSTRASS_MUL3 ( Wt, x1, x1 ),
|
||||
/* [Wt] Txa = Tx + a (mod 3N)
|
||||
* = x^2 + a (mod 3N)
|
||||
*/
|
||||
WEIERSTRASS_MOV ( Wp, a ),
|
||||
WEIERSTRASS_ADD2 ( Wt, Wp ),
|
||||
/* [Wt] Txax = Txa * x (mod 2N)
|
||||
* = (x^2 + a)*x (mod 2N)
|
||||
* = x^3 + a*x (mod 2N)
|
||||
*/
|
||||
WEIERSTRASS_MUL2 ( Wt, x1 ),
|
||||
/* [Wp] Ty = y^2 (mod 2N) */
|
||||
WEIERSTRASS_MUL3 ( Wp, y1, y1 ),
|
||||
/* [Wt] Txaxy = Txax - Ty (mod 4N)
|
||||
* = x^3 + a*x - y^2 (mod 4N)
|
||||
*/
|
||||
WEIERSTRASS_SUB2 ( Wt, Wp, 2N ),
|
||||
/* [Wp] 2Txaxy = Txaxy + Txaxy (mod 8N)
|
||||
* = 2*(x^3 + a*x - y^2) (mod 8N)
|
||||
*/
|
||||
WEIERSTRASS_ADD3 ( Wp, Wt, Wt ),
|
||||
/* [Wt] 3Txaxy = 2Txaxy + Txaxy (mod 12N)
|
||||
* = 3*(x^3 + a*x - y^2) (mod 12N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( Wt, Wp ),
|
||||
/* [Wt] 3Txaxyb = 3Txaxy + 3b (mod 13N)
|
||||
* = 3*(x^3 + a*x - y^2) + 3b (mod 13N)
|
||||
* = 3*(x^3 + a*x + b - y^2) (mod 13N)
|
||||
*/
|
||||
WEIERSTRASS_ADD2 ( Wt, 3b ),
|
||||
/* Stop */
|
||||
WEIERSTRASS_STOP
|
||||
};
|
||||
|
||||
/* Initialise register list */
|
||||
regs[WEIERSTRASS_a] = ( ( void * ) a );
|
||||
regs[WEIERSTRASS_3b] = ( ( void * ) b3 );
|
||||
regs[WEIERSTRASS_x1] = ( ( void * ) &point->x );
|
||||
regs[WEIERSTRASS_y1] = ( ( void * ) &point->y );
|
||||
regs[WEIERSTRASS_Wt] = &temp.Wt;
|
||||
regs[WEIERSTRASS_Wp] = &temp.Wp;
|
||||
|
||||
/* Execute bytecode instruction sequence */
|
||||
for ( op = ops ; *op != WEIERSTRASS_STOP ; op++ )
|
||||
weierstrass_exec ( curve, regs, size, *op );
|
||||
|
||||
/* Check that result is zero (modulo the field prime) */
|
||||
bigint_grow ( &temp.Wt, &temp.Wp );
|
||||
bigint_montgomery ( prime, &temp.Wp, &temp.Wt );
|
||||
if ( ! bigint_is_zero ( &temp.Wt ) ) {
|
||||
DBGC ( curve, "WEIERSTRASS %s base point is not on curve\n",
|
||||
curve->name );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify point is on curve
|
||||
*
|
||||
* @v curve Weierstrass curve
|
||||
* @v point Point (x,y,z) to be verified
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
#define weierstrass_verify( curve, point ) ( { \
|
||||
weierstrass_verify_raw ( (curve), (point)->all.element ); \
|
||||
} )
|
||||
|
||||
/**
|
||||
* Multiply curve point by scalar
|
||||
*
|
||||
* @v curve Weierstrass curve
|
||||
* @v base Base point (or NULL to use generator)
|
||||
* @v scalar Scalar multiple
|
||||
* @v result Result point to fill in
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int weierstrass_multiply ( struct weierstrass_curve *curve, const void *base,
|
||||
const void *scalar, void *result ) {
|
||||
unsigned int size = curve->size;
|
||||
size_t len = curve->len;
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *prime =
|
||||
( ( const void * ) curve->prime[0] );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *prime2 =
|
||||
( ( const void * ) curve->prime[WEIERSTRASS_2N] );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
|
||||
( ( const void * ) curve->fermat );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *square =
|
||||
( ( const void * ) curve->square );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *one =
|
||||
( ( const void * ) curve->one );
|
||||
struct {
|
||||
union {
|
||||
weierstrass_t ( size ) result;
|
||||
bigint_t ( size * 2 ) product_in;
|
||||
};
|
||||
union {
|
||||
weierstrass_t ( size ) multiple;
|
||||
bigint_t ( size * 2 ) product_out;
|
||||
};
|
||||
bigint_t ( bigint_required_size ( len ) ) scalar;
|
||||
} temp;
|
||||
size_t offset;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
/* Initialise curve, if not already done
|
||||
*
|
||||
* The least significant element of the field prime must be
|
||||
* odd, and so the least significant element of the
|
||||
* (initialised) first multiple of the field prime must be
|
||||
* non-zero.
|
||||
*/
|
||||
if ( ! prime2->element[0] )
|
||||
weierstrass_init ( curve );
|
||||
|
||||
/* Use generator if applicable */
|
||||
if ( ! base )
|
||||
base = curve->base;
|
||||
|
||||
/* Convert input to projective coordinates in Montgomery form */
|
||||
DBGC ( curve, "WEIERSTRASS %s base (", curve->name );
|
||||
for ( i = 0, offset = 0 ; i < WEIERSTRASS_AXES ; i++, offset += len ) {
|
||||
bigint_init ( &temp.multiple.axis[i], ( base + offset ), len );
|
||||
DBGC ( curve, "%s%s", ( i ? "," : "" ),
|
||||
bigint_ntoa ( &temp.multiple.axis[i] ) );
|
||||
bigint_multiply ( &temp.multiple.axis[i], square,
|
||||
&temp.product_in );
|
||||
bigint_montgomery_relaxed ( prime, &temp.product_in,
|
||||
&temp.multiple.axis[i] );
|
||||
}
|
||||
bigint_copy ( one, &temp.multiple.z );
|
||||
DBGC ( curve, ")\n" );
|
||||
|
||||
/* Verify point is on curve */
|
||||
if ( ( rc = weierstrass_verify ( curve, &temp.multiple ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Construct identity element (the point at infinity) */
|
||||
memset ( &temp.result, 0, sizeof ( temp.result ) );
|
||||
bigint_copy ( one, &temp.result.y );
|
||||
|
||||
/* Initialise scalar */
|
||||
bigint_init ( &temp.scalar, scalar, len );
|
||||
DBGC ( curve, "WEIERSTRASS %s scalar %s\n",
|
||||
curve->name, bigint_ntoa ( &temp.scalar ) );
|
||||
|
||||
/* Perform multiplication via Montgomery ladder */
|
||||
bigint_ladder ( &temp.result.all, &temp.multiple.all, &temp.scalar,
|
||||
weierstrass_add_ladder, curve, NULL );
|
||||
|
||||
/* Invert result Z co-ordinate (via Fermat's little theorem) */
|
||||
bigint_copy ( one, &temp.multiple.z );
|
||||
bigint_ladder ( &temp.multiple.z, &temp.result.z, fermat,
|
||||
bigint_mod_exp_ladder, prime, &temp.product_out );
|
||||
|
||||
/* Convert result back to affine co-ordinates */
|
||||
DBGC ( curve, "WEIERSTRASS %s result (", curve->name );
|
||||
for ( i = 0, offset = 0 ; i < WEIERSTRASS_AXES ; i++, offset += len ) {
|
||||
bigint_multiply ( &temp.result.axis[i], &temp.multiple.z,
|
||||
&temp.product_out );
|
||||
bigint_montgomery_relaxed ( prime, &temp.product_out,
|
||||
&temp.result.axis[i] );
|
||||
bigint_grow ( &temp.result.axis[i], &temp.product_out );
|
||||
bigint_montgomery ( prime, &temp.product_out,
|
||||
&temp.result.axis[i] );
|
||||
DBGC ( curve, "%s%s", ( i ? "," : "" ),
|
||||
bigint_ntoa ( &temp.result.axis[i] ) );
|
||||
bigint_done ( &temp.result.axis[i], ( result + offset ), len );
|
||||
}
|
||||
DBGC ( curve, ")\n" );
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -839,6 +839,7 @@ static int x25519_curve_multiply ( const void *base, const void *scalar,
|
|||
/** X25519 elliptic curve */
|
||||
struct elliptic_curve x25519_curve = {
|
||||
.name = "x25519",
|
||||
.pointsize = sizeof ( struct x25519_value ),
|
||||
.keysize = sizeof ( struct x25519_value ),
|
||||
.multiply = x25519_curve_multiply,
|
||||
};
|
||||
|
|
|
@ -1323,9 +1323,9 @@ int x509_is_valid ( struct x509_certificate *cert, struct x509_root *root ) {
|
|||
* @v issuer Issuing X.509 certificate (or NULL)
|
||||
* @v root Root certificate list
|
||||
*/
|
||||
static void x509_set_valid ( struct x509_certificate *cert,
|
||||
struct x509_certificate *issuer,
|
||||
struct x509_root *root ) {
|
||||
void x509_set_valid ( struct x509_certificate *cert,
|
||||
struct x509_certificate *issuer,
|
||||
struct x509_root *root ) {
|
||||
unsigned int max_path_remaining;
|
||||
|
||||
/* Sanity checks */
|
||||
|
|
|
@ -1840,7 +1840,7 @@ static int bnxt_hwrm_ring_alloc ( struct bnxt *bp, u8 type )
|
|||
req->page_size = LM_PAGE_BITS ( 8 );
|
||||
req->int_mode = RING_ALLOC_REQ_INT_MODE_POLL;
|
||||
req->length = ( u32 )bp->tx.ring_cnt;
|
||||
req->queue_id = TX_RING_QID;
|
||||
req->queue_id = ( u16 )bp->queue_id;
|
||||
req->stat_ctx_id = ( u32 )bp->stat_ctx_id;
|
||||
req->cmpl_ring_id = bp->cq_ring_id;
|
||||
req->page_tbl_addr = virt_to_bus ( bp->tx.bd_virt );
|
||||
|
|
|
@ -178,7 +178,6 @@ union dma_addr64_t {
|
|||
RX_MASK_ACCEPT_MULTICAST)
|
||||
#define MAX_NQ_DESC_CNT 64
|
||||
#define NQ_RING_BUFFER_SIZE (MAX_NQ_DESC_CNT * sizeof(struct cmpl_base))
|
||||
#define TX_RING_QID (FLAG_TEST(bp->flags, BNXT_FLAG_IS_CHIP_P5_PLUS) ? (u16)bp->queue_id : ((u16)bp->port_idx * 10))
|
||||
#define RX_RING_QID (FLAG_TEST(bp->flags, BNXT_FLAG_IS_CHIP_P5_PLUS) ? bp->queue_id : 0)
|
||||
#define STAT_CTX_ID ((bp->vf || FLAG_TEST(bp->flags, BNXT_FLAG_IS_CHIP_P5_PLUS)) ? bp->stat_ctx_id : 0)
|
||||
#define TX_AVAIL(r) (r - 1)
|
||||
|
|
|
@ -1543,7 +1543,8 @@ static int gve_probe ( struct pci_device *pci ) {
|
|||
gve->netdev = netdev;
|
||||
gve->tx.type = &gve_tx_type;
|
||||
gve->rx.type = &gve_rx_type;
|
||||
process_init ( &gve->startup, &gve_startup_desc, &netdev->refcnt );
|
||||
process_init_stopped ( &gve->startup, &gve_startup_desc,
|
||||
&netdev->refcnt );
|
||||
timer_init ( &gve->watchdog, gve_watchdog, &netdev->refcnt );
|
||||
|
||||
/* Fix up PCI device */
|
||||
|
|
|
@ -207,8 +207,10 @@ static int item_exec ( int argc, char **argv ) {
|
|||
struct choose_options {
|
||||
/** Dynamic user interface name */
|
||||
char *dynui;
|
||||
/** Timeout */
|
||||
/** Initial timeout */
|
||||
unsigned long timeout;
|
||||
/** Post-activity timeout */
|
||||
unsigned long retimeout;
|
||||
/** Default selection */
|
||||
char *select;
|
||||
/** Keep dynamic user interface */
|
||||
|
@ -223,6 +225,8 @@ static struct option_descriptor choose_opts[] = {
|
|||
struct choose_options, select, parse_string ),
|
||||
OPTION_DESC ( "timeout", 't', required_argument,
|
||||
struct choose_options, timeout, parse_timeout ),
|
||||
OPTION_DESC ( "retimeout", 'r', required_argument,
|
||||
struct choose_options, retimeout, parse_timeout ),
|
||||
OPTION_DESC ( "keep", 'k', no_argument,
|
||||
struct choose_options, keep, parse_flag ),
|
||||
};
|
||||
|
@ -259,8 +263,8 @@ static int choose_exec ( int argc, char **argv ) {
|
|||
goto err_parse_dynui;
|
||||
|
||||
/* Show as menu */
|
||||
if ( ( rc = show_menu ( dynui, opts.timeout, opts.select,
|
||||
&item ) ) != 0 )
|
||||
if ( ( rc = show_menu ( dynui, opts.timeout, opts.retimeout,
|
||||
opts.select, &item ) ) != 0 )
|
||||
goto err_show_menu;
|
||||
|
||||
/* Apply default type if necessary */
|
||||
|
|
|
@ -53,8 +53,10 @@ struct menu_ui {
|
|||
struct dynamic_ui *dynui;
|
||||
/** Jump scroller */
|
||||
struct jump_scroller scroll;
|
||||
/** Timeout (0=indefinite) */
|
||||
/** Remaining timeout (0=indefinite) */
|
||||
unsigned long timeout;
|
||||
/** Post-activity timeout (0=indefinite) */
|
||||
unsigned long retimeout;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -180,8 +182,8 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
|
|||
if ( ui->timeout == 0 )
|
||||
chosen = 1;
|
||||
} else {
|
||||
/* Cancel any timeout */
|
||||
ui->timeout = 0;
|
||||
/* Reset timeout after activity */
|
||||
ui->timeout = ui->retimeout;
|
||||
|
||||
/* Handle scroll keys */
|
||||
move = jump_scroll_key ( &ui->scroll, key );
|
||||
|
@ -241,12 +243,14 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
|
|||
* Show menu
|
||||
*
|
||||
* @v dynui Dynamic user interface
|
||||
* @v timeout Timeout period, in ticks (0=indefinite)
|
||||
* @v timeout Initial timeout period, in ticks (0=indefinite)
|
||||
* @v retimeout Post-activity timeout period, in ticks (0=indefinite)
|
||||
* @ret selected Selected item
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int show_menu ( struct dynamic_ui *dynui, unsigned long timeout,
|
||||
const char *select, struct dynamic_item **selected ) {
|
||||
unsigned long retimeout, const char *select,
|
||||
struct dynamic_item **selected ) {
|
||||
struct dynamic_item *item;
|
||||
struct menu_ui ui;
|
||||
char buf[ MENU_COLS + 1 /* NUL */ ];
|
||||
|
@ -258,6 +262,8 @@ int show_menu ( struct dynamic_ui *dynui, unsigned long timeout,
|
|||
ui.dynui = dynui;
|
||||
ui.scroll.rows = MENU_ROWS;
|
||||
ui.timeout = timeout;
|
||||
ui.retimeout = retimeout;
|
||||
|
||||
list_for_each_entry ( item, &dynui->items, list ) {
|
||||
if ( item->name ) {
|
||||
if ( ! named_count )
|
||||
|
|
|
@ -38,32 +38,41 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
*/
|
||||
|
||||
/**
|
||||
* Extract ASN.1 object from image
|
||||
* Extract ASN.1 object from DER data
|
||||
*
|
||||
* @v image DER image
|
||||
* @v offset Offset within image
|
||||
* @v data DER data
|
||||
* @v len Length of DER data
|
||||
* @v offset Offset within data
|
||||
* @v cursor ASN.1 cursor to fill in
|
||||
* @ret next Offset to next image, or negative error
|
||||
* @ret next Offset to next object, or negative error
|
||||
*
|
||||
* The caller is responsible for eventually calling free() on the
|
||||
* allocated ASN.1 cursor.
|
||||
*/
|
||||
static int der_asn1 ( struct image *image, size_t offset __unused,
|
||||
struct asn1_cursor **cursor ) {
|
||||
void *data;
|
||||
int der_asn1 ( userptr_t data, size_t len, size_t offset,
|
||||
struct asn1_cursor **cursor ) {
|
||||
size_t remaining;
|
||||
void *raw;
|
||||
|
||||
/* Sanity check */
|
||||
assert ( offset <= len );
|
||||
remaining = ( len - offset );
|
||||
|
||||
/* Allocate cursor and data buffer */
|
||||
*cursor = malloc ( sizeof ( **cursor ) + image->len );
|
||||
*cursor = malloc ( sizeof ( **cursor ) + remaining );
|
||||
if ( ! *cursor )
|
||||
return -ENOMEM;
|
||||
data = ( ( ( void * ) *cursor ) + sizeof ( **cursor ) );
|
||||
raw = ( ( ( void * ) *cursor ) + sizeof ( **cursor ) );
|
||||
|
||||
/* Populate cursor and data buffer */
|
||||
(*cursor)->data = data;
|
||||
(*cursor)->len = image->len;
|
||||
copy_from_user ( data, image->data, 0, image->len );
|
||||
(*cursor)->data = raw;
|
||||
(*cursor)->len = remaining;
|
||||
copy_from_user ( raw, data, offset, remaining );
|
||||
|
||||
return image->len;
|
||||
/* Shrink cursor */
|
||||
asn1_shrink_any ( *cursor );
|
||||
|
||||
return ( offset + (*cursor)->len );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,7 +81,7 @@ static int der_asn1 ( struct image *image, size_t offset __unused,
|
|||
* @v image DER image
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int der_probe ( struct image *image ) {
|
||||
static int der_image_probe ( struct image *image ) {
|
||||
struct asn1_cursor cursor;
|
||||
uint8_t buf[8];
|
||||
size_t extra;
|
||||
|
@ -105,9 +114,37 @@ static int der_probe ( struct image *image ) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract ASN.1 object from DER image
|
||||
*
|
||||
* @v image DER image
|
||||
* @v offset Offset within image
|
||||
* @v cursor ASN.1 cursor to fill in
|
||||
* @ret next Offset to next image, or negative error
|
||||
*
|
||||
* The caller is responsible for eventually calling free() on the
|
||||
* allocated ASN.1 cursor.
|
||||
*/
|
||||
static int der_image_asn1 ( struct image *image, size_t offset,
|
||||
struct asn1_cursor **cursor ) {
|
||||
int next;
|
||||
int rc;
|
||||
|
||||
/* Extract ASN.1 object */
|
||||
if ( ( next = der_asn1 ( image->data, image->len, offset,
|
||||
cursor ) ) < 0 ) {
|
||||
rc = next;
|
||||
DBGC ( image, "DER %s could not extract ASN.1: %s\n",
|
||||
image->name, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/** DER image type */
|
||||
struct image_type der_image_type __image_type ( PROBE_NORMAL ) = {
|
||||
.name = "DER",
|
||||
.probe = der_probe,
|
||||
.asn1 = der_asn1,
|
||||
.probe = der_image_probe,
|
||||
.asn1 = der_image_asn1,
|
||||
};
|
||||
|
|
|
@ -268,7 +268,7 @@ static int efi_image_exec ( struct image *image ) {
|
|||
efi_snp_release();
|
||||
|
||||
/* Wrap calls made by the loaded image (for debugging) */
|
||||
efi_wrap ( handle );
|
||||
efi_wrap_image ( handle );
|
||||
|
||||
/* Reset console since image will probably use it */
|
||||
console_reset();
|
||||
|
@ -291,6 +291,7 @@ static int efi_image_exec ( struct image *image ) {
|
|||
rc = 0;
|
||||
|
||||
err_start_image:
|
||||
efi_unwrap();
|
||||
efi_snp_claim();
|
||||
err_open_protocol:
|
||||
/* If there was no error, then the image must have been
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI signature lists
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/asn1.h>
|
||||
#include <ipxe/der.h>
|
||||
#include <ipxe/pem.h>
|
||||
#include <ipxe/image.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/Guid/ImageAuthentication.h>
|
||||
#include <ipxe/efi/efi_siglist.h>
|
||||
|
||||
/**
|
||||
* Find EFI signature list entry
|
||||
*
|
||||
* @v data EFI signature list
|
||||
* @v len Length of EFI signature list
|
||||
* @v start Starting offset to update
|
||||
* @v lhdr Signature list header to fill in
|
||||
* @v dhdr Signature data header to fill in
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int efisig_find ( userptr_t data, size_t len, size_t *start,
|
||||
EFI_SIGNATURE_LIST *lhdr, EFI_SIGNATURE_DATA *dhdr ) {
|
||||
size_t offset;
|
||||
size_t remaining;
|
||||
size_t skip;
|
||||
size_t dlen;
|
||||
|
||||
/* Scan through signature list */
|
||||
offset = 0;
|
||||
while ( 1 ) {
|
||||
|
||||
/* Read list header */
|
||||
assert ( offset <= len );
|
||||
remaining = ( len - offset );
|
||||
if ( remaining < sizeof ( *lhdr ) ) {
|
||||
DBGC ( data, "EFISIG [%#zx,%#zx) truncated header "
|
||||
"at +%#zx\n", *start, len, offset );
|
||||
return -EINVAL;
|
||||
}
|
||||
copy_from_user ( lhdr, data, offset, sizeof ( *lhdr ) );
|
||||
|
||||
/* Get length of this signature list */
|
||||
if ( remaining < lhdr->SignatureListSize ) {
|
||||
DBGC ( data, "EFISIG [%#zx,%#zx) truncated list at "
|
||||
"+%#zx\n", *start, len, offset );
|
||||
return -EINVAL;
|
||||
}
|
||||
remaining = lhdr->SignatureListSize;
|
||||
|
||||
/* Get length of each signature in list */
|
||||
dlen = lhdr->SignatureSize;
|
||||
if ( dlen < sizeof ( *dhdr ) ) {
|
||||
DBGC ( data, "EFISIG [%#zx,%#zx) underlength "
|
||||
"signatures at +%#zx\n", *start, len, offset );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Strip list header (including variable portion) */
|
||||
if ( ( remaining < sizeof ( *lhdr ) ) ||
|
||||
( ( remaining - sizeof ( *lhdr ) ) <
|
||||
lhdr->SignatureHeaderSize ) ) {
|
||||
DBGC ( data, "EFISIG [%#zx,%#zx) malformed header at "
|
||||
"+%#zx\n", *start, len, offset );
|
||||
return -EINVAL;
|
||||
}
|
||||
skip = ( sizeof ( *lhdr ) + lhdr->SignatureHeaderSize );
|
||||
offset += skip;
|
||||
remaining -= skip;
|
||||
|
||||
/* Read signatures */
|
||||
for ( ; remaining ; offset += dlen, remaining -= dlen ) {
|
||||
|
||||
/* Check length */
|
||||
if ( remaining < dlen ) {
|
||||
DBGC ( data, "EFISIG [%#zx,%#zx) truncated "
|
||||
"at +%#zx\n", *start, len, offset );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Continue until we find the requested signature */
|
||||
if ( offset < *start )
|
||||
continue;
|
||||
|
||||
/* Read data header */
|
||||
copy_from_user ( dhdr, data, offset, sizeof ( *dhdr ));
|
||||
DBGC2 ( data, "EFISIG [%#zx,%#zx) %s ",
|
||||
offset, ( offset + dlen ),
|
||||
efi_guid_ntoa ( &lhdr->SignatureType ) );
|
||||
DBGC2 ( data, "owner %s\n",
|
||||
efi_guid_ntoa ( &dhdr->SignatureOwner ) );
|
||||
*start = offset;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract ASN.1 object from EFI signature list
|
||||
*
|
||||
* @v data EFI signature list
|
||||
* @v len Length of EFI signature list
|
||||
* @v offset Offset within image
|
||||
* @v cursor ASN.1 cursor to fill in
|
||||
* @ret next Offset to next image, or negative error
|
||||
*
|
||||
* The caller is responsible for eventually calling free() on the
|
||||
* allocated ASN.1 cursor.
|
||||
*/
|
||||
int efisig_asn1 ( userptr_t data, size_t len, size_t offset,
|
||||
struct asn1_cursor **cursor ) {
|
||||
EFI_SIGNATURE_LIST lhdr;
|
||||
EFI_SIGNATURE_DATA dhdr;
|
||||
int ( * asn1 ) ( userptr_t data, size_t len, size_t offset,
|
||||
struct asn1_cursor **cursor );
|
||||
size_t skip = offsetof ( typeof ( dhdr ), SignatureData );
|
||||
int next;
|
||||
int rc;
|
||||
|
||||
/* Locate signature list entry */
|
||||
if ( ( rc = efisig_find ( data, len, &offset, &lhdr, &dhdr ) ) != 0 )
|
||||
goto err_entry;
|
||||
len = ( offset + lhdr.SignatureSize );
|
||||
|
||||
/* Parse as PEM or DER based on first character */
|
||||
asn1 = ( ( dhdr.SignatureData[0] == ASN1_SEQUENCE ) ?
|
||||
der_asn1 : pem_asn1 );
|
||||
DBGC2 ( data, "EFISIG [%#zx,%#zx) extracting %s\n", offset, len,
|
||||
( ( asn1 == der_asn1 ) ? "DER" : "PEM" ) );
|
||||
next = asn1 ( data, len, ( offset + skip ), cursor );
|
||||
if ( next < 0 ) {
|
||||
rc = next;
|
||||
DBGC ( data, "EFISIG [%#zx,%#zx) could not extract ASN.1: "
|
||||
"%s\n", offset, len, strerror ( rc ) );
|
||||
goto err_asn1;
|
||||
}
|
||||
|
||||
/* Check that whole entry was consumed */
|
||||
if ( ( ( unsigned int ) next ) != len ) {
|
||||
DBGC ( data, "EFISIG [%#zx,%#zx) malformed data\n",
|
||||
offset, len );
|
||||
rc = -EINVAL;
|
||||
goto err_whole;
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
err_whole:
|
||||
free ( *cursor );
|
||||
err_asn1:
|
||||
err_entry:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Probe EFI signature list image
|
||||
*
|
||||
* @v image EFI signature list
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int efisig_image_probe ( struct image *image ) {
|
||||
EFI_SIGNATURE_LIST lhdr;
|
||||
EFI_SIGNATURE_DATA dhdr;
|
||||
size_t offset = 0;
|
||||
unsigned int count = 0;
|
||||
int rc;
|
||||
|
||||
/* Check file is a well-formed signature list */
|
||||
while ( 1 ) {
|
||||
|
||||
/* Find next signature list entry */
|
||||
if ( ( rc = efisig_find ( image->data, image->len, &offset,
|
||||
&lhdr, &dhdr ) ) != 0 ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Skip this entry */
|
||||
offset += lhdr.SignatureSize;
|
||||
count++;
|
||||
|
||||
/* Check if we have reached end of the image */
|
||||
if ( offset == image->len ) {
|
||||
DBGC ( image, "EFISIG %s contains %d signatures\n",
|
||||
image->name, count );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract ASN.1 object from EFI signature list image
|
||||
*
|
||||
* @v image EFI signature list
|
||||
* @v offset Offset within image
|
||||
* @v cursor ASN.1 cursor to fill in
|
||||
* @ret next Offset to next image, or negative error
|
||||
*
|
||||
* The caller is responsible for eventually calling free() on the
|
||||
* allocated ASN.1 cursor.
|
||||
*/
|
||||
static int efisig_image_asn1 ( struct image *image, size_t offset,
|
||||
struct asn1_cursor **cursor ) {
|
||||
int next;
|
||||
int rc;
|
||||
|
||||
/* Extract ASN.1 object */
|
||||
if ( ( next = efisig_asn1 ( image->data, image->len, offset,
|
||||
cursor ) ) < 0 ) {
|
||||
rc = next;
|
||||
DBGC ( image, "EFISIG %s could not extract ASN.1: %s\n",
|
||||
image->name, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/** EFI signature list image type */
|
||||
struct image_type efisig_image_type __image_type ( PROBE_NORMAL ) = {
|
||||
.name = "EFISIG",
|
||||
.probe = efisig_image_probe,
|
||||
.asn1 = efisig_image_asn1,
|
||||
};
|
|
@ -127,6 +127,12 @@ struct asn1_builder_header {
|
|||
#define ASN1_OID_TRIPLE( value ) \
|
||||
( 0x80 | ( ( (value) >> 14 ) & 0x7f ) ), ASN1_OID_DOUBLE ( (value) )
|
||||
|
||||
/** ASN.1 OID for prime256v1 (1.2.840.10045.3.1.7) */
|
||||
#define ASN1_OID_PRIME256V1 \
|
||||
ASN1_OID_INITIAL ( 1, 1 ), ASN1_OID_DOUBLE ( 840 ), \
|
||||
ASN1_OID_DOUBLE ( 10045 ), ASN1_OID_SINGLE ( 3 ), \
|
||||
ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 7 )
|
||||
|
||||
/** ASN.1 OID for rsaEncryption (1.2.840.113549.1.1.1) */
|
||||
#define ASN1_OID_RSAENCRYPTION \
|
||||
ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
|
||||
|
@ -192,6 +198,11 @@ struct asn1_builder_header {
|
|||
ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 101 ), \
|
||||
ASN1_OID_SINGLE ( 110 )
|
||||
|
||||
/** ASN.1 OID for secp384r1 (1.3.132.0.34) */
|
||||
#define ASN1_OID_SECP384R1 \
|
||||
ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_DOUBLE ( 132 ), \
|
||||
ASN1_OID_SINGLE ( 0 ), ASN1_OID_SINGLE ( 34 )
|
||||
|
||||
/** ASN.1 OID for id-aes128-cbc (2.16.840.1.101.3.4.1.2) */
|
||||
#define ASN1_OID_AES128_CBC \
|
||||
ASN1_OID_INITIAL ( 2, 16 ), ASN1_OID_DOUBLE ( 840 ), \
|
||||
|
|
|
@ -40,6 +40,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define bigint_size( bigint ) \
|
||||
( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) )
|
||||
|
||||
/**
|
||||
* Transcribe big integer (for debugging)
|
||||
*
|
||||
* @v value Big integer to be transcribed
|
||||
* @ret string Big integer in string form (may be abbreviated)
|
||||
*/
|
||||
#define bigint_ntoa( value ) ( { \
|
||||
unsigned int size = bigint_size (value); \
|
||||
bigint_ntoa_raw ( (value)->element, size ); \
|
||||
} )
|
||||
|
||||
/**
|
||||
* Initialise big integer
|
||||
*
|
||||
|
@ -94,21 +105,23 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
* Shift big integer left
|
||||
*
|
||||
* @v value Big integer
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
#define bigint_shl( value ) do { \
|
||||
#define bigint_shl( value ) ( { \
|
||||
unsigned int size = bigint_size (value); \
|
||||
bigint_shl_raw ( (value)->element, size ); \
|
||||
} while ( 0 )
|
||||
} )
|
||||
|
||||
/**
|
||||
* Shift big integer right
|
||||
*
|
||||
* @v value Big integer
|
||||
* @ret out Bit shifted out
|
||||
*/
|
||||
#define bigint_shr( value ) do { \
|
||||
#define bigint_shr( value ) ( { \
|
||||
unsigned int size = bigint_size (value); \
|
||||
bigint_shr_raw ( (value)->element, size ); \
|
||||
} while ( 0 )
|
||||
} )
|
||||
|
||||
/**
|
||||
* Test if big integer is equal to zero
|
||||
|
@ -133,6 +146,28 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
bigint_is_geq_raw ( (value)->element, (reference)->element, \
|
||||
size ); } )
|
||||
|
||||
/**
|
||||
* Set bit in big integer
|
||||
*
|
||||
* @v value Big integer
|
||||
* @v bit Bit to set
|
||||
*/
|
||||
#define bigint_set_bit( value, bit ) do { \
|
||||
unsigned int size = bigint_size (value); \
|
||||
bigint_set_bit_raw ( (value)->element, size, bit ); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* Clear bit in big integer
|
||||
*
|
||||
* @v value Big integer
|
||||
* @v bit Bit to set
|
||||
*/
|
||||
#define bigint_clear_bit( value, bit ) do { \
|
||||
unsigned int size = bigint_size (value); \
|
||||
bigint_clear_bit_raw ( (value)->element, size, bit ); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* Test if bit is set in big integer
|
||||
*
|
||||
|
@ -230,15 +265,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* Reduce big integer
|
||||
* Reduce big integer R^2 modulo N
|
||||
*
|
||||
* @v modulus Big integer modulus
|
||||
* @v value Big integer to be reduced
|
||||
* @v result Big integer to hold result
|
||||
*/
|
||||
#define bigint_reduce( modulus, value ) do { \
|
||||
unsigned int size = bigint_size (modulus); \
|
||||
bigint_reduce_raw ( (modulus)->element, \
|
||||
(value)->element, size ); \
|
||||
#define bigint_reduce( modulus, result ) do { \
|
||||
unsigned int size = bigint_size (modulus); \
|
||||
bigint_reduce_raw ( (modulus)->element, (result)->element, \
|
||||
size ); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
|
@ -254,20 +289,49 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* Perform Montgomery reduction (REDC) of a big integer product
|
||||
* Perform relaxed Montgomery reduction (REDC) of a big integer
|
||||
*
|
||||
* @v modulus Big integer modulus
|
||||
* @v modinv Big integer inverse of the modulus modulo 2^k
|
||||
* @v mont Big integer Montgomery product
|
||||
* @v modulus Big integer odd modulus
|
||||
* @v value Big integer to be reduced
|
||||
* @v result Big integer to hold result
|
||||
*
|
||||
* Note that the Montgomery product will be overwritten.
|
||||
* @ret carry Carry out
|
||||
*/
|
||||
#define bigint_montgomery( modulus, modinv, mont, result ) do { \
|
||||
#define bigint_montgomery_relaxed( modulus, value, result ) ( { \
|
||||
unsigned int size = bigint_size (modulus); \
|
||||
bigint_montgomery_raw ( (modulus)->element, (modinv)->element, \
|
||||
(mont)->element, (result)->element, \
|
||||
size ); \
|
||||
bigint_montgomery_relaxed_raw ( (modulus)->element, \
|
||||
(value)->element, \
|
||||
(result)->element, size ); \
|
||||
} )
|
||||
|
||||
/**
|
||||
* Perform classic Montgomery reduction (REDC) of a big integer
|
||||
*
|
||||
* @v modulus Big integer odd modulus
|
||||
* @v value Big integer to be reduced
|
||||
* @v result Big integer to hold result
|
||||
*/
|
||||
#define bigint_montgomery( modulus, value, result ) do { \
|
||||
unsigned int size = bigint_size (modulus); \
|
||||
bigint_montgomery_raw ( (modulus)->element, (value)->element, \
|
||||
(result)->element, size ); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* Perform generalised exponentiation via a Montgomery ladder
|
||||
*
|
||||
* @v result Big integer result (initialised to identity element)
|
||||
* @v multiple Big integer multiple (initialised to generator)
|
||||
* @v exponent Big integer exponent
|
||||
* @v op Montgomery ladder commutative operation
|
||||
* @v ctx Operation context (if needed)
|
||||
* @v tmp Temporary working space (if needed)
|
||||
*/
|
||||
#define bigint_ladder( result, multiple, exponent, op, ctx, tmp ) do { \
|
||||
unsigned int size = bigint_size (result); \
|
||||
unsigned int exponent_size = bigint_size (exponent); \
|
||||
bigint_ladder_raw ( (result)->element, (multiple)->element, \
|
||||
size, (exponent)->element, exponent_size, \
|
||||
(op), (ctx), (tmp) ); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
|
@ -301,6 +365,56 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
#include <bits/bigint.h>
|
||||
|
||||
/**
|
||||
* A big integer Montgomery ladder commutative operation
|
||||
*
|
||||
* @v operand Element 0 of first input operand (may overlap result)
|
||||
* @v result Element 0 of second input operand and result
|
||||
* @v size Number of elements in operands and result
|
||||
* @v ctx Operation context (if needed)
|
||||
* @v tmp Temporary working space (if needed)
|
||||
*/
|
||||
typedef void ( bigint_ladder_op_t ) ( const bigint_element_t *operand0,
|
||||
bigint_element_t *result0,
|
||||
unsigned int size, const void *ctx,
|
||||
void *tmp );
|
||||
|
||||
/**
|
||||
* Set bit in big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @v bit Bit to set
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_set_bit_raw ( bigint_element_t *value0, unsigned int size,
|
||||
unsigned int bit ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
|
||||
unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
|
||||
|
||||
value->element[index] |= ( 1UL << subindex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear bit in big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @v bit Bit to clear
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_clear_bit_raw ( bigint_element_t *value0, unsigned int size,
|
||||
unsigned int bit ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
|
||||
unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
|
||||
|
||||
value->element[index] &= ~( 1UL << subindex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if bit is set in big integer
|
||||
*
|
||||
|
@ -337,6 +451,8 @@ bigint_msb_is_set_raw ( const bigint_element_t *value0, unsigned int size ) {
|
|||
return ( !! ( value->element[index] & ( 1UL << subindex ) ) );
|
||||
}
|
||||
|
||||
const char * bigint_ntoa_raw ( const bigint_element_t *value0,
|
||||
unsigned int size );
|
||||
void bigint_init_raw ( bigint_element_t *value0, unsigned int size,
|
||||
const void *data, size_t len );
|
||||
void bigint_done_raw ( const bigint_element_t *value0, unsigned int size,
|
||||
|
@ -345,8 +461,8 @@ int bigint_add_raw ( const bigint_element_t *addend0,
|
|||
bigint_element_t *value0, unsigned int size );
|
||||
int bigint_subtract_raw ( const bigint_element_t *subtrahend0,
|
||||
bigint_element_t *value0, unsigned int size );
|
||||
void bigint_shl_raw ( bigint_element_t *value0, unsigned int size );
|
||||
void bigint_shr_raw ( bigint_element_t *value0, unsigned int size );
|
||||
int bigint_shl_raw ( bigint_element_t *value0, unsigned int size );
|
||||
int bigint_shr_raw ( bigint_element_t *value0, unsigned int size );
|
||||
int bigint_is_zero_raw ( const bigint_element_t *value0, unsigned int size );
|
||||
int bigint_is_geq_raw ( const bigint_element_t *value0,
|
||||
const bigint_element_t *reference0,
|
||||
|
@ -372,14 +488,25 @@ void bigint_multiply_raw ( const bigint_element_t *multiplicand0,
|
|||
const bigint_element_t *multiplier0,
|
||||
unsigned int multiplier_size,
|
||||
bigint_element_t *result0 );
|
||||
void bigint_reduce_raw ( bigint_element_t *modulus0, bigint_element_t *value0,
|
||||
unsigned int size );
|
||||
void bigint_reduce_raw ( const bigint_element_t *modulus0,
|
||||
bigint_element_t *result0, unsigned int size );
|
||||
void bigint_mod_invert_raw ( const bigint_element_t *invertend0,
|
||||
bigint_element_t *inverse0, unsigned int size );
|
||||
int bigint_montgomery_relaxed_raw ( const bigint_element_t *modulus0,
|
||||
bigint_element_t *value0,
|
||||
bigint_element_t *result0,
|
||||
unsigned int size );
|
||||
void bigint_montgomery_raw ( const bigint_element_t *modulus0,
|
||||
const bigint_element_t *modinv0,
|
||||
bigint_element_t *mont0,
|
||||
bigint_element_t *value0,
|
||||
bigint_element_t *result0, unsigned int size );
|
||||
void bigint_ladder_raw ( bigint_element_t *result0,
|
||||
bigint_element_t *multiple0, unsigned int size,
|
||||
const bigint_element_t *exponent0,
|
||||
unsigned int exponent_size, bigint_ladder_op_t *op,
|
||||
const void *ctx, void *tmp );
|
||||
void bigint_mod_exp_ladder ( const bigint_element_t *multiplier0,
|
||||
bigint_element_t *result0, unsigned int size,
|
||||
const void *ctx, void *tmp );
|
||||
void bigint_mod_exp_raw ( const bigint_element_t *base0,
|
||||
const bigint_element_t *modulus0,
|
||||
const bigint_element_t *exponent0,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/image.h>
|
||||
|
||||
/** A CPIO archive header
|
||||
|
@ -50,6 +51,12 @@ struct cpio_header {
|
|||
/** CPIO magic */
|
||||
#define CPIO_MAGIC "070701"
|
||||
|
||||
/** CPIO type for regular files */
|
||||
#define CPIO_MODE_FILE 0100000
|
||||
|
||||
/** CPIO type for directories */
|
||||
#define CPIO_MODE_DIR 0040000
|
||||
|
||||
/** CPIO header length alignment */
|
||||
#define CPIO_ALIGN 4
|
||||
|
||||
|
@ -67,8 +74,20 @@ cpio_name ( struct image *image ) {
|
|||
return image->cmdline;
|
||||
}
|
||||
|
||||
extern void cpio_set_field ( char *field, unsigned long value );
|
||||
extern size_t cpio_name_len ( struct image *image );
|
||||
extern size_t cpio_header ( struct image *image, struct cpio_header *cpio );
|
||||
/**
|
||||
* Get CPIO header zero-padding length
|
||||
*
|
||||
* @v len Length of CPIO header (including name, excluding NUL)
|
||||
* @ret pad_len Padding length
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) size_t
|
||||
cpio_pad_len ( size_t len ) {
|
||||
|
||||
/* Pad by at least one byte (for name's terminating NUL) */
|
||||
return ( CPIO_ALIGN - ( len % CPIO_ALIGN ) );
|
||||
}
|
||||
|
||||
extern size_t cpio_header ( struct image *image, unsigned int index,
|
||||
struct cpio_header *cpio );
|
||||
|
||||
#endif /* _IPXE_CPIO_H */
|
||||
|
|
|
@ -184,7 +184,9 @@ struct pubkey_algorithm {
|
|||
struct elliptic_curve {
|
||||
/** Curve name */
|
||||
const char *name;
|
||||
/** Key size */
|
||||
/** Point (and public key) size */
|
||||
size_t pointsize;
|
||||
/** Scalar (and private key) size */
|
||||
size_t keysize;
|
||||
/** Multiply scalar by curve point
|
||||
*
|
||||
|
|
|
@ -9,8 +9,13 @@
|
|||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/asn1.h>
|
||||
#include <ipxe/image.h>
|
||||
|
||||
extern int der_asn1 ( userptr_t data, size_t len, size_t offset,
|
||||
struct asn1_cursor **cursor );
|
||||
|
||||
extern struct image_type der_image_type __image_type ( PROBE_NORMAL );
|
||||
|
||||
#endif /* _IPXE_DER_H */
|
||||
|
|
|
@ -60,7 +60,8 @@ extern struct dynamic_item * dynui_item ( struct dynamic_ui *dynui,
|
|||
extern struct dynamic_item * dynui_shortcut ( struct dynamic_ui *dynui,
|
||||
int key );
|
||||
extern int show_menu ( struct dynamic_ui *dynui, unsigned long timeout,
|
||||
const char *select, struct dynamic_item **selected );
|
||||
unsigned long retimeout, const char *select,
|
||||
struct dynamic_item **selected );
|
||||
extern int show_form ( struct dynamic_ui *dynui );
|
||||
|
||||
#endif /* _IPXE_DYNUI_H */
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef _IPXE_ECDHE_H
|
||||
#define _IPXE_ECDHE_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Elliptic Curve Ephemeral Diffie-Hellman (ECDHE) key exchange
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/crypto.h>
|
||||
|
||||
extern int ecdhe_key ( struct elliptic_curve *curve, const void *partner,
|
||||
const void *private, void *public, void *shared );
|
||||
|
||||
#endif /* _IPXE_ECDHE_H */
|
|
@ -61,7 +61,7 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
/// up to the compiler to remove any code past that point.
|
||||
///
|
||||
#define UNREACHABLE() __builtin_unreachable ()
|
||||
#elif defined (__has_feature)
|
||||
#elif defined (__has_builtin) && defined (__has_feature)
|
||||
#if __has_builtin (__builtin_unreachable)
|
||||
///
|
||||
/// Signal compilers and analyzers that this call is not reachable. It is
|
||||
|
@ -802,12 +802,12 @@ typedef UINTN *BASE_LIST;
|
|||
@param Message Raised compiler diagnostic message when expression is false.
|
||||
|
||||
**/
|
||||
#ifdef MDE_CPU_EBC
|
||||
#define STATIC_ASSERT(Expression, Message)
|
||||
#elif defined (_MSC_EXTENSIONS) || defined (__cplusplus)
|
||||
#if defined (__cplusplus)
|
||||
#define STATIC_ASSERT static_assert
|
||||
#else
|
||||
#elif defined (__GNUC__) || defined (__clang__)
|
||||
#define STATIC_ASSERT _Static_assert
|
||||
#elif defined (_MSC_EXTENSIONS)
|
||||
#define STATIC_ASSERT static_assert
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -890,7 +890,7 @@ STATIC_ASSERT (ALIGNOF (__VERIFY_INT32_ENUM_SIZE) == sizeof (__VERIFY_INT32_ENUM
|
|||
@return A pointer to the structure from one of it's elements.
|
||||
|
||||
**/
|
||||
#define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field)))
|
||||
#define BASE_CR(Record, TYPE, Field) ((TYPE *) (VOID *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field)))
|
||||
|
||||
/**
|
||||
Checks whether a value is a power of two.
|
||||
|
@ -1060,7 +1060,7 @@ typedef UINTN RETURN_STATUS;
|
|||
@retval FALSE The high bit of StatusCode is clear.
|
||||
|
||||
**/
|
||||
#define RETURN_ERROR(StatusCode) (((INTN)(RETURN_STATUS)(StatusCode)) < 0)
|
||||
#define RETURN_ERROR(StatusCode) (((RETURN_STATUS)(StatusCode)) >= MAX_BIT)
|
||||
|
||||
///
|
||||
/// The operation completed successfully.
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
/** @file
|
||||
GUID for EFI (NVRAM) Variables.
|
||||
|
||||
Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Revision Reference:
|
||||
GUID defined in UEFI 2.1
|
||||
**/
|
||||
|
||||
#ifndef __GLOBAL_VARIABLE_GUID_H__
|
||||
#define __GLOBAL_VARIABLE_GUID_H__
|
||||
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
#define EFI_GLOBAL_VARIABLE \
|
||||
{ \
|
||||
0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } \
|
||||
}
|
||||
|
||||
extern EFI_GUID gEfiGlobalVariableGuid;
|
||||
|
||||
//
|
||||
// Follow UEFI 2.4 spec:
|
||||
// To prevent name collisions with possible future globally defined variables,
|
||||
// other internal firmware data variables that are not defined here must be
|
||||
// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
|
||||
// any other GUID defined by the UEFI Specification. Implementations must
|
||||
// only permit the creation of variables with a UEFI Specification-defined
|
||||
// VendorGuid when these variables are documented in the UEFI Specification.
|
||||
//
|
||||
// Note: except the globally defined variables defined below, the spec also defines
|
||||
// L"Boot####" - A boot load option.
|
||||
// L"Driver####" - A driver load option.
|
||||
// L"SysPrep####" - A System Prep application load option.
|
||||
// L"Key####" - Describes hot key relationship with a Boot#### load option.
|
||||
// The attribute for them is NV+BS+RT, #### is a printed hex value, and no 0x or h
|
||||
// is included in the hex value. They can not be expressed as a #define like other globally
|
||||
// defined variables, it is because we can not list the Boot0000, Boot0001, etc one by one.
|
||||
//
|
||||
|
||||
///
|
||||
/// The language codes that the firmware supports. This value is deprecated.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_LANG_CODES_VARIABLE_NAME L"LangCodes"
|
||||
///
|
||||
/// The language code that the system is configured for. This value is deprecated.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_LANG_VARIABLE_NAME L"Lang"
|
||||
///
|
||||
/// The firmware's boot managers timeout, in seconds, before initiating the default boot selection.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_TIME_OUT_VARIABLE_NAME L"Timeout"
|
||||
///
|
||||
/// The language codes that the firmware supports.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_PLATFORM_LANG_CODES_VARIABLE_NAME L"PlatformLangCodes"
|
||||
///
|
||||
/// The language code that the system is configured for.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_PLATFORM_LANG_VARIABLE_NAME L"PlatformLang"
|
||||
///
|
||||
/// The device path of the default input/output/error output console.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_CON_IN_VARIABLE_NAME L"ConIn"
|
||||
#define EFI_CON_OUT_VARIABLE_NAME L"ConOut"
|
||||
#define EFI_ERR_OUT_VARIABLE_NAME L"ErrOut"
|
||||
///
|
||||
/// The device path of all possible input/output/error output devices.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_CON_IN_DEV_VARIABLE_NAME L"ConInDev"
|
||||
#define EFI_CON_OUT_DEV_VARIABLE_NAME L"ConOutDev"
|
||||
#define EFI_ERR_OUT_DEV_VARIABLE_NAME L"ErrOutDev"
|
||||
///
|
||||
/// The ordered boot option load list.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_BOOT_ORDER_VARIABLE_NAME L"BootOrder"
|
||||
///
|
||||
/// The boot option for the next boot only.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_BOOT_NEXT_VARIABLE_NAME L"BootNext"
|
||||
///
|
||||
/// The boot option that was selected for the current boot.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_BOOT_CURRENT_VARIABLE_NAME L"BootCurrent"
|
||||
///
|
||||
/// The types of boot options supported by the boot manager. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME L"BootOptionSupport"
|
||||
///
|
||||
/// The ordered driver load option list.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_DRIVER_ORDER_VARIABLE_NAME L"DriverOrder"
|
||||
///
|
||||
/// The ordered System Prep Application load option list.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_SYS_PREP_ORDER_VARIABLE_NAME L"SysPrepOrder"
|
||||
///
|
||||
/// Identifies the level of hardware error record persistence
|
||||
/// support implemented by the platform. This variable is
|
||||
/// only modified by firmware and is read-only to the OS.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME L"HwErrRecSupport"
|
||||
///
|
||||
/// Whether the system is operating in setup mode (1) or not (0).
|
||||
/// All other values are reserved. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_SETUP_MODE_NAME L"SetupMode"
|
||||
///
|
||||
/// The Key Exchange Key Signature Database.
|
||||
/// Its attribute is NV+BS+RT+AT.
|
||||
///
|
||||
#define EFI_KEY_EXCHANGE_KEY_NAME L"KEK"
|
||||
///
|
||||
/// The public Platform Key.
|
||||
/// Its attribute is NV+BS+RT+AT.
|
||||
///
|
||||
#define EFI_PLATFORM_KEY_NAME L"PK"
|
||||
///
|
||||
/// Array of GUIDs representing the type of signatures supported
|
||||
/// by the platform firmware. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_SIGNATURE_SUPPORT_NAME L"SignatureSupport"
|
||||
///
|
||||
/// Whether the platform firmware is operating in Secure boot mode (1) or not (0).
|
||||
/// All other values are reserved. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot"
|
||||
///
|
||||
/// The OEM's default Key Exchange Key Signature Database. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_KEK_DEFAULT_VARIABLE_NAME L"KEKDefault"
|
||||
///
|
||||
/// The OEM's default public Platform Key. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_PK_DEFAULT_VARIABLE_NAME L"PKDefault"
|
||||
///
|
||||
/// The OEM's default secure boot signature store. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_DB_DEFAULT_VARIABLE_NAME L"dbDefault"
|
||||
///
|
||||
/// The OEM's default secure boot blacklist signature store. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_DBX_DEFAULT_VARIABLE_NAME L"dbxDefault"
|
||||
///
|
||||
/// The OEM's default secure boot timestamp signature store. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_DBT_DEFAULT_VARIABLE_NAME L"dbtDefault"
|
||||
///
|
||||
/// Allows the firmware to indicate supported features and actions to the OS.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME L"OsIndicationsSupported"
|
||||
///
|
||||
/// Allows the OS to request the firmware to enable certain features and to take certain actions.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_OS_INDICATIONS_VARIABLE_NAME L"OsIndications"
|
||||
///
|
||||
/// Whether the system is configured to use only vendor provided
|
||||
/// keys or not. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_VENDOR_KEYS_VARIABLE_NAME L"VendorKeys"
|
||||
|
||||
///
|
||||
/// Whether the platform firmware is operating in device authentication boot mode (1) or not (0).
|
||||
/// The content is UINT8.
|
||||
///
|
||||
#define EFI_DEVICE_AUTH_BOOT_MODE_NAME L"devAuthBoot"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,387 @@
|
|||
/** @file
|
||||
Image signature database are defined for the signed image validation.
|
||||
|
||||
Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Revision Reference:
|
||||
GUIDs defined in UEFI 2.5 spec.
|
||||
**/
|
||||
|
||||
#ifndef __IMAGE_AUTHTICATION_H__
|
||||
#define __IMAGE_AUTHTICATION_H__
|
||||
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
#include <ipxe/efi/Guid/GlobalVariable.h>
|
||||
#include <ipxe/efi/Protocol/Hash.h>
|
||||
|
||||
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
|
||||
{ \
|
||||
0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0xe, 0x67, 0x65, 0x6f } \
|
||||
}
|
||||
|
||||
///
|
||||
/// Varialbe name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
|
||||
/// for the authorized signature database.
|
||||
///
|
||||
#define EFI_IMAGE_SECURITY_DATABASE L"db"
|
||||
///
|
||||
/// Varialbe name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
|
||||
/// for the forbidden signature database.
|
||||
///
|
||||
#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx"
|
||||
///
|
||||
/// Variable name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
|
||||
/// for the timestamp signature database.
|
||||
///
|
||||
#define EFI_IMAGE_SECURITY_DATABASE2 L"dbt"
|
||||
|
||||
#define SECURE_BOOT_MODE_ENABLE 1
|
||||
#define SECURE_BOOT_MODE_DISABLE 0
|
||||
|
||||
#define SETUP_MODE 1
|
||||
#define USER_MODE 0
|
||||
|
||||
#define DEVICE_AUTH_BOOT_MODE_ENABLE 1
|
||||
#define DEVICE_AUTH_BOOT_MODE_DISABLE 0
|
||||
|
||||
// ***********************************************************************
|
||||
// Signature Database
|
||||
// ***********************************************************************
|
||||
///
|
||||
/// The format of a signature database.
|
||||
///
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
///
|
||||
/// An identifier which identifies the agent which added the signature to the list.
|
||||
///
|
||||
EFI_GUID SignatureOwner;
|
||||
///
|
||||
/// The format of the signature is defined by the SignatureType.
|
||||
///
|
||||
UINT8 SignatureData[1];
|
||||
} EFI_SIGNATURE_DATA;
|
||||
|
||||
typedef struct {
|
||||
///
|
||||
/// Type of the signature. GUID signature types are defined in below.
|
||||
///
|
||||
EFI_GUID SignatureType;
|
||||
///
|
||||
/// Total size of the signature list, including this header.
|
||||
///
|
||||
UINT32 SignatureListSize;
|
||||
///
|
||||
/// Size of the signature header which precedes the array of signatures.
|
||||
///
|
||||
UINT32 SignatureHeaderSize;
|
||||
///
|
||||
/// Size of each signature.
|
||||
///
|
||||
UINT32 SignatureSize;
|
||||
///
|
||||
/// Header before the array of signatures. The format of this header is specified
|
||||
/// by the SignatureType.
|
||||
/// UINT8 SignatureHeader[SignatureHeaderSize];
|
||||
///
|
||||
/// An array of signatures. Each signature is SignatureSize bytes in length.
|
||||
/// EFI_SIGNATURE_DATA Signatures[][SignatureSize];
|
||||
///
|
||||
} EFI_SIGNATURE_LIST;
|
||||
|
||||
typedef struct {
|
||||
///
|
||||
/// The SHA256 hash of an X.509 certificate's To-Be-Signed contents.
|
||||
///
|
||||
EFI_SHA256_HASH ToBeSignedHash;
|
||||
///
|
||||
/// The time that the certificate shall be considered to be revoked.
|
||||
///
|
||||
EFI_TIME TimeOfRevocation;
|
||||
} EFI_CERT_X509_SHA256;
|
||||
|
||||
typedef struct {
|
||||
///
|
||||
/// The SHA384 hash of an X.509 certificate's To-Be-Signed contents.
|
||||
///
|
||||
EFI_SHA384_HASH ToBeSignedHash;
|
||||
///
|
||||
/// The time that the certificate shall be considered to be revoked.
|
||||
///
|
||||
EFI_TIME TimeOfRevocation;
|
||||
} EFI_CERT_X509_SHA384;
|
||||
|
||||
typedef struct {
|
||||
///
|
||||
/// The SHA512 hash of an X.509 certificate's To-Be-Signed contents.
|
||||
///
|
||||
EFI_SHA512_HASH ToBeSignedHash;
|
||||
///
|
||||
/// The time that the certificate shall be considered to be revoked.
|
||||
///
|
||||
EFI_TIME TimeOfRevocation;
|
||||
} EFI_CERT_X509_SHA512;
|
||||
|
||||
typedef UINT8 EFI_SM3_HASH[32];
|
||||
|
||||
typedef struct {
|
||||
///
|
||||
/// The SM3 hash of an X.509 certificate's To-Be-Signed contents.
|
||||
///
|
||||
EFI_SM3_HASH ToBeSignedHash;
|
||||
///
|
||||
/// The time that the certificate shall be considered to be revoked.
|
||||
///
|
||||
EFI_TIME TimeOfRevocation;
|
||||
} EFI_CERT_X509_SM3;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
///
|
||||
/// This identifies a signature containing a SHA-256 hash. The SignatureHeader size shall
|
||||
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
|
||||
/// 32 bytes.
|
||||
///
|
||||
#define EFI_CERT_SHA256_GUID \
|
||||
{ \
|
||||
0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing an RSA-2048 key. The key (only the modulus
|
||||
/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
|
||||
/// order.
|
||||
/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
|
||||
/// of SignatureOwner component) + 256 bytes.
|
||||
///
|
||||
#define EFI_CERT_RSA2048_GUID \
|
||||
{ \
|
||||
0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing a RSA-2048 signature of a SHA-256 hash. The
|
||||
/// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
|
||||
/// SignatureOwner component) + 256 bytes.
|
||||
///
|
||||
#define EFI_CERT_RSA2048_SHA256_GUID \
|
||||
{ \
|
||||
0xe2b36190, 0x879b, 0x4a3d, {0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing a SHA-1 hash. The SignatureSize shall always
|
||||
/// be 16 (size of SignatureOwner component) + 20 bytes.
|
||||
///
|
||||
#define EFI_CERT_SHA1_GUID \
|
||||
{ \
|
||||
0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing a SM3 hash. The SignatureSize shall always
|
||||
/// be 16 (size of SignatureOwner component) + 32 bytes.
|
||||
///
|
||||
#define EFI_CERT_SM3_GUID \
|
||||
{ \
|
||||
0x57347f87, 0x7a9b, 0x403a, { 0xb9, 0x3c, 0xdc, 0x4a, 0xfb, 0x7a, 0xe, 0xbc } \
|
||||
}
|
||||
|
||||
///
|
||||
/// TThis identifies a signature containing a RSA-2048 signature of a SHA-1 hash. The
|
||||
/// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
|
||||
/// SignatureOwner component) + 256 bytes.
|
||||
///
|
||||
#define EFI_CERT_RSA2048_SHA1_GUID \
|
||||
{ \
|
||||
0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature based on an X.509 certificate. If the signature is an X.509
|
||||
/// certificate then verification of the signature of an image should validate the public
|
||||
/// key certificate in the image using certificate path verification, up to this X.509
|
||||
/// certificate as a trusted root. The SignatureHeader size shall always be 0. The
|
||||
/// SignatureSize may vary but shall always be 16 (size of the SignatureOwner component) +
|
||||
/// the size of the certificate itself.
|
||||
/// Note: This means that each certificate will normally be in a separate EFI_SIGNATURE_LIST.
|
||||
///
|
||||
#define EFI_CERT_X509_GUID \
|
||||
{ \
|
||||
0xa5c059a1, 0x94e4, 0x4aa7, {0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing the SM3 hash of an X.509 certificate's To-Be-Signed
|
||||
/// contents, and a time of revocation. The SignatureHeader size shall always be 0. The
|
||||
/// SignatureSize shall always be 16 (size of the SignatureOwner component) + 32 bytes for
|
||||
/// an EFI_CERT_X509_SM3 structure. If the TimeOfRevocation is non-zero, the certificate should
|
||||
/// be considered to be revoked from that time and onwards, and otherwise the certificate shall
|
||||
/// be considered to always be revoked.
|
||||
///
|
||||
#define EFI_CERT_X509_SM3_GUID \
|
||||
{ \
|
||||
0x60d807e5, 0x10b4, 0x49a9, {0x93, 0x31, 0xe4, 0x4, 0x37, 0x88, 0x8d, 0x37 } \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing a SHA-224 hash. The SignatureHeader size shall
|
||||
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
|
||||
/// 28 bytes.
|
||||
///
|
||||
#define EFI_CERT_SHA224_GUID \
|
||||
{ \
|
||||
0xb6e5233, 0xa65c, 0x44c9, {0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing a SHA-384 hash. The SignatureHeader size shall
|
||||
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
|
||||
/// 48 bytes.
|
||||
///
|
||||
#define EFI_CERT_SHA384_GUID \
|
||||
{ \
|
||||
0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing a SHA-512 hash. The SignatureHeader size shall
|
||||
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
|
||||
/// 64 bytes.
|
||||
///
|
||||
#define EFI_CERT_SHA512_GUID \
|
||||
{ \
|
||||
0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a} \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing the SHA256 hash of an X.509 certificate's
|
||||
/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
|
||||
/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
|
||||
/// + 48 bytes for an EFI_CERT_X509_SHA256 structure. If the TimeOfRevocation is non-zero,
|
||||
/// the certificate should be considered to be revoked from that time and onwards, and
|
||||
/// otherwise the certificate shall be considered to always be revoked.
|
||||
///
|
||||
#define EFI_CERT_X509_SHA256_GUID \
|
||||
{ \
|
||||
0x3bd2a492, 0x96c0, 0x4079, {0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed } \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing the SHA384 hash of an X.509 certificate's
|
||||
/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
|
||||
/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
|
||||
/// + 64 bytes for an EFI_CERT_X509_SHA384 structure. If the TimeOfRevocation is non-zero,
|
||||
/// the certificate should be considered to be revoked from that time and onwards, and
|
||||
/// otherwise the certificate shall be considered to always be revoked.
|
||||
///
|
||||
#define EFI_CERT_X509_SHA384_GUID \
|
||||
{ \
|
||||
0x7076876e, 0x80c2, 0x4ee6, {0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b } \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing the SHA512 hash of an X.509 certificate's
|
||||
/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
|
||||
/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
|
||||
/// + 80 bytes for an EFI_CERT_X509_SHA512 structure. If the TimeOfRevocation is non-zero,
|
||||
/// the certificate should be considered to be revoked from that time and onwards, and
|
||||
/// otherwise the certificate shall be considered to always be revoked.
|
||||
///
|
||||
#define EFI_CERT_X509_SHA512_GUID \
|
||||
{ \
|
||||
0x446dbf63, 0x2502, 0x4cda, {0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d } \
|
||||
}
|
||||
|
||||
///
|
||||
/// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
|
||||
/// SignedData value.
|
||||
///
|
||||
#define EFI_CERT_TYPE_PKCS7_GUID \
|
||||
{ \
|
||||
0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
|
||||
}
|
||||
|
||||
// ***********************************************************************
|
||||
// Image Execution Information Table Definition
|
||||
// ***********************************************************************
|
||||
typedef UINT32 EFI_IMAGE_EXECUTION_ACTION;
|
||||
|
||||
#define EFI_IMAGE_EXECUTION_AUTHENTICATION 0x00000007
|
||||
#define EFI_IMAGE_EXECUTION_AUTH_UNTESTED 0x00000000
|
||||
#define EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED 0x00000001
|
||||
#define EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED 0x00000002
|
||||
#define EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND 0x00000003
|
||||
#define EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND 0x00000004
|
||||
#define EFI_IMAGE_EXECUTION_POLICY_FAILED 0x00000005
|
||||
#define EFI_IMAGE_EXECUTION_INITIALIZED 0x00000008
|
||||
|
||||
//
|
||||
// EFI_IMAGE_EXECUTION_INFO is added to EFI System Configuration Table
|
||||
// and assigned the GUID EFI_IMAGE_SECURITY_DATABASE_GUID.
|
||||
//
|
||||
typedef struct {
|
||||
///
|
||||
/// Describes the action taken by the firmware regarding this image.
|
||||
///
|
||||
EFI_IMAGE_EXECUTION_ACTION Action;
|
||||
///
|
||||
/// Size of all of the entire structure.
|
||||
///
|
||||
UINT32 InfoSize;
|
||||
///
|
||||
/// If this image was a UEFI device driver (for option ROM, for example) this is the
|
||||
/// null-terminated, user-friendly name for the device. If the image was for an application,
|
||||
/// then this is the name of the application. If this cannot be determined, then a simple
|
||||
/// NULL character should be put in this position.
|
||||
/// CHAR16 Name[];
|
||||
///
|
||||
|
||||
///
|
||||
/// For device drivers, this is the device path of the device for which this device driver
|
||||
/// was intended. In some cases, the driver itself may be stored as part of the system
|
||||
/// firmware, but this field should record the device's path, not the firmware path. For
|
||||
/// applications, this is the device path of the application. If this cannot be determined,
|
||||
/// a simple end-of-path device node should be put in this position.
|
||||
/// EFI_DEVICE_PATH_PROTOCOL DevicePath;
|
||||
///
|
||||
|
||||
///
|
||||
/// Zero or more image signatures. If the image contained no signatures,
|
||||
/// then this field is empty.
|
||||
/// EFI_SIGNATURE_LIST Signature;
|
||||
///
|
||||
} EFI_IMAGE_EXECUTION_INFO;
|
||||
|
||||
typedef struct {
|
||||
///
|
||||
/// Number of EFI_IMAGE_EXECUTION_INFO structures.
|
||||
///
|
||||
UINTN NumberOfImages;
|
||||
///
|
||||
/// Number of image instances of EFI_IMAGE_EXECUTION_INFO structures.
|
||||
///
|
||||
// EFI_IMAGE_EXECUTION_INFO InformationInfo[]
|
||||
} EFI_IMAGE_EXECUTION_INFO_TABLE;
|
||||
|
||||
extern EFI_GUID gEfiImageSecurityDatabaseGuid;
|
||||
extern EFI_GUID gEfiCertSha256Guid;
|
||||
extern EFI_GUID gEfiCertRsa2048Guid;
|
||||
extern EFI_GUID gEfiCertRsa2048Sha256Guid;
|
||||
extern EFI_GUID gEfiCertSha1Guid;
|
||||
extern EFI_GUID gEfiCertRsa2048Sha1Guid;
|
||||
extern EFI_GUID gEfiCertX509Guid;
|
||||
extern EFI_GUID gEfiCertSha224Guid;
|
||||
extern EFI_GUID gEfiCertSha384Guid;
|
||||
extern EFI_GUID gEfiCertSha512Guid;
|
||||
extern EFI_GUID gEfiCertX509Sha256Guid;
|
||||
extern EFI_GUID gEfiCertX509Sha384Guid;
|
||||
extern EFI_GUID gEfiCertX509Sha512Guid;
|
||||
extern EFI_GUID gEfiCertPkcs7Guid;
|
||||
extern EFI_GUID gEfiCertSm3Guid;
|
||||
extern EFI_GUID gEfiCertX509Sm3Guid;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,157 @@
|
|||
/** @file
|
||||
Random Number Generator (RNG) GUIDs and structures shared across RNG interfaces.
|
||||
|
||||
Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) Microsoft Corporation.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef RNG_GUID_H_
|
||||
#define RNG_GUID_H_
|
||||
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
typedef struct _EFI_RNG_INTERFACE EFI_RNG_INTERFACE;
|
||||
|
||||
///
|
||||
/// A selection of EFI_RNG_PROTOCOL algorithms.
|
||||
/// The algorithms listed are optional, not meant to be exhaustive and be argmented by
|
||||
/// vendors or other industry standards.
|
||||
///
|
||||
typedef EFI_GUID EFI_RNG_ALGORITHM;
|
||||
|
||||
///
|
||||
/// The algorithms corresponds to SP800-90 as defined in
|
||||
/// NIST SP 800-90, "Recommendation for Random Number Generation Using Deterministic Random
|
||||
/// Bit Generators", March 2007.
|
||||
///
|
||||
#define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \
|
||||
{ \
|
||||
0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 } \
|
||||
}
|
||||
#define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \
|
||||
{ \
|
||||
0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 } \
|
||||
}
|
||||
#define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \
|
||||
{ \
|
||||
0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e } \
|
||||
}
|
||||
|
||||
///
|
||||
/// The algorithms correspond to X9.31 as defined in
|
||||
/// NIST, "Recommended Random Number Generator Based on ANSI X9.31 Appendix A.2.4 Using
|
||||
/// the 3-Key Triple DES and AES Algorithm", January 2005.
|
||||
///
|
||||
#define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \
|
||||
{ \
|
||||
0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 } \
|
||||
}
|
||||
#define EFI_RNG_ALGORITHM_X9_31_AES_GUID \
|
||||
{ \
|
||||
0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 } \
|
||||
}
|
||||
|
||||
///
|
||||
/// The "raw" algorithm, when supported, is intended to provide entropy directly from
|
||||
/// the source, without it going through some deterministic random bit generator.
|
||||
///
|
||||
#define EFI_RNG_ALGORITHM_RAW \
|
||||
{ \
|
||||
0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 } \
|
||||
}
|
||||
|
||||
///
|
||||
/// The Arm Architecture states the RNDR that the DRBG algorithm should be compliant
|
||||
/// with NIST SP800-90A, while not mandating a particular algorithm, so as to be
|
||||
/// inclusive of different geographies.
|
||||
///
|
||||
#define EFI_RNG_ALGORITHM_ARM_RNDR \
|
||||
{ \
|
||||
0x43d2fde3, 0x9d4e, 0x4d79, {0x02, 0x96, 0xa8, 0x9b, 0xca, 0x78, 0x08, 0x41} \
|
||||
}
|
||||
|
||||
/**
|
||||
Returns information about the random number generation implementation.
|
||||
|
||||
@param[in] This A pointer to this interface instance.
|
||||
@param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
|
||||
On output with a return code of EFI_SUCCESS, the size
|
||||
in bytes of the data returned in RNGAlgorithmList. On output
|
||||
with a return code of EFI_BUFFER_TOO_SMALL,
|
||||
the size of RNGAlgorithmList required to obtain the list.
|
||||
@param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
|
||||
with one EFI_RNG_ALGORITHM element for each supported
|
||||
RNG algorithm. The list must not change across multiple
|
||||
calls to the same driver. The first algorithm in the list
|
||||
is the default algorithm for the driver.
|
||||
|
||||
@retval EFI_SUCCESS The RNG algorithm list was returned successfully.
|
||||
@retval EFI_UNSUPPORTED The services is not supported by this driver.
|
||||
@retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
|
||||
hardware or firmware error.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
|
||||
@retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_RNG_GET_INFO)(
|
||||
IN EFI_RNG_INTERFACE *This,
|
||||
IN OUT UINTN *RNGAlgorithmListSize,
|
||||
OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
|
||||
);
|
||||
|
||||
/**
|
||||
Produces and returns an RNG value using either the default or specified RNG algorithm.
|
||||
|
||||
@param[in] This A pointer to this interface instance.
|
||||
@param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
|
||||
algorithm to use. May be NULL in which case the function will
|
||||
use its default RNG algorithm.
|
||||
@param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
|
||||
RNGValue. The driver shall return exactly this numbers of bytes.
|
||||
@param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
|
||||
resulting RNG value.
|
||||
|
||||
@retval EFI_SUCCESS The RNG value was returned successfully.
|
||||
@retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
|
||||
this driver.
|
||||
@retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
|
||||
firmware error.
|
||||
@retval EFI_NOT_READY There is not enough random data available to satisfy the length
|
||||
requested by RNGValueLength.
|
||||
@retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_RNG_GET_RNG)(
|
||||
IN EFI_RNG_INTERFACE *This,
|
||||
IN EFI_RNG_ALGORITHM *RNGAlgorithm OPTIONAL,
|
||||
IN UINTN RNGValueLength,
|
||||
OUT UINT8 *RNGValue
|
||||
);
|
||||
|
||||
///
|
||||
/// The Random Number Generator (RNG) interface provides random bits for use in
|
||||
/// applications, or entropy for seeding other random number generators.
|
||||
///
|
||||
/// This interface is shared between the RNG Protocol defined in the UEFI 2.4 Specification
|
||||
/// and the RNG PPI defined in the PI 1.9 Specification.
|
||||
///
|
||||
struct _EFI_RNG_INTERFACE {
|
||||
EFI_RNG_GET_INFO GetInfo;
|
||||
EFI_RNG_GET_RNG GetRNG;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid;
|
||||
extern EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid;
|
||||
extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid;
|
||||
extern EFI_GUID gEfiRngAlgorithmX9313DesGuid;
|
||||
extern EFI_GUID gEfiRngAlgorithmX931AesGuid;
|
||||
extern EFI_GUID gEfiRngAlgorithmRaw;
|
||||
extern EFI_GUID gEfiRngAlgorithmArmRndr;
|
||||
|
||||
#endif // #ifndef RNG_GUID_H_
|
|
@ -0,0 +1,25 @@
|
|||
/** @file
|
||||
This file defines TlsCaCertificate variable.
|
||||
|
||||
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __TLS_AUTHENTICATION_H__
|
||||
#define __TLS_AUTHENTICATION_H__
|
||||
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
// Private variable for CA Certificate configuration
|
||||
//
|
||||
#define EFI_TLS_CA_CERTIFICATE_GUID \
|
||||
{ \
|
||||
0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae } \
|
||||
}
|
||||
|
||||
#define EFI_TLS_CA_CERTIFICATE_VARIABLE L"TlsCaCertificate"
|
||||
|
||||
extern EFI_GUID gEfiTlsCaCertificateGuid;
|
||||
|
||||
#endif
|
|
@ -2,6 +2,7 @@
|
|||
ACPI 3.0 definitions from the ACPI Specification Revision 3.0b October 10, 2006
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
|
@ -12,6 +13,16 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
|
||||
#include <ipxe/efi/IndustryStandard/Acpi20.h>
|
||||
|
||||
///
|
||||
/// _CSD Revision for ACPI 3.0
|
||||
///
|
||||
#define EFI_ACPI_3_0_AML_CSD_REVISION 0
|
||||
|
||||
///
|
||||
/// _CSD NumEntries for ACPI 3.0
|
||||
///
|
||||
#define EFI_ACPI_3_0_AML_CSD_NUM_ENTRIES 6
|
||||
|
||||
//
|
||||
// Define for Descriptor
|
||||
//
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
ACPI 4.0 definitions from the ACPI Specification Revision 4.0a April 5, 2010
|
||||
|
||||
Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
|
@ -12,6 +13,16 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
|
||||
#include <ipxe/efi/IndustryStandard/Acpi30.h>
|
||||
|
||||
///
|
||||
/// _CSD Revision for ACPI 4.0
|
||||
///
|
||||
#define EFI_ACPI_4_0_AML_CSD_REVISION 0
|
||||
|
||||
///
|
||||
/// _CSD NumEntries for ACPI 4.0
|
||||
///
|
||||
#define EFI_ACPI_4_0_AML_CSD_NUM_ENTRIES 6
|
||||
|
||||
///
|
||||
/// _PSD Revision for ACPI 4.0
|
||||
///
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
|
||||
Copyright (c) 2011 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
|
@ -14,6 +15,16 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
|
||||
#include <ipxe/efi/IndustryStandard/Acpi40.h>
|
||||
|
||||
///
|
||||
/// _CSD Revision for ACPI 5.0
|
||||
///
|
||||
#define EFI_ACPI_5_0_AML_CSD_REVISION 0
|
||||
|
||||
///
|
||||
/// _CSD NumEntries for ACPI 5.0
|
||||
///
|
||||
#define EFI_ACPI_5_0_AML_CSD_NUM_ENTRIES 6
|
||||
|
||||
//
|
||||
// Define for Descriptor
|
||||
//
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
|
||||
Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
|
@ -15,6 +16,16 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
|
||||
#include <ipxe/efi/IndustryStandard/Acpi50.h>
|
||||
|
||||
///
|
||||
/// _CSD Revision for ACPI 5.1
|
||||
///
|
||||
#define EFI_ACPI_5_1_AML_CSD_REVISION 0
|
||||
|
||||
///
|
||||
/// _CSD NumEntries for ACPI 5.1
|
||||
///
|
||||
#define EFI_ACPI_5_1_AML_CSD_NUM_ENTRIES 6
|
||||
|
||||
///
|
||||
/// _PSD Revision for ACPI 5.1
|
||||
///
|
||||
|
@ -1762,6 +1773,7 @@ typedef struct {
|
|||
#define EFI_ACPI_5_1_EINJ_EXECUTE_OPERATION 0x05
|
||||
#define EFI_ACPI_5_1_EINJ_CHECK_BUSY_STATUS 0x06
|
||||
#define EFI_ACPI_5_1_EINJ_GET_COMMAND_STATUS 0x07
|
||||
#define EFI_ACPI_5_1_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
|
||||
#define EFI_ACPI_5_1_EINJ_TRIGGER_ERROR 0xFF
|
||||
|
||||
///
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Copyright (c) 2015 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
|
||||
Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (C) 2025, Advanced Micro Devices, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
|
@ -14,6 +15,16 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
|
||||
#include <ipxe/efi/IndustryStandard/Acpi51.h>
|
||||
|
||||
///
|
||||
/// _CSD Revision for ACPI 6.0
|
||||
///
|
||||
#define EFI_ACPI_6_0_AML_CSD_REVISION 0
|
||||
|
||||
///
|
||||
/// _CSD NumEntries for ACPI 6.0
|
||||
///
|
||||
#define EFI_ACPI_6_0_AML_CSD_NUM_ENTRIES 6
|
||||
|
||||
///
|
||||
/// _PSD Revision for ACPI 6.0
|
||||
///
|
||||
|
@ -1949,6 +1960,7 @@ typedef struct {
|
|||
#define EFI_ACPI_6_0_EINJ_EXECUTE_OPERATION 0x05
|
||||
#define EFI_ACPI_6_0_EINJ_CHECK_BUSY_STATUS 0x06
|
||||
#define EFI_ACPI_6_0_EINJ_GET_COMMAND_STATUS 0x07
|
||||
#define EFI_ACPI_6_0_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
|
||||
#define EFI_ACPI_6_0_EINJ_TRIGGER_ERROR 0xFF
|
||||
|
||||
///
|
||||
|
|
|
@ -746,8 +746,8 @@ typedef struct tdTPM_PERMANENT_FLAGS {
|
|||
BOOLEAN TPMpost;
|
||||
BOOLEAN TPMpostLock;
|
||||
BOOLEAN FIPS;
|
||||
BOOLEAN operator;
|
||||
BOOLEAN enableRevokeEK;
|
||||
BOOLEAN operator_;
|
||||
BOOLEAN enableRevokeEK;
|
||||
BOOLEAN nvLocked;
|
||||
BOOLEAN readSRKPub;
|
||||
BOOLEAN tpmEstablished;
|
||||
|
|
|
@ -205,15 +205,16 @@ typedef UINT16 TPM_ALG_ID;
|
|||
|
||||
// Table 8 - TPM_ECC_CURVE Constants
|
||||
typedef UINT16 TPM_ECC_CURVE;
|
||||
#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000)
|
||||
#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001)
|
||||
#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002)
|
||||
#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003)
|
||||
#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004)
|
||||
#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005)
|
||||
#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010)
|
||||
#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011)
|
||||
#define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020)
|
||||
#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000)
|
||||
#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001)
|
||||
#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002)
|
||||
#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003)
|
||||
#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004)
|
||||
#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005)
|
||||
#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010)
|
||||
#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011)
|
||||
#define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020)
|
||||
#define TPM_ECC_BP_P512_R1 (TPM_ECC_CURVE)(0x0032)
|
||||
|
||||
// Table 11 - TPM_CC Constants (Numeric Order)
|
||||
typedef UINT32 TPM_CC;
|
||||
|
@ -1249,7 +1250,7 @@ typedef union {
|
|||
TPMI_AES_KEY_BITS aes;
|
||||
TPMI_SM4_KEY_BITS SM4;
|
||||
TPM_KEY_BITS sym;
|
||||
TPMI_ALG_HASH xor;
|
||||
TPMI_ALG_HASH xor_;
|
||||
} TPMU_SYM_KEY_BITS;
|
||||
|
||||
// Table 123 - TPMU_SYM_MODE Union
|
||||
|
@ -1322,7 +1323,7 @@ typedef struct {
|
|||
// Table 136 - TPMU_SCHEME_KEYEDHASH Union
|
||||
typedef union {
|
||||
TPMS_SCHEME_HMAC hmac;
|
||||
TPMS_SCHEME_XOR xor;
|
||||
TPMS_SCHEME_XOR xor_;
|
||||
} TPMU_SCHEME_KEYEDHASH;
|
||||
|
||||
// Table 137 - TPMT_KEYEDHASH_SCHEME Structure
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/** @file
|
||||
TCG EFI Platform Definition in TCG_EFI_Platform_1_20_Final and
|
||||
TCG PC Client Platform Firmware Profile Specification, Revision 1.05
|
||||
TCG PC Client Platform Firmware Profile Specification, Revision 1.06
|
||||
|
||||
Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
@ -55,6 +55,18 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
#define EV_EFI_VARIABLE_AUTHORITY (EV_EFI_EVENT_BASE + 0xE0)
|
||||
#define EV_EFI_SPDM_FIRMWARE_BLOB (EV_EFI_EVENT_BASE + 0xE1)
|
||||
#define EV_EFI_SPDM_FIRMWARE_CONFIG (EV_EFI_EVENT_BASE + 0xE2)
|
||||
#define EV_EFI_SPDM_DEVICE_BLOB EV_EFI_SPDM_FIRMWARE_BLOB
|
||||
#define EV_EFI_SPDM_DEVICE_CONFIG EV_EFI_SPDM_FIRMWARE_CONFIG
|
||||
//
|
||||
// The SPDM policy database for SPDM verification.
|
||||
// It goes to PCR7
|
||||
//
|
||||
#define EV_EFI_SPDM_DEVICE_POLICY (EV_EFI_EVENT_BASE + 0xE3)
|
||||
//
|
||||
// The SPDM policy authority for SPDM verification for the signature
|
||||
// of GET_MEASUREMENT or CHALLENGE_AUTH. It goes to PCR7.
|
||||
//
|
||||
#define EV_EFI_SPDM_DEVICE_AUTHORITY (EV_EFI_EVENT_BASE + 0xE4)
|
||||
|
||||
#define EFI_CALLING_EFI_APPLICATION \
|
||||
"Calling EFI Application from Boot Option"
|
||||
|
@ -376,6 +388,7 @@ typedef struct {
|
|||
#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2 0
|
||||
#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2 0
|
||||
#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105 105
|
||||
#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106 106
|
||||
|
||||
typedef struct {
|
||||
UINT8 signature[16];
|
||||
|
@ -440,6 +453,7 @@ typedef struct tdTCG_PCClientTaggedEvent {
|
|||
|
||||
#define TCG_Sp800_155_PlatformId_Event_SIGNATURE "SP800-155 Event"
|
||||
#define TCG_Sp800_155_PlatformId_Event2_SIGNATURE "SP800-155 Event2"
|
||||
#define TCG_Sp800_155_PlatformId_Event3_SIGNATURE "SP800-155 Event3"
|
||||
|
||||
typedef struct tdTCG_Sp800_155_PlatformId_Event2 {
|
||||
UINT8 Signature[16];
|
||||
|
@ -461,15 +475,58 @@ typedef struct tdTCG_Sp800_155_PlatformId_Event2 {
|
|||
// UINT8 PlatformModel[PlatformModelSize];
|
||||
// UINT8 PlatformVersionSize;
|
||||
// UINT8 PlatformVersion[PlatformVersionSize];
|
||||
// UINT8 PlatformModelSize;
|
||||
// UINT8 PlatformModel[PlatformModelSize];
|
||||
// UINT8 FirmwareManufacturerStrSize;
|
||||
// UINT8 FirmwareManufacturerStr[FirmwareManufacturerStrSize];
|
||||
// UINT32 FirmwareManufacturerId;
|
||||
// UINT8 FirmwareVersion;
|
||||
// UINT8 FirmwareVersion[FirmwareVersionSize]];
|
||||
// UINT8 FirmwareVersion[FirmwareVersionSize];
|
||||
} TCG_Sp800_155_PlatformId_Event2;
|
||||
|
||||
typedef struct tdTCG_Sp800_155_PlatformId_Event3 {
|
||||
UINT8 Signature[16];
|
||||
//
|
||||
// Where Vendor ID is an integer defined
|
||||
// at http://www.iana.org/assignments/enterprisenumbers
|
||||
//
|
||||
UINT32 VendorId;
|
||||
//
|
||||
// 16-byte identifier of a given platform's static configuration of code
|
||||
//
|
||||
EFI_GUID ReferenceManifestGuid;
|
||||
// UINT8 PlatformManufacturerStrSize;
|
||||
// UINT8 PlatformManufacturerStr[PlatformManufacturerStrSize];
|
||||
// UINT8 PlatformModelSize;
|
||||
// UINT8 PlatformModel[PlatformModelSize];
|
||||
// UINT8 PlatformVersionSize;
|
||||
// UINT8 PlatformVersion[PlatformVersionSize];
|
||||
// UINT8 FirmwareManufacturerStrSize;
|
||||
// UINT8 FirmwareManufacturerStr[FirmwareManufacturerStrSize];
|
||||
// UINT32 FirmwareManufacturerId;
|
||||
// UINT8 FirmwareVersion;
|
||||
// UINT8 FirmwareVersion[FirmwareVersionSize];
|
||||
//
|
||||
// Below structure is newly added in TCG_Sp800_155_PlatformId_Event3
|
||||
//
|
||||
// UINT32 RimLocatorType;
|
||||
// UINT32 RimLocatorLength;
|
||||
// UINT8 RimLocator[RimLocatorLength];
|
||||
// UINT32 PlatformCertLocatorType;
|
||||
// UINT32 PlatformCertLocatorLength;
|
||||
// UINT8 PlatformCertLocator[PlatformCertLocatorLength];
|
||||
} TCG_Sp800_155_PlatformId_Event3;
|
||||
|
||||
/**
|
||||
* TCG specifies a locator type with the following values
|
||||
* 0 - Raw data in the locator itself.
|
||||
* 1 - URI in rtf2396 format.
|
||||
* 2 - local device path in EFI_DEVICE_PATH_PROTOCOL format.
|
||||
* 3 - UEFI variable (16 byte EFI_GUID, then 00-terminated UCS2 string)
|
||||
**/
|
||||
#define TCG_LOCATOR_TYPE_RAW_DATA 0
|
||||
#define TCG_LOCATOR_TYPE_URI 1
|
||||
#define TCG_LOCATOR_TYPE_DEVICE_PATH 2
|
||||
#define TCG_LOCATOR_TYPE_UEFI_VARIABLE 3
|
||||
|
||||
#define TCG_EfiStartupLocalityEvent_SIGNATURE "StartupLocality"
|
||||
|
||||
//
|
||||
|
@ -494,4 +551,173 @@ typedef struct tdTCG_EfiStartupLocalityEvent {
|
|||
//
|
||||
#pragma pack ()
|
||||
|
||||
//
|
||||
// ======================================================================================================================
|
||||
// Event Type PCR Event Log Usage
|
||||
// ======================================================================================================================
|
||||
// EV_EFI_SPDM_DEVICE_BLOB 2 SPDM_MEASUREMENT_BLOCK (subtype) MEASUREMENT from device
|
||||
// EV_EFI_SPDM_DEVICE_CONFIG 3 SPDM_MEASUREMENT_BLOCK (subtype) MEASUREMENT from device
|
||||
// EV_EFI_SPDM_DEVICE_BLOB 2 SPDM_MEASUREMENT_SUMMARY_HASH.TCB (subtype) SUMMARY_HASH from device
|
||||
|
||||
// EV_EFI_SPDM_DEVICE_POLICY 7 UEFI_VARIABLE_DATA with EFI_SIGNATURE_LIST Provisioned device public cert.
|
||||
// EV_EFI_SPDM_DEVICE_AUTHORITY 7 UEFI_VARIABLE_DATA with EFI_SIGNATURE_DATA CHALLENGE_AUTH signature verification
|
||||
// ======================================================================================================================
|
||||
//
|
||||
|
||||
#define PCR_INDEX_FOR_SIGNATURE_DB 7
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_1 1
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2 2
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2 "SPDM Device Sec2"
|
||||
|
||||
typedef struct {
|
||||
UINT8 Signature[16];
|
||||
UINT16 Version;
|
||||
UINT8 AuthState;
|
||||
UINT8 Reserved;
|
||||
UINT32 Length; // Length in bytes for all following structures.
|
||||
UINT32 DeviceType;
|
||||
UINT32 SubHeaderType;
|
||||
UINT32 SubHeaderLength; // Length in bytes of the sub header followed by.
|
||||
UINT64 SubHeaderUID; // Universal identifier assigned by the event log creator. It can be used to bind two sub header structure together.
|
||||
// UINT64 DevicePathLength;
|
||||
// UINT8 DevicePath[DevicePathLength];
|
||||
} TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2;
|
||||
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS 0
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH 1
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_BINDING 2
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG 3
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID 4
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM 0xFF
|
||||
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK 0
|
||||
#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN 1
|
||||
|
||||
typedef struct {
|
||||
UINT16 SpdmVersion;
|
||||
UINT8 SpdmMeasurementBlockCount;
|
||||
UINT8 Reserved;
|
||||
UINT32 SpdmMeasurementHashAlgo;
|
||||
// SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock;
|
||||
} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK;
|
||||
|
||||
typedef struct {
|
||||
UINT16 SpdmVersion;
|
||||
UINT8 SpdmSlotId;
|
||||
UINT8 Reserved;
|
||||
UINT32 SpdmHashAlgo;
|
||||
// SPDM_CERT_CHAIN SpdmCertChain;
|
||||
} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN;
|
||||
|
||||
typedef struct {
|
||||
UINT32 Type;
|
||||
UINT32 Length;
|
||||
UINT8 Value[1];
|
||||
} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_OEM_MEASUREMENT;
|
||||
|
||||
typedef union {
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock;
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN SpdmCertChain;
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_OEM_MEASUREMENT OemMeasurement;
|
||||
} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER;
|
||||
|
||||
typedef union {
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT Pci;
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT Usb;
|
||||
} TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2 EventDataHeader;
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER EventDataSubHeader;
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT DeviceContext;
|
||||
} TCG_DEVICE_SECURITY_EVENT_DATA2;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
//
|
||||
// EventType:EV_NO_ACTION
|
||||
// ======================================================================================================================
|
||||
// NVIndex Name PCR/NvIndex Event Log Usage
|
||||
// ======================================================================================================================
|
||||
// NV_EXTEND_INDEX_FOR_INSTANCE 0x01C40200 NV_INDEX_INSTANCE_EVENT_LOG_STRUCT NV Extend Record for instance data (CertChain)
|
||||
// NV_EXTEND_INDEX_FOR_DYNAMIC 0x01C40201 NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT NV Extend Record for dynamic data (Nonce)
|
||||
|
||||
// EVENT_LOG_INTEGRITY_NV_INDEX_EXIT_PM_AUTH 0x01C40202 EVENT_LOG_INTEGRITY_NV_INDEX_STRUCT Event Log Integrity for ExitPmAuth
|
||||
// EVENT_LOG_INTEGRITY_NV_INDEX_READY_TO_BOOT 0x01C40203 EVENT_LOG_INTEGRITY_NV_INDEX_STRUCT Event Log Integrity for ReadyToBoot
|
||||
// ======================================================================================================================
|
||||
//
|
||||
|
||||
#define TCG_NV_EXTEND_INDEX_FOR_INSTANCE 0x01C40200
|
||||
#define TCG_NV_EXTEND_INDEX_FOR_DYNAMIC 0x01C40201
|
||||
#define TCG_EVENT_LOG_INTEGRITY_NV_INDEX_EXIT_PM_AUTH 0x01C40202
|
||||
#define TCG_EVENT_LOG_INTEGRITY_NV_INDEX_READY_TO_BOOT 0x01C40203
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE "NvIndexInstance"
|
||||
#define TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION 1
|
||||
|
||||
typedef struct {
|
||||
UINT8 Signature[16];
|
||||
UINT16 Version;
|
||||
UINT8 Reserved[6];
|
||||
// TCG_DEVICE_SECURITY_EVENT_DATA2 Data;
|
||||
} TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT;
|
||||
|
||||
#define TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE "NvIndexDynamic "
|
||||
#define TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION 1
|
||||
|
||||
#define TCG_SPDM_CHALLENGE_DESCRIPTION "SPDM CHALLENGE"
|
||||
#define TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION "SPDM CHALLENGE_AUTH"
|
||||
#define TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION "SPDM GET_MEASUREMENTS"
|
||||
#define TCG_SPDM_MEASUREMENTS_DESCRIPTION "SPDM MEASUREMENTS"
|
||||
|
||||
typedef struct {
|
||||
UINT8 Signature[16];
|
||||
UINT16 Version;
|
||||
UINT8 Reserved[6];
|
||||
UINT64 Uid;
|
||||
// UINT16 DescriptionSize;
|
||||
// UINT8 Description[DescriptionSize];
|
||||
// UINT16 DataSize;
|
||||
// UINT8 Data[DataSize];
|
||||
} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT;
|
||||
|
||||
typedef struct {
|
||||
TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT Header;
|
||||
UINT16 DescriptionSize;
|
||||
UINT8 Description[sizeof (TCG_SPDM_CHALLENGE_DESCRIPTION)];
|
||||
UINT16 DataSize;
|
||||
UINT8 Data[32];
|
||||
} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE;
|
||||
|
||||
typedef struct {
|
||||
TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT Header;
|
||||
UINT16 DescriptionSize;
|
||||
UINT8 Description[sizeof (TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION)];
|
||||
UINT16 DataSize;
|
||||
UINT8 Data[32];
|
||||
} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE_AUTH;
|
||||
|
||||
typedef struct {
|
||||
TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT Header;
|
||||
UINT16 DescriptionSize;
|
||||
UINT8 Description[sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION)];
|
||||
UINT16 DataSize;
|
||||
UINT8 Data[32];
|
||||
} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_GET_MEASUREMENTS;
|
||||
|
||||
typedef struct {
|
||||
TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT Header;
|
||||
UINT16 DescriptionSize;
|
||||
UINT8 Description[sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION)];
|
||||
UINT16 DataSize;
|
||||
UINT8 Data[32];
|
||||
} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_MEASUREMENTS;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
Support for USB 2.0 standard.
|
||||
|
||||
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2024, American Megatrends International LLC. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
@ -133,6 +135,21 @@ typedef struct {
|
|||
UINT8 MaxPower;
|
||||
} USB_CONFIG_DESCRIPTOR;
|
||||
|
||||
///
|
||||
/// Standard Interface Association Descriptor
|
||||
/// USB 3.0 spec, Section 9.6.4
|
||||
///
|
||||
typedef struct {
|
||||
UINT8 Length;
|
||||
UINT8 DescriptorType;
|
||||
UINT8 FirstInterface;
|
||||
UINT8 InterfaceCount;
|
||||
UINT8 FunctionClass;
|
||||
UINT8 FunctionSubclass;
|
||||
UINT8 FunctionProtocol;
|
||||
UINT8 FunctionDescriptionStringIndex;
|
||||
} USB_INTERFACE_ASSOCIATION_DESCRIPTOR;
|
||||
|
||||
///
|
||||
/// Standard Interface Descriptor
|
||||
/// USB 2.0 spec, Section 9.6.5
|
||||
|
@ -209,13 +226,16 @@ typedef enum {
|
|||
//
|
||||
// USB Descriptor types
|
||||
//
|
||||
USB_DESC_TYPE_DEVICE = 0x01,
|
||||
USB_DESC_TYPE_CONFIG = 0x02,
|
||||
USB_DESC_TYPE_STRING = 0x03,
|
||||
USB_DESC_TYPE_INTERFACE = 0x04,
|
||||
USB_DESC_TYPE_ENDPOINT = 0x05,
|
||||
USB_DESC_TYPE_HID = 0x21,
|
||||
USB_DESC_TYPE_REPORT = 0x22,
|
||||
USB_DESC_TYPE_DEVICE = 0x01,
|
||||
USB_DESC_TYPE_CONFIG = 0x02,
|
||||
USB_DESC_TYPE_STRING = 0x03,
|
||||
USB_DESC_TYPE_INTERFACE = 0x04,
|
||||
USB_DESC_TYPE_ENDPOINT = 0x05,
|
||||
USB_DESC_TYPE_INTERFACE_ASSOCIATION = 0x0b,
|
||||
USB_DESC_TYPE_HID = 0x21,
|
||||
USB_DESC_TYPE_REPORT = 0x22,
|
||||
USB_DESC_TYPE_CS_INTERFACE = 0x24,
|
||||
USB_DESC_TYPE_CS_ENDPOINT = 0x25,
|
||||
|
||||
//
|
||||
// Features to be cleared by CLEAR_FEATURE requests
|
||||
|
|
|
@ -7,6 +7,7 @@ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
|||
Copyright (c) Microsoft Corporation.<BR>
|
||||
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||
Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
|
@ -128,6 +129,92 @@ typedef struct {
|
|||
|
||||
#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
|
||||
|
||||
/**
|
||||
Reads the current value of CNTPCT_EL0 register.
|
||||
|
||||
Reads and returns the current value of CNTPCT_EL0.
|
||||
This function is only available on AARCH64.
|
||||
|
||||
@return The current value of CNTPCT_EL0
|
||||
**/
|
||||
UINT64
|
||||
EFIAPI
|
||||
ArmReadCntPctReg (
|
||||
VOID
|
||||
);
|
||||
|
||||
//
|
||||
// Bit shifts for the ID_AA64ISAR0_EL1 register.
|
||||
//
|
||||
#define ARM_ID_AA64ISAR0_EL1_AES_SHIFT (4U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA1_SHIFT (8U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT (12U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_CRC32_SHIFT (16U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_ATOMIC_SHIFT (20U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_RDM_SHIFT (28U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA3_SHIFT (32U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SM3_SHIFT (36U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SM4_SHIFT (40U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_DP_SHIFT (44U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_FHM_SHIFT (48U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_TS_SHIFT (52U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_TLB_SHIFT (56U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT (60U)
|
||||
|
||||
//
|
||||
// Bit masks for the ID_AA64ISAR0_EL1 fields.
|
||||
//
|
||||
#define ARM_ID_AA64ISAR0_EL1_AES_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA1_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA2_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_CRC32_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_ATOMIC_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_RDM_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA3_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SM3_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SM4_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_DP_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_FHM_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_TS_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_TLB_MASK (0xFU)
|
||||
#define ARM_ID_AA64ISAR0_EL1_RNDR_MASK (0xFU)
|
||||
|
||||
//
|
||||
// Bit masks for the ID_AA64ISAR0_EL1 field values.
|
||||
//
|
||||
#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_AES_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_PMULL_MASK (0x2U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA1_FEAT_SHA1_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA256_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA512_MASK (0x2U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_CRC32_HAVE_CRC32_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_ATOMIC_FEAT_LSE_MASK (0x2U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_RDM_FEAT_RDM_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SHA3_FEAT_SHA3_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SM3_FEAT_SM3_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_SM4_FEAT_SM4_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_DP_FEAT_DOTPROD_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_FHM_FEAT_FHM_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM2_MASK (0x2U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIOS_MASK (0x1U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIRANGE_MASK (0x2U)
|
||||
#define ARM_ID_AA64ISAR0_EL1_RNDR_FEAT_RNG_MASK (0x1U)
|
||||
|
||||
/**
|
||||
Reads the current value of ID_AA64ISAR0_EL1 register.
|
||||
|
||||
Reads and returns the current value of ID_AA64ISAR0_EL1.
|
||||
This function is only available on AARCH64.
|
||||
|
||||
@return The current value of ID_AA64ISAR0_EL1
|
||||
**/
|
||||
UINT64
|
||||
EFIAPI
|
||||
ArmReadIdAA64Isar0Reg (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif // defined (MDE_CPU_AARCH64)
|
||||
|
||||
#if defined (MDE_CPU_RISCV64)
|
||||
|
@ -4902,6 +4989,23 @@ CalculateCrc32c (
|
|||
IN UINT32 InitialValue
|
||||
);
|
||||
|
||||
/**
|
||||
Calculates the CRC16-CCITT-FALSE checksum of the given buffer.
|
||||
|
||||
@param[in] Buffer Pointer to the buffer.
|
||||
@param[in] Length Length of the buffer, in bytes.
|
||||
@param[in] InitialValue Initial value of the CRC.
|
||||
|
||||
@return The CRC16-CCITT-FALSE checksum.
|
||||
**/
|
||||
UINT16
|
||||
EFIAPI
|
||||
CalculateCrc16CcittF (
|
||||
IN CONST VOID *Buffer,
|
||||
IN UINTN Length,
|
||||
IN UINT16 InitialValue
|
||||
);
|
||||
|
||||
//
|
||||
// Base Library CPU Functions
|
||||
//
|
||||
|
@ -5157,8 +5261,6 @@ SpeculationBarrier (
|
|||
VOID
|
||||
);
|
||||
|
||||
#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32)
|
||||
|
||||
/**
|
||||
The TDCALL instruction causes a VM exit to the Intel TDX module. It is
|
||||
used to call guest-side Intel TDX functions, either local or a TD exit
|
||||
|
@ -5221,8 +5323,6 @@ TdIsEnabled (
|
|||
VOID
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (MDE_CPU_X64)
|
||||
//
|
||||
// The page size for the PVALIDATE instruction
|
||||
|
@ -7878,6 +7978,45 @@ AsmVmgExit (
|
|||
VOID
|
||||
);
|
||||
|
||||
///
|
||||
/// The structure used to supply and return data to and from the SVSM.
|
||||
///
|
||||
typedef struct {
|
||||
VOID *Caa;
|
||||
UINT64 RaxIn;
|
||||
UINT64 RcxIn;
|
||||
UINT64 RdxIn;
|
||||
UINT64 R8In;
|
||||
UINT64 R9In;
|
||||
UINT64 RaxOut;
|
||||
UINT64 RcxOut;
|
||||
UINT64 RdxOut;
|
||||
UINT64 R8Out;
|
||||
UINT64 R9Out;
|
||||
UINT8 *CallPending;
|
||||
} SVSM_CALL_DATA;
|
||||
|
||||
/**
|
||||
Executes a VMGEXIT instruction (VMMCALL with a REP prefix) with arguments
|
||||
and return code
|
||||
|
||||
Executes a VMGEXIT instruction placing the specified arguments in the
|
||||
corresponding registers before invocation. Upon return an XCHG is done to
|
||||
atomically clear and retrieve the SVSM call pending value. The returned RAX
|
||||
register value becomes the function return code. This function is intended
|
||||
for use with an SVSM. This function is only available on IA-32 and x64.
|
||||
|
||||
@param[in,out] SvsmCallPending Pointer to the location of the SVSM call data
|
||||
|
||||
@return Value of the RAX register on return
|
||||
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
AsmVmgExitSvsm (
|
||||
IN OUT SVSM_CALL_DATA *SvsmCallData
|
||||
);
|
||||
|
||||
/**
|
||||
Patch the immediate operand of an IA32 or X64 instruction such that the byte,
|
||||
word, dword or qword operand is encoded at the end of the instruction's
|
||||
|
|
|
@ -5,7 +5,7 @@ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
|||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Revision Reference:
|
||||
PI Version 1.7
|
||||
PI Version 1.8.A
|
||||
|
||||
**/
|
||||
|
||||
|
@ -58,14 +58,11 @@ typedef enum {
|
|||
/// system. If all memory has the same reliability, then this bit is not used.
|
||||
///
|
||||
EfiGcdMemoryTypeMoreReliable,
|
||||
// ///
|
||||
// /// A memory region that describes system memory that has not been accepted
|
||||
// /// by a corresponding call to the underlying isolation architecture.
|
||||
// ///
|
||||
// /// Please be noted:
|
||||
// /// EfiGcdMemoryTypeUnaccepted is defined in PrePiDxeCis.h because it has not been
|
||||
// /// defined in PI spec.
|
||||
// EfiGcdMemoryTypeUnaccepted,
|
||||
///
|
||||
/// A memory region that describes system memory that has not been accepted
|
||||
/// by a corresponding call to the underlying isolation architecture.
|
||||
///
|
||||
EfiGcdMemoryTypeUnaccepted,
|
||||
EfiGcdMemoryTypeMaximum = 7
|
||||
} EFI_GCD_MEMORY_TYPE;
|
||||
|
||||
|
@ -696,8 +693,8 @@ EFI_STATUS
|
|||
// DXE Services Table
|
||||
//
|
||||
#define DXE_SERVICES_SIGNATURE 0x565245535f455844ULL
|
||||
#define DXE_SPECIFICATION_MAJOR_REVISION 1
|
||||
#define DXE_SPECIFICATION_MINOR_REVISION 70
|
||||
#define DXE_SPECIFICATION_MAJOR_REVISION PI_SPECIFICATION_MAJOR_REVISION
|
||||
#define DXE_SPECIFICATION_MINOR_REVISION PI_SPECIFICATION_MINOR_REVISION
|
||||
#define DXE_SERVICES_REVISION ((DXE_SPECIFICATION_MAJOR_REVISION<<16) | (DXE_SPECIFICATION_MINOR_REVISION))
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -5,7 +5,7 @@ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
|||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Revision Reference:
|
||||
PI Version 1.6
|
||||
PI Version 1.9
|
||||
|
||||
**/
|
||||
|
||||
|
@ -234,16 +234,8 @@ typedef UINT32 EFI_RESOURCE_TYPE;
|
|||
#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004
|
||||
#define EFI_RESOURCE_MEMORY_RESERVED 0x00000005
|
||||
#define EFI_RESOURCE_IO_RESERVED 0x00000006
|
||||
//
|
||||
// BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED is defined for unaccepted memory.
|
||||
// But this defitinion has not been officially in the PI spec. Base
|
||||
// on the code-first we define BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED at
|
||||
// MdeModulePkg/Include/Pi/PrePiHob.h and update EFI_RESOURCE_MAX_MEMORY_TYPE
|
||||
// to 8. After BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED is officially published
|
||||
// in PI spec, we will re-visit here.
|
||||
//
|
||||
// #define BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
|
||||
#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008
|
||||
#define EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
|
||||
#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008
|
||||
|
||||
///
|
||||
/// A type of recount attribute type.
|
||||
|
@ -299,6 +291,9 @@ typedef UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE;
|
|||
#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED 0x00040000
|
||||
#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00080000
|
||||
|
||||
#define EFI_RESOURCE_ATTRIBUTE_ENCRYPTED 0x04000000
|
||||
#define EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE 0x08000000
|
||||
#define EFI_RESOURCE_ATTRIBUTE_HOT_PLUGGABLE 0x10000000
|
||||
//
|
||||
// Physical memory relative reliability attribute. This
|
||||
// memory provides higher reliability relative to other
|
||||
|
|
|
@ -5,7 +5,7 @@ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
|||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Revision Reference:
|
||||
These elements are defined in UEFI Platform Initialization Specification 1.2.
|
||||
These elements are defined in UEFI Platform Initialization Specification 1.8.A
|
||||
|
||||
**/
|
||||
|
||||
|
@ -22,6 +22,13 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
#include <ipxe/efi/Pi/PiStatusCode.h>
|
||||
#include <ipxe/efi/Pi/PiS3BootScript.h>
|
||||
|
||||
//
|
||||
// PI Specification Version Information
|
||||
//
|
||||
#define PI_SPECIFICATION_MAJOR_REVISION 1
|
||||
#define PI_SPECIFICATION_MINOR_REVISION 80
|
||||
#define PI_SPECIFICATION_VERSION ((PI_SPECIFICATION_MAJOR_REVISION << 16) | (PI_SPECIFICATION_MINOR_REVISION))
|
||||
|
||||
/**
|
||||
Produces an error code in the range reserved for use by the Platform Initialization
|
||||
Architecture Specification.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
StatusCode related definitions in PI.
|
||||
|
||||
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Revision Reference:
|
||||
|
@ -142,6 +143,7 @@ typedef struct {
|
|||
#define EFI_COMPUTING_UNIT_CACHE (EFI_COMPUTING_UNIT | 0x00040000)
|
||||
#define EFI_COMPUTING_UNIT_MEMORY (EFI_COMPUTING_UNIT | 0x00050000)
|
||||
#define EFI_COMPUTING_UNIT_CHIPSET (EFI_COMPUTING_UNIT | 0x00060000)
|
||||
#define EFI_COMPUTING_UNIT_MANAGEABILITY (EFI_COMPUTING_UNIT | 0x00070000)
|
||||
///@}
|
||||
|
||||
///
|
||||
|
@ -345,6 +347,16 @@ typedef struct {
|
|||
#define EFI_CHIPSET_EC_INTRUDER_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000003)
|
||||
///@}
|
||||
|
||||
///
|
||||
/// Computing Unit Manageability Subclass Error Code definitions.
|
||||
/// The detail information is reported by REPORT_STATUS_CODE_WITH_EXTENDED_DATA
|
||||
// with ASCII string in EFI_STATUS_CODE_STRING_DATA.
|
||||
///@{
|
||||
#define EFI_MANAGEABILITY_EC_REDFISH_COMMUNICATION_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000000)
|
||||
#define EFI_MANAGEABILITY_EC_REDFISH_HOST_INTERFACE_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000001)
|
||||
#define EFI_MANAGEABILITY_EC_REDFISH_BOOTSTRAP_CREDENTIAL_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002)
|
||||
///@}
|
||||
|
||||
///
|
||||
/// Peripheral Subclass definitions.
|
||||
/// Values of 12-127 are reserved for future use by this specification.
|
||||
|
|
|
@ -682,23 +682,23 @@ typedef struct {
|
|||
UINT32 STVAL;
|
||||
} EFI_SYSTEM_CONTEXT_RISCV64;
|
||||
|
||||
//
|
||||
// LoongArch processor exception types.
|
||||
//
|
||||
// The exception types is located in the CSR ESTAT
|
||||
// register offset 16 bits, width 6 bits.
|
||||
//
|
||||
// If you want to register an exception hook, you can
|
||||
// shfit the number left by 16 bits, and the exception
|
||||
// handler will know the types.
|
||||
//
|
||||
// For example:
|
||||
// mCpu->CpuRegisterInterruptHandler (
|
||||
// mCpu,
|
||||
// (EXCEPT_LOONGARCH_PPI << CSR_ESTAT_EXC_SHIFT),
|
||||
// PpiExceptionHandler
|
||||
// );
|
||||
//
|
||||
///
|
||||
/// LoongArch processor exception types.
|
||||
///
|
||||
/// The exception types is located in the CSR ESTAT
|
||||
/// register offset 16 bits, width 6 bits.
|
||||
///
|
||||
/// If you want to register an exception hook, you can
|
||||
/// shfit the number left by 16 bits, and the exception
|
||||
/// handler will know the types.
|
||||
///
|
||||
/// For example:
|
||||
/// mCpu->CpuRegisterInterruptHandler (
|
||||
/// mCpu,
|
||||
/// (EXCEPT_LOONGARCH_PPI << CSR_ESTAT_EXC_SHIFT),
|
||||
/// PpiExceptionHandler
|
||||
/// );
|
||||
///
|
||||
#define EXCEPT_LOONGARCH_INT 0
|
||||
#define EXCEPT_LOONGARCH_PIL 1
|
||||
#define EXCEPT_LOONGARCH_PIS 2
|
||||
|
@ -718,11 +718,22 @@ typedef struct {
|
|||
#define EXCEPT_LOONGARCH_SXD 16
|
||||
#define EXCEPT_LOONGARCH_ASXD 17
|
||||
#define EXCEPT_LOONGARCH_FPE 18
|
||||
#define EXCEPT_LOONGARCH_TBR 64 // For code only, there is no such type in the ISA spec, the TLB refill is defined for an independent exception.
|
||||
#define EXCEPT_LOONGARCH_WPE 19
|
||||
#define EXCEPT_LOONGARCH_BTD 20
|
||||
#define EXCEPT_LOONGARCH_BTE 21
|
||||
#define EXCEPT_LOONGARCH_GSPR 22
|
||||
#define EXCEPT_LOONGARCH_HVC 23
|
||||
#define EXCEPT_LOONGARCH_GCXC 24
|
||||
|
||||
//
|
||||
// LoongArch processor Interrupt types.
|
||||
//
|
||||
///
|
||||
/// For coding convenience, define the maximum valid
|
||||
/// LoongArch exception.
|
||||
///
|
||||
#define MAX_LOONGARCH_EXCEPTION 64
|
||||
|
||||
///
|
||||
/// LoongArch processor Interrupt types.
|
||||
///
|
||||
#define EXCEPT_LOONGARCH_INT_SIP0 0
|
||||
#define EXCEPT_LOONGARCH_INT_SIP1 1
|
||||
#define EXCEPT_LOONGARCH_INT_IP0 2
|
||||
|
@ -737,11 +748,11 @@ typedef struct {
|
|||
#define EXCEPT_LOONGARCH_INT_TIMER 11
|
||||
#define EXCEPT_LOONGARCH_INT_IPI 12
|
||||
|
||||
//
|
||||
// For coding convenience, define the maximum valid
|
||||
// LoongArch interrupt.
|
||||
//
|
||||
#define MAX_LOONGARCH_INTERRUPT 14
|
||||
///
|
||||
/// For coding convenience, define the maximum valid
|
||||
/// LoongArch interrupt.
|
||||
///
|
||||
#define MAX_LOONGARCH_INTERRUPT 16
|
||||
|
||||
typedef struct {
|
||||
UINT64 R0;
|
||||
|
|
|
@ -839,6 +839,26 @@ typedef struct {
|
|||
UINT64 NamespaceUuid;
|
||||
} NVME_NAMESPACE_DEVICE_PATH;
|
||||
|
||||
///
|
||||
/// NVMe over Fabric (NVMe-oF) Namespace Device Path SubType.
|
||||
///
|
||||
#define MSG_NVME_OF_NAMESPACE_DP 0x22
|
||||
typedef struct {
|
||||
EFI_DEVICE_PATH_PROTOCOL Header;
|
||||
///
|
||||
/// Namespace Identifier Type (NIDT)
|
||||
///
|
||||
UINT8 NamespaceIdType;
|
||||
///
|
||||
/// Namespace Identifier (NID)
|
||||
///
|
||||
UINT8 NamespaceId[16];
|
||||
///
|
||||
/// Unique identifier of an NVM subsystem
|
||||
///
|
||||
CHAR8 SubsystemNqn[];
|
||||
} NVME_OF_NAMESPACE_DEVICE_PATH;
|
||||
|
||||
///
|
||||
/// DNS Device Path SubType
|
||||
///
|
||||
|
@ -1289,6 +1309,7 @@ typedef union {
|
|||
SAS_DEVICE_PATH Sas;
|
||||
SASEX_DEVICE_PATH SasEx;
|
||||
NVME_NAMESPACE_DEVICE_PATH NvmeNamespace;
|
||||
NVME_OF_NAMESPACE_DEVICE_PATH NvmeOfNamespace;
|
||||
DNS_DEVICE_PATH Dns;
|
||||
URI_DEVICE_PATH Uri;
|
||||
BLUETOOTH_DEVICE_PATH Bluetooth;
|
||||
|
@ -1345,6 +1366,7 @@ typedef union {
|
|||
SAS_DEVICE_PATH *Sas;
|
||||
SASEX_DEVICE_PATH *SasEx;
|
||||
NVME_NAMESPACE_DEVICE_PATH *NvmeNamespace;
|
||||
NVME_OF_NAMESPACE_DEVICE_PATH *NvmeOfNamespace;
|
||||
DNS_DEVICE_PATH *Dns;
|
||||
URI_DEVICE_PATH *Uri;
|
||||
BLUETOOTH_DEVICE_PATH *Bluetooth;
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
/** @file
|
||||
EFI_HASH_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0.
|
||||
EFI_HASH_PROTOCOL as defined in UEFI 2.0.
|
||||
The EFI Hash Service Binding Protocol is used to locate hashing services support
|
||||
provided by a driver and to create and destroy instances of the EFI Hash Protocol
|
||||
so that a multiple drivers can use the underlying hashing services.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HASH_PROTOCOL_H__
|
||||
#define __EFI_HASH_PROTOCOL_H__
|
||||
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
#define EFI_HASH_SERVICE_BINDING_PROTOCOL_GUID \
|
||||
{ \
|
||||
0x42881c98, 0xa4f3, 0x44b0, {0xa3, 0x9d, 0xdf, 0xa1, 0x86, 0x67, 0xd8, 0xcd } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_PROTOCOL_GUID \
|
||||
{ \
|
||||
0xc5184932, 0xdba5, 0x46db, {0xa5, 0xba, 0xcc, 0x0b, 0xda, 0x9c, 0x14, 0x35 } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_ALGORITHM_SHA1_GUID \
|
||||
{ \
|
||||
0x2ae9d80f, 0x3fb2, 0x4095, {0xb7, 0xb1, 0xe9, 0x31, 0x57, 0xb9, 0x46, 0xb6 } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_ALGORITHM_SHA224_GUID \
|
||||
{ \
|
||||
0x8df01a06, 0x9bd5, 0x4bf7, {0xb0, 0x21, 0xdb, 0x4f, 0xd9, 0xcc, 0xf4, 0x5b } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_ALGORITHM_SHA256_GUID \
|
||||
{ \
|
||||
0x51aa59de, 0xfdf2, 0x4ea3, {0xbc, 0x63, 0x87, 0x5f, 0xb7, 0x84, 0x2e, 0xe9 } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_ALGORITHM_SHA384_GUID \
|
||||
{ \
|
||||
0xefa96432, 0xde33, 0x4dd2, {0xae, 0xe6, 0x32, 0x8c, 0x33, 0xdf, 0x77, 0x7a } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_ALGORITHM_SHA512_GUID \
|
||||
{ \
|
||||
0xcaa4381e, 0x750c, 0x4770, {0xb8, 0x70, 0x7a, 0x23, 0xb4, 0xe4, 0x21, 0x30 } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_ALGORTIHM_MD5_GUID \
|
||||
{ \
|
||||
0xaf7c79c, 0x65b5, 0x4319, {0xb0, 0xae, 0x44, 0xec, 0x48, 0x4e, 0x4a, 0xd7 } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID \
|
||||
{ \
|
||||
0x24c5dc2f, 0x53e2, 0x40ca, {0x9e, 0xd6, 0xa5, 0xd9, 0xa4, 0x9f, 0x46, 0x3b } \
|
||||
}
|
||||
|
||||
#define EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID \
|
||||
{ \
|
||||
0x8628752a, 0x6cb7, 0x4814, {0x96, 0xfc, 0x24, 0xa8, 0x15, 0xac, 0x22, 0x26 } \
|
||||
}
|
||||
|
||||
//
|
||||
// Note: Use of the following algorithms with EFI_HASH_PROTOCOL is deprecated.
|
||||
// EFI_HASH_ALGORITHM_SHA1_GUID
|
||||
// EFI_HASH_ALGORITHM_SHA224_GUID
|
||||
// EFI_HASH_ALGORITHM_SHA256_GUID
|
||||
// EFI_HASH_ALGORITHM_SHA384_GUID
|
||||
// EFI_HASH_ALGORITHM_SHA512_GUID
|
||||
// EFI_HASH_ALGORTIHM_MD5_GUID
|
||||
//
|
||||
|
||||
typedef struct _EFI_HASH_PROTOCOL EFI_HASH_PROTOCOL;
|
||||
|
||||
typedef UINT8 EFI_MD5_HASH[16];
|
||||
typedef UINT8 EFI_SHA1_HASH[20];
|
||||
typedef UINT8 EFI_SHA224_HASH[28];
|
||||
typedef UINT8 EFI_SHA256_HASH[32];
|
||||
typedef UINT8 EFI_SHA384_HASH[48];
|
||||
typedef UINT8 EFI_SHA512_HASH[64];
|
||||
|
||||
typedef union {
|
||||
EFI_MD5_HASH *Md5Hash;
|
||||
EFI_SHA1_HASH *Sha1Hash;
|
||||
EFI_SHA224_HASH *Sha224Hash;
|
||||
EFI_SHA256_HASH *Sha256Hash;
|
||||
EFI_SHA384_HASH *Sha384Hash;
|
||||
EFI_SHA512_HASH *Sha512Hash;
|
||||
} EFI_HASH_OUTPUT;
|
||||
|
||||
/**
|
||||
Returns the size of the hash which results from a specific algorithm.
|
||||
|
||||
@param[in] This Points to this instance of EFI_HASH_PROTOCOL.
|
||||
@param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
|
||||
@param[out] HashSize Holds the returned size of the algorithm's hash.
|
||||
|
||||
@retval EFI_SUCCESS Hash size returned successfully.
|
||||
@retval EFI_INVALID_PARAMETER HashSize is NULL or HashAlgorithm is NULL.
|
||||
@retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported
|
||||
by this driver.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_HASH_GET_HASH_SIZE)(
|
||||
IN CONST EFI_HASH_PROTOCOL *This,
|
||||
IN CONST EFI_GUID *HashAlgorithm,
|
||||
OUT UINTN *HashSize
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a hash for the specified message text.
|
||||
|
||||
@param[in] This Points to this instance of EFI_HASH_PROTOCOL.
|
||||
@param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
|
||||
@param[in] Extend Specifies whether to create a new hash (FALSE) or extend the specified
|
||||
existing hash (TRUE).
|
||||
@param[in] Message Points to the start of the message.
|
||||
@param[in] MessageSize The size of Message, in bytes.
|
||||
@param[in,out] Hash On input, if Extend is TRUE, then this parameter holds a pointer
|
||||
to a pointer to an array containing the hash to extend. If Extend
|
||||
is FALSE, then this parameter holds a pointer to a pointer to a
|
||||
caller-allocated array that will receive the result of the hash
|
||||
computation. On output (regardless of the value of Extend), the
|
||||
array will contain the result of the hash computation.
|
||||
|
||||
@retval EFI_SUCCESS Hash returned successfully.
|
||||
@retval EFI_INVALID_PARAMETER Message or Hash, HashAlgorithm is NULL or MessageSize is 0.
|
||||
MessageSize is not an integer multiple of block size.
|
||||
@retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this
|
||||
driver. Or, Extend is TRUE, and the algorithm doesn't support extending the hash.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_HASH_HASH)(
|
||||
IN CONST EFI_HASH_PROTOCOL *This,
|
||||
IN CONST EFI_GUID *HashAlgorithm,
|
||||
IN BOOLEAN Extend,
|
||||
IN CONST UINT8 *Message,
|
||||
IN UINT64 MessageSize,
|
||||
IN OUT EFI_HASH_OUTPUT *Hash
|
||||
);
|
||||
|
||||
///
|
||||
/// This protocol allows creating a hash of an arbitrary message digest
|
||||
/// using one or more hash algorithms.
|
||||
///
|
||||
struct _EFI_HASH_PROTOCOL {
|
||||
EFI_HASH_GET_HASH_SIZE GetHashSize;
|
||||
EFI_HASH_HASH Hash;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEfiHashServiceBindingProtocolGuid;
|
||||
extern EFI_GUID gEfiHashProtocolGuid;
|
||||
extern EFI_GUID gEfiHashAlgorithmSha1Guid;
|
||||
extern EFI_GUID gEfiHashAlgorithmSha224Guid;
|
||||
extern EFI_GUID gEfiHashAlgorithmSha256Guid;
|
||||
extern EFI_GUID gEfiHashAlgorithmSha384Guid;
|
||||
extern EFI_GUID gEfiHashAlgorithmSha512Guid;
|
||||
extern EFI_GUID gEfiHashAlgorithmMD5Guid;
|
||||
extern EFI_GUID gEfiHashAlgorithmSha1NoPadGuid;
|
||||
extern EFI_GUID gEfiHashAlgorithmSha256NoPadGuid;
|
||||
|
||||
#endif
|
|
@ -100,7 +100,8 @@ typedef enum {
|
|||
HTTP_STATUS_503_SERVICE_UNAVAILABLE,
|
||||
HTTP_STATUS_504_GATEWAY_TIME_OUT,
|
||||
HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED,
|
||||
HTTP_STATUS_308_PERMANENT_REDIRECT
|
||||
HTTP_STATUS_308_PERMANENT_REDIRECT,
|
||||
HTTP_STATUS_429_TOO_MANY_REQUESTS
|
||||
} EFI_HTTP_STATUS_CODE;
|
||||
|
||||
///
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE;
|
|||
///
|
||||
/// Default IP TTL and ToS.
|
||||
///
|
||||
#define DEFAULT_TTL 16
|
||||
#define DEFAULT_TTL 64
|
||||
#define DEFAULT_ToS 0
|
||||
|
||||
///
|
||||
|
|
|
@ -8,11 +8,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_RNG_PROTOCOL_H__
|
||||
#define __EFI_RNG_PROTOCOL_H__
|
||||
#ifndef EFI_RNG_PROTOCOL_H_
|
||||
#define EFI_RNG_PROTOCOL_H_
|
||||
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
#include <ipxe/efi/Guid/Rng.h>
|
||||
|
||||
///
|
||||
/// Global ID for the Random Number Generator Protocol
|
||||
///
|
||||
|
@ -21,142 +23,8 @@ FILE_LICENCE ( BSD2_PATENT );
|
|||
0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
|
||||
}
|
||||
|
||||
typedef struct _EFI_RNG_PROTOCOL EFI_RNG_PROTOCOL;
|
||||
|
||||
///
|
||||
/// A selection of EFI_RNG_PROTOCOL algorithms.
|
||||
/// The algorithms listed are optional, not meant to be exhaustive and be argmented by
|
||||
/// vendors or other industry standards.
|
||||
///
|
||||
|
||||
typedef EFI_GUID EFI_RNG_ALGORITHM;
|
||||
|
||||
///
|
||||
/// The algorithms corresponds to SP800-90 as defined in
|
||||
/// NIST SP 800-90, "Recommendation for Random Number Generation Using Deterministic Random
|
||||
/// Bit Generators", March 2007.
|
||||
///
|
||||
#define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \
|
||||
{ \
|
||||
0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 } \
|
||||
}
|
||||
#define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \
|
||||
{ \
|
||||
0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 } \
|
||||
}
|
||||
#define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \
|
||||
{ \
|
||||
0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e } \
|
||||
}
|
||||
///
|
||||
/// The algorithms correspond to X9.31 as defined in
|
||||
/// NIST, "Recommended Random Number Generator Based on ANSI X9.31 Appendix A.2.4 Using
|
||||
/// the 3-Key Triple DES and AES Algorithm", January 2005.
|
||||
///
|
||||
#define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \
|
||||
{ \
|
||||
0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 } \
|
||||
}
|
||||
#define EFI_RNG_ALGORITHM_X9_31_AES_GUID \
|
||||
{ \
|
||||
0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 } \
|
||||
}
|
||||
///
|
||||
/// The "raw" algorithm, when supported, is intended to provide entropy directly from
|
||||
/// the source, without it going through some deterministic random bit generator.
|
||||
///
|
||||
#define EFI_RNG_ALGORITHM_RAW \
|
||||
{ \
|
||||
0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 } \
|
||||
}
|
||||
///
|
||||
/// The Arm Architecture states the RNDR that the DRBG algorithm should be compliant
|
||||
/// with NIST SP800-90A, while not mandating a particular algorithm, so as to be
|
||||
/// inclusive of different geographies.
|
||||
///
|
||||
#define EFI_RNG_ALGORITHM_ARM_RNDR \
|
||||
{ \
|
||||
0x43d2fde3, 0x9d4e, 0x4d79, {0x02, 0x96, 0xa8, 0x9b, 0xca, 0x78, 0x08, 0x41} \
|
||||
}
|
||||
|
||||
/**
|
||||
Returns information about the random number generation implementation.
|
||||
|
||||
@param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
|
||||
@param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
|
||||
On output with a return code of EFI_SUCCESS, the size
|
||||
in bytes of the data returned in RNGAlgorithmList. On output
|
||||
with a return code of EFI_BUFFER_TOO_SMALL,
|
||||
the size of RNGAlgorithmList required to obtain the list.
|
||||
@param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
|
||||
with one EFI_RNG_ALGORITHM element for each supported
|
||||
RNG algorithm. The list must not change across multiple
|
||||
calls to the same driver. The first algorithm in the list
|
||||
is the default algorithm for the driver.
|
||||
|
||||
@retval EFI_SUCCESS The RNG algorithm list was returned successfully.
|
||||
@retval EFI_UNSUPPORTED The services is not supported by this driver.
|
||||
@retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
|
||||
hardware or firmware error.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
|
||||
@retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_RNG_GET_INFO)(
|
||||
IN EFI_RNG_PROTOCOL *This,
|
||||
IN OUT UINTN *RNGAlgorithmListSize,
|
||||
OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
|
||||
);
|
||||
|
||||
/**
|
||||
Produces and returns an RNG value using either the default or specified RNG algorithm.
|
||||
|
||||
@param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
|
||||
@param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
|
||||
algorithm to use. May be NULL in which case the function will
|
||||
use its default RNG algorithm.
|
||||
@param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
|
||||
RNGValue. The driver shall return exactly this numbers of bytes.
|
||||
@param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
|
||||
resulting RNG value.
|
||||
|
||||
@retval EFI_SUCCESS The RNG value was returned successfully.
|
||||
@retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
|
||||
this driver.
|
||||
@retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
|
||||
firmware error.
|
||||
@retval EFI_NOT_READY There is not enough random data available to satisfy the length
|
||||
requested by RNGValueLength.
|
||||
@retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_RNG_GET_RNG)(
|
||||
IN EFI_RNG_PROTOCOL *This,
|
||||
IN EFI_RNG_ALGORITHM *RNGAlgorithm OPTIONAL,
|
||||
IN UINTN RNGValueLength,
|
||||
OUT UINT8 *RNGValue
|
||||
);
|
||||
|
||||
///
|
||||
/// The Random Number Generator (RNG) protocol provides random bits for use in
|
||||
/// applications, or entropy for seeding other random number generators.
|
||||
///
|
||||
struct _EFI_RNG_PROTOCOL {
|
||||
EFI_RNG_GET_INFO GetInfo;
|
||||
EFI_RNG_GET_RNG GetRNG;
|
||||
};
|
||||
typedef EFI_RNG_INTERFACE EFI_RNG_PROTOCOL;
|
||||
|
||||
extern EFI_GUID gEfiRngProtocolGuid;
|
||||
extern EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid;
|
||||
extern EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid;
|
||||
extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid;
|
||||
extern EFI_GUID gEfiRngAlgorithmX9313DesGuid;
|
||||
extern EFI_GUID gEfiRngAlgorithmX931AesGuid;
|
||||
extern EFI_GUID gEfiRngAlgorithmRaw;
|
||||
extern EFI_GUID gEfiRngAlgorithmArmRndr;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -102,6 +102,7 @@ EFI_STATUS
|
|||
@retval EFI_NOT_READY There was no keystroke data available.
|
||||
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to
|
||||
hardware errors.
|
||||
@retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data.
|
||||
|
||||
**/
|
||||
typedef
|
||||
|
|
|
@ -188,6 +188,7 @@ typedef struct {
|
|||
@retval EFI_NOT_READY There was no keystroke data available.
|
||||
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to
|
||||
hardware errors.
|
||||
@retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data.
|
||||
|
||||
|
||||
**/
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
/** @file
|
||||
TPM2 Protocol as defined in TCG PC Client Platform EFI Protocol Specification Family "2.0".
|
||||
See http://trustedcomputinggroup.org for the latest specification
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __TCG2_PROTOCOL_H__
|
||||
#define __TCG2_PROTOCOL_H__
|
||||
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
#include <ipxe/efi/IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <ipxe/efi/IndustryStandard/Tpm20.h>
|
||||
|
||||
|
@ -22,79 +21,79 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
|
||||
|
||||
typedef struct tdEFI_TCG2_VERSION {
|
||||
UINT8 Major;
|
||||
UINT8 Minor;
|
||||
UINT8 Major;
|
||||
UINT8 Minor;
|
||||
} EFI_TCG2_VERSION;
|
||||
|
||||
typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
|
||||
typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
|
||||
typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
|
||||
|
||||
#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
|
||||
#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002
|
||||
#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
|
||||
#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002
|
||||
|
||||
typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
|
||||
//
|
||||
// Allocated size of the structure
|
||||
//
|
||||
UINT8 Size;
|
||||
UINT8 Size;
|
||||
//
|
||||
// Version of the EFI_TCG2_BOOT_SERVICE_CAPABILITY structure itself.
|
||||
// For this version of the protocol, the Major version shall be set to 1
|
||||
// and the Minor version shall be set to 1.
|
||||
//
|
||||
EFI_TCG2_VERSION StructureVersion;
|
||||
EFI_TCG2_VERSION StructureVersion;
|
||||
//
|
||||
// Version of the EFI TCG2 protocol.
|
||||
// For this version of the protocol, the Major version shall be set to 1
|
||||
// and the Minor version shall be set to 1.
|
||||
//
|
||||
EFI_TCG2_VERSION ProtocolVersion;
|
||||
EFI_TCG2_VERSION ProtocolVersion;
|
||||
//
|
||||
// Supported hash algorithms (this bitmap is determined by the supported PCR
|
||||
// banks in the TPM and the hashing algorithms supported by the firmware)
|
||||
//
|
||||
EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
|
||||
EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
|
||||
//
|
||||
// Bitmap of supported event log formats
|
||||
//
|
||||
EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
|
||||
EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
|
||||
//
|
||||
// False = TPM not present
|
||||
//
|
||||
BOOLEAN TPMPresentFlag;
|
||||
BOOLEAN TPMPresentFlag;
|
||||
//
|
||||
// Max size (in bytes) of a command that can be sent to the TPM
|
||||
//
|
||||
UINT16 MaxCommandSize;
|
||||
UINT16 MaxCommandSize;
|
||||
//
|
||||
// Max size (in bytes) of a response that can be provided by the TPM
|
||||
//
|
||||
UINT16 MaxResponseSize;
|
||||
UINT16 MaxResponseSize;
|
||||
//
|
||||
// 4-byte Vendor ID
|
||||
// (see TCG Vendor ID registry, Section "TPM Capabilities Vendor ID")
|
||||
//
|
||||
UINT32 ManufacturerID;
|
||||
UINT32 ManufacturerID;
|
||||
//
|
||||
// Maximum number of PCR banks (hashing algorithms) supported.
|
||||
// No granularity is provided to support a specific set of algorithms.
|
||||
// Minimum value is 1.
|
||||
//
|
||||
UINT32 NumberOfPCRBanks;
|
||||
UINT32 NumberOfPCRBanks;
|
||||
//
|
||||
// A bitmap of currently active PCR banks (hashing algorithms).
|
||||
// This is a subset of the supported hashing algorithms reported in HashAlgorithmBitMap.
|
||||
// NumberOfPcrBanks defines the number of bits that are set.
|
||||
//
|
||||
EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
|
||||
EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
|
||||
} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
|
||||
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SHA1 0x00000001
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SHA256 0x00000002
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SHA384 0x00000004
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SHA512 0x00000008
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SM3_256 0x00000010
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SHA1 0x00000001
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SHA256 0x00000002
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SHA384 0x00000004
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SHA512 0x00000008
|
||||
#define EFI_TCG2_BOOT_HASH_ALG_SM3_256 0x00000010
|
||||
|
||||
//
|
||||
// This bit is shall be set when an event shall be extended but not logged.
|
||||
|
@ -103,7 +102,7 @@ typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
|
|||
//
|
||||
// This bit shall be set when the intent is to measure a PE/COFF image.
|
||||
//
|
||||
#define PE_COFF_IMAGE 0x0000000000000010
|
||||
#define PE_COFF_IMAGE 0x0000000000000010
|
||||
|
||||
#define MAX_PCR_INDEX 23
|
||||
|
||||
|
@ -115,28 +114,28 @@ typedef struct {
|
|||
//
|
||||
// Size of the event header itself (sizeof(EFI_TCG2_EVENT_HEADER)).
|
||||
//
|
||||
UINT32 HeaderSize;
|
||||
UINT32 HeaderSize;
|
||||
//
|
||||
// Header version. For this version of this specification, the value shall be 1.
|
||||
//
|
||||
UINT16 HeaderVersion;
|
||||
UINT16 HeaderVersion;
|
||||
//
|
||||
// Index of the PCR that shall be extended (0 - 23).
|
||||
//
|
||||
TCG_PCRINDEX PCRIndex;
|
||||
TCG_PCRINDEX PCRIndex;
|
||||
//
|
||||
// Type of the event that shall be extended (and optionally logged).
|
||||
//
|
||||
TCG_EVENTTYPE EventType;
|
||||
TCG_EVENTTYPE EventType;
|
||||
} EFI_TCG2_EVENT_HEADER;
|
||||
|
||||
typedef struct tdEFI_TCG2_EVENT {
|
||||
//
|
||||
// Total size of the event including the Size component, the header and the Event data.
|
||||
//
|
||||
UINT32 Size;
|
||||
EFI_TCG2_EVENT_HEADER Header;
|
||||
UINT8 Event[1];
|
||||
UINT32 Size;
|
||||
EFI_TCG2_EVENT_HEADER Header;
|
||||
UINT8 Event[1];
|
||||
} EFI_TCG2_EVENT;
|
||||
|
||||
#pragma pack()
|
||||
|
@ -144,12 +143,14 @@ typedef struct tdEFI_TCG2_EVENT {
|
|||
/**
|
||||
The EFI_TCG2_PROTOCOL GetCapability function call provides protocol
|
||||
capability information and state information.
|
||||
|
||||
@param[in] This Indicates the calling context
|
||||
@param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY
|
||||
structure and sets the size field to the size of the structure allocated.
|
||||
The callee fills in the fields with the EFI protocol capability information
|
||||
and the current EFI TCG2 state information up to the number of fields which
|
||||
fit within the size of the structure passed in.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
The ProtocolCapability variable will not be populated.
|
||||
|
@ -160,7 +161,7 @@ typedef struct tdEFI_TCG2_EVENT {
|
|||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_TCG2_GET_CAPABILITY) (
|
||||
(EFIAPI *EFI_TCG2_GET_CAPABILITY)(
|
||||
IN EFI_TCG2_PROTOCOL *This,
|
||||
IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability
|
||||
);
|
||||
|
@ -168,6 +169,7 @@ EFI_STATUS
|
|||
/**
|
||||
The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to
|
||||
retrieve the address of a given event log and its last entry.
|
||||
|
||||
@param[in] This Indicates the calling context
|
||||
@param[in] EventLogFormat The type of the event log for which the information is requested.
|
||||
@param[out] EventLogLocation A pointer to the memory address of the event log.
|
||||
|
@ -176,13 +178,14 @@ EFI_STATUS
|
|||
@param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
|
||||
have exceeded the area allocated for events, this value is set to TRUE.
|
||||
Otherwise, the value will be FALSE and the Event Log will be complete.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
|
||||
(e.g. asking for an event log whose format is not supported).
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_TCG2_GET_EVENT_LOG) (
|
||||
(EFIAPI *EFI_TCG2_GET_EVENT_LOG)(
|
||||
IN EFI_TCG2_PROTOCOL *This,
|
||||
IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
|
||||
|
@ -196,11 +199,13 @@ EFI_STATUS
|
|||
knowledge of actual TPM commands.
|
||||
The extend operation will occur even if this function cannot create an event
|
||||
log entry (e.g. due to the event log being full).
|
||||
|
||||
@param[in] This Indicates the calling context
|
||||
@param[in] Flags Bitmap providing additional information.
|
||||
@param[in] DataToHash Physical address of the start of the data buffer to be hashed.
|
||||
@param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
|
||||
@param[in] EfiTcgEvent Pointer to data buffer containing information about the event.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_DEVICE_ERROR The command was unsuccessful.
|
||||
@retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
|
||||
|
@ -209,7 +214,7 @@ EFI_STATUS
|
|||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI * EFI_TCG2_HASH_LOG_EXTEND_EVENT) (
|
||||
(EFIAPI *EFI_TCG2_HASH_LOG_EXTEND_EVENT)(
|
||||
IN EFI_TCG2_PROTOCOL *This,
|
||||
IN UINT64 Flags,
|
||||
IN EFI_PHYSICAL_ADDRESS DataToHash,
|
||||
|
@ -219,11 +224,13 @@ EFI_STATUS
|
|||
|
||||
/**
|
||||
This service enables the sending of commands to the TPM.
|
||||
|
||||
@param[in] This Indicates the calling context
|
||||
@param[in] InputParameterBlockSize Size of the TPM input parameter block.
|
||||
@param[in] InputParameterBlock Pointer to the TPM input parameter block.
|
||||
@param[in] OutputParameterBlockSize Size of the TPM output parameter block.
|
||||
@param[in] OutputParameterBlock Pointer to the TPM output parameter block.
|
||||
|
||||
@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
|
||||
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
|
||||
|
@ -231,7 +238,7 @@ EFI_STATUS
|
|||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_TCG2_SUBMIT_COMMAND) (
|
||||
(EFIAPI *EFI_TCG2_SUBMIT_COMMAND)(
|
||||
IN EFI_TCG2_PROTOCOL *This,
|
||||
IN UINT32 InputParameterBlockSize,
|
||||
IN UINT8 *InputParameterBlock,
|
||||
|
@ -241,59 +248,65 @@ EFI_STATUS
|
|||
|
||||
/**
|
||||
This service returns the currently active PCR banks.
|
||||
|
||||
@param[in] This Indicates the calling context
|
||||
@param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.
|
||||
|
||||
@retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_TCG2_GET_ACTIVE_PCR_BANKS) (
|
||||
(EFIAPI *EFI_TCG2_GET_ACTIVE_PCR_BANKS)(
|
||||
IN EFI_TCG2_PROTOCOL *This,
|
||||
OUT UINT32 *ActivePcrBanks
|
||||
);
|
||||
|
||||
/**
|
||||
This service sets the currently active PCR banks.
|
||||
|
||||
@param[in] This Indicates the calling context
|
||||
@param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.
|
||||
|
||||
@retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_TCG2_SET_ACTIVE_PCR_BANKS) (
|
||||
(EFIAPI *EFI_TCG2_SET_ACTIVE_PCR_BANKS)(
|
||||
IN EFI_TCG2_PROTOCOL *This,
|
||||
IN UINT32 ActivePcrBanks
|
||||
);
|
||||
|
||||
/**
|
||||
This service retrieves the result of a previous invocation of SetActivePcrBanks.
|
||||
|
||||
@param[in] This Indicates the calling context
|
||||
@param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.
|
||||
@param[out] Response The response from the SetActivePcrBank request.
|
||||
|
||||
@retval EFI_SUCCESS The result value could be returned.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS) (
|
||||
(EFIAPI *EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS)(
|
||||
IN EFI_TCG2_PROTOCOL *This,
|
||||
OUT UINT32 *OperationPresent,
|
||||
OUT UINT32 *Response
|
||||
);
|
||||
|
||||
struct tdEFI_TCG2_PROTOCOL {
|
||||
EFI_TCG2_GET_CAPABILITY GetCapability;
|
||||
EFI_TCG2_GET_EVENT_LOG GetEventLog;
|
||||
EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
|
||||
EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
|
||||
EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
|
||||
EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
|
||||
EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
|
||||
EFI_TCG2_GET_CAPABILITY GetCapability;
|
||||
EFI_TCG2_GET_EVENT_LOG GetEventLog;
|
||||
EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
|
||||
EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
|
||||
EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
|
||||
EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
|
||||
EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEfiTcg2ProtocolGuid;
|
||||
extern EFI_GUID gEfiTcg2ProtocolGuid;
|
||||
|
||||
//
|
||||
// Log entries after Get Event Log service
|
||||
|
@ -302,23 +315,23 @@ extern EFI_GUID gEfiTcg2ProtocolGuid;
|
|||
#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID \
|
||||
{0x1e2ed096, 0x30e2, 0x4254, { 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25 }}
|
||||
|
||||
extern EFI_GUID gEfiTcg2FinalEventsTableGuid;
|
||||
extern EFI_GUID gEfiTcg2FinalEventsTableGuid;
|
||||
|
||||
typedef struct tdEFI_TCG2_FINAL_EVENTS_TABLE {
|
||||
//
|
||||
// The version of this structure.
|
||||
//
|
||||
UINT64 Version;
|
||||
UINT64 Version;
|
||||
//
|
||||
// Number of events recorded after invocation of GetEventLog API
|
||||
//
|
||||
UINT64 NumberOfEvents;
|
||||
UINT64 NumberOfEvents;
|
||||
//
|
||||
// List of events of type TCG_PCR_EVENT2.
|
||||
//
|
||||
//TCG_PCR_EVENT2 Event[1];
|
||||
// TCG_PCR_EVENT2 Event[1];
|
||||
} EFI_TCG2_FINAL_EVENTS_TABLE;
|
||||
|
||||
#define EFI_TCG2_FINAL_EVENTS_TABLE_VERSION 1
|
||||
#define EFI_TCG2_FINAL_EVENTS_TABLE_VERSION 1
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef _IPXE_EFI_USBHOSTCONTROLLER_H
|
||||
#define _IPXE_EFI_USBHOSTCONTROLLER_H
|
||||
|
||||
/** @file
|
||||
EFI_USB_HC_PROTOCOL as defined in EFI 1.10.
|
||||
|
||||
|
@ -501,3 +504,5 @@ struct _EFI_USB_HC_PROTOCOL {
|
|||
extern EFI_GUID gEfiUsbHcProtocolGuid;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _IPXE_EFI_USBHOSTCONTROLLER_H */
|
||||
|
|
|
@ -1698,7 +1698,17 @@ typedef enum {
|
|||
EfiKeyF12,
|
||||
EfiKeyPrint,
|
||||
EfiKeySLck,
|
||||
EfiKeyPause
|
||||
EfiKeyPause,
|
||||
EfiKeyIntl0,
|
||||
EfiKeyIntl1,
|
||||
EfiKeyIntl2,
|
||||
EfiKeyIntl3,
|
||||
EfiKeyIntl4,
|
||||
EfiKeyIntl5,
|
||||
EfiKeyIntl6,
|
||||
EfiKeyIntl7,
|
||||
EfiKeyIntl8,
|
||||
EfiKeyIntl9
|
||||
} EFI_KEY;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -110,7 +110,22 @@ typedef enum {
|
|||
/// by a corresponding call to the underlying isolation architecture.
|
||||
///
|
||||
EfiUnacceptedMemoryType,
|
||||
EfiMaxMemoryType
|
||||
EfiMaxMemoryType,
|
||||
//
|
||||
// +---------------------------------------------------+
|
||||
// | 0..(EfiMaxMemoryType - 1) - Normal memory type |
|
||||
// +---------------------------------------------------+
|
||||
// | EfiMaxMemoryType..0x6FFFFFFF - Invalid |
|
||||
// +---------------------------------------------------+
|
||||
// | 0x70000000..0x7FFFFFFF - OEM reserved |
|
||||
// +---------------------------------------------------+
|
||||
// | 0x80000000..0xFFFFFFFF - OS reserved |
|
||||
// +---------------------------------------------------+
|
||||
//
|
||||
MEMORY_TYPE_OEM_RESERVED_MIN = 0x70000000,
|
||||
MEMORY_TYPE_OEM_RESERVED_MAX = 0x7FFFFFFF,
|
||||
MEMORY_TYPE_OS_RESERVED_MIN = 0x80000000,
|
||||
MEMORY_TYPE_OS_RESERVED_MAX = 0xFFFFFFFF
|
||||
} EFI_MEMORY_TYPE;
|
||||
|
||||
///
|
||||
|
|
|
@ -107,6 +107,16 @@ typedef enum {
|
|||
//
|
||||
#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000ULL
|
||||
|
||||
//
|
||||
// If this flag is set, the memory region is present and capable of having
|
||||
// memory dynamically removed from the platform. This attribute serves as
|
||||
// a hint to the OS prior to its ACPI subsystem initialization to avoid
|
||||
// allocating this memory for core OS data or code that cannot be dynamically
|
||||
// relocated at runtime. If this flag is clear, the memory region is not
|
||||
// capable of being dynamically removed from the platform at runtime.
|
||||
//
|
||||
#define EFI_MEMORY_HOT_PLUGGABLE 0x0000000000100000
|
||||
|
||||
//
|
||||
// Runtime memory attribute
|
||||
//
|
||||
|
@ -1841,21 +1851,24 @@ EFI_STATUS
|
|||
//
|
||||
// EFI Runtime Services Table
|
||||
//
|
||||
#define EFI_SYSTEM_TABLE_SIGNATURE SIGNATURE_64 ('I','B','I',' ','S','Y','S','T')
|
||||
#define EFI_2_80_SYSTEM_TABLE_REVISION ((2 << 16) | (80))
|
||||
#define EFI_2_70_SYSTEM_TABLE_REVISION ((2 << 16) | (70))
|
||||
#define EFI_2_60_SYSTEM_TABLE_REVISION ((2 << 16) | (60))
|
||||
#define EFI_2_50_SYSTEM_TABLE_REVISION ((2 << 16) | (50))
|
||||
#define EFI_2_40_SYSTEM_TABLE_REVISION ((2 << 16) | (40))
|
||||
#define EFI_2_31_SYSTEM_TABLE_REVISION ((2 << 16) | (31))
|
||||
#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30))
|
||||
#define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20))
|
||||
#define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10))
|
||||
#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00))
|
||||
#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
|
||||
#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
|
||||
#define EFI_SYSTEM_TABLE_REVISION EFI_2_70_SYSTEM_TABLE_REVISION
|
||||
#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION
|
||||
#define EFI_SYSTEM_TABLE_SIGNATURE SIGNATURE_64 ('I','B','I',' ','S','Y','S','T')
|
||||
#define EFI_2_110_SYSTEM_TABLE_REVISION ((2 << 16) | (110))
|
||||
#define EFI_2_100_SYSTEM_TABLE_REVISION ((2 << 16) | (100))
|
||||
#define EFI_2_90_SYSTEM_TABLE_REVISION ((2 << 16) | (90))
|
||||
#define EFI_2_80_SYSTEM_TABLE_REVISION ((2 << 16) | (80))
|
||||
#define EFI_2_70_SYSTEM_TABLE_REVISION ((2 << 16) | (70))
|
||||
#define EFI_2_60_SYSTEM_TABLE_REVISION ((2 << 16) | (60))
|
||||
#define EFI_2_50_SYSTEM_TABLE_REVISION ((2 << 16) | (50))
|
||||
#define EFI_2_40_SYSTEM_TABLE_REVISION ((2 << 16) | (40))
|
||||
#define EFI_2_31_SYSTEM_TABLE_REVISION ((2 << 16) | (31))
|
||||
#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30))
|
||||
#define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20))
|
||||
#define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10))
|
||||
#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00))
|
||||
#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
|
||||
#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
|
||||
#define EFI_SYSTEM_TABLE_REVISION EFI_2_70_SYSTEM_TABLE_REVISION
|
||||
#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION
|
||||
|
||||
#define EFI_RUNTIME_SERVICES_SIGNATURE SIGNATURE_64 ('R','U','N','T','S','E','R','V')
|
||||
#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION
|
||||
|
@ -2044,7 +2057,8 @@ typedef struct {
|
|||
UINT32 FirmwareRevision;
|
||||
///
|
||||
/// The handle for the active console input device. This handle must support
|
||||
/// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
|
||||
/// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL. If
|
||||
/// there is no active console, these protocols must still be present.
|
||||
///
|
||||
EFI_HANDLE ConsoleInHandle;
|
||||
///
|
||||
|
@ -2053,7 +2067,9 @@ typedef struct {
|
|||
///
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
|
||||
///
|
||||
/// The handle for the active console output device.
|
||||
/// The handle for the active console output device. This handle must support the
|
||||
/// EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. If there is no active console, these protocols
|
||||
/// must still be present.
|
||||
///
|
||||
EFI_HANDLE ConsoleOutHandle;
|
||||
///
|
||||
|
@ -2063,7 +2079,8 @@ typedef struct {
|
|||
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
|
||||
///
|
||||
/// The handle for the active standard error console device.
|
||||
/// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
|
||||
/// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. If there
|
||||
/// is no active console, this protocol must still be present.
|
||||
///
|
||||
EFI_HANDLE StandardErrorHandle;
|
||||
///
|
||||
|
|
|
@ -219,6 +219,7 @@ extern EFI_GUID efi_nii31_protocol_guid;
|
|||
extern EFI_GUID efi_pci_io_protocol_guid;
|
||||
extern EFI_GUID efi_pci_root_bridge_io_protocol_guid;
|
||||
extern EFI_GUID efi_pxe_base_code_protocol_guid;
|
||||
extern EFI_GUID efi_rng_protocol_guid;
|
||||
extern EFI_GUID efi_serial_io_protocol_guid;
|
||||
extern EFI_GUID efi_shim_lock_protocol_guid;
|
||||
extern EFI_GUID efi_simple_file_system_protocol_guid;
|
||||
|
@ -228,6 +229,7 @@ extern EFI_GUID efi_simple_text_input_protocol_guid;
|
|||
extern EFI_GUID efi_simple_text_input_ex_protocol_guid;
|
||||
extern EFI_GUID efi_simple_text_output_protocol_guid;
|
||||
extern EFI_GUID efi_tcg_protocol_guid;
|
||||
extern EFI_GUID efi_tcg2_protocol_guid;
|
||||
extern EFI_GUID efi_tcp4_protocol_guid;
|
||||
extern EFI_GUID efi_tcp4_service_binding_protocol_guid;
|
||||
extern EFI_GUID efi_tcp6_protocol_guid;
|
||||
|
@ -244,8 +246,11 @@ extern EFI_GUID efi_usb2_hc_protocol_guid;
|
|||
extern EFI_GUID efi_usb_io_protocol_guid;
|
||||
extern EFI_GUID efi_vlan_config_protocol_guid;
|
||||
|
||||
extern EFI_GUID efi_cert_x509_guid;
|
||||
extern EFI_GUID efi_file_info_id;
|
||||
extern EFI_GUID efi_file_system_info_id;
|
||||
extern EFI_GUID efi_global_variable;
|
||||
extern EFI_GUID efi_tls_ca_certificate_guid;
|
||||
|
||||
extern EFI_HANDLE efi_image_handle;
|
||||
extern EFI_LOADED_IMAGE_PROTOCOL *efi_loaded_image;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef _IPXE_EFI_SIGLIST_H
|
||||
#define _IPXE_EFI_SIGLIST_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* PEM-encoded ASN.1 data
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/uaccess.h>
|
||||
#include <ipxe/asn1.h>
|
||||
#include <ipxe/image.h>
|
||||
|
||||
extern int efisig_asn1 ( userptr_t data, size_t len, size_t offset,
|
||||
struct asn1_cursor **cursor );
|
||||
|
||||
extern struct image_type efisig_image_type __image_type ( PROBE_NORMAL );
|
||||
|
||||
#endif /* _IPXE_EFI_SIGLIST_H */
|
|
@ -10,7 +10,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
#include <ipxe/efi/efi.h>
|
||||
|
||||
extern EFI_BOOT_SERVICES * efi_wrap_bs ( void );
|
||||
extern void efi_wrap ( EFI_HANDLE handle );
|
||||
extern void efi_wrap_bs ( EFI_BOOT_SERVICES *wrapped );
|
||||
extern void efi_wrap_systab ( int global );
|
||||
extern void efi_unwrap ( void );
|
||||
|
||||
extern void efi_wrap_image ( EFI_HANDLE handle );
|
||||
|
||||
#endif /* _IPXE_EFI_WRAP_H */
|
||||
|
|
|
@ -118,7 +118,8 @@ pod2usage ( 1 ) unless @ARGV == 1;
|
|||
my $edktop = shift;
|
||||
|
||||
# Identify edk import directories
|
||||
my $edkdirs = [ "MdePkg/Include", "MdeModulePkg/Include" ];
|
||||
my $edkdirs = [ "MdePkg/Include", "MdeModulePkg/Include",
|
||||
"NetworkPkg/Include" ];
|
||||
foreach my $edkdir ( @$edkdirs ) {
|
||||
die "Directory \"$edktop\" does not appear to contain the EFI EDK2 "
|
||||
."(missing \"$edkdir\")\n" unless -d catdir ( $edktop, $edkdir );
|
||||
|
|
|
@ -323,6 +323,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define ERRFILE_archive ( ERRFILE_IMAGE | 0x000a0000 )
|
||||
#define ERRFILE_zlib ( ERRFILE_IMAGE | 0x000b0000 )
|
||||
#define ERRFILE_gzip ( ERRFILE_IMAGE | 0x000c0000 )
|
||||
#define ERRFILE_efi_siglist ( ERRFILE_IMAGE | 0x000d0000 )
|
||||
|
||||
#define ERRFILE_asn1 ( ERRFILE_OTHER | 0x00000000 )
|
||||
#define ERRFILE_chap ( ERRFILE_OTHER | 0x00010000 )
|
||||
|
@ -426,7 +427,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define ERRFILE_form_ui ( ERRFILE_OTHER | 0x00630000 )
|
||||
#define ERRFILE_usb_cmd ( ERRFILE_OTHER | 0x00640000 )
|
||||
#define ERRFILE_usb_settings ( ERRFILE_OTHER | 0x00650000 )
|
||||
#define ERRFILE_tpm ( ERRFILE_OTHER | 0x00660000 )
|
||||
#define ERRFILE_weierstrass ( ERRFILE_OTHER | 0x00660000 )
|
||||
#define ERRFILE_efi_cacert ( ERRFILE_OTHER | 0x00670000 )
|
||||
#define ERRFILE_tpm ( ERRFILE_OTHER | 0x00680000 )
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ extern size_t maxusedmem;
|
|||
extern void * __malloc alloc_memblock ( size_t size, size_t align,
|
||||
size_t offset );
|
||||
extern void free_memblock ( void *ptr, size_t size );
|
||||
extern void mpopulate ( void *start, size_t len );
|
||||
extern void mdumpfree ( void );
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef _IPXE_P256_H
|
||||
#define _IPXE_P256_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* NIST P-256 elliptic curve
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/weierstrass.h>
|
||||
|
||||
/** P-256 value length */
|
||||
#define P256_LEN ( 256 / 8 )
|
||||
|
||||
extern struct elliptic_curve p256_curve;
|
||||
|
||||
#endif /* _IPXE_P256_H */
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef _IPXE_P384_H
|
||||
#define _IPXE_P384_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* NIST P-384 elliptic curve
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/weierstrass.h>
|
||||
|
||||
/** P-384 value length */
|
||||
#define P384_LEN ( 384 / 8 )
|
||||
|
||||
extern struct elliptic_curve p384_curve;
|
||||
|
||||
#endif /* _IPXE_P384_H */
|
|
@ -16,28 +16,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
struct random_bit_generator {
|
||||
/** DRBG state */
|
||||
struct drbg_state state;
|
||||
/** Startup has been attempted */
|
||||
int started;
|
||||
};
|
||||
|
||||
extern struct random_bit_generator rbg;
|
||||
|
||||
/**
|
||||
* Generate bits using RBG
|
||||
*
|
||||
* @v additional Additional input
|
||||
* @v additional_len Length of additional input
|
||||
* @v prediction_resist Prediction resistance is required
|
||||
* @v data Output buffer
|
||||
* @v len Length of output buffer
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This is the RBG_Generate function defined in ANS X9.82 Part 4
|
||||
* (April 2011 Draft) Section 9.1.2.2.
|
||||
*/
|
||||
static inline int rbg_generate ( const void *additional, size_t additional_len,
|
||||
int prediction_resist, void *data,
|
||||
size_t len ) {
|
||||
return drbg_generate ( &rbg.state, additional, additional_len,
|
||||
prediction_resist, data, len );
|
||||
}
|
||||
extern int rbg_generate ( const void *additional, size_t additional_len,
|
||||
int prediction_resist, void *data, size_t len );
|
||||
|
||||
#endif /* _IPXE_RBG_H */
|
||||
|
|
|
@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
#include <ipxe/x509.h>
|
||||
|
||||
extern const int allow_trust_override;
|
||||
extern struct x509_root root_certificates;
|
||||
|
||||
#endif /* _IPXE_ROOTCERT_H */
|
||||
|
|
|
@ -127,6 +127,8 @@ struct tls_header {
|
|||
|
||||
/* TLS named curve extension */
|
||||
#define TLS_NAMED_CURVE 10
|
||||
#define TLS_NAMED_CURVE_SECP256R1 23
|
||||
#define TLS_NAMED_CURVE_SECP384R1 24
|
||||
#define TLS_NAMED_CURVE_X25519 29
|
||||
|
||||
/* TLS signature algorithms extension */
|
||||
|
@ -218,12 +220,19 @@ struct tls_cipher_suite {
|
|||
/** TLS named curved type */
|
||||
#define TLS_NAMED_CURVE_TYPE 3
|
||||
|
||||
/** TLS uncompressed curve point format */
|
||||
#define TLS_POINT_FORMAT_UNCOMPRESSED 4
|
||||
|
||||
/** A TLS named curve */
|
||||
struct tls_named_curve {
|
||||
/** Elliptic curve */
|
||||
struct elliptic_curve *curve;
|
||||
/** Numeric code (in network-endian order) */
|
||||
uint16_t code;
|
||||
/** Curve point format byte (if any) */
|
||||
uint8_t format;
|
||||
/** Pre-master secret length */
|
||||
uint8_t pre_master_secret_len;
|
||||
};
|
||||
|
||||
/** TLS named curve table */
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
#ifndef _IPXE_WEIERSTRASS_H
|
||||
#define _IPXE_WEIERSTRASS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Weierstrass elliptic curves
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/bigint.h>
|
||||
#include <ipxe/crypto.h>
|
||||
|
||||
/** Number of axes in Weierstrass curve point representation */
|
||||
#define WEIERSTRASS_AXES 2
|
||||
|
||||
/**
|
||||
* Maximum multiple of field prime encountered during calculations
|
||||
*
|
||||
* Calculations are performed using values modulo a small multiple of
|
||||
* the field prime, rather than modulo the field prime itself. This
|
||||
* allows explicit reductions after additions, subtractions, and
|
||||
* relaxed Montgomery multiplications to be omitted entirely, provided
|
||||
* that we keep careful track of the field prime multiple for each
|
||||
* intermediate value.
|
||||
*
|
||||
* Relaxed Montgomery multiplication will produce a result in the
|
||||
* range t < (1+m/k)N, where m is this maximum multiple of the field
|
||||
* prime, and k is the constant in R > kN representing the leading
|
||||
* zero padding in the big integer representation of the field prime.
|
||||
* We choose to set k=m so that multiplications will always produce a
|
||||
* result in the range t < 2N.
|
||||
*
|
||||
* This is expressed as the base-two logarithm of the multiple
|
||||
* (rounded up), to simplify compile-time calculations.
|
||||
*/
|
||||
#define WEIERSTRASS_MAX_MULTIPLE_LOG2 5 /* maximum reached is mod 20N */
|
||||
|
||||
/**
|
||||
* Determine number of elements in scalar values for a Weierstrass curve
|
||||
*
|
||||
* @v len Length of field prime, in bytes
|
||||
* @ret size Number of elements
|
||||
*/
|
||||
#define weierstrass_size( len ) \
|
||||
bigint_required_size ( (len) + \
|
||||
( ( WEIERSTRASS_MAX_MULTIPLE_LOG2 + 7 ) \
|
||||
/ 8 ) )
|
||||
|
||||
/**
|
||||
* Define a Weierstrass projective co-ordinate type
|
||||
*
|
||||
* @v size Number of elements in scalar values
|
||||
* @ret weierstrass_t Projective co-ordinate type
|
||||
*/
|
||||
#define weierstrass_t( size ) \
|
||||
union { \
|
||||
bigint_t ( size ) axis[3]; \
|
||||
struct { \
|
||||
bigint_t ( size ) x; \
|
||||
bigint_t ( size ) y; \
|
||||
bigint_t ( size ) z; \
|
||||
}; \
|
||||
bigint_t ( size * 3 ) all; \
|
||||
}
|
||||
|
||||
/** Indexes for stored multiples of the field prime */
|
||||
enum weierstrass_multiple {
|
||||
WEIERSTRASS_N = 0,
|
||||
WEIERSTRASS_2N,
|
||||
WEIERSTRASS_4N,
|
||||
WEIERSTRASS_NUM_MULTIPLES
|
||||
};
|
||||
|
||||
/** Number of cached in Montgomery form for each Weierstrass curve */
|
||||
#define WEIERSTRASS_NUM_MONT 3
|
||||
|
||||
/** Number of cached big integers for each Weierstrass curve */
|
||||
#define WEIERSTRASS_NUM_CACHED \
|
||||
( WEIERSTRASS_NUM_MULTIPLES + \
|
||||
1 /* fermat */ + 1 /* mont */ + \
|
||||
WEIERSTRASS_NUM_MONT )
|
||||
|
||||
/**
|
||||
* A Weierstrass elliptic curve
|
||||
*
|
||||
* This is an elliptic curve y^2 = x^3 + ax + b
|
||||
*/
|
||||
struct weierstrass_curve {
|
||||
/** Number of elements in scalar values */
|
||||
const unsigned int size;
|
||||
/** Curve name */
|
||||
const char *name;
|
||||
/** Length of raw scalar values */
|
||||
size_t len;
|
||||
/** Field prime */
|
||||
const uint8_t *prime_raw;
|
||||
/** Constant "a" */
|
||||
const uint8_t *a_raw;
|
||||
/** Constant "b" */
|
||||
const uint8_t *b_raw;
|
||||
/** Base point */
|
||||
const uint8_t *base;
|
||||
|
||||
/** Cached field prime "N" (and multiples thereof) */
|
||||
bigint_element_t *prime[WEIERSTRASS_NUM_CACHED];
|
||||
/** Cached constant "N-2" (for Fermat's little theorem) */
|
||||
bigint_element_t *fermat;
|
||||
/** Cached Montgomery constant (R^2 mod N) */
|
||||
bigint_element_t *square;
|
||||
/** Cached constants in Montgomery form */
|
||||
union {
|
||||
struct {
|
||||
/** Cached constant "1", in Montgomery form */
|
||||
bigint_element_t *one;
|
||||
/** Cached constant "a", in Montgomery form */
|
||||
bigint_element_t *a;
|
||||
/** Cached constant "3b", in Montgomery form */
|
||||
bigint_element_t *b3;
|
||||
};
|
||||
bigint_element_t *mont[WEIERSTRASS_NUM_MONT];
|
||||
};
|
||||
};
|
||||
|
||||
extern int weierstrass_multiply ( struct weierstrass_curve *curve,
|
||||
const void *base, const void *scalar,
|
||||
void *result );
|
||||
|
||||
/** Define a Weierstrass curve */
|
||||
#define WEIERSTRASS_CURVE( _name, _curve, _len, _prime, _a, _b, _base ) \
|
||||
static bigint_t ( weierstrass_size(_len) ) \
|
||||
_name ## _cache[WEIERSTRASS_NUM_CACHED]; \
|
||||
static struct weierstrass_curve _name ## _weierstrass = { \
|
||||
.size = weierstrass_size(_len), \
|
||||
.name = #_name, \
|
||||
.len = (_len), \
|
||||
.prime_raw = (_prime), \
|
||||
.a_raw = (_a), \
|
||||
.b_raw = (_b), \
|
||||
.base = (_base), \
|
||||
.prime = { \
|
||||
(_name ## _cache)[0].element, \
|
||||
(_name ## _cache)[1].element, \
|
||||
(_name ## _cache)[2].element, \
|
||||
}, \
|
||||
.fermat = (_name ## _cache)[3].element, \
|
||||
.square = (_name ## _cache)[4].element, \
|
||||
.one = (_name ## _cache)[5].element, \
|
||||
.a = (_name ## _cache)[6].element, \
|
||||
.b3 = (_name ## _cache)[7].element, \
|
||||
}; \
|
||||
static int _name ## _multiply ( const void *base, \
|
||||
const void *scalar, \
|
||||
void *result ) { \
|
||||
return weierstrass_multiply ( &_name ## _weierstrass, \
|
||||
base, scalar, result ); \
|
||||
} \
|
||||
struct elliptic_curve _curve = { \
|
||||
.name = #_name, \
|
||||
.pointsize = ( WEIERSTRASS_AXES * (_len) ), \
|
||||
.keysize = (_len), \
|
||||
.multiply = _name ## _multiply, \
|
||||
}
|
||||
|
||||
#endif /* _IPXE_WEIERSTRASS_H */
|
|
@ -421,6 +421,9 @@ extern int x509_certificate ( const void *data, size_t len,
|
|||
struct x509_certificate **cert );
|
||||
extern int x509_is_valid ( struct x509_certificate *cert,
|
||||
struct x509_root *root );
|
||||
extern void x509_set_valid ( struct x509_certificate *cert,
|
||||
struct x509_certificate *issuer,
|
||||
struct x509_root *root );
|
||||
extern int x509_validate ( struct x509_certificate *cert,
|
||||
struct x509_certificate *issuer,
|
||||
time_t time, struct x509_root *root );
|
||||
|
|
|
@ -43,7 +43,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
*/
|
||||
|
||||
/** Timeout for autoexec script downloads */
|
||||
#define EFI_AUTOEXEC_TIMEOUT ( 2 * TICKS_PER_SEC )
|
||||
#define EFI_AUTOEXEC_TIMEOUT ( 30 * TICKS_PER_SEC )
|
||||
|
||||
/** Timeout for autoexec pending operation completion */
|
||||
#define EFI_AUTOEXEC_SYNC_TIMEOUT ( 1 * TICKS_PER_SEC )
|
||||
|
||||
/** Autoexec script image name */
|
||||
#define EFI_AUTOEXEC_NAME "autoexec.ipxe"
|
||||
|
@ -136,7 +139,7 @@ static int efi_autoexec_network ( EFI_HANDLE handle, struct image **image ) {
|
|||
}
|
||||
|
||||
/* Ensure network exchanges have completed */
|
||||
sync ( EFI_AUTOEXEC_TIMEOUT );
|
||||
sync ( EFI_AUTOEXEC_SYNC_TIMEOUT );
|
||||
|
||||
err_open:
|
||||
err_cwuri:
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI CA certificates
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/x509.h>
|
||||
#include <ipxe/rootcert.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/efi_siglist.h>
|
||||
#include <ipxe/efi/Guid/TlsAuthentication.h>
|
||||
|
||||
/** List of EFI CA certificates */
|
||||
static struct x509_chain efi_cacerts = {
|
||||
.refcnt = REF_INIT ( ref_no_free ),
|
||||
.links = LIST_HEAD_INIT ( efi_cacerts.links ),
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve EFI CA certificate
|
||||
*
|
||||
* @v data TlsCaCertificate variable data
|
||||
* @v len Length of TlsCaCertificate
|
||||
* @v offset Offset within data
|
||||
* @v next Next offset, or negative error
|
||||
*/
|
||||
static int efi_cacert ( void *data, size_t len, size_t offset ) {
|
||||
struct asn1_cursor *cursor;
|
||||
struct x509_certificate *cert;
|
||||
int next;
|
||||
int rc;
|
||||
|
||||
/* Extract ASN.1 object */
|
||||
next = efisig_asn1 ( virt_to_user ( data ), len, offset, &cursor );
|
||||
if ( next < 0 ) {
|
||||
rc = next;
|
||||
DBGC ( &efi_cacerts, "EFICA could not parse at +%#zx: %s\n",
|
||||
offset, strerror ( rc ) );
|
||||
goto err_asn1;
|
||||
}
|
||||
|
||||
/* Append to list of EFI CA certificates */
|
||||
if ( ( rc = x509_append_raw ( &efi_cacerts, cursor->data,
|
||||
cursor->len ) ) != 0 ) {
|
||||
DBGC ( &efi_cacerts, "EFICA could not append at +%#zx: %s\n",
|
||||
offset, strerror ( rc ) );
|
||||
goto err_append;
|
||||
}
|
||||
cert = x509_last ( &efi_cacerts );
|
||||
DBGC ( &efi_cacerts, "EFICA found certificate %s\n",
|
||||
x509_name ( cert ) );
|
||||
|
||||
/* Mark certificate as valid (i.e. trusted) if permitted */
|
||||
if ( allow_trust_override ) {
|
||||
DBGC ( &efi_cacerts, "EFICA trusting certificate %s\n",
|
||||
x509_name ( cert ) );
|
||||
x509_set_valid ( cert, NULL, &root_certificates );
|
||||
}
|
||||
|
||||
/* Free ASN.1 object */
|
||||
free ( cursor );
|
||||
|
||||
return next;
|
||||
|
||||
err_append:
|
||||
free ( cursor );
|
||||
err_asn1:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all EFI CA certificates
|
||||
*
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int efi_cacert_all ( void ) {
|
||||
EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
|
||||
EFI_GUID *guid = &efi_tls_ca_certificate_guid;
|
||||
static CHAR16 *wname = EFI_TLS_CA_CERTIFICATE_VARIABLE;
|
||||
int offset = 0;
|
||||
UINT32 attrs;
|
||||
UINTN size;
|
||||
void *data;
|
||||
EFI_STATUS efirc;
|
||||
int rc;
|
||||
|
||||
/* Get variable length */
|
||||
size = 0;
|
||||
if ( ( efirc = rs->GetVariable ( wname, guid, &attrs, &size,
|
||||
NULL ) ) != EFI_BUFFER_TOO_SMALL ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( &efi_cacerts, "EFICA could not get %ls size: %s\n",
|
||||
wname, strerror ( rc ) );
|
||||
goto err_len;
|
||||
}
|
||||
|
||||
/* Allocate temporary buffer */
|
||||
data = malloc ( size );
|
||||
if ( ! data ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
/* Read variable */
|
||||
if ( ( efirc = rs->GetVariable ( wname, guid, &attrs, &size,
|
||||
data ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( &efi_cacerts, "EFICA could not read %ls: %s\n",
|
||||
wname, strerror ( rc ) );
|
||||
goto err_get;
|
||||
}
|
||||
|
||||
/* Parse certificates */
|
||||
while ( ( ( size_t ) offset ) < size ) {
|
||||
offset = efi_cacert ( data, size, offset );
|
||||
if ( offset < 0 ) {
|
||||
rc = offset;
|
||||
goto err_cacert;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success */
|
||||
rc = 0;
|
||||
|
||||
err_cacert:
|
||||
err_get:
|
||||
free ( data );
|
||||
err_alloc:
|
||||
err_len:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise EFI CA certificates
|
||||
*
|
||||
*/
|
||||
static void efi_cacert_init ( void ) {
|
||||
int rc;
|
||||
|
||||
/* Initialise all certificates */
|
||||
if ( ( rc = efi_cacert_all() ) != 0 ) {
|
||||
DBGC ( &efi_cacert, "EFICA could not initialise: %s\n",
|
||||
strerror ( rc ) );
|
||||
/* Nothing we can do at this point */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** EFI CA certificates initialisation function */
|
||||
struct init_fn efi_cacert_init_fn __init_fn ( INIT_LATE ) = {
|
||||
.initialise = efi_cacert_init,
|
||||
};
|
||||
|
||||
/**
|
||||
* Discard any EFI CA certificates
|
||||
*
|
||||
*/
|
||||
static void efi_cacert_shutdown ( int booting __unused ) {
|
||||
|
||||
/* Drop our references to the certificates */
|
||||
DBGC ( &efi_cacert, "EFICA discarding certificates\n" );
|
||||
x509_truncate ( &efi_cacerts, NULL );
|
||||
assert ( list_empty ( &efi_cacerts.links ) );
|
||||
}
|
||||
|
||||
/** EFI CA certificates shutdown function */
|
||||
struct startup_fn efi_cacert_shutdown_fn __startup_fn ( STARTUP_NORMAL ) = {
|
||||
.name = "efi_cacert",
|
||||
.shutdown = efi_cacert_shutdown,
|
||||
};
|
|
@ -31,15 +31,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/uuid.h>
|
||||
#include <ipxe/base16.h>
|
||||
#include <ipxe/vsprintf.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/efi_path.h>
|
||||
#include <ipxe/efi/Protocol/ComponentName.h>
|
||||
#include <ipxe/efi/Protocol/ComponentName2.h>
|
||||
#include <ipxe/efi/Protocol/DriverBinding.h>
|
||||
#include <ipxe/efi/Protocol/DevicePathToText.h>
|
||||
#include <ipxe/efi/IndustryStandard/PeImage.h>
|
||||
|
||||
|
@ -47,236 +46,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *efidpt;
|
||||
EFI_REQUEST_PROTOCOL ( EFI_DEVICE_PATH_TO_TEXT_PROTOCOL, &efidpt );
|
||||
|
||||
/** HttpBootDxe module GUID */
|
||||
static EFI_GUID efi_http_boot_dxe_guid = {
|
||||
0xecebcb00, 0xd9c8, 0x11e4,
|
||||
{ 0xaf, 0x3d, 0x8c, 0xdc, 0xd4, 0x26, 0xc9, 0x73 }
|
||||
};
|
||||
|
||||
/** IScsiDxe module GUID */
|
||||
static EFI_GUID efi_iscsi_dxe_guid = {
|
||||
0x86cddf93, 0x4872, 0x4597,
|
||||
{ 0x8a, 0xf9, 0xa3, 0x5a, 0xe4, 0xd3, 0x72, 0x5f }
|
||||
};
|
||||
|
||||
/** Old IScsi4Dxe module GUID */
|
||||
static EFI_GUID efi_iscsi4_dxe_guid = {
|
||||
0x4579b72d, 0x7ec4, 0x4dd4,
|
||||
{ 0x84, 0x86, 0x08, 0x3c, 0x86, 0xb1, 0x82, 0xa7 }
|
||||
};
|
||||
|
||||
/** UefiPxeBcDxe module GUID */
|
||||
static EFI_GUID efi_uefi_pxe_bc_dxe_guid = {
|
||||
0xb95e9fda, 0x26de, 0x48d2,
|
||||
{ 0x88, 0x07, 0x1f, 0x91, 0x07, 0xac, 0x5e, 0x3a }
|
||||
};
|
||||
|
||||
/** VlanConfigDxe module GUID */
|
||||
static EFI_GUID efi_vlan_config_dxe_guid = {
|
||||
0xe4f61863, 0xfe2c, 0x4b56,
|
||||
{ 0xa8, 0xf4, 0x08, 0x51, 0x9b, 0xc4, 0x39, 0xdf }
|
||||
};
|
||||
|
||||
/** A well-known GUID */
|
||||
struct efi_well_known_guid {
|
||||
/** GUID */
|
||||
EFI_GUID *guid;
|
||||
/** Name */
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/** Well-known GUIDs */
|
||||
static struct efi_well_known_guid efi_well_known_guids[] = {
|
||||
{ &efi_absolute_pointer_protocol_guid,
|
||||
"AbsolutePointer" },
|
||||
{ &efi_acpi_table_protocol_guid,
|
||||
"AcpiTable" },
|
||||
{ &efi_apple_net_boot_protocol_guid,
|
||||
"AppleNetBoot" },
|
||||
{ &efi_arp_protocol_guid,
|
||||
"Arp" },
|
||||
{ &efi_arp_service_binding_protocol_guid,
|
||||
"ArpSb" },
|
||||
{ &efi_block_io_protocol_guid,
|
||||
"BlockIo" },
|
||||
{ &efi_block_io2_protocol_guid,
|
||||
"BlockIo2" },
|
||||
{ &efi_bus_specific_driver_override_protocol_guid,
|
||||
"BusSpecificDriverOverride" },
|
||||
{ &efi_component_name_protocol_guid,
|
||||
"ComponentName" },
|
||||
{ &efi_component_name2_protocol_guid,
|
||||
"ComponentName2" },
|
||||
{ &efi_console_control_protocol_guid,
|
||||
"ConsoleControl" },
|
||||
{ &efi_device_path_protocol_guid,
|
||||
"DevicePath" },
|
||||
{ &efi_driver_binding_protocol_guid,
|
||||
"DriverBinding" },
|
||||
{ &efi_dhcp4_protocol_guid,
|
||||
"Dhcp4" },
|
||||
{ &efi_dhcp4_service_binding_protocol_guid,
|
||||
"Dhcp4Sb" },
|
||||
{ &efi_dhcp6_protocol_guid,
|
||||
"Dhcp6" },
|
||||
{ &efi_dhcp6_service_binding_protocol_guid,
|
||||
"Dhcp6Sb" },
|
||||
{ &efi_disk_io_protocol_guid,
|
||||
"DiskIo" },
|
||||
{ &efi_dns4_protocol_guid,
|
||||
"Dns4" },
|
||||
{ &efi_dns4_service_binding_protocol_guid,
|
||||
"Dns4Sb" },
|
||||
{ &efi_dns6_protocol_guid,
|
||||
"Dns6" },
|
||||
{ &efi_dns6_service_binding_protocol_guid,
|
||||
"Dns6Sb" },
|
||||
{ &efi_graphics_output_protocol_guid,
|
||||
"GraphicsOutput" },
|
||||
{ &efi_hii_config_access_protocol_guid,
|
||||
"HiiConfigAccess" },
|
||||
{ &efi_hii_font_protocol_guid,
|
||||
"HiiFont" },
|
||||
{ &efi_http_boot_dxe_guid,
|
||||
"HttpBootDxe" },
|
||||
{ &efi_http_protocol_guid,
|
||||
"Http" },
|
||||
{ &efi_http_service_binding_protocol_guid,
|
||||
"HttpSb" },
|
||||
{ &efi_ip4_protocol_guid,
|
||||
"Ip4" },
|
||||
{ &efi_ip4_config_protocol_guid,
|
||||
"Ip4Config" },
|
||||
{ &efi_ip4_config2_protocol_guid,
|
||||
"Ip4Config2" },
|
||||
{ &efi_ip4_service_binding_protocol_guid,
|
||||
"Ip4Sb" },
|
||||
{ &efi_ip6_protocol_guid,
|
||||
"Ip6" },
|
||||
{ &efi_ip6_config_protocol_guid,
|
||||
"Ip6Config" },
|
||||
{ &efi_ip6_service_binding_protocol_guid,
|
||||
"Ip6Sb" },
|
||||
{ &efi_iscsi_dxe_guid,
|
||||
"IScsiDxe" },
|
||||
{ &efi_iscsi4_dxe_guid,
|
||||
"IScsi4Dxe" },
|
||||
{ &efi_load_file_protocol_guid,
|
||||
"LoadFile" },
|
||||
{ &efi_load_file2_protocol_guid,
|
||||
"LoadFile2" },
|
||||
{ &efi_loaded_image_protocol_guid,
|
||||
"LoadedImage" },
|
||||
{ &efi_loaded_image_device_path_protocol_guid,
|
||||
"LoadedImageDevicePath"},
|
||||
{ &efi_managed_network_protocol_guid,
|
||||
"ManagedNetwork" },
|
||||
{ &efi_managed_network_service_binding_protocol_guid,
|
||||
"ManagedNetworkSb" },
|
||||
{ &efi_mtftp4_protocol_guid,
|
||||
"Mtftp4" },
|
||||
{ &efi_mtftp4_service_binding_protocol_guid,
|
||||
"Mtftp4Sb" },
|
||||
{ &efi_mtftp6_protocol_guid,
|
||||
"Mtftp6" },
|
||||
{ &efi_mtftp6_service_binding_protocol_guid,
|
||||
"Mtftp6Sb" },
|
||||
{ &efi_nii_protocol_guid,
|
||||
"Nii" },
|
||||
{ &efi_nii31_protocol_guid,
|
||||
"Nii31" },
|
||||
{ &efi_pci_io_protocol_guid,
|
||||
"PciIo" },
|
||||
{ &efi_pci_root_bridge_io_protocol_guid,
|
||||
"PciRootBridgeIo" },
|
||||
{ &efi_pxe_base_code_protocol_guid,
|
||||
"PxeBaseCode" },
|
||||
{ &efi_serial_io_protocol_guid,
|
||||
"SerialIo" },
|
||||
{ &efi_shim_lock_protocol_guid,
|
||||
"ShimLock" },
|
||||
{ &efi_simple_file_system_protocol_guid,
|
||||
"SimpleFileSystem" },
|
||||
{ &efi_simple_network_protocol_guid,
|
||||
"SimpleNetwork" },
|
||||
{ &efi_simple_pointer_protocol_guid,
|
||||
"SimplePointer" },
|
||||
{ &efi_simple_text_input_protocol_guid,
|
||||
"SimpleTextInput" },
|
||||
{ &efi_simple_text_input_ex_protocol_guid,
|
||||
"SimpleTextInputEx" },
|
||||
{ &efi_simple_text_output_protocol_guid,
|
||||
"SimpleTextOutput" },
|
||||
{ &efi_tcg_protocol_guid,
|
||||
"Tcg" },
|
||||
{ &efi_tcp4_protocol_guid,
|
||||
"Tcp4" },
|
||||
{ &efi_tcp4_service_binding_protocol_guid,
|
||||
"Tcp4Sb" },
|
||||
{ &efi_tcp6_protocol_guid,
|
||||
"Tcp6" },
|
||||
{ &efi_tcp6_service_binding_protocol_guid,
|
||||
"Tcp6Sb" },
|
||||
{ &efi_tree_protocol_guid,
|
||||
"TrEE" },
|
||||
{ &efi_udp4_protocol_guid,
|
||||
"Udp4" },
|
||||
{ &efi_udp4_service_binding_protocol_guid,
|
||||
"Udp4Sb" },
|
||||
{ &efi_udp6_protocol_guid,
|
||||
"Udp6" },
|
||||
{ &efi_udp6_service_binding_protocol_guid,
|
||||
"Udp6Sb" },
|
||||
{ &efi_uefi_pxe_bc_dxe_guid,
|
||||
"UefiPxeBcDxe" },
|
||||
{ &efi_uga_draw_protocol_guid,
|
||||
"UgaDraw" },
|
||||
{ &efi_unicode_collation_protocol_guid,
|
||||
"UnicodeCollation" },
|
||||
{ &efi_usb_hc_protocol_guid,
|
||||
"UsbHc" },
|
||||
{ &efi_usb2_hc_protocol_guid,
|
||||
"Usb2Hc" },
|
||||
{ &efi_usb_io_protocol_guid,
|
||||
"UsbIo" },
|
||||
{ &efi_vlan_config_protocol_guid,
|
||||
"VlanConfig" },
|
||||
{ &efi_vlan_config_dxe_guid,
|
||||
"VlanConfigDxe" },
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert GUID to a printable string
|
||||
*
|
||||
* @v guid GUID
|
||||
* @ret string Printable string
|
||||
*/
|
||||
const __attribute__ (( pure )) char * efi_guid_ntoa ( CONST EFI_GUID *guid ) {
|
||||
union {
|
||||
union uuid uuid;
|
||||
EFI_GUID guid;
|
||||
} u;
|
||||
unsigned int i;
|
||||
|
||||
/* Sanity check */
|
||||
if ( ! guid )
|
||||
return NULL;
|
||||
|
||||
/* Check for a match against well-known GUIDs */
|
||||
for ( i = 0 ; i < ( sizeof ( efi_well_known_guids ) /
|
||||
sizeof ( efi_well_known_guids[0] ) ) ; i++ ) {
|
||||
if ( memcmp ( guid, efi_well_known_guids[i].guid,
|
||||
sizeof ( *guid ) ) == 0 ) {
|
||||
return efi_well_known_guids[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert GUID to standard endianness */
|
||||
memcpy ( &u.guid, guid, sizeof ( u.guid ) );
|
||||
uuid_mangle ( &u.uuid );
|
||||
return uuid_ntoa ( &u.uuid );
|
||||
}
|
||||
|
||||
/**
|
||||
* Name locate search type
|
||||
*
|
||||
|
@ -552,6 +321,90 @@ static const char * efi_driver_name2 ( EFI_COMPONENT_NAME2_PROTOCOL *wtf ) {
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get driver binding name
|
||||
*
|
||||
* @v binding Driver binding protocol
|
||||
* @ret name Driver name, or NULL
|
||||
*/
|
||||
static const char * efi_binding_name ( EFI_DRIVER_BINDING_PROTOCOL *binding ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
union {
|
||||
EFI_COMPONENT_NAME_PROTOCOL *name;
|
||||
void *interface;
|
||||
} u;
|
||||
EFI_HANDLE image;
|
||||
const char *name;
|
||||
EFI_STATUS efirc;
|
||||
|
||||
/* Sanity check */
|
||||
if ( ! binding ) {
|
||||
DBG ( "[NULL DriverBinding]" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Try to open component name protocol on image handle */
|
||||
image = binding->ImageHandle;
|
||||
if ( ( efirc = bs->OpenProtocol ( image,
|
||||
&efi_component_name_protocol_guid,
|
||||
&u.interface, efi_image_handle, image,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL)) !=0){
|
||||
DBG ( "[DriverBinding no ComponentName]" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Try to get name from component name protocol */
|
||||
name = efi_driver_name ( u.name );
|
||||
|
||||
/* Close component name protocol */
|
||||
bs->CloseProtocol ( image, &efi_component_name_protocol_guid,
|
||||
efi_image_handle, image );
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get driver binding name
|
||||
*
|
||||
* @v binding Driver binding protocol
|
||||
* @ret name Driver name, or NULL
|
||||
*/
|
||||
static const char * efi_binding_name2 ( EFI_DRIVER_BINDING_PROTOCOL *binding ){
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
EFI_HANDLE image;
|
||||
union {
|
||||
EFI_COMPONENT_NAME2_PROTOCOL *name2;
|
||||
void *interface;
|
||||
} u;
|
||||
const char *name;
|
||||
EFI_STATUS efirc;
|
||||
|
||||
/* Sanity check */
|
||||
if ( ! binding ) {
|
||||
DBG ( "[NULL DriverBinding]" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Try to open component name protocol on image handle */
|
||||
image = binding->ImageHandle;
|
||||
if ( ( efirc = bs->OpenProtocol ( image,
|
||||
&efi_component_name2_protocol_guid,
|
||||
&u.interface, efi_image_handle, image,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL)) !=0){
|
||||
DBG ( "[DriverBinding no ComponentName2]" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Try to get name from component name protocol */
|
||||
name = efi_driver_name2 ( u.name2 );
|
||||
|
||||
/* Close component name protocol */
|
||||
bs->CloseProtocol ( image, &efi_component_name2_protocol_guid,
|
||||
efi_image_handle, image );
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PE/COFF debug filename
|
||||
*
|
||||
|
@ -770,15 +623,18 @@ struct efi_handle_name_type {
|
|||
|
||||
/** EFI handle name types */
|
||||
static struct efi_handle_name_type efi_handle_name_types[] = {
|
||||
/* Device path */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_device_path_protocol_guid,
|
||||
efi_devpath_text ),
|
||||
/* Driver name (for driver image handles) */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_component_name2_protocol_guid,
|
||||
efi_driver_name2 ),
|
||||
/* Driver name (via obsolete original ComponentName protocol) */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_component_name_protocol_guid,
|
||||
efi_driver_name ),
|
||||
/* Driver name (for driver binding handles) */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_driver_binding_protocol_guid,
|
||||
efi_binding_name2 ),
|
||||
/* Driver name (via obsolete original ComponentName protocol) */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_driver_binding_protocol_guid,
|
||||
efi_binding_name ),
|
||||
/* PE/COFF debug filename (for image handles) */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
|
||||
efi_pecoff_debug_name ),
|
||||
|
@ -791,6 +647,9 @@ static struct efi_handle_name_type efi_handle_name_types[] = {
|
|||
/* Handle's loaded image file path (for image handles) */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
|
||||
efi_loaded_image_filepath_name ),
|
||||
/* Device path */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_device_path_protocol_guid,
|
||||
efi_devpath_text ),
|
||||
/* Our standard input file handle */
|
||||
EFI_HANDLE_NAME_TYPE ( &efi_simple_text_input_protocol_guid,
|
||||
efi_conin_name ),
|
||||
|
|
|
@ -245,6 +245,7 @@ static size_t efi_file_read_initrd ( struct efi_file_reader *reader ) {
|
|||
size_t cpio_len;
|
||||
size_t name_len;
|
||||
size_t len;
|
||||
unsigned int i;
|
||||
|
||||
/* Read from file */
|
||||
len = 0;
|
||||
|
@ -263,15 +264,16 @@ static size_t efi_file_read_initrd ( struct efi_file_reader *reader ) {
|
|||
}
|
||||
len += efi_file_read_chunk ( reader, UNULL, pad_len );
|
||||
|
||||
/* Read CPIO header, if applicable */
|
||||
cpio_len = cpio_header ( image, &cpio );
|
||||
if ( cpio_len ) {
|
||||
name = cpio_name ( image );
|
||||
name_len = cpio_name_len ( image );
|
||||
pad_len = ( cpio_len - sizeof ( cpio ) - name_len );
|
||||
/* Read CPIO header(s), if applicable */
|
||||
name = cpio_name ( image );
|
||||
for ( i = 0 ; ( cpio_len = cpio_header ( image, i, &cpio ) );
|
||||
i++ ) {
|
||||
name_len = ( cpio_len - sizeof ( cpio ) );
|
||||
pad_len = cpio_pad_len ( cpio_len );
|
||||
DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) %s header\n",
|
||||
efi_file_name ( file ), reader->pos,
|
||||
( reader->pos + cpio_len ), image->name );
|
||||
( reader->pos + cpio_len + pad_len ),
|
||||
image->name );
|
||||
len += efi_file_read_chunk ( reader,
|
||||
virt_to_user ( &cpio ),
|
||||
sizeof ( cpio ) );
|
||||
|
@ -386,8 +388,12 @@ efi_file_open ( EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new,
|
|||
name++;
|
||||
}
|
||||
|
||||
/* Strip redundant path separator characters */
|
||||
while ( ( *name == '\\' ) || ( *name == '.' ) )
|
||||
name++;
|
||||
|
||||
/* Allow root directory itself to be opened */
|
||||
if ( ( name[0] == '\0' ) || ( name[0] == '.' ) )
|
||||
if ( ! *name )
|
||||
return efi_file_open_fixed ( &efi_file_root, wname, new );
|
||||
|
||||
/* Fail unless opening from the root */
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
#include <ipxe/uuid.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/Protocol/AbsolutePointer.h>
|
||||
#include <ipxe/efi/Protocol/AcpiTable.h>
|
||||
|
@ -61,6 +63,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <ipxe/efi/Protocol/PciIo.h>
|
||||
#include <ipxe/efi/Protocol/PciRootBridgeIo.h>
|
||||
#include <ipxe/efi/Protocol/PxeBaseCode.h>
|
||||
#include <ipxe/efi/Protocol/Rng.h>
|
||||
#include <ipxe/efi/Protocol/SerialIo.h>
|
||||
#include <ipxe/efi/Protocol/ShimLock.h>
|
||||
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
|
||||
|
@ -70,6 +73,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <ipxe/efi/Protocol/SimpleTextInEx.h>
|
||||
#include <ipxe/efi/Protocol/SimpleTextOut.h>
|
||||
#include <ipxe/efi/Protocol/TcgService.h>
|
||||
#include <ipxe/efi/Protocol/Tcg2Protocol.h>
|
||||
#include <ipxe/efi/Protocol/Tcp4.h>
|
||||
#include <ipxe/efi/Protocol/Tcp6.h>
|
||||
#include <ipxe/efi/Protocol/Udp4.h>
|
||||
|
@ -82,6 +86,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <ipxe/efi/Protocol/VlanConfig.h>
|
||||
#include <ipxe/efi/Guid/FileInfo.h>
|
||||
#include <ipxe/efi/Guid/FileSystemInfo.h>
|
||||
#include <ipxe/efi/Guid/GlobalVariable.h>
|
||||
#include <ipxe/efi/Guid/ImageAuthentication.h>
|
||||
#include <ipxe/efi/Guid/TlsAuthentication.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
|
@ -290,6 +297,10 @@ EFI_GUID efi_pci_root_bridge_io_protocol_guid
|
|||
EFI_GUID efi_pxe_base_code_protocol_guid
|
||||
= EFI_PXE_BASE_CODE_PROTOCOL_GUID;
|
||||
|
||||
/** Random number generator protocol GUID */
|
||||
EFI_GUID efi_rng_protocol_guid
|
||||
= EFI_RNG_PROTOCOL_GUID;
|
||||
|
||||
/** Serial I/O protocol GUID */
|
||||
EFI_GUID efi_serial_io_protocol_guid
|
||||
= EFI_SERIAL_IO_PROTOCOL_GUID;
|
||||
|
@ -326,6 +337,10 @@ EFI_GUID efi_simple_text_output_protocol_guid
|
|||
EFI_GUID efi_tcg_protocol_guid
|
||||
= EFI_TCG_PROTOCOL_GUID;
|
||||
|
||||
/** TCG2 protocol GUID */
|
||||
EFI_GUID efi_tcg2_protocol_guid
|
||||
= EFI_TCG2_PROTOCOL_GUID;
|
||||
|
||||
/** TCPv4 protocol GUID */
|
||||
EFI_GUID efi_tcp4_protocol_guid
|
||||
= EFI_TCP4_PROTOCOL_GUID;
|
||||
|
@ -386,8 +401,257 @@ EFI_GUID efi_usb_io_protocol_guid
|
|||
EFI_GUID efi_vlan_config_protocol_guid
|
||||
= EFI_VLAN_CONFIG_PROTOCOL_GUID;
|
||||
|
||||
/** X.509 certificate GUID */
|
||||
EFI_GUID efi_cert_x509_guid = EFI_CERT_X509_GUID;
|
||||
|
||||
/** File information GUID */
|
||||
EFI_GUID efi_file_info_id = EFI_FILE_INFO_ID;
|
||||
|
||||
/** File system information GUID */
|
||||
EFI_GUID efi_file_system_info_id = EFI_FILE_SYSTEM_INFO_ID;
|
||||
|
||||
/** Global variable GUID */
|
||||
EFI_GUID efi_global_variable = EFI_GLOBAL_VARIABLE;
|
||||
|
||||
/** TLS CA certificate variable GUID */
|
||||
EFI_GUID efi_tls_ca_certificate_guid = EFI_TLS_CA_CERTIFICATE_GUID;
|
||||
|
||||
/** HttpBootDxe module GUID */
|
||||
static EFI_GUID efi_http_boot_dxe_guid = {
|
||||
0xecebcb00, 0xd9c8, 0x11e4,
|
||||
{ 0xaf, 0x3d, 0x8c, 0xdc, 0xd4, 0x26, 0xc9, 0x73 }
|
||||
};
|
||||
|
||||
/** IScsiDxe module GUID */
|
||||
static EFI_GUID efi_iscsi_dxe_guid = {
|
||||
0x86cddf93, 0x4872, 0x4597,
|
||||
{ 0x8a, 0xf9, 0xa3, 0x5a, 0xe4, 0xd3, 0x72, 0x5f }
|
||||
};
|
||||
|
||||
/** Old IScsi4Dxe module GUID */
|
||||
static EFI_GUID efi_iscsi4_dxe_guid = {
|
||||
0x4579b72d, 0x7ec4, 0x4dd4,
|
||||
{ 0x84, 0x86, 0x08, 0x3c, 0x86, 0xb1, 0x82, 0xa7 }
|
||||
};
|
||||
|
||||
/** UefiPxeBcDxe module GUID */
|
||||
static EFI_GUID efi_uefi_pxe_bc_dxe_guid = {
|
||||
0xb95e9fda, 0x26de, 0x48d2,
|
||||
{ 0x88, 0x07, 0x1f, 0x91, 0x07, 0xac, 0x5e, 0x3a }
|
||||
};
|
||||
|
||||
/** VlanConfigDxe module GUID */
|
||||
static EFI_GUID efi_vlan_config_dxe_guid = {
|
||||
0xe4f61863, 0xfe2c, 0x4b56,
|
||||
{ 0xa8, 0xf4, 0x08, 0x51, 0x9b, 0xc4, 0x39, 0xdf }
|
||||
};
|
||||
|
||||
/** A well-known GUID */
|
||||
struct efi_well_known_guid {
|
||||
/** GUID */
|
||||
EFI_GUID *guid;
|
||||
/** Name */
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/** Well-known GUIDs */
|
||||
static struct efi_well_known_guid efi_well_known_guids[] = {
|
||||
{ &efi_absolute_pointer_protocol_guid,
|
||||
"AbsolutePointer" },
|
||||
{ &efi_acpi_table_protocol_guid,
|
||||
"AcpiTable" },
|
||||
{ &efi_apple_net_boot_protocol_guid,
|
||||
"AppleNetBoot" },
|
||||
{ &efi_arp_protocol_guid,
|
||||
"Arp" },
|
||||
{ &efi_arp_service_binding_protocol_guid,
|
||||
"ArpSb" },
|
||||
{ &efi_block_io_protocol_guid,
|
||||
"BlockIo" },
|
||||
{ &efi_block_io2_protocol_guid,
|
||||
"BlockIo2" },
|
||||
{ &efi_bus_specific_driver_override_protocol_guid,
|
||||
"BusSpecificDriverOverride" },
|
||||
{ &efi_cert_x509_guid,
|
||||
"CertX509" },
|
||||
{ &efi_component_name_protocol_guid,
|
||||
"ComponentName" },
|
||||
{ &efi_component_name2_protocol_guid,
|
||||
"ComponentName2" },
|
||||
{ &efi_console_control_protocol_guid,
|
||||
"ConsoleControl" },
|
||||
{ &efi_device_path_protocol_guid,
|
||||
"DevicePath" },
|
||||
{ &efi_driver_binding_protocol_guid,
|
||||
"DriverBinding" },
|
||||
{ &efi_dhcp4_protocol_guid,
|
||||
"Dhcp4" },
|
||||
{ &efi_dhcp4_service_binding_protocol_guid,
|
||||
"Dhcp4Sb" },
|
||||
{ &efi_dhcp6_protocol_guid,
|
||||
"Dhcp6" },
|
||||
{ &efi_dhcp6_service_binding_protocol_guid,
|
||||
"Dhcp6Sb" },
|
||||
{ &efi_disk_io_protocol_guid,
|
||||
"DiskIo" },
|
||||
{ &efi_dns4_protocol_guid,
|
||||
"Dns4" },
|
||||
{ &efi_dns4_service_binding_protocol_guid,
|
||||
"Dns4Sb" },
|
||||
{ &efi_dns6_protocol_guid,
|
||||
"Dns6" },
|
||||
{ &efi_dns6_service_binding_protocol_guid,
|
||||
"Dns6Sb" },
|
||||
{ &efi_global_variable,
|
||||
"GlobalVar" },
|
||||
{ &efi_graphics_output_protocol_guid,
|
||||
"GraphicsOutput" },
|
||||
{ &efi_hii_config_access_protocol_guid,
|
||||
"HiiConfigAccess" },
|
||||
{ &efi_hii_font_protocol_guid,
|
||||
"HiiFont" },
|
||||
{ &efi_http_boot_dxe_guid,
|
||||
"HttpBootDxe" },
|
||||
{ &efi_http_protocol_guid,
|
||||
"Http" },
|
||||
{ &efi_http_service_binding_protocol_guid,
|
||||
"HttpSb" },
|
||||
{ &efi_ip4_protocol_guid,
|
||||
"Ip4" },
|
||||
{ &efi_ip4_config_protocol_guid,
|
||||
"Ip4Config" },
|
||||
{ &efi_ip4_config2_protocol_guid,
|
||||
"Ip4Config2" },
|
||||
{ &efi_ip4_service_binding_protocol_guid,
|
||||
"Ip4Sb" },
|
||||
{ &efi_ip6_protocol_guid,
|
||||
"Ip6" },
|
||||
{ &efi_ip6_config_protocol_guid,
|
||||
"Ip6Config" },
|
||||
{ &efi_ip6_service_binding_protocol_guid,
|
||||
"Ip6Sb" },
|
||||
{ &efi_iscsi_dxe_guid,
|
||||
"IScsiDxe" },
|
||||
{ &efi_iscsi4_dxe_guid,
|
||||
"IScsi4Dxe" },
|
||||
{ &efi_load_file_protocol_guid,
|
||||
"LoadFile" },
|
||||
{ &efi_load_file2_protocol_guid,
|
||||
"LoadFile2" },
|
||||
{ &efi_loaded_image_protocol_guid,
|
||||
"LoadedImage" },
|
||||
{ &efi_loaded_image_device_path_protocol_guid,
|
||||
"LoadedImageDevicePath"},
|
||||
{ &efi_managed_network_protocol_guid,
|
||||
"ManagedNetwork" },
|
||||
{ &efi_managed_network_service_binding_protocol_guid,
|
||||
"ManagedNetworkSb" },
|
||||
{ &efi_mtftp4_protocol_guid,
|
||||
"Mtftp4" },
|
||||
{ &efi_mtftp4_service_binding_protocol_guid,
|
||||
"Mtftp4Sb" },
|
||||
{ &efi_mtftp6_protocol_guid,
|
||||
"Mtftp6" },
|
||||
{ &efi_mtftp6_service_binding_protocol_guid,
|
||||
"Mtftp6Sb" },
|
||||
{ &efi_nii_protocol_guid,
|
||||
"Nii" },
|
||||
{ &efi_nii31_protocol_guid,
|
||||
"Nii31" },
|
||||
{ &efi_pci_io_protocol_guid,
|
||||
"PciIo" },
|
||||
{ &efi_pci_root_bridge_io_protocol_guid,
|
||||
"PciRootBridgeIo" },
|
||||
{ &efi_pxe_base_code_protocol_guid,
|
||||
"PxeBaseCode" },
|
||||
{ &efi_rng_protocol_guid,
|
||||
"Rng" },
|
||||
{ &efi_serial_io_protocol_guid,
|
||||
"SerialIo" },
|
||||
{ &efi_shim_lock_protocol_guid,
|
||||
"ShimLock" },
|
||||
{ &efi_simple_file_system_protocol_guid,
|
||||
"SimpleFileSystem" },
|
||||
{ &efi_simple_network_protocol_guid,
|
||||
"SimpleNetwork" },
|
||||
{ &efi_simple_pointer_protocol_guid,
|
||||
"SimplePointer" },
|
||||
{ &efi_simple_text_input_protocol_guid,
|
||||
"SimpleTextInput" },
|
||||
{ &efi_simple_text_input_ex_protocol_guid,
|
||||
"SimpleTextInputEx" },
|
||||
{ &efi_simple_text_output_protocol_guid,
|
||||
"SimpleTextOutput" },
|
||||
{ &efi_tcg_protocol_guid,
|
||||
"Tcg" },
|
||||
{ &efi_tcg2_protocol_guid,
|
||||
"Tcg2" },
|
||||
{ &efi_tcp4_protocol_guid,
|
||||
"Tcp4" },
|
||||
{ &efi_tcp4_service_binding_protocol_guid,
|
||||
"Tcp4Sb" },
|
||||
{ &efi_tcp6_protocol_guid,
|
||||
"Tcp6" },
|
||||
{ &efi_tcp6_service_binding_protocol_guid,
|
||||
"Tcp6Sb" },
|
||||
{ &efi_tls_ca_certificate_guid,
|
||||
"TlsCaCert" },
|
||||
{ &efi_tree_protocol_guid,
|
||||
"TrEE" },
|
||||
{ &efi_udp4_protocol_guid,
|
||||
"Udp4" },
|
||||
{ &efi_udp4_service_binding_protocol_guid,
|
||||
"Udp4Sb" },
|
||||
{ &efi_udp6_protocol_guid,
|
||||
"Udp6" },
|
||||
{ &efi_udp6_service_binding_protocol_guid,
|
||||
"Udp6Sb" },
|
||||
{ &efi_uefi_pxe_bc_dxe_guid,
|
||||
"UefiPxeBcDxe" },
|
||||
{ &efi_uga_draw_protocol_guid,
|
||||
"UgaDraw" },
|
||||
{ &efi_unicode_collation_protocol_guid,
|
||||
"UnicodeCollation" },
|
||||
{ &efi_usb_hc_protocol_guid,
|
||||
"UsbHc" },
|
||||
{ &efi_usb2_hc_protocol_guid,
|
||||
"Usb2Hc" },
|
||||
{ &efi_usb_io_protocol_guid,
|
||||
"UsbIo" },
|
||||
{ &efi_vlan_config_protocol_guid,
|
||||
"VlanConfig" },
|
||||
{ &efi_vlan_config_dxe_guid,
|
||||
"VlanConfigDxe" },
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert GUID to a printable string
|
||||
*
|
||||
* @v guid GUID
|
||||
* @ret string Printable string
|
||||
*/
|
||||
const __attribute__ (( pure )) char * efi_guid_ntoa ( CONST EFI_GUID *guid ) {
|
||||
union {
|
||||
union uuid uuid;
|
||||
EFI_GUID guid;
|
||||
} u;
|
||||
unsigned int i;
|
||||
|
||||
/* Sanity check */
|
||||
if ( ! guid )
|
||||
return NULL;
|
||||
|
||||
/* Check for a match against well-known GUIDs */
|
||||
for ( i = 0 ; i < ( sizeof ( efi_well_known_guids ) /
|
||||
sizeof ( efi_well_known_guids[0] ) ) ; i++ ) {
|
||||
if ( memcmp ( guid, efi_well_known_guids[i].guid,
|
||||
sizeof ( *guid ) ) == 0 ) {
|
||||
return efi_well_known_guids[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert GUID to standard endianness */
|
||||
memcpy ( &u.guid, guid, sizeof ( u.guid ) );
|
||||
uuid_mangle ( &u.uuid );
|
||||
return uuid_ntoa ( &u.uuid );
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <ipxe/efi/Protocol/DriverBinding.h>
|
||||
#include <ipxe/efi/Protocol/LoadedImage.h>
|
||||
#include <ipxe/efi/Protocol/ComponentName.h>
|
||||
#include <ipxe/efi/Protocol/ComponentName2.h>
|
||||
#include <ipxe/efi/efi_veto.h>
|
||||
|
||||
/** @file
|
||||
|
@ -46,14 +47,12 @@ struct efi_veto_candidate {
|
|||
*
|
||||
* @v binding Driver binding protocol
|
||||
* @v loaded Loaded image protocol
|
||||
* @v wtf Component name protocol, if present
|
||||
* @v manufacturer Manufacturer name, if present
|
||||
* @v name Driver name (in "eng" language), if present
|
||||
* @v name Driver name, if present
|
||||
* @ret vetoed Driver is to be vetoed
|
||||
*/
|
||||
int ( * veto ) ( EFI_DRIVER_BINDING_PROTOCOL *binding,
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded,
|
||||
EFI_COMPONENT_NAME_PROTOCOL *wtf,
|
||||
const char *manufacturer, const CHAR16 *name );
|
||||
};
|
||||
|
||||
|
@ -394,7 +393,6 @@ static int efi_veto_driver ( struct efi_veto *veto ) {
|
|||
*
|
||||
* @v binding Driver binding protocol
|
||||
* @v loaded Loaded image protocol
|
||||
* @v wtf Component name protocol, if present
|
||||
* @v manufacturer Manufacturer name, if present
|
||||
* @v name Driver name, if present
|
||||
* @ret vetoed Driver is to be vetoed
|
||||
|
@ -402,7 +400,6 @@ static int efi_veto_driver ( struct efi_veto *veto ) {
|
|||
static int
|
||||
efi_veto_ip4config ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded __unused,
|
||||
EFI_COMPONENT_NAME_PROTOCOL *wtf __unused,
|
||||
const char *manufacturer, const CHAR16 *name ) {
|
||||
static const CHAR16 ip4cfg[] = L"IP4 CONFIG Network Service Driver";
|
||||
static const char *dell = "Dell Inc.";
|
||||
|
@ -427,7 +424,6 @@ efi_veto_ip4config ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
|||
*
|
||||
* @v binding Driver binding protocol
|
||||
* @v loaded Loaded image protocol
|
||||
* @v wtf Component name protocol, if present
|
||||
* @v manufacturer Manufacturer name, if present
|
||||
* @v name Driver name, if present
|
||||
* @ret vetoed Driver is to be vetoed
|
||||
|
@ -435,7 +431,6 @@ efi_veto_ip4config ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
|||
static int
|
||||
efi_veto_hp_xhci ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded __unused,
|
||||
EFI_COMPONENT_NAME_PROTOCOL *wtf __unused,
|
||||
const char *manufacturer, const CHAR16 *name ) {
|
||||
static const CHAR16 xhci[] = L"Usb Xhci Driver";
|
||||
static const char *hp = "HP";
|
||||
|
@ -468,7 +463,6 @@ efi_veto_hp_xhci ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
|||
*
|
||||
* @v binding Driver binding protocol
|
||||
* @v loaded Loaded image protocol
|
||||
* @v wtf Component name protocol, if present
|
||||
* @v manufacturer Manufacturer name, if present
|
||||
* @v name Driver name, if present
|
||||
* @ret vetoed Driver is to be vetoed
|
||||
|
@ -476,7 +470,6 @@ efi_veto_hp_xhci ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
|||
static int
|
||||
efi_veto_vmware_uefipxebc ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded __unused,
|
||||
EFI_COMPONENT_NAME_PROTOCOL *wtf __unused,
|
||||
const char *manufacturer, const CHAR16 *name ) {
|
||||
static const CHAR16 uefipxebc[] = L"UEFI PXE Base Code Driver";
|
||||
static const char *vmware = "VMware, Inc.";
|
||||
|
@ -499,14 +492,12 @@ efi_veto_vmware_uefipxebc ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
|||
*
|
||||
* @v binding Driver binding protocol
|
||||
* @v loaded Loaded image protocol
|
||||
* @v wtf Component name protocol, if present
|
||||
* @v manufacturer Manufacturer name, if present
|
||||
* @v name Driver name, if present
|
||||
* @ret vetoed Driver is to be vetoed
|
||||
*/
|
||||
static int efi_veto_dhcp6 ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded __unused,
|
||||
EFI_COMPONENT_NAME_PROTOCOL *wtf __unused,
|
||||
const char *manufacturer __unused,
|
||||
const CHAR16 *name ) {
|
||||
static const CHAR16 dhcp6[] = L"DHCP6 Protocol Driver";
|
||||
|
@ -559,6 +550,10 @@ static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
|||
EFI_LOADED_IMAGE_PROTOCOL *loaded;
|
||||
void *interface;
|
||||
} loaded;
|
||||
union {
|
||||
EFI_COMPONENT_NAME2_PROTOCOL *wtf2;
|
||||
void *interface;
|
||||
} wtf2;
|
||||
union {
|
||||
EFI_COMPONENT_NAME_PROTOCOL *wtf;
|
||||
void *interface;
|
||||
|
@ -569,9 +564,6 @@ static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
|||
EFI_STATUS efirc;
|
||||
int rc;
|
||||
|
||||
DBGC2 ( &efi_vetoes, "EFIVETO checking %s\n",
|
||||
efi_handle_name ( driver ) );
|
||||
|
||||
/* Mark as not vetoed */
|
||||
memset ( veto, 0, sizeof ( *veto ) );
|
||||
|
||||
|
@ -601,19 +593,31 @@ static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
|||
goto err_loaded;
|
||||
}
|
||||
|
||||
/* Open component name protocol, if present*/
|
||||
/* Open component name protocol, if present */
|
||||
if ( ( efirc = bs->OpenProtocol (
|
||||
driver, &efi_component_name_protocol_guid,
|
||||
&wtf.interface, efi_image_handle, driver,
|
||||
image, &efi_component_name2_protocol_guid,
|
||||
&wtf2.interface, efi_image_handle, image,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ) != 0 ) {
|
||||
/* Ignore failure; is not required to be present */
|
||||
wtf2.interface = NULL;
|
||||
}
|
||||
|
||||
/* Open obsolete component name protocol, if present */
|
||||
if ( ( efirc = bs->OpenProtocol (
|
||||
image, &efi_component_name_protocol_guid,
|
||||
&wtf.interface, efi_image_handle, image,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ) != 0 ) {
|
||||
/* Ignore failure; is not required to be present */
|
||||
wtf.interface = NULL;
|
||||
}
|
||||
|
||||
/* Get driver name, if available */
|
||||
if ( wtf.wtf &&
|
||||
( ( efirc = wtf.wtf->GetDriverName ( wtf.wtf, "eng",
|
||||
&name ) == 0 ) ) ) {
|
||||
if ( ( wtf2.wtf2 &&
|
||||
( ( efirc = wtf2.wtf2->GetDriverName ( wtf2.wtf2, "en",
|
||||
&name ) == 0 ) ) ) ||
|
||||
( wtf.wtf &&
|
||||
( ( efirc = wtf.wtf->GetDriverName ( wtf.wtf, "eng",
|
||||
&name ) == 0 ) ) ) ) {
|
||||
/* Driver has a name */
|
||||
} else {
|
||||
/* Ignore failure; name is not required to be present */
|
||||
|
@ -621,10 +625,13 @@ static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
|||
}
|
||||
|
||||
/* Check vetoes */
|
||||
DBGC2 ( &efi_vetoes, "EFIVETO checking %s [%p,%p)\n",
|
||||
efi_handle_name ( driver ), loaded.loaded->ImageBase,
|
||||
( loaded.loaded->ImageBase + loaded.loaded->ImageSize ) );
|
||||
for ( i = 0 ; i < ( sizeof ( efi_vetoes ) /
|
||||
sizeof ( efi_vetoes[0] ) ) ; i++ ) {
|
||||
if ( efi_vetoes[i].veto ( binding.binding, loaded.loaded,
|
||||
wtf.wtf, manufacturer, name ) ) {
|
||||
manufacturer, name ) ) {
|
||||
DBGC ( driver, "EFIVETO %s is vetoed (%s)\n",
|
||||
efi_handle_name ( driver ),
|
||||
efi_vetoes[i].name );
|
||||
|
@ -641,8 +648,12 @@ static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
|||
|
||||
/* Close protocols */
|
||||
if ( wtf.wtf ) {
|
||||
bs->CloseProtocol ( driver, &efi_component_name_protocol_guid,
|
||||
efi_image_handle, driver );
|
||||
bs->CloseProtocol ( image, &efi_component_name_protocol_guid,
|
||||
efi_image_handle, image );
|
||||
}
|
||||
if ( wtf2.wtf2 ) {
|
||||
bs->CloseProtocol ( image, &efi_component_name2_protocol_guid,
|
||||
efi_image_handle, image );
|
||||
}
|
||||
bs->CloseProtocol ( image, &efi_loaded_image_protocol_guid,
|
||||
efi_image_handle, image );
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue