Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit 202585c
Author: vnugent <public@vaughnnugent.com>
Date:   Thu Aug 22 17:51:51 2024 -0400

    update changelog and readme for 0.1.4

commit 2cc0099
Author: vnugent <public@vaughnnugent.com>
Date:   Sat Aug 17 21:53:16 2024 -0400

    fix: #8 patched reusable cipher encryption bug

commit 756a184
Author: vnugent <public@vaughnnugent.com>
Date:   Mon Aug 12 14:23:13 2024 -0400

    fix changelog tags, whoops

commit 489d90f
Merge: a639280 fa5e809
Author: vnugent <public@vaughnnugent.com>
Date:   Mon Aug 12 13:58:15 2024 -0400

    Merge branch 'master' into develop
  • Loading branch information
VnUgE committed Aug 23, 2024
1 parent fa5e809 commit ea15299
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 80 deletions.
20 changes: 15 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.1.3-beta] - 2024-08-6
### Added
- C# .NET 8.0 library wrapper for noscrypt
- NIP44 vector testing for encryption

## [0.1.4]

### Fixed
- [#8](https://www.vaughnnugent.com/resources/software/modules/noscrypt-issues?id=51) - an issue where nip44 encryption fails on reusable cipher instances

## [0.1.3]

### Added
- Utilities sidecar library for easy note encryption (noscryptutil.h)
- Utilities sidecar library for easy note encryption [(noscryptutil.h)](https://github.com/VnUgE/noscrypt/blob/v0.1.3/include/noscryptutil.h)
- 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)
Expand All @@ -35,7 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `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
## [0.1.2]

### Added

Expand All @@ -60,7 +69,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- NCContext structure defintion.
- Internal headers from the public include directory.

[unreleased]: https://github.com/VnUgE/noscrypt/compare/v0.1.3-beta...HEAD
[0.1.3-beta]: https://github.com/VnUgE/noscrypt/compare/v0.1.2...v0.1.3-beta
[unreleased]: https://github.com/VnUgE/noscrypt/compare/v0.1.4...HEAD
[0.1.4]: https://github.com/VnUgE/noscrypt/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/VnUgE/noscrypt/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/VnUgE/noscrypt/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/VnUgE/noscrypt/compare/v0.1.0...v0.1.1
79 changes: 21 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ NCVerifyMac()
```

## Motivation
At the time of building this project I have not come across any C-only libraries that exposed functionality for nostr specific cryptography. IMO it is easy to use the secp256k1 library incorrectly. In the process of building [NVault](https://github.com/VnUgE/NVault) NIP-44 came out in December and I realized my libraries were falling short for my needs for proper and safe nostr cryptographic operations, and I needed to start over and start with a good base that has all the basic functionality built with trusted and tested libraries.
At the time of building this project I have not come across any C-only libraries that exposed functionality for nostr specific cryptography. IMO it is easy to use the secp256k1 library [incorrectly](https://www.vaughnnugent.com/Blog/d9ab8a46cfa8d6bd59cf048fec8d73ffc44f881c). In the process of building [NVault](https://github.com/VnUgE/NVault) NIP-44 came out in December and I realized my libraries were falling short for my needs for proper and safe nostr cryptographic operations, and I needed to start over and start with a good base that has all the basic functionality built with trusted and tested libraries.

I wanted a compact and efficient utility library that was portable across systems and runtimes. I will primarily be using this library in a .NET environment, but would like to make a hardware signer sometime.

Expand All @@ -41,7 +41,7 @@ Testing is an will be important to a cryptography library, I take that responsib

### Hardness
- Time sensitive verification always uses fixed time comparison
- No explicit/dynamic memory allocations
- No explicit/dynamic memory allocations (in core library)
- Public API function input validation is on by default
- All stack allocated structures are securely zeroed before return
- Stack protection is enabled by default for GCC and MSVC compilers
Expand All @@ -60,65 +60,26 @@ The following table lists the supported platforms and cryptography libraries tha


## Getting started
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.
GitHub and Codeberg are only mirrors 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 source code](https://www.vaughnnugent.com/resources/software/modules/noscrypt)**
[__Project homepage__](https://www.vaughnnugent.com/resources/software/modules/noscrypt)
[__Startup & Install Guide__](https://www.vaughnnugent.com/resources/software/articles/62ca932f68b8e0b1b99dca6e1c9ffe5538205efb)
[__Extended Documentation__](https://www.vaughnnugent.com/resources/software/articles?tags=docs,_noscrypt)

### Getting the package
There are 3 ways to get the source code to build this project.
1. Download the signed `noscrypt-src.tgz` package from my website above (recommended)
2. Clone the GitHub repo `git clone https://github.com/VnUgE/noscrypt.git`
3. Download a github archive or release when they are available
### Super quick start
If you are in a hurry to try out noscrypt these steps will get you by. Otherwise website documentation is authoritative and I encourage you read the docs.

## Building
**The following build commands may be incomplete.** Please read documentation (link above) for all custom build configurations and tips.
#### Prerequisites
- Supported operating system and compiler from table above
- [CMake](https://cmake.org/download) build system
- [Taskfile.dev](https://taskfile.dev) to execute build recipe

### Using CMake
```shell
cmake -S . -Bbuild/ -DCMAKE_BUILD_TYPE=Release
```

Enable built-in tests and debug mode
```shell
cmake -S . -Bbuild/test -DCMAKE_BUILD_TYPE=Debug -DNC_BUILD_TESTS=ON
```

Specify the crypto library
```shell
cmake -S . -Bbuild/ -DCMAKE_BUILD_TYPE=Release -DCRYPTO_LIB=<openssl | mbedtls | bcrypt>
```

Install library globally
```shell
cmake --install build/
```

### Using Task
A [Taskfile](https://taskfile.dev) file is included for easy building if you wish to build in easy mode! Use the `task --list` to see all available commands. The default command `task` will build the library locally in release mode using defaults.

```shell
task
```
Build in debug mode with tests enabled
```shell
task build-debug
```

Build in debug mode, with testing enabled, then runs the test executable after it's built
```shell
task test
```

Install globally. Run after running the default task or `build-debug` task
```shell
task install
```

Task accepts any extra arguments following `--` and passes them to the cmake build command.
Example:
```shell
task <command> -- -DCMAKE_X_X=x
mkdir noscrypt/ && cd noscrypt/
wget https://www.vaughnnugent.com/public/resources/software/builds/noscrypt/<master-git-hash>/noscrypt/noscrypt-src.tgz
tar -xzf noscrypt-src.tgz
task
sudo task install
```

## Notes
Expand All @@ -129,13 +90,15 @@ Build packages on my website are "manual" I use an internal tool called *vnbuild
There are currently 2 branches I use because of my build process. `develop` and `master`. All changes happen in develop, then are merged to master when I feel like they are stable enough. After some testing and time, a tag and release will become available.

#### Windows Dlls
You may notice that I have msvc pre-compiled packages available for download. I have not compatibility tested them yet so they should only support Windows 10/Server version 1904 running amd64 processors.
msvc pre-compiled packages available for download on the website package page. I have not compatibility tested them yet so they should only support Windows NT version 1904 (10/Server 2016 and later) running amd64 processors.

## License
The software in this repository is licensed to you under the GNU Lesser GPL v2.1 or later. `SPDX-License-Identifier: LGPL-2.1-or-later` see the [LICENSE](LICENSE) file for more details.

## Donations
If you feel so inclined to support me an this project, donations are welcome and much appreciated.
If you feel so inclined to support me an this project, donations are welcome and much appreciated. LNURL coming soon.

BTC On-Chain: ``bc1qgj4fk6gdu8lnhd4zqzgxgcts0vlwcv3rqznxn9``

I am also a member of [GitCitadel](https://next.nostrudel.ninja/#/wiki/topic/gitcitadel-project) so feel free to [send some sats](https://geyser.fund/project/gitcitadel) that way too!

52 changes: 35 additions & 17 deletions src/noscryptutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@


#define _nc_mem_free(x) if(x != NULL) { free(x); x = NULL; }
#define _nc_mem_alloc(elements, size) calloc(elements, size);
#define _nc_mem_alloc(elements, size) calloc(elements, size)
#define ZERO_FILL ncCryptoSecureZero

#ifndef NC_INPUT_VALIDATION_OFF
Expand Down Expand Up @@ -129,8 +129,11 @@ static _nc_fn_inline span_t _ncUtilAllocSpan(uint32_t count, size_t size)

#endif

span.data = _nc_mem_alloc((size_t)count, size);
span.size = (uint32_t)count;
ncSpanInit(
&span,
_nc_mem_alloc((size_t)count, size),
(uint32_t)count
);

return span;
}
Expand Down Expand Up @@ -233,7 +236,7 @@ static _nc_fn_inline span_t _nip44GetMacData(span_t payload)
return ncSpanSlice(
payload,
NIP44_VERSION_SIZE,
payload.size - (NIP44_VERSION_SIZE + NC_ENCRYPTION_MAC_SIZE)
ncSpanGetSize(payload) - (NIP44_VERSION_SIZE + NC_ENCRYPTION_MAC_SIZE)
);
}

Expand All @@ -246,7 +249,7 @@ static _nc_fn_inline span_t _nip44GetMacOutput(span_t payload)
*/
return ncSpanSlice(
payload,
payload.size - NC_ENCRYPTION_MAC_SIZE,
ncSpanGetSize(payload) - NC_ENCRYPTION_MAC_SIZE,
NC_ENCRYPTION_MAC_SIZE
);
}
Expand All @@ -259,7 +262,7 @@ static _nc_fn_inline int _nip44ParseSegments(
cspan_t* cipherText
)
{
if (payload.size < NIP44_MIN_PAYLOAD_SIZE)
if (ncSpanGetSizeC(payload) < NIP44_MIN_PAYLOAD_SIZE)
{
return 0;
}
Expand All @@ -276,7 +279,7 @@ static _nc_fn_inline int _nip44ParseSegments(
*/
*mac = ncSpanSliceC(
payload,
payload.size - NC_ENCRYPTION_MAC_SIZE,
ncSpanGetSizeC(payload) - NC_ENCRYPTION_MAC_SIZE,
NC_ENCRYPTION_MAC_SIZE
);

Expand All @@ -286,7 +289,7 @@ static _nc_fn_inline int _nip44ParseSegments(
*macData = ncSpanSliceC(
payload,
NIP44_VERSION_SIZE,
payload.size - (NIP44_VERSION_SIZE + NC_ENCRYPTION_MAC_SIZE)
ncSpanGetSizeC(payload) - (NIP44_VERSION_SIZE + NC_ENCRYPTION_MAC_SIZE)
);

/*
Expand All @@ -295,7 +298,7 @@ static _nc_fn_inline int _nip44ParseSegments(
*cipherText = ncSpanSliceC(
payload,
NIP44_VERSION_SIZE + NIP44_NONCE_SIZE,
payload.size - (NIP44_VERSION_SIZE + NIP44_NONCE_SIZE + NC_ENCRYPTION_MAC_SIZE)
ncSpanGetSizeC(payload) - (NIP44_VERSION_SIZE + NIP44_NONCE_SIZE + NC_ENCRYPTION_MAC_SIZE)
);

return 1;
Expand Down Expand Up @@ -351,8 +354,21 @@ static NCResult _nip44EncryptCompleteCore(

outPos = 0;
encArgs = state->encArgs;
message = state->buffer.output;
plainText = state->buffer.input;

/*
* Output buffer may be reused for multiple operations
* so it may be larger than the actual output size but
* it is always guaranteed to be large enough to hold the
* output data.
*
* slice has debug guards to ensure output is large enough
*/
message = ncSpanSlice(
state->buffer.output,
0,
_calcNip44TotalOutSize(plainText.size)
);

DEBUG_ASSERT(encArgs.version == NC_ENC_VERSION_NIP44);

Expand Down Expand Up @@ -440,7 +456,9 @@ static NCResult _nip44EncryptCompleteCore(
ncSpanGetSizeC(plainText)
);

/* Move position pointer directly after final padding bytes */
/*
* Move position pointer directly after final padding bytes
*/
outPos += encArgs.dataSize;

result = NCEncrypt(libContext, sk, pk, &encArgs);
Expand Down Expand Up @@ -473,7 +491,7 @@ static NCResult _nip44EncryptCompleteCore(

outPos += NC_ENCRYPTION_MAC_SIZE;

DEBUG_ASSERT2(outPos == message.size, "Buffer under/overflow detected");
DEBUG_ASSERT2(outPos == ncSpanGetSize(message), "Buffer under/overflow detected");

/* publish all message bytes to output */
_cipherPublishOutput(state, 0, outPos);
Expand Down Expand Up @@ -607,7 +625,7 @@ static NCResult _nip44DecryptCompleteCore(
*/
_cipherPublishOutput(state, NIP44_PT_LEN_SIZE, ptSize);

DEBUG_ASSERT(ncSpanGetSizeC(state->buffer.actualOutput) < cipherText.size);
DEBUG_ASSERT(ncSpanGetSizeC(state->buffer.actualOutput) < ncSpanGetSizeC(cipherText));

return NC_SUCCESS;
}
Expand Down Expand Up @@ -782,7 +800,7 @@ NC_EXPORT NCResult NC_CC NCUtilCipherInit(
* data reuse it, otherwise free it and allocate a new buffer
*/

if (outputSize <= encCtx->buffer.output.size)
if (outputSize <= ncSpanGetSize(encCtx->buffer.output))
{
_ncUtilZeroSpan(encCtx->buffer.output);

Expand Down Expand Up @@ -829,7 +847,7 @@ NC_EXPORT NCResult NC_CC NCUtilCipherGetOutputSize(const NCUtilCipherContext* en
return E_CIPHER_NO_OUTPUT;
}

return (NCResult)(encCtx->buffer.actualOutput.size);
return (NCResult)(ncSpanGetSizeC(encCtx->buffer.actualOutput));
}

NC_EXPORT NCResult NC_CC NCUtilCipherReadOutput(
Expand All @@ -847,15 +865,15 @@ NC_EXPORT NCResult NC_CC NCUtilCipherReadOutput(
}

/* Buffer must be as large as the output data */
CHECK_ARG_RANGE(outputSize, encCtx->buffer.actualOutput.size, UINT32_MAX, 2);
CHECK_ARG_RANGE(outputSize, ncSpanGetSizeC(encCtx->buffer.actualOutput), UINT32_MAX, 2);

ncSpanReadC(
encCtx->buffer.actualOutput,
output,
outputSize
);

return (NCResult)encCtx->buffer.actualOutput.size;
return (NCResult)(ncSpanGetSizeC(encCtx->buffer.actualOutput));
}

NC_EXPORT NCResult NC_CC NCUtilCipherSetProperty(
Expand Down

0 comments on commit ea15299

Please sign in to comment.