Skip to content

Commit

Permalink
wolfCrypt CSharp Wrapper:
Browse files Browse the repository at this point in the history
* Adds RNG, ECC(ECIES and ECDHE), RSA, ED25519/Curve25519, AES-GCM, and Hashing to the CSharp wrapper.
* Adds GitHub action for building the CSharp wrapper solution and running wolfCrypt test and a TLS server/client example.
* Adds "new" API's for wolfCrypt for platforms that cannot tolerate the structs directly.
* Fixes for several scan-build warnings.
  • Loading branch information
aidangarske authored and dgarske committed Sep 24, 2024
1 parent 72711b4 commit 5fd4880
Show file tree
Hide file tree
Showing 45 changed files with 5,414 additions and 559 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/win-csharp-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Windows CSharp Build Test

on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]

jobs:
build:

runs-on: windows-latest

# This should be a safe limit for the tests to run.
timeout-minutes: 6

env:
# Path to the solution file relative to the root of the project.
SOLUTION_FILE_PATH: wolfssl\wrapper\CSharp\wolfSSL_CSharp.sln

# Configuration type to build.
# You can convert this to a build matrix if you need coverage of multiple configuration types.
# https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
BUILD_CONFIGURATION: Debug
BUILD_PLATFORM: x64

steps:
- name: Pull wolfssl
uses: actions/checkout@master
with:
repository: wolfssl/wolfssl
path: wolfssl

- name: Create FIPS stub files (autogen)
working-directory: wolfssl
run: |
echo $null >> wolfcrypt\src\fips.c
echo $null >> wolfcrypt\src\fips_test.c
echo $null >> wolfcrypt\src\wolfcrypt_first.c
echo $null >> wolfcrypt\src\wolfcrypt_last.c
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1

- name: Build
working-directory: ${{env.GITHUB_WORKSPACE}}
# Add additional options to the MSBuild command line here (like platform or verbosity level).
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
run: msbuild /m /p:PlatformToolset=v142 /p:Platform=${{env.BUILD_PLATFORM}} /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}

- name: Run wolfCrypt test
working-directory: ${{env.GITHUB_WORKSPACE}}wolfssl\wrapper\CSharp\Debug\x64\
run: ./wolfCrypt-test.exe

- name: Run wolfSSL client/server example
working-directory: ${{env.GITHUB_WORKSPACE}}wolfssl\wrapper\CSharp\Debug\x64\
run: ./wolfSSL-TLS-Server.exe && sleep 1 & ./wolfSSL-TLS-Client.exe
4 changes: 2 additions & 2 deletions mcapi/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ enum {
typedef struct CRYPT_AES_CTX {
/* big enough to hold internal, but check on init */
#ifdef WOLF_PRIVATE_KEY_ID
int holder[110];
int holder[114];
#else
int holder[92];
int holder[96];
#endif
} CRYPT_AES_CTX;

Expand Down
4 changes: 2 additions & 2 deletions src/pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
int ret = 0;
int paddingSz = 0;
word32 idx;
word32 cipherInfoSz;
word32 cipherInfoSz = 0;
#ifdef WOLFSSL_SMALL_STACK
EncryptedInfo* info = NULL;
#else
Expand Down Expand Up @@ -3300,7 +3300,7 @@ static int wolfssl_rsa_generate_key_native(WOLFSSL_RSA* rsa, int bits,
#endif
int initTmpRng = 0;
WC_RNG* rng = NULL;
long en;
long en = 0;
#endif

(void)cb;
Expand Down
11 changes: 7 additions & 4 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -16119,11 +16119,14 @@ long wolfSSL_set_options(WOLFSSL* ssl, long op)
else {
/* Only preserve overlapping suites */
Suites tmpSuites;
word16 in, out, haveECDSAsig = 0;
word16 haveStaticECC = ssl->options.haveStaticECC;
word16 in, out;
word16 haveECDSAsig, haveStaticECC;
#ifdef NO_RSA
haveECDSAsig = 1;
haveStaticECC = 1;
#else
haveECDSAsig = 0;
haveStaticECC = ssl->options.haveStaticECC;
#endif
XMEMSET(&tmpSuites, 0, sizeof(Suites));
/* Get all possible ciphers and sigalgs for the version. Following
Expand Down Expand Up @@ -21928,9 +21931,9 @@ int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names,
#endif /* HAVE_SUPPORTED_CURVES */
}

if (ssl)
if (ssl != NULL)
ssl->disabledCurves = disabled;
else
else if (ctx != NULL)
ctx->disabledCurves = disabled;
ret = WOLFSSL_SUCCESS;

Expand Down
9 changes: 5 additions & 4 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -27659,7 +27659,7 @@ static int test_wc_EccPrivateKeyToDer(void)
byte output[ONEK_BUF];
ecc_key eccKey;
WC_RNG rng;
word32 inLen;
word32 inLen = 0;
word32 outLen = 0;
int ret;

Expand All @@ -27675,12 +27675,13 @@ static int test_wc_EccPrivateKeyToDer(void)
#endif
ExpectIntEQ(ret, 0);

inLen = (word32)sizeof(output);
/* Bad Cases */
ExpectIntEQ(wc_EccPrivateKeyToDer(NULL, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_EccPrivateKeyToDer(NULL, output, inLen), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_EccPrivateKeyToDer(&eccKey, NULL, inLen), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
inLen = wc_EccPrivateKeyToDer(&eccKey, NULL, 0);
ExpectIntGT(inLen, 0);
ExpectIntEQ(wc_EccPrivateKeyToDer(&eccKey, output, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

/* Good Case */
ExpectIntGT(outLen = (word32)wc_EccPrivateKeyToDer(&eccKey, output, inLen), 0);

Expand Down Expand Up @@ -51708,7 +51709,7 @@ static int test_wolfSSL_ASN1_INTEGER(void)
ASN1_INTEGER_free(a);
a = NULL;

p = longDer;
p = invalidLenDer;
ExpectNull(d2i_ASN1_INTEGER(NULL, &p, sizeof(invalidLenDer)));

p = longDer;
Expand Down
31 changes: 30 additions & 1 deletion wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -10530,6 +10530,7 @@ int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
if (ret == 0)
ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
authTag, authTagSz, authIn, authInSz);
aes->isAllocated = 0;
wc_AesFree(aes);
}
ForceZero(aes, sizeof *aes);
Expand Down Expand Up @@ -10571,6 +10572,8 @@ int wc_GmacVerify(const byte* key, word32 keySz,
if (ret == 0)
ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
authTag, authTagSz, authIn, authInSz);

aes->isAllocated = 0;
wc_AesFree(aes);
}
ForceZero(aes, sizeof *aes);
Expand Down Expand Up @@ -11287,6 +11290,20 @@ int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,

#endif /* HAVE_AESCCM */

Aes* wc_AesNew(void* heap, int devId)
{
Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
if (aes != NULL) {
if (wc_AesInit(aes, heap, devId) != 0) {
XFREE(aes, heap, DYNAMIC_TYPE_AES);
aes = NULL;
}
else {
aes->isAllocated = 1;
}
}
return aes;
}

/* Initialize Aes for use with async hardware */
int wc_AesInit(Aes* aes, void* heap, int devId)
Expand All @@ -11296,6 +11313,7 @@ int wc_AesInit(Aes* aes, void* heap, int devId)
if (aes == NULL)
return BAD_FUNC_ARG;

aes->isAllocated = 0;
aes->heap = heap;
aes->rounds = 0;

Expand Down Expand Up @@ -11421,8 +11439,13 @@ int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
/* Free Aes from use with async hardware */
void wc_AesFree(Aes* aes)
{
if (aes == NULL)
unsigned int isAllocated;

if (aes == NULL) {
return;
}

isAllocated = aes->isAllocated;

#ifdef WC_DEBUG_CIPHER_LIFECYCLE
(void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
Expand Down Expand Up @@ -11490,6 +11513,11 @@ void wc_AesFree(Aes* aes)
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(aes, sizeof(Aes));
#endif

if (isAllocated) {
XFREE(aes, aes->heap, DYNAMIC_TYPE_AES);
}

}

int wc_AesGetKeySize(Aes* aes, word32* keySize)
Expand Down Expand Up @@ -14023,6 +14051,7 @@ static WARN_UNUSED_RESULT int AesSivCipher(
}
}

aes->isAllocated = 0;
wc_AesFree(aes);
#ifdef WOLFSSL_SMALL_STACK
XFREE(aes, NULL, DYNAMIC_TYPE_AES);
Expand Down
24 changes: 13 additions & 11 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -22604,7 +22604,7 @@ static int DecodeCertReq(DecodedCert* cert, int* criticalExt)
{
DECL_ASNGETDATA(dataASN, certReqASN_Length);
int ret = 0;
byte version;
byte version = 0;
word32 idx;

CALLOC_ASNGETDATA(dataASN, certReqASN_Length, ret, cert->heap);
Expand Down Expand Up @@ -23497,7 +23497,7 @@ int wc_CertGetPubKey(const byte* cert, word32 certSz,
const unsigned char** pubKey, word32* pubKeySz)
{
int ret = 0;
int l;
int l = 0;
word32 o = 0;
int i;
static DecodeInstr ops[] = {
Expand Down Expand Up @@ -27761,7 +27761,7 @@ static int SetCertificatePolicies(byte *output,
byte oid[MAX_OID_SZ];
word32 oidSz;
word32 sz = 0;
int piSz;
int piSz = 0;

if ((input == NULL) || (nb_certpol > MAX_CERTPOL_NB)) {
ret = BAD_FUNC_ARG;
Expand Down Expand Up @@ -30294,8 +30294,8 @@ int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
return (int)(idx + seqSz);
#else
DECL_ASNSETDATA(dataASN, sigASN_Length);
word32 seqSz;
int sz;
word32 seqSz = 0;
int sz = 0;
int ret = 0;

CALLOC_ASNSETDATA(dataASN, sigASN_Length, ret, NULL);
Expand Down Expand Up @@ -34876,6 +34876,7 @@ int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,

/* Write a Private ecc key, including public to DER format,
* length on success else < 0 */
/* Note: use wc_EccKeyDerSize to get length only */
WOLFSSL_ABI
int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
{
Expand All @@ -34887,10 +34888,7 @@ int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
int wc_EccKeyDerSize(ecc_key* key, int pub)
{
word32 sz = 0;
int ret;

ret = wc_BuildEccKeyDer(key, NULL, &sz, pub, 1);

int ret = wc_BuildEccKeyDer(key, NULL, &sz, pub, 1);
if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
return ret;
}
Expand All @@ -34901,7 +34899,11 @@ int wc_EccKeyDerSize(ecc_key* key, int pub)
* length on success else < 0 */
int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
{
return wc_BuildEccKeyDer(key, output, &inLen, 0, 1);
int ret = wc_BuildEccKeyDer(key, output, &inLen, 0, 1);
if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
return (int)inLen;
}
return ret;
}

#ifdef HAVE_PKCS8
Expand Down Expand Up @@ -35443,7 +35445,7 @@ int SetAsymKeyDer(const byte* privKey, word32 privKeyLen,
word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0, sz;
#else
DECL_ASNSETDATA(dataASN, edKeyASN_Length);
int sz;
int sz = 0;
#endif

/* validate parameters */
Expand Down
28 changes: 28 additions & 0 deletions wolfcrypt/src/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,22 @@ int wc_curve25519_import_private_ex(const byte* priv, word32 privSz,

#endif /* HAVE_CURVE25519_KEY_IMPORT */

curve25519_key* wc_curve25519_new(void* heap, int devId)
{
curve25519_key* key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), heap,
DYNAMIC_TYPE_CURVE25519);
if (key != NULL) {
if (wc_curve25519_init_ex(key, heap, devId) != 0) {
XFREE(key, heap, DYNAMIC_TYPE_CURVE25519);
key = NULL;
}
else {
key->isAllocated = 1;
}
}
return key;
}

int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId)
{
if (key == NULL)
Expand Down Expand Up @@ -691,9 +707,15 @@ int wc_curve25519_init(curve25519_key* key)
/* Clean the memory of a key */
void wc_curve25519_free(curve25519_key* key)
{
int isAllocated = 0;
void* heap;

if (key == NULL)
return;

isAllocated = key->isAllocated;
heap = key->heap;

#ifdef WOLFSSL_SE050
se050_curve25519_free_key(key);
#endif
Expand All @@ -703,9 +725,15 @@ void wc_curve25519_free(curve25519_key* key)
XMEMSET(&key->p, 0, sizeof(key->p));
key->pubSet = 0;
key->privSet = 0;

#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(key, sizeof(curve25519_key));
#endif

if (isAllocated) {
XFREE(key, heap, DYNAMIC_TYPE_CURVE25519);
(void)heap;
}
}

/* get key size */
Expand Down
Loading

0 comments on commit 5fd4880

Please sign in to comment.