Authenticated Encryption with Associated Data Algorithms: high-level encryption ciphers

Related tags

Cryptography AEADs
Overview

RustCrypto: Authenticated Encryption with Associated Data (AEAD) Algorithms

CodeCov Status Project Chat dependency status

Collection of Authenticated Encryption with Associated Data (AEAD) algorithms written in pure Rust.

AEADs are high-level symmetric encryption primitives which defend against a wide range of potential attacks (i.e. IND-CCA3).

Usage

Crates functionality is expressed in terms of traits defined in the aead crate.

Crates

Name Algorithm Crates.io Documentation MSRV
aes-gcm-siv AES-GCM-SIV crates.io Documentation 1.49
aes-gcm AES-GCM crates.io Documentation 1.49
aes-siv AES-SIV crates.io Documentation 1.49
ccm CCM crates.io Documentation 1.41
chacha20poly1305 (X)ChaCha20Poly1305 crates.io Documentation 1.51
deoxys Deoxys-I/II crates.io Documentation 1.50
eax EAX crates.io Documentation 1.41
mgm MGM crates.io Documentation 1.41
xsalsa20poly1305 XSalsa20Poly1305 crates.io Documentation 1.49

MSRV Policy

Minimum Supported Rust Version (MSRV) can be changed in the future, but it will be done with a minor version bump.

License

All crates licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Deoxys

    Deoxys

    This is an initial implementation of the Deoxys AEAD. The Deoxys-II variant has been selected as the first choice for defense in-depth during the CAESAR competition.

    A couple of things I checked:

    • All the official test vectors passes (see the tests/ folder)
    • The crate is [no_std]
    • The crate compiles and run in WASM.

    There is still improvements to be done on the performance side, but this seems good enough for a first release.

    opened by zer0x64 49
  • eax: Introduce a streaming API

    eax: Introduce a streaming API

    Introduces a stream module that implements EaxStream, which is the streaming variant of the regular Eax implemented here.

    This can be useful for two reasons, in addition to having the existing one-shot-like API:

    1. The associated data can be processed separately
    2. The protected data can be processed in a streaming fashion, rather than requiring it to be entirely allocated and contiguous.

    I'm trying to reuse the EAX implementation for use in Sequoia (Rust OpenPGP implementation) but unfortunately I need the streaming API variant for that.

    Because the newly-introduced in-place API can be somewhat easily misused, I tried to mimic a linear type, forcing the user to explicitly consume and handle the resulting value after decryption. With std feature enabled, it aborts the process using a drop bomb pattern, unless it's forgotten by the EaxStream::finish associated function.

    Note that this changes the existing Eax implementation by first performing the decryption in-place and then checking against the expected tag, rather than scanning the ciphertext first to calculate tag and then decrypting if the tags match. I have to admit that I did that to share more of the implementation and leverage the testing framework test both implementations but I can revert that change if needed.

    Let me know what you think about this and if this is something you'd consider merging in one form or another.

    opened by Xanewok 17
  • GCM: Allow nonces of any length

    GCM: Allow nonces of any length

    Currently, AesGcm only allows nonces with a length of 12 bytes. However, the the AES-GCM specification allows nonces of any length:

    screenshot20191206010437

    Is there a way to use AesGcm with a nonce of a length ≠ 12 bytes?

    opened by oberien 12
  • aes-gcm: Allow variable sized nonce at runtime

    aes-gcm: Allow variable sized nonce at runtime

    In Deno, WebCrypto nonces are coming from JavaScript at runtime and so generic compile-time nonces are not possible without setting a restriction on the user (Some packages in the Node ecosystem like cryptr use 128bit IVs instead of 96bit).

    It would be nice to have a non-generic-array based API for use cases like this :-)

    opened by littledivy 11
  • Outdated version of zeroize forced in aes-gcm-siv

    Outdated version of zeroize forced in aes-gcm-siv

    Currently the version of zeroize is required to be < 1.4 which conflicts with the latest version of secrecy, which needs zeroice to be >= 1.4.

    Is there a reason why zeroize is explicitly needed in that version, or can it be updated?

    opened by mervyn-mccreight 11
  • Add CCM

    Add CCM

    For now implementation does not use parallel block processing for CTR part. Also not all combinations of tag and nonce size are tested, only vectors from RFC 3610.

    cc @martindisch

    opened by newpavlov 10
  • [doc] user specified associated data API

    [doc] user specified associated data API

    Currently documentation on trait aead::Aead and specific instantiation of AEAD suites only cover how to directly encrypt a message with (by default) an empty associated data field,

    The Payload type can be used to provide Additional Associated Data (AAD) along with the message: this is an optional bytestring which is not encrypted, but is authenticated along with the message. Failure to pass the same AAD that was used during encryption will cause decryption to fail, which is useful if you would like to "bind" the ciphertext to some other identifier, like a digital signature key or other identifier.

    If I construct my own Payload with msg and aad specified, then how to pass to the encrypt() function is not so clear to me, cuz Payload itself doesn't implement Into<Payload>.

    I could be misunderstanding things, but maybe some examples in the documentation would be helpful. Thanks!

    opened by alxiong 9
  • aes-gcm online mode

    aes-gcm online mode

    Hello,

    Is it possible to have an online mode for AES-GCM (like EAX) ? I want to encrypt large chunk of data in a memory constraint way. The standard allows to cipher up to 64GiB. Note that I'm aware of the STREAM mode but it does not allow the ciphering of a large block all at once

    I'm also aware of the decryption unsafety but it is inherent of large chunk ciphering

    opened by BoOTheFurious 8
  • RustCrypto crates as an experimental impl for thrussh

    RustCrypto crates as an experimental impl for thrussh

    Hi folks,

    First of all, amazing work! Second, I am not sure if here is the right place to ask, since this is more a discussion than an issue. So forgive me if here is not the proper place.

    A bit of context: thrussh is an implementation of the SSH 2 protocol, both server-side and client-side. It uses libsodium to provide chacha20, poly1305, ed25519 and scalarmult_curve25519 functionalities. Recently I wondered if one could add an experimental feature gate to test an alternative impl using RustCrypto.

    What came up in the discussion was

    1. Are the RNGs robust to current computations (so a malicious agent cannot take advantage of them)?
    2. What you folks recommend to increase robustness, e.g., adding random timers around the crypto functions calls?

    Finally, I would be thrilled to know your thoughts on this.

    cc @P-E-Meunier

    opened by darleybarreto 8
  • Partial tag comparison

    Partial tag comparison

    Hi, I’m trying to use the eax crate to decrypt data with decrypt_in_place_detached but I only have the first 8 byte of the tag available as the network protocol I implement cuts off the other 8 byte of the 16 byte tag. All aead functions expect the whole tag, so I can’t find a way to decrypt the data.

    opened by Flakebi 8
  • A constant-time version of aes-gcm decrypt-in-place-detached?

    A constant-time version of aes-gcm decrypt-in-place-detached?

    Hi, I have a use-case that is roughly the following (simplified):

    • A private key exists only in an SGX enclave
    • A stream of ciphertexts are passed to the enclave, which it attempts to decrypt
    • It must remain a secret which ones were decryptable by the enclave and which ones aren't, taking into account side-channel leakage via code and data access patterns.

    Unfortunately I can't quite do that with the aes-gcm code as is:

        fn decrypt_in_place_detached(
            &self,
            nonce: &GenericArray<u8, NonceSize>,
            associated_data: &[u8],
            buffer: &mut [u8],
            tag: &Tag,
        ) -> Result<(), Error> {
            if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX {
                return Err(Error);
            }
    
            // TODO(tarcieri): interleave encryption with GHASH
            // See: <https://github.com/RustCrypto/AEADs/issues/74>
            let mut expected_tag = self.compute_tag(associated_data, buffer);
            let mut ctr = self.init_ctr(nonce);
            ctr.apply_keystream(&self.cipher, expected_tag.as_mut_slice());
    
            use subtle::ConstantTimeEq;
            if expected_tag.ct_eq(&tag).unwrap_u8() == 1 {
                ctr.apply_keystream(&self.cipher, buffer);
                Ok(())
            } else {
                Err(Error)
            }
        }
    

    What I would really like is a version of this function that looks like this for example:

        fn ct_decrypt_in_place_detached(
            &self,
            nonce: &GenericArray<u8, NonceSize>,
            associated_data: &[u8],
            buffer: &mut [u8],
            tag: &Tag,
        ) -> bool {
            if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX {
                return false;
            }
    
            // TODO(tarcieri): interleave encryption with GHASH
            // See: <https://github.com/RustCrypto/AEADs/issues/74>
            let mut expected_tag = self.compute_tag(associated_data, buffer);
            let mut ctr = self.init_ctr(nonce);
            ctr.apply_keystream(&self.cipher, expected_tag.as_mut_slice());
            ctr.apply_keystream(&self.cipher, buffer);
    
            use subtle::ConstantTimeEq;
            bool::from(expected_tag.ct_eq(&tag))
        }
    

    The key differences being:

    • ctr.apply_keystream(&self.cipher, buffer); happens unconditionally and we never branch on the outcome of mac check
    • Instead of returning Result, we return bool, or perhaps some subtle type. Because afaik there is no branchless way to access Result. (I don't know that I can assume that result.is_ok() won't contain a branch? I assume it boils down to a rust match against an enum, and would contain a branch unless the compiler optimized the branch away. I would hope that llvm can optimize this though.) But also, it's not clear that in rust, you can create Result type without branching?

    What do you think? Would you take a patch that (1) Adds ct_detached_in_place_decrypt to trait AeadInPlace in RustCrypto/traits? (and possibly, makes detached_in_place_decrypt chain to this by default?) OR (2) Adds a new trait AeadInPlaceCt or similar in RustCrypto/traits , and adds the function there, and implements it on AesGcm struct?

    Slight preference for not putting subtle types in an API because it will ease versioning?

    opened by cbeck88 8
  • AES-SIV-CMAC nonce sizes

    AES-SIV-CMAC nonce sizes

    RFC 5297 specifies AES-CIV-CMAC as being able to accept any nonce size >= 1. However, the implementation here only supports 16 byte nonces. Would it be possible to support the other nonce sizes? I guess this would require a more general change to move closer to the aead interface specified in rfc 5116?

    I am specifically asking for this as it would be required for me to support those different nonce sizes if I want to build a RFC-8915 compliant NTS server.

    opened by davidv1992 5
  • Question: How to safely increment Nonces?

    Question: How to safely increment Nonces?

    Hey, this might be a bit of a dumb question but: i want to encrypt multiple quite large byte slices, and increment the nonce in between the two calls... since reusing a (key, nonce) is very dangerous.

    i was wondering? can i just literally increment the value by one? or does the library split my byte slices into blocks, for which the nonce is also incremented, requiring me to increment the value by at least the amount of blocks in a slice?

    or should i use a random one every time? that doesn't really feel safer though... i mean it would be technically possible for a value to repeat randomly.

    uh is there a good approach for this? e.g an abstraction that promises me safety? or can you explain how the nonces are handled internally? whhich guarantees does my code need to enforce for these values, exactly?

    there is a possibility i am overthinking this and the value just has to be unique between calls but... uh better safe then sorry i'd be thankful if someone could briefly answer... it was hard to find anything on this topic since it's kind of implementation specific / a stupid question

    opened by DRKSLV 6
  • Confusing names for AES-SIV algorithms

    Confusing names for AES-SIV algorithms

    The current naming scheme in the AES-SIV uses a different naming scheme for the lengths than rfc5297, naming the algorithm lengths to the number of bits of security provided rather than the key length. This is highly confusing for potential users refering to standards documents and or the IANA registry of AEAD algorithm identifiers.

    From my perspective, ideally these aeads should follow the naming convention from the rfc, but if not this should be clearly indicated in the documentation so as to avoid pitfalls for new users.

    opened by davidv1992 1
  • ccm: Mention AES-CCM in README

    ccm: Mention AES-CCM in README

    This adds a mention of AES-CCM in CCM's README as an example.

    AES-CCM is the most prominent use case of CCM, as evidenced by the wikipedia articles both of CCM and its users always listing that combination.

    Practically, this ensures that users looking for aes-ccm at crates.io find this, especially if https://github.com/martindisch/aes-ccm/issues/9 is not followed up on. (Concrete example: I was a few steps short of starting to update the aes-ccm crate to recent traits when I found that issue which pointed me here; the present fix would have spared me that detour).

    opened by chrysn 3
  • Sundae

    Sundae

    This is an optimized implementation of the (SUNDAE)[https://tosc.iacr.org/index.php/ToSC/article/view/7296/6470] AEAD cipher using x86_64 instructions. SUNDAE reached the second stage of the (NIST lightweight cryptography competition)[https://csrc.nist.gov/Projects/lightweight-cryptography] as part of SUNDAE-GIFT and is generally paired well with low area, low power consumption block ciphers (like GIFT), because it was specifically designed for resource constrained environments such as IoT devices. It can also be used as a MAC algorithm, if only associated data is provided.

    This pull request contains a full implementation of the mode, no features missing (at least to my knowledge), though it would definitely be nice to implement an ARM version in the future.

    It comes with a pre-defined SundaeAes type using Aes128 as underlying block cipher, though I think I would swap that out for GIFT once (#322)[https://github.com/RustCrypto/block-ciphers/pull/322] is approved.

    I was able to benchmark an optimized C vs this implementation and found, that both operate almost equally, with C being around 0.4 cpb faster for lower buffer sizes and 0.12 cpb for bigger buffer sizes. On an Intel Core i7 8700k with 3.7GHz core clock the Rust implementation performed at 5.595 - 5.387cpb and the C implementation at 5.18 - 5.265cpb for buffer sizes from 1KiB to 16KiB, both using Aes128 as block cipher.

    The crate is [no_std] but one thing I have to point out is that I am using the u8x16 type from core::simd, which requires me to enable #![feature(portable_simd)], because it is still considered an unstable library feature.

    opened by Schmid7k 0
  • COLM

    COLM

    This is an optimized implementation of the COLM AEAD cipher using x86_64 instructions. COLM has been selected as the second choice for defense in-depth during the CAESAR competition.

    Currently it is only COLM0, meaning the COLM variant without intermediate tag generation.

    It comes with a pre-defined Colm0 type using Aes128 as underlying block cipher, as specified by the original COLM document, though it can be used with any block cipher.

    Given the same inputs it produces the same output as the reference implementation in C.

    Since I am in contact with an author of the original COLM specification I was able to benchmark an optimized C implementation against this optimized Rust implementation. Both versions behave almost equally in terms of performance, though the Rust implementation was slightly faster (diff of ~0.06cpb, so negligible) with smaller buffer sizes (<= 1KB), while the C implementation was slightly faster (diff of ~0.05cpb, again negligible) with bigger buffer sizes (>= 2KB). The general speed was 2.73 - 2.61cpb for buffer sizes of 1KB - 16KB on an Intel Core I7 8700k at 3.7GHz core clock.

    The crate is [no_std] but one thing I have to point out is that I am using the u8x16 type from core::simd, which requires me to enable #![feature(portable_simd)], because it is still considered an unstable library feature.

    I think this is good enough for an initial release though I can certainly still improve some parts of the encryption procedure. And then there is also the case of implementing it generic over the intermediate tag generation.

    opened by Schmid7k 6
Owner
Rust Crypto
Cryptographic algorithms written in pure Rust
Rust Crypto
✈️A private, authenticated, permissioned cargo registry

chartered a little dig at creating a private cargo repository with authenticated downloads, the plan is to have git connect to a git server we setup t

Jordan Doyle 121 Dec 26, 2022
Password-Authenticated Key Agreement protocols

RustCrypto: PAKEs Password-Authenticated Key Agreement protocols implementation. Warnings Crates in this repository have not yet received any formal c

Rust Crypto 81 Dec 5, 2022
Bessie - an authenticated, chunked cipher based on BLAKE3

Bessie Bessie is an authenticated, chunked cipher based on BLAKE3. Right now it's in the early design stages. See design.md. Although the Bessie ciphe

Jack O'Connor 12 Dec 9, 2022
Gnosis Safe Tx Service API client & associated tooling

Safe Transaction Service API Client Using the SDK Instantiate an API client use safe_sdk::SafeClient; /// From a chain id, by looking up hardcoded en

Nomad 3 Dec 15, 2022
A Rust Library of China's Standards of Encryption Algorithms (SM2/3/4)

Libsm Libsm is an open source pure rust library of China Cryptographic Algorithm Standards. It is completed by a collaborative effort between the Cryp

CITAHub 149 Dec 23, 2022
A Rust Implementation of China's Standards of Encryption Algorithms(SM2/SM3/SM4)

gm-rs A Pure Rust High-Performance Implementation of China's Standards of Encryption Algorithms(SM2/SM3/SM4) Usage Add this to your Cargo.toml: [depen

null 2 Oct 27, 2022
Chargo is a tool for file encryption/decryption. It's based on Argon2 and ChaCha20Poly1305 algorithms.

| Documentation Chargo is a tool for file encryption/decryption with password. It's based on Argon2 and ChaCha20Poly1305 algorithms. From arg2u with ♥

Airat Galiullin 7 Jan 1, 2023
Rust encryption library for practical time-lock encryption.

tlock_age: Hybrid Timelock Encryption/Decryption in Rust tlock_age is a library to encrypt and decrypt age filekey using tlock scheme. It provides an

Thibault 5 Mar 29, 2023
Rust DDC/CI high level library

ddc-enhanced-rs ddc-enhanced-rs is a cross platform Rust crate and Node package for controlling monitors with DDC/CI. Documentation Rust: https://docs

ThalusA 5 Oct 2, 2022
High-level networking library that extends the bevy_replicon library to allow snapshot interpolation and client-side prediction

bevy_replicon_snap A Snapshot Interpolation plugin for the networking solution bevy_replicon in the Bevy game engine. This library is a very rough pro

Ben 3 Oct 15, 2023
A guide for Mozilla's developers and data scientists to analyze and interpret the data gathered by our data collection systems.

Mozilla Data Documentation This documentation was written to help Mozillians analyze and interpret data collected by our products, such as Firefox and

Mozilla 75 Dec 1, 2022
A (mostly) pure-Rust implementation of various cryptographic algorithms.

Rust-Crypto A (mostly) pure-Rust implementation of various common cryptographic algorithms. Rust-Crypto seeks to create practical, auditable, pure-Rus

null 1.2k Dec 27, 2022
Port path module (and tests) of nodejs to rust using the same algorithms.

rusty_nodejs_path Port path module (and tests) of nodejs to rust using the same algorithms. crates.io Documents Progress posix path.basename(path[, ex

Yunfei He 10 Sep 25, 2022
Cryptographic signature algorithms: ECDSA, Ed25519

RustCrypto: signatures Support for digital signatures, which provide authentication of data using public-key cryptography. All algorithms reside in th

Rust Crypto 300 Jan 8, 2023
Collection of stream cipher algorithms

RustCrypto: stream ciphers Collection of stream cipher algorithms written in pure Rust. ⚠️ Security Warning: Hazmat! Crates in this repository do not

Rust Crypto 186 Dec 14, 2022
Collection of block cipher algorithms written in pure Rust

RustCrypto: block ciphers Collection of block ciphers and block modes written in pure Rust. Warnings Currently only the aes crate provides constant-ti

Rust Crypto 506 Jan 3, 2023
A collection of algorithms that can do join between two parties while preserving the privacy of keys on which the join happens

Private-ID Private-ID is a collection of algorithms to match records between two parties, while preserving the privacy of these records. We present tw

Meta Research 169 Dec 5, 2022
Opendp - The core library of differential privacy algorithms powering the OpenDP Project.

OpenDP The OpenDP Library is a modular collection of statistical algorithms that adhere to the definition of differential privacy. It can be used to b

OpenDP 176 Dec 27, 2022
Symmetric key-wrapping algorithms

RustCrypto: Key Wrapping Functions Collection of symmetric Key Wrapping Functions (KW) written in pure Rust. About "Key Wrapping" describes symmetric

Rust Crypto 5 Nov 28, 2022