Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// PRTKeyDerivation.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include "pch.h"
#include <iostream>
#include "ntstatus.h"
#include "windows.h"
#include "bcrypt.h"
int main(int argc, char* argv[], char* envp[])
{
if (argc < 3) {
printf("Usage PRTKeyDerivation.exe <32-byte hex secretkey> <24-byte hex context>");
return -1;
}
if (strlen(argv[1]) != 64) {
printf("Size of secretkey != 32 hex bytes");
return -1;
}
if (strlen(argv[2]) != 48) {
printf("Size of context != 24 hex bytes");
return -1;
}
UCHAR secret[32]{};
UCHAR *j = 0;
for (int i = 0; i < sizeof(secret); i++) {
sscanf_s((argv[1]) + i * 2, "%02hhX", &j);
secret[i] = (UCHAR)j;
}
UCHAR context[24]{};
char *endptr;
for (int i = 0; i < sizeof(context); i++) {
sscanf_s((argv[2])+ i * 2, "%02hhX", &j);
context[i] = (UCHAR)j;
}
BCRYPT_ALG_HANDLE hProvider = NULL;
BCRYPT_KEY_HANDLE hKey = NULL;
NTSTATUS ret = BCryptOpenAlgorithmProvider(&hProvider, BCRYPT_SP800108_CTR_HMAC_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
if (!(BCRYPT_SUCCESS(ret)))
{
return -1;
}
NTSTATUS ret2 = BCryptGenerateSymmetricKey(hProvider, &hKey, NULL, 0, (PBYTE)secret, 32, 0);
const char *text = "AzureAD-SecureConversation";
static
BCryptBuffer SP800108ParamBuffer[] = {
{
26,
KDF_LABEL,
(PBYTE)text,
},
{
24,
KDF_CONTEXT,
(PBYTE)context,
},
{
sizeof(BCRYPT_SHA256_ALGORITHM),
KDF_HASH_ALGORITHM,
(PBYTE) BCRYPT_SHA256_ALGORITHM,
}
};
BCryptBufferDesc desc = { 0, 3, SP800108ParamBuffer };
PBYTE DerivedKey = NULL;
DWORD DerivedKeyLength = 0x20;
DerivedKey = (PBYTE)HeapAlloc(GetProcessHeap(), 0, DerivedKeyLength);
ULONG result = NULL;
NTSTATUS ret3 = BCryptKeyDerivation(hKey, &desc, DerivedKey, DerivedKeyLength, &result, 0);
int i = 0;
for (i = 0; i < result; i++)
{
printf("%02X", DerivedKey[i]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.