sbd_e2e_crypto_client/
sodoken_crypto.rs1use crate::*;
2
3pub struct Encryptor {
5 sk: sodoken::SizedLockedArray<32>,
6 state: sodoken::secretstream::State,
7}
8
9impl Encryptor {
10 fn init(&mut self) -> Result<[u8; 24]> {
12 let mut header = [0; 24];
13 sodoken::secretstream::init_push(
14 &mut self.state,
15 &mut header,
16 &self.sk.lock(),
17 )?;
18 Ok(header)
19 }
20
21 pub fn encrypt(
24 &mut self,
25 pub_key: &[u8],
26 msg: &[u8],
27 ) -> Result<protocol::Protocol> {
28 let mut out = bytes::BytesMut::zeroed(
29 32 + 1 + msg.len() + sodoken::secretstream::ABYTES,
30 );
31 out[..32].copy_from_slice(&pub_key[..32]);
32 out[32] = protocol::T_MESSAGE;
33
34 sodoken::secretstream::push(
35 &mut self.state,
36 &mut out[33..],
37 msg,
38 None,
39 sodoken::secretstream::Tag::Message,
40 )?;
41
42 Ok(protocol::Protocol::from_full(out.freeze()).unwrap())
44 }
45}
46
47pub struct Decryptor {
49 state: sodoken::secretstream::State,
50}
51
52impl Decryptor {
53 pub fn decrypt(&mut self, msg: &[u8]) -> Result<bytes::Bytes> {
55 let mut out =
56 bytes::BytesMut::zeroed(msg.len() - sodoken::secretstream::ABYTES);
57 sodoken::secretstream::pull(&mut self.state, &mut out[..], msg, None)?;
58 Ok(out.freeze())
59 }
60}
61
62pub struct SodokenCrypto {
64 sign_pk: [u8; 32],
65 sign_sk: Mutex<sodoken::SizedLockedArray<64>>,
66 enc_pk: [u8; 32],
67 enc_sk: Mutex<sodoken::SizedLockedArray<32>>,
68}
69
70impl SodokenCrypto {
71 pub fn new() -> Result<Self> {
73 loop {
74 let mut sign_pk = [0; 32];
75 let mut sign_sk = sodoken::SizedLockedArray::new()?;
76
77 sodoken::sign::keypair(&mut sign_pk, &mut sign_sk.lock())?;
78
79 if sign_pk[..28] == [0; 28] {
80 continue;
81 }
82
83 let mut enc_pk = [0; 32];
84 sodoken::sign::pk_to_curve25519(&mut enc_pk, &sign_pk)?;
85
86 let mut enc_sk = sodoken::SizedLockedArray::new()?;
87 sodoken::sign::sk_to_curve25519(
88 &mut enc_sk.lock(),
89 &sign_sk.lock(),
90 )?;
91
92 return Ok(Self {
93 sign_pk,
94 sign_sk: Mutex::new(sign_sk),
95 enc_pk,
96 enc_sk: Mutex::new(enc_sk),
97 });
98 }
99 }
100
101 fn session(
103 &self,
104 peer_sign_pk: &[u8; 32],
105 ) -> Result<(sodoken::SizedLockedArray<32>, sodoken::SizedLockedArray<32>)>
106 {
107 let mut peer_enc_pk = [0; 32];
108 sodoken::sign::pk_to_curve25519(&mut peer_enc_pk, peer_sign_pk)?;
109
110 let mut rx = sodoken::SizedLockedArray::new()?;
111 let mut tx = sodoken::SizedLockedArray::new()?;
112
113 if peer_enc_pk > self.enc_pk {
115 sodoken::kx::client_session_keys(
116 &mut rx.lock(),
117 &mut tx.lock(),
118 &self.enc_pk,
119 &self.enc_sk.lock().unwrap().lock(),
120 &peer_enc_pk,
121 )?;
122 } else {
123 sodoken::kx::server_session_keys(
124 &mut rx.lock(),
125 &mut tx.lock(),
126 &self.enc_pk,
127 &self.enc_sk.lock().unwrap().lock(),
128 &peer_enc_pk,
129 )?;
130 }
131
132 Ok((rx, tx))
133 }
134
135 pub fn new_enc(
137 &self,
138 peer_sign_pk: &[u8; 32],
139 ) -> Result<(Encryptor, [u8; 24])> {
140 let (_rx, tx) = self.session(peer_sign_pk)?;
141
142 let mut enc = Encryptor {
143 sk: tx,
144 state: sodoken::secretstream::State::default(),
145 };
146
147 let hdr = enc.init()?;
148
149 Ok((enc, hdr))
150 }
151
152 pub fn new_dec(
154 &self,
155 peer_sign_pk: &[u8],
156 hdr: &[u8],
157 ) -> Result<Decryptor> {
158 let mut pk = [0; 32];
159 pk.copy_from_slice(&peer_sign_pk[..32]);
160 let (mut rx, _tx) = self.session(&pk)?;
161
162 let mut state = sodoken::secretstream::State::default();
163
164 let mut header = [0; 24];
165 header.copy_from_slice(&hdr[..24]);
166
167 sodoken::secretstream::init_pull(&mut state, &header, &rx.lock())?;
168
169 Ok(Decryptor { state })
170 }
171}
172
173impl sbd_client::Crypto for SodokenCrypto {
174 fn pub_key(&self) -> &[u8; 32] {
175 &self.sign_pk
176 }
177
178 fn sign(&self, nonce: &[u8]) -> Result<[u8; 64]> {
179 let mut sig = [0; 64];
180 sodoken::sign::sign_detached(
181 &mut sig,
182 nonce,
183 &self.sign_sk.lock().unwrap().lock(),
184 )?;
185 Ok(sig)
186 }
187}