mls_rs_core/crypto/cipher_suite.rs
1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// Copyright by contributors to this project.
3// SPDX-License-Identifier: (Apache-2.0 OR MIT)
4
5use core::ops::Deref;
6
7use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
8
9/// Wrapper type representing a ciphersuite identifier
10/// along with default values defined by the MLS RFC. Custom ciphersuites
11/// can be defined using a custom [`CryptoProvider`](crate::crypto::CryptoProvider).
12///
13/// ## Default Ciphersuites
14///
15/// Note: KEM values are defined by the HPKE standard (RFC 9180).
16///
17/// | | | | | |
18/// |----|-------------|---------|---------|------------------|
19/// | ID | KEM | AEAD | Hash Function | Signature Scheme |
20/// | 1 | DHKEMX25519 | AES 128 | SHA 256 | Ed25519 |
21/// | 2 | DHKEMP256 | AES 128 | SHA 256 | P256 |
22/// | 3 | DHKEMX25519 | ChaCha20Poly1305 | SHA 256 | Ed25519 |
23/// | 4 | DHKEMX448 | AES 256 | SHA 512 | Ed448 |
24/// | 5 | DHKEMP521 | AES 256 | SHA 512 | P521 |
25/// | 6 | DHKEMX448 | ChaCha20Poly1305 | SHA 512 | Ed448 |
26/// | 7 | DHKEMP384 | AES 256 | SHA 512 | P384 |
27#[derive(Debug, Copy, Clone, Eq, PartialEq, MlsSize, MlsEncode, MlsDecode, PartialOrd, Ord)]
28#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
29#[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::ffi_type)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31#[repr(transparent)]
32pub struct CipherSuite(u16);
33
34impl From<u16> for CipherSuite {
35 fn from(value: u16) -> Self {
36 CipherSuite(value)
37 }
38}
39
40impl From<CipherSuite> for u16 {
41 fn from(val: CipherSuite) -> Self {
42 val.0
43 }
44}
45
46impl Deref for CipherSuite {
47 type Target = u16;
48
49 fn deref(&self) -> &Self::Target {
50 &self.0
51 }
52}
53
54impl CipherSuite {
55 /// MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519
56 pub const CURVE25519_AES128: CipherSuite = CipherSuite(1);
57 /// MLS_128_DHKEMP256_AES128GCM_SHA256_P256
58 pub const P256_AES128: CipherSuite = CipherSuite(2);
59 /// MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519
60 pub const CURVE25519_CHACHA: CipherSuite = CipherSuite(3);
61 /// MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448
62 pub const CURVE448_AES256: CipherSuite = CipherSuite(4);
63 /// MLS_256_DHKEMP521_AES256GCM_SHA512_P521
64 pub const P521_AES256: CipherSuite = CipherSuite(5);
65 /// MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448
66 pub const CURVE448_CHACHA: CipherSuite = CipherSuite(6);
67 /// MLS_256_DHKEMP384_AES256GCM_SHA384_P384
68 pub const P384_AES256: CipherSuite = CipherSuite(7);
69
70 /// So far, there are no official PQ cipher suites
71 #[cfg(feature = "post-quantum")]
72 pub const ML_KEM_512: CipherSuite = CipherSuite(65001);
73 #[cfg(feature = "post-quantum")]
74 pub const ML_KEM_768: CipherSuite = CipherSuite(65002);
75 #[cfg(feature = "post-quantum")]
76 pub const ML_KEM_1024: CipherSuite = CipherSuite(65003);
77
78 /// So far, there are no official PQ cipher suites
79 #[cfg(feature = "post-quantum")]
80 pub const ML_KEM_768_X25519: CipherSuite = CipherSuite(65100);
81
82 /// Ciphersuite from a raw value.
83 pub const fn new(value: u16) -> CipherSuite {
84 CipherSuite(value)
85 }
86
87 /// Raw numerical value wrapped value.
88 pub const fn raw_value(&self) -> u16 {
89 self.0
90 }
91
92 /// An iterator over all of the default MLS ciphersuites.
93 pub fn all() -> impl Iterator<Item = CipherSuite> {
94 (1..=7).map(CipherSuite)
95 }
96}
97
98/// Modes of HPKE operation.
99#[derive(Clone, Copy, Debug, Eq, PartialEq)]
100#[repr(u8)]
101pub enum HpkeModeId {
102 /// Base mode of HPKE for key exchange and AEAD cipher
103 Base = 0x00,
104 /// Base mode with a user provided PSK
105 Psk = 0x01,
106 /// Authenticated variant that authenticates possession of a KEM private key.
107 Auth = 0x02,
108 /// Authenticated variant that authenticates possession of a PSK as well as a KEM private key.
109 AuthPsk = 0x03,
110}