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 
5 use core::ops::Deref;
6 
7 use 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)]
32 pub struct CipherSuite(u16);
33 
34 impl From<u16> for CipherSuite {
from(value: u16) -> Self35     fn from(value: u16) -> Self {
36         CipherSuite(value)
37     }
38 }
39 
40 impl From<CipherSuite> for u16 {
from(val: CipherSuite) -> Self41     fn from(val: CipherSuite) -> Self {
42         val.0
43     }
44 }
45 
46 impl Deref for CipherSuite {
47     type Target = u16;
48 
deref(&self) -> &Self::Target49     fn deref(&self) -> &Self::Target {
50         &self.0
51     }
52 }
53 
54 impl 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     /// Ciphersuite from a raw value.
new(value: u16) -> CipherSuite71     pub const fn new(value: u16) -> CipherSuite {
72         CipherSuite(value)
73     }
74 
75     /// Raw numerical value wrapped value.
raw_value(&self) -> u1676     pub const fn raw_value(&self) -> u16 {
77         self.0
78     }
79 
80     /// An iterator over all of the default MLS ciphersuites.
all() -> impl Iterator<Item = CipherSuite>81     pub fn all() -> impl Iterator<Item = CipherSuite> {
82         (1..=7).map(CipherSuite)
83     }
84 }
85 
86 /// Modes of HPKE operation.
87 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
88 #[repr(u8)]
89 pub enum HpkeModeId {
90     /// Base mode of HPKE for key exchange and AEAD cipher
91     Base = 0x00,
92     /// Base mode with a user provided PSK
93     Psk = 0x01,
94     /// Authenticated variant that authenticates possession of a KEM private key.
95     Auth = 0x02,
96     /// Authenticated variant that authenticates possession of a PSK as well as a KEM private key.
97     AuthPsk = 0x03,
98 }
99