This commit is contained in:
Akshay Kumar 2021-04-04 20:36:20 +05:30 коммит произвёл Mitch Lindgren
Коммит d9f5d13ef6
35 изменённых файлов: 6342 добавлений и 0 удалений

384
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,384 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
### CMakeLists ###
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.pem

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

@ -0,0 +1,21 @@
{
"files.associations": {
"e_symcrypt_digests.h": "c",
"cstring": "cpp",
"array": "cpp",
"deque": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"string_view": "cpp",
"initializer_list": "cpp",
"random": "c",
"system_error": "cpp",
"functional": "c",
"istream": "c",
"ostream": "c",
"tuple": "c",
"type_traits": "c",
"utility": "c"
}
}

9
CMakeLists.txt Normal file
Просмотреть файл

@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 2.8)
project(OpenSSL_FIPS)
add_subdirectory (SymcryptEngine/static)
add_subdirectory (SymcryptEngine/dynamic)
add_subdirectory (SslPlay)

12
README.md Normal file
Просмотреть файл

@ -0,0 +1,12 @@
# Building Instructions
## Comple Instructions
```
cmake -DOPENSSL_ROOT_DIR=/usr/local/ssl -DOPENSSL_LIBRARIES=/usr/local/ssl/lib .
make
```
## Run Samples
```
cd SslPlay
./SslPlay
```

14
SslPlay/CMakeLists.txt Normal file
Просмотреть файл

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 2.8)
project(SslPlay)
find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})
LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
add_executable (SslPlay
SslPlay.cpp
)
target_link_libraries(SslPlay LINK_PUBLIC symcryptengine symcrypt ${OPENSSL_CRYPTO_LIBRARY})
#target_link_libraries(SslPlay ${OPENSSL_CRYPTO_LIBRARY})

1436
SslPlay/SslPlay.cpp Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,69 @@
cmake_minimum_required(VERSION 2.8)
project(symcrypt_engine_dynamic)
set(DEFAULT_BUILD_TYPE "Release")
include(GNUInstallDirs)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra -Wno-unused-parameter")
find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})
include_directories(/home/akshay/SymCrypt/inc)
# Set CMake variables that subsequent CMake scripts can check against
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR AMD64)
# For now this is just used for separating the output directories
set(SYMCRYPT_TARGET_ENV Linux)
# Define _AMD64_ to set up the correct SymCrypt macros, e.g. SYMCRYPT_CPU_AMD64
add_compile_options(-D_AMD64_)
add_compile_options(-DDBG)
add_compile_options(-O3)
# Enable a baseline of features for the compiler to support everywhere
# Other than for SSSE3 we do not expect the compiler to generate these instructions anywhere other than with intrinsics
#
# We cannot globally enable AVX and later, as we need to keep use of these instructions behind CPU detection, and the
# instructions are definitely useful enough for a smart compiler to use them in C code (i.e. in memcpy)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mssse3 -mxsave -maes -mpclmul -msha -mrdrnd -mrdseed")
set(CMAKE_ASM_FLAGS "-x assembler-with-cpp")
add_library(e_symcrypt SHARED
../src/e_symcrypt.c
../src/e_symcrypt_ciphers.c
../src/e_symcrypt_dh.c
../src/e_symcrypt_digests.c
../src/e_symcrypt_dsa.c
../src/e_symcrypt_ecc.c
../src/e_symcrypt_pkey_asn1_meths.c
../src/e_symcrypt_pkey_meths.c
../src/e_symcrypt_rand.c
../src/e_symcrypt_rsa.c
../src/e_symcrypt_hkdf.c
../src/e_symcrypt_tls1prf.c
../src/e_symcrypt_helpers.c
)
set_target_properties(e_symcrypt PROPERTIES PUBLIC_HEADER ../inc/e_symcrypt.h)
# target_link_libraries(symcryptengine ${OPENSSL_CRYPTO_LIBRARY})
target_include_directories(e_symcrypt PUBLIC ../inc)
target_include_directories(e_symcrypt PRIVATE ../src)
target_include_directories (e_symcrypt PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(e_symcrypt PROPERTIES PREFIX "")
set_target_properties(e_symcrypt PROPERTIES OUTPUT_NAME "symcryptengine")
install(TARGETS e_symcrypt
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

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

@ -0,0 +1,14 @@
```
openssl_conf = openssl_init
[ openssl_init ]
engines = engine_section
[ engine_section ]
symcrypt = symcrypt_section
[ symcrypt_section ]
engine_id = symcrypt
dynamic_path = /usr/local/ssl/lib/engines-1.1/symcryptengine.so
default_algorithms = ALL
```

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

@ -0,0 +1,24 @@
#include <openssl/ossl_typ.h>
#include <openssl/crypto.h>
#include <openssl/engine.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SYMCRYPT_LOG_LEVEL_OFF 0
#define SYMCRYPT_LOG_LEVEL_ERROR 1 // DEFAULT
#define SYMCRYPT_LOG_LEVEL_INFO 2
#define SYMCRYPT_LOG_LEVEL_DEBUG 3
void SYMCRYPT_ENGINE_set_trace_level(int trace_level);
void SYMCRYPT_ENGINE_set_trace_log_filename(const char *filename);
// Syncrypt Engine Initialization.
int SYMCRYPT_ENGINE_Initialize();
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,300 @@
#include "e_symcrypt.h"
#include "e_symcrypt_ecc.h"
#include "e_symcrypt_rsa.h"
#include "e_symcrypt_dsa.h"
#include "e_symcrypt_dh.h"
#include "e_symcrypt_digests.h"
#include "e_symcrypt_ciphers.h"
#include "e_symcrypt_pkey_meths.h"
#include "e_symcrypt_rand.h"
#include "e_symcrypt_helpers.h"
#include <symcrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
int symcrypt_module_initialized = 0;
/* The constants used when creating the ENGINE */
static const char* engine_symcrypt_id = "symcrypt";
static const char* engine_symcrypt_name = "Symcrypt Engine";
static EC_KEY_METHOD* symcrypt_eckey_method = NULL;
static RSA_METHOD* symcrypt_rsa_method = NULL;
static DSA_METHOD* symcrypt_dsa_method = NULL;
static DH_METHOD* symcrypt_dh_method = NULL;
int symcrypt_destroy(ENGINE* e)
{
SYMCRYPT_LOG_DEBUG(NULL);
symcrypt_destroy_digests();
symcrypt_destroy_ciphers();
symcrypt_destroy_pkey_methods();
RSA_meth_free(symcrypt_rsa_method);
symcrypt_rsa_method = NULL;
EC_KEY_METHOD_free(symcrypt_eckey_method);
symcrypt_eckey_method = NULL;
// DSA_meth_free(symcrypt_dsa_method);
// symcrypt_dsa_method = NULL;
// DH_meth_free(symcrypt_dh_method);
// symcrypt_dh_method = NULL;
return 1;
}
static int engine_set_defaults(ENGINE* e)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (!ENGINE_set_default_digests(e)
|| !ENGINE_set_default_ciphers(e)
|| !ENGINE_set_default_pkey_meths(e)
|| !ENGINE_set_default_RSA(e)
|| !ENGINE_set_default_EC(e)
|| !ENGINE_set_default_RAND(e)
// || !ENGINE_set_default_DSA(e)
// || !ENGINE_set_default_DH(e)
)
{
return 0;
}
return 1;
}
static int bind_symcrypt_engine(ENGINE* e)
{
SYMCRYPT_LOG_DEBUG(NULL);
PFN_eckey_copy eckey_copy_pfunc = NULL;
PFN_eckey_set_group eckey_set_group_pfunc = NULL;
PFN_eckey_set_private eckey_set_private_pfunc = NULL;
PFN_eckey_set_public eckey_set_public_pfunc = NULL;
if (!symcrypt_module_initialized) {
SymCryptModuleInit();
symcrypt_module_initialized = 1;
}
symcrypt_eckey_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL());
symcrypt_rsa_method = RSA_meth_new("Symcrypt RSA Method", 0);
symcrypt_dsa_method = DSA_meth_dup(DSA_OpenSSL());
symcrypt_dh_method = DH_meth_dup(DH_OpenSSL());
if (!symcrypt_rsa_method ||
!symcrypt_eckey_method ||
!symcrypt_dsa_method ||
!symcrypt_dh_method)
{
goto memerr;
}
/* Setup RSA_METHOD */
rsa_symcrypt_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
RSA_meth_set1_name(symcrypt_rsa_method, "Symcrypt RSA Method");
if (!RSA_meth_set_pub_enc(symcrypt_rsa_method, symcrypt_rsa_pub_enc)
|| !RSA_meth_set_pub_dec(symcrypt_rsa_method, symcrypt_rsa_pub_dec)
|| !RSA_meth_set_priv_enc(symcrypt_rsa_method, symcrypt_rsa_priv_enc)
|| !RSA_meth_set_priv_dec(symcrypt_rsa_method, symcrypt_rsa_priv_dec)
|| !RSA_meth_set_mod_exp(symcrypt_rsa_method, symcrypt_rsa_mod_exp)
|| !RSA_meth_set_bn_mod_exp(symcrypt_rsa_method, symcrypt_rsa_bn_mod_exp)
|| !RSA_meth_set_init(symcrypt_rsa_method, symcrypt_rsa_init)
|| !RSA_meth_set_finish(symcrypt_rsa_method, symcrypt_rsa_finish)
|| !RSA_meth_set_sign(symcrypt_rsa_method, symcrypt_rsa_sign)
|| !RSA_meth_set_verify(symcrypt_rsa_method, symcrypt_rsa_verify)
|| !RSA_meth_set_keygen(symcrypt_rsa_method, symcrypt_rsa_keygen)
)
{
goto memerr;
}
eckey_symcrypt_idx = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, 0);
/* Setup EC_METHOD */
// Need to get existing methods so that we can set Init and Finish which will
// take care of ex_data initialization and freeing.
EC_KEY_METHOD_get_init(symcrypt_eckey_method,
NULL, // Init
NULL, // Finish
&eckey_copy_pfunc,
&eckey_set_group_pfunc,
&eckey_set_private_pfunc,
&eckey_set_public_pfunc);
EC_KEY_METHOD_set_init(symcrypt_eckey_method,
symcrypt_eckey_init,
symcrypt_eckey_finish,
eckey_copy_pfunc,
eckey_set_group_pfunc,
eckey_set_private_pfunc,
eckey_set_public_pfunc);
EC_KEY_METHOD_set_keygen(symcrypt_eckey_method,
symcrypt_eckey_keygen);
EC_KEY_METHOD_set_compute_key(symcrypt_eckey_method,
symcrypt_eckey_compute_key);
EC_KEY_METHOD_set_sign(symcrypt_eckey_method,
symcrypt_eckey_sign,
symcrypt_eckey_sign_setup,
symcrypt_eckey_sign_sig);
EC_KEY_METHOD_set_verify(symcrypt_eckey_method,
symcrypt_eckey_verify,
symcrypt_eckey_verify_sig);
// /* Setup DSA METHOD */
// if (!DSA_meth_set_sign(symcrypt_dsa_method, symcrypt_dsa_sign)
// || !DSA_meth_set_sign_setup(symcrypt_dsa_method, symcrypt_dsa_sign_setup)
// || !DSA_meth_set_verify(symcrypt_dsa_method, symcrypt_dsa_verify)
// || !DSA_meth_set_init(symcrypt_dsa_method, symcrypt_dsa_init)
// || !DSA_meth_set_finish(symcrypt_dsa_method, symcrypt_dsa_finish)
// )
// {
// goto memerr;
// }
// /* Setup DH METHOD */
// if (!DH_meth_set_generate_key(symcrypt_dh_method, symcrypt_dh_generate_key)
// || !DH_meth_set_compute_key(symcrypt_dh_method, symcrypt_dh_compute_key)
// || !DH_meth_set_bn_mod_exp(symcrypt_dh_method, symcrypt_dh_bn_mod_exp)
// || !DH_meth_set_init(symcrypt_dh_method, symcrypt_dh_init)
// || !DH_meth_set_finish(symcrypt_dh_method, symcrypt_dh_finish)
// )
// {
// goto memerr;
// }
// Engine initialization
if (!ENGINE_set_id(e, engine_symcrypt_id)
|| !ENGINE_set_name(e, engine_symcrypt_name)
|| !ENGINE_set_destroy_function(e, symcrypt_destroy)
|| !ENGINE_set_EC(e, symcrypt_eckey_method)
|| !ENGINE_set_RSA(e, symcrypt_rsa_method)
//|| !ENGINE_set_DSA(e, symcrypt_dsa_method)
//|| !ENGINE_set_DH(e, symcrypt_dh_method)
|| !ENGINE_set_RAND(e, symcrypt_rand_method())
|| !ENGINE_set_digests(e, symcrypt_digests)
|| !ENGINE_set_ciphers(e, symcrypt_ciphers)
|| !ENGINE_set_pkey_meths(e, symcrypt_pkey_methods)
)
{
return 0;
}
// Set Engine as default
if (!engine_set_defaults(e)) {
return 0;
}
return 1;
memerr:
return 0;
}
# ifndef OPENSSL_NO_DYNAMIC_ENGINE
static int bind_helper(ENGINE *e, const char *id)
{
if (id && (strcmp(id, engine_symcrypt_id) != 0))
return 0;
if (!bind_symcrypt_engine(e))
return 0;
return 1;
}
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
# endif
static ENGINE* engine_symcrypt(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
ENGINE* ret = ENGINE_new();
if (ret == NULL)
{
return NULL;
}
if (!bind_symcrypt_engine(ret))
{
ENGINE_free(ret);
return NULL;
}
return ret;
}
void engine_load_symcrypt_int(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
ENGINE* symcryptEngine = engine_symcrypt();
if (!symcryptEngine)
return;
ENGINE_add(symcryptEngine);
ENGINE_free(symcryptEngine);
ERR_clear_error();
}
int SYMCRYPT_ENGINE_Initialize()
{
SYMCRYPT_LOG_DEBUG(NULL);
engine_load_symcrypt_int();
return 1;
}
SYMCRYPT_ENVIRONMENT_GENERIC
// Symcrypt requires memory allocation should be SYMCRYPT_ASYM_ALIGN_VALUE aligned.
// To do this, we allocate more SYMCRYPT_ASYM_ALIGN_VALUE + 4 - 1 space. This ensures
// that we can find a pointer which is SYMCRYPT_ASYM_ALIGN_VALUE aligned, which is
// res in the code. We have set aside 4 bytes space to store the offset between p,
// which is returned from BCryptAlloc, and res. That is, offset = p - offset. Later,
// When we release memory, we calculate p = res - offset to obtain the correct pointer
// to free.
PVOID
SYMCRYPT_CALL
SymCryptCallbackAlloc(SIZE_T nBytes)
{
PBYTE p, res = NULL;
ULONG offset;
p = (PBYTE)OPENSSL_zalloc(nBytes + SYMCRYPT_ASYM_ALIGN_VALUE + 4);
if (!p)
{
goto cleanup;
}
res = (PBYTE) (((ULONG_PTR)p + 4 + SYMCRYPT_ASYM_ALIGN_VALUE - 1) & ~(SYMCRYPT_ASYM_ALIGN_VALUE - 1));
offset = (ULONG)(res - p);
*(ULONG *) &res[-4] = offset;
cleanup:
return res;
}
VOID
SYMCRYPT_CALL
SymCryptCallbackFree(PVOID ptr)
{
PBYTE p;
ULONG offset;
p = (PBYTE) ptr;
offset = *(ULONG *) &p[-4];
OPENSSL_free(p - offset);
}
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptCallbackRandom(
_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer,
SIZE_T cbBuffer)
{
SYMCRYPT_ERROR status = SYMCRYPT_NO_ERROR;
if (!RAND_bytes(pbBuffer, cbBuffer))
{
status = SYMCRYPT_EXTERNAL_FAILURE;
}
return status;
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,661 @@
#include "e_symcrypt_ciphers.h"
#include "e_symcrypt_helpers.h"
#include <symcrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
struct cipher_cbc_ctx {
int enc; /* COP_ENCRYPT or COP_DECRYPT */
char iv[SYMCRYPT_AES_BLOCK_SIZE];
SYMCRYPT_AES_EXPANDED_KEY key;
};
struct cipher_ecb_ctx {
int enc; /* COP_ENCRYPT or COP_DECRYPT */
char iv[SYMCRYPT_AES_BLOCK_SIZE];
SYMCRYPT_AES_EXPANDED_KEY key;
};
struct cipher_xts_ctx {
int enc; /* COP_ENCRYPT or COP_DECRYPT */
char iv[SYMCRYPT_AES_BLOCK_SIZE];
SYMCRYPT_XTS_AES_EXPANDED_KEY key;
};
#define SYMCRYPT_GCM_IV_LENGTH 12
struct cipher_ctx_gcm {
int enc; /* COP_ENCRYPT or COP_DECRYPT */
char IV[SYMCRYPT_GCM_IV_LENGTH];
SYMCRYPT_GCM_STATE state;
SYMCRYPT_GCM_EXPANDED_KEY key;
char tag[EVP_GCM_TLS_TAG_LEN];
int taglen;
};
static int symcrypt_cipher_nids[] = {
NID_aes_128_cbc,
NID_aes_192_cbc,
NID_aes_256_cbc,
NID_aes_128_ecb,
NID_aes_192_ecb,
NID_aes_256_ecb,
// NID_aes_128_xts,
// NID_aes_256_xts,
NID_aes_128_gcm,
NID_aes_192_gcm,
NID_aes_256_gcm,
};
int symcrypt_aes_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc);
int symcrypt_aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl);
/* AES128 - CBC */
#define AES_128_KEY_SIZE 16
static EVP_CIPHER *_hidden_aes_128_cbc = NULL;
static const EVP_CIPHER *symcrypt_aes_128_cbc(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_128_cbc == NULL
&& ((_hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc, SYMCRYPT_AES_BLOCK_SIZE , AES_128_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc, EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_CBC_MODE)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc, symcrypt_aes_cbc_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc, symcrypt_aes_cbc_cipher)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc, sizeof(struct cipher_cbc_ctx))))
{
EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
_hidden_aes_128_cbc = NULL;
}
return _hidden_aes_128_cbc;
}
/* AES192 - CBC */
#define AES_192_KEY_SIZE 24
static EVP_CIPHER *_hidden_aes_192_cbc = NULL;
static const EVP_CIPHER *symcrypt_aes_192_cbc(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_192_cbc == NULL
&& ((_hidden_aes_192_cbc = EVP_CIPHER_meth_new(NID_aes_192_cbc, SYMCRYPT_AES_BLOCK_SIZE , AES_192_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_192_cbc,16)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_192_cbc, EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_CBC_MODE)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_192_cbc, symcrypt_aes_cbc_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_192_cbc, symcrypt_aes_cbc_cipher)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_192_cbc, sizeof(struct cipher_cbc_ctx))))
{
EVP_CIPHER_meth_free(_hidden_aes_192_cbc);
_hidden_aes_192_cbc = NULL;
}
return _hidden_aes_192_cbc;
}
/* AES256 - CBC */
#define AES_256_KEY_SIZE 32
static EVP_CIPHER *_hidden_aes_256_cbc = NULL;
static const EVP_CIPHER *symcrypt_aes_256_cbc(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_256_cbc == NULL
&& ((_hidden_aes_256_cbc = EVP_CIPHER_meth_new(NID_aes_256_cbc, SYMCRYPT_AES_BLOCK_SIZE , AES_256_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_cbc,16)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_256_cbc, EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_CBC_MODE)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_256_cbc, symcrypt_aes_cbc_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_cbc, symcrypt_aes_cbc_cipher)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_cbc, sizeof(struct cipher_cbc_ctx))))
{
EVP_CIPHER_meth_free(_hidden_aes_256_cbc);
_hidden_aes_256_cbc = NULL;
}
return _hidden_aes_256_cbc;
}
int symcrypt_aes_ecb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc);
int symcrypt_aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl);
/* AES128 - ecb */
#define AES_128_KEY_SIZE 16
static EVP_CIPHER *_hidden_aes_128_ecb = NULL;
static const EVP_CIPHER *symcrypt_aes_128_ecb(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_128_ecb == NULL
&& ((_hidden_aes_128_ecb = EVP_CIPHER_meth_new(NID_aes_128_ecb, SYMCRYPT_AES_BLOCK_SIZE , AES_128_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_ecb,16)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_ecb, EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_ECB_MODE)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_ecb, symcrypt_aes_ecb_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_ecb, symcrypt_aes_ecb_cipher)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_ecb, sizeof(struct cipher_ecb_ctx))))
{
EVP_CIPHER_meth_free(_hidden_aes_128_ecb);
_hidden_aes_128_ecb = NULL;
}
return _hidden_aes_128_ecb;
}
/* AES192 - ecb */
#define AES_192_KEY_SIZE 24
static EVP_CIPHER *_hidden_aes_192_ecb = NULL;
static const EVP_CIPHER *symcrypt_aes_192_ecb(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_192_ecb == NULL
&& ((_hidden_aes_192_ecb = EVP_CIPHER_meth_new(NID_aes_192_ecb, SYMCRYPT_AES_BLOCK_SIZE , AES_192_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_192_ecb,16)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_192_ecb, EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_ECB_MODE)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_192_ecb, symcrypt_aes_ecb_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_192_ecb, symcrypt_aes_ecb_cipher)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_192_ecb, sizeof(struct cipher_ecb_ctx))))
{
EVP_CIPHER_meth_free(_hidden_aes_192_ecb);
_hidden_aes_192_ecb = NULL;
}
return _hidden_aes_192_ecb;
}
/* AES256 - ecb */
#define AES_256_KEY_SIZE 32
static EVP_CIPHER *_hidden_aes_256_ecb = NULL;
static const EVP_CIPHER *symcrypt_aes_256_ecb(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_256_ecb == NULL
&& ((_hidden_aes_256_ecb = EVP_CIPHER_meth_new(NID_aes_256_ecb, SYMCRYPT_AES_BLOCK_SIZE , AES_256_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_ecb,16)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_256_ecb, EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_ECB_MODE)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_256_ecb, symcrypt_aes_ecb_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_ecb, symcrypt_aes_ecb_cipher)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_ecb, sizeof(struct cipher_ecb_ctx))))
{
EVP_CIPHER_meth_free(_hidden_aes_256_ecb);
_hidden_aes_256_ecb = NULL;
}
return _hidden_aes_256_ecb;
}
int symcrypt_aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc);
int symcrypt_aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl);
/* AES128 - XTS */
static EVP_CIPHER *_hidden_aes_128_xts = NULL;
static const EVP_CIPHER *symcrypt_aes_128_xts(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_128_xts == NULL)
{
_hidden_aes_128_xts = EVP_CIPHER_meth_new(NID_aes_128_xts, 16 , 128 / 8 * 2);
if (_hidden_aes_128_xts == NULL)
{
SYMCRYPT_LOG_ERROR("EVP_CIPHER_meth_new Failed");
}
else
{
// ISSUES HERE on either flags or Key Length or padding
if (!EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_xts, 16)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_xts, EVP_CIPH_CUSTOM_IV| EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_XTS_MODE)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_xts, symcrypt_aes_xts_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_xts, symcrypt_aes_xts_cipher)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_xts, sizeof(struct cipher_xts_ctx)))
{
SYMCRYPT_LOG_ERROR("CIPHER Initialization Failed");
EVP_CIPHER_meth_free(_hidden_aes_128_xts);
_hidden_aes_128_xts = NULL;
}
}
}
return _hidden_aes_128_xts;
}
/* AES256 - XTS */
static EVP_CIPHER *_hidden_aes_256_xts = NULL;
static const EVP_CIPHER *symcrypt_aes_256_xts(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_256_xts == NULL
&& ((_hidden_aes_256_xts = EVP_CIPHER_meth_new(NID_aes_256_xts, 16 , 256 / 8 * 2)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_xts, 4)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_256_xts, EVP_CIPH_CUSTOM_IV|EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_XTS_MODE)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_256_xts, symcrypt_aes_xts_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_xts, symcrypt_aes_xts_cipher)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_xts, sizeof(struct cipher_xts_ctx))))
{
SYMCRYPT_LOG_ERROR("CIPHER Initialization Failed");
EVP_CIPHER_meth_free(_hidden_aes_256_xts);
_hidden_aes_256_xts = NULL;
}
return _hidden_aes_256_xts;
}
/* AES128 - GCM */
int symcrypt_aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc);
int symcrypt_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl);
static int symcrypt_aes_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
static EVP_CIPHER *_hidden_aes_128_gcm = NULL;
#define AES_GCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
| EVP_CIPH_CUSTOM_COPY |EVP_CIPH_FLAG_AEAD_CIPHER \
| EVP_CIPH_GCM_MODE)
static const EVP_CIPHER *symcrypt_aes_128_gcm(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_128_gcm == NULL
&& ((_hidden_aes_128_gcm = EVP_CIPHER_meth_new(NID_aes_128_gcm, 1 , AES_128_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_gcm,12)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_gcm, AES_GCM_FLAGS)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_gcm, symcrypt_aes_gcm_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_gcm, symcrypt_aes_gcm_cipher)
|| !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_gcm, symcrypt_aes_gcm_ctrl)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_gcm, sizeof(struct cipher_ctx_gcm))))
{
EVP_CIPHER_meth_free(_hidden_aes_128_gcm);
_hidden_aes_128_gcm = NULL;
}
return _hidden_aes_128_gcm;
}
/* AES192 - GCM */
int symcrypt_aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc);
int symcrypt_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl);
static int symcrypt_aes_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
static EVP_CIPHER *_hidden_aes_192_gcm = NULL;
#define AES_GCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
| EVP_CIPH_CUSTOM_COPY |EVP_CIPH_FLAG_AEAD_CIPHER \
| EVP_CIPH_GCM_MODE)
static const EVP_CIPHER *symcrypt_aes_192_gcm(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_192_gcm == NULL
&& ((_hidden_aes_192_gcm = EVP_CIPHER_meth_new(NID_aes_192_gcm, 1 , AES_192_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_192_gcm,12)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_192_gcm, AES_GCM_FLAGS)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_192_gcm, symcrypt_aes_gcm_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_192_gcm, symcrypt_aes_gcm_cipher)
|| !EVP_CIPHER_meth_set_ctrl(_hidden_aes_192_gcm, symcrypt_aes_gcm_ctrl)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_192_gcm, sizeof(struct cipher_ctx_gcm))))
{
EVP_CIPHER_meth_free(_hidden_aes_192_gcm);
_hidden_aes_192_gcm = NULL;
}
return _hidden_aes_192_gcm;
}
/* AES256 - GCM */
int symcrypt_aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc);
int symcrypt_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl);
static int symcrypt_aes_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
static EVP_CIPHER *_hidden_aes_256_gcm = NULL;
#define AES_GCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
| EVP_CIPH_CUSTOM_COPY |EVP_CIPH_FLAG_AEAD_CIPHER \
| EVP_CIPH_GCM_MODE)
static const EVP_CIPHER *symcrypt_aes_256_gcm(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_aes_256_gcm == NULL
&& ((_hidden_aes_256_gcm = EVP_CIPHER_meth_new(NID_aes_128_gcm, 1 , AES_256_KEY_SIZE)) == NULL
|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_gcm,12)
|| !EVP_CIPHER_meth_set_flags(_hidden_aes_256_gcm, AES_GCM_FLAGS)
|| !EVP_CIPHER_meth_set_init(_hidden_aes_256_gcm, symcrypt_aes_gcm_init_key)
|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_gcm, symcrypt_aes_gcm_cipher)
|| !EVP_CIPHER_meth_set_ctrl(_hidden_aes_256_gcm, symcrypt_aes_gcm_ctrl)
|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_gcm, sizeof(struct cipher_ctx_gcm))))
{
EVP_CIPHER_meth_free(_hidden_aes_256_gcm);
_hidden_aes_256_gcm = NULL;
}
return _hidden_aes_256_gcm;
}
void symcrypt_destroy_ciphers(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
EVP_CIPHER_meth_free(_hidden_aes_192_cbc);
EVP_CIPHER_meth_free(_hidden_aes_256_cbc);
EVP_CIPHER_meth_free(_hidden_aes_128_ecb);
EVP_CIPHER_meth_free(_hidden_aes_192_ecb);
EVP_CIPHER_meth_free(_hidden_aes_256_ecb);
// EVP_CIPHER_meth_free(_hidden_aes_128_xts);
// EVP_CIPHER_meth_free(_hidden_aes_256_xts);
EVP_CIPHER_meth_free(_hidden_aes_128_gcm);
EVP_CIPHER_meth_free(_hidden_aes_192_gcm);
EVP_CIPHER_meth_free(_hidden_aes_256_gcm);
_hidden_aes_128_cbc = NULL;
_hidden_aes_192_cbc = NULL;
_hidden_aes_256_cbc = NULL;
_hidden_aes_128_ecb = NULL;
_hidden_aes_192_ecb = NULL;
_hidden_aes_256_ecb = NULL;
// _hidden_aes_128_xts = NULL;
// _hidden_aes_256_xts = NULL;
_hidden_aes_128_gcm = NULL;
_hidden_aes_192_gcm = NULL;
_hidden_aes_256_gcm = NULL;
}
int symcrypt_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid)
{
SYMCRYPT_LOG_DEBUG(NULL);
int ok = 1;
if (!cipher) {
/* We are returning a list of supported nids */
*nids = symcrypt_cipher_nids;
return (sizeof(symcrypt_cipher_nids))
/ sizeof(symcrypt_cipher_nids[0]);
}
/* We are being asked for a specific cipher */
switch (nid) {
case NID_aes_128_cbc:
*cipher = symcrypt_aes_128_cbc();
break;
case NID_aes_192_cbc:
*cipher = symcrypt_aes_192_cbc();
break;
case NID_aes_256_cbc:
*cipher = symcrypt_aes_256_cbc();
break;
case NID_aes_128_ecb:
*cipher = symcrypt_aes_128_ecb();
break;
case NID_aes_192_ecb:
*cipher = symcrypt_aes_192_ecb();
break;
case NID_aes_256_ecb:
*cipher = symcrypt_aes_256_ecb();
break;
// case NID_aes_128_xts:
// *cipher = symcrypt_aes_128_xts();
// break;
// case NID_aes_256_xts:
// *cipher = symcrypt_aes_256_xts();
// break;
case NID_aes_128_gcm:
*cipher = symcrypt_aes_128_gcm();
break;
case NID_aes_192_gcm:
*cipher = symcrypt_aes_192_gcm();
break;
case NID_aes_256_gcm:
*cipher = symcrypt_aes_256_gcm();
break;
default:
ok = 0;
*cipher = NULL;
break;
}
return ok;
}
/*
* AES-CBC Implementation
*/
int symcrypt_aes_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_LOG_DEBUG("Encryption?: %d", enc);
struct cipher_cbc_ctx *cipherCtx = (struct cipher_cbc_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
cipherCtx->enc = enc;
memcpy(cipherCtx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
SymCryptAesExpandKey(&cipherCtx->key, key, EVP_CIPHER_CTX_key_length(ctx));
return 1;
}
int symcrypt_aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_LOG_DEBUG("in: %x, out: %x, Input Length: %ld", in, out, inl);
int ret = 0;
struct cipher_cbc_ctx *cipherCtx = (struct cipher_cbc_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
SYMCRYPT_LOG_DEBUG("cipherCtx->key: %x, cipherCtx->iv: %x", cipherCtx->key, cipherCtx->iv);
if (cipherCtx->enc)
{
SymCryptAesCbcEncrypt(&cipherCtx->key, cipherCtx->iv, in, out, inl);
}
else
{
SymCryptAesCbcDecrypt(&cipherCtx->key, cipherCtx->iv, in, out, inl);
}
ret = 1;
end:
return ret;
}
/*
* AES-ECB Implementation
*/
int symcrypt_aes_ecb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
// SYMCRYPT_LOG_DEBUG(NULL);
// SYMCRYPT_LOG_DEBUG("Encryption?: %d", enc);
struct cipher_ecb_ctx *cipherCtx = (struct cipher_ecb_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
cipherCtx->enc = enc;
//memcpy(cipherCtx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
SymCryptAesExpandKey(&cipherCtx->key, key, EVP_CIPHER_CTX_key_length(ctx));
return 1;
}
int symcrypt_aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
// TOO NOISY
// SYMCRYPT_LOG_DEBUG(NULL);
// SYMCRYPT_LOG_DEBUG("in: %x, out: %x, Input Length: %ld", in, out, inl);
int ret = 0;
struct cipher_ecb_ctx *cipherCtx = (struct cipher_ecb_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
//SYMCRYPT_LOG_DEBUG("cipherCtx->key: %x, cipherCtx->iv: %x", cipherCtx->key, cipherCtx->iv);
if (cipherCtx->enc)
{
SymCryptAesEcbEncrypt(&cipherCtx->key, in, out, inl);
}
else
{
SymCryptAesEcbDecrypt(&cipherCtx->key, in, out, inl);
}
ret = 1;
end:
return ret;
}
/*
* AES-XTS Implementation
*/
int symcrypt_aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_LOG_DEBUG("Encryption?: %d, EVP_CIPHER_CTX_iv_length: %d", enc, EVP_CIPHER_CTX_iv_length(ctx));
struct cipher_xts_ctx *cipherCtx = (struct cipher_xts_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
cipherCtx->enc = enc;
memcpy(cipherCtx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
SymCryptXtsAesExpandKey(&cipherCtx->key, key, EVP_CIPHER_CTX_key_length(ctx));
return 1;
}
int symcrypt_aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_LOG_DEBUG("in: %x, out: %x, Input Length: %ld", in, out, inl);
int ret = 0;
struct cipher_xts_ctx *cipherCtx = (struct cipher_xts_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
SYMCRYPT_LOG_DEBUG("cipherCtx->key: %x, cipherCtx->iv: %x", cipherCtx->key, cipherCtx->iv);
if (cipherCtx->enc)
{
SymCryptXtsAesEncrypt(
&cipherCtx->key,
EVP_CIPHER_CTX_block_size(ctx),
*(UINT64 *) cipherCtx->iv,
in,
out,
inl);
}
else
{
SymCryptXtsAesDecrypt(
&cipherCtx->key,
EVP_CIPHER_CTX_block_size(ctx),
*(UINT64 *) cipherCtx->iv,
in,
out,
inl);
}
ret = 1;
end:
return ret;
}
/*
* AES-GCM Implementation
*/
int symcrypt_aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_LOG_DEBUG("Encryption?: %d", enc);
SYMCRYPT_ERROR SymError = SYMCRYPT_NO_ERROR;
struct cipher_ctx_gcm *cipherCtx = (struct cipher_ctx_gcm *)EVP_CIPHER_CTX_get_cipher_data(ctx);
cipherCtx->enc = enc;
if (iv) {
memcpy(cipherCtx->IV, iv, EVP_CIPHER_CTX_iv_length(ctx));
SYMCRYPT_LOG_BYTES_DEBUG("Saved IV", cipherCtx->IV, EVP_CIPHER_CTX_iv_length(ctx));
}
if (key)
{
SYMCRYPT_LOG_DEBUG("SymCryptGcmExpandKey Input: key");
BIO_dump_fp(stdout, (const char *)key, EVP_CIPHER_CTX_key_length(ctx));
SymError = SymCryptGcmExpandKey(&cipherCtx->key, SymCryptAesBlockCipher, key, EVP_CIPHER_CTX_key_length(ctx));
if (SymError != SYMCRYPT_NO_ERROR)
{
SYMCRYPT_LOG_DEBUG("ERROR: SymCryptGcmExpandKey failed. SymError = %d ", SymError);
return 0;
}
SYMCRYPT_LOG_BYTES_DEBUG("SymCryptGcmInit Input cipherCtx->IV", cipherCtx->IV, EVP_CIPHER_CTX_iv_length(ctx));
SymCryptGcmInit(&cipherCtx->state, &cipherCtx->key, cipherCtx->IV, EVP_CIPHER_CTX_iv_length(ctx));
}
return 1;
}
int symcrypt_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
SYMCRYPT_LOG_DEBUG(NULL);
int ret = 0;
SYMCRYPT_ERROR SymError = SYMCRYPT_NO_ERROR;
SYMCRYPT_LOG_DEBUG("Input Length: %ld", inl);
struct cipher_ctx_gcm *cipherCtx = (struct cipher_ctx_gcm *)EVP_CIPHER_CTX_get_cipher_data(ctx);
if (out == NULL && in != NULL && inl > 0)
{
// Auth Data Passed in
SYMCRYPT_LOG_BYTES_DEBUG("SymCryptGcmAuthPart input: AuthData", (const char *)in, inl);
SymCryptGcmAuthPart(&cipherCtx->state, in, inl);
ret = 1;
goto end;
}
if (cipherCtx->enc)
{
if (inl > 0)
{
// Encrypt Part
SYMCRYPT_LOG_BYTES_DEBUG("SymCryptGcmEncryptPart output: in", (const char *)in, inl);
SymCryptGcmEncryptPart(&cipherCtx->state, in, out, inl);
SYMCRYPT_LOG_BYTES_DEBUG("SymCryptGcmEncryptPart output: out", (const char *)out, inl);
ret = inl;
goto end;
}
else
{
// Final Encrypt Call
SymCryptGcmEncryptFinal(&cipherCtx->state, cipherCtx->tag, cipherCtx->taglen);
SYMCRYPT_LOG_BYTES_DEBUG("SymCryptGcmEncryptFinal output: tag", (const char *)cipherCtx->tag, cipherCtx->taglen);
ret = EVP_GCM_TLS_TAG_LEN;
goto end;
}
}
else
{
if (inl > 0)
{
// Decrypt Part
SYMCRYPT_LOG_BYTES_DEBUG("SymCryptGcmDecryptPart output: in", (const char *)in, inl);
SymCryptGcmDecryptPart(&cipherCtx->state, in, out, inl);
SYMCRYPT_LOG_BYTES_DEBUG("SymCryptGcmDecryptPart output: out", (const char *)out, inl);
ret = inl;
goto end;
}
else
{
// Final Decrypt Call
SymError = SymCryptGcmDecryptFinal(&cipherCtx->state, cipherCtx->tag, cipherCtx->taglen);
if (SymError != SYMCRYPT_NO_ERROR)
{
SYMCRYPT_LOG_ERROR("SymCryptGcmDecryptFinal failed. SymError = %ld", SymError);
return 0;
}
SYMCRYPT_LOG_BYTES_DEBUG("SymCryptGcmEncryptFinal output: tag", (const char *)cipherCtx->tag, cipherCtx->taglen);
ret = cipherCtx->taglen;
goto end;
}
}
end:
return ret;
}
static int symcrypt_aes_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
void *ptr)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_LOG_DEBUG("type: %d, arg: %d", type, arg);
struct cipher_ctx_gcm *cipherCtx = (struct cipher_ctx_gcm *)EVP_CIPHER_CTX_get_cipher_data(ctx);
unsigned char *iv = NULL;
switch(type) {
case EVP_CTRL_INIT:
iv = (unsigned char *)EVP_CIPHER_CTX_iv(ctx);
if (iv)
{
memcpy(cipherCtx->IV, iv, SYMCRYPT_GCM_IV_LENGTH);
}
cipherCtx->taglen = EVP_GCM_TLS_TAG_LEN;
break;
case EVP_CTRL_GET_IVLEN:
*(int *)ptr = SYMCRYPT_GCM_IV_LENGTH;
break;
case EVP_CTRL_AEAD_SET_IVLEN:
// Symcrypt only support SYMCRYPT_GCM_IV_LENGTH
break;
case EVP_CTRL_AEAD_SET_TAG:
if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_encrypting(ctx))
return 0;
memcpy(cipherCtx->tag, ptr, arg);
cipherCtx->taglen = arg;
break;
case EVP_CTRL_AEAD_GET_TAG:
if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_encrypting(ctx))
return 0;
memcpy(ptr, cipherCtx->tag, cipherCtx->taglen);
break;
default:
break;
}
return 1;
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,18 @@
#include "e_symcrypt.h"
#include <symcrypt.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
int symcrypt_ciphers(ENGINE *, const EVP_CIPHER **,
const int **, int);
void symcrypt_destroy_ciphers(void);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,85 @@
#include "e_symcrypt_dh.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*PFN_DH_meth_generate_key) (DH*);
typedef int (*PFN_DH_meth_compute_key)(unsigned char* key, const BIGNUM* pub_key, DH* dh);
typedef int (*PFN_DH_meth_bn_mod_exp)(const DH* dh, BIGNUM* r,
const BIGNUM* a, const BIGNUM* p,
const BIGNUM* m, BN_CTX* ctx, BN_MONT_CTX* m_ctx);
typedef int (*PFN_DH_meth_init)(DH* dh);
typedef int (*PFN_DH_meth_finish)(DH* dh);
int symcrypt_dh_generate_key(DH* dh)
{
const DH_METHOD* ossl_dh_meth = DH_OpenSSL();
PFN_DH_meth_generate_key pfn_dh_meth_generate_key = DH_meth_get_generate_key(ossl_dh_meth);
if (!pfn_dh_meth_generate_key) {
return 0;
}
return pfn_dh_meth_generate_key(dh);
}
int symcrypt_dh_compute_key(unsigned char* key, const BIGNUM* pub_key, DH* dh)
{
const DH_METHOD* ossl_dh_meth = DH_OpenSSL();
PFN_DH_meth_compute_key pfn_dh_meth_compute_key = DH_meth_get_compute_key(ossl_dh_meth);
if (!pfn_dh_meth_compute_key) {
return 0;
}
return pfn_dh_meth_compute_key(key, pub_key, dh);
}
int symcrypt_dh_bn_mod_exp(const DH* dh, BIGNUM* r,
const BIGNUM* a, const BIGNUM* p,
const BIGNUM* m, BN_CTX* ctx, BN_MONT_CTX* m_ctx)
{
const DH_METHOD* ossl_dh_meth = DH_OpenSSL();
PFN_DH_meth_bn_mod_exp pfn_dh_meth_bm_mod_exp = DH_meth_get_bn_mod_exp(ossl_dh_meth);
if (!pfn_dh_meth_bm_mod_exp) {
return 0;
}
return pfn_dh_meth_bm_mod_exp(dh, r, a, p, m, ctx, m_ctx);
}
int symcrypt_dh_init(DH* dh)
{
const DH_METHOD* ossl_dh_meth = DH_OpenSSL();
PFN_DH_meth_init pfn_dh_meth_init = DH_meth_get_init(ossl_dh_meth);
if (!pfn_dh_meth_init) {
return 0;
}
return pfn_dh_meth_init(dh);
}
int symcrypt_dh_finish(DH* dh)
{
const DH_METHOD* ossl_dh_meth = DH_OpenSSL();
PFN_DH_meth_finish pfn_dh_meth_finish = DH_meth_get_finish(ossl_dh_meth);
if (!pfn_dh_meth_finish) {
return 0;
}
return pfn_dh_meth_finish(dh);
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,24 @@
#include "e_symcrypt.h"
#include <openssl/dh.h>
#ifdef __cplusplus
extern "C" {
#endif
int symcrypt_dh_generate_key(DH* dh);
int symcrypt_dh_compute_key(unsigned char* key, const BIGNUM* pub_key, DH* dh);
int symcrypt_dh_bn_mod_exp(const DH* dh, BIGNUM* r,
const BIGNUM* a, const BIGNUM* p,
const BIGNUM* m, BN_CTX* ctx, BN_MONT_CTX* m_ctx);
int symcrypt_dh_init(DH* dh);
int symcrypt_dh_finish(DH* dh);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,665 @@
#include "e_symcrypt_digests.h"
#include "e_symcrypt_helpers.h"
#include <symcrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
/* MD5 */
typedef struct _SYMCRYPT_MD_MD5_STATE {
PSYMCRYPT_MD5_STATE state;
} SYMCRYPT_MD_MD5_STATE, *PSYMCRYPT_MD_MD5_STATE;
static int symcrypt_digest_md5_init(EVP_MD_CTX *ctx);
static int symcrypt_digest_md5_update(EVP_MD_CTX *ctx, const void *data, size_t count);
static int symcrypt_digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md);
static int symcrypt_digest_md5_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
static int symcrypt_digest_md5_cleanup(EVP_MD_CTX *ctx);
static EVP_MD *_hidden_md5_md = NULL;
static const EVP_MD *symcrypt_digest_md5(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_md5_md == NULL) {
EVP_MD *md;
if ((md = EVP_MD_meth_new(NID_md5, NID_md5WithRSAEncryption)) == NULL
|| !EVP_MD_meth_set_result_size(md, MD5_DIGEST_LENGTH)
|| !EVP_MD_meth_set_input_blocksize(md, MD5_CBLOCK)
|| !EVP_MD_meth_set_app_datasize(md, sizeof(EVP_MD *) + sizeof(SYMCRYPT_MD_MD5_STATE))
|| !EVP_MD_meth_set_flags(md, 0)
|| !EVP_MD_meth_set_init(md, symcrypt_digest_md5_init)
|| !EVP_MD_meth_set_update(md, symcrypt_digest_md5_update)
|| !EVP_MD_meth_set_final(md, symcrypt_digest_md5_final)
|| !EVP_MD_meth_set_copy(md, symcrypt_digest_md5_copy)
|| !EVP_MD_meth_set_cleanup(md, symcrypt_digest_md5_cleanup)
)
{
EVP_MD_meth_free(md);
md = NULL;
}
_hidden_md5_md = md;
}
return _hidden_md5_md;
}
/* SHA1 */
typedef struct _SYMCRYPT_MD_SHA1_STATE {
PSYMCRYPT_SHA1_STATE state;
} SYMCRYPT_MD_SHA1_STATE, *PSYMCRYPT_MD_SHA1_STATE;
static int symcrypt_digest_sha1_init(EVP_MD_CTX *ctx);
static int symcrypt_digest_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count);
static int symcrypt_digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);
static int symcrypt_digest_sha1_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
static int symcrypt_digest_sha1_cleanup(EVP_MD_CTX *ctx);
static EVP_MD *_hidden_sha1_md = NULL;
static const EVP_MD *symcrypt_digest_sha1(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_sha1_md == NULL) {
EVP_MD *md;
if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL
|| !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
|| !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
|| !EVP_MD_meth_set_app_datasize(md, sizeof(EVP_MD *) + sizeof(SYMCRYPT_MD_SHA1_STATE))
|| !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
|| !EVP_MD_meth_set_init(md, symcrypt_digest_sha1_init)
|| !EVP_MD_meth_set_update(md, symcrypt_digest_sha1_update)
|| !EVP_MD_meth_set_final(md, symcrypt_digest_sha1_final)
|| !EVP_MD_meth_set_copy(md, symcrypt_digest_sha1_copy)
|| !EVP_MD_meth_set_cleanup(md, symcrypt_digest_sha1_cleanup)
)
{
EVP_MD_meth_free(md);
md = NULL;
}
_hidden_sha1_md = md;
}
return _hidden_sha1_md;
}
/* SHA256 */
typedef struct _SYMCRYPT_MD_SHA256_STATE {
PSYMCRYPT_SHA256_STATE state;
} SYMCRYPT_MD_SHA256_STATE, *PSYMCRYPT_MD_SHA256_STATE;
static int symcrypt_digest_sha256_init(EVP_MD_CTX *ctx);
static int symcrypt_digest_sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count);
static int symcrypt_digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md);
static int symcrypt_digest_sha256_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
static int symcrypt_digest_sha256_cleanup(EVP_MD_CTX *ctx);
static EVP_MD *_hidden_sha256_md = NULL;
static const EVP_MD *symcrypt_digest_sha256(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_sha256_md == NULL) {
EVP_MD *md;
if ((md = EVP_MD_meth_new(NID_sha256, NID_sha256WithRSAEncryption)) == NULL
|| !EVP_MD_meth_set_result_size(md, SHA256_DIGEST_LENGTH)
|| !EVP_MD_meth_set_input_blocksize(md, SHA256_CBLOCK)
|| !EVP_MD_meth_set_app_datasize(md, sizeof(EVP_MD *) + sizeof(SYMCRYPT_MD_SHA256_STATE))
|| !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
|| !EVP_MD_meth_set_init(md, symcrypt_digest_sha256_init)
|| !EVP_MD_meth_set_update(md, symcrypt_digest_sha256_update)
|| !EVP_MD_meth_set_final(md, symcrypt_digest_sha256_final)
|| !EVP_MD_meth_set_copy(md, symcrypt_digest_sha256_copy)
|| !EVP_MD_meth_set_cleanup(md, symcrypt_digest_sha256_cleanup)
)
{
EVP_MD_meth_free(md);
md = NULL;
}
_hidden_sha256_md = md;
}
return _hidden_sha256_md;
}
/* SHA384 */
typedef struct _SYMCRYPT_MD_SHA384_STATE {
PSYMCRYPT_SHA384_STATE state;
} SYMCRYPT_MD_SHA384_STATE, *PSYMCRYPT_MD_SHA384_STATE;
static int symcrypt_digest_sha384_init(EVP_MD_CTX *ctx);
static int symcrypt_digest_sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count);
static int symcrypt_digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md);
static int symcrypt_digest_sha384_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
static int symcrypt_digest_sha384_cleanup(EVP_MD_CTX *ctx);
static EVP_MD *_hidden_sha384_md = NULL;
static const EVP_MD *symcrypt_digest_sha384(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_sha384_md == NULL) {
EVP_MD *md;
if ((md = EVP_MD_meth_new(NID_sha384, NID_sha384WithRSAEncryption)) == NULL
|| !EVP_MD_meth_set_result_size(md, SHA384_DIGEST_LENGTH)
|| !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK)
|| !EVP_MD_meth_set_app_datasize(md, sizeof(EVP_MD *) + sizeof(SYMCRYPT_MD_SHA384_STATE))
|| !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
|| !EVP_MD_meth_set_init(md, symcrypt_digest_sha384_init)
|| !EVP_MD_meth_set_update(md, symcrypt_digest_sha384_update)
|| !EVP_MD_meth_set_final(md, symcrypt_digest_sha384_final)
|| !EVP_MD_meth_set_copy(md, symcrypt_digest_sha384_copy)
|| !EVP_MD_meth_set_cleanup(md, symcrypt_digest_sha384_cleanup)
)
{
EVP_MD_meth_free(md);
md = NULL;
}
_hidden_sha384_md = md;
}
return _hidden_sha384_md;
}
/* SHA512 */
typedef struct _SYMCRYPT_MD_SHA512_STATE {
PSYMCRYPT_SHA512_STATE state;
} SYMCRYPT_MD_SHA512_STATE, *PSYMCRYPT_MD_SHA512_STATE;
static int symcrypt_digest_sha512_init(EVP_MD_CTX *ctx);
static int symcrypt_digest_sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count);
static int symcrypt_digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md);
static int symcrypt_digest_sha512_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
static int symcrypt_digest_sha512_cleanup(EVP_MD_CTX *ctx);
static EVP_MD *_hidden_sha512_md = NULL;
static const EVP_MD *symcrypt_digest_sha512(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_hidden_sha512_md == NULL) {
EVP_MD *md;
if ((md = EVP_MD_meth_new(NID_sha512, NID_sha512WithRSAEncryption)) == NULL
|| !EVP_MD_meth_set_result_size(md, SHA512_DIGEST_LENGTH)
|| !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK)
|| !EVP_MD_meth_set_app_datasize(md, sizeof(EVP_MD *) + sizeof(SYMCRYPT_MD_SHA512_STATE))
|| !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
|| !EVP_MD_meth_set_init(md, symcrypt_digest_sha512_init)
|| !EVP_MD_meth_set_update(md, symcrypt_digest_sha512_update)
|| !EVP_MD_meth_set_final(md, symcrypt_digest_sha512_final)
|| !EVP_MD_meth_set_copy(md, symcrypt_digest_sha512_copy)
|| !EVP_MD_meth_set_cleanup(md, symcrypt_digest_sha512_cleanup)
)
{
EVP_MD_meth_free(md);
md = NULL;
}
_hidden_sha512_md = md;
}
return _hidden_sha512_md;
}
void symcrypt_destroy_digests(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
EVP_MD_meth_free(_hidden_md5_md);
_hidden_md5_md = NULL;
EVP_MD_meth_free(_hidden_sha1_md);
_hidden_sha1_md = NULL;
EVP_MD_meth_free(_hidden_sha256_md);
_hidden_sha256_md = NULL;
EVP_MD_meth_free(_hidden_sha384_md);
_hidden_sha384_md = NULL;
EVP_MD_meth_free(_hidden_sha512_md);
_hidden_sha512_md = NULL;
}
static int symcrypt_digest_nids(const int **nids)
{
SYMCRYPT_LOG_DEBUG(NULL);
static int symcrypt_digest_nids[6] = { 0, 0, 0, 0, 0, 0 };
static int pos = 0;
static int init = 0;
if (!init) {
const EVP_MD *md;
if ((md = symcrypt_digest_md5()) != NULL)
symcrypt_digest_nids[pos++] = EVP_MD_type(md);
if ((md = symcrypt_digest_sha1()) != NULL)
symcrypt_digest_nids[pos++] = EVP_MD_type(md);
if ((md = symcrypt_digest_sha256()) != NULL)
symcrypt_digest_nids[pos++] = EVP_MD_type(md);
if ((md = symcrypt_digest_sha384()) != NULL)
symcrypt_digest_nids[pos++] = EVP_MD_type(md);
if ((md = symcrypt_digest_sha512()) != NULL)
symcrypt_digest_nids[pos++] = EVP_MD_type(md);
symcrypt_digest_nids[pos] = 0;
init = 1;
}
*nids = symcrypt_digest_nids;
return pos;
}
int symcrypt_digests(ENGINE *e, const EVP_MD **digest,
const int **nids, int nid)
{
SYMCRYPT_LOG_DEBUG(NULL);
int ok = 1;
if (!digest) {
/* We are returning a list of supported nids */
return symcrypt_digest_nids(nids);
}
/* We are being asked for a specific digest */
switch (nid) {
case NID_md5:
*digest = symcrypt_digest_md5();
break;
case NID_sha1:
*digest = symcrypt_digest_sha1();
break;
case NID_sha256:
*digest = symcrypt_digest_sha256();
break;
case NID_sha384:
*digest = symcrypt_digest_sha384();
break;
case NID_sha512:
*digest = symcrypt_digest_sha512();
break;
default:
ok = 0;
*digest = NULL;
break;
}
return ok;
}
/*
* MD5 implementation.
*/
static int symcrypt_digest_md5_init(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_MD5_STATE md_state = (PSYMCRYPT_MD_MD5_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
md_state->state = (PSYMCRYPT_MD5_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_MD5_STATE));
if (md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptMd5Init(md_state->state);
return 1;
}
static int symcrypt_digest_md5_update(EVP_MD_CTX *ctx, const void *data,
size_t count)
{
SYMCRYPT_LOG_DEBUG("Count: %d", count);
PSYMCRYPT_MD_MD5_STATE md_state = (PSYMCRYPT_MD_MD5_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptMd5Append(md_state->state, data, count);
return 1;
}
static int symcrypt_digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_MD5_STATE md_state = (PSYMCRYPT_MD_MD5_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptMd5Result(md_state->state, md);
return 1;
}
static int symcrypt_digest_md5_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_MD5_STATE md_state_to = (PSYMCRYPT_MD_MD5_STATE)EVP_MD_CTX_md_data(to);
PSYMCRYPT_MD_MD5_STATE md_state_from = (PSYMCRYPT_MD_MD5_STATE)EVP_MD_CTX_md_data(from);
if (md_state_from == NULL) {
SYMCRYPT_LOG_DEBUG("No MD 'from' Present");
return 1;
}
if (md_state_from->state == NULL) {
SYMCRYPT_LOG_DEBUG("No MD Symcrypt State Present in 'from'");
return 1;
}
md_state_to->state = (PSYMCRYPT_MD5_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_MD5_STATE));
if (md_state_to->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptMd5StateCopy(md_state_from->state, md_state_to->state);
return 1;
}
static int symcrypt_digest_md5_cleanup(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_MD5_STATE md_state = (PSYMCRYPT_MD_MD5_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state != NULL && md_state->state != NULL) {
OPENSSL_free(md_state->state);
md_state->state = NULL;
}
return 1;
}
/*
* SHA1 implementation.
*/
static int symcrypt_digest_sha1_init(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA1_STATE md_state = (PSYMCRYPT_MD_SHA1_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
md_state->state = (PSYMCRYPT_SHA1_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_SHA1_STATE));
if (md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptSha1Init(md_state->state);
return 1;
}
static int symcrypt_digest_sha1_update(EVP_MD_CTX *ctx, const void *data,
size_t count)
{
SYMCRYPT_LOG_DEBUG("Count: %d", count);
PSYMCRYPT_MD_SHA1_STATE md_state = (PSYMCRYPT_MD_SHA1_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptSha1Append(md_state->state, data, count);
return 1;
}
static int symcrypt_digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA1_STATE md_state = (PSYMCRYPT_MD_SHA1_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptSha1Result(md_state->state, md);
return 1;
}
static int symcrypt_digest_sha1_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA1_STATE md_state_to = (PSYMCRYPT_MD_SHA1_STATE)EVP_MD_CTX_md_data(to);
PSYMCRYPT_MD_SHA1_STATE md_state_from = (PSYMCRYPT_MD_SHA1_STATE)EVP_MD_CTX_md_data(from);
if (md_state_from == NULL) {
SYMCRYPT_LOG_DEBUG("No MD 'from' Present");
return 1;
}
if (md_state_from->state == NULL) {
SYMCRYPT_LOG_DEBUG("No MD Symcrypt State Present in 'from'");
return 1;
}
md_state_to->state = (PSYMCRYPT_SHA1_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_SHA1_STATE));
if (md_state_to->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptSha1StateCopy(md_state_from->state, md_state_to->state);
return 1;
}
static int symcrypt_digest_sha1_cleanup(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA1_STATE md_state = (PSYMCRYPT_MD_SHA1_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state != NULL && md_state->state != NULL) {
OPENSSL_free(md_state->state);
md_state->state = NULL;
}
return 1;
}
/*
* SHA256 implementation.
*/
static int symcrypt_digest_sha256_init(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA256_STATE md_state = (PSYMCRYPT_MD_SHA256_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
md_state->state = (PSYMCRYPT_SHA256_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_SHA256_STATE));
if (md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptSha256Init(md_state->state);
return 1;
}
static int symcrypt_digest_sha256_update(EVP_MD_CTX *ctx, const void *data,
size_t count)
{
SYMCRYPT_LOG_DEBUG("Count: %d", count);
PSYMCRYPT_MD_SHA256_STATE md_state = (PSYMCRYPT_MD_SHA256_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptSha256Append(md_state->state, data, count);
return 1;
}
static int symcrypt_digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA256_STATE md_state = (PSYMCRYPT_MD_SHA256_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptSha256Result(md_state->state, md);
return 1;
}
static int symcrypt_digest_sha256_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA256_STATE md_state_to = (PSYMCRYPT_MD_SHA256_STATE)EVP_MD_CTX_md_data(to);
PSYMCRYPT_MD_SHA256_STATE md_state_from = (PSYMCRYPT_MD_SHA256_STATE)EVP_MD_CTX_md_data(from);
if (md_state_from == NULL) {
SYMCRYPT_LOG_DEBUG("No MD 'from' Present");
return 1;
}
if (md_state_from->state == NULL) {
SYMCRYPT_LOG_DEBUG("No MD Symcrypt State Present in 'from'");
return 1;
}
md_state_to->state = (PSYMCRYPT_SHA256_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_SHA256_STATE));
if (md_state_to->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptSha256StateCopy(md_state_from->state, md_state_to->state);
return 1;
}
static int symcrypt_digest_sha256_cleanup(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA256_STATE md_state = (PSYMCRYPT_MD_SHA256_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state != NULL && md_state->state != NULL) {
OPENSSL_free(md_state->state);
md_state->state = NULL;
}
return 1;
}
/*
* SHA384 implementation.
*/
static int symcrypt_digest_sha384_init(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA384_STATE md_state = (PSYMCRYPT_MD_SHA384_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
md_state->state = (PSYMCRYPT_SHA384_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_SHA384_STATE));
if (md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptSha384Init(md_state->state);
return 1;
}
static int symcrypt_digest_sha384_update(EVP_MD_CTX *ctx, const void *data,
size_t count)
{
SYMCRYPT_LOG_DEBUG("Count: %d", count);
PSYMCRYPT_MD_SHA384_STATE md_state = (PSYMCRYPT_MD_SHA384_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptSha384Append(md_state->state, data, count);
return 1;
}
static int symcrypt_digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA384_STATE md_state = (PSYMCRYPT_MD_SHA384_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptSha384Result(md_state->state, md);
return 1;
}
static int symcrypt_digest_sha384_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA384_STATE md_state_to = (PSYMCRYPT_MD_SHA384_STATE)EVP_MD_CTX_md_data(to);
PSYMCRYPT_MD_SHA384_STATE md_state_from = (PSYMCRYPT_MD_SHA384_STATE)EVP_MD_CTX_md_data(from);
if (md_state_from == NULL) {
SYMCRYPT_LOG_DEBUG("No MD 'from' Present");
return 1;
}
if (md_state_from->state == NULL) {
SYMCRYPT_LOG_DEBUG("No MD Symcrypt State Present in 'from'");
return 1;
}
md_state_to->state = (PSYMCRYPT_SHA384_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_SHA384_STATE));
if (md_state_to->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptSha384StateCopy(md_state_from->state, md_state_to->state);
return 1;
}
static int symcrypt_digest_sha384_cleanup(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA384_STATE md_state = (PSYMCRYPT_MD_SHA384_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state != NULL && md_state->state != NULL) {
OPENSSL_free(md_state->state);
md_state->state = NULL;
}
return 1;
}
/*
* SHA512 implementation.
*/
static int symcrypt_digest_sha512_init(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA512_STATE md_state = (PSYMCRYPT_MD_SHA512_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
md_state->state = (PSYMCRYPT_SHA512_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_SHA512_STATE));
if (md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptSha512Init(md_state->state);
return 1;
}
static int symcrypt_digest_sha512_update(EVP_MD_CTX *ctx, const void *data,
size_t count)
{
SYMCRYPT_LOG_DEBUG("Count: %d", count);
PSYMCRYPT_MD_SHA512_STATE md_state = (PSYMCRYPT_MD_SHA512_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptSha512Append(md_state->state, data, count);
return 1;
}
static int symcrypt_digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA512_STATE md_state = (PSYMCRYPT_MD_SHA512_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state == NULL || md_state->state == NULL) {
SYMCRYPT_LOG_ERROR("No MD Data Present");
return 0;
}
SymCryptSha512Result(md_state->state, md);
return 1;
}
static int symcrypt_digest_sha512_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA512_STATE md_state_to = (PSYMCRYPT_MD_SHA512_STATE)EVP_MD_CTX_md_data(to);
PSYMCRYPT_MD_SHA512_STATE md_state_from = (PSYMCRYPT_MD_SHA512_STATE)EVP_MD_CTX_md_data(from);
if (md_state_from == NULL) {
SYMCRYPT_LOG_DEBUG("No MD 'from' Present");
return 1;
}
if (md_state_from->state == NULL) {
SYMCRYPT_LOG_DEBUG("No MD Symcrypt State Present in 'from'");
return 1;
}
md_state_to->state = (PSYMCRYPT_SHA512_STATE)OPENSSL_zalloc(sizeof(SYMCRYPT_SHA512_STATE));
if (md_state_to->state == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
SymCryptSha512StateCopy(md_state_from->state, md_state_to->state);
return 1;
}
static int symcrypt_digest_sha512_cleanup(EVP_MD_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
PSYMCRYPT_MD_SHA512_STATE md_state = (PSYMCRYPT_MD_SHA512_STATE)EVP_MD_CTX_md_data(ctx);
if (md_state != NULL && md_state->state != NULL) {
OPENSSL_free(md_state->state);
md_state->state = NULL;
}
return 1;
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,19 @@
#include "e_symcrypt.h"
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/md4.h>
#include <openssl/md2.h>
#include <symcrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
int symcrypt_digests(ENGINE *e, const EVP_MD **digest,
const int **nids, int nid);
void symcrypt_destroy_digests(void);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,76 @@
#include "e_symcrypt_dsa.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef DSA_SIG* (*PFN_DSA_meth_sign) (const unsigned char* dgst, int dlen, DSA* dsa);
typedef int (*PFN_DSA_meth_sign_setup) (DSA* dsa, BN_CTX* ctx_in, BIGNUM** kinvp, BIGNUM** rp);
typedef int (*PFN_DSA_meth_verify) (const unsigned char* dgst, int dgst_len, DSA_SIG* sig, DSA* dsa);
typedef int (*PFN_DSA_meth_init)(DSA* dsa);
typedef int (*PFN_DSA_meth_finish)(DSA* dsa);
DSA_SIG* symcrypt_dsa_sign(const unsigned char* dgst, int dlen, DSA* dsa)
{
const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL();
PFN_DSA_meth_sign pfn_dsa_sign = DSA_meth_get_sign(ossl_dsa_meth);
if (!pfn_dsa_sign) {
return 0;
}
return pfn_dsa_sign(dgst, dlen, dsa);
}
int symcrypt_dsa_sign_setup(DSA* dsa, BN_CTX* ctx_in,
BIGNUM** kinvp, BIGNUM** rp)
{
const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL();
PFN_DSA_meth_sign_setup pfn_dsa_sign_setup = DSA_meth_get_sign_setup(ossl_dsa_meth);
if (!pfn_dsa_sign_setup) {
return 0;
}
return pfn_dsa_sign_setup(dsa, ctx_in, kinvp, rp);
}
int symcrypt_dsa_verify(const unsigned char* dgst, int dgst_len,
DSA_SIG* sig, DSA* dsa)
{
const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL();
PFN_DSA_meth_verify pfn_dsa_verify = DSA_meth_get_verify(ossl_dsa_meth);
if (!pfn_dsa_verify) {
return 0;
}
return pfn_dsa_verify(dgst, dgst_len, sig, dsa);
}
int symcrypt_dsa_init(DSA* dsa)
{
const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL();
PFN_DSA_meth_init pfn_dsa_init = DSA_meth_get_init(ossl_dsa_meth);
if (!pfn_dsa_init) {
return 0;
}
return pfn_dsa_init(dsa);
}
int symcrypt_dsa_finish(DSA* dsa)
{
const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL();
PFN_DSA_meth_finish pfn_dsa_finish = DSA_meth_get_finish(ossl_dsa_meth);
if (!pfn_dsa_finish) {
return 0;
}
return pfn_dsa_finish(dsa);
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,23 @@
#include "e_symcrypt.h"
#include <openssl/dsa.h>
#ifdef __cplusplus
extern "C" {
#endif
DSA_SIG* symcrypt_dsa_sign(const unsigned char* dgst, int dlen, DSA* dsa);
int symcrypt_dsa_sign_setup(DSA* dsa, BN_CTX* ctx_in, BIGNUM** kinvp, BIGNUM** rp);
int symcrypt_dsa_verify(const unsigned char* dgst, int dgst_len, DSA_SIG* sig, DSA* dsa);
int symcrypt_dsa_init(DSA* dsa);
int symcrypt_dsa_finish(DSA* dsa);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,198 @@
#include "e_symcrypt_ecc.h"
#include "e_symcrypt_helpers.h"
#include <symcrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*PFN_eckey_sign)(
int type, const unsigned char* dgst, int dlen,
unsigned char* sig, unsigned int* siglen,
const BIGNUM* kinv, const BIGNUM* r, EC_KEY* eckey);
typedef int (*PFN_eckey_sign_setup)(
EC_KEY* eckey, BN_CTX* ctx_in, BIGNUM** kinvp,
BIGNUM** rp);
typedef ECDSA_SIG* (*PFN_eckey_sign_sig)(
const unsigned char* dgst, int dgst_len,
const BIGNUM* in_kinv, const BIGNUM* in_r,
EC_KEY* eckey);
typedef int (*PFN_eckey_verify)(
int type, const unsigned char* dgst, int dgst_len,
const unsigned char* sigbuf, int sig_len, EC_KEY* eckey);
typedef int (*PFN_eckey_verify_sig)(
const unsigned char* dgst, int dgst_len,
const ECDSA_SIG* sig, EC_KEY* eckey);
typedef int (*PFN_eckey_init)(EC_KEY *key);
typedef void (*PFN_eckey_finish)(EC_KEY *key);
typedef int (*PFN_eckey_copy)(EC_KEY *dest, const EC_KEY *src);
typedef int (*PFN_eckey_set_group)(EC_KEY *key, const EC_GROUP *grp);
typedef int (*PFN_eckey_set_private)(EC_KEY *key, const BIGNUM *priv_key);
typedef int (*PFN_eckey_set_public)(EC_KEY *key, const EC_POINT *pub_key);
typedef int (*PFN_eckey_keygen)(EC_KEY *key);
typedef int (*PFN_eckey_compute_key)(unsigned char **psec,
size_t *pseclen,
const EC_POINT *pub_key,
const EC_KEY *ecdh);
typedef struct _SYMCRYPT_ECC_KEY_CONTEXT {
int initialized;
char* data;
PSYMCRYPT_ECKEY key;
} SYMCRYPT_ECC_KEY_CONTEXT;
int eckey_symcrypt_idx = -1;
int symcrypt_eckey_sign(int type, const unsigned char* dgst, int dlen,
unsigned char* sig, unsigned int* siglen,
const BIGNUM* kinv, const BIGNUM* r, EC_KEY* eckey)
{
SYMCRYPT_LOG_DEBUG(NULL);
const EC_KEY_METHOD* ossl_eckey_method = EC_KEY_OpenSSL();
PFN_eckey_sign pfn_eckey_sign = NULL;
EC_KEY_METHOD_get_sign(ossl_eckey_method, &pfn_eckey_sign, NULL, NULL);
if (!pfn_eckey_sign) {
return 0;
}
return pfn_eckey_sign(type, dgst, dlen, sig, siglen, kinv, r, eckey);
}
int symcrypt_eckey_sign_setup(EC_KEY* eckey, BN_CTX* ctx_in, BIGNUM** kinvp,
BIGNUM** rp)
{
SYMCRYPT_LOG_DEBUG(NULL);
const EC_KEY_METHOD* ossl_eckey_method = EC_KEY_OpenSSL();
PFN_eckey_sign_setup pfn_eckey_sign_setup = NULL;
EC_KEY_METHOD_get_sign(ossl_eckey_method, NULL, &pfn_eckey_sign_setup, NULL);
if (!pfn_eckey_sign_setup) {
return 0;
}
return pfn_eckey_sign_setup(eckey, ctx_in, kinvp, rp);
}
ECDSA_SIG* symcrypt_eckey_sign_sig(const unsigned char* dgst, int dgst_len,
const BIGNUM* in_kinv, const BIGNUM* in_r,
EC_KEY* eckey)
{
SYMCRYPT_LOG_DEBUG(NULL);
const EC_KEY_METHOD* ossl_eckey_method = EC_KEY_OpenSSL();
PFN_eckey_sign_sig pfn_eckey_sign_sig = NULL;
EC_KEY_METHOD_get_sign(ossl_eckey_method, NULL, NULL, &pfn_eckey_sign_sig);
if (!pfn_eckey_sign_sig) {
return NULL;
}
return pfn_eckey_sign_sig(dgst, dgst_len, in_kinv, in_r, eckey);
}
int symcrypt_eckey_verify(
int type, const unsigned char* dgst, int dgst_len,
const unsigned char* sigbuf, int sig_len, EC_KEY* eckey)
{
SYMCRYPT_LOG_DEBUG(NULL);
const EC_KEY_METHOD* ossl_eckey_method = EC_KEY_OpenSSL();
PFN_eckey_verify pfn_eckey_verify = NULL;
EC_KEY_METHOD_get_verify(ossl_eckey_method, &pfn_eckey_verify, NULL);
if (!pfn_eckey_verify) {
return 0;
}
return pfn_eckey_verify(type, dgst, dgst_len, sigbuf, sig_len, eckey);
}
int symcrypt_eckey_verify_sig(
const unsigned char* dgst, int dgst_len, const ECDSA_SIG* sig, EC_KEY* eckey)
{
SYMCRYPT_LOG_DEBUG(NULL);
const EC_KEY_METHOD* ossl_eckey_method = EC_KEY_OpenSSL();
PFN_eckey_verify_sig pfn_eckey_verify_sig = NULL;
EC_KEY_METHOD_get_verify(ossl_eckey_method, NULL, &pfn_eckey_verify_sig);
if (!pfn_eckey_verify_sig) {
return 0;
}
return pfn_eckey_verify_sig(dgst, dgst_len, sig, eckey);
}
int symcrypt_eckey_keygen(EC_KEY *key)
{
SYMCRYPT_LOG_DEBUG(NULL);
const EC_KEY_METHOD* ossl_eckey_method = EC_KEY_OpenSSL();
PFN_eckey_keygen pfn_eckey_keygen = NULL;
EC_KEY_METHOD_get_keygen(ossl_eckey_method, &pfn_eckey_keygen);
if (!pfn_eckey_keygen) {
return 0;
}
return pfn_eckey_keygen(key);
}
int symcrypt_eckey_compute_key(unsigned char **psec,
size_t *pseclen,
const EC_POINT *pub_key,
const EC_KEY *ecdh)
{
SYMCRYPT_LOG_DEBUG(NULL);
const EC_KEY_METHOD* ossl_eckey_method = EC_KEY_OpenSSL();
PFN_eckey_compute_key pfn_eckey_compute_key = NULL;
EC_KEY_METHOD_get_compute_key(ossl_eckey_method, &pfn_eckey_compute_key);
if (!pfn_eckey_compute_key) {
return 0;
}
return pfn_eckey_compute_key(psec, pseclen, pub_key, ecdh);
}
int symcrypt_eckey_init(EC_KEY *key)
{
SYMCRYPT_LOG_DEBUG(NULL);
int ret = 0;
SYMCRYPT_ECC_KEY_CONTEXT *keyCtx = OPENSSL_zalloc(sizeof(*keyCtx));
if (!keyCtx) {
SYMCRYPT_LOG_ERROR("OPENSSL_zalloc failed");
goto err;
}
EC_KEY_set_ex_data(key, eckey_symcrypt_idx, keyCtx);
ret = 1;
CommonReturn:
return ret;
err:
ret = 0;
goto CommonReturn;
}
void symcrypt_ecc_free_key_context(SYMCRYPT_ECC_KEY_CONTEXT *keyCtx)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (keyCtx->data) {
OPENSSL_free(keyCtx->data);
}
if (keyCtx->key) {
SymCryptEckeyFree(keyCtx->key);
}
keyCtx->initialized = 0;
return;
}
void symcrypt_eckey_finish(EC_KEY *key)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_ECC_KEY_CONTEXT *keyCtx = EC_KEY_get_ex_data(key, eckey_symcrypt_idx);
symcrypt_ecc_free_key_context(keyCtx);
EC_KEY_set_ex_data(key, eckey_symcrypt_idx, NULL);
return;
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,45 @@
#include "e_symcrypt.h"
#include <openssl/ec.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int eckey_symcrypt_idx;
typedef int (*PFN_eckey_copy)(EC_KEY *dest, const EC_KEY *src);
typedef int (*PFN_eckey_set_group)(EC_KEY *key, const EC_GROUP *grp);
typedef int (*PFN_eckey_set_private)(EC_KEY *key, const BIGNUM *priv_key);
typedef int (*PFN_eckey_set_public)(EC_KEY *key, const EC_POINT *pub_key);
int symcrypt_eckey_init(EC_KEY *key);
void symcrypt_eckey_finish(EC_KEY *key);
// int symcrypt_eckey_copy(EC_KEY *dest, const EC_KEY *src);
// int symcrypt_eckey_set_group(EC_KEY *key, const EC_GROUP *grp);
// int symcrypt_eckey_set_private(EC_KEY *key, const BIGNUM *priv_key);
// int symcrypt_eckey_set_public(EC_KEY *key, const EC_POINT *pub_key);
int symcrypt_eckey_keygen(EC_KEY *key);
int symcrypt_eckey_compute_key(unsigned char **psec,
size_t *pseclen,
const EC_POINT *pub_key,
const EC_KEY *ecdh);
int symcrypt_eckey_sign(int type,
const unsigned char* dgst,
int dlen,
unsigned char* sig,
unsigned int* siglen,
const BIGNUM* kinv,
const BIGNUM* r,
EC_KEY* eckey);
int symcrypt_eckey_sign_setup(EC_KEY* eckey, BN_CTX* ctx_in, BIGNUM** kinvp, BIGNUM** rp);
ECDSA_SIG* symcrypt_eckey_sign_sig(const unsigned char* dgst, int dgst_len,
const BIGNUM* in_kinv, const BIGNUM* in_r,
EC_KEY* eckey);
int symcrypt_eckey_verify(int type, const unsigned char* dgst, int dgst_len,
const unsigned char* sigbuf, int sig_len, EC_KEY* eckey);
int symcrypt_eckey_verify_sig(const unsigned char* dgst, int dgst_len,
const ECDSA_SIG* sig, EC_KEY* eckey);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,153 @@
#include "e_symcrypt_helpers.h"
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SYMCRYPT_ENGINE_TRACELOG_PARA_LENGTH 256
#define SYMCRYPT_LOG_LEVEL_PREFIX_ERROR "ERROR"
#define SYMCRYPT_LOG_LEVEL_PREFIX_INFO "INFO"
#define SYMCRYPT_LOG_LEVEL_PREFIX_DEBUG "DEBUG"
static int _traceLogLevel = SYMCRYPT_LOG_LEVEL_INFO;
static char *_traceLogFilename = NULL;
void SYMCRYPT_ENGINE_set_trace_level(int trace_level)
{
if (trace_level >= SYMCRYPT_LOG_LEVEL_OFF &&
trace_level <= SYMCRYPT_LOG_LEVEL_DEBUG)
{
_traceLogLevel = trace_level;
}
return;
}
void SYMCRYPT_ENGINE_set_trace_log_filename(const char *filename)
{
if (_traceLogFilename)
OPENSSL_free(_traceLogFilename);
_traceLogFilename = OPENSSL_strdup(filename);
return;
}
static FILE *_open_trace_log_filename()
{
FILE *fp = stdout;
if (_traceLogFilename != NULL) {
fp = fopen(_traceLogFilename, "a");
if (fp == NULL) {
fp = stdout;
}
}
return fp;
}
static void _close_trace_log_filename(FILE *fp)
{
if (fp != stdout) {
fflush(fp);
fclose(fp);
}
return;
}
void _SYMCRYPT_log(
int trace_level,
const char *func,
const char *format, ...)
{
char paraBuf[SYMCRYPT_ENGINE_TRACELOG_PARA_LENGTH];
FILE *fp = NULL;
va_list args;
va_start(args, format);
char *trace_level_prefix = "";
if (_traceLogLevel < trace_level) {
return;
}
switch(trace_level)
{
case SYMCRYPT_LOG_LEVEL_ERROR:
trace_level_prefix = SYMCRYPT_LOG_LEVEL_PREFIX_ERROR;
case SYMCRYPT_LOG_LEVEL_INFO:
trace_level_prefix = SYMCRYPT_LOG_LEVEL_PREFIX_INFO;
break;
case SYMCRYPT_LOG_LEVEL_DEBUG:
trace_level_prefix = SYMCRYPT_LOG_LEVEL_PREFIX_DEBUG;
default:
break;
}
if (func == NULL) { func = ""; }
if (format == NULL) { format = ""; }
if (vsnprintf(paraBuf, sizeof(paraBuf), format, args) < 0) {
*paraBuf = '\0';
}
fp = _open_trace_log_filename();
fprintf(fp, "[%s] %s: %s\n", trace_level_prefix, func, paraBuf);
_close_trace_log_filename(fp);
return;
}
void _SYMCRYPT_log_bytes(
int trace_level,
const char *func,
char *description,
const char *s,
int len)
{
if (_traceLogLevel < trace_level) {
return;
}
FILE *fp = NULL;
_SYMCRYPT_log(trace_level, func, description);
fp = _open_trace_log_filename();
BIO_dump_fp(fp, s, len);
_close_trace_log_filename(fp);
return;
}
void _SYMCRYPT_log_bignum(
int trace_level,
const char *func,
char *description,
BIGNUM *bn)
{
unsigned char *string = NULL;
int length = 0;
FILE *fp = NULL;
if (_traceLogLevel < trace_level) {
return;
}
if (bn == NULL) {
return;
}
length = BN_num_bytes(bn);
if (length < 0) {
return;
}
string = (unsigned char *)OPENSSL_zalloc(length);
if (string == NULL) {
return;
}
if (BN_bn2bin(bn, string) < 0) {
return;
}
_SYMCRYPT_log_bytes(trace_level, func, description, string, length);
OPENSSL_free(string);
return;
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,62 @@
#include "e_symcrypt.h"
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
void* SYMCRYPT_ENGINE_zalloc(size_t num);
void* SYMCRYPT_ENGINE_realloc(void *mem, size_t num);
void SYMCRYPT_ENGINE_free(void *mem);
void _SYMCRYPT_log(
int trace_level,
const char *func,
const char *format, ...);
#define SYMCRYPT_LOG_DEBUG(...) \
_SYMCRYPT_log(SYMCRYPT_LOG_LEVEL_DEBUG, __FUNCTION__, __VA_ARGS__)
#define SYMCRYPT_LOG_INFO(...) \
_SYMCRYPT_log(SYMCRYPT_LOG_LEVEL_INFO, __FUNCTION__, __VA_ARGS__)
#define SYMCRYPT_LOG_ERROR(...) \
_SYMCRYPT_log(SYMCRYPT_LOG_LEVEL_ERROR, __FUNCTION__, __VA_ARGS__)
void _SYMCRYPT_log_bytes(
int trace_level,
const char *func,
char *description,
const char *s,
int len);
#define SYMCRYPT_LOG_BYTES_DEBUG(description, s, len) \
_SYMCRYPT_log_bytes(SYMCRYPT_LOG_LEVEL_DEBUG, __FUNCTION__, description, s, len)
#define SYMCRYPT_LOG_BYTES_INFO(description, s, len) \
_SYMCRYPT_log_bytes(SYMCRYPT_LOG_LEVEL_INFO, __FUNCTION__, description, s, len)
#define SYMCRYPT_LOG_BYTES_ERROR(description, s, len) \
_SYMCRYPT_log_bytes(SYMCRYPT_LOG_LEVEL_ERROR, __FUNCTION__, description, s, len)
void _SYMCRYPT_log_bignum(
int trace_level,
const char *func,
char *description,
BIGNUM *bn);
#define SYMCRYPT_LOG_BIGNUM_DEBUG(description, bn) \
_SYMCRYPT_log_bignum(SYMCRYPT_LOG_LEVEL_DEBUG, __FUNCTION__, description, bn)
#define SYMCRYPT_LOG_BIGNUM_INFO(description, s, len) \
_SYMCRYPT_log_bignum(SYMCRYPT_LOG_LEVEL_INFO, __FUNCTION__, description, bn)
#define SYMCRYPT_LOG_BIGNUM_ERROR(description, s, len) \
_SYMCRYPT_log_bignum(SYMCRYPT_LOG_LEVEL_ERROR, __FUNCTION__, description, bn)
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,311 @@
#include "e_symcrypt.h"
#include "e_symcrypt_hkdf.h"
#include "e_symcrypt_helpers.h"
#include <openssl/hmac.h>
#include <symcrypt.h>
#include <openssl/kdf.h>
#ifdef __cplusplus
extern "C" {
#endif
#define HKDF_MAXBUF 1024
typedef struct {
int mode;
const EVP_MD *md;
unsigned char *salt;
size_t salt_len;
unsigned char *key;
size_t key_len;
unsigned char info[HKDF_MAXBUF];
size_t info_len;
} SYMCRYPT_HKDF_PKEY_CTX;
int symcrypt_hkdf_init(EVP_PKEY_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_HKDF_PKEY_CTX *symcrypt_hkdf_context;
if ((symcrypt_hkdf_context = OPENSSL_zalloc(sizeof(*symcrypt_hkdf_context))) == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
EVP_PKEY_CTX_set_data(ctx, symcrypt_hkdf_context);
return 1;
}
void symcrypt_hkdf_cleanup(EVP_PKEY_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_HKDF_PKEY_CTX *symcrypt_hkdf_context = NULL;
symcrypt_hkdf_context = (SYMCRYPT_HKDF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
if (symcrypt_hkdf_context == NULL) {
return;
}
OPENSSL_clear_free(symcrypt_hkdf_context->salt, symcrypt_hkdf_context->salt_len);
OPENSSL_clear_free(symcrypt_hkdf_context->key, symcrypt_hkdf_context->key_len);
OPENSSL_cleanse(symcrypt_hkdf_context->info, symcrypt_hkdf_context->info_len);
OPENSSL_free(symcrypt_hkdf_context);
return;
}
int symcrypt_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_HKDF_PKEY_CTX *symcrypt_hkdf_context = (SYMCRYPT_HKDF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
switch (type) {
case EVP_PKEY_CTRL_HKDF_MD:
if (p2 == NULL)
return 0;
symcrypt_hkdf_context->md = p2;
return 1;
case EVP_PKEY_CTRL_HKDF_MODE:
symcrypt_hkdf_context->mode = p1;
return 1;
case EVP_PKEY_CTRL_HKDF_SALT:
if (p1 == 0 || p2 == NULL)
return 1;
if (p1 < 0)
return 0;
if (symcrypt_hkdf_context->salt != NULL)
OPENSSL_clear_free(symcrypt_hkdf_context->salt, symcrypt_hkdf_context->salt_len);
symcrypt_hkdf_context->salt = OPENSSL_memdup(p2, p1);
if (symcrypt_hkdf_context->salt == NULL)
return 0;
symcrypt_hkdf_context->salt_len = p1;
return 1;
case EVP_PKEY_CTRL_HKDF_KEY:
if (p1 < 0)
return 0;
if (symcrypt_hkdf_context->key != NULL)
OPENSSL_clear_free(symcrypt_hkdf_context->key, symcrypt_hkdf_context->key_len);
symcrypt_hkdf_context->key = OPENSSL_memdup(p2, p1);
if (symcrypt_hkdf_context->key == NULL)
return 0;
symcrypt_hkdf_context->key_len = p1;
return 1;
case EVP_PKEY_CTRL_HKDF_INFO:
if (p1 == 0 || p2 == NULL)
return 1;
if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - symcrypt_hkdf_context->info_len))
return 0;
memcpy(symcrypt_hkdf_context->info + symcrypt_hkdf_context->info_len, p2, p1);
symcrypt_hkdf_context->info_len += p1;
return 1;
default:
return -2;
}
}
int symcrypt_hkdf_derive_init(EVP_PKEY_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_HKDF_PKEY_CTX *symcrypt_hkdf_context = (SYMCRYPT_HKDF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
OPENSSL_clear_free(symcrypt_hkdf_context->key, symcrypt_hkdf_context->key_len);
OPENSSL_clear_free(symcrypt_hkdf_context->salt, symcrypt_hkdf_context->salt_len);
OPENSSL_cleanse(symcrypt_hkdf_context->info, symcrypt_hkdf_context->info_len);
memset(symcrypt_hkdf_context, 0, sizeof(*symcrypt_hkdf_context));
return 1;
}
static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
const unsigned char *salt, size_t salt_len,
const unsigned char *key, size_t key_len,
unsigned char *prk, size_t *prk_len)
{
SYMCRYPT_LOG_DEBUG(NULL);
unsigned int tmp_len;
if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
return NULL;
*prk_len = tmp_len;
return prk;
}
static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
const unsigned char *prk, size_t prk_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len)
{
SYMCRYPT_LOG_DEBUG(NULL);
HMAC_CTX *hmac;
unsigned char *ret = NULL;
unsigned int i;
unsigned char prev[EVP_MAX_MD_SIZE];
size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
size_t n = okm_len / dig_len;
if (okm_len % dig_len)
n++;
if (n > 255 || okm == NULL)
return NULL;
if ((hmac = HMAC_CTX_new()) == NULL)
return NULL;
if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
goto err;
for (i = 1; i <= n; i++) {
size_t copy_len;
const unsigned char ctr = i;
if (i > 1) {
if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
goto err;
if (!HMAC_Update(hmac, prev, dig_len))
goto err;
}
if (!HMAC_Update(hmac, info, info_len))
goto err;
if (!HMAC_Update(hmac, &ctr, 1))
goto err;
if (!HMAC_Final(hmac, prev, NULL))
goto err;
copy_len = (done_len + dig_len > okm_len) ?
okm_len - done_len :
dig_len;
memcpy(okm + done_len, prev, copy_len);
done_len += copy_len;
}
ret = okm;
err:
OPENSSL_cleanse(prev, sizeof(prev));
HMAC_CTX_free(hmac);
return ret;
}
PCSYMCRYPT_MAC
SymCryptMacAlgorithm(
const EVP_MD *evp_md)
{
SYMCRYPT_LOG_DEBUG(NULL);
int type = EVP_MD_type(evp_md);
if (type == NID_sha1)
return SymCryptHmacSha1Algorithm;
if (type == NID_sha256)
return SymCryptHmacSha256Algorithm;
if (type == NID_sha384)
return SymCryptHmacSha384Algorithm;
if (type == NID_sha512)
return SymCryptHmacSha512Algorithm;
// if (type == NID_AES_CMC)
// return SymCryptAesCmacAlgorithm;
return NULL;
}
int symcrypt_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_ERROR SymError = SYMCRYPT_NO_ERROR;
SYMCRYPT_HKDF_PKEY_CTX *symcrypt_hkdf_context = (SYMCRYPT_HKDF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
PCSYMCRYPT_MAC symcrypt_mac_algo = NULL;
SYMCRYPT_HKDF_EXPANDED_KEY scExpandedKey;
if (symcrypt_hkdf_context->md == NULL) {
SYMCRYPT_LOG_ERROR("Missing Digest");
return 0;
}
symcrypt_mac_algo = SymCryptMacAlgorithm(symcrypt_hkdf_context->md);
if (symcrypt_hkdf_context->key == NULL) {
SYMCRYPT_LOG_ERROR("Missing Key");
return 0;
}
switch (symcrypt_hkdf_context->mode) {
case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND:
SymError = SymCryptHkdf(
symcrypt_mac_algo,
symcrypt_hkdf_context->key,
symcrypt_hkdf_context->key_len,
symcrypt_hkdf_context->salt,
symcrypt_hkdf_context->salt_len,
symcrypt_hkdf_context->info,
symcrypt_hkdf_context->info_len,
key,
*keylen);
if (SymError != SYMCRYPT_NO_ERROR)
{
SYMCRYPT_LOG_DEBUG("ERROR: SymCryptHkdf failed. SymError = %d ", SymError);
return 0;
}
return 1;
case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
if (key == NULL) {
*keylen = EVP_MD_size(symcrypt_hkdf_context->md);
return 1;
}
// SymCryptError = SymCryptHkdfExpandKey(
// &scExpandedKey,
// symcrypt_mac_algo,
// symcrypt_hkdf_context->key,
// symcrypt_hkdf_context->key_len,
// symcrypt_hkdf_context->salt,
// symcrypt_hkdf_context->salt_len);
// if (SymCryptError != SYMCRYPT_NO_ERROR)
// {
// SYMCRYPT_LOG_DEBUG("ERROR: SymCryptHkdfExpandKey failed. SymError = %d ", SymError);
// return 0;
// }
// // TODO:
// // Extract expanded key output and copy it to key[keylen]
// return 1;
return HKDF_Extract(
symcrypt_hkdf_context->md,
symcrypt_hkdf_context->salt,
symcrypt_hkdf_context->salt_len,
symcrypt_hkdf_context->key,
symcrypt_hkdf_context->key_len,
key, keylen) != NULL;
case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
// // TODO:
// // Populate scExpandedKey
// SymCryptError = SymCryptHkdfDerive(
// &scExpandedKey,
// symcrypt_hkdf_context->info,
// symcrypt_hkdf_context->info_len,
// key,
// *keylen);
// if (SymCryptError != SYMCRYPT_NO_ERROR)
// {
// SYMCRYPT_LOG_DEBUG("ERROR: SymCryptHkdfExpandKey failed. SymError = %d ", SymError);
// return 0;
// }
// return 1;
return HKDF_Expand(
symcrypt_hkdf_context->md,
symcrypt_hkdf_context->key,
symcrypt_hkdf_context->key_len,
symcrypt_hkdf_context->info,
symcrypt_hkdf_context->info_len,
key, *keylen) != NULL;
default:
return 0;
}
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,15 @@
#include "e_symcrypt.h"
#ifdef __cplusplus
extern "C" {
#endif
int symcrypt_hkdf_init(EVP_PKEY_CTX *ctx);
void symcrypt_hkdf_cleanup(EVP_PKEY_CTX *ctx);
int symcrypt_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
int symcrypt_hkdf_derive_init(EVP_PKEY_CTX *ctx);
int symcrypt_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
#ifdef __cplusplus
}
#endif

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

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

@ -0,0 +1 @@
#pragma once

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

@ -0,0 +1,92 @@
#include "e_symcrypt_pkey_meths.h"
#include "e_symcrypt_helpers.h"
#include "e_symcrypt_hkdf.h"
#include "e_symcrypt_tls1prf.h"
#include <symcrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
static int symcrypt_evp_nids[] = {
EVP_PKEY_TLS1_PRF,
EVP_PKEY_HKDF,
// EVP_PKEY_X25519 - Future
};
const int evp_nids_count = sizeof(symcrypt_evp_nids) / sizeof(symcrypt_evp_nids[0]);
static EVP_PKEY_METHOD *_symcrypt_pkey_tls1_prf = NULL;
static EVP_PKEY_METHOD *symcrypt_pkey_tls1_prf(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_symcrypt_pkey_tls1_prf == NULL)
{
if((_symcrypt_pkey_tls1_prf = EVP_PKEY_meth_new(EVP_PKEY_TLS1_PRF, 0)) != NULL)
{
EVP_PKEY_meth_set_init(_symcrypt_pkey_tls1_prf, symcrypt_tls1prf_init);
EVP_PKEY_meth_set_cleanup(_symcrypt_pkey_tls1_prf, symcrypt_tls1prf_cleanup);
EVP_PKEY_meth_set_derive(_symcrypt_pkey_tls1_prf, symcrypt_tls1prf_derive_init, symcrypt_tls1prf_derive);
EVP_PKEY_meth_set_ctrl(_symcrypt_pkey_tls1_prf, symcrypt_tls1prf_ctrl, NULL);
}
}
return _symcrypt_pkey_tls1_prf;
}
static EVP_PKEY_METHOD *_symcrypt_pkey_hkdf = NULL;
static EVP_PKEY_METHOD *symcrypt_pkey_hkdf(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
if (_symcrypt_pkey_hkdf == NULL)
{
if((_symcrypt_pkey_hkdf = EVP_PKEY_meth_new(EVP_PKEY_HKDF, 0)) != NULL)
{
EVP_PKEY_meth_set_init(_symcrypt_pkey_hkdf, symcrypt_hkdf_init);
EVP_PKEY_meth_set_cleanup(_symcrypt_pkey_hkdf, symcrypt_hkdf_cleanup);
EVP_PKEY_meth_set_derive(_symcrypt_pkey_hkdf, symcrypt_hkdf_derive_init, symcrypt_hkdf_derive);
EVP_PKEY_meth_set_ctrl(_symcrypt_pkey_hkdf, symcrypt_hkdf_ctrl, NULL);
}
}
return _symcrypt_pkey_hkdf;
}
int symcrypt_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth,
const int **nids, int nid)
{
SYMCRYPT_LOG_DEBUG(NULL);
int ok = 1;
if (!pmeth) {
/* We are returning a list of supported nids */
*nids = symcrypt_evp_nids;
return evp_nids_count;
}
/* We are being asked for a specific cipher */
switch (nid) {
case EVP_PKEY_TLS1_PRF:
*pmeth = symcrypt_pkey_tls1_prf();
break;
case EVP_PKEY_HKDF:
*pmeth = symcrypt_pkey_hkdf();
break;
default:
SYMCRYPT_LOG_ERROR("NID %d not supported");
ok = 0;
*pmeth = NULL;
break;
}
return ok;
}
void symcrypt_destroy_pkey_methods(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
EVP_PKEY_meth_free(_symcrypt_pkey_hkdf);
EVP_PKEY_meth_free(_symcrypt_pkey_tls1_prf);
_symcrypt_pkey_hkdf = NULL;
_symcrypt_pkey_tls1_prf = NULL;
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,15 @@
#include "e_symcrypt.h"
#include <openssl/dh.h>
#ifdef __cplusplus
extern "C" {
#endif
int symcrypt_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth,
const int **nids, int nid);
void symcrypt_destroy_pkey_methods(void);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,71 @@
#include "e_symcrypt.h"
#include "e_symcrypt_ecc.h"
#include "e_symcrypt_rsa.h"
#include "e_symcrypt_dsa.h"
#include "e_symcrypt_dh.h"
#include "e_symcrypt_digests.h"
#include "e_symcrypt_ciphers.h"
#include "e_symcrypt_pkey_meths.h"
#include "e_symcrypt_rand.h"
#include "e_symcrypt_helpers.h"
#include <symcrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
static int symcrypt_rand_seed(const void *buf, int num)
{
//SYMCRYPT_LOG_DEBUG(NULL);
RAND_METHOD *ossl_rand = RAND_OpenSSL();
return ossl_rand->seed(buf, num);
}
static int symcrypt_rand_bytes(unsigned char *buf, int num)
{
//SYMCRYPT_LOG_DEBUG(NULL);
RAND_METHOD *ossl_rand = RAND_OpenSSL();
return ossl_rand->bytes(buf, num);
}
static int symcrypt_rand_add(const void *buf, int num, double randomness)
{
//SYMCRYPT_LOG_DEBUG(NULL);
RAND_METHOD *ossl_rand = RAND_OpenSSL();
return ossl_rand->add(buf, num, randomness);
}
static int symcrypt_rand_pseudorand(unsigned char *buf, int num)
{
//SYMCRYPT_LOG_DEBUG(NULL);
RAND_METHOD *ossl_rand = RAND_OpenSSL();
return ossl_rand->pseudorand(buf, num);
}
static int symcrypt_rand_status(void)
{
//SYMCRYPT_LOG_DEBUG(NULL);
RAND_METHOD *ossl_rand = RAND_OpenSSL();
return ossl_rand->status();
}
RAND_METHOD _symcrypt_rand_meth = {
symcrypt_rand_seed,
symcrypt_rand_bytes,
NULL,
symcrypt_rand_add,
symcrypt_rand_pseudorand,
symcrypt_rand_status
};
RAND_METHOD *symcrypt_rand_method(void)
{
SYMCRYPT_LOG_DEBUG(NULL);
return &_symcrypt_rand_meth;
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,12 @@
#include "e_symcrypt.h"
#include <openssl/rand.h>
#ifdef __cplusplus
extern "C" {
#endif
RAND_METHOD *symcrypt_rand_method(void);
#ifdef __cplusplus
}
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,50 @@
#include "e_symcrypt.h"
#include <openssl/rsa.h>
#include <symcrypt.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int rsa_symcrypt_idx;
int symcrypt_rsa_pub_enc(int flen, const unsigned char* from,
unsigned char* to, RSA* rsa,
int padding);
int symcrypt_rsa_pub_dec(int flen, const unsigned char* from,
unsigned char* to, RSA* rsa,
int padding);
int symcrypt_rsa_priv_enc(int flen, const unsigned char* from,
unsigned char* to, RSA* rsa, int padding);
int symcrypt_rsa_priv_dec(int flen, const unsigned char* from,
unsigned char* to, RSA* rsa, int padding);
int symcrypt_rsa_mod_exp(BIGNUM* r0, const BIGNUM* i, RSA* rsa, BN_CTX* ctx);
int symcrypt_rsa_bn_mod_exp(BIGNUM* r,
const BIGNUM* a,
const BIGNUM* p,
const BIGNUM* m,
BN_CTX* ctx,
BN_MONT_CTX* m_ctx);
int symcrypt_rsa_sign(int type, const unsigned char* m,
unsigned int m_length,
unsigned char* sigret, unsigned int* siglen,
const RSA* rsa);
int symcrypt_rsa_verify(int dtype, const unsigned char* m,
unsigned int m_length,
const unsigned char* sigbuf,
unsigned int siglen, const RSA* rsa);
int symcrypt_rsa_keygen(RSA* rsa, int bits, BIGNUM* e, BN_GENCB* cb);
int symcrypt_rsa_init(RSA *rsa);
int symcrypt_rsa_finish(RSA *rsa);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,154 @@
#include "e_symcrypt.h"
#include "e_symcrypt_helpers.h"
#include <symcrypt.h>
#include <openssl/kdf.h>
#ifdef __cplusplus
extern "C" {
#endif
static int tls1_prf_alg(const EVP_MD *md,
const unsigned char *sec, size_t slen,
const unsigned char *seed, size_t seed_len,
unsigned char *out, size_t olen);
#define TLS1_PRF_MAXBUF 1024
/* TLS KDF pkey context structure */
typedef struct {
/* Digest to use for PRF */
const EVP_MD *md;
/* Secret value to use for PRF */
unsigned char *secret;
size_t secret_length;
/* Buffer of concatenated seed data */
unsigned char seed[TLS1_PRF_MAXBUF];
size_t seed_length;
} SYMCRYPT_TLS1_PRF_PKEY_CTX;
int symcrypt_tls1prf_init(EVP_PKEY_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_TLS1_PRF_PKEY_CTX *key_context = NULL;
if ((key_context = OPENSSL_zalloc(sizeof(*key_context))) == NULL) {
SYMCRYPT_LOG_ERROR("Memory Allocation Error");
return 0;
}
EVP_PKEY_CTX_set_data(ctx, key_context);
return 1;
}
void symcrypt_tls1prf_cleanup(EVP_PKEY_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_TLS1_PRF_PKEY_CTX *key_context = (SYMCRYPT_TLS1_PRF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
if (key_context == NULL) {
return;
}
OPENSSL_clear_free(key_context->secret, key_context->secret_length);
OPENSSL_cleanse(key_context->seed, key_context->seed_length);
OPENSSL_free(key_context);
}
int symcrypt_tls1prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_TLS1_PRF_PKEY_CTX *key_context = (SYMCRYPT_TLS1_PRF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
switch (type) {
case EVP_PKEY_CTRL_TLS_MD:
key_context->md = p2;
return 1;
case EVP_PKEY_CTRL_TLS_SECRET:
if (p1 < 0)
return 0;
if (key_context->secret != NULL)
OPENSSL_clear_free(key_context->secret, key_context->secret_length);
OPENSSL_cleanse(key_context->seed, key_context->seed_length);
key_context->seed_length = 0;
key_context->secret = OPENSSL_memdup(p2, p1);
if (key_context->secret == NULL)
return 0;
key_context->secret_length = p1;
return 1;
case EVP_PKEY_CTRL_TLS_SEED:
if (p1 == 0 || p2 == NULL)
return 1;
if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - key_context->seed_length))
return 0;
memcpy(key_context->seed + key_context->seed_length, p2, p1);
key_context->seed_length += p1;
return 1;
default:
return -2;
}
}
int symcrypt_tls1prf_derive_init(EVP_PKEY_CTX *ctx)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_TLS1_PRF_PKEY_CTX *key_context = (SYMCRYPT_TLS1_PRF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
OPENSSL_clear_free(key_context->secret, key_context->secret_length);
OPENSSL_cleanse(key_context->seed, key_context->seed_length);
memset(key_context, 0, sizeof(*key_context));
return 1;
}
PCSYMCRYPT_MAC
GetSymCryptMacAlgorithm(
const EVP_MD *evp_md)
{
SYMCRYPT_LOG_DEBUG(NULL);
int type = EVP_MD_type(evp_md);
if (type == NID_sha1)
return SymCryptHmacSha1Algorithm;
if (type == NID_sha256)
return SymCryptHmacSha256Algorithm;
if (type == NID_sha384)
return SymCryptHmacSha384Algorithm;
if (type == NID_sha512)
return SymCryptHmacSha512Algorithm;
// if (type == NID_AES_CMC)
// return SymCryptAesCmacAlgorithm;
return NULL;
}
int symcrypt_tls1prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
SYMCRYPT_LOG_DEBUG(NULL);
SYMCRYPT_TLS1_PRF_PKEY_CTX *key_context = (SYMCRYPT_TLS1_PRF_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx);
PCSYMCRYPT_MAC symcrypt_mac_algo = NULL;
SYMCRYPT_ERROR SymError = SYMCRYPT_NO_ERROR;
if (key_context->md == NULL) {
SYMCRYPT_LOG_ERROR("Missing Digest");
return 0;
}
symcrypt_mac_algo = GetSymCryptMacAlgorithm(key_context->md);
if (key_context->secret == NULL) {
SYMCRYPT_LOG_ERROR("Missing Secret");
return 0;
}
SymError = SymCryptTlsPrf1_2(
symcrypt_mac_algo,
key_context->secret,
key_context->secret_length,
NULL,
0,
key_context->seed,
key_context->seed_length,
key,
*keylen);
if (SymError != SYMCRYPT_NO_ERROR)
{
SYMCRYPT_LOG_DEBUG("ERROR: SymCryptHkdf failed. SymError = %d ", SymError);
return 0;
}
return 1;
}
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,15 @@
#include "e_symcrypt.h"
#ifdef __cplusplus
extern "C" {
#endif
int symcrypt_tls1prf_init(EVP_PKEY_CTX *ctx);
void symcrypt_tls1prf_cleanup(EVP_PKEY_CTX *ctx);
int symcrypt_tls1prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
int symcrypt_tls1prf_derive_init(EVP_PKEY_CTX *ctx);
int symcrypt_tls1prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
#ifdef __cplusplus
}
#endif

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

@ -0,0 +1,61 @@
cmake_minimum_required(VERSION 2.8)
project(symcrypt_engine)
set(DEFAULT_BUILD_TYPE "Release")
include(GNUInstallDirs)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra -Wno-unused-parameter")
find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})
include_directories(/home/akshay/SymCrypt/inc)
# Set CMake variables that subsequent CMake scripts can check against
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR AMD64)
# For now this is just used for separating the output directories
set(SYMCRYPT_TARGET_ENV Linux)
# Define _AMD64_ to set up the correct SymCrypt macros, e.g. SYMCRYPT_CPU_AMD64
add_compile_options(-D_AMD64_)
add_compile_options(-DDBG)
add_compile_options(-O3)
# Enable a baseline of features for the compiler to support everywhere
# Other than for SSSE3 we do not expect the compiler to generate these instructions anywhere other than with intrinsics
#
# We cannot globally enable AVX and later, as we need to keep use of these instructions behind CPU detection, and the
# instructions are definitely useful enough for a smart compiler to use them in C code (i.e. in memcpy)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mssse3 -mxsave -maes -mpclmul -msha -mrdrnd -mrdseed")
set(CMAKE_ASM_FLAGS "-x assembler-with-cpp")
add_library(symcryptengine STATIC
../src/e_symcrypt.c
../src/e_symcrypt_ciphers.c
../src/e_symcrypt_dh.c
../src/e_symcrypt_digests.c
../src/e_symcrypt_dsa.c
../src/e_symcrypt_ecc.c
../src/e_symcrypt_pkey_asn1_meths.c
../src/e_symcrypt_pkey_meths.c
../src/e_symcrypt_rand.c
../src/e_symcrypt_rsa.c
../src/e_symcrypt_hkdf.c
../src/e_symcrypt_tls1prf.c
../src/e_symcrypt_helpers.c
)
set_target_properties(symcryptengine PROPERTIES PUBLIC_HEADER ../inc/e_symcrypt.h)
# target_link_libraries(symcryptengine ${OPENSSL_CRYPTO_LIBRARY})
target_include_directories(symcryptengine PUBLIC ../inc)
target_include_directories(symcryptengine PRIVATE ../src)
target_include_directories (symcryptengine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
install(TARGETS symcryptengine
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})