Merge branch 'master' into feature/tpm-info

pull/1024/head
Konst Kolesnichenko 2025-03-21 15:59:06 +02:00
commit 6577252e18
110 changed files with 6767 additions and 1456 deletions

View File

@ -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")

View File

@ -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

View File

@ -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)
###############################################################################

View File

@ -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;
}
/**

View File

@ -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 );
}
/**

View File

@ -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 );
}
/**

View File

@ -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 );
}
/**

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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 );

View File

@ -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();
}

View File

@ -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

View File

@ -37,3 +37,6 @@ REQUIRE_OBJECT ( der );
#ifdef IMAGE_PEM
REQUIRE_OBJECT ( pem );
#endif
#ifdef IMAGE_EFISIG
REQUIRE_OBJECT ( efi_siglist );
#endif

View File

@ -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

View File

@ -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 );

View File

@ -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

View File

@ -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

View File

@ -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
*

View File

@ -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 */

View File

@ -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 );
}

View File

@ -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

View File

@ -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 );

View File

@ -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 );

66
src/crypto/ecdhe.c 100644
View File

@ -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;
}

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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 ),
};

67
src/crypto/p256.c 100644
View File

@ -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 );

76
src/crypto/p384.c 100644
View File

@ -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 );

View File

@ -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 */

View File

@ -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 };

View File

@ -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;
}

View File

@ -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,
};

View File

@ -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 */

View File

@ -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 );

View File

@ -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)

View File

@ -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 */

View File

@ -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 */

View File

@ -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 )

View File

@ -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,
};

View File

@ -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

View File

@ -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,
};

View File

@ -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 ), \

View File

@ -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,

View File

@ -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 */

View File

@ -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
*

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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
//

View File

@ -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
///

View File

@ -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
//

View File

@ -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
///

View File

@ -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
///

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;
///

View File

@ -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
///

View File

@ -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

View File

@ -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

View File

@ -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.
**/

View File

@ -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

View File

@ -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 */

View File

@ -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 {

View File

@ -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;
///

View File

@ -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;
///

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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 );

View File

@ -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 )
/** @} */

View File

@ -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 );
/**

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 );

View File

@ -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:

View File

@ -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,
};

View File

@ -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 ),

View File

@ -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 */

View File

@ -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 );
}

View File

@ -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