Ejemplo n.º 1
0
NTSTATUS WINAPI RegisterProvider(BOOLEAN KernelMode)
{
    NTSTATUS status;

    UNREFERENCED_PARAMETER(KernelMode);

    status = BCryptRegisterProvider(VIRTRNG_PROVIDER_NAME, CRYPT_OVERWRITE,
        &VirtRngProvider);

    if (!NT_SUCCESS(status))
    {
        SetupWriteTextLogError(SetupGetThreadLogToken(),
            TXTLOG_INSTALLER,
            TXTLOG_ERROR,
            ToDosError(status),
            "Failed to register as a CNG provider.");
        return status;
    }

    status = BCryptAddContextFunctionProvider(CRYPT_LOCAL, NULL,
        BCRYPT_RNG_INTERFACE, BCRYPT_RNG_ALGORITHM, VIRTRNG_PROVIDER_NAME,
        CRYPT_PRIORITY_BOTTOM);

    if (!NT_SUCCESS(status))
    {
        SetupWriteTextLogError(SetupGetThreadLogToken(),
            TXTLOG_INSTALLER,
            TXTLOG_ERROR,
            ToDosError(status),
            "Failed to add cryptographic function.");
    }

    return status;
}
	void cng_register_algorithms(){
		CSP_LOG_TRACE
		
		//hash  reg
		PWSTR	cng_hash_functions[1] = {0};
		cng_hash_functions[0]=CNG_G34311_ALGORITHM;


		CRYPT_INTERFACE_REG	cng_prov_intrface_hash = {0};
		cng_prov_intrface_hash.dwInterface = BCRYPT_HASH_INTERFACE;
		cng_prov_intrface_hash.dwFlags = CRYPT_LOCAL;
		cng_prov_intrface_hash.cFunctions = STC_ARRAY_SIZE(cng_hash_functions);
		cng_prov_intrface_hash.rgpszFunctions = &cng_hash_functions[0];

		//symm reg
		PWSTR	cng_symm_functions[1] = {0};
		cng_symm_functions[0]=CNG_G28147_89;


		CRYPT_INTERFACE_REG	cng_prov_intrface_symm = {0};
		cng_prov_intrface_symm.dwInterface = BCRYPT_CIPHER_INTERFACE;
		cng_prov_intrface_symm.dwFlags = CRYPT_LOCAL;
		cng_prov_intrface_symm.cFunctions = STC_ARRAY_SIZE(cng_symm_functions);
		cng_prov_intrface_symm.rgpszFunctions = &cng_symm_functions[0];

		//asym
		PWSTR	cng_asymm_functions[1] = {0};
		cng_asymm_functions[0]=CNG_DSTU4145;


		CRYPT_INTERFACE_REG	cng_prov_intrface_asymm = {0};
		cng_prov_intrface_asymm.dwInterface = BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE;
		cng_prov_intrface_asymm.dwFlags = CRYPT_LOCAL;
		cng_prov_intrface_asymm.cFunctions = STC_ARRAY_SIZE(cng_asymm_functions);
		cng_prov_intrface_asymm.rgpszFunctions = &cng_asymm_functions[0];

		//storage
		PWSTR	cng_keystorage_functions[1] = {0};
		cng_keystorage_functions[0]=NCRYPT_KEY_STORAGE_ALGORITHM;


		CRYPT_INTERFACE_REG	cng_prov_intrface_keystorage = {0};
		cng_prov_intrface_keystorage.dwInterface = NCRYPT_KEY_STORAGE_INTERFACE;
		cng_prov_intrface_keystorage.dwFlags = CRYPT_LOCAL;
		cng_prov_intrface_keystorage.cFunctions = STC_ARRAY_SIZE(cng_keystorage_functions);
		cng_prov_intrface_keystorage.rgpszFunctions = &cng_keystorage_functions[0];

		//rng
		PWSTR	cng_rng_functions[1] = {0};
		cng_rng_functions[0]=BCRYPT_RNG_ALGORITHM;


		CRYPT_INTERFACE_REG	cng_prov_intrface_rng = {0};
		cng_prov_intrface_rng.dwInterface = BCRYPT_RNG_INTERFACE;
		cng_prov_intrface_rng.dwFlags = CRYPT_LOCAL;
		cng_prov_intrface_rng.cFunctions = STC_ARRAY_SIZE(cng_rng_functions);
		cng_prov_intrface_rng.rgpszFunctions = &cng_rng_functions[0];

		//secret agr
		PWSTR	cng_secret_agr_functions[1] = {0};
		cng_secret_agr_functions[0]=BCRYPT_DH_ALGORITHM;


		CRYPT_INTERFACE_REG	cng_prov_intrface_secret_agr = {0};
		cng_prov_intrface_secret_agr.dwInterface = BCRYPT_SECRET_AGREEMENT_INTERFACE;
		cng_prov_intrface_secret_agr.dwFlags = CRYPT_LOCAL;
		cng_prov_intrface_secret_agr.cFunctions = STC_ARRAY_SIZE(cng_secret_agr_functions);
		cng_prov_intrface_secret_agr.rgpszFunctions = &cng_secret_agr_functions[0];

		//common reg
		PCRYPT_INTERFACE_REG cng_prov_intrfaces[] = {
			&cng_prov_intrface_hash,
			&cng_prov_intrface_symm,
			&cng_prov_intrface_asymm,
			&cng_prov_intrface_keystorage,
			&cng_prov_intrface_rng,
			&cng_prov_intrface_secret_agr
		};

		CRYPT_IMAGE_REG	   	cng_prov_use_mode_info = {0};
		cng_prov_use_mode_info.pszImage = L"stcrypt-cng.dll"; //TODO: extract name from rt module
		cng_prov_use_mode_info.cInterfaces = STC_ARRAY_SIZE(cng_prov_intrfaces);
		cng_prov_use_mode_info.rgpInterfaces = &cng_prov_intrfaces[0];

		PWSTR prov_aliases[] = {
			CNG_STCRYPT_KEYSTORAGE
		};

		CRYPT_PROVIDER_REG	cng_prov_reg_info = {0};
		cng_prov_reg_info.rgpszAliases = &prov_aliases[0];
		cng_prov_reg_info.cAliases = STC_ARRAY_SIZE(prov_aliases);
		cng_prov_reg_info.pUM = &cng_prov_use_mode_info;

		NTSTATUS const r1 = BCryptRegisterProvider(STCRYPT_PROVIDER_NAME_W, CRYPT_OVERWRITE, &cng_prov_reg_info);
		if(r1!=STATUS_SUCCESS) STCRYPT_THROW_EXCEPTION( exception::cng_call() << exception::ntstatus_einfo(r1) );

		struct context_reg_info_t {
			ULONG	m_interface;
			LPCWSTR m_function;
			ULONG	m_priority;
		};

		context_reg_info_t context_reg_info[]={
			{NCRYPT_KEY_STORAGE_INTERFACE,				NCRYPT_KEY_STORAGE_ALGORITHM,	CRYPT_PRIORITY_BOTTOM},
			{BCRYPT_HASH_INTERFACE,						CNG_G34311_ALGORITHM,			CRYPT_PRIORITY_TOP},
			{BCRYPT_CIPHER_INTERFACE,					CNG_G28147_89,					CRYPT_PRIORITY_TOP},
			{BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE,	CNG_DSTU4145,					CRYPT_PRIORITY_TOP},
			{BCRYPT_RNG_INTERFACE,						BCRYPT_RNG_ALGORITHM,	CRYPT_PRIORITY_BOTTOM}
		};

		std::for_each( boost::begin(context_reg_info), boost::end(context_reg_info), [](context_reg_info_t const& ri){
			NTSTATUS const r2 = BCryptAddContextFunctionProvider(
				CRYPT_LOCAL, 
				NULL, // Default context.
				ri.m_interface, 
				ri.m_function,
				STCRYPT_PROVIDER_NAME_W,
				ri.m_priority);

			if(r2!=STATUS_SUCCESS)  STCRYPT_THROW_EXCEPTION( exception::cng_call() << exception::ntstatus_einfo(r2) );;
		} );

 		
	}