Merge "Start adding documentation for IFingerprint"
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 85d1f57..9cbf343 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -20,7 +20,7 @@
interface IFingerprint {
android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
- void setResetLockoutCallback(in android.hardware.biometrics.fingerprint.IResetLockoutCallback cb);
+ void setLockoutCallback(in android.hardware.biometrics.fingerprint.ILockoutCallback cb);
void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb);
- void revokeChallenge(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb);
+ void revokeChallenge(in int sensorId, in int userId, in long challenge, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb);
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
index eaf27d2..063be60 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
@@ -18,5 +18,5 @@
package android.hardware.biometrics.fingerprint;
@VintfStability
interface IGenerateChallengeCallback {
- oneway void onChallengeGenerated(in int sensorId, in int userId, in long keystoreOperationId, in long challenge);
+ oneway void onChallengeGenerated(in int sensorId, in int userId, in long challenge);
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
similarity index 82%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl
rename to biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
index ac0decd..88aabbf 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
@@ -17,6 +17,8 @@
package android.hardware.biometrics.fingerprint;
@VintfStability
-interface IResetLockoutCallback {
- oneway void onLockoutReset(in int sensorId, in int userId, in long durationMilli);
+interface ILockoutCallback {
+ oneway void onLockoutTimed(in int sensorId, in int userId, in long durationMillis);
+ oneway void onLockoutPermanent(in int sensorId, in int userId);
+ oneway void onLockoutCleared(in int sensorId, in int userId);
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 4709778..57319b2 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -17,7 +17,7 @@
package android.hardware.biometrics.fingerprint;
import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback;
-import android.hardware.biometrics.fingerprint.IResetLockoutCallback;
+import android.hardware.biometrics.fingerprint.ILockoutCallback;
import android.hardware.biometrics.fingerprint.IRevokeChallengeCallback;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.ISessionCallback;
@@ -25,13 +25,144 @@
@VintfStability
interface IFingerprint {
+ /**
+ * getSensorProps:
+ *
+ * @return A list of properties for all sensors that an instance of the
+ * HAL supports.
+ */
SensorProps[] getSensorProps();
+ /**
+ * createSession:
+ *
+ * Creates a session which can then be used by the framework to perform
+ * operations such as enroll, authenticate, etc for the given sensorId
+ * and userId.
+ *
+ * A physical sensor identified by sensorId typically supports only a
+ * single in-flight session at a time. As such, if a session is currently
+ * in a state other than SessionState::IDLING, the HAL MUST finish or
+ * cancel the current operation and return to SessionState::IDLING before
+ * the new session is created. For example:
+ * 1) If a session for sensorId=0, userId=0
+ * is currently in a cancellable state (see ICancellationSignal) such
+ * as SessionState::AUTHENTICATING and the framework requests a new
+ * session for sensorId=0, userId=10, the HAL must end the current
+ * session with Error::CANCELED, invoke
+ * ISessionCallback#onStateChanged with SessionState::IDLING, and
+ * then return a new session for sensorId=0, userId=10.
+ * 2) If a session for sensorId=0, userId=0 is currently in a
+ * non-cancellable state such as SessionState::REMOVING_ENROLLMENTS,
+ * and the framework requests a new session for sensorId=0, userId=10,
+ * the HAL must finish the current operation before invoking
+ * ISessionCallback#onStateChanged with SessionState::IDLING, and
+ * return a new session for sensorId=0, userId=10.
+ *
+ * Implementations must store user-specific state or metadata in
+ * /data/vendor_de/<user>/fpdata as specified by the SeLinux policy. This
+ * directory is created/removed by vold (see vold_prepare_subdirs.cpp).
+ * Implementations may store additional user-specific data, such as
+ * embeddings or templates in StrongBox.
+ *
+ * @param sensorId The sensor with which this session is being created.
+ * @param userId The userId with which this session is being created.
+ * @param cb Used to notify the framework.
+ * @return A new session
+ */
ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
- void setResetLockoutCallback(in IResetLockoutCallback cb);
+ /**
+ * setLockoutCallback:
+ *
+ * Sets a callback to notify the framework lockout changes. Note
+ * that lockout is user AND sensor specific. In other words, there is a
+ * separate lockout state for each (user, sensor) pair. For example, the
+ * following is a valid state on a multi-sensor device:
+ * ------------------------------------------------------------------
+ * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil |
+ * |----------|--------|----------------|-----------|---------------|
+ * | 0 | 0 | 1 | false | x |
+ * | 1 | 0 | 5 | true | <future_time> |
+ * | 0 | 10 | 0 | false | x |
+ * | 1 | 10 | 0 | false | x |
+ * ------------------------------------------------------------------
+ *
+ * Lockout may be cleared in the following ways:
+ * 1) ISession#resetLockout
+ * 2) After a period of time, according to a rate-limiter.
+ *
+ * In addition, lockout states MUST persist after device reboots, HAL
+ * crashes, etc.
+ *
+ * See the Android CDD section 7.3.10 for the full set of lockout and
+ * rate-limiting requirements.
+ *
+ * @param cb Used to notify the framework of lockout changes.
+ */
+ void setLockoutCallback(in ILockoutCallback cb);
+ /**
+ * generateChallenge:
+ *
+ * Begins a secure transaction request. Note that the challenge by itself
+ * is not useful. It only becomes useful when wrapped in a verifiable
+ * message such as a HardwareAuthToken.
+ *
+ * Canonical example:
+ * 1) User requests an operation, such as fingerprint enrollment.
+ * 2) Fingerprint enrollment cannot happen until the user confirms
+ * their lockscreen credential (PIN/Pattern/Password).
+ * 3) However, the biometric subsystem does not want just "any"
+ * proof of credential confirmation. It needs proof that the
+ * user explicitly authenticated credential in order to allow
+ * addition of biometric enrollments.
+ * To secure this path, the following path is taken:
+ * 1) Upon user requesting fingerprint enroll, the framework requests
+ * IFingerprint#generateChallenge
+ * 2) Framework sends the challenge to the credential subsystem, and upon
+ * credential confirmation, a HAT is created, containing the challenge
+ * in the "challenge" field.
+ * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll.
+ * 4) Implementation verifies the authenticity and integrity of the HAT.
+ * 5) Implementation now has confidence that the user entered their
+ * credential to allow biometric enrollment.
+ *
+ * Note that the interface allows multiple in-flight challenges. For
+ * example, invoking generateChallenge(0, 0, timeoutSec, cb) twice
+ * does not invalidate the first challenge. The challenge is invalidated
+ * only when:
+ * 1) The provided timeout expires, or
+ * 2) IFingerprint#revokeChallenge is invoked
+ *
+ * For example, the following is a possible table of valid challenges:
+ * ----------------------------------------------
+ * | SensorId | UserId | ValidUntil | Challenge |
+ * |----------|--------|------------|-----------|
+ * | 0 | 0 | <Time1> | <Random1> |
+ * | 0 | 0 | <Time2> | <Random2> |
+ * | 1 | 0 | <Time3> | <Random3> |
+ * | 0 | 10 | <Time4> | <Random4> |
+ * ----------------------------------------------
+ *
+ * @param sensorId Sensor to associate the challenge with
+ * @param userId User to associate the challenge with
+ * @param timeoutSec Duration for which the challenge is valid for
+ * @param cb Callback to notify the framework
+ */
void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in IGenerateChallengeCallback cb);
- void revokeChallenge(in int sensorId, in int userId, in IRevokeChallengeCallback cb);
+ /**
+ * revokeChallenge:
+ *
+ * Revokes a challenge that was previously generated. Note that if an
+ * invalid combination of parameters is requested, the implementation
+ * must still notify the framework using the provided callback.
+ *
+ * @param sensorId Sensor that the revocation should apply to.
+ * @param userId User that the revocation should apply to.
+ * @param challenge Challenge that should be revoked.
+ * @param cb Used to notify the framework.
+ */
+ void revokeChallenge(in int sensorId, in int userId, in long challenge, in IRevokeChallengeCallback cb);
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
index 93a2d7b..a51b188 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl
@@ -18,6 +18,9 @@
@VintfStability
oneway interface IGenerateChallengeCallback {
- void onChallengeGenerated(in int sensorId, in int userId, in long keystoreOperationId, in long challenge);
+ /**
+ * Notifies the framework when a challenge is successfully generated.
+ */
+ void onChallengeGenerated(in int sensorId, in int userId, in long challenge);
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
new file mode 100644
index 0000000..4b31a38
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+@VintfStability
+oneway interface ILockoutCallback {
+ /**
+ * Notifies the framework that the user has just entered the Error::LOCKOUT state. This must be
+ * sent in the following scenarios:
+ * 1) The user just attempted authentication and was rejected, resulting in a timed lockout.
+ * 2) The framework just created a session for a sensorId/userId pair that has not been
+ * created since the HAL started (e.g. there is no active or idle session for this
+ * sensorId/userId pair.
+ *
+ * @param sensorId Sensor for which the user is locked out.
+ * @param userId User for which the sensor is locked out.
+ * @param durationMillis Remaining duration of the lockout.
+ */
+ void onLockoutTimed(in int sensorId, in int userId, in long durationMillis);
+
+ /**
+ * Notifies the framework that the user has just entered the Error::LOCKOUT_PERMANENT state.
+ * This must be sent in the following scenarios:
+ * 1) The user just attempted authentication and was rejected, resulting in a permanent lockout.
+ * 2) The framework just created a session for a sensorId/userId pair that has not been
+ * created since the HAL started (e.g. there is no active or idle session for this
+ * sensorId/userId pair.
+ *
+ * @param sensorId Sensor for which the user is locked out.
+ * @param userId User for which the sensor is locked out.
+ */
+ void onLockoutPermanent(in int sensorId, in int userId);
+
+ /**
+ * Notifies the framework that lockout has been cleared for this sensorId/userId pair. This
+ * can happen in the following scenarios:
+ * 1) A timed lockout has ended (e.g. original durationMillis specified in #onLockoutTimed
+ * has expired.
+ * 2) See ISession#resetLockout.
+ *
+ * @param sensorId Sensor for which the user's lockout is cleared.
+ * @param userId User for the sensor's lockout is cleared.
+ */
+ void onLockoutCleared(in int sensorId, in int userId);
+}
+
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl
deleted file mode 100644
index d97a701..0000000
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.biometrics.fingerprint;
-
-@VintfStability
-oneway interface IResetLockoutCallback {
- void onLockoutReset(in int sensorId, in int userId, in long durationMilli);
-}
-
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl
index cca3453..eadba52 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl
@@ -18,6 +18,9 @@
@VintfStability
oneway interface IRevokeChallengeCallback {
+ /**
+ * Notifies the framework when a challenge has been revoked.
+ */
void onChallengeRevoked(in int sensorId, in int userId, in long challenge);
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index dd340e8..e2d23a6 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -82,12 +82,14 @@
* The following only applies to sensors that are configured as
* SensorStrength::STRONG.
*
- * When invoked by the framework, the HAL implementation must perform the
+ * When invoked by the framework, the implementation must perform the
* following sequence of events:
* 1) Verify the authenticity and integrity of the provided HAT
- * 2) Update the authenticatorId with a new entropy-encoded random number
- * 3) Persist the new authenticatorId to non-ephemeral storage
- * 4) Notify the framework that the above is completed, via
+ * 2) Verify that the timestamp provided within the HAT is relatively
+ * recent (e.g. on the order of minutes, not hours).
+ * 3) Update the authenticatorId with a new entropy-encoded random number
+ * 4) Persist the new authenticatorId to non-ephemeral storage
+ * 5) Notify the framework that the above is completed, via
* ISessionCallback#onAuthenticatorInvalidated
*
* A practical use case of invalidation would be when the user adds a new
@@ -105,6 +107,26 @@
*/
void invalidateAuthenticatorId(in int cookie, in HardwareAuthToken hat);
+ /**
+ * resetLockout:
+ *
+ * Requests the implementation to clear the lockout counter. Upon receiving
+ * this request, the implementation must perform the following:
+ * 1) Verify the authenticity and integrity of the provided HAT
+ * 2) Verify that the timestamp provided within the HAT is relatively
+ * recent (e.g. on the order of minutes, not hours).
+ *
+ * Upon successful verification, the HAL must notify the framework via
+ * ILockoutCallback#onLockoutChanged(sensorId, userId, 0).
+ *
+ * If verification was uncessful, the HAL must notify the framework via
+ * ILockoutCallback#onLockoutChanged(sensorId, userId, remaining_time).
+ *
+ * @param cookie An identifier used to track subsystem operations related
+ * to this call path. The framework will guarantee that it is
+ * unique per ISession.
+ * @param hat HardwareAuthToken See above documentation.
+ */
void resetLockout(in int cookie, in HardwareAuthToken hat);
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index a1d9d0a..b3bd4e7 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -61,8 +61,8 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Fingerprint::setResetLockoutCallback(
- const std::shared_ptr<IResetLockoutCallback>& /*cb*/) {
+ndk::ScopedAStatus Fingerprint::setLockoutCallback(
+ const std::shared_ptr<ILockoutCallback>& /*cb*/) {
return ndk::ScopedAStatus::ok();
}
@@ -73,7 +73,7 @@
}
ndk::ScopedAStatus Fingerprint::revokeChallenge(
- int32_t /*sensorId*/, int32_t /*userId*/,
+ int32_t /*sensorId*/, int32_t /*userId*/, int64_t /*challenge*/,
const std::shared_ptr<IRevokeChallengeCallback>& /*cb*/) {
return ndk::ScopedAStatus::ok();
}
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h
index b5b09c0..463d07d 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.h
@@ -28,15 +28,15 @@
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* _aidl_return) override;
- ndk::ScopedAStatus setResetLockoutCallback(
- const std::shared_ptr<IResetLockoutCallback>& cb) override;
+ ndk::ScopedAStatus setLockoutCallback(
+ const std::shared_ptr<ILockoutCallback>& cb) override;
ndk::ScopedAStatus generateChallenge(
int32_t sensorId, int32_t userId, int32_t timeoutSec,
const std::shared_ptr<IGenerateChallengeCallback>& cb) override;
ndk::ScopedAStatus revokeChallenge(
- int32_t sensorId, int32_t userId,
+ int32_t sensorId, int32_t userId, int64_t challenge,
const std::shared_ptr<IRevokeChallengeCallback>& cb) override;
};