aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2024-08-17 12:18:05 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2024-08-17 12:18:05 -0400
commit0925f5c786badb715d564e991d2306632c2aecad (patch)
treebd46009803c2a136eb85ea9d8566f595ba387291 /include
parent614c02097f5f173299948df279c2d3e2f9f748f9 (diff)
parent756a184762db4cb0a9945d066b59d0e2f58c18d8 (diff)
Merge branch 'develop' into c-sharp
Diffstat (limited to 'include')
-rw-r--r--include/noscrypt.h88
-rw-r--r--include/noscryptutil.h194
2 files changed, 239 insertions, 43 deletions
diff --git a/include/noscrypt.h b/include/noscrypt.h
index f408dfc..3702555 100644
--- a/include/noscrypt.h
+++ b/include/noscrypt.h
@@ -58,7 +58,7 @@ extern "C" {
#ifdef _NC_IS_WINDOWS
#define NC_EXPORT __declspec(dllimport)
#else
- #define NC_EXPORT
+ #define NC_EXPORT extern
#endif /* _NC_IS_WINDOWS */
#endif /* !NOSCRYPT_EXPORTING */
#endif /* !NC_EXPORT */
@@ -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
@@ -76,16 +75,17 @@ extern "C" {
#define NC_CONV_KEY_SIZE 0x20
#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_MESSAGE_KEY_SIZE NIP44_MESSAGE_KEY_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
* https://github.com/nostr-protocol/nips/blob/master/44.md#decryption
*/
#define NIP44_MIN_ENC_MESSAGE_SIZE 0x01
-#define NIP44_MAX_ENC_MESSAGE_SIZE 0xffff
+#define NIP44_MAX_ENC_MESSAGE_SIZE UINT16_MAX
#define NC_ENC_VERSION_NIP04 0x04
#define NC_ENC_VERSION_NIP44 0x2c
@@ -121,11 +121,31 @@ 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
+/*
+* API NOTES:
+*
+* - Decisions on integer width
+* Since noscrypt will target general purpose processors and embedded
+* systems (future) I didn't want to risk word size issues causing under/overflow
+* for the time being, so a fixed integer width was used and internal code
+* supports and guards against the platform default integer width (size_t)
+*
+* I'd like to support 64bit stuff, but really the underlying systems don't
+* need to support that size buffer, nor do I expect platforms to have more than
+* 4GB sized buffers (int32_t), it's just not practial and most work is on
+* digests anyway.
+*
+* - Decisions on unsigned vs signed
+* Yeah, I know this is a popular squabble in C land, but implementation details
+* should not trouble the user. If I expect an unsigned int, then it should be
+* explicit, negative number guards are cumbersom to handle return codes with
+* that IMO most engineers don't bother doing anyway or doing well at the very
+* least, so I'm using unsgined integers. Sorry, not sorry.
+*/
/* A compressed resul/return value, negative values
are failure, 0 is success and positive values are
@@ -212,51 +232,26 @@ typedef struct nc_mac_verify {
*/
/*
-* A helper function to cast a buffer to a NCSecretKey struct
-* @param key The buffer to cast
-* @return A pointer to the NCSecretKey struct
+* Casts a buffer pointer to a NCSecretKey pointer
*/
-static _nc_fn_inline NCSecretKey* NCToSecKey(uint8_t key[NC_SEC_KEY_SIZE])
-{
- return (NCSecretKey*)key;
-}
+#define NCByteCastToSecretKey(key) (NCSecretKey*)key
/*
-* A helper function to cast a buffer to a NCPublicKey struct
-* @param key The buffer to cast
-* @return A pointer to the NCPublicKey struct
+* Casts a buffer pointer to a NCPublicKey pointer
*/
-static _nc_fn_inline NCPublicKey* NCToPubKey(uint8_t key[NC_PUBKEY_SIZE])
-{
- return (NCPublicKey*)key;
-}
+#define NCByteCastToPublicKey(key) (NCPublicKey*)key
-static _nc_fn_inline NCResult NCResultWithArgPosition(NCResult err, uint8_t argPosition)
-{
- return -(((NCResult)argPosition << NC_ARG_POSITION_OFFSET) | -err);
-}
+
+NC_EXPORT NCResult NC_CC NCResultWithArgPosition(NCResult err, uint8_t argPosition);
/*
* Parses an error code and returns the error code and the argument position
that caused the error.
* @param result The error code to parse
-* @param argPositionOut A pointer to the argument position to write to
+* @param argPositionOut A pointer to the argument position to write to (optionall, set to NULL of unobserved)
* @return The error code
*/
-static _nc_fn_inline int NCParseErrorCode(NCResult result, uint8_t* argPositionOut)
-{
- NCResult asPositive;
- int code;
-
- /* convert result to a positive value*/
- asPositive = -result;
-
- /* Get the error code from the lower 8 bits and the argument position from the upper 8 bits*/
- code = -(asPositive & NC_ERROR_CODE_MASK);
- *argPositionOut = (asPositive >> NC_ARG_POSITION_OFFSET) & 0xFF;
-
- return code;
-}
+NC_EXPORT int NC_CC NCParseErrorCode(NCResult result, uint8_t* argPositionOut);
/*--------------------------------------
* LIB CONTEXT API
@@ -603,7 +598,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
@@ -620,7 +615,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,
@@ -637,13 +632,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
new file mode 100644
index 0000000..63e08f8
--- /dev/null
+++ b/include/noscryptutil.h
@@ -0,0 +1,194 @@
+/*
+* Copyright (c) 2024 Vaughn Nugent
+*
+* Package: noscrypt
+* File: noscryptutil.h
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public License
+* as published by the Free Software Foundation; either version 2.1
+* of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with noscrypt. If not, see http://www.gnu.org/licenses/.
+*/
+
+/*
+* This header includes some optional high-level nostr crypto utility functions
+* for much easer app development.
+*/
+
+#pragma once
+
+#ifndef NOSCRYPTUTIL_H
+#define NOSCRYPTUTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "noscrypt.h"
+
+#define E_OUT_OF_MEMORY -10
+
+#define E_CIPHER_INVALID_FORMAT -11
+#define E_CIPHER_BAD_NONCE -12
+#define E_CIPHER_MAC_INVALID -13
+#define E_CIPHER_NO_OUTPUT -14
+#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
+#define NC_UTIL_CIPHER_MAC_NO_VERIFY 0x04u
+#define NC_UTIL_CIPHER_REUSEABLE 0x08u
+
+/*
+* The encryption context structure. This structure is used to store the state
+* of the encryption operation. The structure is opaque and should not be accessed
+* directly.
+*/
+typedef struct nc_util_enc_struct NCUtilCipherContext;
+
+/*
+* Gets the size of the padded buffer required for an encryption operation.
+* @param encVersion The encryption specification version to use
+* @param plaintextSize The size of the plaintext buffer in bytes
+* @return The size of the padded buffer in bytes
+*/
+NC_EXPORT NCResult NC_CC NCUtilGetEncryptionPaddedSize(uint32_t encVersion, uint32_t plaintextSize);
+
+/*
+* Gets the size of the payload buffer required for an encryption operation.
+* @param encVersion The encryption specification version to use
+* @param plaintextSize The size of the plaintext buffer in bytes
+* @return The size of the payload buffer in bytes
+* @note The payload buffer is the final buffer to be sent to a nostr user. For nip04 this
+* is a raw AES message, for nip44 this is a mucher lager buffer. See the nostr specifications
+* for more information.
+*/
+NC_EXPORT NCResult NC_CC NCUtilGetEncryptionBufferSize(uint32_t encVersion, uint32_t plaintextSize);
+
+/*
+* Allocates a new encryption context and sets the encryption version and flags. The encryption context
+* must be freed with NCUtilCipherFree when it is no longer needed.
+* @param encVersion The encryption specification version to use
+* @param flags The flags to set on the encryption context
+* @return A valid pointer to an encryption context or NULL if the operation failed
+*/
+NC_EXPORT NCUtilCipherContext* NC_CC NCUtilCipherAlloc(uint32_t encVersion, uint32_t flags);
+
+/*
+* Initializes the cipher context with the input data and size. This function will
+ internally allocate a the required output buffer for the cipher operation. You may only call
+ this function once.
+* @param encCtx A valid pointer to an allocated encryption context
+* @param inputData A pointer to the input data for the Cipher
+* @param inputSize The size of the input data
+* @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 NC_CC NCUtilCipherInit(
+ NCUtilCipherContext* encCtx,
+ const uint8_t* inputData,
+ uint32_t inputSize
+);
+
+/*
+* Frees the encryption context and clears the memory if the NC_UTIL_CIPHER_ZERO_ON_FREE
+* flag is set.
+* @param encCtx A valid pointer to an allocated encryption context to free
+*/
+NC_EXPORT void NC_CC NCUtilCipherFree(NCUtilCipherContext* encCtx);
+
+/*
+* Gets the output size of the encryption context. This function will return the size of
+* the output buffer that will be written to when calling NCUtilCipherReadOutput.
+* @param encCtx A valid pointer to an allocated encryption context
+* @return The size of the output buffer in bytes
+*/
+NC_EXPORT NCResult NC_CC NCUtilCipherGetOutputSize(const NCUtilCipherContext* encCtx);
+
+/*
+* Reads the output buffer from the encryption context. This function will copy the output
+* buffer to the output buffer provided. The output buffer must be at least the size of the
+* output buffer returned by NCUtilCipherGetOutputSize.
+* @param encCtx A valid pointer to an initialized encryption context
+* @param output A pointer to the output buffer to copy the output to
+* @param outputSize The size of the output buffer in bytes
+* @returns The number of bytes written to the output buffer or an error code. Use NCParseErrorCode
+* to get the error code and positional argument that caused the error
+*/
+NC_EXPORT NCResult NC_CC NCUtilCipherReadOutput(
+ const NCUtilCipherContext* encCtx,
+ uint8_t* output,
+ uint32_t outputSize
+);
+
+/*
+* 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
+* @param valueLen The length of the value
+* @return NC_SUCCESS if the operation was successful, otherwise an error code. Use NCParseErrorCode to
+* get the error code and positional argument that caused the error
+*/
+NC_EXPORT NCResult NC_CC NCUtilCipherSetProperty(
+ NCUtilCipherContext* ctx,
+ uint32_t property,
+ uint8_t* value,
+ uint32_t valueLen
+);
+
+/*
+* Gets the flags set on the encryption context during initialization.
+* @param ctx A valid pointer to an encryption context
+* @return The flags set on the encryption context cast to a NCResult, or
+* an error code if the context is invalid. Use NCParseErrorCode to get the error code
+* and positional argument that caused the error.
+*/
+NC_EXPORT NCResult NC_CC NCUtilCipherGetFlags(const NCUtilCipherContext* ctx);
+
+/*
+* Performs the desired Cipher option once. This may either cause an encryption
+* or decryption operation to be performed. Regardless of the operation, input data
+* is consumed and output data is produced.
+* @param encCtx A valid pointer to an initialized encryption context
+* @param libContext A valid pointer to an NCContext structure
+* @param sk A valid pointer to the sender's private key
+* @param pk A valid pointer to the receivers public key
+* @return NC_SUCCESS if the operation was successful, otherwise an error code. Use NCParseErrorCode to
+* get the error code and positional argument that caused the error.
+* @note This function should only be called once. However it is indempotent and deterministic
+* so the exact same operation should happen if called again.
+*/
+NC_EXPORT NCResult NC_CC NCUtilCipherUpdate(
+ NCUtilCipherContext* encCtx,
+ const NCContext* libContext,
+ const NCSecretKey* sk,
+ 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
+
+#endif /* NOSCRYPTUTIL_H */ \ No newline at end of file