sos_core/crypto/cipher/
mod.rs1use super::{AeadPack, Nonce, PrivateKey};
3use crate::{Error, Result};
4use age::x25519::Recipient;
5use serde::{Deserialize, Serialize};
6use std::{fmt, str::FromStr};
7
8pub mod aes_gcm_256;
9pub mod x25519;
10pub mod xchacha20_poly1305;
11
12pub const X_CHACHA20_POLY1305: u8 = 1;
14
15pub const AES_GCM_256: u8 = 2;
17
18pub const X25519: u8 = 3;
20
21#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, Serialize, Deserialize)]
23pub enum Cipher {
24 XChaCha20Poly1305,
26 AesGcm256,
28 X25519,
30}
31
32impl Cipher {
33 pub async fn encrypt_symmetric(
35 &self,
36 key: &PrivateKey,
37 plaintext: &[u8],
38 nonce: Option<Nonce>,
39 ) -> Result<AeadPack> {
40 match self {
41 Cipher::XChaCha20Poly1305 => match key {
42 PrivateKey::Symmetric(key) => {
43 xchacha20_poly1305::encrypt(key, plaintext, nonce)
44 }
45 _ => Err(Error::NotSymmetric),
46 },
47 Cipher::AesGcm256 => match key {
48 PrivateKey::Symmetric(key) => {
49 aes_gcm_256::encrypt(key, plaintext, nonce)
50 }
51 _ => Err(Error::NotSymmetric),
52 },
53 _ => Err(Error::NotSymmetric),
54 }
55 }
56
57 pub async fn decrypt_symmetric(
59 &self,
60 key: &PrivateKey,
61 aead: &AeadPack,
62 ) -> Result<Vec<u8>> {
63 match self {
64 Cipher::XChaCha20Poly1305 => match key {
65 PrivateKey::Symmetric(key) => {
66 xchacha20_poly1305::decrypt(key, aead)
67 }
68 _ => Err(Error::NotSymmetric),
69 },
70 Cipher::AesGcm256 => match key {
71 PrivateKey::Symmetric(key) => aes_gcm_256::decrypt(key, aead),
72 _ => Err(Error::NotSymmetric),
73 },
74 _ => Err(Error::NotSymmetric),
75 }
76 }
77
78 pub async fn encrypt_asymmetric(
80 &self,
81 key: &PrivateKey,
82 plaintext: &[u8],
83 recipients: Vec<Recipient>,
84 ) -> Result<AeadPack> {
85 match self {
86 Cipher::X25519 => match key {
87 PrivateKey::Asymmetric(_) => {
88 x25519::encrypt(plaintext, recipients).await
89 }
90 _ => Err(Error::NotAsymmetric),
91 },
92 _ => Err(Error::NotAsymmetric),
93 }
94 }
95
96 pub async fn decrypt_asymmetric(
98 &self,
99 key: &PrivateKey,
100 aead: &AeadPack,
101 ) -> Result<Vec<u8>> {
102 match self {
103 Cipher::X25519 => match key {
104 PrivateKey::Asymmetric(identity) => {
105 x25519::decrypt(identity, aead).await
106 }
107 _ => Err(Error::NotAsymmetric),
108 },
109 _ => Err(Error::NotAsymmetric),
110 }
111 }
112}
113
114impl Default for Cipher {
115 fn default() -> Self {
116 Self::AesGcm256
117 }
118}
119
120impl fmt::Display for Cipher {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 write!(f, "{}", {
123 match self {
124 Self::XChaCha20Poly1305 => "x_chacha20_poly1305",
125 Self::AesGcm256 => "aes_gcm_256",
126 Self::X25519 => "age_x25519",
127 }
128 })
129 }
130}
131
132impl FromStr for Cipher {
133 type Err = Error;
134
135 fn from_str(s: &str) -> Result<Self> {
136 match s {
137 "x_chacha20_poly1305" => Ok(Self::XChaCha20Poly1305),
138 "aes_gcm_256" => Ok(Self::AesGcm256),
139 "age_x25519" => Ok(Self::X25519),
140 _ => Err(Error::InvalidCipher(s.to_string())),
141 }
142 }
143}
144
145impl From<&Cipher> for u8 {
146 fn from(value: &Cipher) -> Self {
147 match value {
148 Cipher::XChaCha20Poly1305 => X_CHACHA20_POLY1305,
149 Cipher::AesGcm256 => AES_GCM_256,
150 Cipher::X25519 => X25519,
151 }
152 }
153}
154
155impl TryFrom<u8> for Cipher {
156 type Error = Error;
157 fn try_from(value: u8) -> std::result::Result<Self, Self::Error> {
158 match value {
159 X_CHACHA20_POLY1305 => Ok(Cipher::XChaCha20Poly1305),
160 AES_GCM_256 => Ok(Cipher::AesGcm256),
161 X25519 => Ok(Cipher::X25519),
162 _ => Err(Error::InvalidCipher(value.to_string())),
163 }
164 }
165}