blob: 5e2c21c5c85ce206c0d226f6ebabf2aaab7b41f5 [file] [edit]
// Copyright 2019 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BIOD_CROS_FP_DEVICE_INTERFACE_H_
#define BIOD_CROS_FP_DEVICE_INTERFACE_H_
#include <bitset>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <base/functional/callback.h>
#include <brillo/secure_blob.h>
#include <chromeos/ec/ec_commands.h>
#include "libec/ec_command.h"
#include "libec/ec_command_version_supported.h"
#include "libec/fingerprint/fp_mode.h"
#include "libec/fingerprint/fp_sensor_errors.h"
/**
* Though it's nice to have the template as a SecureVector, for some templates
* this will hit the RLIMIT_MEMLOCK and cause a crash. Since the template is
* encrypted by the FPMCU, it's not strictly necessary to use SecureVector.
*/
using VendorTemplate = std::vector<uint8_t>;
namespace biod {
class CrosFpDeviceInterface : public ec::EcCommandVersionSupportedInterface {
public:
using MkbpCallback = base::RepeatingCallback<void(const uint32_t event)>;
CrosFpDeviceInterface() = default;
CrosFpDeviceInterface(const CrosFpDeviceInterface&) = delete;
CrosFpDeviceInterface& operator=(const CrosFpDeviceInterface&) = delete;
virtual ~CrosFpDeviceInterface() = default;
struct EcVersion {
std::string ro_version;
std::string rw_version;
ec_image current_image = EC_IMAGE_UNKNOWN;
};
virtual void SetMkbpEventCallback(MkbpCallback callback) = 0;
struct FpStats {
uint32_t capture_ms = 0;
uint32_t matcher_ms = 0;
uint32_t overall_ms = 0;
};
struct GetSecretReply {
brillo::Blob encrypted_secret;
brillo::Blob iv;
brillo::Blob pk_out_x;
brillo::Blob pk_out_y;
};
struct PairingKeyKeygenReply {
brillo::Blob pub_x;
brillo::Blob pub_y;
brillo::Blob encrypted_private_key;
};
virtual bool SetFpMode(const ec::FpMode& mode) = 0;
/**
* @return mode on success, FpMode(FpMode::Mode::kModeInvalid) on failure
*/
virtual ec::FpMode GetFpMode() = 0;
virtual std::optional<FpStats> GetFpStats() = 0;
virtual std::optional<std::bitset<32>> GetDirtyMap() = 0;
virtual bool SupportsPositiveMatchSecret() = 0;
virtual std::optional<brillo::SecureVector> GetPositiveMatchSecret(
int index) = 0;
// Get the positive match secret, but with response encrypted by a ECDH
// session.
virtual std::optional<GetSecretReply> GetPositiveMatchSecretWithPubkey(
int index, const brillo::Blob& pk_in_x, const brillo::Blob& pk_in_y) = 0;
virtual std::unique_ptr<VendorTemplate> GetTemplate(int index) = 0;
virtual bool UploadTemplate(const VendorTemplate& tmpl) = 0;
virtual bool UnlockTemplates(size_t num) = 0;
virtual bool SetContext(std::string user_id) = 0;
// Set the nonce context by providing nonce and user_id of the context.
virtual bool SetNonceContext(const brillo::Blob& nonce,
const brillo::Blob& encrypted_user_id,
const brillo::Blob& iv) = 0;
// Get nonce from FPMCU to initiate the session key exchange.
virtual std::optional<brillo::Blob> GetNonce() = 0;
virtual bool ResetContext() = 0;
// Initialise the entropy in the SBP. If |reset| is true, the old entropy
// will be deleted. If |reset| is false, we will only add entropy, and only
// if no entropy had been added before.
virtual bool InitEntropy(bool reset) = 0;
virtual bool UpdateFpInfo() = 0;
// Initiate the ECDH session to establish the pairing key.
// The FPMCU generates and returns its public key and encrypted
// private key. This encrypted private key is provided to the FPMCU
// during the PairingKeyWrap command, so that no FPMCU state is required.
//
// Note that the encrypted private key Blob contains the as-is
// serialization of the returned private key struct. We do not
// unpack the key struct, since we are simply returning the as-is
// contents to the FPMCU through PairingKeyWrap.
virtual std::optional<PairingKeyKeygenReply> PairingKeyKeygen() = 0;
// Complete the ECDH session to establish the pairing key. Give the FPMCU
// the public key of the caller. Also, provide the wrapped private key of
// their key pair returned in PairingKeyKeygen. The wrapped pairing key is
// returned from the FPMCU because it doesn't have persistent storage, and
// relies on userland storing it.
virtual std::optional<brillo::Blob> PairingKeyWrap(
const brillo::Blob& pub_x,
const brillo::Blob& pub_y,
const brillo::Blob& encrypted_priv) = 0;
// Load the wrapped pairing key into the FPMCU. This will be called on
// each boot as most FP operations require the pairing key to be loaded in the
// FPMCU. This is the key returned from PairingKeyWrap, which must be
// persisted on the host.
virtual bool LoadPairingKey(const brillo::Blob& encrypted_pairing_key) = 0;
// Migrate a legacy template |tmpl| (which was created in a user id context
// |user_id| instead of nonce context) to a template in the nonce context.
// This marks the uploaded template as newly enrolled so it should be
// downloaded by GetTemplate() afterwards.
virtual bool MigrateLegacyTemplate(const std::string& user_id,
const VendorTemplate& tmpl) = 0;
virtual int MaxTemplateCount() = 0;
virtual int TemplateVersion() = 0;
virtual int DeadPixelCount() = 0;
virtual ec::FpSensorErrors GetHwErrors() = 0;
};
} // namespace biod
#endif // BIOD_CROS_FP_DEVICE_INTERFACE_H_