Skip to content

Conversation

@vcsjones
Copy link
Member

This changes AesCng and TripleDESCng to require the feedback size to be set to '8' when in CFB mode and using a persisted CNG key.

Prior to this change, BasicSymmetricCipherNCrypt ignored the feedback size which resulted in CFB8 always being used, even if the FeedbackSize was set to another value. However, when padding was applied, the padding size would be padded to the feedback size. In the case of AesCng, this would mean it would be encrypted with CFB8 and padded as if it were CFB128.

It was also determined that persisted CNG keys also do not support setting the feedback size, so that gives us the only option to throw.

This changes the implementation so that the feedback size is required to be set to 8 for persisted keys. No change is made for ephemeral keys.


Developers that are impacted by this change can work around this by setting the FeedbackSize to 8, since that is how it is actually encrypted. Even though it was padded with additional padding, it will be handled by the decryption since this was actually the behavior of .NET Framework (it was always padded to the block size). So the decryption handles the extra padding already, and encryption will start producing smaller ciphertexts since it will contain at most one byte of padding.

As noted in the issue, this breaking change will have a small impact.

Closes #55477.

This changes AesCng and TripleDESCng to require the feedback size to be
set to '8' when in CFB mode and using a persisted CNG key.

Prior to this change, BasicSymmetricCipherNCrypt ignored the feedback
size which resulted in CFB8 always being used, even if the FeedbackSize
was set to another value. However, when padding was applied, the padding
size would be padded to the feedback size. In the case of AesCng, this
would mean it would be encrypted with CFB8 and padded as if it were
CFB128.

This changes the implementation so that the feedback size is required
to be set to 8 for persisted keys. No change is made for ephemeral keys.
@ghost ghost added the area-System.Security label Jul 14, 2021
@ghost
Copy link

ghost commented Jul 14, 2021

Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks
See info in area-owners.md if you want to be subscribed.

Issue Details

This changes AesCng and TripleDESCng to require the feedback size to be set to '8' when in CFB mode and using a persisted CNG key.

Prior to this change, BasicSymmetricCipherNCrypt ignored the feedback size which resulted in CFB8 always being used, even if the FeedbackSize was set to another value. However, when padding was applied, the padding size would be padded to the feedback size. In the case of AesCng, this would mean it would be encrypted with CFB8 and padded as if it were CFB128.

It was also determined that persisted CNG keys also do not support setting the feedback size, so that gives us the only option to throw.

This changes the implementation so that the feedback size is required to be set to 8 for persisted keys. No change is made for ephemeral keys.


Developers that are impacted by this change can work around this by setting the FeedbackSize to 8, since that is how it is actually encrypted. Even though it was padded with additional padding, it will be handled by the decryption since this was actually the behavior of .NET Framework (it was always padded to the block size). So the decryption handles the extra padding already, and encryption will start producing smaller ciphertexts since it will contain at most one byte of padding.

As noted in the issue, this breaking change will have a small impact.

Closes #55477.

Author: vcsjones
Assignees: -
Labels:

area-System.Security

Milestone: -

//
// The delegate must instantiate a new CngKey, based on a new underlying NCryptKeyHandle, each time is called.
//
public BasicSymmetricCipherNCrypt(Func<CngKey> cngKeyFactory, CipherMode cipherMode, int blockSizeInBytes, byte[]? iv, bool encrypting, int feedbackSizeInBytes, int paddingSize)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't do anything with the feedback size here, so stop accepting it so new callers don't assume it does anything.

{
using (SymmetricAlgorithm alg = persistedFunc(keyName))
{
alg.Mode = CipherMode.CFB;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The positive "it works with CFB8" tests were added in the CFB one-shot PR. #55480

@vcsjones vcsjones added the breaking-change Issue or PR that represents a breaking API or functional change over a previous release. label Jul 14, 2021
@ghost ghost added the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Jul 14, 2021
@ghost
Copy link

ghost commented Jul 14, 2021

Tagging @dotnet/compat for awareness of the breaking change.

@vcsjones vcsjones marked this pull request as ready for review July 14, 2021 01:38
@vcsjones
Copy link
Member Author

vcsjones commented Jul 14, 2021

This should get an outerloop run once the changes look good and innerloop looks reasonable.

@vcsjones vcsjones added this to the 6.0.0 milestone Jul 14, 2021
@vcsjones vcsjones force-pushed the persisted-cfb-cng-feedback-size branch from 9474b27 to 88ac833 Compare July 14, 2021 02:12
Link="CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\SignVerify.netcoreapp.cs" />
<Compile Condition="'$(TargetsWindows)' == 'true'" Include="AesCngTests.cs" />
<Compile Condition="'$(TargetsWindows)' == 'true'" Include="TripleDESCngTests.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\AlgorithmImplementations\TripleDES\TripleDESContractTests.cs"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out we were never running these contract tests under CNG.

@vcsjones
Copy link
Member Author

So the decryption handles the extra padding already, and encryption will start producing smaller ciphertexts since it will contain at most one byte of padding.

I would have bet some sum of money that this test already existed... but I couldn't find it, so I added one. If the CFB8-but-block-length-padded tests are duplicate I would be happy to remove them.

@bartonjs
Copy link
Member

Thanks for continuing to be quite speedy, @vcsjones!

@bartonjs
Copy link
Member

/azp run runtime-libraries-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@vcsjones
Copy link
Member Author

All failures appear unrelated.

@bartonjs
Copy link
Member

All failures appear unrelated.

I concur.

@bartonjs bartonjs merged commit f6e9532 into dotnet:main Jul 14, 2021
@vcsjones vcsjones deleted the persisted-cfb-cng-feedback-size branch July 14, 2021 19:22
@ghost ghost locked as resolved and limited conversation to collaborators Aug 13, 2021
@bartonjs
Copy link
Member

Documentation issue opened: dotnet/docs#26326

@bartonjs bartonjs removed the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Sep 30, 2021
@bartonjs bartonjs removed their assignment Sep 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Security breaking-change Issue or PR that represents a breaking API or functional change over a previous release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Persisted-key AesCng in CFB mode always uses CFB8

2 participants