Exemple de code pour le fournisseur de GNC
Apprenez à indexer les fournisseurs cryptographiques enregistrés dans Dedicated KMS pour trouver le fournisseur CNG installé avec le programme d'installation du client Windows à l'aide de l'exemple de code fourni.
L'exemple de code suivant montre comment indexer les fournisseurs cryptographiques enregistrés pour trouver le fournisseur CNG installé avec le programme d'installation du client Windows. Le code montre également comment créer une paire de clés asymétriques et comment utiliser la paire de clés pour signer des données.
Avant d'exécuter cet exemple, vous devez configurer les données d'identification du module de sécurité matériel. Pour plus d'informations, voir Configuration du client de grappe du module de sécurité matériel sous Windows.
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
int testReturnStatus = 0;
BCRYPT_KEY_HANDLE GenerateKeyPair(
BCRYPT_ALG_HANDLE hAlg,
ULONG keyLen)
{
NTSTATUS status = -1;
BCRYPT_KEY_HANDLE keyHandle = NULL;
print_debug("Generating Key Pair of size: %lu\n", keyLen);
status = BCryptGenerateKeyPair(hAlg, &keyHandle, keyLen, 0);
if (status)
{
ReportErrorStatus(status, "\t\t\t\t\t\t\t FAIL BCryptGenerateKeyPair");
goto cleanup;
}
/* Finalize RSA keys generated */
status = BCryptFinalizeKeyPair(keyHandle, 0);
if (status)
{
ReportErrorStatus(status, "\t\t\t\t\t\t\t FAIL BCryptFinalizeKeyPair");
goto cleanup;
}
print_debug("Keypair Gen Success\n");
ReportErrorStatus(status, "\t\t PASS\n");
return keyHandle;
cleanup:
if (keyHandle) {
status = BCryptDestroyKey(keyHandle);
keyHandle = NULL;
if (status)
ReportErrorStatus(status, "BCryptDestroyKey");
}
return keyHandle;
}
static NTSTATUS testSignVerify(
PBYTE test,
BCRYPT_KEY_HANDLE signKey,
BCRYPT_KEY_HANDLE verifyKey,
ULONG keyLen,
VOID *pPaddingInfo)
{
NTSTATUS status = -1;
BYTE inbuf[CHUNK_SIZE];
BYTE hash[CHUNK_SIZE];
DWORD hash_size;
PBYTE sign = NULL;
DWORD i;
DWORD insize;
DWORD pcbResult = 0;
ULONG dwFlags = 0;
if (signKey == NULL || verifyKey == NULL) {
status = STATUS_INVALID_HANDLE;
goto cleanup;
}
printf("%s", test);
/* Fill input data; Alternatively can read from file */
for (i = 0; i < CHUNK_SIZE; i++)
inbuf[i] = (BYTE)i + 1;
insize = i;/* Length of inbuf */
if (pPaddingInfo)
dwFlags = BCRYPT_PAD_PKCS1;
// calculate the size of sign data needed
status = BCryptSignHash(signKey,
pPaddingInfo,
hash,
CHUNK_SIZE,
NULL,
0,
&pcbResult,
dwFlags
);
if (status)
{
ReportErrorStatus(status, "\t\t FAIL BCryptSignHash get-size");
goto cleanup;
}
print_debug("required sign data size: %lu\n", pcbResult);
status = CreateHash(BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, inbuf, insize, hash, &hash_size, NULL, 0, 0);
if (status)
goto cleanup;
sign = (PBYTE)HEAPALLOC(pcbResult);
if (sign == NULL) {
status = STATUS_UNSUCCESSFUL;
goto cleanup;
}
status = BCryptSignHash(signKey,
pPaddingInfo,
hash,
hash_size,
sign,
pcbResult,
&pcbResult,
dwFlags
);
if (status)
{
ReportErrorStatus(status, "\t\t FAIL BCryptSignHash");
goto cleanup;
}
print_debug("signed data size: %lu\n", pcbResult);
print_debug("Created Signature from Hash using MS Key Success\n");
/* Verify Signature with Cavium key*/
status = BCryptVerifySignature(verifyKey,
pPaddingInfo,
hash,
hash_size,
sign,
pcbResult,
dwFlags);
if (status)
{
ReportErrorStatus(status, "\t\t FAIL BCryptVerifySignature");
goto cleanup;
}
print_debug("Verifying Signature SUCCESS\n");
ReportErrorStatus(status, "\t\t PASS\n");
cleanup:
if (sign)
HeapFree(GetProcessHeap(), 0, sign);
return status;
}
static void testRSA()
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
LPCWSTR pszAlgId = NULL;
BCRYPT_ALG_HANDLE caviumAlg = NULL;
BCRYPT_ALG_HANDLE msAlg = NULL;
EncDecPriv priv = { 0 };
ULONG keyLen = 2048;
pszAlgId = BCRYPT_RSA_ALGORITHM;
//open Cavium CNG Provider
caviumAlg = OpenAlgorithmProvider(pszAlgId, CAVIUM_PROVIDER_NAME, 0);
if (caviumAlg == NULL)
goto cleanup;
//open Microsoft Primitive Provider
msAlg = OpenAlgorithmProvider(pszAlgId, MS_PRIMITIVE_PROVIDER, 0);
if (msAlg == NULL)
goto cleanup;
// fill priv structure
priv.alg = RSA;
priv.blockSize = 1;
printf("\n\n############################# %ls Unit Testing ########################################\n\n", pszAlgId);
printf("KeyLen\t Test\t\t Info\t\t\t Result\n");
printf("=======================================================================================\n");
for (keyLen = 2048; keyLen <= 4096; keyLen = keyLen + 256) {
printf("\n%lu\n", keyLen);
priv.keyLen = keyLen;
status = testRSACommon(caviumAlg, msAlg, &priv);
#ifdef RUN_MINIMAL_TEST
/* To test functionality with RSA 2048 key size only, break now. */
break; /* This will be suitable if we are running these tests in PR checker kind of build.*/
#endif
}
cleanup:
if (caviumAlg)
CloseAlgorithmProvider(caviumAlg, 0);
if (msAlg)
CloseAlgorithmProvider(msAlg, 0);
return;
}