Skip to content

Commit a4e3ca4

Browse files
committed
simplify net10 impl
1 parent 198501e commit a4e3ca4

File tree

1 file changed

+13
-98
lines changed

1 file changed

+13
-98
lines changed

src/DataProtection/DataProtection/src/Managed/ManagedAuthenticatedEncryptor.cs

Lines changed: 13 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -416,52 +416,36 @@ public byte[] Encrypt(ArraySegment<byte> plaintext, ArraySegment<byte> additiona
416416
additionalAuthenticatedData.Validate();
417417
var plainTextSpan = plaintext.AsSpan();
418418

419+
#if NET10_0_OR_GREATER
420+
var size = GetEncryptedSize(plainTextSpan.Length);
421+
var retVal = new byte[size];
422+
if (!TryEncrypt(plaintext.AsSpan(), additionalAuthenticatedData.AsSpan(), retVal, out var bytesWritten))
423+
{
424+
// TODO understand what we really expect here
425+
throw Error.CryptCommon_GenericError();
426+
}
427+
428+
Debug.Assert(bytesWritten == size, "bytesWritten == size");
429+
return retVal;
430+
#endif
431+
419432
try
420433
{
421434
var keyModifierLength = KEY_MODIFIER_SIZE_IN_BYTES;
422435
var ivLength = _symmetricAlgorithmBlockSizeInBytes;
423436

424-
#if NET10_0_OR_GREATER
425-
Span<byte> decryptedKdk = _keyDerivationKey.Length <= 256
426-
? stackalloc byte[256].Slice(0, _keyDerivationKey.Length)
427-
: new byte[_keyDerivationKey.Length];
428-
#else
429437
var decryptedKdk = new byte[_keyDerivationKey.Length];
430-
#endif
431-
432-
#if NET10_0_OR_GREATER
433-
byte[]? validationSubkeyArray = null;
434-
Span<byte> validationSubkey = _validationAlgorithmSubkeyLengthInBytes <= 128
435-
? stackalloc byte[128].Slice(0, _validationAlgorithmSubkeyLengthInBytes)
436-
: (validationSubkeyArray = new byte[_validationAlgorithmSubkeyLengthInBytes]);
437-
#else
438438
var validationSubkeyArray = new byte[_validationAlgorithmSubkeyLengthInBytes];
439439
var validationSubkey = validationSubkeyArray.AsSpan();
440-
#endif
441-
442-
#if NET10_0_OR_GREATER
443-
Span<byte> encryptionSubkey = _symmetricAlgorithmSubkeyLengthInBytes <= 128
444-
? stackalloc byte[128].Slice(0, _symmetricAlgorithmSubkeyLengthInBytes)
445-
: new byte[_symmetricAlgorithmSubkeyLengthInBytes];
446-
#else
447440
byte[] encryptionSubkey = new byte[_symmetricAlgorithmSubkeyLengthInBytes];
448-
#endif
449441

450442
fixed (byte* decryptedKdkUnsafe = decryptedKdk)
451443
fixed (byte* __unused__1 = encryptionSubkey)
452444
fixed (byte* __unused__2 = validationSubkeyArray)
453445
{
454446
// Step 1: Generate a random key modifier and IV for this operation.
455447
// Both will be equal to the block size of the block cipher algorithm.
456-
#if NET10_0_OR_GREATER
457-
Span<byte> keyModifier = keyModifierLength <= 128
458-
? stackalloc byte[128].Slice(0, keyModifierLength)
459-
: new byte[keyModifierLength];
460-
461-
_genRandom.GenRandom(keyModifier);
462-
#else
463448
var keyModifier = _genRandom.GenRandom(keyModifierLength);
464-
#endif
465449

466450
try
467451
{
@@ -475,78 +459,15 @@ public byte[] Encrypt(ArraySegment<byte> plaintext, ArraySegment<byte> additiona
475459
operationSubkey: encryptionSubkey,
476460
validationSubkey: validationSubkey);
477461

478-
#if NET10_0_OR_GREATER
479-
// idea of optimization here is firstly get all the types preset
480-
// for calculating length of the output array and allocating it.
481-
// then we are filling it with the data directly, without any additional copying
482-
483-
using var symmetricAlgorithm = CreateSymmetricAlgorithm();
484-
symmetricAlgorithm.SetKey(encryptionSubkey); // setKey is a single-shot usage of symmetricAlgorithm. Not allocatey
485-
486-
using var validationAlgorithm = CreateValidationAlgorithm();
487-
488-
// Later framework has an API to pre-calculate optimal length of the ciphertext.
489-
// That means we can avoid allocating more data than we need.
490-
491-
var cipherTextLength = symmetricAlgorithm.GetCiphertextLengthCbc(plainTextSpan.Length); // CBC because symmetricAlgorithm is created with CBC mode
492-
var macLength = _validationAlgorithmDigestLengthInBytes;
493-
494-
// allocating an array of a specific required length
495-
var outputArray = new byte[keyModifierLength + ivLength + cipherTextLength + macLength];
496-
var outputSpan = outputArray.AsSpan();
497-
#else
498462
var outputStream = new MemoryStream();
499-
#endif
500-
501-
#if NET10_0_OR_GREATER
502-
// Step 2: Copy the key modifier to the output stream (part of a header)
503-
keyModifier.CopyTo(outputSpan.Slice(start: 0, length: keyModifierLength));
504463

505-
// Step 3: Generate IV for this operation right into the output stream (no allocation)
506-
// key modifier and IV together act as a header.
507-
var iv = outputSpan.Slice(start: keyModifierLength, length: ivLength);
508-
_genRandom.GenRandom(iv);
509-
#else
510464
// Step 2: Copy the key modifier and the IV to the output stream since they'll act as a header.
511465
outputStream.Write(keyModifier, 0, keyModifier.Length);
512466

513467
// Step 3: Generate IV for this operation right into the result array
514468
var iv = _genRandom.GenRandom(_symmetricAlgorithmBlockSizeInBytes);
515469
outputStream.Write(iv, 0, iv.Length);
516-
#endif
517470

518-
#if NET10_0_OR_GREATER
519-
// Step 4: Perform the encryption operation.
520-
// encrypting plaintext into the target array directly
521-
symmetricAlgorithm.EncryptCbc(plainTextSpan, iv, outputSpan.Slice(start: keyModifierLength + ivLength, length: cipherTextLength));
522-
523-
// At this point, outputStream := { keyModifier || IV || ciphertext }
524-
525-
// Step 5: Calculate the digest over the IV and ciphertext.
526-
// We don't need to calculate the digest over the key modifier since that
527-
// value has already been mixed into the KDF used to generate the MAC key.
528-
529-
var ivAndCipherTextSpan = outputSpan.Slice(start: keyModifierLength, length: ivLength + cipherTextLength);
530-
var macDestinationSpan = outputSpan.Slice(keyModifierLength + ivLength + cipherTextLength, macLength);
531-
532-
// if we can use an optimized method for specific algorithm - we use it (no extra alloc for subKey)
533-
if (validationAlgorithm is HMACSHA256)
534-
{
535-
HMACSHA256.HashData(key: validationSubkey, source: ivAndCipherTextSpan, destination: macDestinationSpan);
536-
}
537-
else if (validationAlgorithm is HMACSHA512)
538-
{
539-
HMACSHA512.HashData(key: validationSubkey, source: ivAndCipherTextSpan, destination: macDestinationSpan);
540-
}
541-
else
542-
{
543-
validationAlgorithm.Key = validationSubkeyArray ?? validationSubkey.ToArray();
544-
validationAlgorithm.TryComputeHash(source: ivAndCipherTextSpan, destination: macDestinationSpan, bytesWritten: out _);
545-
}
546-
547-
// At this point, outputArray := { keyModifier || IV || ciphertext || MAC(IV || ciphertext) }
548-
return outputArray;
549-
#else
550471
// Step 4: Perform the encryption operation.
551472
using (var symmetricAlgorithm = CreateSymmetricAlgorithm())
552473
using (var cryptoTransform = symmetricAlgorithm.CreateEncryptor(encryptionSubkey, iv))
@@ -573,17 +494,11 @@ public byte[] Encrypt(ArraySegment<byte> plaintext, ArraySegment<byte> additiona
573494
return outputStream.ToArray();
574495
}
575496
}
576-
#endif
577497
}
578498
finally
579499
{
580-
#if NET10_0_OR_GREATER
581-
keyModifier.Clear();
582-
decryptedKdk.Clear();
583-
#else
584500
Array.Clear(keyModifier, 0, keyModifierLength);
585501
Array.Clear(decryptedKdk, 0, decryptedKdk.Length);
586-
#endif
587502
}
588503
}
589504
}

0 commit comments

Comments
 (0)