Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Client encryption]: Fixes Faster validations and string comparisons #4739

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -192,17 +192,17 @@ private async Task<DataEncryptionKey> FetchDekAsync(string id, string encryption
cancellationToken: cancellationToken);

// supports Encryption with MDE based algorithm using Legacy Encryption Algorithm Configured DEK.
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized) &&
string.Equals(dataEncryptionKeyProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal) &&
string.Equals(dataEncryptionKeyProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal))
{
return await this.dataEncryptionKeyContainerCore.FetchUnWrappedMdeSupportedLegacyDekAsync(
dataEncryptionKeyProperties,
cancellationToken);
}

// supports Encryption with Legacy based algorithm using Mde Encryption Algorithm Configured DEK.
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized) &&
string.Equals(dataEncryptionKeyProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized))
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal) &&
string.Equals(dataEncryptionKeyProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal))
{
return await this.dataEncryptionKeyContainerCore.FetchUnWrappedLegacySupportedMdeDekAsync(
dataEncryptionKeyProperties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public static class CosmosEncryptionAlgorithm
/// <returns> Returns True if the Algorithm is supported. </returns>
internal static bool VerifyIfSupportedAlgorithm(string encryptionAlgorithm)
{
if (!string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized) &&
!string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized))
if (!string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal) &&
!string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal))
{
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public override async Task<ItemResponse<DataEncryptionKeyProperties>> CreateData
EncryptionKeyWrapMetadata updatedMetadata = null;
InMemoryRawDek inMemoryRawDek = null;

if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal))
{
(wrappedDek, updatedMetadata, inMemoryRawDek) = await this.GenerateAndWrapRawDekForLegacyEncAlgoAsync(
id,
Expand All @@ -87,7 +87,7 @@ public override async Task<ItemResponse<DataEncryptionKeyProperties>> CreateData
diagnosticsContext,
cancellationToken);
}
else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized))
else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal))
{
(wrappedDek, updatedMetadata) = this.GenerateAndWrapPdekForMdeEncAlgo(id, encryptionKeyWrapMetadata);
}
Expand Down Expand Up @@ -118,7 +118,7 @@ public override async Task<ItemResponse<DataEncryptionKeyProperties>> CreateData

this.DekProvider.DekCache.SetDekProperties(id, dekProperties);

if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal))
{
this.DekProvider.DekCache.SetRawDek(id, inMemoryRawDek);
}
Expand Down Expand Up @@ -165,7 +165,7 @@ public override async Task<ItemResponse<DataEncryptionKeyProperties>> RewrapData

byte[] rawkey = null;

if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal))
{
InMemoryRawDek inMemoryRawDek = await this.FetchUnwrappedAsync(
dekProperties,
Expand All @@ -174,7 +174,7 @@ public override async Task<ItemResponse<DataEncryptionKeyProperties>> RewrapData

rawkey = inMemoryRawDek.DataEncryptionKey.RawKey;
}
else if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized))
else if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal))
{
EncryptionKeyUnwrapResult encryptionKeyUnwrapResult = await this.DekProvider.MdeKeyWrapProvider.UnwrapKeyAsync(
dekProperties.WrappedDataEncryptionKey,
Expand All @@ -186,8 +186,8 @@ public override async Task<ItemResponse<DataEncryptionKeyProperties>> RewrapData

if (!string.IsNullOrEmpty(encryptionAlgorithm))
{
if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized)
&& string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal)
&& string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal))
{
throw new InvalidOperationException($"Rewrap operation with EncryptionAlgorithm '{encryptionAlgorithm}' is not supported on Data Encryption Keys" +
$" which are configured with '{CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized}'. ");
Expand Down Expand Up @@ -264,7 +264,7 @@ await this.ReadDataEncryptionKeyAsync(

this.DekProvider.DekCache.SetDekProperties(id, dekProperties);

if (string.Equals(newDekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
if (string.Equals(newDekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal))
{
this.DekProvider.DekCache.SetRawDek(id, updatedRawDek);
}
Expand Down Expand Up @@ -384,7 +384,7 @@ internal async Task<InMemoryRawDek> FetchUnwrappedAsync(
{
try
{
if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized))
if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal))
{
DataEncryptionKey dek = this.InitMdeEncryptionAlgorithm(dekProperties, withRawKey);

Expand Down Expand Up @@ -419,11 +419,11 @@ internal async Task<InMemoryRawDek> FetchUnwrappedAsync(

using (diagnosticsContext.CreateScope("WrapDataEncryptionKey"))
{
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized) && this.DekProvider.EncryptionKeyWrapProvider != null)
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal) && this.DekProvider.EncryptionKeyWrapProvider != null)
{
keyWrapResponse = await this.DekProvider.EncryptionKeyWrapProvider.WrapKeyAsync(key, metadata, cancellationToken);
}
else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized) && this.DekProvider.MdeKeyWrapProvider != null)
else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal) && this.DekProvider.MdeKeyWrapProvider != null)
{
keyWrapResponse = await this.DekProvider.MdeKeyWrapProvider.WrapKeyAsync(key, metadata, cancellationToken);
}
Expand All @@ -446,12 +446,12 @@ internal async Task<InMemoryRawDek> FetchUnwrappedAsync(

byte[] rawKey = null;
InMemoryRawDek roundTripResponse = null;
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal))
{
roundTripResponse = await this.UnwrapAsync(tempDekProperties, diagnosticsContext, cancellationToken);
rawKey = roundTripResponse.DataEncryptionKey.RawKey;
}
else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized))
else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal))
{
EncryptionKeyUnwrapResult unwrapResult = await this.UnWrapDekMdeEncAlgoAsync(
tempDekProperties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,26 @@ public static async Task<Stream> EncryptAsync(
return input;
}

if (!encryptionOptions.PathsToEncrypt.Distinct().SequenceEqual(encryptionOptions.PathsToEncrypt))
if (encryptionOptions.PathsToEncrypt.Distinct().Count() != encryptionOptions.PathsToEncrypt.Count())
kirankumarkolli marked this conversation as resolved.
Show resolved Hide resolved
{
throw new InvalidOperationException("Duplicate paths in PathsToEncrypt passed via EncryptionOptions.");
}

foreach (string path in encryptionOptions.PathsToEncrypt)
{
if (string.IsNullOrWhiteSpace(path) || path[0] != '/' || path.LastIndexOf('/') != 0)
if (string.IsNullOrWhiteSpace(path) || path[0] != '/' || path.IndexOf('/', 1) != -1)
{
throw new InvalidOperationException($"Invalid path {path ?? string.Empty}, {nameof(encryptionOptions.PathsToEncrypt)}");
}

if (string.Equals(path.Substring(1), "id"))
if (path.AsSpan(1).Equals("id".AsSpan(), StringComparison.Ordinal))
{
throw new InvalidOperationException($"{nameof(encryptionOptions.PathsToEncrypt)} includes a invalid path: '{path}'.");
}
}

JObject itemJObj = EncryptionProcessor.BaseSerializer.FromStream<JObject>(input);
List<string> pathsEncrypted = new List<string>();
List<string> pathsEncrypted = new List<string>(encryptionOptions.PathsToEncrypt.Count());
EncryptionProperties encryptionProperties = null;
byte[] plainText = null;
byte[] cipherText = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@

BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22631.4169)
11th Gen Intel Core i9-11950H 2.60GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=8.0.108
.NET SDK=8.0.400
[Host] : .NET 6.0.33 (6.0.3324.36610), X64 RyuJIT AVX2

Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
LaunchCount=2 WarmupCount=10

```
| Method | DocumentSizeInKb | Mean | Error | StdDev | Median | Gen0 | Gen1 | Gen2 | Allocated |
|-------- |----------------- |------------:|-----------:|-----------:|------------:|---------:|---------:|---------:|-----------:|
| **Encrypt** | **1** | **36.44 μs** | **0.518 μs** | **0.759 μs** | **36.40 μs** | **4.0894** | **1.0376** | **-** | **50.81 KB** |
| Decrypt | 1 | 44.51 μs | 0.900 μs | 1.291 μs | 43.83 μs | 4.8828 | 1.2207 | - | 60.1 KB |
| **Encrypt** | **10** | **114.63 μs** | **3.234 μs** | **4.841 μs** | **113.80 μs** | **16.2354** | **3.2959** | **-** | **199.75 KB** |
| Decrypt | 10 | 146.56 μs | 1.205 μs | 1.766 μs | 146.08 μs | 24.4141 | 4.6387 | - | 301.94 KB |
| **Encrypt** | **100** | **1,784.59 μs** | **180.928 μs** | **270.805 μs** | **1,743.86 μs** | **158.2031** | **95.7031** | **82.0313** | **1890.27 KB** |
| Decrypt | 100 | 2,772.68 μs | 261.923 μs | 392.035 μs | 2,648.81 μs | 236.3281 | 158.2031 | 142.5781 | 3064.91 KB |

| Method | DocumentSizeInKb | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
|-------- |----------------- |------------:|-----------:|-----------:|---------:|---------:|--------:|-----------:|
| **Encrypt** | **1** | **36.08 μs** | **0.508 μs** | **0.695 μs** | **3.9063** | **0.9766** | **-** | **48.42 KB** |
| Decrypt | 1 | 44.35 μs | 0.793 μs | 1.187 μs | 4.3945 | 1.0986 | - | 53.96 KB |
| **Encrypt** | **10** | **114.38 μs** | **1.323 μs** | **1.940 μs** | **15.8691** | **3.1738** | **-** | **197.37 KB** |
| Decrypt | 10 | 144.66 μs | 2.856 μs | 4.275 μs | 19.5313 | 3.1738 | - | 239.73 KB |
| **Encrypt** | **100** | **1,771.21 μs** | **152.739 μs** | **228.613 μs** | **158.2031** | **119.1406** | **82.0313** | **1887.87 KB** |
| Decrypt | 100 | 2,001.18 μs | 174.355 μs | 260.966 μs | 160.1563 | 111.3281 | 76.1719 | 2042.39 KB |
Loading