Merged PR 10481180: Add OpenSSL implementation for AesGcm test

## Description:

## Admin Checklist:
- [ ] You have updated documentation in symcrypt.h to reflect any changes in behavior
- [ ] You have updated CHANGELOG.md to reflect any changes in behavior
- [ ] You have updated symcryptunittest to exercise any new functionality
- [ ] If you have introduced any symbols in symcrypt.h you have updated production and test dynamic export symbols (exports.ver / exports.def / symcrypt.src) and tested the updated dynamic modules with symcryptunittest
- [ ] If you have introduced functionality that varies based on CPU features, you have manually tested with and without relevant features
- [ ] If you have made significant changes to a particular algorithm, you have checked that performance numbers reported by symcryptunittest are in line with expectations
- [ ] If you have added new algorithms/modes, you have updated the status indicator text for the associated modules if necessary

Add OpenSSL implementation for AesGcm test
This commit is contained in:
Changyu Li 2024-03-29 03:39:59 +00:00
Родитель 476b8382f0
Коммит 7c1f6b4143
12 изменённых файлов: 532 добавлений и 73 удалений

Просмотреть файл

@ -146,7 +146,8 @@ extends:
cc: 'gcc' cc: 'gcc'
cxx: 'g++' cxx: 'g++'
skipTests: true skipTests: true
additionalArgs: '--no-asm --openssl' additionalArgs: '--no-asm'
openssl: true
identifier: 'NoAsm' identifier: 'NoAsm'
- template: .pipelines/templates/build-linux.yml@self - template: .pipelines/templates/build-linux.yml@self
parameters: parameters:
@ -155,7 +156,8 @@ extends:
cc: 'clang' cc: 'clang'
cxx: 'clang++' cxx: 'clang++'
skipTests: true skipTests: true
additionalArgs: '--no-asm --openssl' additionalArgs: '--no-asm'
openssl: true
identifier: 'NoAsm' identifier: 'NoAsm'
- template: .pipelines/templates/build-linux.yml@self - template: .pipelines/templates/build-linux.yml@self
parameters: parameters:

Просмотреть файл

@ -50,7 +50,7 @@ jobs:
${{ else }}: ${{ else }}:
verbose_build_flag: '' verbose_build_flag: ''
${{ if eq(parameters.openssl, true) }}: ${{ if eq(parameters.openssl, true) }}:
openssl_build_flag: '--openssl' openssl_build_flag: '--openssl-build-from-source'
${{ else }}: ${{ else }}:
openssl_build_flag: '' openssl_build_flag: ''
@ -86,10 +86,12 @@ jobs:
apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf qemu-user apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf qemu-user
displayName: 'Install arm cross-compilation tools' displayName: 'Install arm cross-compilation tools'
- ${{ if eq(parameters.openssl, true) }}: # TODO: Once we move to Azure Linux 3 we can use the system-provided OpenSSL package.
- script: | # For now we will built from source since Ubuntu 20.04 doesn't have OpenSSL 3.
apt-get install -y libssl-dev # - ${{ if eq(parameters.openssl, true) }}:
displayName: 'Install OpenSSL' # - script: |
# apt-get install -y libssl-dev
# displayName: 'Install OpenSSL'
- task: PipAuthenticate@1 - task: PipAuthenticate@1
inputs: inputs:

37
.vscode/launch.json поставляемый
Просмотреть файл

@ -4,6 +4,14 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"type": "lldb",
"request": "launch",
"name": "(lldb) symcryptunittest",
"program": "${workspaceFolder}/bin/exe/symcryptunittest",
"args": [],
"cwd": "${workspaceFolder}"
},
{ {
"name": "(Windows) symcryptunittest", "name": "(Windows) symcryptunittest",
"type": "cppvsdbg", "type": "cppvsdbg",
@ -17,34 +25,5 @@
"console": "integratedTerminal", "console": "integratedTerminal",
"internalConsoleOptions": "openOnSessionStart" "internalConsoleOptions": "openOnSessionStart"
}, },
{
"name": "(Windows) symcryptunittest [+openssl +symcrypt +xtsaes]",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/exe/symcryptunittest.exe",
"args": [
"+openssl",
"+symcrypt",
"+xtsaes",
],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"console": "integratedTerminal",
},
{
"name": "(Windows) symcryptunittest [+openssl +symcrypt +xtsaes -vaes]",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/exe/symcryptunittest.exe",
"args": [
"+openssl",
"+symcrypt",
"+xtsaes",
"-vaes"
],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"console": "integratedTerminal",
},
] ]
} }

15
.vscode/settings.json поставляемый
Просмотреть файл

@ -11,5 +11,18 @@
"icon": "terminal-powershell", "icon": "terminal-powershell",
"overrideName": true, "overrideName": true,
} }
} },
"terminal.integrated.defaultProfile.linux": "SymCrypt Profile",
"terminal.integrated.profiles.linux": {
"SymCrypt Profile": {
"args": [
"-c",
"[ -f ./.venv/bin/activate ] && . ./.venv/bin/activate; exec bash"
],
"path": "bash",
"source": "bash",
"icon": "terminal-bash",
"overrideName": true,
}
},
} }

73
.vscode/tasks.json поставляемый
Просмотреть файл

@ -11,16 +11,20 @@
} }
}, },
}, },
"linux": {
"options": {
"shell": {
"executable": "bash",
"args": [
"-c",
]
}
},
},
"tasks": [ "tasks": [
{ {
"label": "Setup", "label": "Setup",
"type": "shell", "type": "shell",
"command": [
"python -m venv .venv;",
". .\\.venv\\Scripts\\activate.ps1;",
"pip install -r .\\scripts\\requirements.txt;",
"Set-Content -value ('pushd;\n& \"\"\"' + (resolve-path 'C:\\Program Files\\Microsoft Visual Studio\\*\\*\\Common7\\Tools\\Launch-VsDevShell.ps1').path + '\"\"\" -Arch $env:PROCESSOR_ARCHITECTURE -HostArch $env:PROCESSOR_ARCHITECTURE;\npopd') -path '${workspaceFolder}\\.venv\\profile.ps1';",
],
"options": { "options": {
"cwd": "${workspaceFolder}/", "cwd": "${workspaceFolder}/",
}, },
@ -31,14 +35,36 @@
"panel": "shared", "panel": "shared",
"showReuseMessage": true, "showReuseMessage": true,
"clear": false, "clear": false,
},
"windows": {
"command": [
"python -m venv .venv;",
". .\\.venv\\Scripts\\activate.ps1;",
"pip install -r .\\scripts\\requirements.txt;",
"Set-Content -value ('pushd;\n& \"\"\"' + (resolve-path 'C:\\Program Files\\Microsoft Visual Studio\\*\\*\\Common7\\Tools\\Launch-VsDevShell.ps1').path + '\"\"\" -Arch $env:PROCESSOR_ARCHITECTURE -HostArch $env:PROCESSOR_ARCHITECTURE;\npopd') -path '${workspaceFolder}\\.venv\\profile.ps1';",
],
},
"linux": {
"command": [
"python3 -m venv .venv;",
". ./.venv/bin/activate;",
"pip install -r ./scripts/requirements.txt;",
],
} }
}, },
{ {
"label": "Clean", "label": "Clean",
"type": "shell", "type": "shell",
"command": [ "windows": {
"del -recurse bin_*,bin;", "command": [
], "del -recurse bin_*,bin,.venv;",
],
},
"linux": {
"command": [
"rm -rf bin_* bin .venv"
]
},
"options": { "options": {
"cwd": "${workspaceFolder}/", "cwd": "${workspaceFolder}/",
}, },
@ -54,16 +80,25 @@
{ {
"label": "Build [Debug]", "label": "Build [Debug]",
"type": "shell", "type": "shell",
"command": "python", "windows": {
"args": [ "command": "python",
".\\scripts\\build.py", "args": [
"cmake", ".\\scripts\\build.py",
"bin", "cmake",
"--arch", "bin",
"amd64", "--arch",
"--config", "amd64",
"Debug", "--config",
], "Debug",
],
},
"linux": {
"command": [
"[ -f ./.venv/bin/activate ] && . ./.venv/bin/activate;",
"python3 ./scripts/build.py cmake bin --arch amd64 --config Debug;",
"exit",
]
},
"options": { "options": {
"cwd": "${workspaceFolder}/", "cwd": "${workspaceFolder}/",
}, },

Просмотреть файл

@ -89,6 +89,7 @@ apt update
apt -y install --no-install-recommends \ apt -y install --no-install-recommends \
cmake \ cmake \
python3-pyelftools \ python3-pyelftools \
build-essential \
gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
``` ```
`python3-pyelftools` is for integrity verification and `gcc-arm-linux-gnueabihf` `g++-arm-linux-gnueabihf` are for ARM cross compile `python3-pyelftools` is for integrity verification and `gcc-arm-linux-gnueabihf` `g++-arm-linux-gnueabihf` are for ARM cross compile
@ -110,19 +111,19 @@ prerequisites to building OpenSSL.
``` ```
winget install nasm strawberryperl winget install nasm strawberryperl
.\scripts\build.py cmake bin --config Release --openssl-build-from-source python3 .\scripts\build.py cmake bin --config Release --openssl-build-from-source
``` ```
And on Linux we can use OpenSSL installed by system's package manager. And on Linux we can use OpenSSL installed by system's package manager.
``` ```
sudo apt install -y libssl-dev sudo apt install -y libssl-dev
./scripts/build.py cmake bin --config Release --openssl python3 ./scripts/build.py cmake bin --config Release --openssl
``` ```
To build OpenSSL on Linux we need to install following prerequisites. To build OpenSSL on Linux we need to install following prerequisites.
``` ```
sudo apt install -y nasm perl sudo apt install -y nasm perl
.\scripts\build.py cmake bin --config Release --openssl-build-from-source python3 ./scripts/build.py cmake bin --config Release --openssl-build-from-source
``` ```

Просмотреть файл

@ -81,9 +81,6 @@ option(
OFF) OFF)
if (SYMCRYPT_TEST_WITH_OPENSSL)
include(${CMAKE_SOURCE_DIR}/cmake-configs/OpenSSL.cmake)
endif()
include(${CMAKE_SOURCE_DIR}/cmake-configs/SymCrypt-Platforms.cmake) include(${CMAKE_SOURCE_DIR}/cmake-configs/SymCrypt-Platforms.cmake)
if(NOT DEFINED CMAKE_BUILD_TYPE) if(NOT DEFINED CMAKE_BUILD_TYPE)
@ -122,4 +119,4 @@ configure_file(build/symcrypt.pc.in symcrypt.pc @ONLY)
add_subdirectory(lib) add_subdirectory(lib)
add_subdirectory(modules) add_subdirectory(modules)
add_subdirectory(unittest) add_subdirectory(unittest)

Просмотреть файл

@ -29,12 +29,12 @@ if(OPENSSL_BUILD_FROM_SOURCE)
set(ENV{CL} /MP) set(ENV{CL} /MP)
if(OPENSSL_BUILD_TYPE STREQUAL "release") if(OPENSSL_BUILD_TYPE STREQUAL "release")
execute_process( execute_process(
COMMAND perl Configure no-ssl no-tls1 no-tls1_1 --release COMMAND perl Configure no-ssl no-tls no-dtls no-legacy no-engine no-weak-ssl-ciphers no-rc4 no-rc5 no-rc2 no-md4 no-deprecated no-apps no-docs no-tests no-shared --release
WORKING_DIRECTORY ${OPENSSL_BUILD_ROOT} WORKING_DIRECTORY ${OPENSSL_BUILD_ROOT}
RESULT_VARIABLE result) RESULT_VARIABLE result)
else() else()
execute_process( execute_process(
COMMAND perl Configure no-ssl no-tls1 no-tls1_1 --debug COMMAND perl Configure no-ssl no-tls no-dtls no-legacy no-engine no-weak-ssl-ciphers no-rc4 no-rc5 no-rc2 no-md4 no-deprecated no-apps no-docs no-tests no-shared --debug
WORKING_DIRECTORY ${OPENSSL_BUILD_ROOT} WORKING_DIRECTORY ${OPENSSL_BUILD_ROOT}
RESULT_VARIABLE result) RESULT_VARIABLE result)
endif() endif()
@ -61,11 +61,11 @@ if(OPENSSL_BUILD_FROM_SOURCE)
include(${OPENSSL_BUILD_ROOT}/OpenSSLConfig.cmake) include(${OPENSSL_BUILD_ROOT}/OpenSSLConfig.cmake)
else() else()
find_package(OpenSSL REQUIRED) find_package(OpenSSL 3 REQUIRED)
endif() endif()
message("Found OpenSSL include directory ${OPENSSL_INCLUDE_DIR}") if(OPENSSL_VERSION_MAJOR LESS 3)
include_directories(${OPENSSL_INCLUDE_DIR}) message(FATAL_ERROR "-- Invalid OpenSSL version found ${OPENSSL_VERSION} at ${OPENSSL_INCLUDE_DIR}")
link_directories(${OPENSSL_LIBRARY_DIR}) else()
link_libraries(${OPENSSL_CRYPTO_LIBRARIES}) message("-- Found OpenSSL ${OPENSSL_VERSION} include directory ${OPENSSL_INCLUDE_DIR}")
add_compile_options(-DINCLUDE_IMPL_OPENSSL=1) endif()

Просмотреть файл

@ -79,6 +79,15 @@ if(WIN32 AND SYMCRYPT_TARGET_ARCH MATCHES "X86")
add_link_options(/SAFESEH:NO) add_link_options(/SAFESEH:NO)
endif() endif()
if(SYMCRYPT_TEST_WITH_OPENSSL)
include(${CMAKE_SOURCE_DIR}/cmake-configs/OpenSSL.cmake)
include_directories(${OPENSSL_INCLUDE_DIR})
link_directories(${OPENSSL_LIBRARY_DIR})
link_libraries(${OPENSSL_CRYPTO_LIBRARIES})
add_compile_options(-DINCLUDE_IMPL_OPENSSL=1)
endif()
include_directories(inc) include_directories(inc)
include_directories(lib) include_directories(lib)
include_directories(resource) include_directories(resource)

Просмотреть файл

@ -24,5 +24,13 @@ public:
EVP_CIPHER_CTX* decCtx; EVP_CIPHER_CTX* decCtx;
}; };
template<>
class AuthEncImpState<ImpOpenssl, AlgAes, ModeGcm> {
public:
EVP_CIPHER_CTX* encCtx;
EVP_CIPHER_CTX* decCtx;
BOOLEAN inComputation;
};
VOID VOID
addOpensslAlgs(); addOpensslAlgs();

Просмотреть файл

@ -4,6 +4,8 @@
#include "precomp.h" #include "precomp.h"
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/core_names.h>
#include <algorithm> #include <algorithm>
char * ImpOpenssl::name = "OpenSSL"; char * ImpOpenssl::name = "OpenSSL";
@ -28,6 +30,8 @@ std::string getOpensslError()
#define CHECK_OPENSSL_SUCCESS(osslInvocation) CHECK(((osslInvocation) == 1), getOpensslError().data()) #define CHECK_OPENSSL_SUCCESS(osslInvocation) CHECK(((osslInvocation) == 1), getOpensslError().data())
// AlgXtsAes
struct ExpandedKeyContext struct ExpandedKeyContext
{ {
EVP_CIPHER_CTX* encCtx; EVP_CIPHER_CTX* encCtx;
@ -337,11 +341,393 @@ XtsImp<ImpOpenssl, AlgXtsAes>::decryptWith128bTweak(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
// AlgXtsAes end
// ModeGcm
template<>
VOID
algImpKeyPerfFunction< ImpOpenssl, AlgAes, ModeGcm>( PBYTE expandedKey, PBYTE keyBytes, PBYTE buf3, SIZE_T keySize )
{
UNREFERENCED_PARAMETER( buf3 );
// SymCryptGcmExpandKey( (PSYMCRYPT_GCM_EXPANDED_KEY) expandedKey,
// SymCryptAesBlockCipher,
// keyBytes, keySize );
const EVP_CIPHER *cipher = NULL;
if (keySize == 32)
{
cipher = EVP_aes_256_gcm();
}
else if (keySize == 24)
{
cipher = EVP_aes_192_gcm();
}
else if (keySize == 16)
{
cipher = EVP_aes_128_gcm();
}
CHECK(cipher != NULL, "Unsupported key length");
EVP_CIPHER_CTX* encCtx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX* decCtx = EVP_CIPHER_CTX_new();
CHECK_OPENSSL_SUCCESS(EVP_EncryptInit_ex(encCtx, cipher, NULL, keyBytes, NULL));
CHECK_OPENSSL_SUCCESS(EVP_DecryptInit_ex(decCtx, cipher, NULL, keyBytes, NULL));
ExpandedKeyContext *pContext = (ExpandedKeyContext *)expandedKey;
pContext->encCtx = encCtx;
pContext->decCtx = decCtx;
}
template<>
VOID
algImpDataPerfFunction<ImpOpenssl,AlgAes, ModeGcm>( PBYTE expandedKey, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
// SymCryptGcmEncrypt( (PCSYMCRYPT_GCM_EXPANDED_KEY) expandedKey,
// buf2, 12,
// nullptr, 0,
// buf2 + 16, buf3 + 16, dataSize,
// buf3, 16 );
int outlen = 0;
PCBYTE pbNonce = buf2;
PCBYTE pbSrc = buf2 + 16;
PBYTE pbDst = buf3 + 16;
SIZE_T cbData = dataSize;
PBYTE pbTag = buf3;
SIZE_T cbTag = 16;
ExpandedKeyContext *pContext = (ExpandedKeyContext *)expandedKey;
// Default nonce size is 12.
CHECK(EVP_EncryptInit_ex2(pContext->encCtx, NULL, NULL, pbNonce, NULL) == 1, getOpensslError().data());
CHECK(EVP_EncryptUpdate(pContext->encCtx, pbDst, &outlen, pbSrc, (int)cbData) == 1, getOpensslError().data());
CHECK(EVP_EncryptFinal_ex(pContext->encCtx, pbDst, &outlen) == 1, getOpensslError().data());
CHECK(EVP_CIPHER_CTX_ctrl(pContext->encCtx, EVP_CTRL_AEAD_GET_TAG, (int)cbTag, pbTag) > 0, getOpensslError().data());
}
template<>
VOID
algImpDecryptPerfFunction<ImpOpenssl,AlgAes, ModeGcm>( PBYTE expandedKey, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
// SymCryptGcmDecrypt( (PCSYMCRYPT_GCM_EXPANDED_KEY) buf1,
// buf2, 12,
// nullptr, 0,
// buf3 + 16, buf2 + 16, dataSize,
// buf3, 16 );
int outlen = 0;
PCBYTE pbNonce = buf2;
PCBYTE pbSrc = buf3 + 16;
PBYTE pbDst = buf2 + 16;
SIZE_T cbData = dataSize;
PBYTE pbTag = buf3;
SIZE_T cbTag = 16;
ExpandedKeyContext *pContext = (ExpandedKeyContext *)expandedKey;
// Default nonce size is 12.
CHECK(EVP_DecryptInit_ex2(pContext->decCtx, NULL, NULL, pbNonce, NULL) == 1, getOpensslError().data());
CHECK(EVP_DecryptUpdate(pContext->decCtx, pbDst, &outlen, pbSrc, (int)cbData) == 1, getOpensslError().data());
CHECK(EVP_CIPHER_CTX_ctrl(pContext->decCtx, EVP_CTRL_AEAD_SET_TAG,
(int)cbTag, (void *)pbTag) > 0, getOpensslError().data());
CHECK(EVP_DecryptFinal_ex(pContext->decCtx, pbDst, &outlen) == 1, getOpensslError().data());
}
template<>
VOID
algImpCleanPerfFunction<ImpOpenssl,AlgAes, ModeGcm>( PBYTE expandedKey, PBYTE buf2, PBYTE buf3 )
{
ExpandedKeyContext *pContext = (ExpandedKeyContext *)expandedKey;
UNREFERENCED_PARAMETER( buf2 );
UNREFERENCED_PARAMETER( buf3 );
EVP_CIPHER_CTX_free(pContext->encCtx);
EVP_CIPHER_CTX_free(pContext->decCtx);
}
template<>
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::AuthEncImp()
{
m_perfKeyFunction = &algImpKeyPerfFunction<ImpOpenssl, AlgAes, ModeGcm>;
m_perfCleanFunction = &algImpCleanPerfFunction<ImpOpenssl, AlgAes, ModeGcm>;
m_perfDataFunction = &algImpDataPerfFunction<ImpOpenssl, AlgAes, ModeGcm>;
m_perfDecryptFunction = &algImpDecryptPerfFunction<ImpOpenssl, AlgAes, ModeGcm>;
state.encCtx = EVP_CIPHER_CTX_new();
state.decCtx = EVP_CIPHER_CTX_new();
}
template<>
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::~AuthEncImp()
{
EVP_CIPHER_CTX_free(state.encCtx);
EVP_CIPHER_CTX_free(state.decCtx);
}
template<>
std::set<SIZE_T>
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::getKeySizes()
{
std::set<SIZE_T> res;
res.insert( 16 );
res.insert( 24 );
res.insert( 32 );
return res;
}
template<>
std::set<SIZE_T>
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::getNonceSizes()
{
std::set<SIZE_T> res;
for(int i = 1; i <= 256; ++i)
{
res.insert( i );
}
return res;
}
template<>
std::set<SIZE_T>
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::getTagSizes()
{
std::set<SIZE_T> res;
for( int i=12; i<=16; i ++ )
{
res.insert( i );
}
return res;
}
template<>
NTSTATUS
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::setKey( PCBYTE pbKey, SIZE_T cbKey )
{
const EVP_CIPHER *cipher = NULL;
if (cbKey == 32)
{
cipher = EVP_aes_256_gcm();
}
else if (cbKey == 24)
{
cipher = EVP_aes_192_gcm();
}
else if (cbKey == 16)
{
cipher = EVP_aes_128_gcm();
}
else
{
return STATUS_NOT_SUPPORTED;
}
CHECK(EVP_EncryptInit_ex2(state.encCtx, cipher, pbKey, NULL, NULL) == 1, getOpensslError().data());
CHECK(EVP_DecryptInit_ex2(state.decCtx, cipher, pbKey, NULL, NULL) == 1, getOpensslError().data());
// SymCryptGcmExpandKey( &state.key, SymCryptAesBlockCipher, pbKey, cbKey );
state.inComputation = FALSE;
return STATUS_SUCCESS;
}
template<>
VOID
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::setTotalCbData( SIZE_T )
{
}
template<>
NTSTATUS
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::encrypt(
_In_reads_( cbNonce ) PCBYTE pbNonce,
SIZE_T cbNonce,
_In_reads_( cbAuthData ) PCBYTE pbAuthData,
SIZE_T cbAuthData,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData,
_Out_writes_( cbTag ) PBYTE pbTag,
SIZE_T cbTag,
ULONG flags )
{
NTSTATUS status = STATUS_SUCCESS;
int outlen = 0;
CHECK( (flags & ~AUTHENC_FLAG_PARTIAL) == 0, "Unknown flag" );
const int GCM_IV_MAX_SIZE = (1024 / 8);
if( cbNonce > GCM_IV_MAX_SIZE )
{
return STATUS_NOT_SUPPORTED;
}
if( (flags & AUTHENC_FLAG_PARTIAL) == 0 )
{
// simple straight GCM computation.
// CHECK( SymCryptGcmValidateParameters(
// SymCryptAesBlockCipher,
// cbNonce,
// cbAuthData,
// cbData,
// cbTag ) == SYMCRYPT_NO_ERROR, "?" );
// SymCryptGcmEncrypt( &state.key,
// pbNonce, cbNonce, pbAuthData, cbAuthData,
// pbSrc, pbDst, cbData,
// pbTag, cbTag );
OSSL_PARAM params[2] = {
OSSL_PARAM_END, OSSL_PARAM_END
};
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN,
&cbNonce);
CHECK(EVP_EncryptInit_ex2(state.encCtx, NULL, NULL, pbNonce, params) == 1, getOpensslError().data());
CHECK(EVP_EncryptUpdate(state.encCtx, NULL, &outlen, pbAuthData, (int)cbAuthData) == 1, getOpensslError().data());
CHECK(EVP_EncryptUpdate(state.encCtx, pbDst, &outlen, pbSrc, (int)cbData) == 1, getOpensslError().data());
CHECK(EVP_EncryptFinal_ex(state.encCtx, pbDst, &outlen) == 1, getOpensslError().data());
params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
pbTag, cbTag);
CHECK(EVP_CIPHER_CTX_get_params(state.encCtx, params) == 1, getOpensslError().data());
// Done
goto cleanup;
}
if( !state.inComputation )
{
OSSL_PARAM params[2] = {
OSSL_PARAM_END, OSSL_PARAM_END
};
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN,
&cbNonce);
CHECK(EVP_EncryptInit_ex2(state.encCtx, NULL, NULL, pbNonce, params) == 1, getOpensslError().data());
CHECK(EVP_EncryptUpdate(state.encCtx, NULL, &outlen, pbAuthData, (int)cbAuthData) == 1, getOpensslError().data());
state.inComputation = TRUE;
}
CHECK(EVP_EncryptUpdate(state.encCtx, pbDst, &outlen, pbSrc, (int)cbData) == 1, getOpensslError().data());
if( pbTag != nullptr )
{
CHECK(EVP_EncryptFinal_ex(state.encCtx, pbDst, &outlen) == 1, getOpensslError().data());
EVP_CIPHER_CTX_ctrl(state.encCtx, EVP_CTRL_AEAD_GET_TAG, (int)cbTag, pbTag);
state.inComputation = FALSE;
}
cleanup:
return status;
}
template<>
NTSTATUS
AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>::decrypt(
_In_reads_( cbNonce ) PCBYTE pbNonce,
SIZE_T cbNonce,
_In_reads_( cbAuthData ) PCBYTE pbAuthData,
SIZE_T cbAuthData,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData,
_In_reads_( cbTag ) PCBYTE pbTag,
SIZE_T cbTag,
ULONG flags )
{
int scError = 1;
int outlen = 0;
CHECK( (flags & ~AUTHENC_FLAG_PARTIAL) == 0, "Unknown flag" );
const int GCM_IV_MAX_SIZE = (1024 / 8);
if( cbNonce > GCM_IV_MAX_SIZE )
{
return STATUS_NOT_SUPPORTED;
}
if( (flags & AUTHENC_FLAG_PARTIAL) == 0 )
{
// simple straight GCM computation.
// CHECK( SymCryptGcmValidateParameters(
// SymCryptAesBlockCipher,
// cbNonce,
// cbAuthData,
// cbData,
// cbTag ) == SYMCRYPT_NO_ERROR, "?" );
// scError = SymCryptGcmDecrypt( &state.key,
// pbNonce, cbNonce, pbAuthData, cbAuthData,
// pbSrc, pbDst, cbData,
// pbTag, cbTag );
OSSL_PARAM params[2] = {
OSSL_PARAM_END, OSSL_PARAM_END
};
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN,
&cbNonce);
CHECK(EVP_DecryptInit_ex2(state.decCtx, NULL, NULL, pbNonce, params) == 1, getOpensslError().data());
CHECK(EVP_DecryptUpdate(state.decCtx, NULL, &outlen, pbAuthData, (int)cbAuthData) == 1, getOpensslError().data());
CHECK(EVP_DecryptUpdate(state.decCtx, pbDst, &outlen, pbSrc, (int)cbData) == 1, getOpensslError().data());
params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
(void *)pbTag, cbTag);
CHECK(EVP_CIPHER_CTX_set_params(state.decCtx, params) == 1, getOpensslError().data());
scError = EVP_DecryptFinal_ex(state.decCtx, pbDst, &outlen);
// Done
goto cleanup;
}
if( !state.inComputation )
{
OSSL_PARAM params[2] = {
OSSL_PARAM_END, OSSL_PARAM_END
};
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN,
&cbNonce);
CHECK(EVP_DecryptInit_ex2(state.decCtx, NULL, NULL, pbNonce, params) == 1, getOpensslError().data());
CHECK(EVP_DecryptUpdate(state.decCtx, NULL, &outlen, pbAuthData, (int)cbAuthData) == 1, getOpensslError().data());
state.inComputation = TRUE;
}
CHECK(EVP_DecryptUpdate(state.decCtx, pbDst, &outlen, pbSrc, (int)cbData) == 1, getOpensslError().data());
if( pbTag != nullptr )
{
// OSSL_PARAM params[2] = {
// OSSL_PARAM_END, OSSL_PARAM_END
// };
// params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
// (void *)pbTag, cbTag);
EVP_CIPHER_CTX_ctrl(state.decCtx, EVP_CTRL_AEAD_SET_TAG,
(int)cbTag, (void *)pbTag);
scError = EVP_DecryptFinal_ex(state.decCtx, pbDst, &outlen);
state.inComputation = FALSE;
}
cleanup:
return scError > 0 ? 0 : STATUS_AUTH_TAG_MISMATCH;
}
// ModeGcm end
VOID VOID
addOpensslAlgs() addOpensslAlgs()
{ {
addImplementationToGlobalList<XtsImp<ImpOpenssl, AlgXtsAes>>(); addImplementationToGlobalList<XtsImp<ImpOpenssl, AlgXtsAes>>();
// addImplementationToGlobalList<AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>>(); addImplementationToGlobalList<AuthEncImp<ImpOpenssl, AlgAes, ModeGcm>>();
// addImplementationToGlobalList<RsaSignImp<ImpOpenssl, AlgRsaSignPss>>(); // addImplementationToGlobalList<RsaSignImp<ImpOpenssl, AlgRsaSignPss>>();
// addImplementationToGlobalList<HashImp<ImpOpenssl, AlgSha256>>(); // addImplementationToGlobalList<HashImp<ImpOpenssl, AlgSha256>>();
// addImplementationToGlobalList<HashImp<ImpOpenssl, AlgSha384>>(); // addImplementationToGlobalList<HashImp<ImpOpenssl, AlgSha384>>();

Просмотреть файл

@ -32,6 +32,15 @@ print( const char *format, ...)
va_start( vl, format ); va_start( vl, format );
// TODO: We should use CHECK here but CHECK will re-enter this function via fatal()
// so we should fix fatal to use fprintf instead of buffering to Output.
if ( OutputOffset >= MAX_OUTPUT_SIZE )
{
fputs( "Out of output buffer space.\n", stderr );
exit(-1);
}
// TODO: We should also replace compiler dependent VSNPRINTF_S with std::vsnprintf.
res = VSNPRINTF_S( &Output[OutputOffset], MAX_OUTPUT_SIZE - OutputOffset, _TRUNCATE, format, vl ); res = VSNPRINTF_S( &Output[OutputOffset], MAX_OUTPUT_SIZE - OutputOffset, _TRUNCATE, format, vl );
CHECK( res >= 0 , "WHOA!!!" ); CHECK( res >= 0 , "WHOA!!!" );
@ -117,6 +126,12 @@ iprint( const char *format, ...)
va_start( vl, format ); va_start( vl, format );
if ( OutputOffset >= MAX_OUTPUT_SIZE )
{
fputs( "Out of output buffer space.\n", stderr );
exit(-1);
}
res = VSNPRINTF_S( &Output[OutputOffset], MAX_OUTPUT_SIZE - OutputOffset, _TRUNCATE, format, vl ); res = VSNPRINTF_S( &Output[OutputOffset], MAX_OUTPUT_SIZE - OutputOffset, _TRUNCATE, format, vl );
CHECK( res >= 0 , "WHOA!!!" ); CHECK( res >= 0 , "WHOA!!!" );
@ -134,6 +149,12 @@ dprint( const char * format, ... )
va_start( vl, format ); va_start( vl, format );
if ( OutputOffset >= MAX_OUTPUT_SIZE )
{
fputs( "Out of output buffer space.\n", stderr );
exit(-1);
}
res = _vsnprintf_s( &Output[OutputOffset], MAX_OUTPUT_SIZE - OutputOffset, _TRUNCATE, format, vl ); res = _vsnprintf_s( &Output[OutputOffset], MAX_OUTPUT_SIZE - OutputOffset, _TRUNCATE, format, vl );
CHECK( res >= 0 , "WHOA!!!" ); CHECK( res >= 0 , "WHOA!!!" );
@ -164,6 +185,12 @@ vprint(BOOL bPrint, const char *format, ...)
{ {
va_start( vl, format ); va_start( vl, format );
if ( OutputOffset >= MAX_OUTPUT_SIZE )
{
fputs( "Out of output buffer space.\n", stderr );
exit(-1);
}
res = VSNPRINTF_S( &Output[OutputOffset], MAX_OUTPUT_SIZE - OutputOffset, _TRUNCATE, format, vl ); res = VSNPRINTF_S( &Output[OutputOffset], MAX_OUTPUT_SIZE - OutputOffset, _TRUNCATE, format, vl );
CHECK( res >= 0 , "WHOA!!!" ); CHECK( res >= 0 , "WHOA!!!" );