Giter Club home page Giter Club logo

o1c's People

Contributors

jvz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

rucko24 matt36

o1c's Issues

C implementation of DRBG doesn't appear to mix in entropy

The C implementation of the DRBG doesn't appear to mix in the gathered entropy, resulting in predictable output.

In the function below the entropy is collected in the local array 'seed', but this is never passed to the hasher.

static void drbg_ensure_init(void) {
    if (!drbg.initialized) {
        drbg.counter = 0;
        uint8_t seed[BLAKE3_KEY_LEN];
        drbg_entropy(seed, BLAKE3_KEY_LEN);
        drbg_ratchet();
        drbg.initialized = true;
    }
}

I think a call to blake3_hasher_init_keyed() would be needed, which I think is equivalent to what the Java version is doing.

Consider variants of crypto primitives aligned with common standards

As a sort of enterprise-style idea, it would be useful to have standards-compliant versions of the APIs that are a little less modern. For example, American standards like FIPS 140 (see also FIPS publications) use AES-GCM instead of ChaCha20-Poly1305, ECDSA instead of EdDSA, and ECDH instead of XDH; there are similar combinations of primitives. There are other country standards that can be looked at as well like CRYPTREC, NESSIE, and all sorts of processes. While these tend to be older (and arguably less secure in practice), they are also still widely used and in demand.

Create a high level API for securing stored data

Consider the design of Themis: https://docs.cossacklabs.com/themis/crypto-theory/cryptosystems/secure-cell/

Similarly, in NaCl and libsodium, this concept is exposed as a secretbox API for authenticated encryption, and the secretstream API is used as a higher level API for authenticated encryption of arbitrary length data streams (the lower level API should be limited to smaller, well tested data limits).

The high level API to develop here should address a similar use case to secretstream.

Note that password-based keys are out of scope for this issue and is covered in #7.

Create a high level API for securing messages

Consider the design of Themis: https://docs.cossacklabs.com/themis/crypto-theory/cryptosystems/secure-message/

And consider the NaCl and libsodium API, the box APIs for authenticated public-key encryption, and the sealed box APIs for anonymous public-key encryption.

Create an analogous API here using XChaCha20-Poly1305 and X25519. This should cover sending encrypted messages and signed messages.

Essentially, given Alice and Bob both have XDH keypairs, we can compute a shared secret to generate a symmetric key. Implementing a perfect-forward-secrecy variant involving ephemeral keypairs and signatures for authentication rather than the static XDH keys would be out of scope for messages at this level and is scoped in #6.

Document how to use high level and low level APIs

The primary feature a good cryptographic library provides for making things easy to use and hard to misuse is documentation; without documentation, the only users who can understand these types of libraries are cryptographers and security engineers who already know how to use the low level primitives and have little need for a library like this. In particular, various vocabulary must be defined, use cases explained (e.g., when do you need non-repudiation versus just authenticity, using context metadata/AAD for simulating type information, identities, and session state, how to handle key exchange, authentication, etc.), and examples provided. For the high level API, these should be both documented in javadoc (for more API-specific concerns) as well as in the wiki or future website with an appropriate narrative. Links to established standards (and perhaps even papers) are expected, but links are not sufficient for the documentation; make sure to summarize any important information.

Some established cryptography projects offer a lot of documentation. See libsodium docs and Themis docs for some decent examples of higher level documentation.

Lower level APIs (e.g., crypto primitives) can be documented via javadoc. While it may be nice to mention some of the math going on in the background (e.g., prime order groups and permutations), this may get overly technical which may also end up incorrect without accompanying proofs.

Offer lightweight cryptographic alternatives for constrained environments

As currently being standardized by the NIST LWC project, there are some very promising algorithms proposed, particularly ones that use a sponge function as popularized by FIPS 202/SHA-3/Keccak. These sponge functions offer extremely versatile cryptographic primitives as demonstrated by libhydrogen and its use of the Gimli permutation.

Based on the ECRYPT benchmarks for the NIST LWC submissions, I propose supporting the top three permutations along with their higher level primitives (AEAD/MAC, MD, PRF, KDF):

  • Ascon - winner of the CAESER competition, current contestant in LWC
  • Gimli - interesting sponge with support for hardware as constrained as 8-bit microcontrollers
  • Xoodoo - taking the state shape formed in Gimli, this can be used in the Xoodyak scheme; note the project XKCP which has reference and optimized implementations of Xoodoo (and Keccak)

As these permutations and cryptographic schema are all fairly new, there doesn't seem to be much in the way of Java libraries supporting them already. Ascon has a Java reference implementation, but in order to support the algorithms, the C reference implementations should be ported to Java (along with fixing any non-constant-time checks in the reference implementations; the sample code seems to usually be lazy about this). At the very least, pure Java implementations should be offered. Linking to optimized C variants may be considered for alternatives, though it's also possible that there may be too much overhead from JNI.

Create a signature SPI for Ed25519 and Ed448

This signature SPI should expose low level functionality and use the standard functionality from RFC 8032. This should have at least two core implementations: one based on BouncyCastle, and the other based on Java 15.

Provide native implementations of supported algorithms

After working out some proof of concept code to try out https://github.com/mit-plv/fiat-crypto for elliptic curve stuff, it turns out to be fairly straightforward to build and include native variants of the algorithms being provided in the Java API through some fairly minimal JNI boilerplate. Since every crypto algorithm tends to have a reference C implementation, most of the symmetric algorithms can be easily imported that way rather than having to be ported again (the Java implementations are ported from C in the first place).

While the plain reference implementations are likely similar in performance to the Java ones, there are several assembly optimizations available for these algorithms and can be included for supported platforms (mostly for x86-64, though some may have additional platforms optimized).

Create a key exchange SPI for X25519 and X448

The key exchange SPI should expose low level functionality and use the standard implementation from RFC 7748. This should have at least two core implementations: one based on BouncyCastle, and the other based on Java 11.

Sodium compatibility

It'd be great to have a libsodium-compatibility mode that works with their box, sealed box, secretbox, etc., APIs.

Create an EdDSA scheme using Ristretto and Blake3

EdDSA provides a lot of tunable parameters, and when Ed25519 was initially created, it used SHA-512 with the note that the hash function could be updated to SHA-3 or other systems later on. Ed25519 still uses SHA-512 in standard contexts, but with the introduction of the Ristretto255 encoding as an alternative to splitting up keys into two algorithms (X25519 and Ed25519), we can provide a signature scheme to match the signcryption scheme that Ristretto support was initially introduced to enable. Instead of using SHA-3, we'll use Blake3, and improved version of Blake2s which was a finalist in SHA-3 anyways. As Blake3 provides 128-bit security, this matches fairly well with Curve25519.

In order to unify the key format used with EdDSA, this scheme will need to modify the previous simplicity assumed by using a scalar/element pair as with signcryption. Instead of using the scalar as the private key, a random 32-byte seed or secret is used as the private key as in EdDSA, then that key is hashed to get the scalar and a prefix key used for creating challenge hashes. In Ed25519, this works by taking the SHA-512 hash of the seed. In this scheme, we have two options: take the Blake3 hash of the seed and finalize its output to 64 bytes, or use the seed as the key for a keyed hash, then finalize 64 bytes of output. The plain hash method matches the EdDSA standard more exactly, though the availability of a keyed hash mode, if properly secure, can simplify the design here a little bit.

When calculating the (r, s) signature pair in an EdDSA scheme, s is still a scalar and is encoded in the usual way. However, r is now a Ristretto element rather than a normal extended Edwards coordinate in that the serialization algorithm should follow the Ristretto encoding instead of the traditional Edwards point compression.

It might be relevant to find out more about including a key id like in signcryption and whether it's useful here, too.

Create service provider descriptors API

In order for the various SPIs to actually be pluggable, some service descriptor classes need to be made to describe the various algorithms. These can be located by ServiceLoader and filtered based on their properties. In doing this, it might be necessary to break up the API/SPI module into its own so that a particular implementation can be chosen at runtime based on the classpath, modulepath, or some other configuration mechanism.

Note, however, that configuration mechanisms should be fairly minimal to avoid introducing insecure ways to use things.

Add support for BLAKE3

As a feasible option for a dependency-free modern hashing algorithm that's more widely supported than the more experimental lightweight cryptography, BLAKE3 support should be added. This will be particularly useful as an update/replacement for BLAKE2b (libsodium default for generic hashing).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.