| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This file contains additional declarations for CTAP2 PIN support. Only |
| // implementations of the PIN protocol should need to include this file. For all |
| // other code, see |pin.h|. |
| |
| #ifndef DEVICE_FIDO_PIN_INTERNAL_H_ |
| #define DEVICE_FIDO_PIN_INTERNAL_H_ |
| |
| #include <stdint.h> |
| |
| #include <array> |
| #include <vector> |
| |
| #include "base/component_export.h" |
| #include "base/containers/span.h" |
| #include "base/optional.h" |
| #include "components/cbor/values.h" |
| #include "device/fido/fido_constants.h" |
| #include "device/fido/pin.h" |
| #include "third_party/boringssl/src/include/openssl/base.h" |
| |
| namespace device { |
| namespace pin { |
| |
| // Subcommand enumerates the subcommands to the main |authenticatorClientPIN| |
| // command. See |
| // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#authenticatorClientPIN |
| enum class Subcommand : uint8_t { |
| kGetRetries = 0x01, |
| kGetKeyAgreement = 0x02, |
| kSetPIN = 0x03, |
| kChangePIN = 0x04, |
| kGetPINToken = 0x05, |
| kGetUvToken = 0x06, |
| kGetUvRetries = 0x07, |
| kSetMinPINLength = 0x08, |
| kGetPinUvAuthTokenUsingPinWithPermissions = 0x09, |
| }; |
| |
| // RequestKey enumerates the keys in the top-level CBOR map for all PIN |
| // commands. |
| enum class RequestKey : int { |
| kProtocol = 0x01, |
| kSubcommand = 0x02, |
| kKeyAgreement = 0x03, |
| kPINAuth = 0x04, |
| kNewPINEnc = 0x05, |
| kPINHashEnc = 0x06, |
| kMinPINLength = 0x07, |
| kMinPINLengthRPIDs = 0x08, |
| kPermissions = 0x09, |
| kPermissionsRPID = 0x0A, |
| }; |
| |
| // ResponseKey enumerates the keys in the top-level CBOR map for all PIN |
| // responses. |
| enum class ResponseKey : int { |
| kKeyAgreement = 1, |
| kPINToken = 2, |
| kRetries = 3, |
| kUvRetries = 5, |
| }; |
| |
| // PointFromKeyAgreementResponse returns an |EC_POINT| that represents the same |
| // P-256 point as |response|. It returns |nullopt| if |response| encodes an |
| // invalid point. |
| base::Optional<bssl::UniquePtr<EC_POINT>> PointFromKeyAgreementResponse( |
| const EC_GROUP* group, |
| const KeyAgreementResponse& response); |
| |
| // Protocol abstracts a PIN/UV Auth Token Protocol. Instances are obtained |
| // through ProtocolVersion(). |
| class COMPONENT_EXPORT(DEVICE_FIDO) Protocol { |
| public: |
| virtual ~Protocol() = default; |
| Protocol(Protocol&) = delete; |
| Protocol& operator=(Protocol&) = delete; |
| |
| // Encapsulate derives a shared secret, which it writes to |out_shared_key|, |
| // and returns the platform's public key. |
| virtual std::array<uint8_t, kP256X962Length> Encapsulate( |
| const KeyAgreementResponse& peers_key, |
| std::vector<uint8_t>* out_shared_key) const = 0; |
| |
| // Encrypt encrypts |plaintext| under |shared_key|. |plaintext| must be a |
| // multiple of AES_BLOCK_SIZE in length. |shared_key| must be a shared secret |
| // derived by Encapsulate(). |
| virtual std::vector<uint8_t> Encrypt( |
| base::span<const uint8_t> shared_key, |
| base::span<const uint8_t> plaintext) const = 0; |
| |
| // Decrypt returns the decryption of |ciphertext|, which must be non-empty and |
| // a multiple of AES_BLOCK_SIZE in length. |shared_key| must be a shared |
| // secret derived by Encapsulate(). |
| virtual std::vector<uint8_t> Decrypt( |
| base::span<const uint8_t> shared_key, |
| base::span<const uint8_t> ciphertext) const = 0; |
| |
| // Authenticate() returns a signature of |data|. |key| must be either a shared |
| // secret derived by Encapsulate() or a valid pinUvAuthToken from the same |
| // PIN/UV Auth Protocol. |
| virtual std::vector<uint8_t> Authenticate( |
| base::span<const uint8_t> key, |
| base::span<const uint8_t> data) const = 0; |
| |
| // Verify verifies a signature computed by Authenticate(). |
| virtual bool Verify(base::span<const uint8_t> key, |
| base::span<const uint8_t> data, |
| base::span<const uint8_t> signature) const = 0; |
| |
| // CalculateSharedKey returns the CTAP2 shared key between |key| and |
| // |peers_key|. |
| virtual std::vector<uint8_t> CalculateSharedKey( |
| const EC_KEY* key, |
| const EC_POINT* peers_key) const = 0; |
| |
| protected: |
| Protocol() = default; |
| }; |
| |
| // ProtocolVersion returns the |Protocol| implementation for |
| // |PINUvAuthProtocol|. |
| COMPONENT_EXPORT(DEVICE_FIDO) |
| const Protocol& ProtocolVersion(PINUVAuthProtocol protocol); |
| |
| } // namespace pin |
| } // namespace device |
| |
| #endif // DEVICE_FIDO_PIN_INTERNAL_H_ |