diff options
-rw-r--r-- | CHANGELOG.md | 7 | ||||
-rw-r--r-- | include/noscrypt.h | 20 | ||||
-rw-r--r-- | include/noscryptutil.h | 13 | ||||
-rw-r--r-- | src/noscrypt.c | 71 | ||||
-rw-r--r-- | src/noscryptutil.c | 57 | ||||
-rw-r--r-- | tests/test.c | 97 |
6 files changed, 165 insertions, 100 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 375d11c..38f1c09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Utilities for padding calculations - Prints the name of the configured crypto backend during build - Many internal hardening improvments (span pass-by-value, span validation functions) +- `NCEncryptionGetIvSize()` function to determine the size of the IV for a chosen encryption spec (nip04 or nip44) ### Fixed - OpenSSL EVP incorrect cipher initialization vector - OpenSSL HKDF incorrect key derivation when switching to EVP api +- Some missing calling convention macros for public api functions ### Changed - Updated libsecp256k1 to v0.5.1 @@ -27,6 +29,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added helper functions to alter the `NCEncryptionArgs` api. Altering fields directly is now deprecated. - Public API visibility for non-Windows platforms now defaults to `extern` - **Breaking:** Changed the `nonce32` and `hmacKeyOut32` properties of the `NCEncryptionArgs` struct to `nonceData` and `keyData` respectively. ABI is still compatible, but API has changed. Again mutating this structure manually is now deprecated. +- Unified some API naming conventions for better consistency + +### Removed +- `NC_ENCRYPTION_NONCE_SIZE` macro for better forward compatability +- `NC_NIP04_AES_IV_SIZE` macro for better forward compatability ## [0.1.2] - 2024-05-29 diff --git a/include/noscrypt.h b/include/noscrypt.h index faad1f1..574cef9 100644 --- a/include/noscrypt.h +++ b/include/noscrypt.h @@ -68,7 +68,6 @@ extern "C" { */ #define BIP340_PUBKEY_HEADER_BYTE 0x02 #define NIP44_MESSAGE_KEY_SIZE 0x4c /*32 + 12 + 32 = 76 */ -#define NC_ENCRYPTION_NONCE_SIZE 0x20 #define NC_SEC_KEY_SIZE 0x20 #define NC_PUBKEY_SIZE 0x20 #define NC_CONTEXT_ENTROPY_SIZE 0x20 @@ -77,8 +76,9 @@ 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 (aka cipher block size) */ #define NC_NIP04_AES_KEY_SIZE 0x20 /* AES 256 key size */ +#define NC_NIP44_IV_SIZE 0x20 /* 32 bytes */ +#define NC_NIP04_IV_SIZE 0x10 /* 16 bytes */ /* * From spec @@ -121,10 +121,9 @@ extern "C" { */ #define NC_ENC_SET_VERSION 0x01 -#define NC_ENC_SET_NIP44_NONCE 0x02 +#define NC_ENC_SET_IV 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 @@ -578,7 +577,7 @@ NC_EXPORT NCResult NCComputeMac( * @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( +NC_EXPORT NCResult NCEncryptionSetProperty( NCEncryptionArgs* args, uint32_t property, uint32_t value @@ -595,7 +594,7 @@ NC_EXPORT NCResult NCSetEncryptionProperty( * @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( +NC_EXPORT NCResult NCEncryptionSetPropertyEx( NCEncryptionArgs* args, uint32_t property, uint8_t* value, @@ -612,13 +611,20 @@ NC_EXPORT NCResult NCSetEncryptionPropertyEx( * @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( +NC_EXPORT NCResult NCEncryptionSetData( NCEncryptionArgs* args, const uint8_t* input, uint8_t* output, uint32_t dataSize ); +/* +* Gets the size of the encryption nonce (iv) for the given encryption version +* @param version The encryption version to get the nonce size for +* @return The size of the nonce in bytes, or 0 if the version is not supported +*/ +NC_EXPORT uint32_t NCEncryptionGetIvSize(uint32_t version); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/include/noscryptutil.h b/include/noscryptutil.h index bd60c79..63e08f8 100644 --- a/include/noscryptutil.h +++ b/include/noscryptutil.h @@ -43,6 +43,8 @@ extern "C" { #define E_CIPHER_BAD_INPUT -15 #define E_CIPHER_BAD_INPUT_SIZE -16 +#define NC_UTIL_CIPHER_MODE 0x01u + #define NC_UTIL_CIPHER_MODE_ENCRYPT 0x00u #define NC_UTIL_CIPHER_MODE_DECRYPT 0x01u #define NC_UTIL_CIPHER_ZERO_ON_FREE 0x02u @@ -132,7 +134,7 @@ NC_EXPORT NCResult NC_CC NCUtilCipherReadOutput( ); /* -* Sets a property on the encryption context. Equivalent to calling NCSetEncryptionPropertyEx +* Sets a property on the encryption context. Equivalent to calling NCEncryptionSetPropertyEx * @param ctx A valid pointer to an encryption context * @param property The property to set * @param value A pointer to the value to set @@ -176,6 +178,15 @@ NC_EXPORT NCResult NC_CC NCUtilCipherUpdate( const NCPublicKey* pk ); +/* +* Gets the size of the IV(nonce) required for the encryption context. +* @param encCtx A valid pointer to an initialized encryption context +* @return The size of the IV in bytes, or a negative error code if the context +* is invalid, or the version is not supported. Use NCParseErrorCode to get the error code +* and positional argument that caused the error. +*/ +NC_EXPORT NCResult NC_CC NCUtilCipherGetIvSize(const NCUtilCipherContext* encCtx); + #ifdef __cplusplus } #endif diff --git a/src/noscrypt.c b/src/noscrypt.c index deadca6..fededaf 100644 --- a/src/noscrypt.c +++ b/src/noscrypt.c @@ -310,7 +310,7 @@ static _nc_fn_inline NCResult _encryptNip44Ex( result = NC_SUCCESS; - ncSpanInitC(&nonceSpan, args->nonceData, NC_ENCRYPTION_NONCE_SIZE); + ncSpanInitC(&nonceSpan, args->nonceData, NC_NIP44_IV_SIZE); /* Message key will be derrived on every encryption call */ if (_getMessageKey(ck, nonceSpan, &messageKey) != CSTATUS_OK) @@ -344,13 +344,14 @@ static _nc_fn_inline NCResult _decryptNip44Ex(const NCContext* ctx, const struct struct message_key messageKey; const struct nc_expand_keys* cipherKeys; - DEBUG_ASSERT2(ctx != NULL, "Expected valid context") - DEBUG_ASSERT2(ck != NULL, "Expected valid conversation key") - DEBUG_ASSERT2(args != NULL, "Expected valid encryption args") + DEBUG_ASSERT2(ctx != NULL, "Expected valid context"); + DEBUG_ASSERT2(ck != NULL, "Expected valid conversation key"); + DEBUG_ASSERT2(args != NULL, "Expected valid encryption args"); + DEBUG_ASSERT(args->version == NC_ENC_VERSION_NIP44); result = NC_SUCCESS; - ncSpanInitC(&nonceSpan, args->nonceData, NC_ENCRYPTION_NONCE_SIZE); + ncSpanInitC(&nonceSpan, args->nonceData, NC_NIP44_IV_SIZE); if (_getMessageKey(ck, nonceSpan, &messageKey) != CSTATUS_OK) { @@ -401,7 +402,7 @@ static NCResult _verifyMacEx( DEBUG_ASSERT2(conversationKey != NULL, "Expected valid conversation key") DEBUG_ASSERT2(args != NULL, "Expected valid mac verification args") - ncSpanInitC(&nonceSpan, args->nonce32, NC_ENCRYPTION_NONCE_SIZE); + ncSpanInitC(&nonceSpan, args->nonce32, NC_NIP44_IV_SIZE); ncSpanInitC(&payloadSpan, args->payload, args->payloadSize); /* @@ -979,7 +980,7 @@ Cleanup: return result; } -NC_EXPORT NCResult NCComputeMac( +NC_EXPORT NCResult NC_CC NCComputeMac( const NCContext* ctx, const uint8_t hmacKey[NC_HMAC_KEY_SIZE], const uint8_t* payload, @@ -1069,13 +1070,14 @@ Cleanup: #define ENSURE_ENC_MODE(args, mode) if(args->version != mode) return E_VERSION_NOT_SUPPORTED; -NC_EXPORT NCResult NCSetEncryptionPropertyEx( +NC_EXPORT NCResult NC_CC NCEncryptionSetPropertyEx( NCEncryptionArgs* args, uint32_t property, uint8_t* value, uint32_t valueLen ) { + uint32_t ivSize; CHECK_NULL_ARG(args, 0) CHECK_NULL_ARG(value, 2) @@ -1091,22 +1093,6 @@ NC_EXPORT NCResult NCSetEncryptionPropertyEx( 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 @@ -1122,13 +1108,17 @@ NC_EXPORT NCResult NCSetEncryptionPropertyEx( return NC_SUCCESS; - case NC_ENC_SET_NIP44_NONCE: + case NC_ENC_SET_IV: + + ivSize = NCEncryptionGetIvSize(args->version); - /* Nonce buffer must be at least the size, max doesnt matter */ - CHECK_ARG_RANGE(valueLen, NC_ENCRYPTION_NONCE_SIZE, UINT32_MAX, 3) + /* Gaurd invalid version */ + if (ivSize == 0) + { + return E_VERSION_NOT_SUPPORTED; + } - /* Nonce is only used in nip44 mode */ - ENSURE_ENC_MODE(args, NC_ENC_VERSION_NIP44) + CHECK_ARG_RANGE(valueLen, ivSize, ivSize, 3) args->nonceData = value; @@ -1155,13 +1145,13 @@ NC_EXPORT NCResult NCSetEncryptionPropertyEx( return E_INVALID_ARG; } -NC_EXPORT NCResult NCSetEncryptionProperty( +NC_EXPORT NCResult NC_CC NCEncryptionSetProperty( NCEncryptionArgs* args, uint32_t property, uint32_t value ) { - return NCSetEncryptionPropertyEx( + return NCEncryptionSetPropertyEx( args, property, (uint8_t*)&value, @@ -1169,7 +1159,7 @@ NC_EXPORT NCResult NCSetEncryptionProperty( ); } -NC_EXPORT NCResult NCSetEncryptionData( +NC_EXPORT NCResult NC_CC NCEncryptionSetData( NCEncryptionArgs* args, const uint8_t* input, uint8_t* output, @@ -1186,4 +1176,19 @@ NC_EXPORT NCResult NCSetEncryptionData( args->dataSize = dataSize; return NC_SUCCESS; -}
\ No newline at end of file +} + +NC_EXPORT uint32_t NC_CC NCEncryptionGetIvSize(uint32_t version) +{ + switch (version) + { + case NC_ENC_VERSION_NIP04: + return NC_NIP04_IV_SIZE; + + case NC_ENC_VERSION_NIP44: + return NC_NIP44_IV_SIZE; + + default: + return 0; + } +} diff --git a/src/noscryptutil.c b/src/noscryptutil.c index 4cee2c3..89e0f35 100644 --- a/src/noscryptutil.c +++ b/src/noscryptutil.c @@ -37,6 +37,7 @@ #define MIN_PADDING_SIZE 0x20u #define NIP44_VERSION_SIZE 0x01u #define NIP44_PT_LEN_SIZE sizeof(uint16_t) +#define NIP44_NONCE_SIZE NC_NIP44_IV_SIZE /* * minimum size for a valid nip44 payload @@ -200,7 +201,7 @@ static _nc_fn_inline uint32_t _calcNip44TotalOutSize(uint32_t inputSize) bufferSize = NIP44_VERSION_SIZE; - bufferSize += NC_ENCRYPTION_NONCE_SIZE; + bufferSize += NIP44_NONCE_SIZE; bufferSize += NIP44_PT_LEN_SIZE; @@ -267,7 +268,7 @@ static _nc_fn_inline int _nip44ParseSegments( *nonce = ncSpanSliceC( payload, NIP44_VERSION_SIZE, - NC_ENCRYPTION_NONCE_SIZE + NIP44_NONCE_SIZE ); /* @@ -293,8 +294,8 @@ static _nc_fn_inline int _nip44ParseSegments( */ *cipherText = ncSpanSliceC( payload, - NIP44_VERSION_SIZE + NC_ENCRYPTION_NONCE_SIZE, - payload.size - (NIP44_VERSION_SIZE + NC_ENCRYPTION_NONCE_SIZE + NC_ENCRYPTION_MAC_SIZE) + NIP44_VERSION_SIZE + NIP44_NONCE_SIZE, + payload.size - (NIP44_VERSION_SIZE + NIP44_NONCE_SIZE + NC_ENCRYPTION_MAC_SIZE) ); return 1; @@ -357,12 +358,23 @@ static NCResult _nip44EncryptCompleteCore( ZERO_FILL(hmacKeyOut, sizeof(hmacKeyOut)); + /* Get the nonce/iv size so we know how much nonce data to write */ + result = NCUtilCipherGetIvSize(state); + DEBUG_ASSERT(result > 0); + /* Start by appending the version number */ ncSpanAppend(message, &outPos, Nip44VersionValue, sizeof(Nip44VersionValue)); /* next is nonce data */ - ncSpanAppend(message, &outPos, encArgs.nonceData, NC_ENCRYPTION_NONCE_SIZE); - DEBUG_ASSERT(outPos == 1 + NC_ENCRYPTION_NONCE_SIZE); + ncSpanAppend(message, &outPos, encArgs.nonceData, (uint32_t)result); + + /* + * Assert the output points to the end of the nonce segment + * for nip44 this is exactly 33 bytes. This assert also doubles + * to check the output of NCUtilCipherGetIvSize() to ensure + * it's returning the correct size for nip44 + */ + DEBUG_ASSERT(outPos == 1 + NIP44_NONCE_SIZE); /* * Assign the hmac key from the stack buffer. Since the args structure @@ -372,7 +384,7 @@ static NCResult _nip44EncryptCompleteCore( * addresses. */ - result = NCSetEncryptionPropertyEx( + result = NCEncryptionSetPropertyEx( &encArgs, NC_ENC_SET_NIP44_MAC_KEY, hmacKeyOut, @@ -397,7 +409,7 @@ static NCResult _nip44EncryptCompleteCore( * plainText size field. */ - result = NCSetEncryptionData( + result = NCEncryptionSetData( &encArgs, ncSpanGetOffset(message, outPos), /* in place encryption */ ncSpanGetOffset(message, outPos), @@ -517,7 +529,7 @@ static NCResult _nip44DecryptCompleteCore( if ((state->_flags & NC_UTIL_CIPHER_MAC_NO_VERIFY) == 0) { DEBUG_ASSERT(ncSpanGetSizeC(macValue) == NC_ENCRYPTION_MAC_SIZE); - DEBUG_ASSERT(ncSpanGetSizeC(macData) > NC_ENCRYPTION_NONCE_SIZE + MIN_PADDING_SIZE); + DEBUG_ASSERT(ncSpanGetSizeC(macData) > NIP44_NONCE_SIZE + MIN_PADDING_SIZE); /* Assign the mac data to the mac verify args */ macArgs.mac32 = ncSpanGetOffsetC(macValue, 0); @@ -550,7 +562,7 @@ static NCResult _nip44DecryptCompleteCore( DEBUG_ASSERT2(cipherText.size >= MIN_PADDING_SIZE, "Cipertext segment was parsed incorrectly. Too small"); - result = NCSetEncryptionData( + result = NCEncryptionSetData( &encArgs, ncSpanGetOffsetC(cipherText, 0), ncSpanGetOffset(output, 0), /*decrypt ciphertext and write directly to the output buffer */ @@ -653,6 +665,10 @@ NC_EXPORT NCUtilCipherContext* NC_CC NCUtilCipherAlloc(uint32_t encVersion, uint if (encCtx != NULL) { + /* + * Technically I should be using the NCEncSetProperty but this + * is an acceptable shortcut for now, may break in future + */ encCtx->encArgs.version = encVersion; encCtx->_flags = flags; } @@ -694,7 +710,7 @@ NC_EXPORT NCResult NC_CC NCUtilCipherInit( CHECK_NULL_ARG(encCtx, 0); CHECK_NULL_ARG(inputData, 1); - if ((encCtx->_flags & NC_UTIL_CIPHER_MODE_DECRYPT) > 0) + if ((encCtx->_flags & NC_UTIL_CIPHER_MODE) == NC_UTIL_CIPHER_MODE_DECRYPT) { /* * Validate the input data for proper format for @@ -842,7 +858,7 @@ NC_EXPORT NCResult NC_CC NCUtilCipherReadOutput( return (NCResult)encCtx->buffer.actualOutput.size; } -NC_EXPORT NCResult NCUtilCipherSetProperty( +NC_EXPORT NCResult NC_CC NCUtilCipherSetProperty( NCUtilCipherContext* ctx, uint32_t property, uint8_t* value, @@ -852,7 +868,7 @@ NC_EXPORT NCResult NCUtilCipherSetProperty( CHECK_NULL_ARG(ctx, 0) /* All other arguments are verified */ - return NCSetEncryptionPropertyEx( + return NCEncryptionSetPropertyEx( &ctx->encArgs, property, value, @@ -889,7 +905,7 @@ NC_EXPORT NCResult NC_CC NCUtilCipherUpdate( { case NC_ENC_VERSION_NIP44: - if ((encCtx->_flags & NC_UTIL_CIPHER_MODE_DECRYPT) > 0) + if ((encCtx->_flags & NC_UTIL_CIPHER_MODE) == NC_UTIL_CIPHER_MODE_DECRYPT) { return _nip44DecryptCompleteCore(libContext, sk, pk, encCtx); } @@ -908,3 +924,16 @@ NC_EXPORT NCResult NC_CC NCUtilCipherUpdate( return E_VERSION_NOT_SUPPORTED; } } + +NC_EXPORT NCResult NC_CC NCUtilCipherGetIvSize(const NCUtilCipherContext* encCtx) +{ + uint32_t ivSize; + + CHECK_NULL_ARG(encCtx, 0); + + ivSize = NCEncryptionGetIvSize(encCtx->encArgs.version); + + return ivSize == 0 + ? E_VERSION_NOT_SUPPORTED + : (NCResult)ivSize; +} diff --git a/tests/test.c b/tests/test.c index b4cdef1..e8b064b 100644 --- a/tests/test.c +++ b/tests/test.c @@ -284,74 +284,78 @@ static int TestPublicApiArgumentValidation() NCSecretKey secKey; NCPublicKey pubKey; uint8_t hmacKeyOut[NC_HMAC_KEY_SIZE]; - uint8_t nonce[NC_ENCRYPTION_NONCE_SIZE]; + uint8_t nonce[NC_NIP44_IV_SIZE]; NCEncryptionArgs cryptoData; PRINTL("TEST: Public API argument validation tests") { + TEST(NCEncryptionGetIvSize(NC_ENC_VERSION_NIP44), sizeof(nonce)); + /* * 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(NCEncryptionSetProperty(NULL, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP04), ARG_ERROR_POS_0) + TEST(NCEncryptionSetProperty(&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) + TEST(NCEncryptionSetData(NULL, zero32, sig64, sizeof(zero32)), ARG_ERROR_POS_0) + TEST(NCEncryptionSetData(&cryptoData, NULL, sig64, sizeof(zero32)), ARG_ERROR_POS_1) + TEST(NCEncryptionSetData(&cryptoData, zero32, NULL, sizeof(zero32)), ARG_ERROR_POS_2) + TEST(NCEncryptionSetData(&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) + /* Setting the IV should fail because a version is not set*/ + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, 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) + TEST(NCEncryptionSetProperty(&cryptoData, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP44), NC_SUCCESS) + + TEST(NCEncryptionSetPropertyEx(&cryptoData, 0, nonce, sizeof(nonce)), E_INVALID_ARG) + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, NULL, sizeof(nonce)), ARG_ERROR_POS_2) + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, nonce, 0), ARG_RANGE_ERROR_POS_3) + /* Nonce size should fail if not exactly the required nonce size */ + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, nonce, NC_NIP44_IV_SIZE - 1), ARG_RANGE_ERROR_POS_3) + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, nonce, NC_NIP44_IV_SIZE + 1), ARG_RANGE_ERROR_POS_3) + + TEST(NCEncryptionSetPropertyEx(&cryptoData, 0, hmacKeyOut, sizeof(hmacKeyOut)), E_INVALID_ARG) + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_NIP44_MAC_KEY, NULL, sizeof(hmacKeyOut)), ARG_ERROR_POS_2) + TEST(NCEncryptionSetPropertyEx(&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(NCEncryptionSetPropertyEx(&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) + + TEST(NCEncryptionSetPropertyEx(&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) + ENSURE(NCEncryptionSetProperty(&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(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, NULL, sizeof(testBuff32)), ARG_ERROR_POS_2) + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, testBuff32, 0), ARG_RANGE_ERROR_POS_3) + /* IV size should fail if not exact size IV for the version */ + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, testBuff32, NC_NIP04_IV_SIZE - 1), ARG_RANGE_ERROR_POS_3) + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, testBuff32, NC_NIP04_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) + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_NIP04_KEY, NULL, sizeof(testBuff32)), ARG_ERROR_POS_2) + TEST(NCEncryptionSetPropertyEx(&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) + TEST(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_NIP04_KEY, testBuff32, NC_NIP04_AES_KEY_SIZE - 1), ARG_RANGE_ERROR_POS_3) } /* Prep the crypto structure for proper usage */ - 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); + ENSURE(NCEncryptionSetProperty(&cryptoData, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP44) == NC_SUCCESS); + ENSURE(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, nonce, sizeof(nonce)) == NC_SUCCESS); + ENSURE(NCEncryptionSetPropertyEx(&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); + ENSURE(NCEncryptionSetData(&cryptoData, zero32, sig64, sizeof(zero32)) == NC_SUCCESS); FillRandomData(ctxRandom, 32); @@ -543,7 +547,7 @@ static int TestCorrectEncryption(const NCContext* context) NCPublicKey pubKey2; uint8_t hmacKeyOut[NC_HMAC_KEY_SIZE]; - uint8_t nonce[NC_ENCRYPTION_NONCE_SIZE]; + uint8_t nonce[NC_NIP44_IV_SIZE]; //nonce is set by cipher spec, shoud use NCEncryptionGetIvSize() in production uint8_t mac[NC_ENCRYPTION_MAC_SIZE]; uint8_t plainText[TEST_ENC_DATA_SIZE]; @@ -555,12 +559,13 @@ static int TestCorrectEncryption(const NCContext* context) PRINTL("TEST: Correct encryption") - 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); + ENSURE(NCEncryptionGetIvSize(NC_ENC_VERSION_NIP44) == (uint32_t)sizeof(nonce)); + ENSURE(NCEncryptionSetProperty(&cryptoData, NC_ENC_SET_VERSION, NC_ENC_VERSION_NIP44) == NC_SUCCESS); + ENSURE(NCEncryptionSetPropertyEx(&cryptoData, NC_ENC_SET_IV, nonce, sizeof(nonce)) == NC_SUCCESS); + ENSURE(NCEncryptionSetPropertyEx(&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); + ENSURE(NCEncryptionSetData(&cryptoData, plainText, cipherText, TEST_ENC_DATA_SIZE) == NC_SUCCESS); macVerifyArgs.nonce32 = nonce; /* nonce is shared */ macVerifyArgs.mac32 = mac; @@ -634,10 +639,12 @@ static int TestUtilNip44Encryption( ENSURE(ctx != NULL); + TEST(ncSpanGetSize(nonce), (uint32_t)NCUtilCipherGetIvSize(ctx)); + TEST(NCUtilCipherInit(ctx, plainText.data, plainText.size), NC_SUCCESS); /* Nonce is required for nip44 encryption */ - TEST(NCUtilCipherSetProperty(ctx, NC_ENC_SET_NIP44_NONCE, nonce.data, nonce.size), NC_SUCCESS); + TEST(NCUtilCipherSetProperty(ctx, NC_ENC_SET_IV, nonce.data, nonce.size), NC_SUCCESS); /* Cipher update should return the */ TEST(NCUtilCipherUpdate(ctx, libCtx, NCByteCastToSecretKey(sendKey.data), &recvPubKey), NC_SUCCESS); @@ -650,7 +657,7 @@ static int TestUtilNip44Encryption( TASSERT(outData != NULL); /* Read the encrypted payload to test */ - TEST(NCUtilCipherReadOutput(ctx, outData, cipherOutputSize), cipherOutputSize); + TEST(NCUtilCipherReadOutput(ctx, outData, (uint32_t)cipherOutputSize), cipherOutputSize); /* Ensure encrypted payload matches */ TEST(memcmp(outData, expected.data, cipherOutputSize), 0); @@ -699,7 +706,7 @@ static int TestUtilNip44Decryption( TASSERT(outData != NULL); /* Read the encrypted payload to test */ - TEST(NCUtilCipherReadOutput(ctx, outData, plaintextSize), plaintextSize); + TEST(NCUtilCipherReadOutput(ctx, outData, (uint32_t)plaintextSize), plaintextSize); /* Ensure encrypted payload matches */ TEST(memcmp(outData, expectedPt.data, plaintextSize), 0); @@ -729,7 +736,7 @@ static int TestUtilFunctions(const NCContext* libCtx) /* From the nip44 vectors file */ span_t sendKey = FromHexString("0000000000000000000000000000000000000000000000000000000000000001", sizeof(NCSecretKey)); span_t recvKey = FromHexString("0000000000000000000000000000000000000000000000000000000000000002", sizeof(NCSecretKey)); - span_t nonce = FromHexString("0000000000000000000000000000000000000000000000000000000000000001", NC_ENCRYPTION_NONCE_SIZE); + span_t nonce = FromHexString("0000000000000000000000000000000000000000000000000000000000000001", NC_NIP44_IV_SIZE); span_t payload = FromHexString("02000000000000000000000000000000000000000000000000000000000000000179ed06e5548ad3ff58ca920e6c0b4329f6040230f7e6e5641f20741780f0adc35a09794259929a02bb06ad8e8cf709ee4ccc567e9d514cdf5781af27a3e905e55b1b", 99); span_t plainText = FromHexString("61", 1); |