Secure Device Connection Protocol
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.[1]
The term "fingerprint sensor", "sensor", and "device" are used interchangeably, and broadly encompass all hardware involved in the gathering of (and potentially matching of) fingerprint input. For example, a capacitive sensor connected to a microcontroller over SPI is considered to be a single "sensor" for our purposes. A "basic" sensor is match-on-host, and an "advanced" sensor is match-off-host (i.e. match-on-chip, or in some other secure execution environment).
The goal of secure biometrics is to prevent a compromised OS (System and kernel-level malware) from authorizing use of user keys when the user is not present. In other words, if authentication is performed with secure biometrics, the server can be certain that the user was present at the time of authentication.
To facilitate this goal, we need to be able to answer these three questions about each sensor:
- How do we know we are talking to a trusted device? A trusted device has been certified by Microsoft as one that meets our security bar.
- How do we know this device is healthy? A healthy device is not running compromised firmware.
- How is the raw input protected?
- The input MUST be authenticated.
- The input MUST NOT be replayable.
- The input MUST be "fresh" (i.e. nothing in the pipeline has held on to it and used it later).
In general, there are two approaches the problem of secure device input:
- Secure the path
Data travels over the communication channel in the clear, and we make the channel inaccessible to the attacker. In other words, the channel itself is inside the trusted computing base (TCB). - End-to-End secure channel
In this scheme, both parties use a shared secret to secure the data, and the path itself is not in the TCB.
One goal of this effort is to support multiple classes of sensors, including devices that are pluggable or use other transports (such as Bluetooth). Moving an external USB port (for example) into the TCB, as would be required by a secure-the-path approach, is a non-starter. So we opt for a secure channel instead, which will allow for host-device communication over any channel, even one with a MITM.
To meet the goals above, the device must have a small, non-updatable bootloader, capable of hashing the firmware it is about to load. This bootloader is our root of trust. We will have no cryptographic guarantees about the health of the bootloader at runtime, and instead will rely on a certification process[2] to validate that the solution meets our security bar. To that end, each secure sensor is REQUIRED to have a Microsoft-issued certificate with an ECDSA-capable public key, which is obtained (along with the corresponding private key) via certification. This certificate serves as proof that the host is talking to a sensor that it trusts.
This per-model certificate and private key are one of the three key pairs involved in the secure boot and attestation of the device:
-
(cert_m, sk_m)
: The per-model ECDSA certificate and private key, described above. -
(pk_d, sk_d)
: A per-device ECDSA key pair. -
(pk_f, sk_f)
: An ephemeral ECDH key pair, used to perform key agreement with the host and establish a secure channel.
The keys are chained in the following way:
- The per-model private key signs the device public key, creating the
signature
s_m
:s_m <- Sig(sk_m, H(pk_d))
- The device private key signs the current hash of the firmware and
firmware public key, creating the signature
s_d
:h_f <- H(firmware)
s_d <- Sig(sk_d, H(h_f||pk_f))
Together, these keys and signatures form an attestation claim, c
:
c <- (cert_m, pk_d, pk_f, h_f, s_m, s_d)
The host can verify this claim and know that it is connected to a trusted, healthy device.
Our certification requirements revolve around the lifetime and management of the key pairs and signatures described above. To ensure that compromised firmware cannot generate a false attestation statement:
- The key pair
(pk_d, sk_d)
MUST be unique to each device. - The unique, per-device public key,
pk_d
, MUST be signed by the per-model private key,sk_m
, generating the signatures_m
, which persists on the device. - The per-model private key,
sk_m
, MUST NOT be present on the device. - The device MUST have a secure bootloader, capable of providing a
signed hash of the firmware it loads.
- Compromised firmware MUST NOT be able to manipulate this bootloader into providing an incorrect hash.
- Only the bootloader can sign with the per-device private key,
sk_d
:- Firmware MUST NOT have access to the key material of
sk_d
. - Firmware MUST NOT have oracle access to
sk_d
(i.e. the ability to request that arbitrary data be signed). - There MUST NOT be any debug back doors or JTAG mechanism to
access
sk_d
.
- Firmware MUST NOT have access to the key material of
- The bootloader MUST generate an ephemeral ECDH key pair
(pk_f, sk_f)
on every boot, which firmware MUST be able to use for key agreement.
This is one example implementation of the scheme above. Sensors MAY implement other solutions, as long as they meet the certification requirements set forth.
- Break sensor firmware into 2 parts: ROM firmware and flash firmware. ROM firmware must not be updatable. It can still be stored in flash, but flash needs to make sure it is not updatable.
- The assumption is that ROM firmware is small enough to get it correct, and flash firmware will be too big and have bugs that we need to update.
- On the factory floor, generate a device key
(pk_d, sk_d)
for each device. For each device key, signpk_d
with the model private keysk_m
, creating signatures_m
. - Each device is provisioned with:
-
cert_m
: The model certificate (accessible to firmware) -
(pk_d, sk_d)
: The per-device key pair (sk_d
is only accessible to the secure bootloader) -
s_m
: The model signature overpk_d
(accessible to firmware)
-
- On boot, before jumping to the flash firmware, the bootloader
generates an ECDH key pair, hashes the firmware it is about to load,
and signs the public key and hash with
sk_d
. - Before jumping into flash firmware, the area of flash holding
sk_d
is blocked from further reads and writes for this boot session. - The firmware jumps to flash, passing up the hash, key pair, and signature.
- Firmware is now prepared to perform attestation and set up a secure channel with the host.
It is possible for a compromise to happen at any level of our key hierarchy:
- Model keys
- Device keys
- Firmware keys
The only place the model secret key is vulnerable is the factory itself.
That key does not leave the factory. If it is compromised, the model
certificate, cert_m
will be revoked.
There are two ways that device secret keys can be compromised:
- There is a flaw in the bootloader that exposes
sk_d
. In this case, we will revoke the model certificate,cert_m
. - Hardware attacks, e.g. attacker decapsulates a chip and extracts
sk_d
for that device. In this situation, the attacker has complete control of that device, and it can never get back into a secure state. However, the attacker still cannot pretend to be any other device, and we have the ability to revoke at this level if we detect a device-key compromise at scale (e.g. thousands of devices start showing up with the same device key pair).
Compromised firmware has access to the (pk_f, sk_f)
key pair, and can
replay an attestation claim for the compromised version. Note that
compromised firmware can not pretend to be any other version of the
firmware, because that would require a signature from sk_d
, which is
not accessible to even compromised firmware.
We have no runtime mitigations for this attack, instead we rely on out-of-band detection (e.g. through pen-testing and telemetry) of compromised firmware versions. Once the compromised firmware version has been blacklisted, none of the stolen or replayed attestation claims will be valid, and once a firmware update has been applied the sensor will be back in a good state.
To bootstrap a secure channel, the host and device exchange public keys, perform key agreement, and derive application keys for authentication and encryption. Once the channel has been established, the device sends an authenticated attestation statement to the host so that the device knows it is communicating with a trusted, healthy device.
Prior to this flow, the device has been provisioned with the per-model
cert, cert_m
, and the model signature over the device public key,
s_m
.
- Device Bootloader:
- Has access to
sk_d
, the device private key - Generates the hash of the firmware it is going to load:
h_f <- H(firmware)
- Generates an ephemeral ECDH key pair:
(pk_f, sk_f) <- KGen()
- Signs a two-byte prefix
{0xC0, 0x01}
,h_f
, andpk_f
with the device private key:s_d <- Sig(sk_d, H(C001||h_f||pk_f))
- Locks access to
sk_d
. - Transitions to untrusted code, passing up
s_d
, the firmware hashh_f
, and the(pk_f, sk_f)
key pair.
- Has access to
- Device firmware now has access to:
-
cert_m
: The per-model certificate -
h_f
: The firmware hash -
pk_d
: The device public key -
pk_f
: The ephemeral public key -
sk_f
: The ephemeral private key -
s_m
: The signature overpk_d
using the per-model private keysk_m
, which MUST NOT be present on the device. -
s_d
: The signature overh_f
andpk_f
, using the private keysk_d
, which MUST NOT be accessible to firmware.
-
- Host:
- Generates an ephemeral ECDH key pair
(pk_h, sk_h)
- Generates random bytes:
r_h <- GenRand()
- Sends the
Connect
message, containing:r_h
pk_h
- Generates an ephemeral ECDH key pair
- Device:
- Generates random bytes:
r_d <- GenRand()
- Performs key agreement:
a <- KeyAgreement(sk_f, pk_h)
- Derives master secret:
ms <- KDF(a, "master secret", r_h||r_d)
- Derives MAC secret,
s
, and symmetric key,k
:(s, k) <- KDF(ms, "application keys")
- Generates the claim:
c <- (cert_m, pk_d, pk_f, h_f, s_m, s_d)
- Generates a MAC of the claim hash:
m <- MAC(s, "connect"||H(c))
- Sends the
ConnectResponse
message containing:- Device random:
r_d
- Claim:
c
- Claim MAC:
m
- Device random:
- Generates random bytes:
- Host:
- Performs key agreement:
a <- KeyAgreement(sk_h, pk_f)
- Derives master secret:
ms <- KDF(a, "master secret", r_h||r_d)
- Derives MAC secret,
s
, and symmetric key,k
:(s, k) <- KDF(ms, "application keys")
- Validates the MAC
m
overH(c)
- Unpacks the claim:
(cert_m, pk_d, pk_f, h_f, s_m, s_d) <- c
- Verifies the claim :
pk_m <- Validate(cert_m)
Verify(pk_m, H(pk_d), s_m)
Verify(pk_d, H(C001||h_f||pk_f), s_d)
Validate(h_f)
- Performs key agreement:
After the full connection, for performance reasons, the device MAY
choose to persist the master key in-memory and participate in the
abbreviated reconnection flow below. This is a performance optimization
only, not a guarantee that connections will always be re-used. The
device must be ready to perform the full connection above at any time.
The device MUST NOT persist ms
across power-off. ms
MUST NOT survive
a firmware update.
- Host and device have access to the previously negotiated master
secret
ms
. - Host:
r_h <- GenRand()
- Sends the
Reconnect
message, containingr_h
.
- Device:
- Derives application keys:
(s, k) <- KDF(ms, "application keys")
- Generates a MAC over the
r_h
:m <- MAC(s, "reconnect"||r_h)
- Sends the
ReconnectResponse
message, containingm
.
- Derives application keys:
- Host:
- Verifies the MAC
m
overr_h
, and perform the full connection if needed.
- Verifies the MAC
Quoted strings (e.g. "this string"), are null-terminated ASCII strings. For example, the string "connect" is represented as
63 6f 6e 6e 65 63 74 00
The operator ||
used in the protocols above represents concatenation.
For example:
{0x01, 0x02, 0x03} || 0x040506 -> 0x010203040506
"foo" || "bar" -> 0x666f6f0062617200
Version one of this protocol uses a fixed cipher suite:
- Signatures use ECDSA on NIST P256 curve, using SHA256 digest
- In the absence of a secure RNG, the device MUST use deterministic ECDSA, as described in RFC 6979[3]
- Key agreement uses ECDH on NIST P256 curve
- MAC function is HMAC SHA256
- KDF is the NIST SP 800-108[4] KDF in counter mode using HMAC SHA256. (Details below.)
- Symmetric encryption algorithm is AES256 CBC with PKCS#7 block
padding, using a random IV
- All encrypted data must be MAC'd using HMAC SHA256.
The KDF in this protocol is the NIST SP 800-108 KDF in counter mode, using SHA256. The input is:
-
K_i
256-bit HMAC secret. -
Label
Null-terminated ASCII string, encoded as bytes, including the null-terminator. -
Context
Optional binary string containing information related to the derived keying material. -
L
An unsigned integer specifying the length (in bits) of the output keying material. Encoded as a big-endian, 32-bit unsigned integer. This encoding limits the maximum output bit-count toMAX_UINT32
. -
i
The counter, encoded as a big-endian, 32-bit unsigned integer.
Process:
1. If (L > MAX_UINT32), then indicate an error and stop
2. n <- ceil(L/256) // 256 is the digest length for SHA256
3. result(0) <- {}
4. For i from 1 to n:
a. K(i) <- HMAC_SH256(K_i, i || Label || Context || L)
b. result(i) <- result(i-1) || K(i)
5. Return the leftmost L bits of result(n)
Test vectors can be found in Apendix A.
-
cert_m
is an x509 ASN.1 DER encoded certificate. - ECC public keys
(x, y)
shall be constructed as described in SEC1, section 2.3.3[5], with no point compression. For the v1 protocol using the P256 curve, this will result in a byte string 65 (`32*2- 1`) bytes long.
- ECC signatures
(r, s)
shall be constructed asr||s
, where the integersr
ands
are converted to octet strings as described in SEC1, section 2.3.7[6]. For the v1 protocol using the P256 curve, this will result in a byte string 64 (32*2
) bytes long.
After the connection flow above, the sensor and the biometric trustlet
now share the MAC secret, s
, and the symmetric encryption key, k
. To
motivate their use, consider a black box that does biometric sample
collection, template construction, matching, and storage. The Windows
Biometric Framework (WBF) calls into black boxes like this (we call them
Biometric Units (BUs)[7]) to perform two main functions:
Enroll(identity) -> ()
Identify() -> identity
The purpose of this high-level abstraction is to make sample-collection
and hardware details opaque to the biometric framework. The APIs above
are exposed to WBF through our pluggable adapter model. Internally,
Enroll
will collect biometric samples, construct a biometric template,
and store the (template, identity)
mapping in a database. Identify
collects a biometric
sample, matches it against the stored templates, and returns the user
identity.
In this model, there are two layers to secure:
- The internal implementation of
Enroll
andIdentify
:- Stored biometric templates MUST be private and MUST be protected against manipulation and injection.
- Biometric samples used by
Enroll
andIdentify
MUST NOT be injected or replayed.
- The communication between the biometric framework and the biometric
unit:
- The input to
Enroll
MUST NOT be manipulated by an attacker. - The result of
Identify
MUST NOT be manipulated by an attacker.
- The input to
The goal of the biometric trustlet in VSM is to provide security for these two layers.
An advanced, match-off-host sensor already secures the first layer, as
the samples and templates are never seen by the OS. The implementations
for Enroll
and Identify
essentially do no processing of data, it is
control-flow only. Currently, only advanced sensors are supported by the protocol.
With secured samples traveling from sensor to matcher, we now focus on securing the WBF <-> BU interface.
At enrollment time, the sensor generates a nonce and sends it to the bio trustlet. To commit the enrollment, the bio trustlet MACs the nonce, and sends the MAC to the sensor. That MAC is stored in the template database, and in the biometric trustlet's authorized enrollment database. Only authorized enrollments may release user credentials.
This MAC is the persistent identifier for the enrolling user; after enrollment, the MAC is no longer semantically a MAC, it's just a persistent ID. Using a MAC as the identifier prevents against enrollments from one host being used on another[8] – enrolling on a different host will result in an entry that is not in the original host's authorized enrollment database, because it is not possible to manipulate the connection such that the same master secret is negotiated on both hosts.
- Bio Service (normal-world):
- Sends
EnrollBegin
.
- Sends
- Sensor:
- Generates a nonce,
n
. - Sends the
EnrollmentNonce
message, containingn
.
- Generates a nonce,
- Bio Service (normal-world):
- Begins sample collection for the construction of a biometric template, until the sensor indicates that enough samples have been collected.
- After the template has been constructed, the bio service sends
the enrollment nonce,
n
, to the bio trustlet.
- Bio Trustlet (VSM):
- Computes the MAC over
n
:id <- MAC(s, "enroll"||n)
- Authorizes the user, resulting in a user SID,
sid
. - Stores the following mapping in its authorized enrollment
database:
id -> (sid, pk_d, h_f)
- Sends
id
to the bio service in normal-world
- Computes the MAC over
- Bio Service (normal-world)
- Sends the
EnrollCommit
message, containingid
.
- Sends the
- Sensor:
- Validates the MAC,
id
, overn
. - Stores the
(template, id)
tuple in the template database.
- Validates the MAC,
After enrollment, id
is not treated like a MAC, it becomes the
identifier for the authorized user.
After enrollment, the identifier id
is in two places:
- The template database.
- The authorized enrollment database.
The match result for a secure biometric match will be id
from the
template database, MAC'd with a nonce to prevent replay.
- Bio Trustlet (VSM):
- Generates a nonce,
n
, and passes it out to the bio service.
- Generates a nonce,
- Bio Service (normal-world):
- Sends the
Identify
command to the device, containingn
.
- Sends the
- Sensor:
- Matches the sample, and looks up the corresponding
id
. - MACs the nonce and identifier:
m <- MAC(s, "identify"||n||id)
- Sends the
AuthorizedIdentity
response, containingid
andm
.
- Matches the sample, and looks up the corresponding
- Bio Service (normal-world)
- Forwards the
AuthorizedIdentity
response to the trustlet.
- Forwards the
- Bio Trustlet (VSM):
- Validates the MAC,
m
. - Looks up
id
in the authorized enrollment database, yielding:(s, pk_d, h_f) <- LookupEnrollment(id)
- Validates the MAC,
For a secure fingerprint sensor, only enrollments in VSM's authorized enrollment database will be able to authorize key release. This means that existing third-party fingerprint enrollment applications will not be able to enroll a secure fingerprint, because they will not be able to perform the authorized credential collection (step 4.2 in the enrollment flow above) required to create an entry in that database.
From the identification flow above, the bio trustlet now knows:
-
s
: The SID of the user who was identified. -
pk_d
: The device public key. -
h_f
: the hash of the firmware on which the enrollment was created.
Credential release for user s
will be authorized if-and-only-if:
-
pk_d
from the identification result matches thepk_d
of the currently paired device. -
h_f
has not been revoked.
- New WBDI IOCTL will be added for the new connection messages.
- Sensor adapter methods will be added for calling the new IOCTL.
- Engine adapter methods will be added for for enrolling and identifying securely.
A new sensor capability bit will be added so that the sensor can report that it supports the new secure connection protocol, and existing (but previously unreferenced) encryption capability will be used to specify that templates should have privacy and integrity guarantees.
//
// Capabilities for template encryption (basic sensors) and
// the secure connection protocol
//
#define WINBIO_CAPABILITY_ENCRYPTION ((WINBIO_CAPABILITIES)0x00000010)
#define WINBIO_CAPABILITY_SCP_V1 ((WINBIO_CAPABILITIES)0x00000200)
//
// Constants for the SCP V1 protocol
//
typedef USHORT WINBIO_SCP_VERSION;
#define WINBIO_SCP_VERSION_1 1
// Sizes for the fixed V1 cipher suite
#define WINBIO_SCP_RANDOM_SIZE_V1 32
#define WINBIO_SCP_DIGEST_SIZE_V1 32 // SHA256
#define WINBIO_SCP_CURVE_FIELD_SIZE_V1 32 // NIST P256
#define WINBIO_SCP_PUBLIC_KEY_SIZE_V1 65 // 0x04||x||y
#define WINBIO_SCP_PRIVATE_KEY_SIZE_V1 32 // log_2(n)/8
#define WINBIO_SCP_SIGNATURE_SIZE_V1 64 // r||s
#define WINBIO_SCP_ENCRYPTION_BLOCK_SIZE_V1 16 // AES
#define WINBIO_SCP_ENCRYPTION_KEY_SIZE_V1 32 // AES256
typedef USHORT WINBIO_SCP_FLAGS;
#define WINBIO_SCP_FLAG_RECONNECT ((WINBIO_SCP_FLAGS)0x0001)
//
// Optional IOCTLs for support of the Secure Connection Protocol (SCP) V1
// Capability: WINBIO_CAPABILITY_SCP_V1
//
#define IOCTL_BIOMETRIC_CONNECT_SECURE BIO_CTL_CODE(0x00B)
This IOCTL will be sent to connect or reconnect using the secure connection protocol defined in this document.
-
Input
typedef struct _WINBIO_SECURE_CONNECTION_PARAMS { DWORD PayloadSize; WINBIO_SCP_VERSION Version; // WINBIO_SCP_VERSION_1 WINBIO_SCP_FLAGS Flags; // Required fields: // HostRandom[WINBIO_SCP_RANDOM_SIZE_V1]; // Fields omitted for reconnection: // PublicKey[WINBIO_SCP_PUBLIC_KEY_SIZE_V1] } WINBIO_SECURE_CONNECTION_PARAMS, *PWINBIO_SECURE_CONNECTION_PARAMS;
- PayloadSize
The total size of the payload. - Version
Must be 1. - Flags
If this is a reconnection attempt,WINBIO_CONNECTION_FLAG_RECONNECT
must be set. - HostRandom
Host's random bytes. - PublicKey
Host's public key,pk_h
. IfWINBIO_CONNECTION_FLAG_RECONNECT
is set,PublicKey
is omitted.
- PayloadSize
-
Output
typedef struct _WINBIO_SECURE_CONNECTION_DATA { DWORD Size; WINBIO_SCP_VERSION Version; // WINBIO_SCP_VERSION_1 WINBIO_SCP_FLAGS Flags; DWORD ModelCertificateSize; DWORD IntermediateCA1Size; DWORD IntermediateCA2Size; // Required fields: // Mac[WINBIO_SCP_DIGEST_SIZE_V1]; // Fields omitted for reconnection: // DeviceRandom[WINBIO_SCP_RANDOM_SIZE_V1] // ModelCertificate[ModelCertificateSize] // DevicePublicKey[WINBIO_SCP_PUBLIC_KEY_SIZE_V1] // FirmwarePublicKey[WINBIO_SPC_PUBLIC_KEY_SIZE_V1] // FirmwareHash[WINBIO_SCP_DIGEST_SIZE_V1] // ModelSignature[WINBIO_SCP_SIGNATURE_SIZE_V1] // DeviceSignature[WINBIO_SCP_SIGNATURE_SIZE_V1] // Fields that the driver should append during a full connection // IntermediateCA1[IntermediateCA1Size] // IntermediateCA2[IntermediateCA2Size] } WINBIO_SECURE_CONNECTION_DATA, *PWINBIO_SECURE_CONNECTION_DATA;
- Size
The total size of the connection data structure and following variable-length data. - Version
Version 1. - Flags
If this is a reconnection response,WINBIO_CONNECTION_FLAG_RECONNECT
must be set. - Mac
If the is a reconnection, a MAC overHostRandom
. If this is a full connection, a MAC over the hash of claim, which immediately follows theMac
. - DeviceRandom
The device random bytes. - ModelCertificate
The x509 ASN.1 DER encoded certificate,cert_m
. - DevicePublicKey
The public keypk_d
. - FirmwarePublicKey
The firmware public keypk_f
. - FirmwareHash
The firmware hashh_f
. - ModelSignature
To model signatures_m
. - DeviceSignature
The device signature ~sd. - IntermediateCA1
Certificate for an intermediate CA betweencert_m
and the root. - IntermediateCA2
Certificate for an intermediate CA betweencert_m
and the root.
typedef struct _WINBIO_SECURE_CONNECTION_RESPONSE { DWORD PayloadSize; HRESULT WinBioHresult; WINBIO_SECURE_CONNECTION_DATA SecureConnection; // Variable-length connection data follows } WINBIO_SECURE_CONNECTION_RESPONSE, *PWINBIO_SECURE_CONNECTION_RESPONSE
- PayloadSize
The total size of the payload. - WinBioHresult
The status detail of the I/O operation. - SecureConnectionData
The output buffer containing the device connection data.
- Size
HRESULT WINAPI SensorAdapterConnectSecure(
_Inout_ WINBIO_PIPELINE* Pipeline,
_In_ const WINBIO_SECURE_CONNECTION_PARAMS* ConnectionParams,
_Outptr_result_bytebuffer_(*ConnectionDataSize)
WINBIO_SECURE_CONNECTION_DATA** ConnectionData);
- Pipeline
Pointer to theWINBIO_PIPELINE
structure associated with the biometric unit performing the operation. - ConnectionParams
Input connection parameters. - ConnectionData
Connection response data.
To support the secure identifier that will be used by the new engine
adapter methods, a new type will be added to the WINBIO_IDENTITY
union:
#define WINBIO_ID_TYPE_SECURE_ID ((WINBIO_IDENTITY_TYPE)4)
typedef struct _WINBIO_IDENTITY {
WINBIO_IDENTITY_TYPE Type;
union {
ULONG Null;
ULONG Wildcard;
GUID TemplateGuid;
struct {
ULONG Size;
UCHAR Data[SECURITY_MAX_SID_SIZE];
} AccountSid;
#if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
UCHAR SecureId[WINBIO_SCP_DIGEST_SIZE_V1];
#endif // (NTDDI_VERSION >= NTDDI_WIN10_RS4)
} Value;
} WINBIO_IDENTITY;
HRESULT WINAPI EngineAdapterCreateEnrollmentAuthenticated(
_Inout_ WINBIO_PIPELINE* Pipeline,
_Outptr_result_bytebuffer_(*NonceSize) PUCHAR* Nonce,
_Out_ SIZE_T* NonceSize);
- Pipeline
Pointer to theWINBIO_PIPELINE
structure associated with the biometric unit performing the operation. - Nonce
A buffer containing the nonce to be included in the MAC sent by the host inEngineAdapterCommitEnrollment
. - NonceSize
The size of the nonce, in bytes.
The host's corresponding EngineAdapterCommitEnrollment
call will
contain a WINBIO_IDENTITY
structure of type
WINBIO_ID_TYPE_SECURE_ID
, with the SecureId
member set to the
following MAC:
SecureId <- MAC(s, "enroll"||Nonce)
HRESULT WINAPI EngineAdapterIdentifyFeatureSetAuthenticated(
_Inout_ WINBIO_PIPELINE* Pipeline,
_In_reads_bytes_(NonceSize) const UCHAR* Nonce,
_In_ SIZE_T NonceSize,
_Out_ WINBIO_IDENTITY* Identity,
_Out_ WINBIO_BIOMETRIC_SUBTYPE* SubFactor,
_Out_ WINBIO_REJECT_DETAIL* RejectDetail,
_Outptr_result_bytebuffer_(*AuthenticationSize)
PUCHAR* Authentication,
_Out_ SIZE_T* AuthenticationSize);
- Pipeline
Pointer to theWINBIO_PIPELINE
structure associated with the biometric unit performing the operation. - Nonce
A buffer containing the nonce to be included in the MAC. - NonceSize
The size of the nonce, in bytes. - Identity
Pointer to aWINBIO_IDENTITY
structure that contains the secure identity (WINBIO_ID_TYPE_SECURE_ID
) of the template recovered from the database. This value is returned only if a match is found. - SubFactor
Pointer to aWINBIO_BIOMETRIC_SUBTYPE
value that receives the sub-factor associated with the template in the database. This value is returned only if a match is found. - RejectDetail
Pointer to a variable that receives additional information if a capture failure prevents the engine from performing a matching operation. If the most recent capture succeeded, set this parameter to zero. - Authentication
MAC(s, "identify"||Nonce||Identity->Value.SecureId)
. This value is returned only if a match is found. - AuthenticationSize
The size of theAuthentication
, in bytes. This value is returned only if a match is found.
To use the new framework, the device driver must be updated to include a new configuration. Multiple configurations can be defined in the .inf to support normal winbio operations. In the example below, configuration 0 is a normal configuration and configuration 1 supports SDCP.
- SensorMode
Specifies whether the sensor is a basic or advanced sensor. Setting to 1 denotes a basic sensor and 2 denotes an advanced sensor. SensorMode MUST be set to 2 for the SDCP configuration. - SystemSensor
Defines whether the sensor is part of the system pool. SystemSensor MUST be set to 1 for the SDCP configuration
[Fingerprint_Configuration]
HKR,,"Exclusive",0x10001,1
HKR,WinBio\Configurations,DefaultConfiguration,0x00010001,0x00000000
HKR,WinBio\Configurations\0,DatabaseId,,"<MY_GUID_FOR_NORMAL_CONFIG>"
HKR,WinBio\Configurations\0,EngineAdapterBinary,,"MyEngineAdapter.dll"
HKR,WinBio\Configurations\0,SensorAdapterBinary,,"MySensorAdapter.dll"
HKR,WinBio\Configurations\0,SensorMode,0x00010001,0x00000001
HKR,WinBio\Configurations\0,StorageAdapterBinary,,"MyStorageAdapter.dll"
HKR,WinBio\Configurations\0,SystemSensor,0x00010001,0x00000001
HKR,WinBio\Configurations,VirtualSecureConfiguration,0x00010001,0x00000001
HKR,WinBio\Configurations\1,DatabaseId,,"<MY_GUID_FOR_SECURE_DEVICE_CONFIG>"
HKR,WinBio\Configurations\1,EngineAdapterBinary,,"MySecureEngineAdapter.dll"
HKR,WinBio\Configurations\1,SensorAdapterBinary,,"MySecureSensorAdapter.dll"
HKR,WinBio\Configurations\1,StorageAdapterBinary,,"MySecureStorageAdapter.dll"
HKR,WinBio\Configurations\1,VsmEngineAdapterBinary,,"WinBioVsmNullAdapter"
HKR,WinBio\Configurations\1,VsmSensorAdapterBinary,,"WinBioVsmNullAdapter"
HKR,WinBio\Configurations\1,VsmStorageAdapterBinary,,"WinBioVsmNullAdapter"
HKR,WinBio\Configurations\1,SensorMode,0x00010001,0x00000002
HKR,WinBio\Configurations\1,SystemSensor,0x00010001,0x00000001
HKR,WinBio\Configurations\1,VirtualSecureMode,0x00010001,0x00000001
The SDCP configuration MUST have 'WinBioVsmNullAdapter' set for vsmEngineAdapterBinary, vsmSensorAdapterBinary, and vsmStorageAdapterBinary. 'MySecureEngineAdapter.dll', 'MySecureSensorAdapter.dll', and 'MySecureStorageAdapter.dll', 'MyEngineAdapter.dll', 'MySensorAdapter.dll', and 'MyStorageAdapter.dll' are vendor defined components and should be replaced in the example with the vendor provided .dll names. For a non-SDCP configuration, a vendor can specify the inbox sensor and storage adapter for 'MySensorAdapter.dll' and 'MyStorageAdapter.dll'. Each configuration MUST have a unique database GUID and VirtualSecureMode MUST match the index for the SDCP configuration
If multiple configurations are defined, each configuration should have a separate database. The unique GUIDs defined in fingerprint configurations should match the ones defined in the database configuration.
[WBioSrvc_Database]
HKR,Databases\{<MY_GUID_FOR_NORMAL_CONFIG>},BiometricType,0x00010001,0x00000008
HKR,Databases\{<MY_GUID_FOR_NORMAL_CONFIG>},Attributes,0x00010001,0x00000001
HKR,Databases\{<MY_GUID_FOR_NORMAL_CONFIG>},Format,,"A2697CB9-B200-4BF5-9F40-3A8F699B4BD6"
HKR,Databases\{<MY_GUID_FOR_NORMAL_CONFIG>},InitialSize,0x00010001,0x00000020
HKR,Databases\{<MY_GUID_FOR_NORMAL_CONFIG>},AutoCreate,0x00010001,0x00000001
HKR,Databases\{<MY_GUID_FOR_NORMAL_CONFIG>},AutoName,0x00010001,0x00000001
HKR,Databases\{<MY_GUID_FOR_NORMAL_CONFIG>},FilePath,,""
HKR,Databases\{<MY_GUID_FOR_NORMAL_CONFIG>},ConnectionString,,""
HKR,Databases\{<MY_GUID_FOR_SECURE_DEVICE_CONFIG>},BiometricType,0x00010001,0x00000008
HKR,Databases\{<MY_GUID_FOR_SECURE_DEVICE_CONFIG>},Attributes,0x00010001,0x00000001
HKR,Databases\{<MY_GUID_FOR_SECURE_DEVICE_CONFIG>},Format,,"3B2F61F2-D8DF-40AF-B5A0-DDC0A6BCF589"
HKR,Databases\{<MY_GUID_FOR_SECURE_DEVICE_CONFIG>},InitialSize,0x00010001,0x00000020
HKR,Databases\{<MY_GUID_FOR_SECURE_DEVICE_CONFIG>},AutoCreate,0x00010001,0x00000001
HKR,Databases\{<MY_GUID_FOR_SECURE_DEVICE_CONFIG>},AutoName,0x00010001,0x00000001
HKR,Databases\{<MY_GUID_FOR_SECURE_DEVICE_CONFIG>},FilePath,,""
HKR,Databases\{<MY_GUID_FOR_SECURE_DEVICE_CONFIG>},ConnectionString,,""
Input:
K_i = 0000000000000000000000000000000000000000000000000000000000000000
Label = "Example 1"
Context = null
L = 1024
Output:
ced7fc06140681bddcccdab36e154f42b364ba94a9e2ebc5693a0fd0f8184359
63c975a829bf3501798cafcb766f031d54294c08d12196885b96725fc190b532
c6b2d2977242262319daed6def6e2621f6e32a27066e2ee34cda40bebad2f1fa
d5730d9f9a95fecef06bef70eccf0b39c8a07598f84ad2f6bfc1d9e0e6de94d8
Input:
K_i = 0000000000000000000000000000000000000000000000000000000000000000
Label = ""
Context = aabbccddeeff
L = 256
Output:
b32a81f79729951e5694c0f7e21eeb1337c08627453d17248422dec8e1c8fbff
Input:
K_i = 41c1239619bbf4dd5385e6fdaee6a4301e3d14437e262d97668a44111fb3973d
Label = "test vector"
Context = 7b4b562b553b8f205af6f6680027c1035d427b650bca1eba971266c65f54ed24
49734a5d9867e339a509982fead5d28b952ac98a35be025919f248605b04adf6
L = 760
Output:
5a644067ecf9e62552a448e66ddea42ab961893b45995e815d951e91fe7283e2
6857ca82a4f6d10f6dc16760f8ab830a69bcc89e5c2c22ac0de3acd73e417672
08969362e9e5986c8a0a696fd7afd689498f575b9559fe7206fb1fcf76d5f8
Note: TestSigning MUST be enabled to use these certificate test vectors.
0x30, 0x82, 0x03, 0x4A, 0x30, 0x82, 0x02, 0xF1, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, 0x00, 0x04, 0x65, 0x4F, 0x77, 0xFA, 0xD9, 0x1C, 0x24, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x31, 0x39, 0x42, 0x39, 0x32, 0x39, 0x36, 0x35, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x35, 0x32, 0x34, 0x32, 0x30, 0x33, 0x34, 0x34, 0x32, 0x5A, 0x17, 0x0D, 0x31, 0x39, 0x30, 0x38, 0x32, 0x34, 0x32, 0x30, 0x33, 0x34, 0x34, 0x32, 0x5A, 0x30, 0x1C, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42, 0x49, 0x4F, 0x20, 0x53, 0x65, 0x6E, 0x73, 0x6F, 0x72, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x86, 0x83, 0xC1, 0xBD, 0x6B, 0x3B, 0x7C, 0xDC, 0x64, 0x86, 0x29, 0x29, 0x1B, 0xC9, 0xCA, 0x98, 0x20, 0x6B, 0x39, 0xD5, 0x94, 0xE1, 0xC8, 0x79, 0x6B, 0xA4, 0xE7, 0x7E, 0x86, 0x24, 0x51, 0xE7, 0x9C, 0xAC, 0xF8, 0xBD, 0x82, 0x3F, 0x9D, 0x07, 0x1E, 0x8A, 0x43, 0x68, 0x2D, 0xDF, 0x40, 0xBF, 0x0C, 0x0C, 0x6C, 0xC0, 0x5B, 0x26, 0x05, 0x9F, 0xC5, 0x68, 0x3A, 0x0A, 0xE6, 0xDC, 0x0E, 0x82, 0xA3, 0x82, 0x01, 0xAF, 0x30, 0x82, 0x01, 0xAB, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1D, 0x11, 0x04, 0x6E, 0x30, 0x6C, 0xA4, 0x6A, 0x30, 0x68, 0x31, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x04, 0x82, 0x37, 0x64, 0x02, 0x13, 0x24, 0x34, 0x36, 0x44, 0x33, 0x42, 0x30, 0x30, 0x33, 0x2D, 0x30, 0x32, 0x31, 0x46, 0x2D, 0x34, 0x44, 0x31, 0x42, 0x2D, 0x42, 0x31, 0x44, 0x35, 0x2D, 0x36, 0x43, 0x33, 0x33, 0x32, 0x43, 0x46, 0x41, 0x46, 0x36, 0x42, 0x43, 0x31, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x04, 0x82, 0x37, 0x64, 0x01, 0x13, 0x24, 0x46, 0x41, 0x45, 0x30, 0x35, 0x41, 0x39, 0x44, 0x2D, 0x46, 0x43, 0x42, 0x32, 0x2D, 0x34, 0x46, 0x31, 0x34, 0x2D, 0x39, 0x30, 0x37, 0x44, 0x2D, 0x39, 0x36, 0x36, 0x36, 0x43, 0x43, 0x45, 0x31, 0x46, 0x30, 0x38, 0x38, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xA7, 0xBA, 0x70, 0x4D, 0x99, 0x4B, 0x82, 0x1F, 0xB3, 0xCB, 0xB6, 0x03, 0xD5, 0x30, 0x08, 0xC5, 0xB3, 0x2D, 0x9C, 0xF9, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x13, 0x93, 0xC8, 0xCD, 0xF2, 0x23, 0x9A, 0x2D, 0xC6, 0x9B, 0x2A, 0xEB, 0x9A, 0xAB, 0x99, 0x0B, 0x56, 0x04, 0x5E, 0x7C, 0x30, 0x5F, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x58, 0x30, 0x56, 0x30, 0x54, 0xA0, 0x52, 0xA0, 0x50, 0x86, 0x4E, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32, 0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25, 0x32, 0x30, 0x31, 0x39, 0x42, 0x39, 0x32, 0x39, 0x36, 0x35, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x6C, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x60, 0x30, 0x5E, 0x30, 0x5C, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x50, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32, 0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25, 0x32, 0x30, 0x31, 0x39, 0x42, 0x39, 0x32, 0x39, 0x36, 0x35, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E, 0x63, 0x72, 0x74, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x02, 0x30, 0x00, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1D, 0x25, 0x04, 0x0E, 0x30, 0x0C, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x2B, 0x01, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x29, 0x3D, 0x2C, 0xB3, 0x27, 0x5A, 0xA6, 0xBB, 0xE3, 0x19, 0x57, 0xEC, 0x39, 0x55, 0x5D, 0x0A, 0x4E, 0xE4, 0xCA, 0x0A, 0x4B, 0xDA, 0xFD, 0x1E, 0xE5, 0x54, 0xF7, 0x40, 0x50, 0xCC, 0xA5, 0x44, 0x02, 0x20, 0x73, 0x85, 0xFF, 0x05, 0xC9, 0x05, 0x91, 0x76, 0xE7, 0x5E, 0x48, 0xE6, 0x63, 0x52, 0xCB, 0xE1, 0x27, 0x7C, 0xBF, 0x6D, 0x3D, 0xC0, 0xA0, 0x21, 0x57, 0xF4, 0xB6, 0xA9, 0xAA, 0xBC, 0x3D, 0x25
0x3a, 0x8a, 0xaa, 0xc1, 0x7d, 0xfa, 0x01, 0x36, 0x4e, 0x02, 0x49, 0xfb, 0x8a, 0xd8, 0xa6, 0x79, 0xdd, 0x81, 0x9d, 0xb3, 0x95, 0x64, 0xa7, 0xe4, 0xa5, 0xf8, 0x00, 0x1a, 0x4d, 0xb6, 0x9c, 0x74
0x30, 0x82, 0x03, 0xFD, 0x30, 0x82, 0x03, 0x82, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, 0x00, 0x07, 0xE8, 0x9D, 0x61, 0x62, 0x4D, 0x46, 0x0F, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81, 0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x33, 0x31, 0x31, 0x39, 0x35, 0x34, 0x35, 0x33, 0x5A, 0x17, 0x0D, 0x32, 0x38, 0x30, 0x31, 0x33, 0x31, 0x32, 0x30, 0x30, 0x34, 0x35, 0x33, 0x5A, 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x31, 0x39, 0x42, 0x39, 0x32, 0x39, 0x36, 0x35, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xBE, 0x4B, 0x90, 0x6E, 0x24, 0xFC, 0xA1, 0x53, 0xC8, 0xA7, 0x3C, 0x70, 0xE8, 0x97, 0xCD, 0x1B, 0x31, 0xE4, 0x95, 0x91, 0x7A, 0x58, 0xA2, 0x86, 0xA8, 0x70, 0xF6, 0x09, 0x30, 0x77, 0x99, 0x3D, 0x10, 0xDF, 0xF7, 0x95, 0x0F, 0x68, 0x83, 0xE6, 0xA4, 0x11, 0x7C, 0xDA, 0x82, 0xE7, 0x0B, 0x8B, 0xF2, 0x9D, 0x6B, 0x5B, 0xF5, 0x3E, 0x77, 0xB4, 0xC1, 0x0E, 0x49, 0x00, 0x83, 0xBA, 0x94, 0xF8, 0xA3, 0x82, 0x01, 0xD7, 0x30, 0x82, 0x01, 0xD3, 0x30, 0x10, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x13, 0x93, 0xC8, 0xCD, 0xF2, 0x23, 0x9A, 0x2D, 0xC6, 0x9B, 0x2A, 0xEB, 0x9A, 0xAB, 0x99, 0x0B, 0x56, 0x04, 0x5E, 0x7C, 0x30, 0x65, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04, 0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00, 0x30, 0x52, 0x06, 0x0C, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01, 0x30, 0x42, 0x30, 0x40, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x44, 0x6F, 0x63, 0x73, 0x2F, 0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E, 0x68, 0x74, 0x6D, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0C, 0x1E, 0x0A, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03, 0x27, 0x5F, 0x97, 0xEB, 0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x68, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x61, 0x30, 0x5F, 0x30, 0x5D, 0xA0, 0x5B, 0xA0, 0x59, 0x86, 0x57, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32, 0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25, 0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x75, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x69, 0x30, 0x67, 0x30, 0x65, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x59, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32, 0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25, 0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0x87, 0xB6, 0x82, 0xF3, 0xDA, 0xBE, 0xB1, 0x7B, 0x98, 0x7D, 0x3D, 0x0A, 0x90, 0xA8, 0xF5, 0xBF, 0x15, 0xC3, 0xEE, 0x8A, 0x4E, 0xC0, 0x7B, 0x10, 0x1D, 0xA9, 0xE3, 0x0B, 0xEC, 0x2C, 0x53, 0x4E, 0xA7, 0xBD, 0xF1, 0x6C, 0xAD, 0x18, 0x55, 0xBA, 0x25, 0x73, 0x55, 0xB7, 0x5B, 0x12, 0x24, 0xF4, 0x02, 0x31, 0x00, 0xAF, 0x02, 0x9C, 0x4B, 0x92, 0xD0, 0x72, 0xA5, 0x80, 0xCA, 0x69, 0x2B, 0x38, 0x50, 0x64, 0xD8, 0x58, 0x9E, 0xEA, 0xD6, 0x35, 0xCF, 0x68, 0x98, 0x92, 0x81, 0x09, 0x61, 0xC2, 0xBD, 0xB1, 0x4C, 0x7F, 0xAE, 0x55, 0x7B, 0xFC, 0x22, 0xDD, 0xD6, 0xB7, 0x7C, 0xB5, 0xA8, 0x18, 0x5D, 0x33, 0x04
0x30, 0x82, 0x04, 0x56, 0x30, 0x82, 0x03, 0xDC, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, 0x00, 0x03, 0x6C, 0xCF, 0xED, 0xE2, 0x44, 0x70, 0x19, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x3E, 0x30, 0x3C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x35, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x31, 0x39, 0x34, 0x39, 0x33, 0x38, 0x5A, 0x17, 0x0D, 0x33, 0x33, 0x30, 0x31, 0x32, 0x35, 0x31, 0x39, 0x35, 0x39, 0x33, 0x38, 0x5A, 0x30, 0x81, 0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0x1D, 0xDD, 0x08, 0x02, 0x03, 0x25, 0x75, 0x20, 0xE2, 0x71, 0x8B, 0xAD, 0x28, 0x09, 0x82, 0xE9, 0x06, 0xEE, 0x83, 0xC5, 0x3A, 0x6C, 0x4B, 0x71, 0x92, 0x50, 0x4E, 0x20, 0xE9, 0x72, 0xB4, 0xFC, 0x53, 0x2A, 0xEF, 0x5D, 0xCC, 0x9A, 0xB4, 0xCD, 0x76, 0xB8, 0x94, 0x97, 0x44, 0xB2, 0x71, 0x0E, 0xC9, 0xB1, 0x16, 0x03, 0xA1, 0x65, 0x2B, 0xB9, 0xE8, 0x5D, 0x5F, 0xF2, 0x30, 0x2E, 0xDD, 0xB1, 0x2B, 0x20, 0xFC, 0xBE, 0x00, 0x88, 0xEA, 0x1F, 0xA7, 0x7F, 0x99, 0x84, 0x98, 0x7C, 0x71, 0x3E, 0x4D, 0x34, 0x83, 0x69, 0x9B, 0x08, 0xCB, 0x78, 0xB2, 0x4B, 0xBD, 0xD7, 0x3E, 0xBE, 0x67, 0xA0, 0xA3, 0x82, 0x01, 0xFC, 0x30, 0x82, 0x01, 0xF8, 0x30, 0x10, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03, 0x27, 0x5F, 0x97, 0xEB, 0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x65, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04, 0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00, 0x30, 0x52, 0x06, 0x0C, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01, 0x30, 0x42, 0x30, 0x40, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x44, 0x6F, 0x63, 0x73, 0x2F, 0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E, 0x68, 0x74, 0x6D, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0C, 0x1E, 0x0A, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x14, 0xDA, 0x5B, 0xF1, 0x0E, 0x66, 0x47, 0xD1, 0x5D, 0x13, 0x5F, 0x5B, 0x7A, 0xEB, 0xEB, 0x5F, 0x01, 0x08, 0xB5, 0x49, 0x30, 0x7A, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x73, 0x30, 0x71, 0x30, 0x6F, 0xA0, 0x6D, 0xA0, 0x6B, 0x86, 0x69, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32, 0x30, 0x45, 0x43, 0x43, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x37, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x81, 0x87, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x7B, 0x30, 0x79, 0x30, 0x77, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x6B, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32, 0x30, 0x45, 0x43, 0x43, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x37, 0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x30, 0x56, 0x2A, 0xAD, 0x72, 0x4C, 0xB9, 0x8C, 0xB3, 0x23, 0x80, 0xF5, 0x5F, 0xF8, 0x21, 0x94, 0x66, 0x0F, 0x76, 0x77, 0xE2, 0x7B, 0x03, 0xDD, 0x30, 0x5E, 0xCB, 0x90, 0xCA, 0x78, 0xE6, 0x0B, 0x2D, 0x12, 0xE5, 0xF7, 0x67, 0x31, 0x58, 0x71, 0xE6, 0xF3, 0x64, 0xC1, 0x04, 0xB3, 0x8B, 0xE9, 0xE2, 0x02, 0x31, 0x00, 0xB9, 0x20, 0x61, 0xB9, 0xD0, 0x5E, 0x3A, 0xA4, 0xA2, 0x8A, 0xFE, 0x1D, 0xFC, 0x27, 0x61, 0x0B, 0x98, 0x16, 0x8C, 0x02, 0x9C, 0x20, 0x7F, 0xEE, 0xF3, 0xCB, 0x1F, 0x0A, 0x37, 0x62, 0xB1, 0x8E, 0xCE, 0xD9, 0x9A, 0x9E, 0xAC, 0xE6, 0x1A, 0xD4, 0xB8, 0xF1, 0xA8, 0x2B, 0xB1, 0xB4, 0x40, 0x9B
-
S. Brander, "Key words for use in RFCs to Indicate Requirement Levels", RFC 2119, March 1997.
-
This process has not yet been defined.
-
T. Pornin, "Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)", RFC 6979, August 2013.
-
Lily Chen, "Recommendation for Key Derivation Using Pseudorandom Functions (Revised)", NIST SP 800-108, October 2009.
-
Certicom Research, "Standards for Efficient Cryptography 1 (Version 2.0)", SEC 1, May 2009.
-
Ibid.
-
https://msdn.microsoft.com/en-us/library/windows/desktop/dd401551(v=vs.85).aspx
-
E.g. a pluggable sensor, or an embedded sensor on a host with multiple operating systems.
-
Adding a new nonce parameter to the end of
WINBIO_CAPTURE_PARAMETERS
is not an option, unfortunately, for backward compatibility reasons. -
Previously unused, but already defined: https://msdn.microsoft.com/en-us/library/windows/hardware/ff536461(v=vs.85).aspx