Skip to content

Secure Device Connection Protocol

mapalko edited this page Aug 28, 2018 · 6 revisions

Terminology

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).

Goals

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:

  1. 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.
  2. How do we know this device is healthy? A healthy device is not running compromised firmware.
  3. 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.

Trusted, Healthy Devices – Secure Boot

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:

  1. (cert_m, sk_m): The per-model ECDSA certificate and private key, described above.
  2. (pk_d, sk_d): A per-device ECDSA key pair.
  3. (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:

  1. The per-model private key signs the device public key, creating the signature s_m:
    • s_m <- Sig(sk_m, H(pk_d))
  2. 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.

Certification Requirements

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:

  1. The key pair (pk_d, sk_d) MUST be unique to each device.
  2. The unique, per-device public key, pk_d, MUST be signed by the per-model private key, sk_m, generating the signature s_m, which persists on the device.
  3. The per-model private key, sk_m, MUST NOT be present on the device.
  4. 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.
  5. 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.
  6. 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.

Example Implementation

This is one example implementation of the scheme above. Sensors MAY implement other solutions, as long as they meet the certification requirements set forth.

  1. 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.
  2. 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.
  3. On the factory floor, generate a device key (pk_d, sk_d) for each device. For each device key, sign pk_d with the model private key sk_m, creating signature s_m.
  4. 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 over pk_d (accessible to firmware)
  5. 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.
  6. Before jumping into flash firmware, the area of flash holding sk_d is blocked from further reads and writes for this boot session.
  7. The firmware jumps to flash, passing up the hash, key pair, and signature.
  8. Firmware is now prepared to perform attestation and set up a secure channel with the host.

Mitigations

It is possible for a compromise to happen at any level of our key hierarchy:

  1. Model keys
  2. Device keys
  3. Firmware keys

Model Compromise

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.

Device Compromise

There are two ways that device secret keys can be compromised:

  1. There is a flaw in the bootloader that exposes sk_d. In this case, we will revoke the model certificate, cert_m.
  2. 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).

Firmware Compromise

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.

Bootstrapping a Secure Channel

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.

Secure Connection Protocol

Secure connection protocol

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.

  1. Device Bootloader:
    1. Has access to sk_d, the device private key
    2. Generates the hash of the firmware it is going to load:
      • h_f <- H(firmware)
    3. Generates an ephemeral ECDH key pair:
      • (pk_f, sk_f) <- KGen()
    4. Signs a two-byte prefix {0xC0, 0x01}, h_f, and pk_f with the device private key:
      • s_d <- Sig(sk_d, H(C001||h_f||pk_f))
    5. Locks access to sk_d.
    6. Transitions to untrusted code, passing up s_d, the firmware hash h_f, and the (pk_f, sk_f) key pair.
  2. Device firmware now has access to:
    1. cert_m: The per-model certificate
    2. h_f: The firmware hash
    3. pk_d: The device public key
    4. pk_f: The ephemeral public key
    5. sk_f: The ephemeral private key
    6. s_m: The signature over pk_d using the per-model private key sk_m, which MUST NOT be present on the device.
    7. s_d: The signature over h_f and pk_f, using the private key sk_d, which MUST NOT be accessible to firmware.
  3. Host:
    1. Generates an ephemeral ECDH key pair (pk_h, sk_h)
    2. Generates random bytes: r_h <- GenRand()
    3. Sends the Connect message, containing:
      • r_h
      • pk_h
  4. Device:
    1. Generates random bytes:
      • r_d <- GenRand()
    2. Performs key agreement:
      • a <- KeyAgreement(sk_f, pk_h)
    3. Derives master secret:
      • ms <- KDF(a, "master secret", r_h||r_d)
    4. Derives MAC secret, s, and symmetric key, k:
      • (s, k) <- KDF(ms, "application keys")
    5. Generates the claim:
      • c <- (cert_m, pk_d, pk_f, h_f, s_m, s_d)
    6. Generates a MAC of the claim hash:
      • m <- MAC(s, "connect"||H(c))
    7. Sends the ConnectResponse message containing:
      • Device random: r_d
      • Claim: c
      • Claim MAC: m
  5. Host:
    1. Performs key agreement:
      • a <- KeyAgreement(sk_h, pk_f)
    2. Derives master secret:
      • ms <- KDF(a, "master secret", r_h||r_d)
    3. Derives MAC secret, s, and symmetric key, k:
      • (s, k) <- KDF(ms, "application keys")
    4. Validates the MAC m over H(c)
    5. Unpacks the claim:
      • (cert_m, pk_d, pk_f, h_f, s_m, s_d) <- c
    6. 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)

Reusing an Existing Connection

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.

Reconnection protocol

  1. Host and device have access to the previously negotiated master secret ms.
  2. Host:
    1. r_h <- GenRand()
    2. Sends the Reconnect message, containing r_h.
  3. Device:
    1. Derives application keys:
      • (s, k) <- KDF(ms, "application keys")
    2. Generates a MAC over the r_h:
      • m <- MAC(s, "reconnect"||r_h)
    3. Sends the ReconnectResponse message, containing m.
  4. Host:
    1. Verifies the MAC m over r_h, and perform the full connection if needed.

Notation

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

Cryptographic Algorithms

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.

KDF in Counter Mode

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 to MAX_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.

Data Encoding

  • 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 as r||s, where the integers r and s 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.

Securing Biometric Operations

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:

  1. The internal implementation of Enroll and Identify:
    • Stored biometric templates MUST be private and MUST be protected against manipulation and injection.
    • Biometric samples used by Enroll and Identify MUST NOT be injected or replayed.
  2. 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 goal of the biometric trustlet in VSM is to provide security for these two layers.

Sample Collection and Template Storage (Layer One)

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.

Securing the Interface (Layer Two)

With secured samples traveling from sensor to matcher, we now focus on securing the WBF <-> BU interface.

Enrollment

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.

Enrollment

  1. Bio Service (normal-world):
    1. Sends EnrollBegin.
  2. Sensor:
    1. Generates a nonce, n.
    2. Sends the EnrollmentNonce message, containing n.
  3. Bio Service (normal-world):
    1. Begins sample collection for the construction of a biometric template, until the sensor indicates that enough samples have been collected.
    2. After the template has been constructed, the bio service sends the enrollment nonce, n, to the bio trustlet.
  4. Bio Trustlet (VSM):
    1. Computes the MAC over n:
      • id <- MAC(s, "enroll"||n)
    2. Authorizes the user, resulting in a user SID, sid.
    3. Stores the following mapping in its authorized enrollment database:
      • id -> (sid, pk_d, h_f)
    4. Sends id to the bio service in normal-world
  5. Bio Service (normal-world)
    1. Sends the EnrollCommit message, containing id.
  6. Sensor:
    1. Validates the MAC, id, over n.
    2. Stores the (template, id) tuple in the template database.

After enrollment, id is not treated like a MAC, it becomes the identifier for the authorized user.

Identification

After enrollment, the identifier id is in two places:

  1. The template database.
  2. 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.

Identification

  1. Bio Trustlet (VSM):
    1. Generates a nonce, n, and passes it out to the bio service.
  2. Bio Service (normal-world):
    1. Sends the Identify command to the device, containing n.
  3. Sensor:
    1. Matches the sample, and looks up the corresponding id.
    2. MACs the nonce and identifier:
      • m <- MAC(s, "identify"||n||id)
    3. Sends the AuthorizedIdentity response, containing id and m.
  4. Bio Service (normal-world)
    1. Forwards the AuthorizedIdentity response to the trustlet.
  5. Bio Trustlet (VSM):
    1. Validates the MAC, m.
    2. Looks up id in the authorized enrollment database, yielding:
      • (s, pk_d, h_f) <- LookupEnrollment(id)

Credential Release

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:

  1. s: The SID of the user who was identified.
  2. pk_d: The device public key.
  3. 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:

  1. pk_d from the identification result matches the pk_d of the currently paired device.
  2. h_f has not been revoked.

Windows Biometric Framework Changes

  • 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.

Constants

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)

WBDI IOCTLs

//
// 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)

IOCTL_BIOMETRIC_CONNECT_SECURE

This IOCTL will be sent to connect or reconnect using the secure connection protocol defined in this document.

  1. 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. If WINBIO_CONNECTION_FLAG_RECONNECT is set, PublicKey is omitted.
  2. 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 over HostRandom. If this is a full connection, a MAC over the hash of claim, which immediately follows the Mac.
    • DeviceRandom
      The device random bytes.
    • ModelCertificate
      The x509 ASN.1 DER encoded certificate, cert_m.
    • DevicePublicKey
      The public key pk_d.
    • FirmwarePublicKey
      The firmware public key pk_f.
    • FirmwareHash
      The firmware hash h_f.
    • ModelSignature
      To model signature s_m.
    • DeviceSignature
      The device signature ~sd.
    • IntermediateCA1
      Certificate for an intermediate CA between cert_m and the root.
    • IntermediateCA2
      Certificate for an intermediate CA between cert_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.

Sensor Adapter Methods

SensorAdapterConnectSecure

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 the WINBIO_PIPELINE structure associated with the biometric unit performing the operation.
  • ConnectionParams
    Input connection parameters.
  • ConnectionData
    Connection response data.

Engine Adapter Functions

WINBIO_IDENTITY

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;

EngineAdapterCreateEnrollmentAuthenticated

HRESULT WINAPI EngineAdapterCreateEnrollmentAuthenticated(
    _Inout_ WINBIO_PIPELINE* Pipeline,
    _Outptr_result_bytebuffer_(*NonceSize) PUCHAR* Nonce,
    _Out_ SIZE_T* NonceSize);
  • Pipeline
    Pointer to the WINBIO_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 in EngineAdapterCommitEnrollment.
  • 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)

EngineAdapterIdentifyFeatureSetAuthenticated

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 the WINBIO_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 a WINBIO_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 a WINBIO_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 the Authentication, in bytes. This value is returned only if a match is found.

INF Changes

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,,""

Appendix A. Test Vectors

KDF

Example 1

Input:
  K_i     = 0000000000000000000000000000000000000000000000000000000000000000
  Label   = "Example 1"
  Context = null
  L       = 1024
Output:
  ced7fc06140681bddcccdab36e154f42b364ba94a9e2ebc5693a0fd0f8184359
  63c975a829bf3501798cafcb766f031d54294c08d12196885b96725fc190b532
  c6b2d2977242262319daed6def6e2621f6e32a27066e2ee34cda40bebad2f1fa
  d5730d9f9a95fecef06bef70eccf0b39c8a07598f84ad2f6bfc1d9e0e6de94d8

Example 2

Input:
  K_i     = 0000000000000000000000000000000000000000000000000000000000000000
  Label   = ""
  Context = aabbccddeeff
  L       = 256
Output:
  b32a81f79729951e5694c0f7e21eeb1337c08627453d17248422dec8e1c8fbff

Example 3

Input:
  K_i     = 41c1239619bbf4dd5385e6fdaee6a4301e3d14437e262d97668a44111fb3973d
  Label   = "test vector"
  Context = 7b4b562b553b8f205af6f6680027c1035d427b650bca1eba971266c65f54ed24
            49734a5d9867e339a509982fead5d28b952ac98a35be025919f248605b04adf6
  L       = 760
Output:
  5a644067ecf9e62552a448e66ddea42ab961893b45995e815d951e91fe7283e2
  6857ca82a4f6d10f6dc16760f8ab830a69bcc89e5c2c22ac0de3acd73e417672
  08969362e9e5986c8a0a696fd7afd689498f575b9559fe7206fb1fcf76d5f8

Certificates

Note: TestSigning MUST be enabled to use these certificate test vectors.

Model Certificate

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

Model Certificate Private Key

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

IntermediateCA1

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

IntermediateCA2

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

Footnotes

  1. S. Brander, "Key words for use in RFCs to Indicate Requirement Levels", RFC 2119, March 1997.

  2. This process has not yet been defined.

  3. T. Pornin, "Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)", RFC 6979, August 2013.

  4. Lily Chen, "Recommendation for Key Derivation Using Pseudorandom Functions (Revised)", NIST SP 800-108, October 2009.

  5. Certicom Research, "Standards for Efficient Cryptography 1 (Version 2.0)", SEC 1, May 2009.

  6. Ibid.

  7. https://msdn.microsoft.com/en-us/library/windows/desktop/dd401551(v=vs.85).aspx

  8. E.g. a pluggable sensor, or an embedded sensor on a host with multiple operating systems.

  9. Adding a new nonce parameter to the end of WINBIO_CAPTURE_PARAMETERS is not an option, unfortunately, for backward compatibility reasons.

  10. Previously unused, but already defined: https://msdn.microsoft.com/en-us/library/windows/hardware/ff536461(v=vs.85).aspx

Clone this wiki locally