Skip to content

Commit 2367aff

Browse files
committed
Improved memory management
1 parent 95758dd commit 2367aff

39 files changed

Lines changed: 304 additions & 289 deletions

SecureFolderFS.Backend/ViewModels/Pages/VaultDashboardPageViewModel.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
using SecureFolderFS.Backend.ViewModels.Pages.DashboardPages;
99
using SecureFolderFS.Core.VaultLoader.Routine;
1010

11-
#nullable enable
12-
1311
namespace SecureFolderFS.Backend.ViewModels.Pages
1412
{
15-
public class VaultDashboardPageViewModel : BasePageViewModel, IRecipient<DashboardNavigationFinishedMessage>
13+
public sealed class VaultDashboardPageViewModel : BasePageViewModel, IRecipient<DashboardNavigationFinishedMessage>
1614
{
1715
public NavigationBreadcrumbViewModel NavigationBreadcrumbViewModel { get; }
1816

SecureFolderFS.Core/Chunks/Factory/AesCtrHmacChunkFactory.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using SecureFolderFS.Core.Chunks.Implementation;
2+
using System;
23

34
namespace SecureFolderFS.Core.Chunks.Factory
45
{
@@ -14,9 +15,9 @@ public ICleartextChunk FromCleartextChunkBuffer(byte[] cleartextChunkBuffer, int
1415
return new CleartextAesCtrHmacChunk(cleartextChunkBuffer, actualLength);
1516
}
1617

17-
public ICiphertextChunk FromCiphertextChunkBuffer(byte[] ciphertextChunkBuffer)
18+
public ICiphertextChunk FromCiphertextChunkBuffer(ReadOnlyMemory<byte> ciphertextChunkBuffer)
1819
{
19-
return CiphertextAesCtrHmacChunk.FromCiphertextChunkBuffer(ciphertextChunkBuffer);
20+
return new CiphertextAesCtrHmacChunk(ciphertextChunkBuffer);
2021
}
2122
}
2223
}

SecureFolderFS.Core/Chunks/Factory/AesGcmChunkFactory.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using SecureFolderFS.Core.Chunks.Implementation;
2+
using System;
23

34
namespace SecureFolderFS.Core.Chunks.Factory
45
{
@@ -14,9 +15,9 @@ public ICleartextChunk FromCleartextChunkBuffer(byte[] cleartextChunkBuffer, int
1415
return new CleartextAesGcmChunk(cleartextChunkBuffer, actualLength);
1516
}
1617

17-
public ICiphertextChunk FromCiphertextChunkBuffer(byte[] ciphertextChunkBuffer)
18+
public ICiphertextChunk FromCiphertextChunkBuffer(ReadOnlyMemory<byte> ciphertextChunkBuffer)
1819
{
19-
return CiphertextAesGcmChunk.FromCiphertextChunkBuffer(ciphertextChunkBuffer);
20+
return new CiphertextAesGcmChunk(ciphertextChunkBuffer);
2021
}
2122
}
2223
}

SecureFolderFS.Core/Chunks/Factory/XChaCha20ChunkFactory.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using SecureFolderFS.Core.Chunks.Implementation;
2+
using System;
23

34
namespace SecureFolderFS.Core.Chunks.Factory
45
{
@@ -14,9 +15,9 @@ public ICleartextChunk FromCleartextChunkBuffer(byte[] cleartextChunkBuffer, int
1415
return new CleartextXChaCha20Chunk(cleartextChunkBuffer, actualLength);
1516
}
1617

17-
public ICiphertextChunk FromCiphertextChunkBuffer(byte[] ciphertextChunkBuffer)
18+
public ICiphertextChunk FromCiphertextChunkBuffer(ReadOnlyMemory<byte> ciphertextChunkBuffer)
1819
{
19-
return CiphertextXChaCha20Chunk.FromCiphertextChunkBuffer(ciphertextChunkBuffer);
20+
return new CiphertextXChaCha20Chunk(ciphertextChunkBuffer);
2021
}
2122
}
2223
}
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
namespace SecureFolderFS.Core.Chunks
1+
using System;
2+
3+
namespace SecureFolderFS.Core.Chunks
24
{
35
internal interface IChunkFactory
46
{
57
ICleartextChunk FromCleartextChunkBuffer(byte[] cleartextChunkBuffer);
68

79
ICleartextChunk FromCleartextChunkBuffer(byte[] cleartextChunkBuffer, int actualLength);
810

9-
ICiphertextChunk FromCiphertextChunkBuffer(byte[] ciphertextChunkBuffer);
11+
ICiphertextChunk FromCiphertextChunkBuffer(ReadOnlyMemory<byte> ciphertextChunkBuffer);
1012
}
1113
}

SecureFolderFS.Core/Chunks/ICiphertextChunk.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace SecureFolderFS.Core.Chunks
44
{
5-
internal interface ICiphertextChunk : IDisposable
5+
internal interface ICiphertextChunk
66
{
7-
byte[] ToArray();
7+
ReadOnlyMemory<byte> Buffer { get; }
88
}
99
}

SecureFolderFS.Core/Chunks/ICleartextChunk.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ internal interface ICleartextChunk : IDisposable
1111

1212
void CopyTo(MemoryStream destinationStream, int offset);
1313

14-
int CopyFrom(MemoryStream sourceStream, int offset);
15-
16-
void CopyFrom2(ReadOnlySpan<byte> sourceBuffer, int offset, ref int positionInBuffer);
14+
void CopyFrom(ReadOnlySpan<byte> sourceBuffer, int offset, ref int positionInBuffer);
1715

1816
void SetActualLength(int length);
1917

20-
byte[] ToArray();
18+
ReadOnlySpan<byte> AsSpan();
2119
}
2220
}

SecureFolderFS.Core/Chunks/IO/ChunkReader.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using SecureFolderFS.Core.Security;
33
using SecureFolderFS.Core.FileHeaders;
44
using SecureFolderFS.Core.Tracking;
5-
using SecureFolderFS.Shared.Extensions;
65
using SecureFolderFS.Core.Streams.Management;
76

87
namespace SecureFolderFS.Core.Chunks.IO
@@ -34,28 +33,31 @@ public ICleartextChunk ReadChunk(long chunkNumber)
3433
{
3534
AssertNotDisposed();
3635

36+
// Calculate
3737
var payloadSize = _security.ContentCryptor.FileContentCryptor.ChunkCleartextSize;
3838
var chunkSize = _security.ContentCryptor.FileContentCryptor.ChunkFullCiphertextSize;
39-
4039
var ciphertextPosition = _security.ContentCryptor.FileHeaderCryptor.HeaderSize + (chunkNumber * chunkSize);
40+
41+
// Initialize buffer
4142
var ciphertextBuffer = new byte[chunkSize];
43+
var ciphertextBufferMemory = ciphertextBuffer.AsMemory();
4244

45+
// Read from stream
4346
var ciphertextFileStream = _ciphertextStreamsManager.EnsureReadOnlyStreamInstance();
4447
ciphertextFileStream.Position = ciphertextPosition;
45-
var read = ciphertextFileStream.Read(ciphertextBuffer, 0, ciphertextBuffer.Length);
48+
var read = ciphertextFileStream.Read(ciphertextBufferMemory.Span);
4649

50+
// Check for end-of-file
4751
if (read == Constants.IO.FILE_EOF)
4852
{
4953
return _chunkFactory.FromCleartextChunkBuffer(new byte[payloadSize], 0);
5054
}
5155

5256
_fileSystemStatsTracker?.AddBytesRead(read);
5357

54-
var actualCiphertextBuffer = new byte[read];
55-
actualCiphertextBuffer.EmplaceArrays(ciphertextBuffer);
56-
58+
// Decrypt
5759
var cleartextChunk = _security.ContentCryptor.FileContentCryptor.DecryptChunk(
58-
_chunkFactory.FromCiphertextChunkBuffer(actualCiphertextBuffer),
60+
_chunkFactory.FromCiphertextChunkBuffer(ciphertextBufferMemory.Slice(0, read)),
5961
chunkNumber,
6062
_fileHeader,
6163
Constants.Security.ALWAYS_CHECK_CHUNK_INTEGRITY);

SecureFolderFS.Core/Chunks/IO/ChunkWriter.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,13 @@ public void WriteChunk(long chunkNumber, ICleartextChunk cleartextChunk)
3838
chunkNumber,
3939
_fileHeader);
4040

41-
byte[] ciphertextChunkBuffer = ciphertextChunk.ToArray();
42-
4341
_fileSystemStatsTracker?.AddBytesEncrypted(cleartextChunk.ActualLength);
4442

4543
var ciphertextFileStream = _ciphertextStreamsManager.EnsureReadWriteStreamInstance();
4644
ciphertextFileStream.Position = ciphertextPosition;
47-
ciphertextFileStream.Write(ciphertextChunkBuffer, 0, ciphertextChunkBuffer.Length);
45+
ciphertextFileStream.Write(ciphertextChunk.Buffer.Span);
4846

49-
_fileSystemStatsTracker?.AddBytesWritten(ciphertextChunkBuffer.Length);
47+
_fileSystemStatsTracker?.AddBytesWritten(ciphertextChunk.Buffer.Length);
5048
}
5149
}
5250

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,20 @@
11
using System;
2-
using SecureFolderFS.Shared.Extensions;
32

43
namespace SecureFolderFS.Core.Chunks.Implementation
54
{
65
internal abstract class BaseCiphertextChunk : ICiphertextChunk
76
{
8-
public byte[] Nonce { get; }
7+
public ReadOnlyMemory<byte> Buffer { get; }
98

10-
public byte[] Payload { get; }
11-
12-
public byte[] Auth { get; }
13-
14-
protected BaseCiphertextChunk(byte[] nonce, byte[] payload, byte[] auth)
9+
protected BaseCiphertextChunk(ReadOnlyMemory<byte> buffer)
1510
{
16-
this.Nonce = nonce;
17-
this.Payload = payload;
18-
this.Auth = auth;
11+
this.Buffer = buffer;
1912
}
2013

21-
public virtual byte[] ToArray()
22-
{
23-
var fullChunk = new byte[Nonce.Length + Payload.Length + Auth.Length];
24-
fullChunk.EmplaceArrays(Nonce, Payload, Auth);
14+
public abstract ReadOnlySpan<byte> GetNonceAsSpan();
2515

26-
return fullChunk;
27-
}
16+
public abstract ReadOnlySpan<byte> GetPayloadAsSpan();
2817

29-
public virtual void Dispose()
30-
{
31-
Array.Clear(Nonce);
32-
Array.Clear(Payload);
33-
Array.Clear(Auth);
34-
}
18+
public abstract ReadOnlySpan<byte> GetAuthAsSpan();
3519
}
3620
}

0 commit comments

Comments
 (0)