Win32 API 日本語リファレンス
ホーム › Security.Cryptography › BCryptKeyDerivation

BCryptKeyDerivation

関数
鍵オブジェクトからパラメータに基づき鍵データを導出する。
DLLbcrypt.dll呼出規約winapi対応OSwindows8.0

シグネチャ

// bcrypt.dll
#include <windows.h>

NTSTATUS BCryptKeyDerivation(
    BCRYPT_KEY_HANDLE hKey,
    BCryptBufferDesc* pParameterList,   // optional
    BYTE* pbDerivedKey,
    DWORD cbDerivedKey,
    DWORD* pcbResult,
    DWORD dwFlags
);

パラメーター

名前型方向説明
hKeyBCRYPT_KEY_HANDLEinキー派生関数 (KDF) キーのハンドル。「解説」を参照してください。
pParameterListBCryptBufferDesc*inoptional

KDF パラメーターを格納する BCryptBufferDesc 構造体のアドレス。このパラメーターは省略可能であり、不要な場合は NULL を指定できます。

パラメーターには、キー派生関数 (KDF) に固有のものと汎用的なものがあります。次の表は、Microsoft Primitive プロバイダーが実装する個々の KDF について、必須および省略可能なパラメーターを示しています。追加情報の一部は BCryptBuffer のドキュメントに記載されています。

KDF パラメーター 必須 既定値
カウンター モードの SP800-108 HMAC KDF_LABEL はい
KDF_CONTEXT はい
KDF_HASH_ALGORITHM はい
SP800-56A KDF_ALGORITHMID はい
KDF_PARTYUINFO はい
KDF_PARTYVINFO はい
KDF_HASH_ALGORITHM はい
KDF_SUPPPUBINFO いいえ ""
KDF_SUPPPRIVINFO いいえ ""
PBKDF2 KDF_HASH_ALGORITHM はい
KDF_SALT はい
KDF_ITERATION_COUNT いいえ 10000
CAPI_KDF KDF_HASH_ALGORITHM はい
TLS1_1_PRF KDF_TLS_PRF_LABEL はい
KDF_TLS_PRF_SEED はい
TLS1_2_PRF KDF_TLS_PRF_LABEL はい
KDF_TLS_PRF_SEED はい
KDF_HASH_ALGORITHM はい
HKDF KDF_HKDF_INFO いいえ ""

一部のアルゴリズムでは、複数のパラメーターを個別に指定する代わりに KDF_GENERIC_PARAMETER を使用できます。これは、次のように KDF 固有のパラメーターに対応付けられます。

カウンター モードの SP800-108 HMAC:

SP800-56A:

PBKDF2:

pbDerivedKeyBYTE*outキーを受け取るバッファーのアドレス。cbDerivedKey パラメーターには、このバッファーのサイズを指定します。
cbDerivedKeyDWORDinpbDerivedKey パラメーターが指すバッファーのサイズ (バイト単位)。
pcbResultDWORD*outpbDerivedKey パラメーターが指すバッファーにコピーされたバイト数を受け取る ULONG へのポインター。
dwFlagsDWORDin

この関数の動作を変更するフラグ。Microsoft Primitive プロバイダーでは次の値を使用できます。

値 意味
BCRYPT_CAPI_AES_FLAG 対象のアルゴリズムが AES であり、そのためキーを二重に拡張する必要があることを指定します。このフラグは CAPI_KDF アルゴリズムでのみ有効です。

戻り値の型: NTSTATUS

公式ドキュメント

シークレット アグリーメントを必要とせずにキーを派生させます。

戻り値

関数の成功または失敗を示すステータス コードを返します。

解説(Remarks)

BCryptKeyDerivation を使用する流れは次のとおりです。

  1. 使用する KDF アルゴリズムを決定し、そのアルゴリズム ハンドルを取得します。BCryptOpenAlgorithmProvider では次のアルゴリズム識別子を使用できます。
  1. キーの派生元となるシークレット データを決定し、アルゴリズム ハンドルとともに BCryptGenerateSymmetricKey に渡して、KDF キー ハンドルを生成します。

  2. KDF キー ハンドルを指定して BCryptKeyDerivation を呼び出します。

この関数をカーネル モードで呼び出すには、Driver Development Kit (DDK) に含まれる Cng.lib を使用します。 Windows Server 2008 および Windows Vista: この関数をカーネル モードで呼び出すには、Ksecdd.lib を使用します。

HKDF

HKDF では、次のどちらからキーを派生させるのかが区別されます。

  1. 一様ランダムではなく、入力キー マテリアル (IKM) と見なされる、シークレット アグリーメント関数の出力。
  2. 一様ランダムなシークレット値。
最初の手順は、提供されたシークレット データから疑似ランダム キー (PRK) を "Extract" (抽出) することです。

この手順は、KDF キー ハンドルに対して BCRYPT_HKDF_HASH_ALGORITHM を指定して BCryptSetProperty を呼び出し、HKDF の HMAC 計算で使用するハッシュ アルゴリズムを設定することで行います。 続いて、次のいずれかを指定して BCryptSetProperty を 2 回目に呼び出します。

  1. 提供されたシークレット データが IKM を表す場合は、BCRYPT_HKDF_SALT_AND_FINALIZE を使用して省略可能なソルト値を指定し、IKM から PRK を抽出して KDF キー ハンドルを確定します。
  2. それ以外の場合は、BCRYPT_HKDF_PRK_AND_FINALIZE を使用して、提供されたシークレットを直接 HKDF の PRK に変換し、KDF キー ハンドルを確定します。
2 番目の手順は、PRK を出力の派生キーへと "Expand" (展開) することです。

この手順は、確定済みの KDF キー ハンドルに対して BCryptKeyDerivation を呼び出すことで行います。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// bcrypt.dll
#include <windows.h>

NTSTATUS BCryptKeyDerivation(
    BCRYPT_KEY_HANDLE hKey,
    BCryptBufferDesc* pParameterList,   // optional
    BYTE* pbDerivedKey,
    DWORD cbDerivedKey,
    DWORD* pcbResult,
    DWORD dwFlags
);
[DllImport("bcrypt.dll", ExactSpelling = true)]
static extern int BCryptKeyDerivation(
    IntPtr hKey,   // BCRYPT_KEY_HANDLE
    IntPtr pParameterList,   // BCryptBufferDesc* optional
    IntPtr pbDerivedKey,   // BYTE* out
    uint cbDerivedKey,   // DWORD
    out uint pcbResult,   // DWORD* out
    uint dwFlags   // DWORD
);
<DllImport("bcrypt.dll", ExactSpelling:=True)>
Public Shared Function BCryptKeyDerivation(
    hKey As IntPtr,   ' BCRYPT_KEY_HANDLE
    pParameterList As IntPtr,   ' BCryptBufferDesc* optional
    pbDerivedKey As IntPtr,   ' BYTE* out
    cbDerivedKey As UInteger,   ' DWORD
    <Out> ByRef pcbResult As UInteger,   ' DWORD* out
    dwFlags As UInteger   ' DWORD
) As Integer
End Function
' hKey : BCRYPT_KEY_HANDLE
' pParameterList : BCryptBufferDesc* optional
' pbDerivedKey : BYTE* out
' cbDerivedKey : DWORD
' pcbResult : DWORD* out
' dwFlags : DWORD
Declare PtrSafe Function BCryptKeyDerivation Lib "bcrypt" ( _
    ByVal hKey As LongPtr, _
    ByVal pParameterList As LongPtr, _
    ByVal pbDerivedKey As LongPtr, _
    ByVal cbDerivedKey As Long, _
    ByRef pcbResult As Long, _
    ByVal dwFlags As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

BCryptKeyDerivation = ctypes.windll.bcrypt.BCryptKeyDerivation
BCryptKeyDerivation.restype = ctypes.c_int
BCryptKeyDerivation.argtypes = [
    wintypes.HANDLE,  # hKey : BCRYPT_KEY_HANDLE
    ctypes.c_void_p,  # pParameterList : BCryptBufferDesc* optional
    ctypes.POINTER(ctypes.c_ubyte),  # pbDerivedKey : BYTE* out
    wintypes.DWORD,  # cbDerivedKey : DWORD
    ctypes.POINTER(wintypes.DWORD),  # pcbResult : DWORD* out
    wintypes.DWORD,  # dwFlags : DWORD
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('bcrypt.dll')
BCryptKeyDerivation = Fiddle::Function.new(
  lib['BCryptKeyDerivation'],
  [
    Fiddle::TYPE_VOIDP,  # hKey : BCRYPT_KEY_HANDLE
    Fiddle::TYPE_VOIDP,  # pParameterList : BCryptBufferDesc* optional
    Fiddle::TYPE_VOIDP,  # pbDerivedKey : BYTE* out
    -Fiddle::TYPE_INT,  # cbDerivedKey : DWORD
    Fiddle::TYPE_VOIDP,  # pcbResult : DWORD* out
    -Fiddle::TYPE_INT,  # dwFlags : DWORD
  ],
  Fiddle::TYPE_INT)
#[link(name = "bcrypt")]
extern "system" {
    fn BCryptKeyDerivation(
        hKey: *mut core::ffi::c_void,  // BCRYPT_KEY_HANDLE
        pParameterList: *mut BCryptBufferDesc,  // BCryptBufferDesc* optional
        pbDerivedKey: *mut u8,  // BYTE* out
        cbDerivedKey: u32,  // DWORD
        pcbResult: *mut u32,  // DWORD* out
        dwFlags: u32  // DWORD
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("bcrypt.dll")]
public static extern int BCryptKeyDerivation(IntPtr hKey, IntPtr pParameterList, IntPtr pbDerivedKey, uint cbDerivedKey, out uint pcbResult, uint dwFlags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'bcrypt_BCryptKeyDerivation' -Namespace Win32 -PassThru
# $api::BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags)
#uselib "bcrypt.dll"
#func global BCryptKeyDerivation "BCryptKeyDerivation" sptr, sptr, sptr, sptr, sptr, sptr
; BCryptKeyDerivation hKey, varptr(pParameterList), varptr(pbDerivedKey), cbDerivedKey, varptr(pcbResult), dwFlags   ; 戻り値は stat
; hKey : BCRYPT_KEY_HANDLE -> "sptr"
; pParameterList : BCryptBufferDesc* optional -> "sptr"
; pbDerivedKey : BYTE* out -> "sptr"
; cbDerivedKey : DWORD -> "sptr"
; pcbResult : DWORD* out -> "sptr"
; dwFlags : DWORD -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "bcrypt.dll"
#cfunc global BCryptKeyDerivation "BCryptKeyDerivation" sptr, var, var, int, var, int
; res = BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags)
; hKey : BCRYPT_KEY_HANDLE -> "sptr"
; pParameterList : BCryptBufferDesc* optional -> "var"
; pbDerivedKey : BYTE* out -> "var"
; cbDerivedKey : DWORD -> "int"
; pcbResult : DWORD* out -> "var"
; dwFlags : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; NTSTATUS BCryptKeyDerivation(BCRYPT_KEY_HANDLE hKey, BCryptBufferDesc* pParameterList, BYTE* pbDerivedKey, DWORD cbDerivedKey, DWORD* pcbResult, DWORD dwFlags)
#uselib "bcrypt.dll"
#cfunc global BCryptKeyDerivation "BCryptKeyDerivation" intptr, var, var, int, var, int
; res = BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags)
; hKey : BCRYPT_KEY_HANDLE -> "intptr"
; pParameterList : BCryptBufferDesc* optional -> "var"
; pbDerivedKey : BYTE* out -> "var"
; cbDerivedKey : DWORD -> "int"
; pcbResult : DWORD* out -> "var"
; dwFlags : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	bcrypt = windows.NewLazySystemDLL("bcrypt.dll")
	procBCryptKeyDerivation = bcrypt.NewProc("BCryptKeyDerivation")
)

// hKey (BCRYPT_KEY_HANDLE), pParameterList (BCryptBufferDesc* optional), pbDerivedKey (BYTE* out), cbDerivedKey (DWORD), pcbResult (DWORD* out), dwFlags (DWORD)
r1, _, err := procBCryptKeyDerivation.Call(
	uintptr(hKey),
	uintptr(pParameterList),
	uintptr(pbDerivedKey),
	uintptr(cbDerivedKey),
	uintptr(pcbResult),
	uintptr(dwFlags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // NTSTATUS
function BCryptKeyDerivation(
  hKey: THandle;   // BCRYPT_KEY_HANDLE
  pParameterList: Pointer;   // BCryptBufferDesc* optional
  pbDerivedKey: Pointer;   // BYTE* out
  cbDerivedKey: DWORD;   // DWORD
  pcbResult: Pointer;   // DWORD* out
  dwFlags: DWORD   // DWORD
): Integer; stdcall;
  external 'bcrypt.dll' name 'BCryptKeyDerivation';
result := DllCall("bcrypt\BCryptKeyDerivation"
    , "Ptr", hKey   ; BCRYPT_KEY_HANDLE
    , "Ptr", pParameterList   ; BCryptBufferDesc* optional
    , "Ptr", pbDerivedKey   ; BYTE* out
    , "UInt", cbDerivedKey   ; DWORD
    , "Ptr", pcbResult   ; DWORD* out
    , "UInt", dwFlags   ; DWORD
    , "Int")   ; return: NTSTATUS
●BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags) = DLL("bcrypt.dll", "int BCryptKeyDerivation(void*, void*, void*, dword, void*, dword)")
# 呼び出し: BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags)
# hKey : BCRYPT_KEY_HANDLE -> "void*"
# pParameterList : BCryptBufferDesc* optional -> "void*"
# pbDerivedKey : BYTE* out -> "void*"
# cbDerivedKey : DWORD -> "dword"
# pcbResult : DWORD* out -> "void*"
# dwFlags : DWORD -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "bcrypt" fn BCryptKeyDerivation(
    hKey: ?*anyopaque, // BCRYPT_KEY_HANDLE
    pParameterList: [*c]BCryptBufferDesc, // BCryptBufferDesc* optional
    pbDerivedKey: [*c]u8, // BYTE* out
    cbDerivedKey: u32, // DWORD
    pcbResult: [*c]u32, // DWORD* out
    dwFlags: u32 // DWORD
) callconv(std.os.windows.WINAPI) i32;
proc BCryptKeyDerivation(
    hKey: pointer,  # BCRYPT_KEY_HANDLE
    pParameterList: ptr BCryptBufferDesc,  # BCryptBufferDesc* optional
    pbDerivedKey: ptr uint8,  # BYTE* out
    cbDerivedKey: uint32,  # DWORD
    pcbResult: ptr uint32,  # DWORD* out
    dwFlags: uint32  # DWORD
): int32 {.importc: "BCryptKeyDerivation", stdcall, dynlib: "bcrypt.dll".}
pragma(lib, "bcrypt");
extern(Windows)
int BCryptKeyDerivation(
    void* hKey,   // BCRYPT_KEY_HANDLE
    BCryptBufferDesc* pParameterList,   // BCryptBufferDesc* optional
    ubyte* pbDerivedKey,   // BYTE* out
    uint cbDerivedKey,   // DWORD
    uint* pcbResult,   // DWORD* out
    uint dwFlags   // DWORD
);
ccall((:BCryptKeyDerivation, "bcrypt.dll"), stdcall, Int32,
      (Ptr{Cvoid}, Ptr{BCryptBufferDesc}, Ptr{UInt8}, UInt32, Ptr{UInt32}, UInt32),
      hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags)
# hKey : BCRYPT_KEY_HANDLE -> Ptr{Cvoid}
# pParameterList : BCryptBufferDesc* optional -> Ptr{BCryptBufferDesc}
# pbDerivedKey : BYTE* out -> Ptr{UInt8}
# cbDerivedKey : DWORD -> UInt32
# pcbResult : DWORD* out -> Ptr{UInt32}
# dwFlags : DWORD -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t BCryptKeyDerivation(
    void* hKey,
    void* pParameterList,
    uint8_t* pbDerivedKey,
    uint32_t cbDerivedKey,
    uint32_t* pcbResult,
    uint32_t dwFlags);
]]
local bcrypt = ffi.load("bcrypt")
-- bcrypt.BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags)
-- hKey : BCRYPT_KEY_HANDLE
-- pParameterList : BCryptBufferDesc* optional
-- pbDerivedKey : BYTE* out
-- cbDerivedKey : DWORD
-- pcbResult : DWORD* out
-- dwFlags : DWORD
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('bcrypt.dll');
const BCryptKeyDerivation = lib.func('__stdcall', 'BCryptKeyDerivation', 'int32_t', ['void *', 'void *', 'uint8_t *', 'uint32_t', 'uint32_t *', 'uint32_t']);
// BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags)
// hKey : BCRYPT_KEY_HANDLE -> 'void *'
// pParameterList : BCryptBufferDesc* optional -> 'void *'
// pbDerivedKey : BYTE* out -> 'uint8_t *'
// cbDerivedKey : DWORD -> 'uint32_t'
// pcbResult : DWORD* out -> 'uint32_t *'
// dwFlags : DWORD -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("bcrypt.dll", {
  BCryptKeyDerivation: { parameters: ["pointer", "pointer", "pointer", "u32", "pointer", "u32"], result: "i32" },
});
// lib.symbols.BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags)
// hKey : BCRYPT_KEY_HANDLE -> "pointer"
// pParameterList : BCryptBufferDesc* optional -> "pointer"
// pbDerivedKey : BYTE* out -> "pointer"
// cbDerivedKey : DWORD -> "u32"
// pcbResult : DWORD* out -> "pointer"
// dwFlags : DWORD -> "u32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t BCryptKeyDerivation(
    void* hKey,
    void* pParameterList,
    uint8_t* pbDerivedKey,
    uint32_t cbDerivedKey,
    uint32_t* pcbResult,
    uint32_t dwFlags);
C, "bcrypt.dll");
// $ffi->BCryptKeyDerivation(hKey, pParameterList, pbDerivedKey, cbDerivedKey, pcbResult, dwFlags);
// hKey : BCRYPT_KEY_HANDLE
// pParameterList : BCryptBufferDesc* optional
// pbDerivedKey : BYTE* out
// cbDerivedKey : DWORD
// pcbResult : DWORD* out
// dwFlags : DWORD
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Bcrypt extends StdCallLibrary {
    Bcrypt INSTANCE = Native.load("bcrypt", Bcrypt.class);
    int BCryptKeyDerivation(
        Pointer hKey,   // BCRYPT_KEY_HANDLE
        Pointer pParameterList,   // BCryptBufferDesc* optional
        byte[] pbDerivedKey,   // BYTE* out
        int cbDerivedKey,   // DWORD
        IntByReference pcbResult,   // DWORD* out
        int dwFlags   // DWORD
    );
}
@[Link("bcrypt")]
lib Libbcrypt
  fun BCryptKeyDerivation = BCryptKeyDerivation(
    hKey : Void*,   # BCRYPT_KEY_HANDLE
    pParameterList : BCryptBufferDesc*,   # BCryptBufferDesc* optional
    pbDerivedKey : UInt8*,   # BYTE* out
    cbDerivedKey : UInt32,   # DWORD
    pcbResult : UInt32*,   # DWORD* out
    dwFlags : UInt32   # DWORD
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef BCryptKeyDerivationNative = Int32 Function(Pointer<Void>, Pointer<Void>, Pointer<Uint8>, Uint32, Pointer<Uint32>, Uint32);
typedef BCryptKeyDerivationDart = int Function(Pointer<Void>, Pointer<Void>, Pointer<Uint8>, int, Pointer<Uint32>, int);
final BCryptKeyDerivation = DynamicLibrary.open('bcrypt.dll')
    .lookupFunction<BCryptKeyDerivationNative, BCryptKeyDerivationDart>('BCryptKeyDerivation');
// hKey : BCRYPT_KEY_HANDLE -> Pointer<Void>
// pParameterList : BCryptBufferDesc* optional -> Pointer<Void>
// pbDerivedKey : BYTE* out -> Pointer<Uint8>
// cbDerivedKey : DWORD -> Uint32
// pcbResult : DWORD* out -> Pointer<Uint32>
// dwFlags : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function BCryptKeyDerivation(
  hKey: THandle;   // BCRYPT_KEY_HANDLE
  pParameterList: Pointer;   // BCryptBufferDesc* optional
  pbDerivedKey: Pointer;   // BYTE* out
  cbDerivedKey: DWORD;   // DWORD
  pcbResult: Pointer;   // DWORD* out
  dwFlags: DWORD   // DWORD
): Integer; stdcall;
  external 'bcrypt.dll' name 'BCryptKeyDerivation';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "BCryptKeyDerivation"
  c_BCryptKeyDerivation :: Ptr () -> Ptr () -> Ptr Word8 -> Word32 -> Ptr Word32 -> Word32 -> IO Int32
-- hKey : BCRYPT_KEY_HANDLE -> Ptr ()
-- pParameterList : BCryptBufferDesc* optional -> Ptr ()
-- pbDerivedKey : BYTE* out -> Ptr Word8
-- cbDerivedKey : DWORD -> Word32
-- pcbResult : DWORD* out -> Ptr Word32
-- dwFlags : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let bcryptkeyderivation =
  foreign "BCryptKeyDerivation"
    ((ptr void) @-> (ptr void) @-> (ptr uint8_t) @-> uint32_t @-> (ptr uint32_t) @-> uint32_t @-> returning int32_t)
(* hKey : BCRYPT_KEY_HANDLE -> (ptr void) *)
(* pParameterList : BCryptBufferDesc* optional -> (ptr void) *)
(* pbDerivedKey : BYTE* out -> (ptr uint8_t) *)
(* cbDerivedKey : DWORD -> uint32_t *)
(* pcbResult : DWORD* out -> (ptr uint32_t) *)
(* dwFlags : DWORD -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library bcrypt (t "bcrypt.dll"))
(cffi:use-foreign-library bcrypt)

(cffi:defcfun ("BCryptKeyDerivation" bcrypt-key-derivation :convention :stdcall) :int32
  (h-key :pointer)   ; BCRYPT_KEY_HANDLE
  (p-parameter-list :pointer)   ; BCryptBufferDesc* optional
  (pb-derived-key :pointer)   ; BYTE* out
  (cb-derived-key :uint32)   ; DWORD
  (pcb-result :pointer)   ; DWORD* out
  (dw-flags :uint32))   ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $BCryptKeyDerivation = Win32::API::More->new('bcrypt',
    'int BCryptKeyDerivation(HANDLE hKey, LPVOID pParameterList, LPVOID pbDerivedKey, DWORD cbDerivedKey, LPVOID pcbResult, DWORD dwFlags)');
# my $ret = $BCryptKeyDerivation->Call($hKey, $pParameterList, $pbDerivedKey, $cbDerivedKey, $pcbResult, $dwFlags);
# hKey : BCRYPT_KEY_HANDLE -> HANDLE
# pParameterList : BCryptBufferDesc* optional -> LPVOID
# pbDerivedKey : BYTE* out -> LPVOID
# cbDerivedKey : DWORD -> DWORD
# pcbResult : DWORD* out -> LPVOID
# dwFlags : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

使用する型