aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--include/noscrypt.h72
-rw-r--r--src/nc-crypto.c41
-rw-r--r--src/nc-crypto.h10
-rw-r--r--src/noscrypt.c233
-rw-r--r--tests/test.c160
6 files changed, 426 insertions, 92 deletions
diff --git a/README.md b/README.md
index e351cb2..ebbb9f7 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,7 @@ The following table lists the supported platforms and cryptography libraries tha
GitHub is simply a mirror for my projects. Extended documentation, pre-compiled binaries and source code bundles are always available on my website, along with PGP signatures and checksums.
- **[Documentation](https://www.vaughnnugent.com/resources/software/articles?tags=docs,_noscrypt)**
-- **[Signed builds and sourcecode ](https://www.vaughnnugent.com/resources/software/modules/noscrypt)**
+- **[Signed builds and sourc ecode](https://www.vaughnnugent.com/resources/software/modules/noscrypt)**
### Getting the package
There are 3 ways to get the source code to build this project.
diff --git a/include/noscrypt.h b/include/noscrypt.h
index cdc74fe..f408dfc 100644
--- a/include/noscrypt.h
+++ b/include/noscrypt.h
@@ -77,7 +77,8 @@ extern "C" {
#define NC_HMAC_KEY_SIZE 0x20
#define NC_ENCRYPTION_MAC_SIZE 0x20
#define NC_MESSAGE_KEY_SIZE NIP44_MESSAGE_KEY_SIZE
-#define NC_NIP04_AES_IV_SIZE 0x10 /* AES IV size is 16 bytes (block size) */
+#define NC_NIP04_AES_IV_SIZE 0x10 /* AES IV size is 16 bytes (aka cipher block size) */
+#define NC_NIP04_AES_KEY_SIZE 0x20 /* AES 256 key size */
/*
* From spec
@@ -112,6 +113,20 @@ extern "C" {
#define E_VERSION_NOT_SUPPORTED -6
+/*
+* ENCRYPTION ALTERATION PROPERTEIS
+*
+* Codes for assigning values to an NCEncryptionArgs
+* structure.
+*/
+
+#define NC_ENC_SET_VERSION 0x01
+#define NC_ENC_SET_NIP44_NONCE 0x02
+#define NC_ENC_SET_NIP44_MAC_KEY 0x03
+#define NC_ENC_SET_NIP04_KEY 0x04
+#define NC_ENC_SET_NIP04_IV 0x05
+
+
/* A compressed resul/return value, negative values
are failure, 0 is success and positive values are
defined by the operation.
@@ -149,11 +164,11 @@ data buffers and required nonce used for the stream cipher.
typedef struct nc_encryption_struct {
/* The nonce used for the stream cipher. */
- const uint8_t* nonce32;
+ const uint8_t* nonceData;
/* Writes the hmac key to the buffer during encryption events.
Set to NULL on decryption */
- uint8_t* hmacKeyOut32;
+ uint8_t* keyData;
/* The input data buffer to encrypt/decrypt */
const uint8_t* inputData;
@@ -578,6 +593,57 @@ NC_EXPORT NCResult NCComputeMac(
uint8_t hmacOut[NC_ENCRYPTION_MAC_SIZE]
);
+
+/*
+* A special function that configures custom properties on
+* the NCEncryptionArgs structure for a given operation.
+* @param args A pointer to the encryption arguments structure
+* @param property The ID property to set
+* @param value The value to set the property to as a 32-bit integer
+* @return NC_SUCCESS if the operation was successful, otherwise an error code. Use NCParseErrorCode to
+* the error code and positional argument that caused the error.
+*/
+NC_EXPORT NCResult NCSetEncryptionProperty(
+ NCEncryptionArgs* args,
+ uint32_t property,
+ uint32_t value
+);
+
+/*
+* A special function that configures custom properties on
+* the NCEncryptionArgs structure for a given operation.
+*
+* @param args A pointer to the encryption arguments structure
+* @param property The ID property to set
+* @param value The value to set the property to as a byte buffer
+* @param valueLen The length of the value buffer
+* @return NC_SUCCESS if the operation was successful, otherwise an error code. Use NCParseErrorCode to
+* the error code and positional argument that caused the error.
+*/
+NC_EXPORT NCResult NCSetEncryptionPropertyEx(
+ NCEncryptionArgs* args,
+ uint32_t property,
+ uint8_t* value,
+ uint32_t valueLen
+);
+
+/*
+* Sets the encryption data buffers for the encryption/decryption
+* operation.
+* @param args A pointer to the encryption arguments structure
+* @param input The input data buffer
+* @param output The output data buffer
+* @param dataSize The size of the data buffers
+* @return NC_SUCCESS if the operation was successful, otherwise an error code. Use NCParseErrorCode to
+* the error code and positional argument that caused the error.
+*/
+NC_EXPORT NCResult NCSetEncryptionData(
+ NCEncryptionArgs* args,
+ const uint8_t* input,
+ uint8_t* output,
+ uint32_t dataSize
+);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/src/nc-crypto.c b/src/nc-crypto.c
index 97b59cb..99c072d 100644
--- a/src/nc-crypto.c
+++ b/src/nc-crypto.c
@@ -41,6 +41,7 @@
* _IMPL_CRYPTO_SHA256_DIGEST standard sha256 digest function
* _IMPL_CRYPTO_SHA256_HKDF_EXPAND hkdf expand function
* _IMPL_CRYPTO_SHA256_HKDF_EXTRACT hkdf extract function
+* _IMPL_AES256_CBC_CRYPT performs an AES 256 CBC encryption/decryption
*
* Macros are used to allow the preprocessor to select the correct implementation
* or raise errors if no implementation is defined.
@@ -49,6 +50,26 @@
* calling function, and should return CSTATUS_OK on success, CSTATUS_FAIL on failure.
*/
+#define UNREFPARAM(x) (void)(x)
+
+_IMPLSTB cstatus_t _dummyAesFunc(
+ const uint8_t key[32],
+ const uint8_t iv[16],
+ const uint8_t* input,
+ uint8_t* output,
+ uint32_t dataSize
+)
+{
+ UNREFPARAM(key);
+ UNREFPARAM(iv);
+ UNREFPARAM(input);
+ UNREFPARAM(output);
+ UNREFPARAM(dataSize);
+
+ return CSTATUS_FAIL;
+}
+
+#define _IMPL_AES256_CBC_CRYPT _dummyAesFunc
/*
* Prioritize embedded builds with mbedtls
@@ -282,3 +303,23 @@ cstatus_t ncCryptoChacha20(
return _IMPL_CHACHA20_CRYPT(key, nonce, input, output, dataSize);
}
+
+cstatus_t ncAes256CBCEncrypt(
+ const uint8_t key[32],
+ const uint8_t iv[16],
+ const uint8_t* input,
+ uint8_t* output,
+ uint32_t dataSize
+)
+{
+ DEBUG_ASSERT2(key != NULL, "Expected key to be non-null")
+ DEBUG_ASSERT2(iv != NULL, "Expected iv to be non-null")
+ DEBUG_ASSERT2(input != NULL, "Expected input to be non-null")
+ DEBUG_ASSERT2(output != NULL, "Expected output to be non-null")
+
+#ifndef _IMPL_AES256_CBC_CRYPT
+ #error "No AES256 CBC encrypt implementation defined"
+#endif /* !_IMPL_AES256_CBC_CRYPT */
+
+ return _IMPL_AES256_CBC_CRYPT(key, iv, input, output, dataSize);
+} \ No newline at end of file
diff --git a/src/nc-crypto.h b/src/nc-crypto.h
index f04ebe0..11da6d3 100644
--- a/src/nc-crypto.h
+++ b/src/nc-crypto.h
@@ -29,6 +29,8 @@
#define CHACHA_NONCE_SIZE 0x0cu /* Size of 12 is set by the cipher spec */
#define CHACHA_KEY_SIZE 0x20u /* Size of 32 is set by the cipher spec */
#define SHA256_DIGEST_SIZE 0x20u /* Size of 32 is set by the cipher spec */
+#define AES_IV_SIZE 0x10u /* CBC IV size matches the AES block size of 128 */
+#define AES_KEY_SIZE 0x20u /* AES 256 key size */
typedef uint8_t cstatus_t;
#define CSTATUS_OK ((cstatus_t)0x01u)
@@ -56,4 +58,12 @@ cstatus_t ncCryptoChacha20(
uint32_t dataSize
);
+cstatus_t ncAes256CBCEncrypt(
+ const uint8_t key[32],
+ const uint8_t iv[16],
+ const uint8_t* input,
+ uint8_t* output,
+ uint32_t dataSize
+);
+
#endif /* !_NC_CRYPTO_H */
diff --git a/src/noscrypt.c b/src/noscrypt.c
index f1aabd4..4254ee2 100644
--- a/src/noscrypt.c
+++ b/src/noscrypt.c
@@ -293,7 +293,7 @@ static _nc_fn_inline cstatus_t _getMessageKey(
return ncCryptoSha256HkdfExpand(&prkSpan, nonce, &okmSpan);
}
-static _nc_fn_inline NCResult _encryptEx(
+static _nc_fn_inline NCResult _encryptNip44Ex(
const NCContext* ctx,
const struct conversation_key* ck,
uint8_t* hmacKey,
@@ -312,7 +312,7 @@ static _nc_fn_inline NCResult _encryptEx(
result = NC_SUCCESS;
- ncSpanInitC(&nonceSpan, args->nonce32, NC_ENCRYPTION_NONCE_SIZE);
+ ncSpanInitC(&nonceSpan, args->nonceData, NC_ENCRYPTION_NONCE_SIZE);
/* Message key will be derrived on every encryption call */
if (_getMessageKey(ck, &nonceSpan, &messageKey) != CSTATUS_OK)
@@ -339,7 +339,7 @@ Cleanup:
return result;
}
-static _nc_fn_inline NCResult _decryptEx(const NCContext* ctx, const struct conversation_key* ck, NCEncryptionArgs* args)
+static _nc_fn_inline NCResult _decryptNip44Ex(const NCContext* ctx, const struct conversation_key* ck, NCEncryptionArgs* args)
{
NCResult result;
cspan_t nonceSpan;
@@ -352,7 +352,7 @@ static _nc_fn_inline NCResult _decryptEx(const NCContext* ctx, const struct conv
result = NC_SUCCESS;
- ncSpanInitC(&nonceSpan, args->nonce32, NC_ENCRYPTION_NONCE_SIZE);
+ ncSpanInitC(&nonceSpan, args->nonceData, NC_ENCRYPTION_NONCE_SIZE);
if (_getMessageKey(ck, &nonceSpan, &messageKey) != CSTATUS_OK)
{
@@ -646,7 +646,6 @@ NC_EXPORT NCResult NC_CC NCVerifyDigest(
return E_INVALID_ARG;
}
- /* Verify the signature */
result = secp256k1_schnorrsig_verify(ctx->secpCtx, sig64, digest32, 32, &xonly);
ZERO_FILL(&xonly, sizeof(xonly));
@@ -679,7 +678,6 @@ NC_EXPORT NCResult NC_CC NCVerifyData(
return E_INVALID_ARG;
}
- /* Verify the freshly computed digest */
return NCVerifyDigest(ctx, pk, digest, sig64);
}
@@ -765,11 +763,23 @@ NC_EXPORT NCResult NC_CC NCEncryptEx(
/* Validte ciphertext/plaintext */
CHECK_INVALID_ARG(args->inputData, 2)
CHECK_INVALID_ARG(args->outputData, 2)
- CHECK_INVALID_ARG(args->nonce32, 2)
- CHECK_INVALID_ARG(args->hmacKeyOut32, 2)
+ CHECK_INVALID_ARG(args->nonceData, 2)
+ CHECK_INVALID_ARG(args->keyData, 2)
CHECK_ARG_RANGE(args->dataSize, NIP44_MIN_ENC_MESSAGE_SIZE, NIP44_MAX_ENC_MESSAGE_SIZE, 2)
- return _encryptEx(ctx, (struct conversation_key*)conversationKey, args->hmacKeyOut32, args);
+ switch (args->version)
+ {
+ /* TODO: Implement nip04 */
+ case NC_ENC_VERSION_NIP04:
+ return E_VERSION_NOT_SUPPORTED;
+
+ case NC_ENC_VERSION_NIP44:
+ return _encryptNip44Ex(ctx, (struct conversation_key*)conversationKey, args->keyData, args);
+
+ default:
+ return E_VERSION_NOT_SUPPORTED;
+ }
+
}
NC_EXPORT NCResult NC_CC NCEncrypt(
@@ -792,34 +802,40 @@ NC_EXPORT NCResult NC_CC NCEncrypt(
/* Validate input/output data */
CHECK_INVALID_ARG(args->inputData, 3)
CHECK_INVALID_ARG(args->outputData, 3)
- CHECK_INVALID_ARG(args->nonce32, 3)
- CHECK_INVALID_ARG(args->hmacKeyOut32, 3)
+ CHECK_INVALID_ARG(args->nonceData, 3)
+ CHECK_INVALID_ARG(args->keyData, 3)
CHECK_ARG_RANGE(args->dataSize, NIP44_MIN_ENC_MESSAGE_SIZE, NIP44_MAX_ENC_MESSAGE_SIZE, 3)
+ result = E_OPERATION_FAILED;
+
switch(args->version)
{
case NC_ENC_VERSION_NIP44:
- break; /* Allow nip44 */
+ {
+ /* Compute the shared point */
+ if ((result = _computeSharedSecret(ctx, sk, pk, &sharedSecret)) != NC_SUCCESS)
+ {
+ goto Cleanup;
+ }
+
+ /* Compute the conversation key from secret and pubkic keys */
+ if ((result = _computeConversationKey(ctx, &sharedSecret, &conversationKey)) != NC_SUCCESS)
+ {
+ goto Cleanup;
+ }
+
+ result = _encryptNip44Ex(ctx, &conversationKey, args->keyData, args);
+ }
+
+ break;
/* At the moment nip04 compatability is not supported */
case NC_ENC_VERSION_NIP04:
default:
- return E_VERSION_NOT_SUPPORTED;
+ result = E_VERSION_NOT_SUPPORTED;
+ break;
}
- /* Compute the shared point */
- if ((result = _computeSharedSecret(ctx, sk, pk, &sharedSecret)) != NC_SUCCESS)
- {
- goto Cleanup;
- }
-
- /* Compute the conversation key from secret and pubkic keys */
- if ((result = _computeConversationKey(ctx, &sharedSecret, &conversationKey)) != NC_SUCCESS)
- {
- goto Cleanup;
- }
-
- result = _encryptEx(ctx, &conversationKey, args->hmacKeyOut32, args);
Cleanup:
/* Clean up sensitive data */
@@ -843,10 +859,18 @@ NC_EXPORT NCResult NC_CC NCDecryptEx(
/* Validte ciphertext/plaintext */
CHECK_INVALID_ARG(args->inputData, 2)
CHECK_INVALID_ARG(args->outputData, 2)
- CHECK_INVALID_ARG(args->nonce32, 2)
+ CHECK_INVALID_ARG(args->nonceData, 2)
CHECK_ARG_RANGE(args->dataSize, NIP44_MIN_ENC_MESSAGE_SIZE, NIP44_MAX_ENC_MESSAGE_SIZE, 2)
- return _decryptEx(ctx, (struct conversation_key*)conversationKey, args);
+ switch (args->version)
+ {
+ case NC_ENC_VERSION_NIP44:
+ return _decryptNip44Ex(ctx, (struct conversation_key*)conversationKey, args);
+
+ case NC_ENC_VERSION_NIP04:
+ default:
+ return E_VERSION_NOT_SUPPORTED;
+ }
}
NC_EXPORT NCResult NC_CC NCDecrypt(
@@ -869,20 +893,34 @@ NC_EXPORT NCResult NC_CC NCDecrypt(
/* Validte ciphertext/plaintext */
CHECK_INVALID_ARG(args->inputData, 3)
CHECK_INVALID_ARG(args->outputData, 3)
- CHECK_INVALID_ARG(args->nonce32, 3)
+ CHECK_INVALID_ARG(args->nonceData, 3)
CHECK_ARG_RANGE(args->dataSize, NIP44_MIN_ENC_MESSAGE_SIZE, NIP44_MAX_ENC_MESSAGE_SIZE, 3)
- if ((result = _computeSharedSecret(ctx, sk, pk, &sharedSecret)) != NC_SUCCESS)
- {
- goto Cleanup;
- }
+ result = E_OPERATION_FAILED;
- if ((result = _computeConversationKey(ctx, &sharedSecret, &conversationKey)) != NC_SUCCESS)
+ switch (args->version)
{
- goto Cleanup;
- }
+ case NC_ENC_VERSION_NIP44:
+ {
+ if ((result = _computeSharedSecret(ctx, sk, pk, &sharedSecret)) != NC_SUCCESS)
+ {
+ goto Cleanup;
+ }
+
+ if ((result = _computeConversationKey(ctx, &sharedSecret, &conversationKey)) != NC_SUCCESS)
+ {
+ goto Cleanup;
+ }
- result = _decryptEx(ctx, &conversationKey, args);
+ result = _decryptNip44Ex(ctx, &conversationKey, args);
+ }
+ break;
+
+ case NC_ENC_VERSION_NIP04:
+ default:
+ result = E_VERSION_NOT_SUPPORTED;
+ break;
+ }
Cleanup:
/* Clean up sensitive data */
@@ -978,4 +1016,125 @@ Cleanup:
ZERO_FILL(&conversationKey, sizeof(conversationKey));
return result;
+}
+
+#define ENSURE_ENC_MODE(args, mode) if(args->version != mode) return E_VERSION_NOT_SUPPORTED;
+
+NC_EXPORT NCResult NCSetEncryptionPropertyEx(
+ NCEncryptionArgs* args,
+ uint32_t property,
+ uint8_t* value,
+ uint32_t valueLen
+)
+{
+
+ CHECK_NULL_ARG(args, 0)
+ CHECK_NULL_ARG(value, 2)
+
+ switch (property)
+ {
+ case NC_ENC_SET_VERSION:
+
+ /* Ensure version is proper length */
+ CHECK_ARG_RANGE(valueLen, sizeof(uint32_t), sizeof(uint32_t), 2)
+
+ args->version = *((uint32_t*)value);
+
+ return NC_SUCCESS;
+
+ case NC_ENC_SET_NIP04_IV:
+ /*
+ * The safest way to store the nip04 IV is in the nonce
+ * field. An IV is essentially a nonce. A secure random
+ * number used to encrypt the first block of a CBC chain.
+ */
+
+ CHECK_ARG_RANGE(valueLen, AES_IV_SIZE, UINT32_MAX, 3)
+
+ ENSURE_ENC_MODE(args, NC_ENC_VERSION_NIP04)
+
+ args->nonceData = value;
+
+ return NC_SUCCESS;
+
+
+ case NC_ENC_SET_NIP04_KEY:
+ /*
+ * The AES key is stored in the hmac key field, since
+ * it won't be used for the operating and should be the same size
+ * as the hmac key.
+ */
+
+ CHECK_ARG_RANGE(valueLen, AES_KEY_SIZE, UINT32_MAX, 3)
+
+ ENSURE_ENC_MODE(args, NC_ENC_VERSION_NIP04)
+
+ args->keyData = value;
+
+ return NC_SUCCESS;
+
+ case NC_ENC_SET_NIP44_NONCE:
+
+ /* Nonce buffer must be at least the size, max doesnt matter */
+ CHECK_ARG_RANGE(valueLen, NC_ENCRYPTION_NONCE_SIZE, UINT32_MAX, 3)
+
+ /* Nonce is only used in nip44 mode */
+ ENSURE_ENC_MODE(args, NC_ENC_VERSION_NIP44)
+
+ args->nonceData = value;
+
+ return NC_SUCCESS;
+
+ case NC_ENC_SET_NIP44_MAC_KEY:
+
+ /* The maximum size of the buffer doesn't matter as long as its larger than the key size */
+ CHECK_ARG_RANGE(valueLen, NC_HMAC_KEY_SIZE, UINT32_MAX, 3)
+
+ /* Mac key is only used in nip44 mode */
+ ENSURE_ENC_MODE(args, NC_ENC_VERSION_NIP44)
+
+ /*
+ * During encryption the key data buffer is used
+ * to write the hmac hey used for MAC computation
+ * operations.
+ */
+ args->keyData = value;
+
+ return NC_SUCCESS;
+ }
+
+ return E_INVALID_ARG;
+}
+
+NC_EXPORT NCResult NCSetEncryptionProperty(
+ NCEncryptionArgs* args,
+ uint32_t property,
+ uint32_t value
+)
+{
+ return NCSetEncryptionPropertyEx(
+ args,
+ property,
+ (uint8_t*)&value,
+ sizeof(uint32_t)
+ );
+}
+
+NC_EXPORT NCResult NCSetEncryptionData(
+ NCEncryptionArgs* args,
+ const uint8_t* input,
+ uint8_t* output,
+ uint32_t dataSize
+)
+{
+ CHECK_NULL_ARG(args, 0)
+ CHECK_NULL_ARG(input, 1)
+ CHECK_NULL_ARG(output, 2)
+ CHECK_ARG_RANGE(dataSize, NIP44_MIN_ENC_MESSAGE_SIZE, NIP44_MAX_ENC_MESSAGE_SIZE, 3)
+
+ args->inputData = input;
+ args->outputData = output;
+ args->dataSize = dataSize;
+
+ return NC_SUCCESS;
} \ No newline at end of file
diff --git a/tests/test.c b/tests/test.c
index 084ac13..6e3851e 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -44,7 +44,7 @@
/*Prints a string literal to the console*/
#define PRINTL(x) puts(x); puts("\n");
-#define ENSURE(x) if(!(x)) { puts("Assumption failed!\n"); return 1; }
+#define ENSURE(x) if(!(x)) { printf("Test assumption failed on line %d\n", __LINE__); return 1; }
#define TEST(x, expected) printf("\tTesting %s\n", #x); if(((long)x) != ((long)expected)) \
{ printf("FAILED: Expected %ld but got %ld @ callsite %s. Line: %d \n", ((long)expected), ((long)x), #x, __LINE__); return 1; }
@@ -68,28 +68,31 @@
/*Pre-computed constants for argument errors */
#define ARG_ERROR_POS_0 E_NULL_PTR
-#define ARG_ERROR_POS_1 NCResultWithArgPosition(E_NULL_PTR, 0x01)
-#define ARG_ERROR_POS_2 NCResultWithArgPosition(E_NULL_PTR, 0x02)
-#define ARG_ERROR_POS_3 NCResultWithArgPosition(E_NULL_PTR, 0x03)
-#define ARG_ERROR_POS_4 NCResultWithArgPosition(E_NULL_PTR, 0x04)
-#define ARG_ERROR_POS_5 NCResultWithArgPosition(E_NULL_PTR, 0x05)
-#define ARG_ERROR_POS_6 NCResultWithArgPosition(E_NULL_PTR, 0x06)
+#define ARG_ERROR(pos) NCResultWithArgPosition(E_NULL_PTR, pos)
+#define ARG_ERROR_POS_1 ARG_ERROR(0x01)
+#define ARG_ERROR_POS_2 ARG_ERROR(0x02)
+#define ARG_ERROR_POS_3 ARG_ERROR(0x03)
+#define ARG_ERROR_POS_4 ARG_ERROR(0x04)
+#define ARG_ERROR_POS_5 ARG_ERROR(0x05)
+#define ARG_ERROR_POS_6 ARG_ERROR(0x06)
#define ARG_RANGE_ERROR_POS_0 E_ARGUMENT_OUT_OF_RANGE
-#define ARG_RANGE_ERROR_POS_1 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x01)
-#define ARG_RANGE_ERROR_POS_2 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x02)
-#define ARG_RANGE_ERROR_POS_3 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x03)
-#define ARG_RANGE_ERROR_POS_4 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x04)
-#define ARG_RANGE_ERROR_POS_5 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x05)
-#define ARG_RANGE_ERROR_POS_6 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x06)
+#define ARG_RANGE_ERROR(pos) NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, pos)
+#define ARG_RANGE_ERROR_POS_1 ARG_RANGE_ERROR(0x01)
+#define ARG_RANGE_ERROR_POS_2 ARG_RANGE_ERROR(0x02)
+#define ARG_RANGE_ERROR_POS_3 ARG_RANGE_ERROR(0x03)
+#define ARG_RANGE_ERROR_POS_4 ARG_RANGE_ERROR(0x04)
+#define ARG_RANGE_ERROR_POS_5 ARG_RANGE_ERROR(0x05)
+#define ARG_RANGE_ERROR_POS_6 ARG_RANGE_ERROR(0x06)
#define ARG_INVALID_ERROR_POS_0 E_INVALID_ARG
-#define ARG_INVALID_ERROR_POS_1 NCResultWithArgPosition(E_INVALID_ARG, 0x01)
-#define ARG_INVALID_ERROR_POS_2 NCResultWithArgPosition(E_INVALID_ARG, 0x02)
-#define ARG_INVALID_ERROR_POS_3 NCResultWithArgPosition(E_INVALID_ARG, 0x03)
-#define ARG_INVALID_ERROR_POS_4 NCResultWithArgPosition(E_INVALID_ARG, 0x04)
-#define ARG_INVALID_ERROR_POS_5 NCResultWithArgPosition(E_INVALID_ARG, 0x05)
-#define ARG_INVALID_ERROR_POS_6 NCResultWithArgPosition(E_INVALID_ARG, 0x06)
+#define ARG_INVALID_ERROR(pos) NCResultWithArgPosition(E_INVALID_ARG, pos)
+#define ARG_INVALID_ERROR_POS_1 ARG_INVALID_ERROR(0x01)
+#define ARG_INVALID_ERROR_POS_2 ARG_INVALID_ERROR(0x02)
+#define ARG_INVALID_ERROR_POS_3 ARG_INVALID_ERROR(0x03)
+#define ARG_INVALID_ERROR_POS_4 ARG_INVALID_ERROR(0x04)
+#define ARG_INVALID_ERROR_POS_5 ARG_INVALID_ERROR(0x05)
+#define ARG_INVALID_ERROR_POS_6 ARG_INVALID_ERROR(0x06)
static int RunTests(void);
static void FillRandomData(void* pbBuffer, size_t length);
@@ -273,12 +276,68 @@ static int TestPublicApiArgumentValidation()
uint8_t nonce[NC_ENCRYPTION_NONCE_SIZE];
NCEncryptionArgs cryptoData;
- cryptoData.dataSize = sizeof(zero32);
- cryptoData.inputData = zero32;
- cryptoData.outputData = sig64; /*just an arbitrary writeable buffer*/
- cryptoData.nonce32 = nonce;
- cryptoData.hmacKeyOut32 = hmacKeyOut;
- cryptoData.version = NC_ENC_VERSION_NIP44;
+
+ {
+ /*
+ * Test arguments for encryption properties
+ */
+
+ uint8_t testBuff32[32];
+
+ TEST(NCSetEncryptionProperty(NULL, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP44), ARG_ERROR_POS_0)
+ TEST(NCSetEncryptionProperty(&cryptoData, 0, 1), E_INVALID_ARG)
+
+ TEST(NCSetEncryptionData(NULL, zero32, sig64, sizeof(zero32)), ARG_ERROR_POS_0)
+ TEST(NCSetEncryptionData(&cryptoData, NULL, sig64, sizeof(zero32)), ARG_ERROR_POS_1)
+ TEST(NCSetEncryptionData(&cryptoData, zero32, NULL, sizeof(zero32)), ARG_ERROR_POS_2)
+ TEST(NCSetEncryptionData(&cryptoData, zero32, sig64, 0), ARG_RANGE_ERROR_POS_3)
+
+ /* Setting any version specific value should fail */
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_NONCE, nonce, sizeof(nonce)), E_VERSION_NOT_SUPPORTED)
+
+ /* Set to nip44 to continue nip44 tests */
+ TEST(NCSetEncryptionProperty(&cryptoData, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP44), NC_SUCCESS)
+
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, 0, nonce, sizeof(nonce)), E_INVALID_ARG)
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_NONCE, NULL, sizeof(nonce)), ARG_ERROR_POS_2)
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_NONCE, nonce, 0), ARG_RANGE_ERROR_POS_3)
+ /* Nonce size should fail if smaller than the required nonce size */
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_NONCE, nonce, NC_ENCRYPTION_NONCE_SIZE - 1), ARG_RANGE_ERROR_POS_3)
+
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, 0, hmacKeyOut, sizeof(hmacKeyOut)), E_INVALID_ARG)
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_MAC_KEY, NULL, sizeof(hmacKeyOut)), ARG_ERROR_POS_2)
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_MAC_KEY, hmacKeyOut, 0), ARG_RANGE_ERROR_POS_3)
+ /* Key size should fail if smaller than the required nip44 key size */
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_MAC_KEY, hmacKeyOut, NC_HMAC_KEY_SIZE - 1), ARG_RANGE_ERROR_POS_3)
+
+ /* Test for nip04 */
+
+ /* Any nip04 specific properties should fail since nip44 has already been set */
+
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP04_IV, testBuff32, sizeof(testBuff32)), E_VERSION_NOT_SUPPORTED)
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP04_KEY, testBuff32, sizeof(testBuff32)), E_VERSION_NOT_SUPPORTED)
+
+ /* Set to nip04 to continue nip04 tests */
+ ENSURE(NCSetEncryptionProperty(&cryptoData, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP04) == NC_SUCCESS)
+
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP04_IV, NULL, sizeof(testBuff32)), ARG_ERROR_POS_2)
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP04_IV, testBuff32, 0), ARG_RANGE_ERROR_POS_3)
+ /* IV size should fail if smaller than IV */
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP04_IV, testBuff32, NC_NIP04_AES_IV_SIZE - 1), ARG_RANGE_ERROR_POS_3)
+
+
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP04_KEY, NULL, sizeof(testBuff32)), ARG_ERROR_POS_2)
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP04_KEY, testBuff32, 0), ARG_RANGE_ERROR_POS_3)
+ /* Key size should fail if smaller than the required nip04 key size */
+ TEST(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP04_KEY, testBuff32, NC_NIP04_AES_KEY_SIZE - 1), ARG_RANGE_ERROR_POS_3)
+ }
+
+ ENSURE(NCSetEncryptionProperty(&cryptoData, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP44) == NC_SUCCESS);
+ ENSURE(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_NONCE, nonce, sizeof(nonce)) == NC_SUCCESS);
+ ENSURE(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_MAC_KEY, hmacKeyOut, sizeof(hmacKeyOut)) == NC_SUCCESS);
+
+ /* Assign the encryption material */
+ ENSURE(NCSetEncryptionData(&cryptoData, zero32, sig64, sizeof(zero32)) == NC_SUCCESS);
PRINTL("TEST: Public API argument validation tests")
@@ -308,27 +367,27 @@ static int TestPublicApiArgumentValidation()
TEST(NCDestroyContext(NULL), ARG_ERROR_POS_0)
/*reinit*/
- TEST(NCReInitContext(NULL, ctxRandom), ARG_ERROR_POS_0)
- TEST(NCReInitContext(ctx, NULL), ARG_ERROR_POS_1)
+ TEST(NCReInitContext(NULL, ctxRandom), ARG_ERROR_POS_0)
+ TEST(NCReInitContext(ctx, NULL), ARG_ERROR_POS_1)
/*Test null secret key*/
- TEST(NCGetPublicKey(ctx, NULL, &pubKey), ARG_ERROR_POS_1)
- TEST(NCGetPublicKey(ctx, &secKey, NULL), ARG_ERROR_POS_2)
+ TEST(NCGetPublicKey(ctx, NULL, &pubKey), ARG_ERROR_POS_1)
+ TEST(NCGetPublicKey(ctx, &secKey, NULL), ARG_ERROR_POS_2)
/*Test null secret key*/
TEST(NCValidateSecretKey(NULL, &secKey), ARG_ERROR_POS_0)
- TEST(NCValidateSecretKey(ctx, NULL), ARG_ERROR_POS_1)
+ TEST(NCValidateSecretKey(ctx, NULL), ARG_ERROR_POS_1)
/* Should fail with a zero key */
TEST(NCValidateSecretKey(ctx, NCToSecKey(zero32)), E_OPERATION_FAILED)
/*Verify sig64 args test*/
- TEST(NCVerifyDigest(NULL, &pubKey, zero32, sig64), ARG_ERROR_POS_0)
+ TEST(NCVerifyDigest(NULL, &pubKey, zero32, sig64), ARG_ERROR_POS_0)
TEST(NCVerifyDigest(ctx, NULL, zero32, sig64), ARG_ERROR_POS_1)
TEST(NCVerifyDigest(ctx, &pubKey, NULL, sig64), ARG_ERROR_POS_2)
TEST(NCVerifyDigest(ctx, &pubKey, zero32, NULL), ARG_ERROR_POS_3)
/*Test verify data args*/
- TEST(NCVerifyData(NULL, &pubKey, zero32, 32, sig64), ARG_ERROR_POS_0)
+ TEST(NCVerifyData(NULL, &pubKey, zero32, 32, sig64), ARG_ERROR_POS_0)
TEST(NCVerifyData(ctx, NULL, zero32, 32, sig64), ARG_ERROR_POS_1)
TEST(NCVerifyData(ctx, &pubKey, NULL, 32, sig64), ARG_ERROR_POS_2)
TEST(NCVerifyData(ctx, &pubKey, zero32, 0, sig64), ARG_RANGE_ERROR_POS_3)
@@ -336,24 +395,24 @@ static int TestPublicApiArgumentValidation()
/*Test null sign data args*/
TEST(NCSignData(NULL, &secKey, zero32, zero32, 32, sig64), ARG_ERROR_POS_0)
- TEST(NCSignData(ctx, NULL, zero32, zero32, 32, sig64), ARG_ERROR_POS_1)
- TEST(NCSignData(ctx, &secKey, NULL, zero32, 32, sig64), ARG_ERROR_POS_2)
- TEST(NCSignData(ctx, &secKey, zero32, NULL, 32, sig64), ARG_ERROR_POS_3)
- TEST(NCSignData(ctx, &secKey, zero32, zero32, 0, sig64), ARG_RANGE_ERROR_POS_4)
- TEST(NCSignData(ctx, &secKey, zero32, zero32, 32, NULL), ARG_ERROR_POS_5)
+ TEST(NCSignData(ctx, NULL, zero32, zero32, 32, sig64), ARG_ERROR_POS_1)
+ TEST(NCSignData(ctx, &secKey, NULL, zero32, 32, sig64), ARG_ERROR_POS_2)
+ TEST(NCSignData(ctx, &secKey, zero32, NULL, 32, sig64), ARG_ERROR_POS_3)
+ TEST(NCSignData(ctx, &secKey, zero32, zero32, 0, sig64), ARG_RANGE_ERROR_POS_4)
+ TEST(NCSignData(ctx, &secKey, zero32, zero32, 32, NULL), ARG_ERROR_POS_5)
/*Test null sign digest args*/
TEST(NCSignDigest(NULL, &secKey, zero32, zero32, sig64), ARG_ERROR_POS_0)
- TEST(NCSignDigest(ctx, NULL, zero32, zero32, sig64), ARG_ERROR_POS_1)
- TEST(NCSignDigest(ctx, &secKey, NULL, zero32, sig64), ARG_ERROR_POS_2)
- TEST(NCSignDigest(ctx, &secKey, zero32, NULL, sig64), ARG_ERROR_POS_3)
- TEST(NCSignDigest(ctx, &secKey, zero32, zero32, NULL), ARG_ERROR_POS_4)
+ TEST(NCSignDigest(ctx, NULL, zero32, zero32, sig64), ARG_ERROR_POS_1)
+ TEST(NCSignDigest(ctx, &secKey, NULL, zero32, sig64), ARG_ERROR_POS_2)
+ TEST(NCSignDigest(ctx, &secKey, zero32, NULL, sig64), ARG_ERROR_POS_3)
+ TEST(NCSignDigest(ctx, &secKey, zero32, zero32, NULL), ARG_ERROR_POS_4)
/*Test null encrypt args*/
TEST(NCEncrypt(NULL, &secKey, &pubKey, &cryptoData), ARG_ERROR_POS_0)
- TEST(NCEncrypt(ctx, NULL, &pubKey, &cryptoData), ARG_ERROR_POS_1)
- TEST(NCEncrypt(ctx, &secKey, NULL, &cryptoData), ARG_ERROR_POS_2)
- TEST(NCEncrypt(ctx, &secKey, &pubKey, NULL), ARG_ERROR_POS_3)
+ TEST(NCEncrypt(ctx, NULL, &pubKey, &cryptoData), ARG_ERROR_POS_1)
+ TEST(NCEncrypt(ctx, &secKey, NULL, &cryptoData), ARG_ERROR_POS_2)
+ TEST(NCEncrypt(ctx, &secKey, &pubKey, NULL), ARG_ERROR_POS_3)
/*Test invalid data size*/
cryptoData.dataSize = 0;
@@ -481,13 +540,12 @@ static int TestCorrectEncryption(const NCContext* context)
NCEncryptionArgs cryptoData;
NCMacVerifyArgs macVerifyArgs;
- /* setup the crypto data structure */
- cryptoData.dataSize = TEST_ENC_DATA_SIZE;
- cryptoData.inputData = plainText;
- cryptoData.outputData = cipherText;
- cryptoData.nonce32 = nonce;
- cryptoData.hmacKeyOut32 = hmacKeyOut;
- cryptoData.version = NC_ENC_VERSION_NIP44;
+ ENSURE(NCSetEncryptionProperty(&cryptoData, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP44) == NC_SUCCESS);
+ ENSURE(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_NONCE, nonce, sizeof(nonce)) == NC_SUCCESS);
+ ENSURE(NCSetEncryptionPropertyEx(&cryptoData, NC_ENC_SET_NIP44_MAC_KEY, hmacKeyOut, NC_HMAC_KEY_SIZE) == NC_SUCCESS);
+
+ /* Assign the encryption material */
+ ENSURE(NCSetEncryptionData(&cryptoData, plainText, cipherText, TEST_ENC_DATA_SIZE) == NC_SUCCESS);
macVerifyArgs.nonce32 = nonce; /* nonce is shared */
macVerifyArgs.mac32 = mac;