Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit 5dbd687

Browse files
committed
improve key- & error-handling; cleanups
1 parent fec01c9 commit 5dbd687

3 files changed

Lines changed: 91 additions & 78 deletions

File tree

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ pub enum Error {
4040
WrongKeyKind,
4141
WrongMessageLength,
4242
WrongSignatureLength,
43+
44+
// sw encryption errors
45+
FilesystemEncryptionError
4346
}
4447

4548
// pub struct FutureResult<'a, 'c> {

src/service.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl<P: Platform> ServiceResources<P> {
119119
client_id.path.clone(),
120120
self.rng().map_err(|_| Error::EntropyMalfunction)?,
121121
full_store,
122-
raw_store,
122+
raw_store.clone(),
123123
);
124124
let keystore = &mut keystore;
125125

@@ -128,7 +128,7 @@ impl<P: Platform> ServiceResources<P> {
128128
client_id.path.clone(),
129129
self.rng().map_err(|_| Error::EntropyMalfunction)?,
130130
full_store,
131-
raw_store,
131+
raw_store.clone(),
132132
);
133133
let certstore = &mut certstore;
134134

@@ -137,13 +137,13 @@ impl<P: Platform> ServiceResources<P> {
137137
client_id.path.clone(),
138138
self.rng().map_err(|_| Error::EntropyMalfunction)?,
139139
full_store,
140-
raw_store,
140+
raw_store.clone(),
141141
);
142142
let counterstore = &mut counterstore;
143143

144144
// prepare filestore, bound to client_id, for storage calls
145145
let mut filestore: ClientFilestore<P::S> =
146-
ClientFilestore::new(client_id.path.clone(), full_store, raw_store);
146+
ClientFilestore::new(client_id.path.clone(), full_store, raw_store.clone());
147147
let filestore = &mut filestore;
148148

149149
debug_now!("TRUSSED {:?}", request);
@@ -594,11 +594,9 @@ impl<P: Platform> ServiceResources<P> {
594594
}
595595

596596
Request::ChangePin(request) => {
597-
let res = raw_store.change_pin(request.new_pin.clone());
598-
match res {
599-
Err(e) => { return Err(e); },
600-
Ok(_) => { client_id.pin = Some(request.new_pin.clone()); },
601-
}
597+
raw_store.change_pin(request.new_pin.clone())?;
598+
client_id.pin = Some(request.new_pin.clone());
599+
602600
Ok(Reply::ChangePin(reply::ChangePin {}))
603601
}
604602

src/store/rawstore.rs

Lines changed: 81 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ use sha2::digest::Digest;
2929
use chacha20::ChaCha8Rng;
3030
use rand_core::RngCore;
3131

32-
#[derive(Copy, Clone)]
32+
#[derive(Clone)]
3333
pub struct RawStore<S>
3434
where
3535
S: Store,
3636
{
3737
mode: RawStoreMode,
38-
symmetric_key: Option<[u8; 32]>,
38+
pin: Option<ShortData>,
39+
key_filename: PathBuf,
3940
store: S,
4041
}
4142

@@ -46,21 +47,17 @@ impl<S: Store> RawStore<S> {
4647
pin: Option<ShortData>,
4748
rng: Option<ChaCha8Rng>,
4849
) -> Self {
49-
let mut symmetric_key = [0u8; 32];
50-
50+
let key_filename = PathBuf::from("encryption-key");
5151
if mode == RawStoreMode::Encrypted {
52-
let key_filename = PathBuf::from("encryption-key");
5352
let res: Result<Bytes<128>, Error> =
5453
store::read(store, Location::Internal, &key_filename);
55-
debug_now!("pin: {:?}", pin);
56-
let pin_key = Self::get_pin_key(pin.unwrap()).into_vec();
54+
let pin_key = Self::get_pin_key(pin.clone().unwrap()).into_vec();
5755
match res {
5856
// 'key_filename' not found, generate new key and save (encrypted) to 'key_filename'
5957
Err(e) => {
6058
let mut new_key = [0u8; 32];
6159
rng.unwrap().fill_bytes(&mut new_key);
6260

63-
symmetric_key.copy_from_slice(&new_key);
6461
let content =
6562
Self::encrypt_content(mode, &key_filename, pin_key.as_slice(), &new_key);
6663
store::write(
@@ -70,21 +67,17 @@ impl<S: Store> RawStore<S> {
7067
content.into_vec().as_slice(),
7168
);
7269
}
73-
// 'key_filename' found, extract symmetric key and use it
70+
// 'key_filename' found
7471
Ok(data) => {
75-
symmetric_key.copy_from_slice(&Self::decrypt_content(
76-
mode,
77-
&key_filename,
78-
pin_key.as_slice(),
79-
data,
80-
));
72+
// do nothing, read key on-demand
8173
}
8274
}
8375
}
8476

8577
Self {
8678
mode,
87-
symmetric_key: Some(symmetric_key),
79+
pin: pin.clone(),
80+
key_filename,
8881
store,
8982
}
9083
}
@@ -93,10 +86,8 @@ impl<S: Store> RawStore<S> {
9386
match mode {
9487
RawStoreMode::Unencrypted => Message::from_slice(contents).unwrap(),
9588
RawStoreMode::Encrypted => {
96-
let zero_iv = Self::get_iv(path);
97-
debug_now!("iv: {:?}", zero_iv);
98-
debug_now!("key: {:?}", key);
99-
let cipher = Aes256Cbc::new_from_slices(key, &zero_iv).unwrap();
89+
let iv = Self::get_iv(path);
90+
let cipher = Aes256Cbc::new_from_slices(key, &iv).unwrap();
10091
let mut buffer = Message::from_slice(contents).unwrap();
10192
let l = contents.len();
10293
buffer.resize_default(l + (32 - l % 32));
@@ -113,42 +104,18 @@ impl<S: Store> RawStore<S> {
113104
contents: Bytes<N>,
114105
) -> Bytes<N> {
115106
match mode {
116-
RawStoreMode::Unencrypted => {
117-
//debug_now!("READ DATA LEN - N:{:?} len:{:?} data: {:?}", N, contents.len(), &contents[..10]);
118-
contents
119-
}
107+
RawStoreMode::Unencrypted => contents,
120108
RawStoreMode::Encrypted => {
121-
let zero_iv = Self::get_iv(path);
122-
let cipher = Aes256Cbc::new_from_slices(key, &zero_iv).unwrap();
109+
let iv = Self::get_iv(path);
110+
let cipher = Aes256Cbc::new_from_slices(key, &iv).unwrap();
123111
let mut buffer = contents.clone();
124112
let plaintext = cipher.decrypt(&mut buffer).unwrap();
125113
let out = Bytes::<N>::from_slice(plaintext).unwrap();
126-
//debug_now!("READ DATA LEN - N:{:?} len:{:?} data: {:?}", N, out.len(), &out[..10]);
127114
out
128115
}
129116
}
130117
}
131118

132-
pub fn change_pin(&self, new_pin: ShortData) -> Result<(), Error> {
133-
let key_filename = PathBuf::from("encryption-key");
134-
let pin_key = Self::get_pin_key(new_pin).into_vec();
135-
136-
// write key with new pin
137-
let content = Self::encrypt_content(
138-
RawStoreMode::Encrypted,
139-
&key_filename,
140-
pin_key.as_slice(),
141-
&self.symmetric_key.unwrap(),
142-
);
143-
store::write(
144-
self.store,
145-
Location::Internal,
146-
&key_filename,
147-
content.into_vec().as_slice(),
148-
);
149-
Ok(())
150-
}
151-
152119
pub fn get_pin_key(pin: ShortData) -> Bytes<32> {
153120
let mut hash = sha2::Sha256::new();
154121
hash.update(pin);
@@ -169,12 +136,55 @@ impl<S: Store> RawStore<S> {
169136
Bytes::<16>::from_slice(&hashed.into_vec().as_slice()[..16]).unwrap()
170137
}
171138

172-
pub fn create_directories<'s, X: LfsStorage>(
173-
&self,
174-
fs: &Filesystem<'s, X>,
175-
path: &Path,
176-
) -> Result<(), Error> {
177-
store::create_directories(fs, path)
139+
fn read_symmetric_key(&self) -> Result<[u8; 32], Error> {
140+
if self.mode == RawStoreMode::Unencrypted {
141+
return Ok([0u8; 32]);
142+
}
143+
144+
let pin_key = Self::get_pin_key(self.pin.clone().unwrap()).into_vec();
145+
let res: Result<Bytes<128>, Error> =
146+
store::read(self.store, Location::Internal, &self.key_filename);
147+
let data = res.unwrap();
148+
149+
let mut symmetric_key = [0u8; 32];
150+
151+
/*symmetric_key.copy_from_slice(&Self::decrypt_content(
152+
self.mode,
153+
&self.key_filename,
154+
pin_key.as_slice(),
155+
data,
156+
));*/
157+
// instead explicitly decrypt "by-hand" to catch (and propagate) a wrong pin
158+
let iv = Self::get_iv(&self.key_filename);
159+
let cipher = Aes256Cbc::new_from_slices(pin_key.as_slice(), &iv).unwrap();
160+
let mut buffer = data.clone();
161+
match cipher.decrypt(&mut buffer) {
162+
Err(e) => return Err(Error::FilesystemEncryptionError),
163+
Ok(plaintext) => symmetric_key.copy_from_slice(plaintext)
164+
};
165+
166+
//let out = Bytes::<N>::from_slice(plaintext).unwrap();
167+
168+
Ok(symmetric_key)
169+
}
170+
171+
pub fn change_pin(&self, new_pin: ShortData) -> Result<(), Error> {
172+
let pin_key = Self::get_pin_key(new_pin).into_vec();
173+
// write key with new pin
174+
let key = self.read_symmetric_key()?;
175+
let content = Self::encrypt_content(
176+
RawStoreMode::Encrypted,
177+
&self.key_filename,
178+
pin_key.as_slice(),
179+
&key,
180+
);
181+
store::write(
182+
self.store,
183+
Location::Internal,
184+
&self.key_filename,
185+
content.into_vec().as_slice(),
186+
);
187+
Ok(())
178188
}
179189

180190
pub fn read<const N: usize>(
@@ -183,9 +193,10 @@ impl<S: Store> RawStore<S> {
183193
location: Location,
184194
path: &Path,
185195
) -> Result<Bytes<N>, Error> {
186-
debug_now!("READ: {:?} {:?}", N, path);
196+
//debug_now!("READ: {:?} {:?}", N, path);
197+
let key = self.read_symmetric_key()?;
187198
store::read(store, location, path)
188-
.map(|val| Self::decrypt_content(self.mode, path, &self.symmetric_key.unwrap(), val))
199+
.map(|val| Self::decrypt_content(self.mode, path, &key, val))
189200
}
190201

191202
pub fn write(
@@ -195,13 +206,9 @@ impl<S: Store> RawStore<S> {
195206
path: &Path,
196207
contents: &[u8],
197208
) -> Result<(), Error> {
198-
debug_now!("WRITE: {:?} data: {:?}", path, &contents[..10]);
199-
let data = Self::encrypt_content(
200-
self.mode,
201-
path,
202-
&self.symmetric_key.unwrap(),
203-
&contents.clone(),
204-
);
209+
// debug_now!("WRITE: {:?} data: {:?}", path, &contents[..10]);
210+
let key = self.read_symmetric_key()?;
211+
let data = Self::encrypt_content(self.mode, path, &key, &contents.clone());
205212
store::write(store, location, path, data.into_vec().as_slice())
206213
}
207214

@@ -212,15 +219,20 @@ impl<S: Store> RawStore<S> {
212219
path: &Path,
213220
contents: &[u8],
214221
) -> Result<(), Error> {
215-
debug_now!("STORE: {:?} data: {:?}", path, &contents[..10]);
216-
let data = Self::encrypt_content(
217-
self.mode,
218-
path,
219-
&self.symmetric_key.unwrap(),
220-
&contents.clone(),
221-
);
222+
//debug_now!("STORE: {:?} data: {:?}", path, &contents[..10]);
223+
let key = self.read_symmetric_key()?;
224+
let data = Self::encrypt_content(self.mode, path, &key, &contents.clone());
222225
store::store(store, location, path, data.into_vec().as_slice())
223226
}
227+
228+
pub fn create_directories<'s, X: LfsStorage>(
229+
&self,
230+
fs: &Filesystem<'s, X>,
231+
path: &Path,
232+
) -> Result<(), Error> {
233+
store::create_directories(fs, path)
234+
}
235+
224236
pub fn delete(&self, store: impl Store, location: Location, path: &Path) -> bool {
225237
store::delete(store, location, path)
226238
}

0 commit comments

Comments
 (0)