зеркало из https://github.com/microsoft/SymCrypt.git
Merged PR 5935572: Create SymCrypt shared object module with integrity verification
This change adds a new SymCrypt shared object module for Linux. The shared object module implements integrity verification for FIPS compliance by reading its own memory at runtime, reversing any relocations, calculating the HMAC-SHA256 digest of the module contents in memory, and comparing the digest to a known-good value which is injected into the module (outside the FIPS boundary) post compilation by a Python script. Related work items: #30397153, #30397542, #30397643, #30397707, #30397781, #32407416
This commit is contained in:
Родитель
a667baeaa5
Коммит
5b1cfe0171
|
@ -29,6 +29,7 @@ x64/*
|
|||
*.pdb
|
||||
*.aps
|
||||
*.a
|
||||
*.bin
|
||||
|
||||
# Generated files
|
||||
inc/*.dat.h
|
||||
|
|
|
@ -24,7 +24,7 @@ message(STATUS "Target: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_PROCESSOR} ${SYMCRYP
|
|||
|
||||
# Set output directories binaries
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}/${SYMCRYPT_TARGET_ENV})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}/${SYMCRYPT_TARGET_ENV})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/module/${CMAKE_SYSTEM_PROCESSOR}/${SYMCRYPT_TARGET_ENV})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/exe/${CMAKE_SYSTEM_PROCESSOR}/${SYMCRYPT_TARGET_ENV})
|
||||
|
||||
if(WIN32 AND SYMCRYPT_TARGET_ENV MATCHES "WindowsUserMode")
|
||||
|
@ -57,6 +57,8 @@ elseif(NOT WIN32)
|
|||
add_compile_options(-g)
|
||||
add_compile_options(-Wno-multichar)
|
||||
add_compile_options(-fPIC)
|
||||
add_compile_options(-fno-stack-protector)
|
||||
add_compile_options(-fno-plt)
|
||||
|
||||
# GCC and clang unroll more aggressively than they should for best performance
|
||||
# When we want to unroll loops, we unroll in the source code, so tell the compiler not to unroll
|
||||
|
@ -77,4 +79,9 @@ include_directories(${CMAKE_BINARY_DIR}/inc)
|
|||
include(build/buildInfo.cmake)
|
||||
|
||||
add_subdirectory(lib)
|
||||
|
||||
if(NOT WIN32)
|
||||
add_subdirectory(module)
|
||||
endif()
|
||||
|
||||
add_subdirectory(unittest)
|
|
@ -0,0 +1,25 @@
|
|||
SymCrypt on Linux uses elfdefinitions.h from FreeBSD. See the following license notice:
|
||||
|
||||
Copyright (c) 2010 Joseph Koshy
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
|
@ -22,6 +22,7 @@ jobs:
|
|||
steps:
|
||||
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||
submodules: recursive
|
||||
- task: ComponentGovernanceComponentDetection@0
|
||||
# Initialize CMake
|
||||
# cd bin; cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake-toolchain/windows-amd64.cmake
|
||||
- task: CMake@1
|
||||
|
@ -33,13 +34,12 @@ jobs:
|
|||
- task: CMake@1
|
||||
inputs:
|
||||
workingDirectory: '$(Build.SourcesDirectory)/bin'
|
||||
cmakeArgs: '--build .'
|
||||
cmakeArgs: '--build . -j 8'
|
||||
# Execute unit tests using the inline script
|
||||
- script: |
|
||||
cd bin\exe\AMD64\WindowsUserMode\Debug
|
||||
.\symcryptunittest.exe
|
||||
displayName: 'Execute generic unit test'
|
||||
name: 'WindowsGenericUnitTest'
|
||||
displayName: 'Execute unit test'
|
||||
# Copy build output files to artifact staging directory
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
|
@ -66,12 +66,11 @@ jobs:
|
|||
- task: CMake@1
|
||||
inputs:
|
||||
workingDirectory: '$(Build.SourcesDirectory)/bin'
|
||||
cmakeArgs: '--build .'
|
||||
cmakeArgs: '--build . -j 8'
|
||||
- script: |
|
||||
cd bin\exe\x86\WindowsUserMode\Debug
|
||||
.\symcryptunittest.exe
|
||||
displayName: 'Execute generic unit test'
|
||||
name: 'WindowsGenericUnitTest'
|
||||
displayName: 'Execute unit test'
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
SourceFolder: 'bin'
|
||||
|
@ -89,14 +88,23 @@ jobs:
|
|||
steps:
|
||||
- checkout: self
|
||||
submodules: recursive
|
||||
- task: ComponentGovernanceComponentDetection@0
|
||||
- script: |
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
pip install -r $(Build.SourcesDirectory)/scripts/requirements.txt
|
||||
displayName: 'Install Python requirements'
|
||||
- task: CMake@1
|
||||
inputs:
|
||||
workingDirectory: '$(Build.SourcesDirectory)/bin'
|
||||
cmakeArgs: '.. -DCMAKE_TOOLCHAIN_FILE=cmake-toolchain/linux-amd64.cmake -DCMAKE_C_COMPILER=gcc'
|
||||
cmakeArgs: '.. -DCMAKE_TOOLCHAIN_FILE=cmake-toolchain/linux-amd64.cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++'
|
||||
- task: CMake@1
|
||||
inputs:
|
||||
workingDirectory: '$(Build.SourcesDirectory)/bin'
|
||||
cmakeArgs: '--build .'
|
||||
cmakeArgs: '--build . -j 8'
|
||||
- script: |
|
||||
cd bin/exe/AMD64/Linux
|
||||
./symcryptmoduletest
|
||||
displayName: 'Execute module test'
|
||||
- script: |
|
||||
cd bin/exe/AMD64/Linux
|
||||
./symcryptunittest
|
||||
|
@ -119,19 +127,26 @@ jobs:
|
|||
steps:
|
||||
- checkout: self
|
||||
submodules: recursive
|
||||
- script: |
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
pip install -r $(Build.SourcesDirectory)/scripts/requirements.txt
|
||||
displayName: 'Install Python requirements'
|
||||
- task: CMake@1
|
||||
inputs:
|
||||
workingDirectory: '$(Build.SourcesDirectory)/bin'
|
||||
cmakeArgs: '.. -DCMAKE_TOOLCHAIN_FILE=cmake-toolchain/linux-amd64.cmake -DCMAKE_C_COMPILER=clang'
|
||||
cmakeArgs: '.. -DCMAKE_TOOLCHAIN_FILE=cmake-toolchain/linux-amd64.cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++'
|
||||
- task: CMake@1
|
||||
inputs:
|
||||
workingDirectory: '$(Build.SourcesDirectory)/bin'
|
||||
cmakeArgs: '--build .'
|
||||
cmakeArgs: '--build . -j 8'
|
||||
- script: |
|
||||
cd bin/exe/AMD64/Linux
|
||||
./symcryptmoduletest
|
||||
displayName: 'Execute module test'
|
||||
- script: |
|
||||
cd bin/exe/AMD64/Linux
|
||||
./symcryptunittest
|
||||
displayName: 'Execute generic unit test'
|
||||
name: 'LinuxGenericUnitTest'
|
||||
displayName: 'Execute unit test'
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
SourceFolder: 'bin'
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
#define _SYMCRYPT_EXPAND_JOIN(a, b) _SYMCRYPT_JOIN(a, b)
|
||||
#define SYMCRYPT_BUILD_INFO_BRANCH "@SYMCRYPT_BUILD_INFO_BRANCH@"
|
||||
#define SYMCRYPT_BUILD_INFO_COMMIT "@SYMCRYPT_BUILD_INFO_COMMIT@"
|
||||
#define SYMCRYPT_BUILD_INFO_VERSION _SYMCRYPT_EXPAND_JOIN(SYMCRYPT_CODE_VERSION_API, SYMCRYPT_CODE_VERSION_MINOR)
|
||||
#define SYMCRYPT_BUILD_INFO_VERSION _SYMCRYPT_EXPAND_JOIN(_SYMCRYPT_EXPAND_JOIN(SYMCRYPT_CODE_VERSION_API, SYMCRYPT_CODE_VERSION_MINOR), SYMCRYPT_CODE_VERSION_PATCH)
|
||||
#define SYMCRYPT_BUILD_INFO_TIMESTAMP "@SYMCRYPT_BUILD_INFO_TIMESTAMP@"
|
||||
|
|
|
@ -465,7 +465,7 @@ SymCryptUint64Bytesize( UINT64 value );
|
|||
//
|
||||
// SYMCRYPT_ENVIRONMENT_WINDOWS_BOOTLIBRARY // only for the current OS release
|
||||
//
|
||||
// SYMCRYPT_ENVIRONMENT_WINDWOS_KERNELMODE_LEGACY // Use for any version of Windows.
|
||||
// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_LEGACY // Use for any version of Windows.
|
||||
// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN7_N_LATER // Only for Win7 and later
|
||||
// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN8_1_N_LATER // Only for WinBlue and later
|
||||
// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_LATEST // use for latest OS
|
||||
|
@ -477,6 +477,8 @@ SymCryptUint64Bytesize( UINT64 value );
|
|||
//
|
||||
// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELDEBUGGER
|
||||
//
|
||||
// SYMCRYPT_ENVIRONMENT_LINUX_USERMODE // use for Linux
|
||||
//
|
||||
// SYMCRYPT_ENVIRONMENT_GENERIC // use for all other situations
|
||||
//
|
||||
|
||||
|
@ -484,8 +486,9 @@ VOID
|
|||
SYMCRYPT_CALL
|
||||
SymCryptInit();
|
||||
//
|
||||
// Initialize the library.
|
||||
// Initialize the static library.
|
||||
// This function MUST be called before any other function in the library.
|
||||
// It is not necessary to call this function when using the shared object library.
|
||||
//
|
||||
// This function does not perform the self tests in the library.
|
||||
// Doing so would force the linking of all the algorithm in the library,
|
||||
|
@ -501,7 +504,20 @@ SymCryptInit();
|
|||
// to invoke one of the environment macros documented above.
|
||||
//
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptModuleInit(
|
||||
_In_ UINT32 api,
|
||||
_In_ UINT32 minor,
|
||||
_In_ UINT32 patch);
|
||||
|
||||
#define SYMCRYPT_MODULE_INIT() SymCryptModuleInit(SYMCRYPT_CODE_VERSION_API, SYMCRYPT_CODE_VERSION_MINOR, SYMCRYPT_CODE_VERSION_PATCH);
|
||||
//
|
||||
// Initialize the SymCrypt shared object module/dynamic-link library. This function verifies
|
||||
// that the module version supports the version requested by the application. If the version
|
||||
// is unsupported, a fatal error will occur. The macro SYMCRYPT_MODULE_INIT can be used
|
||||
// to call SymCryptModuleInit with the correct arguments.
|
||||
//
|
||||
|
||||
//==========================================================================
|
||||
// DATA MANIPULATION
|
||||
|
@ -4258,6 +4274,7 @@ SymCryptCallbackFree( VOID * pMem );
|
|||
_Success_(return == SYMCRYPT_NO_ERROR)
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SYMCRYPT_WEAK_SYMBOL
|
||||
SymCryptCallbackRandom(
|
||||
_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,
|
||||
SIZE_T cbBuffer );
|
||||
|
|
|
@ -300,13 +300,20 @@ C_ASSERT( (SYMCRYPT_ALIGN_VALUE & (SYMCRYPT_ALIGN_VALUE - 1 )) == 0 );
|
|||
#define SYMCRYPT_ALIGN_UP( _p ) ((PBYTE) ( ((UINT_PTR) (_p) + SYMCRYPT_ALIGN_VALUE - 1) & ~(SYMCRYPT_ALIGN_VALUE - 1 ) ) )
|
||||
|
||||
#if SYMCRYPT_MS_VC
|
||||
#define SYMCRYPT_ALIGN __declspec(align(SYMCRYPT_ALIGN_VALUE))
|
||||
#define SYMCRYPT_ALIGN_STRUCT SYMCRYPT_ALIGN struct
|
||||
#define SYMCRYPT_ALIGN_AT(x) __declspec(align(x))
|
||||
#define SYMCRYPT_ALIGN __declspec(align(SYMCRYPT_ALIGN_VALUE))
|
||||
#define SYMCRYPT_ALIGN_STRUCT SYMCRYPT_ALIGN struct
|
||||
#define SYMCRYPT_ALIGN_AT(x) __declspec(align(x))
|
||||
#define SYMCRYPT_WEAK_SYMBOL
|
||||
#elif SYMCRYPT_GNUC
|
||||
#define SYMCRYPT_ALIGN __attribute__((aligned(SYMCRYPT_ALIGN_VALUE)))
|
||||
#define SYMCRYPT_ALIGN_STRUCT struct SYMCRYPT_ALIGN
|
||||
#define SYMCRYPT_ALIGN_AT(x) __attribute__((aligned(x)))
|
||||
#define SYMCRYPT_WEAK_SYMBOL __attribute__((weak))
|
||||
#else
|
||||
#define SYMCRYPT_ALIGN __attribute__((aligned(SYMCRYPT_ALIGN_VALUE)))
|
||||
#define SYMCRYPT_ALIGN_STRUCT struct SYMCRYPT_ALIGN
|
||||
#define SYMCRYPT_ALIGN_AT(x) __attribute__((aligned(x)))
|
||||
#define SYMCRYPT_ALIGN
|
||||
#define SYMCRYPT_ALIGN_STRUCT
|
||||
#define SYMCRYPT_ALIGN_AT(x)
|
||||
#define SYMCRYPT_WEAK_SYMBOL
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -2498,6 +2505,8 @@ SYMCRYPT_EXTERN_C_END
|
|||
#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_LATEST SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN8_1_N_LATER
|
||||
|
||||
|
||||
#define SYMCRYPT_ENVIRONMENT_LINUX_USERMODE SYMCRYPT_ENVIRONMENT_DEFS( LinuxUsermode )
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
//
|
||||
// SymCryptWipe & SymCryptWipeKnownSize
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
SYMCRYPT_CODE_VERSION_API EQU 100
|
||||
SYMCRYPT_CODE_VERSION_MINOR EQU 16
|
||||
SYMCRYPT_CODE_VERSION_PATCH EQU 0
|
||||
|
||||
|
||||
if 0 ; Start an area that the assembler ignores
|
||||
|
@ -39,6 +40,7 @@ SYMCRYPT_CODE_VERSION_MINOR EQU 16
|
|||
|
||||
#define SYMCRYPT_CODE_VERSION_API 100
|
||||
#define SYMCRYPT_CODE_VERSION_MINOR 16
|
||||
#define SYMCRYPT_CODE_VERSION_PATCH 0
|
||||
|
||||
;/* ; Switch back into a C comment so that we can close the IF
|
||||
endif
|
||||
|
|
|
@ -1,99 +1,98 @@
|
|||
set(SOURCES_COMMON
|
||||
blockciphermodes.c
|
||||
hash.c
|
||||
parhash.c
|
||||
ccm.c
|
||||
ghash.c
|
||||
gcm.c
|
||||
aes-default.c
|
||||
aes-default-bc.c
|
||||
aes-key.c
|
||||
aes-c.c
|
||||
3des.c
|
||||
a_dispatch.c
|
||||
aes-asm.c
|
||||
aes-xmm.c
|
||||
aes-ymm.c
|
||||
aes-c.c
|
||||
aes-default-bc.c
|
||||
aes-default.c
|
||||
aes-key.c
|
||||
aes-neon.c
|
||||
aes-selftest.c
|
||||
AesTables.c
|
||||
aes-xmm.c
|
||||
aes-ymm.c
|
||||
aescmac.c
|
||||
xtsaes.c
|
||||
3des.c
|
||||
aesCtrDrbg.c
|
||||
AesTables.c
|
||||
blockciphermodes.c
|
||||
ccm.c
|
||||
chacha20_poly1305.c
|
||||
chacha20.c
|
||||
cpuid_notry.c
|
||||
cpuid_um.c
|
||||
cpuid.c
|
||||
crt.c
|
||||
DesTables.c
|
||||
desx.c
|
||||
rc2.c
|
||||
rc4.c
|
||||
sha1.c
|
||||
sha256.c
|
||||
sha512.c
|
||||
md5.c
|
||||
md4.c
|
||||
md2.c
|
||||
dh.c
|
||||
dl_internal_groups.c
|
||||
dlgroup.c
|
||||
dlkey.c
|
||||
dsa.c
|
||||
ec_dh.c
|
||||
ec_dispatch.c
|
||||
ec_dsa.c
|
||||
ec_internal_curves.c
|
||||
ec_montgomery.c
|
||||
ec_mul.c
|
||||
ec_short_weierstrass.c
|
||||
ec_twisted_edwards.c
|
||||
eckey.c
|
||||
ecpoint.c
|
||||
ecurve.c
|
||||
equal.c
|
||||
FatalIntercept.c
|
||||
fdef_general.c
|
||||
fdef_int.c
|
||||
fdef_mod.c
|
||||
fdef369_mod.c
|
||||
gcm.c
|
||||
gen_int.c
|
||||
ghash.c
|
||||
hash.c
|
||||
hkdf_selftest.c
|
||||
hkdf.c
|
||||
hmacmd5.c
|
||||
hmacsha1.c
|
||||
hmacsha256.c
|
||||
hmacsha384.c
|
||||
hmacsha512.c
|
||||
tlsCbcVerify.c
|
||||
aesCtrDrbg.c
|
||||
libmain.c
|
||||
equal.c
|
||||
FatalIntercept.c
|
||||
selftest.c
|
||||
rdrand.c
|
||||
rdseed.c
|
||||
sha256Par.c
|
||||
sha256Par-ymm.c
|
||||
sha512Par.c
|
||||
sha512Par-ymm.c
|
||||
marvin32.c
|
||||
cpuid.c
|
||||
cpuid_um.c
|
||||
cpuid_notry.c
|
||||
pbkdf2.c
|
||||
md2.c
|
||||
md4.c
|
||||
md5.c
|
||||
modexp.c
|
||||
parhash.c
|
||||
pbkdf2_hmacsha1.c
|
||||
pbkdf2_hmacsha256.c
|
||||
sp800_108.c
|
||||
sp800_108_hmacsha1.c
|
||||
sp800_108_hmacsha256.c
|
||||
tlsprf.c
|
||||
tlsprf_selftest.c
|
||||
hkdf.c
|
||||
hkdf_selftest.c
|
||||
chacha20.c
|
||||
pbkdf2.c
|
||||
poly1305.c
|
||||
chacha20_poly1305.c
|
||||
a_dispatch.c
|
||||
fdef_general.c
|
||||
fdef_int.c
|
||||
fdef_mod.c
|
||||
fdef369_mod.c
|
||||
ecpoint.c
|
||||
ecurve.c
|
||||
eckey.c
|
||||
ec_dispatch.c
|
||||
ec_short_weierstrass.c
|
||||
ec_internal_curves.c
|
||||
ec_dsa.c
|
||||
ec_dh.c
|
||||
ec_montgomery.c
|
||||
ec_twisted_edwards.c
|
||||
ec_mul.c
|
||||
ScsTable.c
|
||||
scsTools.c
|
||||
primes.c
|
||||
modexp.c
|
||||
gen_int.c
|
||||
crt.c
|
||||
rsakey.c
|
||||
rc2.c
|
||||
rc4.c
|
||||
rdrand.c
|
||||
rdseed.c
|
||||
recoding.c
|
||||
rsa_enc.c
|
||||
rsa_padding.c
|
||||
dlgroup.c
|
||||
dlkey.c
|
||||
dsa.c
|
||||
dh.c
|
||||
dl_internal_groups.c
|
||||
recoding.c
|
||||
IEEE802_11SaeCustom.c
|
||||
rsakey.c
|
||||
ScsTable.c
|
||||
scsTools.c
|
||||
selftest.c
|
||||
sha1.c
|
||||
sha256.c
|
||||
sha256Par.c
|
||||
sha256Par-ymm.c
|
||||
sha512.c
|
||||
sha512Par.c
|
||||
sha512Par-ymm.c
|
||||
sp800_108_hmacsha1.c
|
||||
sp800_108_hmacsha256.c
|
||||
sp800_108.c
|
||||
tlsCbcVerify.c
|
||||
tlsprf_selftest.c
|
||||
tlsprf.c
|
||||
xtsaes.c
|
||||
)
|
||||
|
||||
function(process_cppasm filepath outformat archdefine)
|
||||
|
@ -176,7 +175,9 @@ function(process_symcryptasm filepath outformat archdefine)
|
|||
process_cppasm(${output_cppasm} ${outformat} ${archdefine})
|
||||
endfunction()
|
||||
|
||||
if(NOT WIN32)
|
||||
if(WIN32)
|
||||
list(APPEND SOURCES_COMMON IEEE802_11SaeCustom.c)
|
||||
else()
|
||||
list(APPEND SOURCES_COMMON linux/intrinsics.c)
|
||||
endif()
|
||||
|
||||
|
@ -284,11 +285,14 @@ if(WIN32)
|
|||
target_link_libraries(symcrypt_windows10sgx symcrypt_common)
|
||||
endif()
|
||||
|
||||
set(SOURCES_GENERIC ${SOURCES_COMMON})
|
||||
list(APPEND SOURCES_GENERIC env_generic.c)
|
||||
if(NOT WIN32)
|
||||
add_compile_options(-Wno-trigraphs)
|
||||
|
||||
add_library(symcrypt_linuxusermode STATIC env_linuxUserMode.c)
|
||||
set_target_properties(symcrypt_linuxusermode PROPERTIES PREFIX "")
|
||||
target_link_libraries(symcrypt_linuxusermode symcrypt_common)
|
||||
endif()
|
||||
|
||||
add_library(symcrypt_generic STATIC env_generic.c)
|
||||
set_target_properties(symcrypt_generic PROPERTIES PREFIX "")
|
||||
target_link_libraries(symcrypt_generic symcrypt_common)
|
||||
|
|
|
@ -55,7 +55,7 @@ const UINT32 g_SymCryptModFnsMask = sizeof( g_SymCryptModFns ) - sizeof( g_SymCr
|
|||
//
|
||||
// Tweaking the selection & function tables allows different tradeoffs of performance vs codesize
|
||||
//
|
||||
SYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY SymCryptModulusTypeSelections[] =
|
||||
const SYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY SymCryptModulusTypeSelections[] =
|
||||
{
|
||||
#if SYMCRYPT_CPU_AMD64
|
||||
// Mulx used for 257-512 and 577-... bits
|
||||
|
|
|
@ -287,7 +287,7 @@ SymCryptRngAesGenerateBlocks(
|
|||
SymCryptAesEncrypt( pAesKey, Vcopy, buf );
|
||||
if( memcmp( buf, pbCheck, 16 ) != 0 )
|
||||
{
|
||||
SymCryptFatal( '????' );
|
||||
SymCryptFatal( 'OLD?' );
|
||||
}
|
||||
pbCheck += SYMCRYPT_AES_BLOCK_SIZE;
|
||||
cbCheck -= SYMCRYPT_AES_BLOCK_SIZE;
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
//
|
||||
// env_linuxUserMode.c
|
||||
// Platform-specific code for linux user mode.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
|
||||
SYMCRYPT_CPU_FEATURES SYMCRYPT_CALL SymCryptCpuFeaturesNeverPresentEnvLinuxUsermode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptInitEnvLinuxUsermode( UINT32 version )
|
||||
{
|
||||
if( g_SymCryptFlags & SYMCRYPT_FLAG_LIB_INITIALIZED )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64
|
||||
SymCryptDetectCpuFeaturesByCpuid( SYMCRYPT_CPUID_DETECT_FLAG_CHECK_OS_SUPPORT_FOR_YMM );
|
||||
|
||||
//
|
||||
// Don't use Ymm registers if the OS doesn't report them as available.
|
||||
// We assume Ymm register swapping isn't supported unless we can verify that it is.
|
||||
//
|
||||
g_SymCryptCpuFeaturesNotPresent |= SYMCRYPT_CPU_FEATURE_AVX2;
|
||||
|
||||
#if SYMCRYPT_MS_VC
|
||||
if( (GetEnabledXStateFeatures() & XSTATE_MASK_AVX) != 0 )
|
||||
{
|
||||
g_SymCryptCpuFeaturesNotPresent &= ~SYMCRYPT_CPU_FEATURE_AVX2;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Our SaveXmm function never fails because it doesn't have to do anything in User mode.
|
||||
//
|
||||
g_SymCryptCpuFeaturesNotPresent &= ~SYMCRYPT_CPU_FEATURE_SAVEXMM_NOFAIL;
|
||||
|
||||
#elif SYMCRYPT_CPU_ARM
|
||||
|
||||
g_SymCryptCpuFeaturesNotPresent = (SYMCRYPT_CPU_FEATURES) ~SYMCRYPT_CPU_FEATURE_NEON;
|
||||
|
||||
#elif SYMCRYPT_CPU_ARM64
|
||||
|
||||
SymCryptDetectCpuFeaturesFromIsProcessorFeaturePresent();
|
||||
|
||||
#endif
|
||||
|
||||
SymCryptInitEnvCommon( version );
|
||||
}
|
||||
|
||||
_Analysis_noreturn_
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptFatalEnvLinuxUsermode( ULONG fatalCode )
|
||||
{
|
||||
UINT32 fatalCodeVar;
|
||||
|
||||
SymCryptFatalIntercept( fatalCode );
|
||||
|
||||
//
|
||||
// Put the fatal code in a location where it shows up in the dump
|
||||
//
|
||||
SYMCRYPT_FORCE_WRITE32( &fatalCodeVar, fatalCode );
|
||||
|
||||
//
|
||||
// Our first preference is to fastfail,
|
||||
// the second to create an AV, which can trigger a core dump so that we get to
|
||||
// see what is going wrong.
|
||||
//
|
||||
__fastfail( FAST_FAIL_CRYPTO_LIBRARY );
|
||||
|
||||
//
|
||||
// Next we write to the NULL pointer, this causes an AV
|
||||
//
|
||||
SYMCRYPT_FORCE_WRITE32( (volatile UINT32 *)NULL, fatalCode );
|
||||
|
||||
SymCryptFatalHang( fatalCode );
|
||||
}
|
||||
|
||||
#if SYMCRYPT_CPU_AMD64
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptSaveXmmEnvLinuxUsermode( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveData )
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pSaveData );
|
||||
|
||||
return SYMCRYPT_NO_ERROR;
|
||||
}
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptRestoreXmmEnvLinuxUsermode( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveData )
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pSaveData );
|
||||
}
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptSaveYmmEnvLinuxUsermode( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveData )
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pSaveData );
|
||||
|
||||
return SYMCRYPT_NO_ERROR;
|
||||
}
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptRestoreYmmEnvLinuxUsermode( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveData )
|
||||
{
|
||||
UNREFERENCED_PARAMETER( pSaveData );
|
||||
}
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptCpuidExFuncEnvLinuxUsermode( int cpuInfo[4], int function_id, int subfunction_id )
|
||||
{
|
||||
__cpuidex( cpuInfo, function_id, subfunction_id );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptTestInjectErrorEnvLinuxUsermode( PBYTE pbBuf, SIZE_T cbBuf )
|
||||
{
|
||||
//
|
||||
// This feature is only used during testing. In production it is always
|
||||
// an empty function that the compiler can optimize away.
|
||||
//
|
||||
UNREFERENCED_PARAMETER( pbBuf );
|
||||
UNREFERENCED_PARAMETER( cbBuf );
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#elif SYMCRYPT_CPU_ARM64
|
||||
#define SYMCRYPT_FDEF369_DIGITS_TO_NUINT32( nD ) ((nD) * 6)
|
||||
#else
|
||||
#??
|
||||
#error ??
|
||||
#endif
|
||||
|
||||
VOID
|
||||
|
|
|
@ -277,7 +277,7 @@ SymCryptFdefDecideModulusType( PCSYMCRYPT_INT piSrc, UINT32 nDigits, UINT32 aver
|
|||
{
|
||||
UINT32 res = 0;
|
||||
BOOLEAN disableMontgomery = 0;
|
||||
PSYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY pEntry;
|
||||
PCSYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY pEntry;
|
||||
|
||||
UINT32 nBitsizeOfValue = SymCryptIntBitsizeOfValue( piSrc );
|
||||
UINT32 modulusFeatures = 0;
|
||||
|
|
|
@ -32,9 +32,9 @@ SymCryptLibraryWasNotInitialized()
|
|||
|
||||
#endif
|
||||
|
||||
const CHAR * SymCryptBuildString =
|
||||
"v" SYMCRYPT_BUILD_INFO_VERSION
|
||||
"_" SYMCRYPT_BUILD_INFO_BRANCH
|
||||
const CHAR * const SymCryptBuildString =
|
||||
"v" SYMCRYPT_BUILD_INFO_VERSION
|
||||
"_" SYMCRYPT_BUILD_INFO_BRANCH
|
||||
"_" SYMCRYPT_BUILD_INFO_COMMIT
|
||||
"_" SYMCRYPT_BUILD_INFO_TIMESTAMP;
|
||||
|
||||
|
|
|
@ -1628,8 +1628,9 @@ typedef struct _SYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY
|
|||
UINT32 maxBits; // Max # bits that the actual value of the modulus is, 0 = no limit
|
||||
UINT32 modulusFeatures; // Required features of the modulus
|
||||
} SYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY, *PSYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY;
|
||||
typedef const SYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY* PCSYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY;
|
||||
|
||||
extern SYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY SymCryptModulusTypeSelections[]; // Array can be any size...
|
||||
extern const SYMCRYPT_MODULUS_TYPE_SELECTION_ENTRY SymCryptModulusTypeSelections[]; // Array can be any size...
|
||||
|
||||
|
||||
// Check that the size is a power of 2
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
add_subdirectory(linux_common) # Common functionality for Linux modules
|
||||
add_subdirectory(oe_full) # OpenEnclave with all functionality
|
|
@ -0,0 +1,6 @@
|
|||
set(SOURCES
|
||||
integrity.c)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/inc)
|
||||
|
||||
add_library(symcrypt_module_linux_common STATIC ${SOURCES})
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"Registrations": [
|
||||
{
|
||||
"Component": {
|
||||
"Type": "Other",
|
||||
"Other": {
|
||||
"Name": "elfdefinitions.h",
|
||||
"Version": "3769",
|
||||
"DownloadUrl": "https://cgit.freebsd.org/src/plain/contrib/elftoolchain/common/elfdefinitions.h"
|
||||
}
|
||||
},
|
||||
"DevelopmentDependency": false
|
||||
}
|
||||
]
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,270 @@
|
|||
//
|
||||
// integrity.c
|
||||
// FIPS 140-3 integrity verification implementation for ELF binaries
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#define SYMCRYPT_FIPS_ASSERT(x) { if(!(x)){ SymCryptFatal('FIPS'); } }
|
||||
|
||||
#define PLACEHOLDER_VALUE 0x8BADF00D
|
||||
#define PLACEHOLDER_ARRAY \
|
||||
{\
|
||||
0x5B, 0x75, 0xBB, 0xE4, 0x9E, 0x18, 0x03, 0x55,\
|
||||
0x08, 0x4E, 0x3F, 0xE7, 0x60, 0x7E, 0x4F, 0x08,\
|
||||
0xAA, 0x77, 0x0F, 0x0B, 0xAB, 0xC6, 0x58, 0x5A,\
|
||||
0xA9, 0x9F, 0x83, 0x4B, 0xD0, 0x6E, 0x67, 0x05\
|
||||
}
|
||||
|
||||
// The following variables use placeholder values which will be modified after compile time by our
|
||||
// helper script. They need to be statically initialized to non-zero values so they are put in the
|
||||
// .data segment rather than the .bss segment, as the latter's representation in the module on disk
|
||||
// is not necessarily the same size as the values in memory at runtime.
|
||||
//
|
||||
// Because these values are modified after compile time, the scalar values must be read using
|
||||
// SYMCRYPT_FORCE_READ64 or the compiler may inline the placeholder values, leading to incorrect
|
||||
// results at runtime.
|
||||
const Elf64_Addr SymCryptVolatileFipsHmacKeyRva = (Elf64_Addr) PLACEHOLDER_VALUE;
|
||||
const Elf64_Off SymCryptVolatileFipsBoundaryOffset = PLACEHOLDER_VALUE;
|
||||
|
||||
const unsigned char SymCryptVolatileFipsHmacKey[32] = PLACEHOLDER_ARRAY;
|
||||
unsigned char SymCryptVolatileFipsHmacDigest[SYMCRYPT_HMAC_SHA256_RESULT_SIZE] = PLACEHOLDER_ARRAY;
|
||||
|
||||
|
||||
void SymCryptModuleUndoRelocation(
|
||||
_In_ const Elf64_Addr module_base,
|
||||
_Inout_ Elf64_Xword* const target,
|
||||
_In_ const Elf64_Rela* rela )
|
||||
{
|
||||
Elf64_Xword replacement = 0;
|
||||
|
||||
switch( ELF64_R_TYPE( rela->r_info ) )
|
||||
{
|
||||
case R_X86_64_RELATIVE:
|
||||
replacement = *target - (Elf64_Off) module_base;
|
||||
break;
|
||||
case R_X86_64_64:
|
||||
case R_X86_64_GLOB_DAT:
|
||||
replacement = 0;
|
||||
break;
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
default:
|
||||
// We cannot handle other relocation types
|
||||
SYMCRYPT_FIPS_ASSERT( FALSE );
|
||||
break;
|
||||
}
|
||||
|
||||
*target = replacement;
|
||||
}
|
||||
|
||||
void SymCryptModuleFindRelocationInfo(
|
||||
_In_ const Elf64_Dyn* const dynStart,
|
||||
_Out_ Elf64_Rela** relaStart,
|
||||
_Out_ size_t* relaEntryCount )
|
||||
{
|
||||
size_t relaTotalSize = 0;
|
||||
size_t relaEntrySize = 0;
|
||||
|
||||
for( const Elf64_Dyn* dyn = dynStart; dyn->d_tag != DT_NULL; ++dyn )
|
||||
{
|
||||
switch( dyn->d_tag )
|
||||
{
|
||||
case DT_RELA:
|
||||
*relaStart = (Elf64_Rela*) dyn->d_un.d_ptr;
|
||||
break;
|
||||
|
||||
case DT_RELASZ:
|
||||
relaTotalSize = dyn->d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELAENT:
|
||||
relaEntrySize = dyn->d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_JMPREL:
|
||||
case DT_PLTRELSZ:
|
||||
// We cannot handle PLT relocations
|
||||
SYMCRYPT_FIPS_ASSERT( FALSE );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SYMCRYPT_FIPS_ASSERT( relaStart != NULL );
|
||||
SYMCRYPT_FIPS_ASSERT( relaEntrySize == sizeof( Elf64_Rela ) );
|
||||
SYMCRYPT_FIPS_ASSERT( relaTotalSize != 0 && relaTotalSize % relaEntrySize == 0 );
|
||||
|
||||
*relaEntryCount = relaTotalSize / relaEntrySize;
|
||||
}
|
||||
|
||||
size_t SymCryptModuleProcessSectionWithRelocations(
|
||||
_In_ const Elf64_Addr module_base,
|
||||
_In_ const Elf64_Phdr* const programHeader,
|
||||
_In_ const Elf64_Dyn* const dynStart,
|
||||
_In_ const Elf64_Rela* const relaStart,
|
||||
_In_ const size_t relaEntryCount,
|
||||
_Inout_ SYMCRYPT_HMAC_SHA256_STATE* hmacState )
|
||||
{
|
||||
// The segment that contains relocations consists of the following sections, in this order:
|
||||
// .data.rel.ro .dynamic .got .data .bss
|
||||
//
|
||||
// .data.rel.ro, .dynamic and .got contain relocations, but are not modified by the code itself
|
||||
// once the dynamic linker has performed the relocations, so these sections are included in our
|
||||
// HMAC calculation.
|
||||
//
|
||||
// .data includes non-constant global variables which can change at runtime. We cannot reverse
|
||||
// these values without tightly coupling this integrity verification implementation to internal
|
||||
// implementation details of SymCrypt, so it is not included in our HMAC. The .bss section in
|
||||
// the module on disk is usually a different size than at runtime, so we cannot include it in
|
||||
// our HMAC either.
|
||||
//
|
||||
// FipsBoundaryOffset marks the start of the .data section, so we read from the start of the
|
||||
// segment up to that offset.
|
||||
size_t hashableSectionSize = SYMCRYPT_FORCE_READ64( &SymCryptVolatileFipsBoundaryOffset ) - programHeader->p_offset;
|
||||
Elf64_Addr segmentStart = module_base + programHeader->p_vaddr;
|
||||
|
||||
BYTE* segmentCopy = SymCryptCallbackAlloc( hashableSectionSize );
|
||||
SYMCRYPT_FIPS_ASSERT( segmentCopy != NULL );
|
||||
|
||||
memcpy( segmentCopy, (const unsigned char*) segmentStart, hashableSectionSize );
|
||||
|
||||
// Some of the entries in the .dynamic section get relocated, but those relocations are not
|
||||
// included in the list of relocations given in the .rela.dyn section. Thus, we must process
|
||||
// these relocations separately. We find the .dynamic section in the copied buffer based on
|
||||
// its offset from the start of the section, which is calculated by subtracting the address
|
||||
// of the start of the segment from the address of the .dynamic section in the segment.
|
||||
Elf64_Off dynOffsetInBuffer = (Elf64_Addr) dynStart - (Elf64_Addr) programHeader->p_vaddr - (Elf64_Off) module_base;
|
||||
Elf64_Dyn* dynStartInBuffer = (Elf64_Dyn*) (segmentCopy + dynOffsetInBuffer);
|
||||
|
||||
for( Elf64_Dyn* dyn = dynStartInBuffer; dyn->d_tag != DT_NULL; ++dyn )
|
||||
{
|
||||
// The following types of .dynamic entries have the module's base address added to
|
||||
// their initial value
|
||||
if( dyn->d_tag == DT_STRTAB ||
|
||||
dyn->d_tag == DT_SYMTAB ||
|
||||
dyn->d_tag == DT_RELA ||
|
||||
dyn->d_tag == DT_GNU_HASH ||
|
||||
dyn->d_tag == DT_VERSYM )
|
||||
{
|
||||
dyn->d_un.d_val -= (Elf64_Xword) module_base;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can process the normal relocations listed in the relocation table
|
||||
for( size_t i = 0; i < relaEntryCount; ++i )
|
||||
{
|
||||
const Elf64_Rela* rela = relaStart + i;
|
||||
|
||||
// Find the relocation within the section. Note that for a shared object module,
|
||||
// rela->r_offset is actually a virtual address
|
||||
Elf64_Xword* target = (Elf64_Xword*) ( segmentCopy +
|
||||
(Elf64_Off) rela->r_offset - (Elf64_Off) programHeader->p_vaddr );
|
||||
|
||||
SymCryptModuleUndoRelocation( module_base, target, rela );
|
||||
}
|
||||
|
||||
SymCryptHmacSha256Append( hmacState, segmentCopy, hashableSectionSize );
|
||||
|
||||
SymCryptCallbackFree( segmentCopy );
|
||||
|
||||
return hashableSectionSize;
|
||||
}
|
||||
|
||||
void SymCryptModuleDoHmac(
|
||||
_In_ const Elf64_Addr module_base,
|
||||
_In_ const Elf64_Dyn* const dynStart,
|
||||
_In_ const Elf64_Rela* const relaStart,
|
||||
_In_ const size_t relaEntryCount )
|
||||
{
|
||||
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
|
||||
SYMCRYPT_HMAC_SHA256_EXPANDED_KEY hmacKey;
|
||||
SYMCRYPT_HMAC_SHA256_STATE hmacState;
|
||||
BYTE actualDigest[SYMCRYPT_HMAC_SHA256_RESULT_SIZE] = {0xFF};
|
||||
|
||||
scError = SymCryptHmacSha256ExpandKey( &hmacKey, SymCryptVolatileFipsHmacKey,
|
||||
sizeof(SymCryptVolatileFipsHmacKey) );
|
||||
SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR );
|
||||
|
||||
SymCryptHmacSha256Init( &hmacState, &hmacKey );
|
||||
|
||||
const Elf64_Ehdr* header = (Elf64_Ehdr*) module_base;
|
||||
const Elf64_Phdr* programHeaderStart = (Elf64_Phdr*) ( module_base + header->e_phoff );
|
||||
|
||||
for( const Elf64_Phdr* programHeader = programHeaderStart;
|
||||
programHeader->p_type == PT_LOAD; ++programHeader )
|
||||
{
|
||||
// Sometimes the virtual address of a segment is greater than its offset into the module
|
||||
// file on disk. This means extra NULL bytes will be inserted into the module's memory
|
||||
// space at runtime. Those bytes are not part of our FIPS boundary, so we skip over them
|
||||
// and always start reading from the segment's virtual address
|
||||
Elf64_Addr segmentStart = module_base + (Elf64_Off) programHeader->p_vaddr;
|
||||
|
||||
if( (programHeader->p_flags & PF_W) == 0 )
|
||||
{
|
||||
// For AMD64, non-writeable segments do not contain relocations, so we can write them in
|
||||
// their entirety without modification. Note that the size in memory of the section may
|
||||
// be larger than the size on disk, but again, the additional size in memory is not
|
||||
// part of our FIPS boundary
|
||||
SymCryptHmacSha256Append( &hmacState, (const unsigned char*) segmentStart,
|
||||
programHeader->p_filesz );
|
||||
}
|
||||
else
|
||||
{
|
||||
SymCryptModuleProcessSectionWithRelocations( module_base, programHeader, dynStart, relaStart,
|
||||
relaEntryCount, &hmacState );
|
||||
}
|
||||
}
|
||||
|
||||
SymCryptHmacSha256Result( &hmacState, actualDigest );
|
||||
|
||||
// Verify that the HMAC result matches our expected digest
|
||||
SYMCRYPT_FIPS_ASSERT(
|
||||
memcmp( actualDigest, SymCryptVolatileFipsHmacDigest, SYMCRYPT_HMAC_SHA256_RESULT_SIZE ) == 0 );
|
||||
}
|
||||
|
||||
void SymCryptModuleVerifyIntegrity()
|
||||
{
|
||||
// Verify that our placeholder values were modified after compile time. The build script
|
||||
// should have replaced the placeholder values with their expected values
|
||||
SYMCRYPT_FIPS_ASSERT( SYMCRYPT_FORCE_READ64( &SymCryptVolatileFipsHmacKeyRva ) != PLACEHOLDER_VALUE );
|
||||
SYMCRYPT_FIPS_ASSERT( SYMCRYPT_FORCE_READ64( &SymCryptVolatileFipsBoundaryOffset ) != PLACEHOLDER_VALUE );
|
||||
|
||||
const Elf64_Addr module_base = (Elf64_Addr) SymCryptVolatileFipsHmacKey -
|
||||
SYMCRYPT_FORCE_READ64( &SymCryptVolatileFipsHmacKeyRva );
|
||||
|
||||
const Elf64_Ehdr* header = (Elf64_Ehdr*) module_base;
|
||||
SYMCRYPT_FIPS_ASSERT( memcmp(header->e_ident.ident.magic, ElfMagic, sizeof(ElfMagic)) == 0 );
|
||||
SYMCRYPT_FIPS_ASSERT( header->e_type == ET_DYN );
|
||||
SYMCRYPT_FIPS_ASSERT( header->e_machine == EM_X86_64 );
|
||||
SYMCRYPT_FIPS_ASSERT( header->e_version == EV_CURRENT );
|
||||
SYMCRYPT_FIPS_ASSERT( header->e_ehsize == sizeof(Elf64_Ehdr) );
|
||||
SYMCRYPT_FIPS_ASSERT( header->e_phentsize == sizeof(Elf64_Phdr) );
|
||||
|
||||
const Elf64_Phdr* programHeaderStart = (Elf64_Phdr*) ( module_base + header->e_phoff );
|
||||
|
||||
Elf64_Rela* relaStart = NULL;
|
||||
size_t relaEntryCount = 0;
|
||||
|
||||
Elf64_Dyn* dynStart = NULL;
|
||||
|
||||
for( unsigned int i = 0; i < header->e_phnum; ++i )
|
||||
{
|
||||
const Elf64_Phdr* programHeader = programHeaderStart + i;
|
||||
if( programHeader->p_type == PT_DYNAMIC )
|
||||
{
|
||||
dynStart = (Elf64_Dyn*) (module_base + (Elf64_Off) programHeader->p_vaddr);
|
||||
|
||||
SymCryptModuleFindRelocationInfo( dynStart, &relaStart, &relaEntryCount );
|
||||
|
||||
// We only expect one PT_DYNAMIC segment
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SymCryptModuleDoHmac( module_base, dynStart, relaStart, relaEntryCount );
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// integrity.h
|
||||
// FIPS 140-3 integrity verification header for ELF binaries
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
void SymCryptModuleVerifyIntegrity();
|
||||
//
|
||||
// This function verifies the integrity of the loadable segments of the SymCrypt ELF module using
|
||||
// HMAC-SHA256. The module must have been postprocessed after compilation using
|
||||
// process_fips_module.py. The integrity check finds the module's base address in memory by
|
||||
// subtracting the relative virtual address of a known variable from its actual address in memory.
|
||||
// It then uses the ELF header to find all the loadable segments in the module and calculate the
|
||||
// HMAC-SHA256 digest of these segments. For writeable segments which are subject to relocations,
|
||||
// the relocations will be reversed prior to being added to the HMAC, so that the HMAC input will
|
||||
// match the contents of the file on disk prior to relocation.
|
||||
//
|
||||
// If the integrity check fails for any reason, the module will fastfail, crashing the process,
|
||||
// since a failed integrity check means it cannot operate in compliance with FIPS 140-3.
|
||||
//
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// SymCrypt DLL/shared object library pre-compiled header file
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "symcrypt.h"
|
||||
#include "elfdefinitions.h"
|
||||
#include "integrity.h"
|
|
@ -0,0 +1,33 @@
|
|||
set(SOURCES
|
||||
module.c)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/inc ../linux_common)
|
||||
|
||||
add_library(symcrypt SHARED ${SOURCES})
|
||||
|
||||
target_link_options(symcrypt PRIVATE
|
||||
-Wl,--whole-archive
|
||||
$<TARGET_FILE:symcrypt_module_linux_common>
|
||||
$<TARGET_FILE:symcrypt_linuxusermode>
|
||||
$<TARGET_FILE:symcrypt_common>
|
||||
-Wl,--no-whole-archive
|
||||
-Wl,-Bsymbolic
|
||||
-Wl,-z,noexecstack
|
||||
-Wl,-z,now
|
||||
-Wl,-gc-sections
|
||||
-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports.ver
|
||||
-nostdlib
|
||||
-nodefaultlibs
|
||||
-nostartfiles
|
||||
)
|
||||
|
||||
add_dependencies(symcrypt symcrypt_linuxusermode symcrypt_common symcrypt_module_linux_common)
|
||||
|
||||
add_custom_target(
|
||||
symcrypt_fips ALL
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/scripts/process_fips_module.py $<TARGET_FILE:symcrypt> -d
|
||||
DEPENDS $<TARGET_FILE:symcrypt>
|
||||
COMMENT "Postprocessing SymCrypt shared object for FIPS integrity verification"
|
||||
)
|
||||
|
||||
# -Wl,--no-undefined,-Bstatic,-Bsymbolic,--export-dynamic,-pie,--build-id
|
|
@ -0,0 +1,520 @@
|
|||
VERSION_100.16 {
|
||||
global:
|
||||
SymCrypt3DesBlockCipher;
|
||||
SymCrypt3DesCbcDecrypt;
|
||||
SymCrypt3DesCbcEncrypt;
|
||||
SymCrypt3DesDecrypt;
|
||||
SymCrypt3DesEncrypt;
|
||||
SymCrypt3DesExpandKey;
|
||||
SymCrypt3DesSelftest;
|
||||
SymCryptAesBlockCipher;
|
||||
SymCryptAesCbcDecrypt;
|
||||
SymCryptAesCbcEncrypt;
|
||||
SymCryptAesCbcMac;
|
||||
SymCryptAesCmac;
|
||||
SymCryptAesCmacAlgorithm;
|
||||
SymCryptAesCmacAppend;
|
||||
SymCryptAesCmacExpandKey;
|
||||
SymCryptAesCmacInit;
|
||||
SymCryptAesCmacKeyCopy;
|
||||
SymCryptAesCmacResult;
|
||||
SymCryptAesCmacSelftest;
|
||||
SymCryptAesCmacStateCopy;
|
||||
SymCryptAesCtrMsb64;
|
||||
SymCryptAesDecrypt;
|
||||
SymCryptAesEcbDecrypt;
|
||||
SymCryptAesEcbEncrypt;
|
||||
SymCryptAesEncrypt;
|
||||
SymCryptAesExpandKey;
|
||||
SymCryptAesExpandKeyEncryptOnly;
|
||||
SymCryptAesKeyCopy;
|
||||
SymCryptAesSelftest;
|
||||
SymCryptBuildString;
|
||||
SymCryptCbcDecrypt;
|
||||
SymCryptCbcEncrypt;
|
||||
SymCryptCbcMac;
|
||||
SymCryptCcmDecrypt;
|
||||
SymCryptCcmDecryptFinal;
|
||||
SymCryptCcmDecryptPart;
|
||||
SymCryptCcmEncrypt;
|
||||
SymCryptCcmEncryptFinal;
|
||||
SymCryptCcmEncryptPart;
|
||||
SymCryptCcmInit;
|
||||
SymCryptCcmSelftest;
|
||||
SymCryptCcmValidateParameters;
|
||||
SymCryptCfbDecrypt;
|
||||
SymCryptCfbEncrypt;
|
||||
SymCryptChaCha20Crypt;
|
||||
SymCryptChaCha20Init;
|
||||
SymCryptChaCha20Poly1305Decrypt;
|
||||
SymCryptChaCha20Poly1305Encrypt;
|
||||
SymCryptChaCha20Poly1305Selftest;
|
||||
SymCryptChaCha20Selftest;
|
||||
SymCryptChaCha20SetOffset;
|
||||
SymCryptCpuFeaturesNeverPresent;
|
||||
SymCryptCreateTrialDivisionContext;
|
||||
SymCryptCrtGenerateInverses;
|
||||
SymCryptCrtSolve;
|
||||
SymCryptCtrMsb64;
|
||||
SymCryptDesBlockCipher;
|
||||
SymCryptDesDecrypt;
|
||||
SymCryptDesEncrypt;
|
||||
SymCryptDesExpandKey;
|
||||
SymCryptDesSelftest;
|
||||
SymCryptDesxBlockCipher;
|
||||
SymCryptDesxDecrypt;
|
||||
SymCryptDesxEncrypt;
|
||||
SymCryptDesxExpandKey;
|
||||
SymCryptDesxSelftest;
|
||||
SymCryptDhSecretAgreement;
|
||||
SymCryptDigitsFromBits;
|
||||
SymCryptDivisorAllocate;
|
||||
SymCryptDivisorCopy;
|
||||
SymCryptDivisorCreate;
|
||||
SymCryptDivisorDigitsizeOfObject;
|
||||
SymCryptDivisorFree;
|
||||
SymCryptDivisorFromModulus;
|
||||
SymCryptDivisorWipe;
|
||||
SymCryptDlgroupAllocate;
|
||||
SymCryptDlgroupCopy;
|
||||
SymCryptDlgroupCreate;
|
||||
SymCryptDlgroupFree;
|
||||
SymCryptDlgroupGenerate;
|
||||
SymCryptDlgroupGetSizes;
|
||||
SymCryptDlgroupGetValue;
|
||||
SymCryptDlgroupIsSame;
|
||||
SymCryptDlgroupSetValue;
|
||||
SymCryptDlgroupSetValueSafePrime;
|
||||
SymCryptDlgroupWipe;
|
||||
SymCryptDlkeyAllocate;
|
||||
SymCryptDlkeyCopy;
|
||||
SymCryptDlkeyCreate;
|
||||
SymCryptDlkeyFree;
|
||||
SymCryptDlkeyGenerate;
|
||||
SymCryptDlkeyGetGroup;
|
||||
SymCryptDlkeyGetValue;
|
||||
SymCryptDlkeyHasPrivateKey;
|
||||
SymCryptDlkeySetValue;
|
||||
SymCryptDlkeySizeofPrivateKey;
|
||||
SymCryptDlkeySizeofPublicKey;
|
||||
SymCryptDlkeyWipe;
|
||||
SymCryptDsaSign;
|
||||
SymCryptDsaVerify;
|
||||
SymCryptEcDhSecretAgreement;
|
||||
SymCryptEcDsaSign;
|
||||
SymCryptEcDsaSignDeterministic;
|
||||
SymCryptEcDsaSignEx;
|
||||
SymCryptEcDsaVerify;
|
||||
SymCryptEcbDecrypt;
|
||||
SymCryptEcbEncrypt;
|
||||
SymCryptEckeyAllocate;
|
||||
SymCryptEckeyCopy;
|
||||
SymCryptEckeyCreate;
|
||||
SymCryptEckeyFree;
|
||||
SymCryptEckeyGetValue;
|
||||
SymCryptEckeyHasPrivateKey;
|
||||
SymCryptEckeySetRandom;
|
||||
SymCryptEckeySetValue;
|
||||
SymCryptEckeySizeofPrivateKey;
|
||||
SymCryptEckeySizeofPublicKey;
|
||||
SymCryptEckeyWipe;
|
||||
SymCryptEcpointAdd;
|
||||
SymCryptEcpointAddDiffNonZero;
|
||||
SymCryptEcpointAllocate;
|
||||
SymCryptEcpointCopy;
|
||||
SymCryptEcpointCreate;
|
||||
SymCryptEcpointDouble;
|
||||
SymCryptEcpointFree;
|
||||
SymCryptEcpointGetValue;
|
||||
SymCryptEcpointIsEqual;
|
||||
SymCryptEcpointIsZero;
|
||||
SymCryptEcpointMaskedCopy;
|
||||
SymCryptEcpointMultiScalarMul;
|
||||
SymCryptEcpointNegate;
|
||||
SymCryptEcpointOnCurve;
|
||||
SymCryptEcpointRetrieveHandle;
|
||||
SymCryptEcpointScalarMul;
|
||||
SymCryptEcpointSetDistinguishedPoint;
|
||||
SymCryptEcpointSetRandom;
|
||||
SymCryptEcpointSetValue;
|
||||
SymCryptEcpointSetZero;
|
||||
SymCryptEcpointWipe;
|
||||
SymCryptEcurveAllocate;
|
||||
SymCryptEcurveBitsizeofFieldModulus;
|
||||
SymCryptEcurveBitsizeofGroupOrder;
|
||||
SymCryptEcurveDigitsofFieldElement;
|
||||
SymCryptEcurveDigitsofScalarMultiplier;
|
||||
SymCryptEcurveFree;
|
||||
SymCryptEcurveGroupOrder;
|
||||
SymCryptEcurveHighBitRestrictionNumOfBits;
|
||||
SymCryptEcurveHighBitRestrictionPosition;
|
||||
SymCryptEcurveHighBitRestrictionValue;
|
||||
SymCryptEcurveIsSame;
|
||||
SymCryptEcurveParamsCurve25519;
|
||||
SymCryptEcurveParamsNistP192;
|
||||
SymCryptEcurveParamsNistP224;
|
||||
SymCryptEcurveParamsNistP256;
|
||||
SymCryptEcurveParamsNistP384;
|
||||
SymCryptEcurveParamsNistP521;
|
||||
SymCryptEcurveParamsNumsP256t1;
|
||||
SymCryptEcurveParamsNumsP384t1;
|
||||
SymCryptEcurveParamsNumsP512t1;
|
||||
SymCryptEcurvePrivateKeyDefaultFormat;
|
||||
SymCryptEcurveSizeofFieldElement;
|
||||
SymCryptEcurveSizeofScalarMultiplier;
|
||||
SymCryptFreeTrialDivisionContext;
|
||||
SymCryptGcmAuthPart;
|
||||
SymCryptGcmDecrypt;
|
||||
SymCryptGcmDecryptFinal;
|
||||
SymCryptGcmDecryptPart;
|
||||
SymCryptGcmEncrypt;
|
||||
SymCryptGcmEncryptFinal;
|
||||
SymCryptGcmEncryptPart;
|
||||
SymCryptGcmExpandKey;
|
||||
SymCryptGcmInit;
|
||||
SymCryptGcmKeyCopy;
|
||||
SymCryptGcmSelftest;
|
||||
SymCryptGcmStateCopy;
|
||||
SymCryptGcmValidateParameters;
|
||||
SymCryptHash;
|
||||
SymCryptHashAppend;
|
||||
SymCryptHashInit;
|
||||
SymCryptHashInputBlockSize;
|
||||
SymCryptHashResult;
|
||||
SymCryptHashResultSize;
|
||||
SymCryptHashStateSize;
|
||||
SymCryptHkdf;
|
||||
SymCryptHkdfDerive;
|
||||
SymCryptHkdfExpandKey;
|
||||
SymCryptHkdfPrkExpandKey;
|
||||
SymCryptHkdfSelfTest;
|
||||
SymCryptHmacMd5;
|
||||
SymCryptHmacMd5Algorithm;
|
||||
SymCryptHmacMd5Append;
|
||||
SymCryptHmacMd5ExpandKey;
|
||||
SymCryptHmacMd5Init;
|
||||
SymCryptHmacMd5KeyCopy;
|
||||
SymCryptHmacMd5Result;
|
||||
SymCryptHmacMd5Selftest;
|
||||
SymCryptHmacMd5StateCopy;
|
||||
SymCryptHmacSha1;
|
||||
SymCryptHmacSha1Algorithm;
|
||||
SymCryptHmacSha1Append;
|
||||
SymCryptHmacSha1ExpandKey;
|
||||
SymCryptHmacSha1Init;
|
||||
SymCryptHmacSha1KeyCopy;
|
||||
SymCryptHmacSha1Result;
|
||||
SymCryptHmacSha1Selftest;
|
||||
SymCryptHmacSha1StateCopy;
|
||||
SymCryptHmacSha256;
|
||||
SymCryptHmacSha256Algorithm;
|
||||
SymCryptHmacSha256Append;
|
||||
SymCryptHmacSha256ExpandKey;
|
||||
SymCryptHmacSha256Init;
|
||||
SymCryptHmacSha256KeyCopy;
|
||||
SymCryptHmacSha256Result;
|
||||
SymCryptHmacSha256Selftest;
|
||||
SymCryptHmacSha256StateCopy;
|
||||
SymCryptHmacSha384;
|
||||
SymCryptHmacSha384Algorithm;
|
||||
SymCryptHmacSha384Append;
|
||||
SymCryptHmacSha384ExpandKey;
|
||||
SymCryptHmacSha384Init;
|
||||
SymCryptHmacSha384KeyCopy;
|
||||
SymCryptHmacSha384Result;
|
||||
SymCryptHmacSha384Selftest;
|
||||
SymCryptHmacSha384StateCopy;
|
||||
SymCryptHmacSha512;
|
||||
SymCryptHmacSha512Algorithm;
|
||||
SymCryptHmacSha512Append;
|
||||
SymCryptHmacSha512ExpandKey;
|
||||
SymCryptHmacSha512Init;
|
||||
SymCryptHmacSha512KeyCopy;
|
||||
SymCryptHmacSha512Result;
|
||||
SymCryptHmacSha512Selftest;
|
||||
SymCryptHmacSha512StateCopy;
|
||||
SymCryptIntAddMixedSize;
|
||||
SymCryptIntAddSameSize;
|
||||
SymCryptIntAddUint32;
|
||||
SymCryptIntAllocate;
|
||||
SymCryptIntBitsizeOfObject;
|
||||
SymCryptIntBitsizeOfValue;
|
||||
SymCryptIntConditionalCopy;
|
||||
SymCryptIntConditionalSwap;
|
||||
SymCryptIntCopy;
|
||||
SymCryptIntCopyMixedSize;
|
||||
SymCryptIntCreate;
|
||||
SymCryptIntDigitsizeOfObject;
|
||||
SymCryptIntDivMod;
|
||||
SymCryptIntDivPow2;
|
||||
SymCryptIntExtendedGcd;
|
||||
SymCryptIntFindSmallDivisor;
|
||||
SymCryptIntFree;
|
||||
SymCryptIntFromDivisor;
|
||||
SymCryptIntFromModulus;
|
||||
SymCryptIntGenerateRandomPrime;
|
||||
SymCryptIntGetBit;
|
||||
SymCryptIntGetBits;
|
||||
SymCryptIntGetValue;
|
||||
SymCryptIntGetValueLsbits32;
|
||||
SymCryptIntGetValueLsbits64;
|
||||
SymCryptIntIsEqual;
|
||||
SymCryptIntIsEqualUint32;
|
||||
SymCryptIntIsLessThan;
|
||||
SymCryptIntMaskedCopy;
|
||||
SymCryptIntMillerRabinPrimalityTest;
|
||||
SymCryptIntModPow2;
|
||||
SymCryptIntMulMixedSize;
|
||||
SymCryptIntMulPow2;
|
||||
SymCryptIntMulSameSize;
|
||||
SymCryptIntMulUint32;
|
||||
SymCryptIntNeg;
|
||||
SymCryptIntSetBits;
|
||||
SymCryptIntSetValue;
|
||||
SymCryptIntSetValueUint32;
|
||||
SymCryptIntSetValueUint64;
|
||||
SymCryptIntShr1;
|
||||
SymCryptIntSquare;
|
||||
SymCryptIntSubMixedSize;
|
||||
SymCryptIntSubSameSize;
|
||||
SymCryptIntSubUint32;
|
||||
SymCryptIntToDivisor;
|
||||
SymCryptIntToModElement;
|
||||
SymCryptIntToModulus;
|
||||
SymCryptIntWipe;
|
||||
SymCryptLoadLsbFirstUint32;
|
||||
SymCryptLoadLsbFirstUint64;
|
||||
SymCryptLoadMsbFirstUint32;
|
||||
SymCryptLoadMsbFirstUint64;
|
||||
SymCryptMarvin32;
|
||||
SymCryptMarvin32Append;
|
||||
SymCryptMarvin32DefaultSeed;
|
||||
SymCryptMarvin32ExpandSeed;
|
||||
SymCryptMarvin32Init;
|
||||
SymCryptMarvin32Result;
|
||||
SymCryptMarvin32SeedCopy;
|
||||
SymCryptMarvin32Selftest;
|
||||
SymCryptMarvin32StateCopy;
|
||||
SymCryptMask32EqU32;
|
||||
SymCryptMask32IsNonzeroU31;
|
||||
SymCryptMask32IsZeroU31;
|
||||
SymCryptMask32LtU31;
|
||||
SymCryptMask32NeqU31;
|
||||
SymCryptMd2;
|
||||
SymCryptMd2Algorithm;
|
||||
SymCryptMd2Append;
|
||||
SymCryptMd2Init;
|
||||
SymCryptMd2Result;
|
||||
SymCryptMd2Selftest;
|
||||
SymCryptMd2StateCopy;
|
||||
SymCryptMd2StateExport;
|
||||
SymCryptMd2StateImport;
|
||||
SymCryptMd4;
|
||||
SymCryptMd4Algorithm;
|
||||
SymCryptMd4Append;
|
||||
SymCryptMd4Init;
|
||||
SymCryptMd4Result;
|
||||
SymCryptMd4Selftest;
|
||||
SymCryptMd4StateCopy;
|
||||
SymCryptMd4StateExport;
|
||||
SymCryptMd4StateImport;
|
||||
SymCryptMd5;
|
||||
SymCryptMd5Algorithm;
|
||||
SymCryptMd5Append;
|
||||
SymCryptMd5Init;
|
||||
SymCryptMd5OidList;
|
||||
SymCryptMd5Result;
|
||||
SymCryptMd5Selftest;
|
||||
SymCryptMd5StateCopy;
|
||||
SymCryptMd5StateExport;
|
||||
SymCryptMd5StateImport;
|
||||
SymCryptModAdd;
|
||||
SymCryptModDivPow2;
|
||||
SymCryptModElementAllocate;
|
||||
SymCryptModElementConditionalSwap;
|
||||
SymCryptModElementCopy;
|
||||
SymCryptModElementCreate;
|
||||
SymCryptModElementFree;
|
||||
SymCryptModElementGetValue;
|
||||
SymCryptModElementIsEqual;
|
||||
SymCryptModElementIsZero;
|
||||
SymCryptModElementMaskedCopy;
|
||||
SymCryptModElementSetValue;
|
||||
SymCryptModElementSetValueNegUint32;
|
||||
SymCryptModElementSetValueUint32;
|
||||
SymCryptModElementToInt;
|
||||
SymCryptModElementWipe;
|
||||
SymCryptModExp;
|
||||
SymCryptModInv;
|
||||
SymCryptModMul;
|
||||
SymCryptModMultiExp;
|
||||
SymCryptModNeg;
|
||||
SymCryptModSetRandom;
|
||||
SymCryptModSquare;
|
||||
SymCryptModSub;
|
||||
SymCryptModuleInit;
|
||||
SymCryptModulusAllocate;
|
||||
SymCryptModulusBitsizeOfObject;
|
||||
SymCryptModulusCopy;
|
||||
SymCryptModulusCreate;
|
||||
SymCryptModulusDigitsizeOfObject;
|
||||
SymCryptModulusFree;
|
||||
SymCryptModulusWipe;
|
||||
SymCryptParallelSha256Init;
|
||||
SymCryptParallelSha256Process;
|
||||
SymCryptParallelSha256Selftest;
|
||||
SymCryptParallelSha384Init;
|
||||
SymCryptParallelSha384Process;
|
||||
SymCryptParallelSha384Selftest;
|
||||
SymCryptParallelSha512Init;
|
||||
SymCryptParallelSha512Process;
|
||||
SymCryptParallelSha512Selftest;
|
||||
SymCryptPbkdf2;
|
||||
SymCryptPbkdf2Derive;
|
||||
SymCryptPbkdf2ExpandKey;
|
||||
SymCryptPbkdf2_HmacSha1SelfTest;
|
||||
SymCryptPbkdf2_HmacSha256SelfTest;
|
||||
SymCryptPoly1305;
|
||||
SymCryptPoly1305Append;
|
||||
SymCryptPoly1305Init;
|
||||
SymCryptPoly1305Result;
|
||||
SymCryptPoly1305Selftest;
|
||||
SymCryptRc2BlockCipher;
|
||||
SymCryptRc2Decrypt;
|
||||
SymCryptRc2Encrypt;
|
||||
SymCryptRc2ExpandKey;
|
||||
SymCryptRc2ExpandKeyEx;
|
||||
SymCryptRc2Selftest;
|
||||
SymCryptRc4Crypt;
|
||||
SymCryptRc4Init;
|
||||
SymCryptRc4Selftest;
|
||||
SymCryptRdrandGet;
|
||||
SymCryptRdrandGetBytes;
|
||||
SymCryptRdrandStatus;
|
||||
SymCryptRdseedGet;
|
||||
SymCryptRdseedGetBytes;
|
||||
SymCryptRdseedStatus;
|
||||
SymCryptRngAesFips140_2Generate;
|
||||
SymCryptRngAesFips140_2Instantiate;
|
||||
SymCryptRngAesFips140_2Reseed;
|
||||
SymCryptRngAesFips140_2Uninstantiate;
|
||||
SymCryptRngAesGenerate;
|
||||
SymCryptRngAesGenerateSelftest;
|
||||
SymCryptRngAesInstantiate;
|
||||
SymCryptRngAesInstantiateSelftest;
|
||||
SymCryptRngAesReseed;
|
||||
SymCryptRngAesReseedSelftest;
|
||||
SymCryptRngAesUninstantiate;
|
||||
SymCryptRoundUpPow2Sizet;
|
||||
SymCryptRsaOaepDecrypt;
|
||||
SymCryptRsaOaepEncrypt;
|
||||
SymCryptRsaPkcs1Decrypt;
|
||||
SymCryptRsaPkcs1Encrypt;
|
||||
SymCryptRsaPkcs1Sign;
|
||||
SymCryptRsaPkcs1Verify;
|
||||
SymCryptRsaPssSign;
|
||||
SymCryptRsaPssVerify;
|
||||
SymCryptRsaRawDecrypt;
|
||||
SymCryptRsaRawEncrypt;
|
||||
SymCryptRsakeyAllocate;
|
||||
SymCryptRsakeyFree;
|
||||
SymCryptRsakeyGenerate;
|
||||
SymCryptRsakeyGetCrtValue;
|
||||
SymCryptRsakeyGetNumberOfPrimes;
|
||||
SymCryptRsakeyGetNumberOfPublicExponents;
|
||||
SymCryptRsakeyGetValue;
|
||||
SymCryptRsakeyHasPrivateKey;
|
||||
SymCryptRsakeyModulusBits;
|
||||
SymCryptRsakeySetValue;
|
||||
SymCryptRsakeySizeofModulus;
|
||||
SymCryptRsakeySizeofPrime;
|
||||
SymCryptRsakeySizeofPublicExponent;
|
||||
SymCryptRsakeyWipe;
|
||||
SymCryptScsCopy;
|
||||
SymCryptScsRotateBuffer;
|
||||
SymCryptScsTableInit;
|
||||
SymCryptScsTableLoad;
|
||||
SymCryptScsTableSetBuffer;
|
||||
SymCryptScsTableStore;
|
||||
SymCryptScsTableWipe;
|
||||
SymCryptSha1;
|
||||
SymCryptSha1Algorithm;
|
||||
SymCryptSha1Append;
|
||||
SymCryptSha1Init;
|
||||
SymCryptSha1OidList;
|
||||
SymCryptSha1Result;
|
||||
SymCryptSha1Selftest;
|
||||
SymCryptSha1StateCopy;
|
||||
SymCryptSha1StateExport;
|
||||
SymCryptSha1StateImport;
|
||||
SymCryptSha256;
|
||||
SymCryptSha256Algorithm;
|
||||
SymCryptSha256Append;
|
||||
SymCryptSha256Init;
|
||||
SymCryptSha256OidList;
|
||||
SymCryptSha256Result;
|
||||
SymCryptSha256Selftest;
|
||||
SymCryptSha256StateCopy;
|
||||
SymCryptSha256StateExport;
|
||||
SymCryptSha256StateImport;
|
||||
SymCryptSha384;
|
||||
SymCryptSha384Algorithm;
|
||||
SymCryptSha384Append;
|
||||
SymCryptSha384Init;
|
||||
SymCryptSha384OidList;
|
||||
SymCryptSha384Result;
|
||||
SymCryptSha384Selftest;
|
||||
SymCryptSha384StateCopy;
|
||||
SymCryptSha384StateExport;
|
||||
SymCryptSha384StateImport;
|
||||
SymCryptSha512;
|
||||
SymCryptSha512Algorithm;
|
||||
SymCryptSha512Append;
|
||||
SymCryptSha512Init;
|
||||
SymCryptSha512OidList;
|
||||
SymCryptSha512Result;
|
||||
SymCryptSha512Selftest;
|
||||
SymCryptSha512StateCopy;
|
||||
SymCryptSha512StateExport;
|
||||
SymCryptSha512StateImport;
|
||||
SymCryptSizeofDivisorFromDigits;
|
||||
SymCryptSizeofDlgroupFromBitsizes;
|
||||
SymCryptSizeofDlkeyFromDlgroup;
|
||||
SymCryptSizeofEckeyFromCurve;
|
||||
SymCryptSizeofEcpointFromCurve;
|
||||
SymCryptSizeofIntFromDigits;
|
||||
SymCryptSizeofModElementFromModulus;
|
||||
SymCryptSizeofModulusFromDigits;
|
||||
SymCryptSizeofRsakeyFromParams;
|
||||
SymCryptSp800_108;
|
||||
SymCryptSp800_108Derive;
|
||||
SymCryptSp800_108ExpandKey;
|
||||
SymCryptSp800_108_HmacSha1SelfTest;
|
||||
SymCryptSp800_108_HmacSha256SelfTest;
|
||||
SymCryptStoreLsbFirstUint32;
|
||||
SymCryptStoreLsbFirstUint64;
|
||||
SymCryptStoreMsbFirstUint32;
|
||||
SymCryptStoreMsbFirstUint64;
|
||||
SymCryptTlsCbcHmacVerify;
|
||||
SymCryptTlsPrf1_1;
|
||||
SymCryptTlsPrf1_1Derive;
|
||||
SymCryptTlsPrf1_1ExpandKey;
|
||||
SymCryptTlsPrf1_1SelfTest;
|
||||
SymCryptTlsPrf1_2;
|
||||
SymCryptTlsPrf1_2Derive;
|
||||
SymCryptTlsPrf1_2ExpandKey;
|
||||
SymCryptTlsPrf1_2SelfTest;
|
||||
SymCryptUint32Bitsize;
|
||||
SymCryptUint32Bytesize;
|
||||
SymCryptUint64Bitsize;
|
||||
SymCryptUint64Bytesize;
|
||||
SymCryptUint64Gcd;
|
||||
SymCryptWipe;
|
||||
SymCryptWipeKnownSize;
|
||||
SymCryptXtsAesDecrypt;
|
||||
SymCryptXtsAesEncrypt;
|
||||
SymCryptXtsAesExpandKey;
|
||||
SymCryptXtsAesSelftest;
|
||||
local:
|
||||
*;
|
||||
};
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// module.c
|
||||
// Main file for SymCrypt DLL/shared object library
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
SYMCRYPT_ENVIRONMENT_LINUX_USERMODE
|
||||
|
||||
// Module main function executed by the runtime upon load
|
||||
VOID __attribute__((constructor)) SymCryptModuleMain()
|
||||
{
|
||||
SymCryptInit();
|
||||
|
||||
// We must test HMAC-SHA256 first since it's used by our integrity verification
|
||||
SymCryptHmacSha256Selftest();
|
||||
|
||||
SymCryptModuleVerifyIntegrity();
|
||||
|
||||
SymCrypt3DesSelftest();
|
||||
|
||||
SymCryptAesSelftest( SYMCRYPT_AES_SELFTEST_ALL );
|
||||
SymCryptAesCmacSelftest();
|
||||
SymCryptCcmSelftest();
|
||||
SymCryptGcmSelftest();
|
||||
SymCryptXtsAesSelftest();
|
||||
|
||||
SymCryptRngAesInstantiateSelftest();
|
||||
SymCryptRngAesReseedSelftest();
|
||||
SymCryptRngAesGenerateSelftest();
|
||||
|
||||
SymCryptHmacSha1Selftest();
|
||||
SymCryptHmacSha384Selftest();
|
||||
SymCryptHmacSha512Selftest();
|
||||
|
||||
SymCryptParallelSha256Selftest();
|
||||
SymCryptParallelSha512Selftest();
|
||||
|
||||
SymCryptTlsPrf1_1SelfTest();
|
||||
SymCryptTlsPrf1_2SelfTest();
|
||||
|
||||
SymCryptHkdfSelfTest();
|
||||
}
|
||||
|
||||
PVOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptCallbackAlloc( SIZE_T nBytes )
|
||||
{
|
||||
PVOID ptr = NULL;
|
||||
if(posix_memalign( &ptr, SYMCRYPT_ASYM_ALIGN_VALUE, nBytes ) != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptCallbackFree( VOID * pMem )
|
||||
{
|
||||
free( pMem );
|
||||
}
|
||||
|
||||
VOID SYMCRYPT_CALL SymCryptModuleInit( UINT32 api, UINT32 minor, UINT32 patch )
|
||||
{
|
||||
if( api > SYMCRYPT_CODE_VERSION_API )
|
||||
{
|
||||
SymCryptFatal( 'vers' );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
//
|
||||
// SymCrypt DLL/shared object library pre-compiled header file
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "symcrypt.h"
|
||||
#include "integrity.h"
|
|
@ -0,0 +1,262 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
This script facilitaties module integrity verification for FIPS 140 by processing the input ELF
|
||||
shared object module and replacing key variables so that the module can calculate its own base
|
||||
address, and thereby HMAC its own memory, at runtime.
|
||||
|
||||
Requires PyElfTools: https://github.com/eliben/pyelftools
|
||||
|
||||
Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import hmac
|
||||
import io
|
||||
import logging
|
||||
import os
|
||||
import secrets
|
||||
import stat
|
||||
import struct
|
||||
import sys
|
||||
|
||||
from elftools.elf.elffile import ELFFile
|
||||
from elftools.elf.sections import Section, SymbolTableSection, Symbol
|
||||
from elftools.elf.segments import Segment
|
||||
|
||||
KEY_NAME = "SymCryptVolatileFipsHmacKey"
|
||||
KEY_RVA_NAME = "SymCryptVolatileFipsHmacKeyRva"
|
||||
BOUNDARY_OFFSET_NAME = "SymCryptVolatileFipsBoundaryOffset"
|
||||
DIGEST_NAME = "SymCryptVolatileFipsHmacDigest"
|
||||
|
||||
PLACEHOLDER_VALUE = struct.pack("Q", 0x8BADF00D)
|
||||
PLACEHOLDER_ARRAY = bytes((
|
||||
0x5B, 0x75, 0xBB, 0xE4, 0x9E, 0x18, 0x03, 0x55,
|
||||
0x08, 0x4E, 0x3F, 0xE7, 0x60, 0x7E, 0x4F, 0x08,
|
||||
0xAA, 0x77, 0x0F, 0x0B, 0xAB, 0xC6, 0x58, 0x5A,
|
||||
0xA9, 0x9F, 0x83, 0x4B, 0xD0, 0x6E, 0x67, 0x05))
|
||||
|
||||
# Writeable flag for segments since elftools doesn't define it
|
||||
PF_W = 2
|
||||
|
||||
class Variable(object):
|
||||
"""
|
||||
Wrapper for a pyelftools Symbol which makes it easier to get the value and offset/
|
||||
virtual address of the object that the symbol represents.
|
||||
"""
|
||||
|
||||
def __init__(self, elf_file, name):
|
||||
"""
|
||||
Initializes a Variable object by finding the symbol name in the symbol table and mapping
|
||||
it to the offset in the file.
|
||||
"""
|
||||
|
||||
self.elf_file = elf_file
|
||||
self.name = name
|
||||
|
||||
symtab = self.elf_file.get_section_by_name(".symtab")
|
||||
symbols = symtab.get_symbol_by_name(name)
|
||||
assert(len(symbols) == 1)
|
||||
self.symbol = symbols[0]
|
||||
|
||||
self.vaddr = self.symbol.entry["st_value"]
|
||||
self.length = self.symbol.entry["st_size"]
|
||||
self.section = self.elf_file.get_section(self.symbol["st_shndx"])
|
||||
self.section_offset = self.vaddr - self.section.header["sh_addr"]
|
||||
self.offset = self.section.header["sh_offset"] + self.section_offset
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self.section.data()[self.section_offset:self.section_offset + self.length]
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
assert(type(value) == bytes)
|
||||
assert(len(value) == self.length)
|
||||
assert(bool(self.section.compressed) is False)
|
||||
|
||||
# The .data() method returns a bytes object. We can't use it to write back to the original
|
||||
# buffer, so we need to find the appropriate section within the stream using sh_offset and
|
||||
# write to that.
|
||||
logging.debug("Writing {} to offset {}".format(value.hex(), hex(self.offset)))
|
||||
self.section.stream.seek(self.offset)
|
||||
self.section.stream.write(value)
|
||||
|
||||
def set_value(self, format, *args):
|
||||
new_value = struct.pack(format, *args)
|
||||
assert(len(new_value) == self.length)
|
||||
|
||||
logging.debug("Changing {} value".format(self.name))
|
||||
|
||||
self.value = new_value
|
||||
|
||||
def log_variable(var):
|
||||
logging.debug("{}: offset {}, virtual address {}, Value {}".format(
|
||||
var.name,
|
||||
hex(var.offset),
|
||||
hex(var.vaddr),
|
||||
var.value.hex()))
|
||||
|
||||
def hmac_module(loadable_segments, data_section_offset, key, digest, dump_file_path = None):
|
||||
"""
|
||||
Performs HMAC-SHA256 on module contents and writes it back to the module buffer
|
||||
"""
|
||||
|
||||
module_bytes = bytearray()
|
||||
last_segment_offset = -1
|
||||
|
||||
for (index, segment) in enumerate(loadable_segments):
|
||||
|
||||
segment_hashable_length = 0
|
||||
|
||||
# Ensure the loadable segments were given in ascending order by offset
|
||||
# (i.e. the same order as in the file)
|
||||
assert(last_segment_offset < segment["p_offset"])
|
||||
|
||||
if segment["p_offset"] + segment["p_filesz"] > data_section_offset:
|
||||
segment_hashable_length = data_section_offset - segment["p_offset"]
|
||||
module_bytes += segment.data()[:segment_hashable_length]
|
||||
else:
|
||||
module_bytes += segment.data()
|
||||
segment_hashable_length = len(segment.data())
|
||||
|
||||
logging.info("Segment {}: {} - {}".format(
|
||||
index,
|
||||
hex(segment["p_offset"]),
|
||||
hex(segment["p_offset"] + segment_hashable_length)))
|
||||
|
||||
last_segment_offset = segment["p_offset"]
|
||||
|
||||
if dump_file_path is not None:
|
||||
with open(dump_file_path, "wb") as dump_file:
|
||||
dump_file.write(module_bytes)
|
||||
|
||||
logging.debug("Using key: {}".format(key.value.hex()))
|
||||
digest_bytes = hmac.digest(key.value, module_bytes, hashlib.sha256)
|
||||
logging.debug("Calculated SHA256 digest: {}".format(digest_bytes.hex()))
|
||||
|
||||
digest.set_value(str(len(digest_bytes)) + "s", digest_bytes)
|
||||
log_variable(digest)
|
||||
|
||||
def process_loadable_segments(elf_file):
|
||||
"""
|
||||
Finds all loadable segments in the module and ensures that the assumptions made by our runtime
|
||||
integrity verification code are valid. Returns the list of loadable segments. If an assumption
|
||||
is found to be invalid, an exception will be thrown.
|
||||
"""
|
||||
|
||||
# Find all loadable segments and calculate their sizes and offsets
|
||||
loadable_segments = []
|
||||
writeable_segment = None
|
||||
for segment in elf_file.iter_segments():
|
||||
if segment["p_type"] == "PT_LOAD":
|
||||
|
||||
logging.debug("PT_LOAD: Offset {} VAddr {} PAddr {} FileSz {} MemSz {} Align {}".format(
|
||||
hex(segment["p_offset"]),
|
||||
hex(segment["p_vaddr"]),
|
||||
hex(segment["p_paddr"]),
|
||||
hex(segment["p_filesz"]),
|
||||
hex(segment["p_memsz"]),
|
||||
hex(segment["p_align"])
|
||||
))
|
||||
|
||||
loadable_segments.append(segment)
|
||||
|
||||
if writeable_segment is not None:
|
||||
# There must be exactly one writeable segment, and it must be the last of the
|
||||
# PT_LOAD segments
|
||||
logging.error("Found more than one loadable, writeable segment!")
|
||||
raise RuntimeError
|
||||
|
||||
if segment["p_flags"] & PF_W != 0:
|
||||
writeable_segment = segment
|
||||
|
||||
writeable_segment_sections = []
|
||||
for section in elf_file.iter_sections():
|
||||
if writeable_segment.section_in_segment(section):
|
||||
writeable_segment_sections.append(section)
|
||||
|
||||
# We set our FIPS module boundary based on where the .data section starts (since it and the
|
||||
# .bss section cannot be included in the HMAC). Therefore, .data and .bss must be the second
|
||||
# last and last sections of that segment, respectively.
|
||||
if writeable_segment_sections[-2].name != ".data" or \
|
||||
writeable_segment_sections[-1].name != ".bss":
|
||||
logging.error("Unexpected section order in writeable segment!")
|
||||
raise RuntimeError
|
||||
|
||||
return loadable_segments
|
||||
|
||||
def main():
|
||||
"""
|
||||
Entrypoint
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(description = "Postprocess SymCrypt shared object module")
|
||||
parser.add_argument("input", type=str, help = "Path to SymCrypt module")
|
||||
parser.add_argument("-d", "--debug", action = "store_true", help = "Enable debug output (also dumps hashable module contents to file)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
logging.basicConfig(level = logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(level = logging.INFO)
|
||||
|
||||
with open(args.input, "rb") as input_file:
|
||||
buffer = input_file.read()
|
||||
buffer_stream = io.BytesIO(buffer)
|
||||
|
||||
# Copy the original input file to a backup file
|
||||
os.replace(args.input, args.input + ".bak")
|
||||
|
||||
elf_file = ELFFile(buffer_stream)
|
||||
loadable_segments = process_loadable_segments(elf_file)
|
||||
|
||||
# Find the HMAC key placeholder and replace it with a randomly generated key
|
||||
key_variable = Variable(elf_file, KEY_NAME)
|
||||
assert(key_variable.value == PLACEHOLDER_ARRAY)
|
||||
|
||||
random_key = secrets.token_bytes(len(key_variable.value)) # NB: not actually a secret
|
||||
key_variable.set_value(str(len(random_key)) + "s", random_key)
|
||||
log_variable(key_variable)
|
||||
|
||||
# Find the HMAC key relative virtual address placeholder and replace it with
|
||||
# the actual relative virtual address of the HMAC key
|
||||
key_rva_variable = Variable(elf_file, KEY_RVA_NAME)
|
||||
assert(key_rva_variable.value == PLACEHOLDER_VALUE)
|
||||
|
||||
key_rva_variable.set_value("Q", key_variable.vaddr)
|
||||
log_variable(key_rva_variable)
|
||||
|
||||
# Find the FIPS module boundary placeholder and replace it with the our actual
|
||||
# FIPS module boundary, which we have defined to be the start of the .data section
|
||||
fips_boundary_variable = Variable(elf_file, BOUNDARY_OFFSET_NAME)
|
||||
assert(fips_boundary_variable.value == PLACEHOLDER_VALUE)
|
||||
|
||||
data_section = elf_file.get_section_by_name(".data")
|
||||
data_section_offset = data_section["sh_offset"]
|
||||
|
||||
fips_boundary_variable.set_value("Q", data_section_offset)
|
||||
log_variable(fips_boundary_variable)
|
||||
|
||||
# Find the HMAC digest placeholder, HMAC the loadable segments of the module, and replace
|
||||
# the placeholder with the actual digest
|
||||
digest_variable = Variable(elf_file, DIGEST_NAME)
|
||||
assert(digest_variable.value == PLACEHOLDER_ARRAY)
|
||||
|
||||
hmac_module(loadable_segments, data_section_offset, key_variable, digest_variable,
|
||||
dump_file_path = args.input + ".loadable.bin" if args.debug else None)
|
||||
|
||||
with open(args.input, "wb") as output_file:
|
||||
output_file.write(buffer_stream.getbuffer())
|
||||
|
||||
# chmod 0755 the new output file so that it"s marked as executable (required by some platforms)
|
||||
os.chmod(args.input,
|
||||
stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | # User: read, write, execute
|
||||
stat.S_IRGRP | stat.S_IXGRP | # Group: read, execute
|
||||
stat.S_IXOTH | stat.S_IXOTH) # Other: read, execute
|
||||
|
||||
logging.info("Success!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1 @@
|
|||
pyelftools
|
|
@ -92,4 +92,5 @@ if(WIN32)
|
|||
add_subdirectory(exe_Win8_1nLater)
|
||||
else()
|
||||
add_subdirectory(exe_linux)
|
||||
add_subdirectory(exe_moduletest)
|
||||
endif()
|
|
@ -8,4 +8,4 @@ add_compile_options(-DINCLUDE_IMPL_MSBIGNUM=0)
|
|||
add_compile_options(-DINCLUDE_IMPL_RSA32=0)
|
||||
|
||||
add_executable(symcryptunittest ${SOURCES})
|
||||
target_link_libraries(symcryptunittest symcryptunittest_lib symcrypt_generic)
|
||||
target_link_libraries(symcryptunittest symcryptunittest_lib symcrypt_common)
|
|
@ -0,0 +1,8 @@
|
|||
set(SOURCES
|
||||
moduletest.cpp
|
||||
)
|
||||
|
||||
add_executable(symcryptmoduletest ${SOURCES})
|
||||
target_link_libraries(symcryptmoduletest symcrypt)
|
||||
|
||||
add_dependencies(symcryptmoduletest symcrypt_fips)
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// moduletest.cpp
|
||||
// Test executable for SymCrypt module smoke tests
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include "symcrypt.h"
|
||||
|
||||
int
|
||||
main( int argc, _In_reads_( argc ) char * argv[] )
|
||||
{
|
||||
SYMCRYPT_MODULE_INIT();
|
||||
|
||||
printf("Success!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -929,7 +929,7 @@ extern DWORD g_osVersion; // 0xaabb for major version aa and minor version
|
|||
|
||||
_Analysis_noreturn_
|
||||
VOID
|
||||
fatal( _In_ PSTR file, ULONG line, _In_ PSTR text, ... );
|
||||
fatal( _In_ PCSTR file, ULONG line, _In_ PCSTR text, ... );
|
||||
|
||||
typedef CONST CHAR * PCCHAR;
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ set(SOURCES
|
|||
testDsa.cpp
|
||||
testScsTable.cpp
|
||||
testScsTools.cpp
|
||||
testIEEE802_11SaeCustom.cpp
|
||||
perf.cpp
|
||||
)
|
||||
|
||||
|
@ -43,6 +42,7 @@ if(WIN32)
|
|||
capi_implementations.cpp
|
||||
cng_implementations.cpp
|
||||
msbignum_implementations.cpp
|
||||
testIEEE802_11SaeCustom.cpp
|
||||
# testInterop.cpp
|
||||
# testRsa.cpp
|
||||
# testRsa_sc.cpp
|
||||
|
|
|
@ -898,7 +898,7 @@ AlgorithmImplementationVector g_algorithmImplementation;
|
|||
|
||||
_Analysis_noreturn_
|
||||
VOID
|
||||
fatal( _In_ PSTR file, ULONG line, _In_ PSTR format, ... )
|
||||
fatal( _In_ PCSTR file, ULONG line, _In_ PCSTR format, ... )
|
||||
{
|
||||
va_list vl;
|
||||
printOutput( 0 );
|
||||
|
@ -1196,7 +1196,7 @@ testpbkdf2()
|
|||
//
|
||||
// Reach into the internals of Symcrypt to retrieve the build string
|
||||
extern "C" {
|
||||
extern const CHAR * SymCryptBuildString;
|
||||
extern const CHAR * const SymCryptBuildString;
|
||||
};
|
||||
|
||||
VOID
|
||||
|
@ -1561,7 +1561,9 @@ runFunctionalTests()
|
|||
|
||||
testEcc();
|
||||
|
||||
#if SYMCRYPT_MS_VC
|
||||
testIEEE802_11SaeCustom();
|
||||
#endif
|
||||
|
||||
iprint( "Functional testing done.\n" );
|
||||
|
||||
|
|
|
@ -6877,6 +6877,7 @@ EccImp<ImpSc, AlgEcdh>::~EccImp()
|
|||
}
|
||||
|
||||
//============================
|
||||
#if SYMCRYPT_MS_VC
|
||||
template<>
|
||||
VOID
|
||||
algImpKeyPerfFunction<ImpSc, AlgIEEE802_11SaeCustom>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize )
|
||||
|
@ -6926,7 +6927,7 @@ template<>
|
|||
ArithImp<ImpSc, AlgIEEE802_11SaeCustom>::~ArithImp()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
VOID
|
||||
|
@ -7083,7 +7084,9 @@ addSymCryptAlgs()
|
|||
addImplementationToGlobalList<EccImp<ImpSc, AlgEcdsaVerify>>();
|
||||
addImplementationToGlobalList<EccImp<ImpSc, AlgEcdh>>();
|
||||
|
||||
#if SYMCRYPT_MS_VC
|
||||
addImplementationToGlobalList<ArithImp<ImpSc, AlgIEEE802_11SaeCustom>>();
|
||||
#endif
|
||||
|
||||
addImplementationToGlobalList<ArithImp<ImpSc, AlgDeveloperTest>>();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче