Skip to content

Commit 34d52e7

Browse files
committed
correct empty plain text scenario
1 parent afbad47 commit 34d52e7

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

src/DataProtection/DataProtection/src/Cng/CbcAuthenticatedEncryptor.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ public override int GetEncryptedSize(int plainTextLength)
306306
return checked((int)(KEY_MODIFIER_SIZE_IN_BYTES + _symmetricAlgorithmBlockSizeInBytes + paddedCiphertextLength + _hmacAlgorithmDigestLengthInBytes));
307307
}
308308

309-
public override bool TryEncrypt(ReadOnlySpan<byte> plainText, ReadOnlySpan<byte> additionalAuthenticatedData, Span<byte> destination, out int bytesWritten)
309+
public override bool TryEncrypt(ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> additionalAuthenticatedData, Span<byte> destination, out int bytesWritten)
310310
{
311311
bytesWritten = 0;
312312

@@ -348,9 +348,11 @@ public override bool TryEncrypt(ReadOnlySpan<byte> plainText, ReadOnlySpan<byte>
348348
using (var symmetricKeyHandle = _symmetricAlgorithmHandle.GenerateSymmetricKey(pbSymmetricEncryptionSubkey, _symmetricAlgorithmSubkeyLengthInBytes))
349349
{
350350
// Get the padded output size
351-
fixed (byte* pbPlainText = plainText)
351+
byte dummy;
352+
fixed (byte* pbPlaintextArray = plaintext)
352353
{
353-
var cbOutputCiphertext = GetCbcEncryptedOutputSizeWithPadding(symmetricKeyHandle, pbPlainText, (uint)plainText.Length);
354+
var pbPlaintext = (pbPlaintextArray != null) ? pbPlaintextArray : &dummy;
355+
var cbOutputCiphertext = GetCbcEncryptedOutputSizeWithPadding(symmetricKeyHandle, pbPlaintext, (uint)plaintext.Length);
354356

355357
fixed (byte* pbDestination = destination)
356358
{
@@ -368,8 +370,8 @@ public override bool TryEncrypt(ReadOnlySpan<byte> plainText, ReadOnlySpan<byte>
368370
DoCbcEncrypt(
369371
symmetricKeyHandle: symmetricKeyHandle,
370372
pbIV: pbIV,
371-
pbInput: pbPlainText,
372-
cbInput: (uint)plainText.Length,
373+
pbInput: pbPlaintext,
374+
cbInput: (uint)plaintext.Length,
373375
pbOutput: pbOutputCiphertext,
374376
cbOutput: cbOutputCiphertext);
375377
bytesWritten += checked((int)cbOutputCiphertext);

src/DataProtection/DataProtection/src/Cng/CngGcmAuthenticatedEncryptor.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public override int GetEncryptedSize(int plainTextLength)
239239
return checked((int)(KEY_MODIFIER_SIZE_IN_BYTES + NONCE_SIZE_IN_BYTES + plainTextLength + TAG_SIZE_IN_BYTES));
240240
}
241241

242-
public override bool TryEncrypt(ReadOnlySpan<byte> plainText, ReadOnlySpan<byte> additionalAuthenticatedData, Span<byte> destination, out int bytesWritten)
242+
public override bool TryEncrypt(ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> additionalAuthenticatedData, Span<byte> destination, out int bytesWritten)
243243
{
244244
bytesWritten = 0;
245245

@@ -251,7 +251,7 @@ public override bool TryEncrypt(ReadOnlySpan<byte> plainText, ReadOnlySpan<byte>
251251
byte* pbKeyModifier = pbDestination;
252252
byte* pbNonce = &pbKeyModifier[KEY_MODIFIER_SIZE_IN_BYTES];
253253
byte* pbEncryptedData = &pbNonce[NONCE_SIZE_IN_BYTES];
254-
byte* pbAuthTag = &pbEncryptedData[plainText.Length];
254+
byte* pbAuthTag = &pbEncryptedData[plaintext.Length];
255255

256256
// Randomly generate the key modifier and nonce
257257
_genRandom.GenRandom(pbKeyModifier, KEY_MODIFIER_SIZE_IN_BYTES + NONCE_SIZE_IN_BYTES);
@@ -277,21 +277,24 @@ public override bool TryEncrypt(ReadOnlySpan<byte> plainText, ReadOnlySpan<byte>
277277
}
278278

279279
// Perform the encryption operation
280-
fixed (byte* pbPlainText = plainText)
280+
byte dummy;
281+
fixed (byte* pbPlaintextArray = plaintext)
281282
{
283+
var pbPlaintext = (pbPlaintextArray != null) ? pbPlaintextArray : &dummy;
284+
282285
DoGcmEncrypt(
283286
pbKey: pbSymmetricEncryptionSubkey,
284287
cbKey: _symmetricAlgorithmSubkeyLengthInBytes,
285288
pbNonce: pbNonce,
286-
pbPlaintextData: pbPlainText,
287-
cbPlaintextData: (uint)plainText.Length,
289+
pbPlaintextData: pbPlaintext,
290+
cbPlaintextData: (uint)plaintext.Length,
288291
pbEncryptedData: pbEncryptedData,
289292
pbTag: pbAuthTag);
290293
}
291294

292295
// At this point, retVal := { preBuffer | keyModifier | nonce | encryptedData | authenticationTag | postBuffer }
293296
// And we're done!
294-
bytesWritten += plainText.Length + checked((int)TAG_SIZE_IN_BYTES);
297+
bytesWritten += plaintext.Length + checked((int)TAG_SIZE_IN_BYTES);
295298
return true;
296299
}
297300
finally

src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/Cng/CbcAuthenticatedEncryptorTests.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,32 @@ public void Encrypt_KnownKey()
120120

121121
[ConditionalTheory]
122122
[ConditionalRunTestOnlyOnWindows]
123-
[InlineData(128, "SHA256")]
124-
[InlineData(192, "SHA256")]
125-
[InlineData(256, "SHA256")]
126-
[InlineData(128, "SHA512")]
127-
[InlineData(192, "SHA512")]
128-
[InlineData(256, "SHA512")]
129-
public void Roundtrip_TryEncryptDecrypt_CorrectlyEstimatesDataLength(int symmetricKeySizeBits, string hmacAlgorithm)
123+
[InlineData(128, "SHA256", "")]
124+
[InlineData(128, "SHA256", "This is a small text")]
125+
[InlineData(128, "SHA256", "This is a very long plaintext message that spans multiple blocks and should test the encryption and size estimation with larger payloads to ensure everything works correctly")]
126+
[InlineData(192, "SHA256", "")]
127+
[InlineData(192, "SHA256", "This is a small text")]
128+
[InlineData(192, "SHA256", "This is a very long plaintext message that spans multiple blocks and should test the encryption and size estimation with larger payloads to ensure everything works correctly")]
129+
[InlineData(256, "SHA256", "")]
130+
[InlineData(256, "SHA256", "This is a small text")]
131+
[InlineData(256, "SHA256", "This is a very long plaintext message that spans multiple blocks and should test the encryption and size estimation with larger payloads to ensure everything works correctly")]
132+
[InlineData(128, "SHA512", "")]
133+
[InlineData(128, "SHA512", "This is a small text")]
134+
[InlineData(128, "SHA512", "This is a very long plaintext message that spans multiple blocks and should test the encryption and size estimation with larger payloads to ensure everything works correctly")]
135+
[InlineData(192, "SHA512", "")]
136+
[InlineData(192, "SHA512", "This is a small text")]
137+
[InlineData(192, "SHA512", "This is a very long plaintext message that spans multiple blocks and should test the encryption and size estimation with larger payloads to ensure everything works correctly")]
138+
[InlineData(256, "SHA512", "")]
139+
[InlineData(256, "SHA512", "This is a small text")]
140+
[InlineData(256, "SHA512", "This is a very long plaintext message that spans multiple blocks and should test the encryption and size estimation with larger payloads to ensure everything works correctly")]
141+
public void Roundtrip_TryEncryptDecrypt_CorrectlyEstimatesDataLength(int symmetricKeySizeBits, string hmacAlgorithm, string plainText)
130142
{
131143
Secret kdk = new Secret(new byte[512 / 8]);
132144
IAuthenticatedEncryptor encryptor = new CbcAuthenticatedEncryptor(kdk,
133145
symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_CBC,
134146
symmetricAlgorithmKeySizeInBytes: (uint)(symmetricKeySizeBits / 8),
135147
hmacAlgorithmHandle: BCryptAlgorithmHandle.OpenAlgorithmHandle(hmacAlgorithm, hmac: true));
136-
ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes("plaintext"));
148+
ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes(plainText));
137149
ArraySegment<byte> aad = new ArraySegment<byte>(Encoding.UTF8.GetBytes("aad"));
138150

139151
RoundtripEncryptionHelpers.AssertTryEncryptTryDecryptParity(encryptor, plaintext, aad);

0 commit comments

Comments
 (0)