absl::Status RegisterProvider()

in kmscng/util/registration.cc [28:94]


absl::Status RegisterProvider() {
  NTSTATUS status = 0;
  PWSTR algorithms[1] = {const_cast<wchar_t*>(NCRYPT_KEY_STORAGE_ALGORITHM)};

  CRYPT_INTERFACE_REG algorithm_class = {
      NCRYPT_KEY_STORAGE_INTERFACE,  // Ncrypt key storage interface
      CRYPT_LOCAL,                   // Scope: local system only
      1,                             // Algorithms count
      algorithms                     // Name(s) of the algorithm(s)
  };

  PCRYPT_INTERFACE_REG algorithm_classes[1] = {&algorithm_class};
  CRYPT_IMAGE_REG ksp_image = {
      const_cast<wchar_t*>(
          kProviderDllName.data()),  // File name of the KSP binary
      1,                 // Number of algorithm classes the binary supports
      algorithm_classes  // List of all algorithm classes available
  };

  CRYPT_PROVIDER_REG ksp_provider = {
      0,           // Aliases
      NULL,        // Names of aliases
      &ksp_image,  // Image that provides user-mode support
      NULL         // Image that provides kernel-mode support (*MUST* be NULL)
  };

  // Register our custom CNG provider
  status =
      BCryptRegisterProvider(kProviderName.data(),
                             CRYPT_OVERWRITE,  // overwrite an existing entry
                             &ksp_provider);
  if (!NT_SUCCESS(status)) {
    return absl::InternalError(absl::StrFormat(
        "BCryptRegisterProvider failed with error code 0x%08x\n", status));
  }

  // Add the algorithm name to the priority list of the key storage algorithm
  // class. (This makes it visible to BCryptResolveProviders.)
  status =
      BCryptAddContextFunction(CRYPT_LOCAL,  // Scope: local machine only
                               NULL,         // Application context: default
                               NCRYPT_KEY_STORAGE_INTERFACE,  // Algorithm class
                               NCRYPT_KEY_STORAGE_ALGORITHM,  // Algorithm name
                               CRYPT_PRIORITY_BOTTOM          // Lowest priority
      );
  if (!NT_SUCCESS(status)) {
    return absl::InternalError(absl::StrFormat(
        "BCryptAddContextFunction failed with error code 0x%08x\n", status));
  }

  // Identify our provider as an implementation of the key storage interface.
  status = BCryptAddContextFunctionProvider(
      CRYPT_LOCAL,                   // Scope: local machine only
      NULL,                          // Application context: default
      NCRYPT_KEY_STORAGE_INTERFACE,  // Algorithm class
      NCRYPT_KEY_STORAGE_ALGORITHM,  // Algorithm name
      kProviderName.data(),          // Provider name
      CRYPT_PRIORITY_BOTTOM          // Lowest priority
  );
  if (!NT_SUCCESS(status)) {
    return absl::InternalError(absl::StrFormat(
        "BCryptAddContextFunctionProvider failed with error code 0x%08x\n",
        status));
  }

  return absl::OkStatus();
}