aboutsummaryrefslogtreecommitdiff
path: root/src/noscrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/noscrypt.c')
-rw-r--r--src/noscrypt.c171
1 files changed, 87 insertions, 84 deletions
diff --git a/src/noscrypt.c b/src/noscrypt.c
index d63fe53..8aeeefe 100644
--- a/src/noscrypt.c
+++ b/src/noscrypt.c
@@ -23,7 +23,7 @@
#include <secp256k1_ecdh.h>
#include <secp256k1_schnorrsig.h>
-//Setup mbedtls
+/* Setup mbedtls */
#include <mbedtls/platform_util.h>
#include <mbedtls/md.h>
#include <mbedtls/hkdf.h>
@@ -35,22 +35,22 @@
/* Non win platforms may need an inline override */
#if !defined(_NC_IS_WINDOWS) && !defined(inline)
#define inline __inline__
-#endif // !IS_WINDOWS
+#endif /* !IS_WINDOWS */
-//NULL
+/* NULL */
#ifndef NULL
#define NULL ((void*)0)
-#endif // !NULL
+#endif /* !NULL */
-#define CHACHA_NONCE_SIZE 12 //Size of 12 is set by the cipher spec
-#define CHACHA_KEY_SIZE 32 //Size of 32 is set by the cipher spec
+#define CHACHA_NONCE_SIZE 12 /* Size of 12 is set by the cipher spec */
+#define CHACHA_KEY_SIZE 32 /* Size of 32 is set by the cipher spec */
/*
* Local macro for secure zero buffer fill
*/
#define ZERO_FILL(x, size) mbedtls_platform_zeroize(x, size)
-//Include string for memmove
+/* Include string for memmove */
#include <string.h>
#define MEMMOV(dst, src, size) memmove(dst, src, size)
@@ -63,11 +63,11 @@
#define CHECK_NULL_ARG(x, argPos) if(x == NULL) return NCResultWithArgPosition(E_NULL_PTR, argPos);
#define CHECK_ARG_RANGE(x, min, max, argPos) if(x < min || x > max) return NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, argPos);
#else
- //empty macros
+ /* empty macros */
#define CHECK_INVALID_ARG(x)
#define CHECK_NULL_ARG(x, argPos)
#define CHECK_ARG_RANGE(x, min, max, argPos)
-#endif // !NC_DISABLE_INPUT_VALIDATION
+#endif /* !NC_DISABLE_INPUT_VALIDATION */
#ifdef DEBUG
@@ -88,7 +88,7 @@
*/
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define STATIC_ASSERT(x, m) static_assert(x, m)
- #else
+ #elif !defined(STATIC_ASSERT)
#define STATIC_ASSERT(x, m)
#pragma message("Static assertions are not supported by this language version")
#endif
@@ -137,7 +137,7 @@ static inline int _convertToXonly(const NCContext* ctx, const NCPublicKey* compr
DEBUG_ASSERT2(compressedPubKey != NULL, "Expected a valid public 32byte key structure")
DEBUG_ASSERT2(xonly != NULL, "Expected valid X-only secp256k1 public key structure ")
- //Parse the public key into the x-only structure
+ /* Parse the public key into the x-only structure */
return secp256k1_xonly_pubkey_parse(ctx->secpCtx, xonly, compressedPubKey->key);
}
@@ -150,15 +150,15 @@ static int _convertToPubKey(const NCContext* ctx, const NCPublicKey* compressedP
DEBUG_ASSERT2(compressedPubKey != NULL, "Expected a valid public 32byte key structure")
DEBUG_ASSERT2(pubKey != NULL, "Expected valid secp256k1 public key structure")
- //Set the first byte to 0x02 to indicate a compressed public key
+ /* Set the first byte to 0x02 to indicate a compressed public key */
compressed[0] = BIP340_PUBKEY_HEADER_BYTE;
- //Copy the compressed public key data into a new buffer (offset by 1 to store the header byte)
+ /* Copy the compressed public key data into a new buffer (offset by 1 to store the header byte) */
MEMMOV((compressed + 1), compressedPubKey, sizeof(NCPublicKey));
result = secp256k1_ec_pubkey_parse(ctx->secpCtx, pubKey, compressed, sizeof(compressed));
- //zero everything
+ /* zero everything */
ZERO_FILL(compressed, sizeof(compressed));
return result;
@@ -191,16 +191,16 @@ static int _edhHashFuncInternal(
void* data
)
{
- ((void)y32); //unused for nostr
+ ((void)y32); /* unused for nostr */
((void)data);
DEBUG_ASSERT2(output != NULL, "Expected valid output buffer")
DEBUG_ASSERT2(x32 != NULL, "Expected a valid public 32byte x-coodinate buffer")
- //Copy the x coordinate of the shared point into the output buffer
+ /* Copy the x coordinate of the shared point into the output buffer */
MEMMOV(output, x32, 32);
- return 32; //Return the number of bytes written to the output buffer
+ return 32; /* Return the number of bytes written to the output buffer */
}
static NCResult _computeSharedSecret(
@@ -218,7 +218,7 @@ static NCResult _computeSharedSecret(
DEBUG_ASSERT(otherPk != NULL)
DEBUG_ASSERT(sharedPoint != NULL)
- //Recover pubkey from compressed public key data
+ /* Recover pubkey from compressed public key data */
if (_convertToPubKey(ctx, otherPk, &pubKey) != 1)
{
return E_INVALID_ARG;
@@ -240,17 +240,17 @@ static NCResult _computeSharedSecret(
NULL
);
- //Clean up sensitive data
+ /* Clean up sensitive data */
ZERO_FILL(&pubKey, sizeof(pubKey));
- //Result should be 1 on success
+ /* Result should be 1 on success */
return result > 0 ? NC_SUCCESS : E_OPERATION_FAILED;
}
static inline const mbedtls_md_info_t* _getSha256MdInfo(void)
{
const mbedtls_md_info_t* info;
- //Get sha256 md info for hdkf operations
+ /* Get sha256 md info for hdkf operations */
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
DEBUG_ASSERT2(info != NULL, "Expected SHA256 md info struct to be valid")
return info;
@@ -265,23 +265,23 @@ static inline NCResult _computeConversationKey(
)
{
int opResult;
- //Validate internal args
+ /* Validate internal args */
DEBUG_ASSERT2(ctx != NULL, "Expected valid context")
DEBUG_ASSERT2(sharedSecret != NULL, "Expected a valid shared-point")
DEBUG_ASSERT2(mdInfo != NULL, "Expected valid md context")
DEBUG_ASSERT2(ck != NULL, "Expected a valid conversation key")
- //Derive the encryption key
+ /* Derive the encryption key */
opResult = mbedtls_hkdf_extract(
mdInfo,
Nip44ConstantSalt,
sizeof(Nip44ConstantSalt),
- (uint8_t*)sharedSecret, //Shared secret is the input key
+ (uint8_t*)sharedSecret, /* Shared secret is the input key */
NC_SHARED_SEC_SIZE,
- (uint8_t*)ck //Output produces a conversation key
+ (uint8_t*)ck /* Output produces a conversation key */
);
- //Return success if the hkdf operation was successful
+ /* Return success if the hkdf operation was successful */
return opResult == 0 ? NC_SUCCESS : E_OPERATION_FAILED;
}
@@ -302,10 +302,10 @@ static int _chachaEncipher(const struct nc_expand_keys* keys, NCCryptoData* args
return mbedtls_chacha20_crypt(
keys->chacha_key,
keys->chacha_nonce,
- 0, //Counter (always starts at 0)
- args->dataSize, //Data size (input and output are assumed to be the same size)
- args->inputData, //Input data
- args->outputData //Output data
+ 0, /* Counter (always starts at 0) */
+ args->dataSize, /* Data size (input and output are assumed to be the same size) */
+ args->inputData, /* Input data */
+ args->outputData /* Output data */
);
}
@@ -323,14 +323,14 @@ static inline NCResult _getMessageKey(
DEBUG_ASSERT2(converstationKey != NULL, "Expected valid conversation key")
DEBUG_ASSERT2(messageKey != NULL, "Expected valid message key buffer")
- //Another HKDF to derive the message key with nonce
+ /* Another HKDF to derive the message key with nonce */
result = mbedtls_hkdf_expand(
mdInfo,
- (uint8_t*)converstationKey, //Conversation key is the input key
+ (uint8_t*)converstationKey, /* Conversation key is the input key */
NC_CONV_KEY_SIZE,
nonce,
nonceSize,
- (uint8_t*)messageKey, //Output produces a message key (write it directly to struct memory)
+ (uint8_t*)messageKey, /* Output produces a message key (write it directly to struct memory) */
NC_MESSAGE_KEY_SIZE
);
@@ -355,23 +355,23 @@ static inline NCResult _encryptEx(
DEBUG_ASSERT2(mdINfo != NULL, "Expected valid md info struct")
DEBUG_ASSERT2(hmacKey != NULL, "Expected valid hmac key buffer")
- //Failure, bail out
+ /* Failure, bail out */
if ((result = _getMessageKey(mdINfo, ck, args->nonce32, NC_ENCRYPTION_NONCE_SIZE, &messageKey)) != NC_SUCCESS)
{
goto Cleanup;
}
- //Expand the keys from the hkdf so we can use them in the cipher
+ /* Expand the keys from the hkdf so we can use them in the cipher */
expandedKeys = _expandKeysFromHkdf(&messageKey);
- //Copy the hmac key into the args
+ /* Copy the hmac key into the args */
MEMMOV(hmacKey, expandedKeys->hmac_key, NC_HMAC_KEY_SIZE);
- //CHACHA20 (the result will be 0 on success)
+ /* CHACHA20 (the result will be 0 on success) */
result = (NCResult)_chachaEncipher(expandedKeys, args);
Cleanup:
- //Clean up sensitive data
+ /* Clean up sensitive data */
ZERO_FILL(&messageKey, sizeof(messageKey));
return result;
@@ -393,20 +393,20 @@ static inline NCResult _decryptEx(
DEBUG_ASSERT2(args != NULL, "Expected valid encryption args")
DEBUG_ASSERT2(mdInfo != NULL, "Expected valid md info struct")
- //Failure to get message keys, bail out
+ /* Failure to get message keys, bail out */
if ((result = _getMessageKey(mdInfo, ck, args->nonce32, NC_ENCRYPTION_NONCE_SIZE, &messageKey)) != NC_SUCCESS)
{
goto Cleanup;
}
- //Expand the keys from the hkdf so we can use them in the cipher
+ /* Expand the keys from the hkdf so we can use them in the cipher */
cipherKeys = _expandKeysFromHkdf(&messageKey);
- //CHACHA20 (the result will be 0 on success)
+ /* CHACHA20 (the result will be 0 on success) */
result = (NCResult) _chachaEncipher(cipherKeys, args);
Cleanup:
- //Clean up sensitive data
+ /* Clean up sensitive data */
ZERO_FILL(&messageKey, sizeof(messageKey));
return result;
@@ -421,6 +421,7 @@ static inline int _computeHmac(
DEBUG_ASSERT2(key != NULL, "Expected valid hmac key")
DEBUG_ASSERT2(args != NULL, "Expected valid mac verification args")
DEBUG_ASSERT2(hmacOut != NULL, "Expected valid hmac output buffer")
+ DEBUG_ASSERT(args->payload != NULL)
return mbedtls_md_hmac(
_getSha256MdInfo(),
@@ -509,7 +510,7 @@ NC_EXPORT NCResult NC_CC NCInitContext(
ctx->secpCtx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
- //Randomize once on init
+ /* Randomize once on init */
return secp256k1_context_randomize(ctx->secpCtx, entropy) ? NC_SUCCESS : E_INVALID_ARG;
}
@@ -522,7 +523,7 @@ NC_EXPORT NCResult NC_CC NCReInitContext(
CHECK_INVALID_ARG(ctx->secpCtx, 0)
CHECK_NULL_ARG(entropy, 1)
- //Only randomize again
+ /* Only randomize again */
return secp256k1_context_randomize(ctx->secpCtx, entropy) ? NC_SUCCESS : E_INVALID_ARG;
}
@@ -531,16 +532,16 @@ NC_EXPORT NCResult NC_CC NCDestroyContext(NCContext* ctx)
CHECK_NULL_ARG(ctx, 0);
CHECK_INVALID_ARG(ctx->secpCtx, 0);
- //Destroy secp256k1 context
+ /* Destroy secp256k1 context */
secp256k1_context_destroy(ctx->secpCtx);
- //Wipe the context
+ /* Wipe the context */
ZERO_FILL(ctx, sizeof(NCContext));
return NC_SUCCESS;
}
-//KEY Functions
+/* KEY Functions */
NC_EXPORT NCResult NC_CC NCGetPublicKey(
const NCContext* ctx,
const NCSecretKey* sk,
@@ -561,15 +562,15 @@ NC_EXPORT NCResult NC_CC NCGetPublicKey(
return E_INVALID_ARG;
}
- //Generate the x-only public key, docs say this should always return 1
+ /* Generate the x-only public key, docs say this should always return 1 */
result = secp256k1_keypair_xonly_pub(ctx->secpCtx, &xonly, NULL, &keyPair);
DEBUG_ASSERT2(result == 1, "Expected x-only kepair to ALWAYS return 1")
- //Convert to compressed pubkey
+ /* Convert to compressed pubkey */
result = _convertFromXonly(ctx, &xonly, pk);
DEBUG_ASSERT2(result == 1, "Expected x-only pubkey serialize to return 1")
- //Clean out keypair
+ /* Clean out keypair */
ZERO_FILL(&keyPair, sizeof(keyPair));
ZERO_FILL(&xonly, sizeof(xonly));
@@ -585,11 +586,11 @@ NC_EXPORT NCResult NC_CC NCValidateSecretKey(
CHECK_NULL_ARG(sk, 1)
CHECK_INVALID_ARG(ctx->secpCtx, 0)
- //Validate the secret key
+ /* Validate the secret key */
return secp256k1_ec_seckey_verify(ctx->secpCtx, sk->key);
}
-//Ecdsa Functions
+/* Ecdsa Functions */
NC_EXPORT NCResult NC_CC NCSignDigest(
const NCContext* ctx,
@@ -603,7 +604,7 @@ NC_EXPORT NCResult NC_CC NCSignDigest(
secp256k1_keypair keyPair;
secp256k1_xonly_pubkey xonly;
- //Validate arguments
+ /* Validate arguments */
CHECK_NULL_ARG(ctx, 0)
CHECK_INVALID_ARG(ctx->secpCtx, 0)
CHECK_NULL_ARG(sk, 1)
@@ -611,24 +612,24 @@ NC_EXPORT NCResult NC_CC NCSignDigest(
CHECK_NULL_ARG(digest32, 3)
CHECK_NULL_ARG(sig64, 4)
- //Generate the keypair
+ /* Generate the keypair */
if (secp256k1_keypair_create(ctx->secpCtx, &keyPair, sk->key) != 1)
{
return E_INVALID_ARG;
}
- //Sign the digest
+ /* Sign the digest */
result = secp256k1_schnorrsig_sign32(ctx->secpCtx, sig64, digest32, &keyPair, random32);
DEBUG_ASSERT2(result == 1, "Expected schnorr signature to return 1");
- //x-only public key from keypair so the signature can be verified
+ /* x-only public key from keypair so the signature can be verified */
result = secp256k1_keypair_xonly_pub(ctx->secpCtx, &xonly, NULL, &keyPair);
DEBUG_ASSERT2(result == 1, "Expected x-only public key to ALWAYS return 1");
- //Verify the signature is valid
+ /* Verify the signature is valid */
result = secp256k1_schnorrsig_verify(ctx->secpCtx, sig64, digest32, 32, &xonly);
- //cleanup any sensitive data
+ /* cleanup any sensitive data */
ZERO_FILL(&keyPair, sizeof(keyPair));
ZERO_FILL(&xonly, sizeof(xonly));
@@ -646,7 +647,7 @@ NC_EXPORT NCResult NC_CC NCSignData(
{
uint8_t digest[32];
- //Double check is required because arg position differs
+ /* Double check is required because arg position differs */
CHECK_NULL_ARG(ctx, 0)
CHECK_NULL_ARG(sk, 1)
CHECK_NULL_ARG(random32, 2)
@@ -654,13 +655,13 @@ NC_EXPORT NCResult NC_CC NCSignData(
CHECK_ARG_RANGE(dataSize, 1, UINT32_MAX, 4)
CHECK_NULL_ARG(sig64, 5)
- //Compute sha256 of the data before signing
+ /* Compute sha256 of the data before signing */
if(mbedtls_sha256(data, dataSize, digest, 0) != 0)
{
return E_INVALID_ARG;
}
- //Sign the freshly computed digest
+ /* Sign the freshly computed digest */
return NCSignDigest(ctx, sk, random32, digest, sig64);
}
@@ -680,16 +681,16 @@ NC_EXPORT NCResult NC_CC NCVerifyDigest(
CHECK_NULL_ARG(digest32, 2)
CHECK_NULL_ARG(sig64, 3)
- //recover the x-only key from a compressed public key
+ /* recover the x-only key from a compressed public key */
if(_convertToXonly(ctx, pk, &xonly) != 1)
{
return E_INVALID_ARG;
}
- //Verify the signature
+ /* Verify the signature */
result = secp256k1_schnorrsig_verify(ctx->secpCtx, sig64, digest32, 32, &xonly);
- //cleanup any sensitive data
+ /* cleanup any sensitive data */
ZERO_FILL(&xonly, sizeof(xonly));
return result == 1 ? NC_SUCCESS : E_INVALID_ARG;
@@ -711,17 +712,18 @@ NC_EXPORT NCResult NC_CC NCVerifyData(
CHECK_ARG_RANGE(dataSize, 1, UINT32_MAX, 3)
CHECK_NULL_ARG(sig64, 4)
- //Compute sha256 of the data before verifying
+ /* Compute sha256 of the data before verifying */
if (mbedtls_sha256(data, dataSize, digest, 0) != 0)
{
return E_INVALID_ARG;
}
- //Verify the freshly computed digest
+ /* Verify the freshly computed digest */
return NCVerifyDigest(ctx, pk, digest, sig64);
}
-//ECDH Functions
+/* ECDH Functions */
+
NC_EXPORT NCResult NC_CC NCGetSharedSecret(
const NCContext* ctx,
const NCSecretKey* sk,
@@ -754,7 +756,7 @@ NC_EXPORT NCResult NC_CC NCGetConversationKeyEx(
CHECK_NULL_ARG(sharedPoint, 1)
CHECK_NULL_ARG(conversationKey, 2)
- //Cast the shared point to the shared secret type
+ /* Cast the shared point to the shared secret type */
return _computeConversationKey(
ctx,
_getSha256MdInfo(),
@@ -779,7 +781,7 @@ NC_EXPORT NCResult NC_CC NCGetConversationKey(
CHECK_NULL_ARG(pk, 2)
CHECK_NULL_ARG(conversationKey, 3)
- //Compute the shared point
+ /* Compute the shared point */
if ((result = _computeSharedSecret(ctx, sk, pk, &sharedSecret)) != NC_SUCCESS)
{
goto Cleanup;
@@ -793,7 +795,7 @@ NC_EXPORT NCResult NC_CC NCGetConversationKey(
);
Cleanup:
- //Clean up sensitive data
+ /* Clean up sensitive data */
ZERO_FILL(&sharedSecret, sizeof(sharedSecret));
return result;
@@ -812,7 +814,7 @@ NC_EXPORT NCResult NC_CC NCEncryptEx(
CHECK_NULL_ARG(hmacKeyOut, 2)
CHECK_NULL_ARG(args, 3)
- //Validte ciphertext/plaintext
+ /* Validte ciphertext/plaintext */
CHECK_INVALID_ARG(args->inputData, 3)
CHECK_INVALID_ARG(args->outputData, 3)
CHECK_INVALID_ARG(args->nonce32, 3)
@@ -847,7 +849,7 @@ NC_EXPORT NCResult NC_CC NCEncrypt(
CHECK_NULL_ARG(hmacKeyOut, 3)
CHECK_NULL_ARG(args, 4)
- //Validate input/output data
+ /* Validate input/output data */
CHECK_INVALID_ARG(args->inputData, 4)
CHECK_INVALID_ARG(args->outputData, 4)
CHECK_INVALID_ARG(args->nonce32, 4)
@@ -855,13 +857,13 @@ NC_EXPORT NCResult NC_CC NCEncrypt(
mdInfo = _getSha256MdInfo();
- //Compute the shared point
+ /* Compute the shared point */
if ((result = _computeSharedSecret(ctx, sk, pk, &sharedSecret)) != NC_SUCCESS)
{
goto Cleanup;
}
- //Compute the conversation key from secret and pubkic keys
+ /* Compute the conversation key from secret and pubkic keys */
if ((result = _computeConversationKey(ctx, mdInfo, &sharedSecret, &conversationKey)) != NC_SUCCESS)
{
goto Cleanup;
@@ -870,7 +872,7 @@ NC_EXPORT NCResult NC_CC NCEncrypt(
result = _encryptEx(ctx, mdInfo, &conversationKey, hmacKeyOut, args);
Cleanup:
- //Clean up sensitive data
+ /* Clean up sensitive data */
ZERO_FILL(&sharedSecret, sizeof(sharedSecret));
ZERO_FILL(&conversationKey, sizeof(conversationKey));
@@ -888,7 +890,7 @@ NC_EXPORT NCResult NC_CC NCDecryptEx(
CHECK_NULL_ARG(conversationKey, 1)
CHECK_NULL_ARG(args, 2)
- //Validte ciphertext/plaintext
+ /* Validte ciphertext/plaintext */
CHECK_INVALID_ARG(args->inputData, 2)
CHECK_INVALID_ARG(args->outputData, 2)
CHECK_INVALID_ARG(args->nonce32, 2)
@@ -920,7 +922,7 @@ NC_EXPORT NCResult NC_CC NCDecrypt(
CHECK_NULL_ARG(pk, 2)
CHECK_NULL_ARG(args, 3)
- //Validte ciphertext/plaintext
+ /* Validte ciphertext/plaintext */
CHECK_INVALID_ARG(args->inputData, 3)
CHECK_INVALID_ARG(args->outputData, 3)
CHECK_INVALID_ARG(args->nonce32, 3)
@@ -941,7 +943,7 @@ NC_EXPORT NCResult NC_CC NCDecrypt(
result = _decryptEx(ctx, mdInfo, &conversationKey, args);
Cleanup:
- //Clean up sensitive data
+ /* Clean up sensitive data */
ZERO_FILL(&sharedSecret, sizeof(sharedSecret));
ZERO_FILL(&conversationKey, sizeof(conversationKey));
@@ -956,22 +958,23 @@ NC_EXPORT NCResult NCComputeMac(
uint8_t hmacOut[NC_ENCRYPTION_MAC_SIZE]
)
{
+ NCMacVerifyArgs args;
+
CHECK_NULL_ARG(ctx, 0)
CHECK_INVALID_ARG(ctx->secpCtx, 0)
CHECK_NULL_ARG(hmacKey, 1)
CHECK_NULL_ARG(payload, 2)
CHECK_ARG_RANGE(payloadSize, 1, UINT32_MAX, 3)
CHECK_NULL_ARG(hmacOut, 4)
+
+ /*Fill args with 0 before use because we are only using some of the properties*/
+ ZERO_FILL(&args, sizeof(args));
+ args.payload = payload;
+ args.payloadSize = payloadSize;
/*
* Compute the hmac of the data using the supplied hmac key
*/
-
- NCMacVerifyArgs args = {
- .payload = payload,
- .payloadSize = payloadSize
- };
-
return _computeHmac(hmacKey, &args, hmacOut) == 0 ? NC_SUCCESS : E_OPERATION_FAILED;
}