Skip to content

Instantly share code, notes, and snippets.

@johnallers
Last active October 31, 2018 13:25
Show Gist options
  • Save johnallers/ead0d1e4e7dd47f2b0af2c53455e81ec to your computer and use it in GitHub Desktop.
Save johnallers/ead0d1e4e7dd47f2b0af2c53455e81ec to your computer and use it in GitHub Desktop.
Test basic CNG API methods
#include <stdio.h>
#include <Windows.h>
#include <ncrypt.h>
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#define CAVIUM_KEYSTORE_PROVIDER L"Cavium Key Storage Provider"
#define MS_KEY_STORAGE_PROVIDER L"Microsoft Software Key Storage Provider"
// Enumerate the registered providers and determine whether the Cavium CNG provider
// and the Cavium KSP provider exist.
//
void ListStorageProviders()
{
NTSTATUS status;
ULONG cbBuffer = 0;
PCRYPT_PROVIDERS pBuffer = NULL;
bool foundCng = false;
bool foundKeystore = false;
DWORD pdwProviderCount = 0;
NCryptProviderName* ppProviderList = NULL;
NCryptEnumStorageProviders(&pdwProviderCount, &ppProviderList, NCRYPT_SILENT_FLAG);
if (ppProviderList != NULL)
{
for (DWORD i = 0; i < pdwProviderCount; i++)
{
NCryptProviderName current = ppProviderList[i];
printf("Found %S\n", current.pszName);
}
}
// Free memory allocated for the CRYPT_PROVIDERS structure.
if (NULL != ppProviderList)
{
NCryptFreeBuffer(ppProviderList);
}
}
// Enumerate the registered providers and determine whether the Cavium CNG provider
// and the Cavium KSP provider exist.
//
bool VerifyProvider()
{
NTSTATUS status;
ULONG cbBuffer = 0;
PCRYPT_PROVIDERS pBuffer = NULL;
bool foundKeystore = false;
// Retrieve information about the registered providers.
// cbBuffer - the size, in bytes, of the buffer pointed to by pBuffer.
// pBuffer - pointer to a buffer that contains a CRYPT_PROVIDERS structure.
status = BCryptEnumRegisteredProviders(&cbBuffer, &pBuffer);
// If registered providers exist, enumerate them and determine whether the
// Cavium CNG provider and Cavium KSP provider have been registered.
if (NT_SUCCESS(status))
{
if (pBuffer != NULL)
{
for (ULONG i = 0; i < pBuffer->cProviders; i++)
{
// Determine whether the Cavium KSP provider exists.
if (wcscmp(CAVIUM_KEYSTORE_PROVIDER, pBuffer->rgpszProviders[i]) == 0)
{
printf("Found %S\n", CAVIUM_KEYSTORE_PROVIDER);
foundKeystore = true;
}
}
}
}
else
{
printf("BCryptEnumRegisteredProviders failed with error code 0x%08x\n", status);
}
// Free memory allocated for the CRYPT_PROVIDERS structure.
if (NULL != pBuffer)
{
BCryptFreeBuffer(pBuffer);
}
return foundKeystore == true;
}
void CheckHardwareImpl(NCRYPT_HANDLE hProv) {
DWORD type = 0;
DWORD size = sizeof(type);
NCryptGetProperty(hProv, NCRYPT_IMPL_TYPE_PROPERTY, PBYTE(type), size, &size, 0);
if ((type & NCRYPT_IMPL_HARDWARE_FLAG) == 0)
{
printf("Provider DOES NOT contain NCRYPT_IMPL_HARDWARE_FLAG\n");
}
else
{
printf("Provider contains NCRYPT_IMPL_HARDWARE_FLAG\n");
}
}
// Generate an asymmetric key pair. As used here, this example generates an RSA key pair
// and returns a handle. The handle is used in subsequent operations that use the key pair.
// The key material is not available.
//
// The key pair is used in the SignData function.
//
NTSTATUS GenerateEphemeralKeyPair(NCRYPT_PROV_HANDLE hProv, NCRYPT_KEY_HANDLE *hKey)
{
NTSTATUS status;
// Generate the key pair.
status = NCryptCreatePersistedKey(hProv, hKey, L"RSA", NULL, 0, 0);
if (!NT_SUCCESS(status))
{
printf("NCryptCreatePersistedKey failed with code 0x%08x\n", status);
return status;
}
// Set export policy to no export
DWORD exportPolicy = 0;
NCryptSetProperty((NCRYPT_HANDLE)hKey, NCRYPT_EXPORT_POLICY_PROPERTY, PBYTE(exportPolicy), sizeof(exportPolicy), 0);
// Finalize the key pair. The public/private key pair cannot be used until this
// function is called.
status = NCryptFinalizeKey(*hKey, NCRYPT_SILENT_FLAG);
if (!NT_SUCCESS(status))
{
printf("NCryptFinalizeKey failed with code 0x%08x\n", status);
return status;
}
return status;
}
// Main function.
//
int main()
{
NTSTATUS status;
NCRYPT_KEY_HANDLE hKey = NULL;
NCRYPT_PROV_HANDLE hProv = NULL;
printf("Available storage providers...\n");
ListStorageProviders();
// Enumerate the registered providers.
printf("Searching for Cavium providers...\n");
if (VerifyProvider() == false) {
printf("Could not find the Keystore providers\n");
return 1;
}
// Opening the Cavium Keystore Provider
status = NCryptOpenStorageProvider(&hProv, CAVIUM_KEYSTORE_PROVIDER, NCRYPT_SILENT_FLAG);
if (!NT_SUCCESS(status))
{
printf("NCryptOpenStorageProvider failed with code 0x%08x\n", status);
return status;
}
CheckHardwareImpl(hProv);
// Generate an asymmetric key pair using the RSA algorithm.
printf("Generating RSA Keypair\n");
GenerateEphemeralKeyPair(hProv, &hKey);
if (hKey == NULL)
{
printf("Invalid key handle returned\n");
return 0;
}
printf("Done!\n");
if (hProv != NULL)
{
NCryptFreeBuffer(&hProv);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment