Skip to content

Commit

Permalink
ECIES fixes and max ECIES size chagne for test and `ecc_ctx_kdf_salt_…
Browse files Browse the repository at this point in the history
…test`
  • Loading branch information
aidangarske committed Sep 12, 2024
1 parent 4b282ff commit 3bbb22a
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 112 deletions.
21 changes: 12 additions & 9 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -33461,16 +33461,19 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void)
(defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_256))

#if ((! defined(HAVE_FIPS)) || FIPS_VERSION_GE(5,3))
/* maximum encrypted message:
* msgSz (14) + pad (2) + pubKeySz(1+66*2) + ivSz(16) + digestSz(32) = 197 */
#define MAX_ECIES_TEST_SZ 200
static wc_test_ret_t ecc_ctx_kdf_salt_test(WC_RNG* rng, ecc_key* a, ecc_key* b)
{
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
byte* plaintext;
byte* encrypted;
byte* decrypted;
#else
byte plaintext[128];
byte encrypted[128];
byte decrypted[128];
byte plaintext[MAX_ECIES_TEST_SZ];
byte encrypted[MAX_ECIES_TEST_SZ];
byte decrypted[MAX_ECIES_TEST_SZ];
#endif
ecEncCtx* aCtx = NULL;
ecEncCtx* bCtx = NULL;
Expand All @@ -33479,13 +33482,13 @@ static wc_test_ret_t ecc_ctx_kdf_salt_test(WC_RNG* rng, ecc_key* a, ecc_key* b)
wc_test_ret_t ret = 0;
static const char message[] = "Hello wolfSSL!";
word32 plaintextLen;
word32 encryptLen = 128;
word32 decryptLen = 128;
word32 encryptLen = MAX_ECIES_TEST_SZ;
word32 decryptLen = MAX_ECIES_TEST_SZ;

#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
plaintext = XMALLOC(128, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
encrypted = XMALLOC(128, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
decrypted = XMALLOC(128, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
plaintext = XMALLOC(MAX_ECIES_TEST_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
encrypted = XMALLOC(MAX_ECIES_TEST_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
decrypted = XMALLOC(MAX_ECIES_TEST_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif

wc_ecc_free(a);
Expand Down Expand Up @@ -33534,7 +33537,7 @@ static wc_test_ret_t ecc_ctx_kdf_salt_test(WC_RNG* rng, ecc_key* a, ecc_key* b)
ret = 10473;
}

XMEMSET(plaintext, 0, 128);
XMEMSET(plaintext, 0, sizeof(plaintext));
XSTRLCPY((char *)plaintext, message, sizeof plaintext);
plaintextLen = (((word32)XSTRLEN(message) + AES_BLOCK_SIZE - 1) /
AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
Expand Down
3 changes: 2 additions & 1 deletion wolfssl/wolfcrypt/ed25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ struct ed25519_key {
wc_Sha512 sha;
unsigned int sha_clean_flag : 1;
#endif
unsigned int isAllocated : 1; /* flag indicates if structure was allocated */
/* flag indicates if structure was allocated */
unsigned int isAllocated : 1;
};

#ifndef WC_ED25519KEY_TYPE_DEFINED
Expand Down
3 changes: 2 additions & 1 deletion wolfssl/wolfcrypt/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ WOLFSSL_API int wc_Hash_ex(enum wc_HashType hash_type,
byte* hash, word32 hash_len, void* heap, int devId);

/* generic hash operation wrappers */
WOLFSSL_API wc_HashAlg* wc_HashNew(enum wc_HashType type, void* heap, int devId);
WOLFSSL_API wc_HashAlg* wc_HashNew(enum wc_HashType type, void* heap,
int devId);
WOLFSSL_API int wc_HashInit_ex(wc_HashAlg* hash, enum wc_HashType type,
void* heap, int devId);
WOLFSSL_API int wc_HashInit(wc_HashAlg* hash, enum wc_HashType type);
Expand Down
175 changes: 89 additions & 86 deletions wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -633,105 +633,106 @@ private static void hash_test(uint hashType)
}
} /* END hash_test */

private static void ecies_test()
{
const int keySize = 32;
const int bufferSize = 128;
const string message = "Hello wolfSSL!";
byte[] salt = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

IntPtr a = IntPtr.Zero;
IntPtr b = IntPtr.Zero;
IntPtr aCtx = IntPtr.Zero;
IntPtr bCtx = IntPtr.Zero;
IntPtr rng = IntPtr.Zero;
IntPtr heap = IntPtr.Zero;

byte[] plaintext = new byte[bufferSize];
byte[] encrypted = new byte[bufferSize];
byte[] decrypted = new byte[bufferSize];

try
private static void ecies_test(int keySize)
{
Console.WriteLine($"\nStarting ecies test for {keySize} key size...");
/* maximum encrypted message:
* msgSz (14) + pad (2) + pubKeySz(1+66*2) + ivSz(16) + digestSz(32) = 197 */
int bufferSize = wolfcrypt.MAX_ECIES_TEST_SZ;
const string message = "Hello wolfSSL!";
byte[] salt = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

IntPtr a = IntPtr.Zero;
IntPtr b = IntPtr.Zero;
IntPtr aCtx = IntPtr.Zero;
IntPtr bCtx = IntPtr.Zero;
IntPtr rng = IntPtr.Zero;
IntPtr heap = IntPtr.Zero;

/* Create a new RNG context */
rng = wolfcrypt.RandomNew();
if (rng == IntPtr.Zero)
{
throw new Exception("RNG initialization failed.");
}
byte[] plaintext = new byte[bufferSize];
byte[] encrypted = new byte[bufferSize];
byte[] decrypted = new byte[bufferSize];

/* Initialize keys */
a = wolfcrypt.EccMakeKey(keySize);
b = wolfcrypt.EccMakeKey(keySize);
if (a == IntPtr.Zero || b == IntPtr.Zero)
try
{
throw new Exception("Key generation failed.");
}
Console.WriteLine("ECC key generation passed.");
Console.WriteLine($"\nStarting ECIES test for {keySize} byte key size...");

/* Create ECIES contexts for encryption and decryption */
aCtx = wolfcrypt.EciesNewCtx((int)wolfcrypt.ecFlags.REQ_RESP_CLIENT, rng, heap);
bCtx = wolfcrypt.EciesNewCtx((int)wolfcrypt.ecFlags.REQ_RESP_SERVER, rng, heap);
if (aCtx == IntPtr.Zero || bCtx == IntPtr.Zero)
{
throw new Exception("Context creation failed.");
}
Console.WriteLine("ECC context creation passed.");
/* Create a new RNG context */
rng = wolfcrypt.RandomNew();
if (rng == IntPtr.Zero)
{
throw new Exception("RNG initialization failed.");
}

/* Set KDF salt */
if (wolfcrypt.EciesSetKdfSalt(aCtx, salt) != 0 ||
wolfcrypt.EciesSetKdfSalt(bCtx, salt) != 0)
{
throw new Exception("Failed to set KDF salt.");
}
Console.WriteLine("KDF salt setup passed.");
/* Initialize keys */
a = wolfcrypt.EccMakeKey(keySize);
b = wolfcrypt.EccMakeKey(keySize);
if (a == IntPtr.Zero || b == IntPtr.Zero)
{
throw new Exception("Key generation failed.");
}
Console.WriteLine("ECC key generation passed.");

/* Prepare plaintext */
Array.Clear(plaintext, 0, plaintext.Length);
Array.Copy(Encoding.ASCII.GetBytes(message), plaintext, message.Length);
/* Pad to block size */
int plaintextLen = ((message.Length + (wolfcrypt.AES_BLOCK_SIZE - 1)) /
wolfcrypt.AES_BLOCK_SIZE) * wolfcrypt.AES_BLOCK_SIZE;
/* Create ECIES contexts for encryption and decryption */
aCtx = wolfcrypt.EciesNewCtx((int)wolfcrypt.ecFlags.REQ_RESP_CLIENT, rng, heap);
bCtx = wolfcrypt.EciesNewCtx((int)wolfcrypt.ecFlags.REQ_RESP_SERVER, rng, heap);
if (aCtx == IntPtr.Zero || bCtx == IntPtr.Zero)
{
throw new Exception("Context creation failed.");
}
Console.WriteLine("ECC context creation passed.");

/* Encrypt message */
int ret = wolfcrypt.EciesEncrypt(a, b, plaintext, (uint)plaintextLen, encrypted, aCtx);
if (ret < 0)
{
throw new Exception("Encryption failed.");
}
/* Set KDF salt */
if (wolfcrypt.EciesSetKdfSalt(aCtx, salt) != 0 ||
wolfcrypt.EciesSetKdfSalt(bCtx, salt) != 0)
{
throw new Exception("Failed to set KDF salt.");
}
Console.WriteLine("KDF salt setup passed.");

/* Prepare plaintext */
Array.Clear(plaintext, 0, plaintext.Length);
Array.Copy(Encoding.ASCII.GetBytes(message), plaintext, message.Length);
/* Pad to block size */
int plaintextLen = ((message.Length + (wolfcrypt.AES_BLOCK_SIZE - 1)) /
wolfcrypt.AES_BLOCK_SIZE) * wolfcrypt.AES_BLOCK_SIZE;

/* Encrypt message */
int ret = wolfcrypt.EciesEncrypt(a, b, plaintext, (uint)plaintextLen, encrypted, aCtx);
if (ret < 0)
{
throw new Exception("Encryption failed.");
}

int encryptedLen = ret;
Console.WriteLine("ECC encryption passed.");
int encryptedLen = ret;
Console.WriteLine("ECC encryption passed.");

/* Decrypt message */
ret = wolfcrypt.EciesDecrypt(b, a, encrypted, (uint)encryptedLen, decrypted, bCtx);
if (ret < 0)
{
throw new Exception("Decryption failed.");
}
/* Decrypt message */
ret = wolfcrypt.EciesDecrypt(b, a, encrypted, (uint)encryptedLen, decrypted, bCtx);
if (ret < 0)
{
throw new Exception("Decryption failed.");
}

int decryptedLen = ret;
Console.WriteLine("ECC decryption passed.");
int decryptedLen = ret;
Console.WriteLine("ECC decryption passed.");

/* Compare decrypted text to original plaintext */
if (!wolfcrypt.ByteArrayVerify(plaintext, decrypted))
/* Compare decrypted text to original plaintext */
if (!wolfcrypt.ByteArrayVerify(plaintext, decrypted))
{
throw new Exception("Decrypted text does not match original plaintext.");
}
Console.WriteLine("Decrypted text matches original plaintext.");
}
finally
{
throw new Exception("Decrypted text does not match original plaintext.");
/* Cleanup key and context */
if (a != IntPtr.Zero) wolfcrypt.EccFreeKey(a);
if (b != IntPtr.Zero) wolfcrypt.EccFreeKey(b);
if (aCtx != IntPtr.Zero) wolfcrypt.EciesFreeCtx(aCtx);
if (bCtx != IntPtr.Zero) wolfcrypt.EciesFreeCtx(bCtx);
if (rng != IntPtr.Zero) wolfcrypt.RandomFree(rng);
}
Console.WriteLine("Decrypted text matches original plaintext.");
}
finally
{
/* Cleanup key and context */
if (a != IntPtr.Zero) wolfcrypt.EccFreeKey(a);
if (b != IntPtr.Zero) wolfcrypt.EccFreeKey(b);
if (aCtx != IntPtr.Zero) wolfcrypt.EciesFreeCtx(aCtx);
if (bCtx != IntPtr.Zero) wolfcrypt.EciesFreeCtx(bCtx);
if (rng != IntPtr.Zero) wolfcrypt.RandomFree(rng);
}
} /* END ecies_test */
} /* END ecies_test */

public static void standard_log(int lvl, StringBuilder msg)
{
Expand Down Expand Up @@ -770,7 +771,9 @@ public static void Main(string[] args)
hash_test((uint)wolfcrypt.hashType.WC_HASH_TYPE_SHA512); /* SHA-512 HASH test */
hash_test((uint)wolfcrypt.hashType.WC_HASH_TYPE_SHA3_256); /* SHA3_256 HASH test */

ecies_test(); /* ECIES test */
ecies_test(32); /* ECIES test (32 byte key size) */
ecies_test(48); /* ECIES test (48 byte key size) */
ecies_test(66); /* ECIES test (66 byte key size) */

wolfcrypt.Cleanup();

Expand Down
39 changes: 24 additions & 15 deletions wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ public class wolfcrypt
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private static extern int wc_EccPrivateKeyToDer(IntPtr key, byte[] output, uint inLen);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private static extern int wc_EccPublicKeyToDer(IntPtr key, byte[] output, uint inLen, int with_AlgCurve);


private static extern int wc_EccPublicKeyToDer(IntPtr key, byte[] output, uint inLen, int with_AlgCurve);


/********************************
* ECIES
*/
Expand Down Expand Up @@ -302,6 +302,7 @@ private static void log(int lvl, string msg)
public static readonly int OTHER_LOG = 4;
public static readonly int INVALID_DEVID = -2;
public static readonly int ECC_MAX_SIG_SIZE = 141; /* ECC max sig size */
public static readonly int MAX_ECIES_TEST_SZ = 200; /* ECIES max sig size */
public static readonly int ED25519_SIG_SIZE = 64; /* ED25519 pub + priv */
public static readonly int ED25519_KEY_SIZE = 32; /* Private key only */
public static readonly int ED25519_PUB_KEY_SIZE = 32; /* Compressed public */
Expand Down Expand Up @@ -841,42 +842,50 @@ public static int EciesSetAlgo(IntPtr ctx, byte encAlgo, byte kdfAlgo, byte macA
}

/// <summary>
/// Get the ECIES own salt.
/// Get the ECIES own salt as a byte array.
/// </summary>
/// <param name="ctx">Pointer to the ECIES context.</param>
/// <returns>Pointer to the own salt, or IntPtr.Zero if there is an error.</returns>
public static IntPtr EciesGetOwnSalt(IntPtr ctx)
/// <returns>Byte array representing the own salt, or null if there is an error.</returns>
public static byte[] EciesGetOwnSalt(IntPtr ctx)
{
IntPtr saltPtr = IntPtr.Zero;
byte[] salt = null;

try
{
/* Check */
/* Check ctx */
if (ctx == IntPtr.Zero)
{
log(ERROR_LOG, "Invalid ECIES context pointer.");
return IntPtr.Zero;
return null;
}

/* Retrieve own salt */
/* Get own salt */
saltPtr = wc_ecc_ctx_get_own_salt(ctx);

if (saltPtr == IntPtr.Zero)
{
log(ERROR_LOG, "Failed to get own salt.");
return IntPtr.Zero;
return null;
}

/* Allocate salt size and copy to byte array */
salt = new byte[(int)ecKeySize.EXCHANGE_SALT_SZ];
Marshal.Copy(saltPtr, salt, 0, (int)ecKeySize.EXCHANGE_SALT_SZ);
}
catch (Exception e)
{
log(ERROR_LOG, "ECIES get own salt exception: " + e.ToString());
saltPtr = IntPtr.Zero;
return null;
}
finally
{
/* Cleanup */
if (saltPtr != IntPtr.Zero) Marshal.FreeHGlobal(saltPtr);
}

return saltPtr;
return salt;
}


/// <summary>
/// Set the peer salt for the ECIES context.
/// </summary>
Expand Down Expand Up @@ -1181,7 +1190,7 @@ public enum ecMacAlgo {
ecHMAC_SHA1 = 2
}

public enum ecKeySizea {
public enum ecKeySize {
KEY_SIZE_128 = 16,
KEY_SIZE_256 = 32,
IV_SIZE_64 = 8,
Expand Down

0 comments on commit 3bbb22a

Please sign in to comment.