What Is the Difference Between isInsideSecureHardware() and isUserAuthenticationRequirementEnforcedBySecureHardware()?
Asked Answered
G

3

15

Android 6.0+ has a KeyInfo class to get info on a key saved in the AndroidKeyStore. On the KeyInfo class, we have isInsideSecureHardware() and isUserAuthenticationRequirementEnforcedBySecureHardware() methods. We also have isUserAuthenticationRequired(). The documentation, as usual, sucks.

Based on method names and the (limited) documentation, it would seem as though isUserAuthenticationRequirementEnforcedBySecureHardware() is simply a logical AND of isInsideSecureHardware() and isUserAuthenticationRequired().

Is there something more to it than that? If so, what does it mean for the user authentication requirement to be enforced by secure hardware, beyond just the key being in secure hardware?

Gavin answered 29/1, 2018 at 23:39 Comment(2)
"As an additional security measure, for keys whose key material is inside secure hardware, some key use authorizations may be enforced by secure hardware, depending on the Android device. Cryptographic and user authentication authorizations are likely to be enforced by secure hardware. Temporal validity interval authorizations are unlikely to be enforced by the secure hardware because it normally does not have an independent secure real-time clock." (source).Quickly
I interpret that as isUserAuthenticationRequirementEnforcedBySecureHardware not simply being a logical AND of isInsideSecureHardware and isUserAuthenticationRequired.Quickly
L
7

The method isUserAuthenticationRequirementEnforcedBySecureHardware() is not a logical AND of isInsideSecureHardware() and isUserAuthenticationRequired().

But if you dig into the code, you can see that it is a logical AND of 3 things:

  1. isUserAuthenticationRequired()
  2. 0 SW Enforced User Authenticators
  3. 1 or more HW Enforced User Authenticators

Snippet of code:

boolean userAuthenticationRequirementEnforcedBySecureHardware = (userAuthenticationRequired)
                && (keymasterHwEnforcedUserAuthenticators != 0)
                && (keymasterSwEnforcedUserAuthenticators == 0);

The difference is not whether the key is secure in hardware, but if user authentication is backed by hardware, not software. For most, if not all devices with fingerprint readers, user authentication in secure hardware means the TEE would contain two things that interact with the Keymaster Trusted App:

  1. Gatekeeper Trusted App for pin/password/pattern
  2. Fingerprint Trusted App for fingerprint authentication

Example scenarios:

  • isUserAuthenticationRequirementEnforcedBySecureHardware() could return false if both isInsideSecureHardware() and isUserAuthenticationRequired() return true, but the user authentication is done in SW and not in the TEE. (not likely)
  • isUserAuthenticationRequirementEnforcedBySecureHardware() could return true if isInsideSecureHardware() returns false (key is not supported in device's secure hardware) and isUserAuthenticationRequired() returns true with the user authentication done in HW. (possible)
Lengthways answered 21/9, 2018 at 21:12 Comment(0)
I
2

isUserAuthenticationRequirementEnforcedBySecureHardware() is simply a logical AND of isInsideSecureHardware() and isUserAuthenticationRequired().

I think that's not true (see methods below) it comes via the key from KeyChain.

Is there something more to it than that?

KeyInfo.java is a container class for key info from a KeyChain. Whether the key is bound to the secure hardware is known only once the key has been imported.

To find out, use:

{
    PrivateKey key = ...; // private key from KeyChain

    KeyFactory keyFactory =
        KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
    KeyInfo keyInfo = keyFactory.getKeySpec(key, KeyInfo.class);
    if (keyInfo.isInsideSecureHardware()) 
    {
        // The key is bound to the secure hardware of this Android
    }
}

From KeyInfo.java:

/**
 * Returns {@code true} if the key resides inside secure hardware (e.g., Trusted Execution
 * Environment (TEE) or Secure Element (SE)). Key material of such keys is available in
 * plaintext only inside the secure hardware and is not exposed outside of it.
 */
public boolean isInsideSecureHardware() 
{
    return mInsideSecureHardware;
}

/**
 * Returns {@code true} if the requirement that this key can only be used if the user has been
 * authenticated is enforced by secure hardware (e.g., Trusted Execution Environment (TEE) or
 * Secure Element (SE)).
 *
 * @see #isUserAuthenticationRequired()
 */
public boolean isUserAuthenticationRequirementEnforcedBySecureHardware() 
{
    return mUserAuthenticationRequirementEnforcedBySecureHardware;
}

/**
 * Returns {@code true} if the key is authorized to be used only if the user has been
 * authenticated.
 *
 * <p>This authorization applies only to secret key and private key operations. Public key
 * operations are not restricted.
 *
 * @see #getUserAuthenticationValidityDurationSeconds()
 * @see KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)
 * @see KeyProtection.Builder#setUserAuthenticationRequired(boolean)
 */
public boolean isUserAuthenticationRequired() 
{
    return mUserAuthenticationRequired;
}

See also: KeyStore.java

Instead answered 1/2, 2018 at 14:31 Comment(3)
That shows three separate fields in KeyInfo. It does not indicate whether those three fields are indeed independent (it would be based on whatever is calling the constructor). Also, it does not explain what it means for the user authentication requirement to be enforced by secure hardware, beyond just the key being in secure hardware. Thanks, though!Gavin
Yes, as I said KeyInfo.java is a container class for key info from a KeyChain, and so it's methods are a simple relay of data from the constructor. I'm not saying how the data to the constructor was formed, I'm saying your contention that a "simply a logical AND" is inferred anywhere in documentation or the code I have displayed, is misplaced (at least to me). I guess I have to look further for the constructorcaller...but secure hardware is known only once the key has been imported hmm pondering, and why have the field if it can be reconstructed (I would not do it that way)?Instead
@Gavin I have in the course of my research on the subect come across the comment that some of these methods return different results on multiple calls on the same device, which if true is very puzzling and extremely worrisome about the integrity of the code..Instead
I
1

isUserAuthenticationRequirementEnforcedBySecureHardware() is simply a logical AND of isInsideSecureHardware() and isUserAuthenticationRequired().

From the given documentation isUserAuthenticationRequirementEnforcedBySecureHardware method must not be logical AND of above two methods.

For observation purpose you can consider this link question, answer and comments.

Ionium answered 6/2, 2018 at 13:13 Comment(1)
"must not be logical AND of above two methods" -- and your proof of this is... what, exactly? And, if you do have proof, what does it mean for the user authentication requirement to be enforced by secure hardware, beyond just the key being in secure hardware? "For observation purpose you can consider this link question, answer and comments" -- none of that addresses this question.Gavin

© 2022 - 2024 — McMap. All rights reserved.