Skip to content

Introduce generic Hash abstraction as foundation for future algorithms - #6561

Open
Kaleb Luedtke (Trenly) wants to merge 13 commits into
microsoft:masterfrom
Trenly:HashAbstraction
Open

Kaleb Luedtke (Trenly) wants to merge 13 commits into
microsoft:masterfrom
Trenly:HashAbstraction

Conversation

@Trenly

@Trenly Kaleb Luedtke (Trenly) commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

📖 Description

Introduces a reusable CNG-backed hash abstraction in winget/Hash.h while preserving the existing AppInstaller::Utility::SHA256 API. This follow-up also clarifies the algorithm-bound alias name and explicitly preserves move support for hashers while disallowing copying.

🔗 References

Related to #5771; this PR does not implement SHA3-256 or close that issue.

🔍 Validation

  • src\x64\Debug\AppInstallerCLITests\AppInstallerCLITests.exe '[Cryptography]' — passed: 12 assertions in 5 test cases.
  • The author reports that the test project was built and the cryptography tests were run successfully.

✅ Checklist

🤖 AI Assistance

  • AI assistance was used and has been disclosed in this PR
  • No AI assistance was used

📋 Issue Type

  • Bug fix
  • Feature
  • Task

* Adds new Hash.cpp in SharedLib to provide base class access to BCrypt hashing functionality
* Moves implementation from SHA256 into the the base class
* Leaves the SHA256 namespace as a wrapper around the base class
Add a HashAlgorithmTraits/AlgorithmHash template in AppInstallerHash.h
that binds the generic Hash engine to a specific algorithm at compile
time, exposing the full SHA256-style API (Add, Get, ComputeHash*,
ConvertTo*, AreEqual) without per-function forwarding code.

Reduce SHA256 to an empty class deriving from
AlgorithmHash<HashAlgorithm::Sha256>, and remove the now-unnecessary
SHA256.cpp along with its project/filter entries.

Adding a new algorithm such as SHA3-256 will only require a new
HashAlgorithm enumerator, a HashAlgorithmTraits specialization, CNG
metadata in Hash.cpp, and an empty named class, with no forwarding
boilerplate.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@Trenly
Kaleb Luedtke (Trenly) marked this pull request as ready for review September 23, 2026 17:46
@Trenly
Kaleb Luedtke (Trenly) requested a review from a team as a code owner September 23, 2026 17:46
Comment thread src/AppInstallerSharedLib/Public/winget/Hash.h
Comment thread src/AppInstallerSharedLib/Public/AppInstallerHash.h Outdated
Comment thread src/AppInstallerSharedLib/Public/winget/Hash.h
Comment thread src/AppInstallerSharedLib/Public/AppInstallerHash.h Outdated
Comment thread src/AppInstallerSharedLib/Public/AppInstallerSHA256.h Outdated
Comment thread src/AppInstallerSharedLib/Public/AppInstallerHash.h Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/AppInstallerSharedLib/Public/winget/Hash.h Outdated
Comment thread src/AppInstallerSharedLib/Hash.cpp Outdated
Comment on lines +55 to +63
THROW_IF_NTSTATUS_FAILED_MSG(
BCryptOpenAlgorithmProvider(
&algHandle,
algorithmInfo.CngAlgorithmId,
nullptr,
0),
"failed opening %hs algorithm provider",
algorithmInfo.Name);
m_context->AlgHandle.reset(algHandle);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Seems like we lost some comments that we had in SHA256.cpp

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Restored concise comments describing opening the CNG algorithm provider, obtaining the hash length, creating the hash handle, stream badbit behavior, and the 1 MB buffer.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I know I'm being nitpicky and it's not a big deal if you keep this as-is, but I would prefer to keep the same level of comments we had before unless there is a reason to delete them, and also keep the same formatting. For example, making this section:

        // Open an algorithm handle
        THROW_IF_NTSTATUS_FAILED_MSG(BCryptOpenAlgorithmProvider(
            &algHandle,                   // Alg Handle pointer
            algorithmInfo.CngAlgorithmId, // Cryptographic Algorithm name (null terminated unicode string)
            nullptr,                      // Provider name; if null, the default provider is loaded
            0),                           // Flags
            "failed opening %hs algorithm provider",
            algorithmInfo.Name);

I'm hoping that would make git see this as a rename instead of a new file, and it would give us a nicer diff/blame.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't mind the nitpick, it makes sense. Totally valid feedback, will update.

Comment thread src/AppInstallerSharedLib/Hash.cpp

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The out-of-line destructor unintentionally removes the previous SHA256 type’s move semantics.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Introduces a reusable CNG-backed hash abstraction for future algorithms while retaining the existing SHA256 API.

Changes:

  • Replaces the SHA256 implementation with generic Hash/HashT types.
  • Updates projects and consumers to include winget/Hash.h.
  • Adds SHA256 regression tests and cryptography tags.
File Description
src/​Microsoft.Management.Configuration/​ConfigurationProcessor.cpp Uses the new hash header.
src/​AppInstallerSharedLib/​YamlWrapper.h Updates hash include.
src/​AppInstallerSharedLib/​SHA256.cpp Removes the previous implementation.
src/​AppInstallerSharedLib/​Public/​winget/​Yaml.h Uses the new public header.
src/​AppInstallerSharedLib/​Public/​winget/​Hash.h Defines the generic hash API and SHA256 alias.
src/​AppInstallerSharedLib/​Public/​AppInstallerSHA256.h Removes the previous SHA256 declaration.
src/​AppInstallerSharedLib/​Hash.cpp Implements generic CNG hashing.
src/​AppInstallerSharedLib/​AppInstallerStrings.cpp Updates hash include.
src/​AppInstallerSharedLib/​AppInstallerSharedLib.vcxproj.filters Replaces project filter entries.
src/​AppInstallerSharedLib/​AppInstallerSharedLib.vcxproj Registers the new source and header.
src/​AppInstallerRepositoryCore/​Rest/​RestInformationCache.h Updates hash include.
src/​AppInstallerRepositoryCore/​pch.h Updates precompiled-header dependency.
src/​AppInstallerRepositoryCore/​Microsoft/​Schema/​1_3/​Interface_1_3.cpp Updates hash include.
src/​AppInstallerRepositoryCore/​IconExtraction.cpp Updates and reorders includes.
src/​AppInstallerCommonCore/​Settings.cpp Updates hash include.
src/​AppInstallerCommonCore/​Public/​winget/​PortableFileEntry.h Updates hash include.
src/​AppInstallerCommonCore/​Public/​winget/​MSStoreDownload.h Updates hash include.
src/​AppInstallerCommonCore/​Public/​winget/​ManifestYamlParser.h Updates hash include.
src/​AppInstallerCommonCore/​Public/​winget/​Manifest.h Updates hash include.
src/​AppInstallerCommonCore/​Public/​winget/​FileCache.h Updates hash include.
src/​AppInstallerCommonCore/​Manifest/​YamlWriter.cpp Updates hash include.
src/​AppInstallerCommonCore/​Manifest/​YamlParser.cpp Updates hash include.
src/​AppInstallerCommonCore/​Manifest/​ManifestYamlPopulator.cpp Updates hash include.
src/​AppInstallerCommonCore/​Downloader.cpp Updates hash include.
src/​AppInstallerCommonCore/​DODownloader.cpp Updates hash include.
src/​AppInstallerCommonCore/​AppInstallerTelemetry.cpp Updates hash include.
src/​AppInstallerCLITests/​YamlManifest.cpp Updates test include.
src/​AppInstallerCLITests/​Strings.cpp Updates test include.
src/​AppInstallerCLITests/​SQLiteIndexTestCommon.cpp Updates test include.
src/​AppInstallerCLITests/​RestInterface_1_0.cpp Updates test include.
src/​AppInstallerCLITests/​MSStoreDownloadFlow.cpp Updates test include.
src/​AppInstallerCLITests/​HashCommand.cpp Adds SHA256 regression coverage.
src/​AppInstallerCLITests/​Downloader.cpp Updates test include.
src/​AppInstallerCLICore/​Workflows/​WorkflowBase.cpp Updates hash include.
src/​AppInstallerCLICore/​Workflows/​MSStoreInstallerHandler.cpp Updates hash include.
src/​AppInstallerCLICore/​Workflows/​ConfigurationFlow.cpp Updates hash include.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/AppInstallerSharedLib/Public/winget/Hash.h
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The implementation can silently produce incorrect hashes on oversized input or read failure, and it removes the legacy public include path despite the compatibility goal.

Review effort: Balanced
Findings: 2 High severity

Open (2)
Resolved since last review (1)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Preserve deleted AppInstallerSHA256.h as a forwarding header

src/​AppInstallerSharedLib/​Public/​winget/​Hash.h:193

This alias does not fully preserve the existing source API because the public AppInstallerSHA256.h header that existing consumers include is deleted. All in-repo includes were migrated, but out-of-tree code will fail before it can see this compatibility alias. Keep AppInstallerSHA256.h as a forwarding header that includes winget/Hash.h (and retain it in the project) while deprecating the old include path.

Comment thread src/AppInstallerSharedLib/Hash.cpp
Comment thread src/AppInstallerSharedLib/Hash.cpp Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@florelis

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

* Restore hash implementation comments

* Carry over hash header comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants