Mundane is a Rust cryptography library backed by BoringSSL that is difficult

to misuse, ergonomic, and performant (in that order)

Mundane

Mundane is a Rust cryptography library backed by BoringSSL that is difficult to misuse, ergonomic, and performant (in that order).

Issues and Contributions

We use GitHub issues for issue tracking, and Gerrit for code reviews. See CONTRIBUTING.md for more details.

Dependencies

Rust 1.36 or newer is required.

Mundane vendors a copy of the BoringSSL source, so BoringSSL does not need to be installed locally in order to build. However, the BoringSSL build system has the following dependencies:

  • CMake 2.8.11 or later
  • Perl 5.6.1 or later. See BoringSSL's build instructions for what to do if CMake fails to find Perl on your system.
  • Either Make or Ninja. Ninja is preferable, as it makes compilation significantly faster; if both are present, Ninja will be used. On Windows, Ninja is required.
  • A C++ compiler
  • Go 1.10 or later
  • To build the x86 and x86_64 assembly, your assembler must support AVX2 instructions and MOVBE. If using GNU binutils, you must have 2.22 or later.

In order to avoid errors at link time due to conflicting symbols, we build BoringSSL with a custom prefix for all of its symbols which is based on the name and version of this crate. That way, even if multiple different versions of Mundane are present in the same dependency graph, none of the symbols from one version's BoringSSL will conflict with the symbols from another version's BoringSSL.

Supported platforms

Mundane supports being built on and for Linux and Mac. Windows support is under development. Cross-compilation is not supported.

License

Everything outside of the boringssl/boringssl directory is licensed under an MIT license which can be found in the LICENSE file. Everything in the boringssl/boringssl directory is licensed with a license that can be found in the boringssl/boringssl/LICENSE file.

Disclaimer: Mundane is not an officially supported Google product.

Issues

Collection of the latest Issues

dwj1210

dwj1210

0

I noticed this comment, the function sign() will both hashing and signing the message.

image

how can i sign the message without hashing ?

Looking forward to your reply ~

martin-lueker

martin-lueker

3

Hello, I recently had the pleasure of building your crate when I noticed that the dependencies may be out of date. It would appear that mundane currently requires cmake 3.3 or higher:

(Paths redacted below)

joshlf

joshlf

experience-hard
0

Per @davidben's comment here:

I think you should probably think about what things you want to support and build an API around that.

  • What flavors of RSA private keys do you believe in? Just CRT? n/e/d as well?
  • If you support multiple, do you want to jam them into one type or separate types? (Separate might make more sense given only CRT is serializable.)

Read the entire comment thread for more context.

We should answer these questions, document them clearly in our RSA code, and then update the organization of our RSA implementation as appropriate.

joshlf

joshlf

experience-hard
7

To err on the safe side, we initially made our key objects neither Send nor Sync. However, BoringSSL provides concurrency semantics for key objects that allow us to relax these restrictions. In particular, key objects' reference counts are incremented and decremented atomically, and all BoringSSL operations on keys have well-defined concurrency safety semantics.

I propose that we implement Sync on key objects, and use BoringSSL's definition of which functions are mutating to decide which methods to have take a &mut self vs a &self receiver.

An aside on Clone and reference counting

Currently, keys are reference counted, and cloning a Mundane key object obtains a new reference-counted reference to the same underlying object. Unfortunately, we cannot implement either Send or Sync so long as it's possible to obtain multiple references to the same underlying object.

If reference-counted key objects are Send, then different clones could be sent to different threads, and we'd have no way of preventing those two separate clones from being operated on using &mut self methods concurrently, which would be unsound.

If reference-counted key objects are Sync, then different clones owned by one thread could be accessed concurrently from different threads, and we'd have no way of preventing those two separate clones from being operated on using &mut self methods concurrently, which would be unsound.

Thus, I conclude that we must remove the ability to clone key objects. The primary benefit to reference counting in BoringSSL is to be able to use keys concurrently from multiple threads at once. Since Rust's lifetime system allows us to share references across threads safely, we get the same advantage even without reference counting. Even if reference counting were desired, we could put a Mundane key object inside of an Rc or an Arc and get the same effect.

Thus, the concrete tasks are:

  • Remove the ability to Clone key objects
  • Audit the codebase to ensure that all mutating BoringSSL functions are exposed via &mut self methods, and document our strategy and reasoning in code comments
  • Implement Send and Sync on key objects

Old (incorrect) text:

BoringSSL key types are reference-counted, and use reference counting to implement Clone. While the reference counting itself is thread-safe (see CRYPTO_refcount_xxx, crypto/internal.h), it's not clear that all operations on keys are also thread-safe. In other words, having two key objects in different threads which are both references to the same underlying BoringSSL object may mean that calling methods on those objects concurrently is unsound. As a result, our key objects do not implement Send.

Eventually, we will want to identify which methods are thread-safe and which are not. This is not only a prerequisite for making our key objects Send, it's also a prerequisite for making them Sync. However, we can much more easily unblock making our key objects Send by just not implementing Clone so that a given key object is always the only reference to its underlying BoringSSL object.

joshlf

joshlf

0

Currently, our error type can be printed as a string, which provides a lot of information about the error. Cryptography errors are a notorious source of information leak, as programmers often misuse the errors and either compute on them or expose them in ways that they shouldn't. Ring, for example, takes the much more aggressive approach of having an error type that contains no information at all.

I'm not sure what the right thing for us to do here is, since it seems useful to provide some error information, such as about parsing failures. But we need to strike the right balance, and exposing as much as we do now may be too much. This is also compounded by the fact that a lot of the errors we would want to expose (like parsing errors) come from BoringSSL, and BoringSSL's errors cannot be inspected programmatically.

joshlf

joshlf

experience-medium
9

UPDATE: ASan has been implemented in https://github.com/google/mundane/commit/0148297bf1c5bb8ccc8acbc7abcc15cb4b53d6ee. We should still run tests with MSan, although it's less important than ASan.

=== old text ===

We should enable ASan and MSan when running cargo test in order to catch issues with our use of the BoringSSL API. ASan should help catch issues with reference counting, allocation, and freeing, while MSan should help catch issues with memory initialization.

joshlf

joshlf

experience-medium
2

Currently, we have a few small smoke tests to make sure that we don't decrement BoringSSL refcounts too far. However, we have no tests to ensure that we decrement refcounts far enough (in other words, that we don't leak resources by leaving unused objects allocated and constructed).

We should also test the latter. The way to do this is probably to figure out how to inspect the refcount on a BoringSSL object and use that mechanism to ensure that the refcount on these objects is 1 when we only hold a single reference. That said, perhaps there's a better way to do this.

EDIT: Let's first try to see if we can enable ASan (#15), which should address this.

inejge

inejge

4

Currently, building Mundane requires Go 1.11+. Utilities in Go are used for three tasks:

  1. Generating the interned error message bundle and its index (crypto/err_data.c in the build tree, from crypto/err/*.errordata in the source tree).

  2. Extracting the names of public symbols from the archive created in the first library build (crypto/libcrypto.a) and saving the result in symbols.txt above the two build directories.

  3. Generating the headers with substitutions from regular to versioned symbol names, using the result of the previous utility.

Those are rather simple programs and I have reimplemented them in Rust without much difficulty. Integrating them into build.rs could lead to elimination of Go as a build dependency of Mundane. While having any single dependency is not particularly onerous, I believe that minimizing their number eases the acceptance of a package, both for developers and end users. Even more so since Go 1.11 is not available on current LTS versions of popular distros.

Would there be any interest of pursuing this further?

8573

8573

0

Both Mundane and the better-established ring are Rust cryptographic libraries that have difficulty-of-misuse as an explicit goal and are based on BoringSSL. I would like to suggest that any significant differences between them be documented such that developers in the target audience (whichever that may be) can make an informed choice between these two libraries.

cc @briansmith

gsquire

gsquire

experience-easy
8

This may have been a conscious choice to avoid but I wanted to see if it makes sense to use some type that implements AsRef<[u8]> in place of &[u8]? This would make it easy for users to supply &str or String in addition to &[u8] when calling functions. I thought this would be in line with the idea that mundane is intended to be easy to use.

joshlf

joshlf

experience-hard
3

Open questions:

  • Presumably individual block operations should be behind a feature flag since they're low level, but we still want to be able to expose high-level cipher modes (e.g., AES-GCM) via composition. How do we do that?
  • What block cipher modes do we have to support?
  • Do we want to build in padding?
    • Do we want to expose a non-padding variant as well?
    • How do we ensure that padding is only with safe block cipher modes (e.g., don't allow PKCS11 padding w/ CBC, which is vulnerable to a padding oracle attack)

Information - Updated Jun 22, 2022

Stars: 1.0K
Forks: 44
Issues: 12

Repositories & Extras

A (mostly) pure-Rust implementation of various common cryptographic algorithms

Rust-Crypto seeks to create practical, auditable, pure-Rust implementations of common cryptographic

A (mostly) pure-Rust implementation of various common cryptographic algorithms

Orion is a cryptography library written in pure Rust

It aims to provide easy and usable crypto while trying to minimize the use of unsafe code

Orion is a cryptography library written in pure Rust

Rustls is a modern TLS library written in Rust

ring for cryptography and rustls-pemfile crate

Rustls is a modern TLS library written in Rust

Rustls is a modern TLS library written in Rust

ring for cryptography and rustls-pemfile crate

Rustls is a modern TLS library written in Rust

A (mostly) pure-Rust implementation of various common cryptographic algorithms

Rust-Crypto seeks to create practical, auditable, pure-Rust implementations of common cryptographic

A (mostly) pure-Rust implementation of various common cryptographic algorithms

This repository holds a Rust port of Google's Tink cryptography library

This repository holds a Rust port of Google's RustCrypto crates – this repo focuses on making

This repository holds a Rust port of Google's Tink cryptography library

A cryptography library that is mainly implemented in Rust

I aim to implement bindings to other languages such as C/C++ and Python

A cryptography library that is mainly implemented in Rust

Libsm is an open source pure rust library of China Cryptographic Algorithm Standards

It is completed by a collaborative effort between the Cryptape Technology LLC

Libsm is an open source pure rust library of China Cryptographic Algorithm Standards

Cryptographic algorithms in pure Rust

The main interface to these crates is the RustCrypto traits

Cryptographic algorithms in pure Rust

A collection of cryptography functions written in Rust

rustup -- curl --proto '=https' --tlsv1

A collection of cryptography functions written in Rust
Facebook Instagram Twitter GitHub Dribbble
Privacy