Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TESTING SOMETHING, NO MERGING. #1914

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ endif()

# Tests and libssl both require the CXX language to be enabled. If a consumer
# chooses to disable building the tests and libssl, do not enable CXX
if(BUILD_TESTING OR BUILD_LIBSSL)
if(BUILD_TESTING OR BUILD_LIBSSL OR FIPS)
enable_language(CXX)
endif()

Expand Down
80 changes: 18 additions & 62 deletions crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# Function to handle assembly files for ARM64 targets when using MSBuild (the "Visual Studio" generator)
# This function is necessary because MSBuild ignores ARM64 assembly file dependencies
include(CMakeParseArguments)
Expand Down Expand Up @@ -615,83 +614,40 @@ function(build_libcrypto name module_source)
target_include_directories(${name} PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

endfunction()

if(FIPS_SHARED)
if(FIPS_SHARED OR FIPS_DELOCATE)
# Rewrite libcrypto.so, libcrypto.dylib, or crypto.dll to inject the correct module
# hash value. For now we support the FIPS build only on Linux, macOS, iOS, and Windows.
if(MSVC)
# On Windows we use capture_hash.go to capture the computed integrity value that bcm.o prints to generate the
# correct value in generated_fips_shared_support.c. See FIPS.md for a full explanation of the process
build_libcrypto(precrypto $<TARGET_OBJECTS:fipsmodule>)
build_libcrypto(helpercrypto $<TARGET_OBJECTS:fipsmodule>)
add_executable(fips_empty_main fipsmodule/fips_empty_main.c)
target_link_libraries(fips_empty_main PUBLIC precrypto)
target_link_libraries(fips_empty_main PUBLIC helpercrypto)
target_include_directories(fips_empty_main PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_include_directories(fips_empty_main BEFORE PRIVATE ${PROJECT_BINARY_DIR}/symbol_prefix_include)
add_custom_command(OUTPUT generated_fips_shared_support.c
COMMAND ${GO_EXECUTABLE} run
${PROJECT_SOURCE_DIR}/util/fipstools/capture_hash/capture_hash.go
-in-executable $<TARGET_FILE:fips_empty_main> > generated_fips_shared_support.c
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS fips_empty_main ${PROJECT_SOURCE_DIR}/util/fipstools/capture_hash/capture_hash.go
)
add_library(
generated_fipsmodule

OBJECT

generated_fips_shared_support.c
${PROJECT_SOURCE_DIR}/crypto/fipsmodule/cpucap/cpucap.c
)
add_dependencies(generated_fipsmodule boringssl_prefix_symbols)
target_include_directories(generated_fipsmodule PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_include_directories(generated_fipsmodule BEFORE PRIVATE ${PROJECT_BINARY_DIR}/symbol_prefix_include)

build_libcrypto(crypto $<TARGET_OBJECTS:generated_fipsmodule>)
else()
# On Apple and Linux platforms inject_hash.go can parse libcrypto and inject
# the hash directly into the final library.
build_libcrypto(crypto $<TARGET_OBJECTS:fipsmodule>)
add_executable(inject_hash ${PROJECT_SOURCE_DIR}/util/fipstools/inject_hash/inject_hash.cpp)
if (APPLE)
set(INJECT_HASH_APPLE_FLAG "-apple")
endif()

add_custom_command(
TARGET crypto POST_BUILD
COMMAND ${GO_EXECUTABLE} run
${PROJECT_SOURCE_DIR}/util/fipstools/inject_hash/inject_hash.go
-o $<TARGET_FILE:crypto> -in-object $<TARGET_FILE:crypto> ${INJECT_HASH_APPLE_FLAG}
# The DEPENDS argument to a POST_BUILD rule appears to be ignored. Thus
# go_executable isn't used (as it doesn't get built), but we list this
# dependency anyway in case it starts working in some CMake version.
DEPENDS ../util/fipstools/inject_hash/inject_hash.go
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)

# On macOS 11 and higher on Apple Silicon, codesigning is mandatory for
# binaries to run. This applies to both executables and dylibs. An ad-hoc
# signature is sufficient, and the linker will automatically apply one when
# a binary is created (see https://github.com/Homebrew/brew/issues/9082).
#
# When we build libcrypto.dylib the linker automatically signs it. But then
# we inject the FIPS integrity hash into libcrypto.dylib which changes the
# binary so the signature applied by the linker is obviously not valid
# anymore. So when an application, like crypto_test, tries to load
# libcrypto.dylib it crashes because the signature is not valid. To work
# around this we add an ad-hoc signature to `libcrypto.dylib` after the
# FIPS integrity hash is injected.
#
# Note: we use CMAKE_SYSTEM_PROCESSOR directly instead of the ARCH variable
# because if NO_ASM build flag is defined then ARCH is set to "generic".
if (APPLE AND CMAKE_SYSTEM_PROCESSOR_LOWER MATCHES "arm64.*|aarch64")
add_custom_command(
TARGET crypto POST_BUILD
COMMAND $<TARGET_FILE:inject_hash> $<TARGET_FILE:crypto> $<TARGET_FILE:fips_empty_main>
COMMAND codesign -s - $<TARGET_FILE:crypto>
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS inject_hash fips_empty_main
COMMENT "Injecting FIPS hash"
)
else()
add_custom_command(
TARGET crypto POST_BUILD
COMMAND $<TARGET_FILE:inject_hash> $<TARGET_FILE:crypto> $<TARGET_FILE:fips_empty_main>
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS inject_hash fips_empty_main
COMMENT "Injecting FIPS hash"
)
endif()

endif()
else()
build_libcrypto(crypto $<TARGET_OBJECTS:fipsmodule>)
endif()
Expand Down
15 changes: 7 additions & 8 deletions crypto/fipsmodule/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ if(FIPS_DELOCATE)
add_library(
bcm_hashunset

STATIC
OBJECT

bcm-delocated.S
)
Expand All @@ -416,20 +416,19 @@ if(FIPS_DELOCATE)
set_target_properties(bcm_hashunset PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(bcm_hashunset PROPERTIES LINKER_LANGUAGE C)

go_executable(inject_hash
boringssl.googlesource.com/boringssl/util/fipstools/inject_hash)
set(BCM_NAME bcm.o)
add_custom_command(
OUTPUT bcm.o
COMMAND ./inject_hash -o bcm.o -in-archive $<TARGET_FILE:bcm_hashunset>
DEPENDS bcm_hashunset inject_hash
OUTPUT ${BCM_NAME}
COMMAND cp $<TARGET_OBJECTS:bcm_hashunset> ${BCM_NAME}
DEPENDS bcm_hashunset
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

# The outputs of add_custom_command cannot be referenced outside of the
# CMakeLists.txt that defines it. Thus we have to wrap bcm.o in a custom target
# so that crypto can depend on it.
add_custom_target(bcm_o_target DEPENDS bcm.o)
set(BCM_NAME bcm.o PARENT_SCOPE)
add_custom_target(bcm_o_target DEPENDS ${BCM_NAME})
set(BCM_NAME ${BCM_NAME} PARENT_SCOPE)

add_library(
fipsmodule
Expand Down
2 changes: 2 additions & 0 deletions crypto/fipsmodule/bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@
#include "sshkdf/sshkdf.c"
#include "tls/kdf.c"

#include "fips_support.h"

#if defined(BORINGSSL_FIPS)

#if !defined(OPENSSL_ASAN)
Expand Down
1 change: 1 addition & 0 deletions crypto/fipsmodule/fips_shared.lds
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SECTIONS
BORINGSSL_bcm_text_end = .;
}
.rodata : {
*(.rodata.bcm_support)
BORINGSSL_bcm_rodata_start = .;
*(.rodata)
*(.rodata.*)
Expand Down
11 changes: 8 additions & 3 deletions crypto/fipsmodule/fips_shared_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <stdint.h>
#include "fips_support.h"


#if defined(BORINGSSL_FIPS) && defined(BORINGSSL_SHARED_LIBRARY)
#if defined(BORINGSSL_FIPS)
// BORINGSSL_bcm_text_hash is is default hash value for the FIPS integrity check
// that must be replaced with the real value during the build process. This
// value need only be distinct, i.e. so that we can safely search-and-replace it
// in an object file.
//
const uint8_t BORINGSSL_bcm_text_hash[32];
#if defined(OPENSSL_LINUX)
__attribute__((section(".rodata.bcm_support")))
#endif
const uint8_t BORINGSSL_bcm_text_hash[32] = {
0xae, 0x2c, 0xea, 0x2a, 0xbd, 0xa6, 0xf3, 0xec, 0x97, 0x7f, 0x9b,
0xf6, 0x94, 0x9a, 0xfc, 0x83, 0x68, 0x27, 0xcb, 0xa0, 0xa0, 0x9f,
0x6b, 0x6f, 0xde, 0x52, 0xcd, 0xe2, 0xcd, 0xff, 0x31, 0x80,
};

#endif // FIPS && SHARED_LIBRARY
7 changes: 7 additions & 0 deletions crypto/fipsmodule/fips_support.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef FIPS_SUPPORT_H
#define FIPS_SUPPORT_H

#include <stdint.h>


#endif
1 change: 1 addition & 0 deletions crypto/fipsmodule/gcc_fips_shared.lds
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SECTIONS
BORINGSSL_bcm_text_end = .;
}
.rodata : {
*(.rodata.bcm_support)
BORINGSSL_bcm_rodata_start = .;
*(.rodata)
*(.rodata.*)
Expand Down
7 changes: 5 additions & 2 deletions util/fipstools/capture_hash/capture_hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ func main() {
fmt.Fprintf(os.Stderr, string(out))
panic("Executable did not fail as expected")
}
lines := strings.Split(string(out), "\r\n")
tmp := strings.ReplaceAll(string(out), "\r\n", "\n")
lines := strings.Split(tmp, "\n")
if len(lines) != 4 {
fmt.Fprintf(os.Stderr, string(out))
panic(fmt.Sprintf("Expected 4 lines in output but got %d", len(lines)))
Expand Down Expand Up @@ -63,5 +64,7 @@ const uint8_t BORINGSSL_bcm_text_hash[32] = {
}
fmt.Printf(`
};
const uint8_t *get_asdasd(void);
const uint8_t *get_asdasd(void) { return BORINGSSL_bcm_text_hash; }
`)
}
}
14 changes: 3 additions & 11 deletions util/fipstools/delocate/delocate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"strings"

"boringssl.googlesource.com/boringssl/util/ar"
"boringssl.googlesource.com/boringssl/util/fipstools/fipscommon"
// "boringssl.googlesource.com/boringssl/util/fipstools/fipscommon"
)

// inputFile represents a textual assembly file.
Expand Down Expand Up @@ -2139,13 +2139,6 @@ func transform(w stringWriter, includes []string, inputs []inputFile, startEndDe
}
}

w.WriteString(".type BORINGSSL_bcm_text_hash, @object\n")
w.WriteString(".size BORINGSSL_bcm_text_hash, 32\n")
w.WriteString("BORINGSSL_bcm_text_hash:\n")
for _, b := range fipscommon.UninitHashValue {
w.WriteString(".byte 0x" + strconv.FormatUint(uint64(b), 16) + "\n")
}

return nil
}

Expand Down Expand Up @@ -2417,13 +2410,12 @@ func localEntryName(name string) string {

func isSynthesized(symbol string, processor processorType) bool {
SymbolisSynthesized := strings.HasSuffix(symbol, "_bss_get") ||
symbol == "OPENSSL_ia32cap_get" ||
symbol == "BORINGSSL_bcm_text_hash"
symbol == "OPENSSL_ia32cap_get"

// While BORINGSSL_bcm_text_[start,end] are known symbols, on aarch64 we go
// through the GOT because adr doesn't have adequate reach.
if processor != aarch64 {
SymbolisSynthesized = SymbolisSynthesized || strings.HasPrefix(symbol, "BORINGSSL_bcm_text_")
SymbolisSynthesized = SymbolisSynthesized || symbol == "BORINGSSL_bcm_text_start" || symbol == "BORINGSSL_bcm_text_end"
}

return SymbolisSynthesized
Expand Down
35 changes: 0 additions & 35 deletions util/fipstools/delocate/testdata/aarch64-Basic/out.s
Original file line number Diff line number Diff line change
Expand Up @@ -261,38 +261,3 @@ bss_symbol_bss_get:
ret
.cfi_endproc
.size .LOPENSSL_armcap_P_addr, .-.LOPENSSL_armcap_P_addr
.type BORINGSSL_bcm_text_hash, @object
.size BORINGSSL_bcm_text_hash, 32
BORINGSSL_bcm_text_hash:
.byte 0xae
.byte 0x2c
.byte 0xea
.byte 0x2a
.byte 0xbd
.byte 0xa6
.byte 0xf3
.byte 0xec
.byte 0x97
.byte 0x7f
.byte 0x9b
.byte 0xf6
.byte 0x94
.byte 0x9a
.byte 0xfc
.byte 0x83
.byte 0x68
.byte 0x27
.byte 0xcb
.byte 0xa0
.byte 0xa0
.byte 0x9f
.byte 0x6b
.byte 0x6f
.byte 0xde
.byte 0x52
.byte 0xcd
.byte 0xe2
.byte 0xcd
.byte 0xff
.byte 0x31
.byte 0x80
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,3 @@ BORINGSSL_bcm_text_end:
OPENSSL_ia32cap_get:
leaq OPENSSL_ia32cap_P(%rip), %rax
ret
.type BORINGSSL_bcm_text_hash, @object
.size BORINGSSL_bcm_text_hash, 32
BORINGSSL_bcm_text_hash:
.byte 0xae
.byte 0x2c
.byte 0xea
.byte 0x2a
.byte 0xbd
.byte 0xa6
.byte 0xf3
.byte 0xec
.byte 0x97
.byte 0x7f
.byte 0x9b
.byte 0xf6
.byte 0x94
.byte 0x9a
.byte 0xfc
.byte 0x83
.byte 0x68
.byte 0x27
.byte 0xcb
.byte 0xa0
.byte 0xa0
.byte 0x9f
.byte 0x6b
.byte 0x6f
.byte 0xde
.byte 0x52
.byte 0xcd
.byte 0xe2
.byte 0xcd
.byte 0xff
.byte 0x31
.byte 0x80
35 changes: 0 additions & 35 deletions util/fipstools/delocate/testdata/generic-FileDirectives/out.s
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,3 @@ BORINGSSL_bcm_text_end:
OPENSSL_ia32cap_get:
leaq OPENSSL_ia32cap_P(%rip), %rax
ret
.type BORINGSSL_bcm_text_hash, @object
.size BORINGSSL_bcm_text_hash, 32
BORINGSSL_bcm_text_hash:
.byte 0xae
.byte 0x2c
.byte 0xea
.byte 0x2a
.byte 0xbd
.byte 0xa6
.byte 0xf3
.byte 0xec
.byte 0x97
.byte 0x7f
.byte 0x9b
.byte 0xf6
.byte 0x94
.byte 0x9a
.byte 0xfc
.byte 0x83
.byte 0x68
.byte 0x27
.byte 0xcb
.byte 0xa0
.byte 0xa0
.byte 0x9f
.byte 0x6b
.byte 0x6f
.byte 0xde
.byte 0x52
.byte 0xcd
.byte 0xe2
.byte 0xcd
.byte 0xff
.byte 0x31
.byte 0x80
Loading
Loading